Version 1.12.0-dev.1.0
Merge commit '0368173f201055c792ea24bedd5a46fd4aa8801e' into dev.
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..f9b1135
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,31 @@
+# Explicitly declare text files we want to be normalized.
+*.c text
+*.cpp text
+*.h text
+*.gyp text
+*.gypi text
+*.dart text
+*.mk text
+*.Makefile text
+*.md text
+*.yaml text
+
+# Files that should not be converted.
+tests/compiler/dart2js_extra/string_interpolation_test.dart -text
+tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart -text
+tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart -text
+tests/language/raw_string_test.dart -text
+tests/language/multiline_strings_test.dart -text
+tests/lib/convert/json_pretty_test.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_test.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_cr.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_lf.dart -text
+tests/lib/mirrors/method_mirror_source_test.dart -text
+tests/lib/mirrors/method_mirror_source_other.dart -text
+pkg/js_ast/test/printer_callback_test.dart -text
+
+# Files to leave alone and not diff.
+*.png binary
+*.jpg binary
+*.xpi binary
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ddd1600..884a584 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,30 @@
`setInnerHtml` or other methods that create DOM from text. It is
also more efficient, skipping the creation of a `DocumentFragment`.
-## 1.11.0
+### Tool changes
+
+* Pub
+
+ * Pub will now generate a ".packages" file in addition to the "packages"
+ directory when running `pub get` or similar operations, per the
+ [package spec proposal][]. Pub now has a `--no-package-symlinks` flag that
+ will stop "packages" directories from being generated at all.
+
+ * When `pub publish` finds a violation, it will emit a non-zero exit code.
+
+ * `pub run` starts up faster for executables that don't import transformed
+ code.
+
+[package spec proposal]: https://github.com/lrhn/dep-pkgspec
+
+## 1.11.1
+
+### Tool changes
+
+* Pub will always load Dart SDK assets from the SDK whose `pub` executable was
+ run, even if a `DART_SDK` environment variable is set.
+
+## 1.11.0 - 2015-06-25
### Core library changes
@@ -56,6 +79,7 @@
* `Isolate` methods `ping` and `addOnExitListener` now have a named parameter
`response`.
[r45092](https://github.com/dart-lang/sdk/commit/1b208bd)
+ * `Isolate.spawnUri` added a named argument `checked`.
* Remove the experimental state of the API.
* `dart:profiler` - **DEPRECATED**
diff --git a/DEPS b/DEPS
index 5fbe981..321d387 100644
--- a/DEPS
+++ b/DEPS
@@ -83,7 +83,7 @@
"ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
"plugin_tag": "@0.1.0",
"pool_rev": "@22e12aeb16ad0b626900dbe79e4a25391ddfb28c",
- "pub_rev": "@9d707158fedc86fc2b02f62cdfe804902b098d9d",
+ "pub_rev": "@0c02113cc761ec5f142a8c41ff277505fafa5e10",
"pub_cache_tag": "@v0.0.1+2",
"pub_semver_tag": "@1.2.1",
"quiver_tag": "@0.21.4",
diff --git a/create_sdk.gyp b/create_sdk.gyp
index 0ca1c9a..232009c 100644
--- a/create_sdk.gyp
+++ b/create_sdk.gyp
@@ -28,7 +28,7 @@
'"^(?!.*pub/test).*dart$",'
'"sdk/lib"])',
'<!@(["python", "tools/list_files.py", "", '
- '"sdk/lib/_internal/compiler/js_lib/preambles"])',
+ '"sdk/lib/_internal/js_runtime/lib/preambles"])',
'<!@(["python", "tools/list_files.py", "", "sdk/bin"])',
'tools/create_sdk.py',
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 10d6f2c..efd9b0d 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -6,8 +6,9 @@
\usepackage{hyperref}
\usepackage{lmodern}
\newcommand{\code}[1]{{\sf #1}}
-\title{Dart Programming Language Specification\\
-{\large Version 1.10}}
+\title{Dart Programming Language Specification \\
+(4th edition draft)\\
+{\large Version 1.11}}
% For information about Location Markers (and in particular the
% commands \LMHash and \LMLabel), see the long comment at the
@@ -1851,7 +1852,7 @@
The scope of the \IMPLEMENTS{} clause of a class $C$ is the type-parameter scope of $C$.
\LMHash{}
-It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies a type variable as a superinterface. It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies an enumerated type (\ref{enums}), a malformed type or deferred type (\ref{staticTypes}) as a superinterface It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies type \DYNAMIC{} as a superinterface. It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies a type $T$ as a superinterface more than once.
+It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies a type variable as a superinterface. It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies an enumerated type (\ref{enums}), a malformed type or deferred type (\ref{staticTypes}) as a superinterface. It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies type \DYNAMIC{} as a superinterface. It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies a type $T$ as a superinterface more than once.
It is a compile-time error if the superclass of a class $C$ is specified as a superinterface of $C$.
\rationale{
@@ -3794,6 +3795,8 @@
\LMHash{}
$((x) => x == \NULL ? \NULL : x.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k}))(o)$.
+unless $o$ is a type literal, in which case it is equivalent to $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$.
+
\LMHash{}
The static type of $e$ is the same as the static type of $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. Exactly the same static warnings that would be caused by $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ are also generated in the case of $o?.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$.
@@ -3870,7 +3873,7 @@
\item
$T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. Or
\item $T$ is \code{Type}, $e$ is a constant type literal and the class corresponding to $e$ has a static getter named $m$.
-\item $T$ is \code{Function} and $m$ is \CALL. \rationale {The type \code{Function} is treated as if it has a \code{call} method for any possible signature of \CALL. The expectation is that any concrete subclass of \code{Function} will implement \CALL. Note that a warning will be issue if this is not the case. Furthermore, any use of \CALL on a subclass of \code{Function} that fails to implement \CALL{} will also provoke a a warning, as this exemption is limited to type \code{Function}, and does not apply to its subtypes.
+\item $T$ is \code{Function} and $m$ is \CALL. \rationale {The type \code{Function} is treated as if it has a \code{call} method for any possible signature of \CALL. The expectation is that any concrete subclass of \code{Function} will implement \CALL. Note that a warning will be issue if this is not the case. Furthermore, any use of \CALL{} on a subclass of \code{Function} that fails to implement \CALL{} will also provoke a a warning, as this exemption is limited to type \code{Function}, and does not apply to its subtypes.
}
\end{itemize}
@@ -3993,11 +3996,10 @@
Tear-offs using the \cd{ x\#id} syntax cannot be conditional at this time; this is inconsistent, and is likely to be addressed in the near future, perhaps via notation such as \cd{ x?\#id} . As indicated in section \ref{ecmaConformance}, experimentation in this area is allowed.
}
-Evaluation of a {\em conditional property extraction expression} $e$ of the form $e_1?.id$ is equivalent to the evaluation of the expression $((x) => x == \NULL ? \NULL : x.id)(e_1)$. The static type of $e$ is the same as the static type of $e_1.id$. Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static warnings that would be caused by $y.id$ are also generated in the case of $e_1?.id$.
+Evaluation of a {\em conditional property extraction expression} $e$ of the form $e_1?.id$ is equivalent to the evaluation of the expression $((x) => x == \NULL ? \NULL : x.id)(e_1)$.
+unless $e_1$ is a type literal, in which case it is equivalent to $e_1.m$.
-\commentary{
-One might be tempted to conclude that for $e \ne \NULL{}$, $e?.v$ is always equivalent to $e.v$. However this is not the case. If $e$ is a type literal representing a type with static member $v$, then $e.v$ refers to that member, but $e?.v$ does not.
-}
+The static type of $e$ is the same as the static type of $e_1.id$. Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static warnings that would be caused by $y.id$ are also generated in the case of $e_1?.id$.
\LMHash{}
Unconditional property extraction takes several syntactic forms: $e.m$ (\ref{getterAccessAndMethodExtraction}), $\SUPER.m$ (\ref{superGetterAccessAndMethodClosurization}), $e\#m$ (\ref{generalClosurization}), $\NEW{}$ $T\#m$ (\ref{namedConstructorExtraction}), $\NEW{}$ $T\#$ (\ref{anonymousConstructorExtraction}) and $\SUPER\#m$ (\ref{generalSuperPropertyExtraction}), where $e$ is an expression, $m$ is an identifier optionally followed by an equal sign and $T$ is a type.
@@ -4434,7 +4436,9 @@
It is a static type warning if the static type of $e$ may not be assigned to the static type of $v$. The static type of the expression $v$ \code{=} $e$ is the static type of $e$.
\LMHash{}
-Evaluation of an assignment $a$ of the form $e_1?.v$ \code{=} $e_2$ is equivalent to the evaluation of the expression $((x) => x == \NULL? \NULL: x.v = e_2)(e_1)$. The static type of $a$ is the static type of $e_2$. Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static warnings that would be caused by $y.v = e_2$ are also generated in the case of $e_1?.v$ \code{=} $e_2$.
+Evaluation of an assignment $a$ of the form $e_1?.v$ \code{=} $e_2$ is equivalent to the evaluation of the expression $((x) => x == \NULL? \NULL: x.v = e_2)(e_1)$
+ unless $e_1$ is a type literal, in which case it is equivalent to $e_1.v$ \code{=} $e_2$.
+. The static type of $a$ is the static type of $e_2$. Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static warnings that would be caused by $y.v = e_2$ are also generated in the case of $e_1?.v$ \code{=} $e_2$.
\LMHash{}
Evaluation of an assignment of the form $e_1.v$ \code{=} $e_2$ proceeds as follows:
@@ -4543,18 +4547,31 @@
\LMLabel{compoundAssignment}
\LMHash{}
-Evaluation of a compound assignment of the form $v$ {\em ??=} $e$ is equivalent to the evaluation of the expression $((x) => x == \NULL{}$ ? $v=e : x)(v)$ where $x$ is a fresh variable that is not used in $e$. Evaluation of a compound assignment of the form $C.v$ {\em ??=} $e$, where $C$ is a type literal, is equivalent to the evaluation of the expression $((x) => x == \NULL{}$? $C.v=e: x)(C.v)$ where $x$ is a fresh variable that is not used in $e$.
+Evaluation of a compound assignment of the form $v$ {\em ??=} $e$ is equivalent to the evaluation of the expression $((x) => x == \NULL{}$ ? $v=e : x)(v)$ where $x$ is a fresh variable that is not used in $e$.
+
+\LMHash{}
+Evaluation of a compound assignment of the form $C.v$ {\em ??=} $e$, where $C$ is a type literal, is equivalent to the evaluation of the expression $((x) => x == \NULL{}$? $C.v=e: x)(C.v)$ where $x$ is a fresh variable that is not used in $e$.
\commentary {
The two rules above also apply when the variable v or the type C is prefixed.
}
-Evaluation of a compound assignment of the form $e_1.v$ {\em ??=} $e_2$ is equivalent to the evaluation of the expression $((x) =>((y) => y == \NULL{}$ ? $ x.v = e_2: y)(x.v))(e_1)$ where $x$ and $y$ are distinct fresh variables that are not used in $e_2$. Evaluation of a compound assignment of the form $e_1[e_2]$ {\em ??=} $e_3$ is equivalent to the evaluation of the expression
-$((a, i) => ((x) => x == \NULL{}$ ? $a[i] = e_3: x)(a[i]))(e_1, e_2)$ where $x$, $a$ and $i$ are distinct fresh variables that are not used in $e_3$. Evaluation of a compound assignment of the form $\SUPER.v$ {\em ??=} $e$ is equivalent to the evaluation of the expression $((x) => x == \NULL{}$ ? $\SUPER.v = e: x)(\SUPER.v)$ where $x$ is a fresh variable that is not used in $e$.
+\LMHash{}
+Evaluation of a compound assignment of the form $e_1.v$ {\em ??=} $e_2$ is equivalent to the evaluation of the expression $((x) =>((y) => y == \NULL{}$ ? $ x.v = e_2: y)(x.v))(e_1)$ where $x$ and $y$ are distinct fresh variables that are not used in $e_2$.
+
+\LMHash{}
+Evaluation of a compound assignment of the form $e_1[e_2]$ {\em ??=} $e_3$ is equivalent to the evaluation of the expression
+$((a, i) => ((x) => x == \NULL{}$ ? $a[i] = e_3: x)(a[i]))(e_1, e_2)$ where $x$, $a$ and $i$ are distinct fresh variables that are not used in $e_3$.
+
+\LMHash{}
+Evaluation of a compound assignment of the form $\SUPER.v$ {\em ??=} $e$ is equivalent to the evaluation of the expression $((x) => x == \NULL{}$ ? $\SUPER.v = e: x)(\SUPER.v)$ where $x$ is a fresh variable that is not used in $e$.
\LMHash{}
Evaluation of a compound assignment of the form $e_1?.v$ {\em ??=} $e_2$ is equivalent to the evaluation of the expression \code{((x) $=>$ x == \NULL{} ? \NULL: $x.v ??= e_2$)($e_1$)} where $x$ is a variable that is not used in $e_2$.
+% But what about C?.v ??= e
+\LMHash{}
+A compound assignment of the form $C?.v$ {\em ??=} $e_2$ is equivalent to the expression $C.v$ {\em ??=} $e$.
\LMHash{}
The static type of a compound assignment of the form $v$ {\em ??=} $e$ is the least upper bound of the static type of $v$ and the static type of $e$. Exactly the same static warnings that would be caused by $v = e$ are also generated in the case of $v$ {\em ??=} $e$.
@@ -4579,7 +4596,9 @@
\LMHash{}
Evaluation of a compound assignment of the form $e_1?.v$ $op = e_2$ is equivalent to \code{((x) $=>$ x?.v = x.v $op$ $e_2$)($e_1$)} where $x$ is a variable that is not used in $e_2$. The static type of $e_1?.v$ $op = e_2$ is the static type of $e_1.v$ $op$ $e_2$. Exactly the same static warnings that would be caused by $e_1.v$ $op = e_2$ are also generated in the case of $e_1?.v$ $op = e_2$.
-% Buggy. Allows C?.v = e.
+\LMHash{}
+A compound assignment of the form $C?.v$ $op = e_2$ is equivalent to the expression
+$C.v$ $op = e_2$.
\begin{grammar}
{\bf compoundAssignmentOperator:}`*=';
@@ -5088,7 +5107,9 @@
\LMHash{}
Execution of a postfix expression of the form \code{$e_1?.v$++} is equivalent to executing
-\code{((x) =$>$ x == \NULL? \NULL : x.v++)($e_1$)}.
+\code{((x) =$>$ x == \NULL? \NULL : x.v++)($e_1$)}
+unless $e_1$ is a type literal, in which case it is equivalent to \code{$e_1.v$++}
+.
\LMHash{}
The static type of such an expression is the static type of $e_1.v$.
@@ -5096,7 +5117,9 @@
\LMHash{}
Execution of a postfix expression of the form \code{$e_1?.v$-{}-} is equivalent to executing
-\code{((x) =$>$ x == \NULL? \NULL : x.v-{}-)($e_1$)}.
+\code{((x) =$>$ x == \NULL? \NULL : x.v-{}-)($e_1$)}
+unless $e_1$ is a type literal, in which case it is equivalent to \code{$e_1.v$-{}-}
+.
\LMHash{}
The static type of such an expression is the static type of $e_1.v$.
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index d42eb49..db15b5f 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -6,6 +6,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:core' hide Resource;
import 'dart:math' show max;
import 'package:analysis_server/plugin/analyzed_files.dart';
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index c397a80..275df09 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -6,6 +6,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:core' hide Resource;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/source/optimizing_pub_package_map_provider.dart';
@@ -477,9 +478,14 @@
info.changeSubscription = folder.changes.listen((WatchEvent event) {
_handleWatchEvent(folder, info, event);
});
- UriResolver packageUriResolver = _computePackageUriResolver(folder, info);
- info.context = addContext(folder, packageUriResolver);
- info.context.name = folder.path;
+ try {
+ UriResolver packageUriResolver = _computePackageUriResolver(folder, info);
+ info.context = addContext(folder, packageUriResolver);
+ info.context.name = folder.path;
+ } catch (_) {
+ info.changeSubscription.cancel();
+ rethrow;
+ }
return info;
}
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 773af6e..fd32646 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -5,6 +5,7 @@
library domain.analysis;
import 'dart:async';
+import 'dart:core' hide Resource;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/computer/computer_hover.dart';
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index 2b5e4f5..1d9c2dd 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -6,6 +6,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:core' hide Resource;
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/constants.dart';
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index e58a19f..3372933 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -10,6 +10,8 @@
import 'package:analysis_server/src/channel/web_socket_channel.dart';
import 'package:analysis_server/src/get_handler.dart';
import 'package:analysis_server/src/socket_server.dart';
+import 'package:analysis_server/src/status/get_handler.dart' as newHandler;
+import 'package:analyzer/src/generated/engine.dart';
/**
* Instances of the class [HttpServer] implement a simple HTTP server. The
@@ -34,6 +36,11 @@
GetHandler getHandler;
/**
+ * An object that can handle GET requests when the new task model is in use.
+ */
+ newHandler.GetHandler newGetHandler;
+
+ /**
* Future that is completed with the HTTP server once it is running.
*/
Future<HttpServer> _server;
@@ -77,10 +84,17 @@
* Handle a GET request received by the HTTP server.
*/
void _handleGetRequest(HttpRequest request) {
- if (getHandler == null) {
- getHandler = new GetHandler(socketServer, _printBuffer);
+ if (AnalysisEngine.instance.useTaskModel) {
+ if (newGetHandler == null) {
+ newGetHandler = new newHandler.GetHandler(socketServer, _printBuffer);
+ }
+ newGetHandler.handleGetRequest(request);
+ } else {
+ if (getHandler == null) {
+ getHandler = new GetHandler(socketServer, _printBuffer);
+ }
+ getHandler.handleGetRequest(request);
}
- getHandler.handleGetRequest(request);
}
/**
diff --git a/pkg/analysis_server/lib/src/services/completion/import_uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/import_uri_contributor.dart
index 0d56e98..574931b 100644
--- a/pkg/analysis_server/lib/src/services/completion/import_uri_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/import_uri_contributor.dart
@@ -6,6 +6,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:core' hide Resource;
import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
import 'package:analyzer/file_system/file_system.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index 654fc4f..849b9e1 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -5,6 +5,7 @@
library services.src.refactoring.move_file;
import 'dart:async';
+import 'dart:core' hide Resource;
import 'package:analysis_server/src/protocol_server.dart' hide Element;
import 'package:analysis_server/src/services/correction/status.dart';
diff --git a/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart b/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart
index f6c9bb7..3d99622 100644
--- a/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart
+++ b/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart
@@ -5,6 +5,7 @@
library source.caching_pub_package_map_provider;
import 'dart:convert';
+import 'dart:core' hide Resource;
import 'dart:io' as io;
import 'package:analyzer/file_system/file_system.dart';
diff --git a/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart b/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart
index ccda5f9..deeee77 100644
--- a/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart
+++ b/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart
@@ -4,6 +4,8 @@
library source.optimizing_pub_package_map_provider;
+import 'dart:core' hide Resource;
+
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/package_map_provider.dart';
import 'package:analyzer/source/pub_package_map_provider.dart';
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
new file mode 100644
index 0000000..01a330a
--- /dev/null
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -0,0 +1,1678 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analysis_server.src.status.get_handler;
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math';
+
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/domain_execution.dart';
+import 'package:analysis_server/src/operation/operation.dart';
+import 'package:analysis_server/src/operation/operation_analysis.dart';
+import 'package:analysis_server/src/operation/operation_queue.dart';
+import 'package:analysis_server/src/protocol.dart' hide Element;
+import 'package:analysis_server/src/services/index/index.dart';
+import 'package:analysis_server/src/services/index/local_index.dart';
+import 'package:analysis_server/src/services/index/store/split_store.dart';
+import 'package:analysis_server/src/socket_server.dart';
+import 'package:analysis_server/src/status/ast_writer.dart';
+import 'package:analysis_server/src/status/element_writer.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart'
+ hide AnalysisContextImpl, AnalysisTask;
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:plugin/plugin.dart';
+
+/**
+ * A function that can be used to generate HTML output into the given [buffer].
+ * The HTML that is generated must be valid (special characters must already be
+ * encoded).
+ */
+typedef void HtmlGenerator(StringBuffer buffer);
+
+/**
+ * Instances of the class [GetHandler] handle GET requests.
+ */
+class GetHandler {
+ /**
+ * The path used to request overall performance information.
+ */
+ static const String ANALYSIS_PERFORMANCE_PATH = '/perf/analysis';
+
+ /**
+ * The path used to request information about a element model.
+ */
+ static const String AST_PATH = '/ast';
+
+ /**
+ * The path used to request information about the cache entry corresponding
+ * to a single file.
+ */
+ static const String CACHE_ENTRY_PATH = '/cache_entry';
+
+ /**
+ * The path used to request the list of source files in a certain cache
+ * state.
+ */
+ static const String CACHE_STATE_PATH = '/cache_state';
+
+ /**
+ * The path used to request code completion information.
+ */
+ static const String COMPLETION_PATH = '/completion';
+
+ /**
+ * The path used to request communication performance information.
+ */
+ static const String COMMUNICATION_PERFORMANCE_PATH = '/perf/communication';
+
+ /**
+ * The path used to request information about a specific context.
+ */
+ static const String CONTEXT_PATH = '/context';
+
+ /**
+ * The path used to request information about a element model.
+ */
+ static const String ELEMENT_PATH = '/element';
+
+ /**
+ * The path used to request information about elements with the given name.
+ */
+ static const String INDEX_ELEMENT_BY_NAME = '/index/element-by-name';
+
+ /**
+ * The path used to request an overlay contents.
+ */
+ static const String OVERLAY_PATH = '/overlay';
+
+ /**
+ * The path used to request overlays information.
+ */
+ static const String OVERLAYS_PATH = '/overlays';
+
+ /**
+ * The path used to request the status of the analysis server as a whole.
+ */
+ static const String STATUS_PATH = '/status';
+
+ /**
+ * Query parameter used to represent the context to search for, when
+ * accessing [CACHE_ENTRY_PATH] or [CACHE_STATE_PATH].
+ */
+ static const String CONTEXT_QUERY_PARAM = 'context';
+
+ /**
+ * Query parameter used to represent the descriptor to search for, when
+ * accessing [CACHE_STATE_PATH].
+ */
+ static const String DESCRIPTOR_QUERY_PARAM = 'descriptor';
+
+ /**
+ * Query parameter used to represent the name of elements to search for, when
+ * accessing [INDEX_ELEMENT_BY_NAME].
+ */
+ static const String INDEX_ELEMENT_NAME = 'name';
+
+ /**
+ * Query parameter used to represent the path of an overlayed file.
+ */
+ static const String PATH_PARAM = 'path';
+
+ /**
+ * Query parameter used to represent the source to search for, when accessing
+ * [CACHE_ENTRY_PATH].
+ */
+ static const String SOURCE_QUERY_PARAM = 'entry';
+
+ /**
+ * Query parameter used to represent the cache state to search for, when
+ * accessing [CACHE_STATE_PATH].
+ */
+ static const String STATE_QUERY_PARAM = 'state';
+
+ static final ContentType _htmlContent =
+ new ContentType("text", "html", charset: "utf-8");
+
+ /**
+ * The socket server whose status is to be reported on.
+ */
+ SocketServer _server;
+
+ /**
+ * Buffer containing strings printed by the analysis server.
+ */
+ List<String> _printBuffer;
+
+ /**
+ * Contents of overlay files.
+ */
+ final Map<String, String> _overlayContents = <String, String>{};
+
+ /**
+ * Initialize a newly created handler for GET requests.
+ */
+ GetHandler(this._server, this._printBuffer);
+
+ /**
+ * Return the active [CompletionDomainHandler]
+ * or `null` if either analysis server is not running
+ * or there is no completion domain handler.
+ */
+ CompletionDomainHandler get _completionDomainHandler {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return null;
+ }
+ return analysisServer.handlers.firstWhere(
+ (h) => h is CompletionDomainHandler, orElse: () => null);
+ }
+
+ /**
+ * Handle a GET request received by the HTTP server.
+ */
+ void handleGetRequest(HttpRequest request) {
+ String path = request.uri.path;
+ if (path == STATUS_PATH) {
+ _returnServerStatus(request);
+ } else if (path == ANALYSIS_PERFORMANCE_PATH) {
+ _returnAnalysisPerformance(request);
+ } else if (path == AST_PATH) {
+ _returnAst(request);
+ } else if (path == CACHE_STATE_PATH) {
+ _returnCacheState(request);
+ } else if (path == CACHE_ENTRY_PATH) {
+ _returnCacheEntry(request);
+ } else if (path == COMPLETION_PATH) {
+ _returnCompletionInfo(request);
+ } else if (path == COMMUNICATION_PERFORMANCE_PATH) {
+ _returnCommunicationPerformance(request);
+ } else if (path == CONTEXT_PATH) {
+ _returnContextInfo(request);
+ } else if (path == ELEMENT_PATH) {
+ _returnElement(request);
+ } else if (path == INDEX_ELEMENT_BY_NAME) {
+ _returnIndexElementByName(request);
+ } else if (path == OVERLAY_PATH) {
+ _returnOverlayContents(request);
+ } else if (path == OVERLAYS_PATH) {
+ _returnOverlaysInfo(request);
+ } else {
+ _returnUnknownRequest(request);
+ }
+ }
+
+ /**
+ * Return the folder being managed by the given [analysisServer] that matches
+ * the given [contextFilter], or `null` if there is none.
+ */
+ Folder _findFolder(AnalysisServer analysisServer, String contextFilter) {
+ return analysisServer.folderMap.keys.firstWhere(
+ (Folder folder) => folder.path == contextFilter, orElse: () => null);
+ }
+
+ /**
+ * Return any AST structure stored in the given [entry].
+ */
+ CompilationUnit _getAnyAst(CacheEntry entry) {
+ CompilationUnit unit = entry.getValue(PARSED_UNIT);
+ if (unit != null) {
+ return unit;
+ }
+ unit = entry.getValue(RESOLVED_UNIT1);
+ if (unit != null) {
+ return unit;
+ }
+ unit = entry.getValue(RESOLVED_UNIT2);
+ if (unit != null) {
+ return unit;
+ }
+ unit = entry.getValue(RESOLVED_UNIT3);
+ if (unit != null) {
+ return unit;
+ }
+ unit = entry.getValue(RESOLVED_UNIT4);
+ if (unit != null) {
+ return unit;
+ }
+ unit = entry.getValue(RESOLVED_UNIT5);
+ if (unit != null) {
+ return unit;
+ }
+ return entry.getValue(RESOLVED_UNIT);
+ }
+
+ /**
+ * Return `true` if the given analysis [context] has at least one entry with
+ * an exception.
+ */
+ bool _hasException(InternalAnalysisContext context) {
+ MapIterator<AnalysisTarget, CacheEntry> iterator =
+ context.analysisCache.iterator();
+ while (iterator.moveNext()) {
+ if (iterator.value.exception != null) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the folder in the [folderMap] with which the given [context] is
+ * associated.
+ */
+ Folder _keyForValue(
+ Map<Folder, AnalysisContext> folderMap, AnalysisContext context) {
+ for (Folder folder in folderMap.keys) {
+ if (folderMap[folder] == context) {
+ return folder;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return a response displaying overall performance information.
+ */
+ void _returnAnalysisPerformance(HttpRequest request) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server is not running');
+ }
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Analysis Performance', [],
+ (StringBuffer buffer) {
+ buffer.write('<h3>Analysis Performance</h3>');
+
+ //
+ // Write performance tags.
+ //
+ {
+ buffer.write('<p><b>Time spent in each phase of analysis</b></p>');
+ buffer.write(
+ '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
+ _writeRow(buffer, ['Time (in ms)', 'Percent', 'Analysis Phase'],
+ header: true);
+ // prepare sorted tags
+ List<PerformanceTag> tags = PerformanceTag.all.toList();
+ tags.remove(ServerPerformanceStatistics.idle);
+ tags.sort((a, b) => b.elapsedMs - a.elapsedMs);
+ // prepare total time
+ int totalTime = 0;
+ tags.forEach((PerformanceTag tag) {
+ totalTime += tag.elapsedMs;
+ });
+ // write rows
+ void writeRow(PerformanceTag tag) {
+ double percent = (tag.elapsedMs * 100) / totalTime;
+ String percentStr = '${percent.toStringAsFixed(2)}%';
+ _writeRow(buffer, [tag.elapsedMs, percentStr, tag.label],
+ classes: ["right", "right", null]);
+ }
+ tags.forEach(writeRow);
+ buffer.write('</table>');
+ }
+
+ //
+ // Write new task model timing information.
+ //
+ if (AnalysisEngine.instance.useTaskModel) {
+ buffer.write('<p><b>Task performace data</b></p>');
+ buffer.write(
+ '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
+ _writeRow(buffer, [
+ 'Task Name',
+ 'Count',
+ 'Total Time (in ms)',
+ 'Average Time (in ms)'
+ ], header: true);
+
+ Map<Type, int> countMap = AnalysisTask.countMap;
+ Map<Type, Stopwatch> stopwatchMap = AnalysisTask.stopwatchMap;
+ List<Type> taskClasses = stopwatchMap.keys.toList();
+ taskClasses.sort((Type first, Type second) =>
+ first.toString().compareTo(second.toString()));
+ int totalTime = 0;
+ taskClasses.forEach((Type taskClass) {
+ int count = countMap[taskClass];
+ if (count == null) {
+ count = 0;
+ }
+ int taskTime = stopwatchMap[taskClass].elapsedMilliseconds;
+ totalTime += taskTime;
+ _writeRow(buffer, [
+ taskClass.toString(),
+ count,
+ taskTime,
+ count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3)
+ ], classes: [null, "right", "right", "right"]);
+ });
+ _writeRow(buffer, ['Total', '-', totalTime, '-'],
+ classes: [null, "right", "right", "right"]);
+ buffer.write('</table>');
+ }
+
+ //
+ // Write old task model transition information.
+ //
+ {
+ Map<DataDescriptor, Map<CacheState, int>> transitionMap =
+ SourceEntry.transitionMap;
+ buffer.write(
+ '<p><b>Number of times a state transitioned to VALID (grouped by descriptor)</b></p>');
+ if (transitionMap.isEmpty) {
+ buffer.write('<p>none</p>');
+ } else {
+ List<DataDescriptor> descriptors = transitionMap.keys.toList();
+ descriptors.sort((DataDescriptor first, DataDescriptor second) =>
+ first.toString().compareTo(second.toString()));
+ for (DataDescriptor key in descriptors) {
+ Map<CacheState, int> countMap = transitionMap[key];
+ List<CacheState> oldStates = countMap.keys.toList();
+ oldStates.sort((CacheState first, CacheState second) =>
+ first.toString().compareTo(second.toString()));
+ buffer.write('<p>${key.toString()}</p>');
+ buffer.write(
+ '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
+ _writeRow(buffer, ['Count', 'Previous State'], header: true);
+ for (CacheState state in oldStates) {
+ _writeRow(buffer, [countMap[state], state.toString()],
+ classes: ["right", null]);
+ }
+ buffer.write('</table>');
+ }
+ }
+ }
+ });
+ });
+ }
+
+ /**
+ * Return a response containing information about an AST structure.
+ */
+ void _returnAst(HttpRequest request) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server not running');
+ }
+ String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+ if (contextFilter == null) {
+ return _returnFailure(
+ request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+ }
+ Folder folder = _findFolder(analysisServer, contextFilter);
+ if (folder == null) {
+ return _returnFailure(request, 'Invalid context: $contextFilter');
+ }
+ String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
+ if (sourceUri == null) {
+ return _returnFailure(
+ request, 'Query parameter $SOURCE_QUERY_PARAM required');
+ }
+
+ InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - AST Structure', [
+ 'Context: $contextFilter',
+ 'File: $sourceUri'
+ ], (HttpResponse) {
+ Source source = context.sourceFactory.forUri(sourceUri);
+ if (source == null) {
+ buffer.write('<p>Not found.</p>');
+ return;
+ }
+ CacheEntry entry = context.analysisCache.get(source);
+ if (entry == null) {
+ buffer.write('<p>Not found.</p>');
+ return;
+ }
+ CompilationUnit ast = _getAnyAst(entry);
+ if (ast == null) {
+ buffer.write('<p>null</p>');
+ return;
+ }
+ AstWriter writer = new AstWriter(buffer);
+ ast.accept(writer);
+ if (writer.exceptions.isNotEmpty) {
+ buffer.write('<h3>Exceptions while creating page</h3>');
+ for (CaughtException exception in writer.exceptions) {
+ _writeException(buffer, exception);
+ }
+ }
+ });
+ });
+ }
+
+ /**
+ * Return a response containing information about a single source file in the
+ * cache.
+ */
+ void _returnCacheEntry(HttpRequest request) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server not running');
+ }
+ String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+ if (contextFilter == null) {
+ return _returnFailure(
+ request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+ }
+ Folder folder = _findFolder(analysisServer, contextFilter);
+ if (folder == null) {
+ return _returnFailure(request, 'Invalid context: $contextFilter');
+ }
+ String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
+ if (sourceUri == null) {
+ return _returnFailure(
+ request, 'Query parameter $SOURCE_QUERY_PARAM required');
+ }
+
+ List<Folder> allContexts = <Folder>[];
+ Map<Folder, List<CacheEntry>> entryMap =
+ new HashMap<Folder, List<CacheEntry>>();
+ analysisServer.folderMap
+ .forEach((Folder folder, InternalAnalysisContext context) {
+ Source source = context.sourceFactory.forUri(sourceUri);
+ if (source != null) {
+ MapIterator<AnalysisTarget, CacheEntry> iterator =
+ context.analysisCache.iterator();
+ while (iterator.moveNext()) {
+ if (source == iterator.key.source) {
+ if (!allContexts.contains(folder)) {
+ allContexts.add(folder);
+ }
+ List<CacheEntry> entries = entryMap[folder];
+ if (entries == null) {
+ entries = <CacheEntry>[];
+ entryMap[folder] = entries;
+ }
+ entries.add(iterator.value);
+ }
+ }
+ }
+ });
+ allContexts.sort((Folder firstFolder, Folder secondFolder) =>
+ firstFolder.path.compareTo(secondFolder.path));
+ InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Cache Entry', [
+ 'Context: $contextFilter',
+ 'File: $sourceUri'
+ ], (HttpResponse) {
+ buffer.write('<h3>Analyzing Contexts</h3><p>');
+ bool first = true;
+ allContexts.forEach((Folder folder) {
+ if (first) {
+ first = false;
+ } else {
+ buffer.write('<br>');
+ }
+ InternalAnalysisContext analyzingContext =
+ analysisServer.folderMap[folder];
+ if (analyzingContext == context) {
+ buffer.write(folder.path);
+ } else {
+ buffer.write(makeLink(CACHE_ENTRY_PATH, {
+ CONTEXT_QUERY_PARAM: folder.path,
+ SOURCE_QUERY_PARAM: sourceUri
+ }, HTML_ESCAPE.convert(folder.path)));
+ }
+ if (entryMap[folder][0].explicitlyAdded) {
+ buffer.write(' (explicit)');
+ } else {
+ buffer.write(' (implicit)');
+ }
+ });
+ buffer.write('</p>');
+
+ List<CacheEntry> entries = entryMap[folder];
+ if (entries == null) {
+ buffer.write('<p>Not being analyzed in this context.</p>');
+ return;
+ }
+ for (CacheEntry entry in entries) {
+ Map<String, String> linkParameters = <String, String>{
+ CONTEXT_QUERY_PARAM: folder.path,
+ SOURCE_QUERY_PARAM: sourceUri
+ };
+ List<ResultDescriptor> results = entry.nonInvalidResults;
+ results.sort((ResultDescriptor first, ResultDescriptor second) =>
+ first.toString().compareTo(second.toString()));
+
+ buffer.write('<h3>');
+ buffer.write(HTML_ESCAPE.convert(entry.target.toString()));
+ buffer.write('</h3>');
+ buffer.write('<dl>');
+ buffer.write('<dt>time</dt><dd>');
+ buffer.write(entry.modificationTime);
+ buffer.write('</dd></dl>');
+ for (ResultDescriptor result in results) {
+ ResultData data = entry.getResultData(result);
+ String descriptorName = HTML_ESCAPE.convert(result.toString());
+ String descriptorState = HTML_ESCAPE.convert(data.state.toString());
+ buffer.write('<dt>$descriptorName ($descriptorState)</dt><dd>');
+ try {
+ _writeValueAsHtml(buffer, data.value, linkParameters);
+ } catch (exception) {
+ buffer.write('(${HTML_ESCAPE.convert(exception.toString())})');
+ }
+ buffer.write('</dd>');
+ }
+ if (entry.exception != null) {
+ buffer.write('<dt>exception</dt><dd>');
+ _writeException(buffer, entry.exception);
+ buffer.write('</dd></dl>');
+ }
+ buffer.write('</dl>');
+ }
+ });
+ });
+ }
+
+ /**
+ * Return a response indicating the set of source files in a certain cache
+ * state.
+ */
+ void _returnCacheState(HttpRequest request) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server not running');
+ }
+ // Figure out which context is being searched within.
+ String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+ if (contextFilter == null) {
+ return _returnFailure(
+ request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+ }
+ // Figure out what CacheState is being searched for.
+ String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM];
+ if (stateQueryParam == null) {
+ return _returnFailure(
+ request, 'Query parameter $STATE_QUERY_PARAM required');
+ }
+ CacheState stateFilter = null;
+ for (CacheState value in CacheState.values) {
+ if (value.toString() == stateQueryParam) {
+ stateFilter = value;
+ }
+ }
+ if (stateFilter == null) {
+ return _returnFailure(
+ request, 'Query parameter $STATE_QUERY_PARAM is invalid');
+ }
+ // Figure out which descriptor is being searched for.
+ String descriptorFilter =
+ request.uri.queryParameters[DESCRIPTOR_QUERY_PARAM];
+ if (descriptorFilter == null) {
+ return _returnFailure(
+ request, 'Query parameter $DESCRIPTOR_QUERY_PARAM required');
+ }
+
+ // TODO(brianwilkerson) Figure out how to convert the 'descriptorFilter' to
+ // a ResultDescriptor so that we can query the state, then uncomment the
+ // code below that computes and prints the list of links.
+// Folder folder = _findFolder(analysisServer, contextFilter);
+// InternalAnalysisContext context = analysisServer.folderMap[folder];
+// List<String> links = <String>[];
+// MapIterator<AnalysisTarget, CacheEntry> iterator = context.analysisCache.iterator();
+// while (iterator.moveNext()) {
+// Source source = iterator.key.source;
+// if (source != null) {
+// CacheEntry entry = iterator.value;
+// if (entry.getState(result) == stateFilter) {
+// String link = makeLink(CACHE_ENTRY_PATH, {
+// CONTEXT_QUERY_PARAM: folder.path,
+// SOURCE_QUERY_PARAM: source.uri.toString()
+// }, HTML_ESCAPE.convert(source.fullName));
+// links.add(link);
+// }
+// }
+// }
+
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Cache Search', [
+ 'Context: $contextFilter',
+ 'Descriptor: ${HTML_ESCAPE.convert(descriptorFilter)}',
+ 'State: ${HTML_ESCAPE.convert(stateQueryParam)}'
+ ], (StringBuffer buffer) {
+ buffer.write('<p>Cache search is not yet implemented.</p>');
+// buffer.write('<p>${links.length} files found</p>');
+// buffer.write('<ul>');
+// links.forEach((String link) {
+// buffer.write('<li>$link</li>');
+// });
+// buffer.write('</ul>');
+ });
+ });
+ }
+
+ /**
+ * Return a response displaying overall performance information.
+ */
+ void _returnCommunicationPerformance(HttpRequest request) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server is not running');
+ }
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Communication Performance', [],
+ (StringBuffer buffer) {
+ buffer.write('<h3>Communication Performance</h3>');
+ _writeTwoColumns(buffer, (StringBuffer buffer) {
+ ServerPerformance perf = analysisServer.performanceDuringStartup;
+ int requestCount = perf.requestCount;
+ num averageLatency = requestCount > 0
+ ? (perf.requestLatency / requestCount).round()
+ : 0;
+ int maximumLatency = perf.maxLatency;
+ num slowRequestPercent = requestCount > 0
+ ? (perf.slowRequestCount * 100 / requestCount).round()
+ : 0;
+ buffer.write('<h4>Startup</h4>');
+ buffer.write('<table>');
+ _writeRow(buffer, [requestCount, 'requests'],
+ classes: ["right", null]);
+ _writeRow(buffer, [averageLatency, 'ms average latency'],
+ classes: ["right", null]);
+ _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
+ classes: ["right", null]);
+ _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
+ classes: ["right", null]);
+ if (analysisServer.performanceAfterStartup != null) {
+ int startupTime = analysisServer.performanceAfterStartup.startTime -
+ perf.startTime;
+ _writeRow(
+ buffer, [startupTime, 'ms for initial analysis to complete']);
+ }
+ buffer.write('</table>');
+ }, (StringBuffer buffer) {
+ ServerPerformance perf = analysisServer.performanceAfterStartup;
+ if (perf == null) {
+ return;
+ }
+ int requestCount = perf.requestCount;
+ num averageLatency = requestCount > 0
+ ? (perf.requestLatency * 10 / requestCount).round() / 10
+ : 0;
+ int maximumLatency = perf.maxLatency;
+ num slowRequestPercent = requestCount > 0
+ ? (perf.slowRequestCount * 100 / requestCount).round()
+ : 0;
+ buffer.write('<h4>Current</h4>');
+ buffer.write('<table>');
+ _writeRow(buffer, [requestCount, 'requests'],
+ classes: ["right", null]);
+ _writeRow(buffer, [averageLatency, 'ms average latency'],
+ classes: ["right", null]);
+ _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
+ classes: ["right", null]);
+ _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
+ classes: ["right", null]);
+ buffer.write('</table>');
+ });
+ });
+ });
+ }
+
+ /**
+ * Return a response displaying code completion information.
+ */
+ void _returnCompletionInfo(HttpRequest request) {
+ String value = request.requestedUri.queryParameters['index'];
+ int index = value != null ? int.parse(value, onError: (_) => 0) : 0;
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Completion Stats', [],
+ (StringBuffer buffer) {
+ _writeCompletionPerformanceDetail(buffer, index);
+ _writeCompletionPerformanceList(buffer);
+ });
+ });
+ }
+
+ /**
+ * Return a response containing information about a single source file in the
+ * cache.
+ */
+ void _returnContextInfo(HttpRequest request) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server not running');
+ }
+ String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+ if (contextFilter == null) {
+ return _returnFailure(
+ request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+ }
+ Folder folder = _findFolder(analysisServer, contextFilter);
+ if (folder == null) {
+ return _returnFailure(request, 'Invalid context: $contextFilter');
+ }
+
+ List<String> priorityNames;
+ List<String> explicitNames = <String>[];
+ List<String> implicitNames = <String>[];
+ Map<String, String> links = new HashMap<String, String>();
+ List<CaughtException> exceptions = <CaughtException>[];
+ InternalAnalysisContext context = analysisServer.folderMap[folder];
+ priorityNames = context.prioritySources
+ .map((Source source) => source.fullName)
+ .toList();
+ MapIterator<AnalysisTarget, CacheEntry> iterator =
+ context.analysisCache.iterator();
+ while (iterator.moveNext()) {
+ Source source = iterator.key.source;
+ if (source != null) {
+ CacheEntry entry = iterator.value;
+ String sourceName = source.fullName;
+ if (!links.containsKey(sourceName)) {
+ CaughtException exception = entry.exception;
+ if (exception != null) {
+ exceptions.add(exception);
+ }
+ String link = makeLink(CACHE_ENTRY_PATH, {
+ CONTEXT_QUERY_PARAM: folder.path,
+ SOURCE_QUERY_PARAM: source.uri.toString()
+ }, sourceName, exception != null);
+ if (entry.explicitlyAdded) {
+ explicitNames.add(sourceName);
+ } else {
+ implicitNames.add(sourceName);
+ }
+ links[sourceName] = link;
+ }
+ }
+ }
+ explicitNames.sort();
+ implicitNames.sort();
+
+ _overlayContents.clear();
+ context.visitContentCache((String fullName, int stamp, String contents) {
+ _overlayContents[fullName] = contents;
+ });
+
+ void _writeFiles(
+ StringBuffer buffer, String title, List<String> fileNames) {
+ buffer.write('<h3>$title</h3>');
+ if (fileNames == null || fileNames.isEmpty) {
+ buffer.write('<p>None</p>');
+ } else {
+ buffer.write('<table style="width: 100%">');
+ for (String fileName in fileNames) {
+ buffer.write('<tr><td>');
+ buffer.write(links[fileName]);
+ buffer.write('</td><td>');
+ if (_overlayContents.containsKey(fileName)) {
+ buffer.write(
+ makeLink(OVERLAY_PATH, {PATH_PARAM: fileName}, 'overlay'));
+ }
+ buffer.write('</td></tr>');
+ }
+ buffer.write('</table>');
+ }
+ }
+
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Context',
+ ['Context: $contextFilter'], (StringBuffer buffer) {
+ List headerRowText = ['Context'];
+ headerRowText.addAll(CacheState.values);
+ buffer.write('<h3>Summary</h3>');
+ buffer.write('<table>');
+ _writeRow(buffer, headerRowText, header: true);
+ AnalysisContextStatistics statistics = context.statistics;
+ statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
+ List rowText = [row.name];
+ for (CacheState state in CacheState.values) {
+ String text = row.getCount(state).toString();
+ Map<String, String> params = <String, String>{
+ STATE_QUERY_PARAM: state.toString(),
+ CONTEXT_QUERY_PARAM: folder.path,
+ DESCRIPTOR_QUERY_PARAM: row.name
+ };
+ rowText.add(makeLink(CACHE_STATE_PATH, params, text));
+ }
+ _writeRow(buffer, rowText, classes: [null, "right"]);
+ });
+ buffer.write('</table>');
+
+ _writeFiles(buffer, 'Priority Files', priorityNames);
+ _writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames);
+ _writeFiles(buffer, 'Implicitly Analyzed Files', implicitNames);
+
+ buffer.write('<h3>Exceptions</h3>');
+ if (exceptions.isEmpty) {
+ buffer.write('<p>None</p>');
+ } else {
+ exceptions.forEach((CaughtException exception) {
+ _writeException(buffer, exception);
+ });
+ }
+ });
+ });
+ }
+
+ /**
+ * Return a response containing information about an element structure.
+ */
+ void _returnElement(HttpRequest request) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server not running');
+ }
+ String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+ if (contextFilter == null) {
+ return _returnFailure(
+ request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+ }
+ Folder folder = _findFolder(analysisServer, contextFilter);
+ if (folder == null) {
+ return _returnFailure(request, 'Invalid context: $contextFilter');
+ }
+ String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
+ if (sourceUri == null) {
+ return _returnFailure(
+ request, 'Query parameter $SOURCE_QUERY_PARAM required');
+ }
+
+ InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Element Model', [
+ 'Context: $contextFilter',
+ 'File: $sourceUri'
+ ], (StringBuffer buffer) {
+ Source source = context.sourceFactory.forUri(sourceUri);
+ if (source == null) {
+ buffer.write('<p>Not found.</p>');
+ return;
+ }
+ CacheEntry entry = context.analysisCache.get(source);
+ if (entry == null) {
+ buffer.write('<p>Not found.</p>');
+ return;
+ }
+ LibraryElement element = entry.getValue(LIBRARY_ELEMENT);
+ if (element == null) {
+ buffer.write('<p>null</p>');
+ return;
+ }
+ element.accept(new ElementWriter(buffer));
+ });
+ });
+ }
+
+ void _returnFailure(HttpRequest request, String message) {
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Failure', [],
+ (StringBuffer buffer) {
+ buffer.write(HTML_ESCAPE.convert(message));
+ });
+ });
+ }
+
+ /**
+ * Return a response containing information about elements with the given
+ * name.
+ */
+ Future _returnIndexElementByName(HttpRequest request) async {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server not running');
+ }
+ Index index = analysisServer.index;
+ if (index == null) {
+ return _returnFailure(request, 'Indexing is disabled');
+ }
+ String name = request.uri.queryParameters[INDEX_ELEMENT_NAME];
+ if (name == null) {
+ return _returnFailure(
+ request, 'Query parameter $INDEX_ELEMENT_NAME required');
+ }
+ if (index is LocalIndex) {
+ Map<List<String>, List<InspectLocation>> relations =
+ await index.findElementsByName(name);
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Index Elements', ['Name: $name'],
+ (StringBuffer buffer) {
+ buffer.write('<table border="1">');
+ _writeRow(buffer, ['Element', 'Relationship', 'Location'],
+ header: true);
+ relations.forEach((List<String> elementPath,
+ List<InspectLocation> relations) {
+ String elementLocation = elementPath.join(' ');
+ relations.forEach((InspectLocation location) {
+ var relString = location.relationship.identifier;
+ var locString = '${location.path} offset=${location.offset} '
+ 'length=${location.length} flags=${location.flags}';
+ _writeRow(buffer, [elementLocation, relString, locString]);
+ });
+ });
+ buffer.write('</table>');
+ });
+ });
+ } else {
+ return _returnFailure(request, 'LocalIndex expected, but $index found.');
+ }
+ }
+
+ void _returnOverlayContents(HttpRequest request) {
+ String path = request.requestedUri.queryParameters[PATH_PARAM];
+ if (path == null) {
+ return _returnFailure(request, 'Query parameter $PATH_PARAM required');
+ }
+ String contents = _overlayContents[path];
+
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Overlay', [],
+ (StringBuffer buffer) {
+ buffer.write('<pre>${HTML_ESCAPE.convert(contents)}</pre>');
+ });
+ });
+ }
+
+ /**
+ * Return a response displaying overlays information.
+ */
+ void _returnOverlaysInfo(HttpRequest request) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ if (analysisServer == null) {
+ return _returnFailure(request, 'Analysis server is not running');
+ }
+
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Overlays', [],
+ (StringBuffer buffer) {
+ buffer.write('<table border="1">');
+ _overlayContents.clear();
+ ContentCache overlayState = analysisServer.overlayState;
+ overlayState.accept((String fullName, int stamp, String contents) {
+ buffer.write('<tr>');
+ String link =
+ makeLink(OVERLAY_PATH, {PATH_PARAM: fullName}, fullName);
+ DateTime time = new DateTime.fromMillisecondsSinceEpoch(stamp);
+ _writeRow(buffer, [link, time]);
+ _overlayContents[fullName] = contents;
+ });
+ int count = _overlayContents.length;
+ buffer.write('<tr><td colspan="2">Total: $count entries.</td></tr>');
+ buffer.write('</table>');
+ });
+ });
+ }
+
+ /**
+ * Return a response indicating the status of the analysis server.
+ */
+ void _returnServerStatus(HttpRequest request) {
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server - Status', [], (StringBuffer buffer) {
+ if (_writeServerStatus(buffer)) {
+ _writeAnalysisStatus(buffer);
+ _writeEditStatus(buffer);
+ _writeExecutionStatus(buffer);
+ _writePluginStatus(buffer);
+ _writeRecentOutput(buffer);
+ }
+ });
+ });
+ }
+
+ /**
+ * Return an error in response to an unrecognized request received by the HTTP
+ * server.
+ */
+ void _returnUnknownRequest(HttpRequest request) {
+ _writeResponse(request, (StringBuffer buffer) {
+ _writePage(buffer, 'Analysis Server', [], (StringBuffer buffer) {
+ buffer.write('<h3>Pages</h3>');
+ buffer.write('<p>');
+ buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
+ buffer.write('</p>');
+ buffer.write('<p>');
+ buffer
+ .write(makeLink(COMMUNICATION_PERFORMANCE_PATH, {}, 'Performance'));
+ buffer.write('</p>');
+ buffer.write('<p>');
+ buffer.write(makeLink(STATUS_PATH, {}, 'Server status'));
+ buffer.write('</p>');
+ buffer.write('<p>');
+ buffer.write(makeLink(OVERLAYS_PATH, {}, 'File overlays'));
+ buffer.write('</p>');
+ });
+ });
+ }
+
+ /**
+ * Return a two digit decimal representation of the given non-negative integer
+ * [value].
+ */
+ String _twoDigit(int value) {
+ if (value < 10) {
+ return '0$value';
+ }
+ return value.toString();
+ }
+
+ /**
+ * Write the status of the analysis domain (on the main status page) to the
+ * given [buffer] object.
+ */
+ void _writeAnalysisStatus(StringBuffer buffer) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ Map<Folder, AnalysisContext> folderMap = analysisServer.folderMap;
+ List<Folder> folders = folderMap.keys.toList();
+ folders.sort((Folder first, Folder second) =>
+ first.shortName.compareTo(second.shortName));
+ AnalysisOptionsImpl options =
+ analysisServer.contextDirectoryManager.defaultOptions;
+ ServerOperationQueue operationQueue = analysisServer.operationQueue;
+
+ buffer.write('<h3>Analysis Domain</h3>');
+ _writeTwoColumns(buffer, (StringBuffer buffer) {
+ if (operationQueue.isEmpty) {
+ buffer.write('<p>Status: Done analyzing</p>');
+ } else {
+ ServerOperation operation = operationQueue.peek();
+ if (operation is PerformAnalysisOperation) {
+ Folder folder = _keyForValue(folderMap, operation.context);
+ if (folder == null) {
+ buffer.write('<p>Status: Analyzing in unmapped context</p>');
+ } else {
+ buffer.write('<p>Status: Analyzing in ${folder.path}</p>');
+ }
+ } else {
+ buffer.write('<p>Status: Analyzing</p>');
+ }
+ }
+
+ buffer.write('<p><b>Analysis Contexts</b></p>');
+ buffer.write('<p>');
+ bool first = true;
+ folders.forEach((Folder folder) {
+ if (first) {
+ first = false;
+ } else {
+ buffer.write('<br>');
+ }
+ String key = folder.shortName;
+ buffer.write(makeLink(CONTEXT_PATH, {
+ CONTEXT_QUERY_PARAM: folder.path
+ }, key, _hasException(folderMap[folder])));
+ });
+ buffer.write('</p>');
+
+ buffer.write('<p><b>Options</b></p>');
+ buffer.write('<p>');
+ _writeOption(
+ buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
+ _writeOption(buffer, 'Cache size', options.cacheSize);
+ _writeOption(buffer, 'Enable null-aware operators',
+ options.enableNullAwareOperators);
+ _writeOption(
+ buffer, 'Enable strict call checks', options.enableStrictCallChecks);
+ _writeOption(buffer, 'Generate hints', options.hint);
+ _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
+ _writeOption(buffer, 'Generate errors in implicit files',
+ options.generateImplicitErrors);
+ _writeOption(
+ buffer, 'Generate errors in SDK files', options.generateSdkErrors);
+ _writeOption(buffer, 'Incremental resolution', options.incremental);
+ _writeOption(buffer, 'Incremental resolution with API changes',
+ options.incrementalApi);
+ _writeOption(buffer, 'Preserve comments', options.preserveComments,
+ last: true);
+ buffer.write('</p>');
+ int freq = AnalysisServer.performOperationDelayFreqency;
+ String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
+ buffer.write('<p><b>perform operation delay:</b> $delay</p>');
+
+ buffer.write('<p><b>Performance Data</b></p>');
+ buffer.write('<p>');
+ buffer.write(makeLink(ANALYSIS_PERFORMANCE_PATH, {}, 'Task data'));
+ buffer.write('</p>');
+ }, (StringBuffer buffer) {
+ _writeSubscriptionMap(
+ buffer, AnalysisService.VALUES, analysisServer.analysisServices);
+ });
+ }
+
+ /**
+ * Write performance information about a specific completion request
+ * to the given [buffer] object.
+ */
+ void _writeCompletionPerformanceDetail(StringBuffer buffer, int index) {
+ CompletionDomainHandler handler = _completionDomainHandler;
+ CompletionPerformance performance;
+ if (handler != null) {
+ List<CompletionPerformance> list = handler.performanceList;
+ if (list != null && list.isNotEmpty) {
+ performance = list[max(0, min(list.length - 1, index))];
+ }
+ }
+ if (performance == null) {
+ buffer.write('<h3>Completion Performance Detail</h3>');
+ buffer.write('<p>No completions yet</p>');
+ return;
+ }
+ buffer.write('<h3>Completion Performance Detail</h3>');
+ buffer.write('<p>${performance.startTimeAndMs} for ${performance.source}');
+ buffer.write('<table>');
+ _writeRow(buffer, ['Elapsed', '', 'Operation'], header: true);
+ performance.operations.forEach((OperationPerformance op) {
+ String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
+ _writeRow(buffer, [elapsed, ' ', op.name]);
+ });
+ buffer.write('</table>');
+ buffer.write('<p><b>Compute Cache Performance</b>: ');
+ if (handler.computeCachePerformance == null) {
+ buffer.write('none');
+ } else {
+ int elapsed = handler.computeCachePerformance.elapsedInMilliseconds;
+ Source source = handler.computeCachePerformance.source;
+ buffer.write(' $elapsed ms for $source');
+ }
+ buffer.write('</p>');
+ }
+
+ /**
+ * Write a table showing summary information for the last several
+ * completion requests to the given [buffer] object.
+ */
+ void _writeCompletionPerformanceList(StringBuffer buffer) {
+ CompletionDomainHandler handler = _completionDomainHandler;
+ buffer.write('<h3>Completion Performance List</h3>');
+ if (handler == null) {
+ return;
+ }
+ buffer.write('<table>');
+ _writeRow(buffer, [
+ 'Start Time',
+ '',
+ 'First (ms)',
+ '',
+ 'Complete (ms)',
+ '',
+ '# Notifications',
+ '',
+ '# Suggestions',
+ '',
+ 'Snippet'
+ ], header: true);
+ int index = 0;
+ for (CompletionPerformance performance in handler.performanceList) {
+ String link = makeLink(COMPLETION_PATH, {
+ 'index': '$index'
+ }, '${performance.startTimeAndMs}');
+ _writeRow(buffer, [
+ link,
+ ' ',
+ performance.firstNotificationInMilliseconds,
+ ' ',
+ performance.elapsedInMilliseconds,
+ ' ',
+ performance.notificationCount,
+ ' ',
+ performance.suggestionCount,
+ ' ',
+ HTML_ESCAPE.convert(performance.snippet)
+ ]);
+ ++index;
+ }
+
+ buffer.write('</table>');
+ buffer.write('''
+ <p><strong>First (ms)</strong> - the number of milliseconds
+ from when completion received the request until the first notification
+ with completion results was queued for sending back to the client.
+ <p><strong>Complete (ms)</strong> - the number of milliseconds
+ from when completion received the request until the final notification
+ with completion results was queued for sending back to the client.
+ <p><strong># Notifications</strong> - the total number of notifications
+ sent to the client with completion results for this request.
+ <p><strong># Suggestions</strong> - the number of suggestions
+ sent to the client in the first notification, followed by a comma,
+ followed by the number of suggestions send to the client
+ in the last notification. If there is only one notification,
+ then there will be only one number in this column.''');
+ }
+
+ /**
+ * Write the status of the edit domain (on the main status page) to the given
+ * [buffer].
+ */
+ void _writeEditStatus(StringBuffer buffer) {
+ buffer.write('<h3>Edit Domain</h3>');
+ _writeTwoColumns(buffer, (StringBuffer buffer) {
+ buffer.write('<p><b>Performance Data</b></p>');
+ buffer.write('<p>');
+ buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
+ buffer.write('</p>');
+ }, (StringBuffer buffer) {});
+ }
+
+ /**
+ * Write a representation of the given [caughtException] to the given
+ * [buffer]. If [isCause] is `true`, then the exception was a cause for
+ * another exception.
+ */
+ void _writeException(StringBuffer buffer, CaughtException caughtException,
+ {bool isCause: false}) {
+ Object exception = caughtException.exception;
+
+ if (exception is AnalysisException) {
+ buffer.write('<p>');
+ if (isCause) {
+ buffer.write('Caused by ');
+ }
+ buffer.write(exception.message);
+ buffer.write('</p>');
+ _writeStackTrace(buffer, caughtException.stackTrace);
+ CaughtException cause = exception.cause;
+ if (cause != null) {
+ buffer.write('<blockquote>');
+ _writeException(buffer, cause, isCause: true);
+ buffer.write('</blockquote>');
+ }
+ } else {
+ buffer.write('<p>');
+ if (isCause) {
+ buffer.write('Caused by ');
+ }
+ buffer.write(exception.toString());
+ buffer.write('<p>');
+ _writeStackTrace(buffer, caughtException.stackTrace);
+ }
+ }
+
+ /**
+ * Write the status of the execution domain (on the main status page) to the
+ * given [buffer].
+ */
+ void _writeExecutionStatus(StringBuffer buffer) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ ExecutionDomainHandler handler = analysisServer.handlers.firstWhere(
+ (RequestHandler handler) => handler is ExecutionDomainHandler,
+ orElse: () => null);
+ Set<ExecutionService> services = new Set<ExecutionService>();
+ if (handler.onFileAnalyzed != null) {
+ services.add(ExecutionService.LAUNCH_DATA);
+ }
+
+ if (handler != null) {
+ buffer.write('<h3>Execution Domain</h3>');
+ _writeTwoColumns(buffer, (StringBuffer buffer) {
+ _writeSubscriptionList(buffer, ExecutionService.VALUES, services);
+ }, (StringBuffer buffer) {});
+ }
+ }
+
+ /**
+ * Write a representation of an analysis option with the given [name] and
+ * [value] to the given [buffer]. The option should be separated from other
+ * options unless the [last] flag is true, indicating that this is the last
+ * option in the list of options.
+ */
+ void _writeOption(StringBuffer buffer, String name, Object value,
+ {bool last: false}) {
+ buffer.write(name);
+ buffer.write(' = ');
+ buffer.write(value.toString());
+ if (!last) {
+ buffer.write('<br>');
+ }
+ }
+
+ /**
+ * Write a standard HTML page to the given [buffer]. The page will have the
+ * given [title] and a body that is generated by the given [body] generator.
+ */
+ void _writePage(StringBuffer buffer, String title, List<String> subtitles,
+ HtmlGenerator body) {
+ DateTime now = new DateTime.now();
+ String date = "${now.month}/${now.day}/${now.year}";
+ String time =
+ "${now.hour}:${_twoDigit(now.minute)}:${_twoDigit(now.second)}.${now.millisecond}";
+
+ buffer.write('<!DOCTYPE html>');
+ buffer.write('<html>');
+ buffer.write('<head>');
+ buffer.write('<meta charset="utf-8">');
+ buffer.write(
+ '<meta name="viewport" content="width=device-width, initial-scale=1.0">');
+ buffer.write('<title>$title</title>');
+ buffer.write('<style>');
+ buffer.write('a {color: #0000DD; text-decoration: none;}');
+ buffer.write('a:link.error {background-color: #FFEEEE;}');
+ buffer.write('a:visited.error {background-color: #FFEEEE;}');
+ buffer.write('a:hover.error {background-color: #FFEEEE;}');
+ buffer.write('a:active.error {background-color: #FFEEEE;}');
+ buffer.write(
+ 'h3 {background-color: #DDDDDD; margin-top: 0em; margin-bottom: 0em;}');
+ buffer.write('p {margin-top: 0.5em; margin-bottom: 0.5em;}');
+// response.write('span.error {text-decoration-line: underline; text-decoration-color: red; text-decoration-style: wavy;}');
+ buffer.write(
+ 'table.column {border: 0px solid black; width: 100%; table-layout: fixed;}');
+ buffer.write('td.column {vertical-align: top; width: 50%;}');
+ buffer.write('td.right {text-align: right;}');
+ buffer.write('</style>');
+ buffer.write('</head>');
+
+ buffer.write('<body>');
+ buffer.write(
+ '<h2>$title <small><small>(as of $time on $date)</small></small></h2>');
+ if (subtitles != null && subtitles.isNotEmpty) {
+ buffer.write('<blockquote>');
+ bool first = true;
+ for (String subtitle in subtitles) {
+ if (first) {
+ first = false;
+ } else {
+ buffer.write('<br>');
+ }
+ buffer.write('<b>');
+ buffer.write(subtitle);
+ buffer.write('</b>');
+ }
+ buffer.write('</blockquote>');
+ }
+ try {
+ body(buffer);
+ } catch (exception, stackTrace) {
+ buffer.write('<h3>Exception while creating page</h3>');
+ _writeException(buffer, new CaughtException(exception, stackTrace));
+ }
+ buffer.write('</body>');
+ buffer.write('</html>');
+ }
+
+ /**
+ * Write the recent output section (on the main status page) to the given
+ * [buffer] object.
+ */
+ void _writePluginStatus(StringBuffer buffer) {
+ void writePlugin(Plugin plugin) {
+ buffer.write(_server.serverPlugin.uniqueIdentifier);
+ buffer.write(' (');
+ buffer.write(_server.serverPlugin.runtimeType);
+ buffer.write(')<br>');
+ }
+ buffer.write('<h3>Plugin Status</h3><p>');
+ writePlugin(AnalysisEngine.instance.enginePlugin);
+ writePlugin(_server.serverPlugin);
+ for (Plugin plugin in _server.analysisServer.userDefinedPlugins) {
+ writePlugin(plugin);
+ }
+ buffer.write('<p>');
+ }
+
+ /**
+ * Write the recent output section (on the main status page) to the given
+ * [buffer] object.
+ */
+ void _writeRecentOutput(StringBuffer buffer) {
+ buffer.write('<h3>Recent Output</h3>');
+ String output = HTML_ESCAPE.convert(_printBuffer.join('\n'));
+ if (output.isEmpty) {
+ buffer.write('<i>none</i>');
+ } else {
+ buffer.write('<pre>');
+ buffer.write(output);
+ buffer.write('</pre>');
+ }
+ }
+
+ void _writeResponse(HttpRequest request, HtmlGenerator writePage) {
+ HttpResponse response = request.response;
+ response.statusCode = HttpStatus.OK;
+ response.headers.contentType = _htmlContent;
+ try {
+ StringBuffer buffer = new StringBuffer();
+ try {
+ writePage(buffer);
+ } catch (exception, stackTrace) {
+ buffer.clear();
+ _writePage(buffer, 'Internal Exception', [], (StringBuffer buffer) {
+ _writeException(buffer, new CaughtException(exception, stackTrace));
+ });
+ }
+ response.write(buffer.toString());
+ } finally {
+ response.close();
+ }
+ }
+
+ /**
+ * Write a single row within a table to the given [buffer]. The row will have
+ * one cell for each of the [columns], and will be a header row if [header] is
+ * `true`.
+ */
+ void _writeRow(StringBuffer buffer, List<Object> columns,
+ {bool header: false, List<String> classes}) {
+ buffer.write('<tr>');
+ int count = columns.length;
+ int maxClassIndex = classes == null ? 0 : classes.length - 1;
+ for (int i = 0; i < count; i++) {
+ String classAttribute = '';
+ if (classes != null) {
+ String className = classes[min(i, maxClassIndex)];
+ if (className != null) {
+ classAttribute = ' class="$className"';
+ }
+ }
+ if (header) {
+ buffer.write('<th$classAttribute>');
+ } else {
+ buffer.write('<td$classAttribute>');
+ }
+ buffer.write(columns[i]);
+ if (header) {
+ buffer.write('</th>');
+ } else {
+ buffer.write('</td>');
+ }
+ }
+ buffer.write('</tr>');
+ }
+
+ /**
+ * Write the status of the service domain (on the main status page) to the
+ * given [response] object.
+ */
+ bool _writeServerStatus(StringBuffer buffer) {
+ AnalysisServer analysisServer = _server.analysisServer;
+ Set<ServerService> services = analysisServer.serverServices;
+
+ buffer.write('<h3>Server Domain</h3>');
+ _writeTwoColumns(buffer, (StringBuffer buffer) {
+ if (analysisServer == null) {
+ buffer.write('Status: <span style="color:red">Not running</span>');
+ return false;
+ }
+ buffer.write('<p>');
+ buffer.write('Status: Running<br>');
+ buffer.write('Instrumentation: ');
+ if (AnalysisEngine.instance.instrumentationService.isActive) {
+ buffer.write('<span style="color:red">Active</span>');
+ } else {
+ buffer.write('Inactive');
+ }
+ buffer.write('<br>');
+ buffer.write('Version: ');
+ buffer.write(AnalysisServer.VERSION);
+ buffer.write('</p>');
+
+ buffer.write('<p><b>Performance Data</b></p>');
+ buffer.write('<p>');
+ buffer.write(makeLink(
+ COMMUNICATION_PERFORMANCE_PATH, {}, 'Communication performance'));
+ buffer.write('</p>');
+ }, (StringBuffer buffer) {
+ _writeSubscriptionList(buffer, ServerService.VALUES, services);
+ });
+ return true;
+ }
+
+ /**
+ * Write a representation of the given [stackTrace] to the given [buffer].
+ */
+ void _writeStackTrace(StringBuffer buffer, StackTrace stackTrace) {
+ if (stackTrace != null) {
+ String trace = stackTrace.toString().replaceAll('#', '<br>#');
+ if (trace.startsWith('<br>#')) {
+ trace = trace.substring(4);
+ }
+ buffer.write('<p>');
+ buffer.write(trace);
+ buffer.write('</p>');
+ }
+ }
+
+ /**
+ * Given a [service] that could be subscribed to and a set of the services
+ * that are actually subscribed to ([subscribedServices]), write a
+ * representation of the service to the given [buffer].
+ */
+ void _writeSubscriptionInList(
+ StringBuffer buffer, Enum service, Set<Enum> subscribedServices) {
+ if (subscribedServices.contains(service)) {
+ buffer.write('<code>+ </code>');
+ } else {
+ buffer.write('<code>- </code>');
+ }
+ buffer.write(service.name);
+ buffer.write('<br>');
+ }
+
+ /**
+ * Given a [service] that could be subscribed to and a set of paths that are
+ * subscribed to the services ([subscribedPaths]), write a representation of
+ * the service to the given [buffer].
+ */
+ void _writeSubscriptionInMap(
+ StringBuffer buffer, Enum service, Set<String> subscribedPaths) {
+ buffer.write('<p>');
+ buffer.write(service.name);
+ buffer.write('</p>');
+ if (subscribedPaths == null || subscribedPaths.isEmpty) {
+ buffer.write('none');
+ } else {
+ List<String> paths = subscribedPaths.toList();
+ paths.sort();
+ for (String path in paths) {
+ buffer.write('<p>');
+ buffer.write(path);
+ buffer.write('</p>');
+ }
+ }
+ }
+
+ /**
+ * Given a list containing all of the services that can be subscribed to in a
+ * single domain ([allServices]) and a set of the services that are actually
+ * subscribed to ([subscribedServices]), write a representation of the
+ * subscriptions to the given [buffer].
+ */
+ void _writeSubscriptionList(StringBuffer buffer, List<Enum> allServices,
+ Set<Enum> subscribedServices) {
+ buffer.write('<p><b>Subscriptions</b></p>');
+ buffer.write('<p>');
+ for (Enum service in allServices) {
+ _writeSubscriptionInList(buffer, service, subscribedServices);
+ }
+ buffer.write('</p>');
+ }
+
+ /**
+ * Given a list containing all of the services that can be subscribed to in a
+ * single domain ([allServices]) and a set of the services that are actually
+ * subscribed to ([subscribedServices]), write a representation of the
+ * subscriptions to the given [buffer].
+ */
+ void _writeSubscriptionMap(StringBuffer buffer, List<Enum> allServices,
+ Map<Enum, Set<String>> subscribedServices) {
+ buffer.write('<p><b>Subscriptions</b></p>');
+ for (Enum service in allServices) {
+ _writeSubscriptionInMap(buffer, service, subscribedServices[service]);
+ }
+ }
+
+ /**
+ * Write two columns of information to the given [buffer], where the
+ * [leftColumn] and [rightColumn] functions are used to generate the content
+ * of those columns.
+ */
+ void _writeTwoColumns(StringBuffer buffer, HtmlGenerator leftColumn,
+ HtmlGenerator rightColumn) {
+ buffer
+ .write('<table class="column"><tr class="column"><td class="column">');
+ leftColumn(buffer);
+ buffer.write('</td><td class="column">');
+ rightColumn(buffer);
+ buffer.write('</td></tr></table>');
+ }
+
+ /**
+ * Render the given [value] as HTML and append it to the given [buffer]. The
+ * [linkParameters] will be used if the value is too large to be displayed on
+ * the current page and needs to be linked to a separate page.
+ */
+ void _writeValueAsHtml(
+ StringBuffer buffer, Object value, Map<String, String> linkParameters) {
+ if (value == null) {
+ buffer.write('<i>null</i>');
+ } else if (value is String) {
+ buffer.write('<pre>${HTML_ESCAPE.convert(value)}</pre>');
+ } else if (value is List) {
+ buffer.write('List containing ${value.length} entries');
+ buffer.write('<ul>');
+ for (var entry in value) {
+ buffer.write('<li>');
+ _writeValueAsHtml(buffer, entry, linkParameters);
+ buffer.write('</li>');
+ }
+ buffer.write('</ul>');
+ } else if (value is AstNode) {
+ String link =
+ makeLink(AST_PATH, linkParameters, value.runtimeType.toString());
+ buffer.write('<i>$link</i>');
+ } else if (value is Element) {
+ String link =
+ makeLink(ELEMENT_PATH, linkParameters, value.runtimeType.toString());
+ buffer.write('<i>$link</i>');
+ } else {
+ buffer.write(HTML_ESCAPE.convert(value.toString()));
+ buffer.write(' <i>(${value.runtimeType.toString()})</i>');
+ }
+ }
+
+ /**
+ * Create a link to [path] with query parameters [params], with inner HTML
+ * [innerHtml]. If [hasError] is `true`, then the link will have the class
+ * 'error'.
+ */
+ static String makeLink(
+ String path, Map<String, String> params, String innerHtml,
+ [bool hasError = false]) {
+ Uri uri = new Uri(path: path, queryParameters: params);
+ String href = HTML_ESCAPE.convert(uri.toString());
+ String classAttribute = hasError ? ' class="error"' : '';
+ return '<a href="$href"$classAttribute>$innerHtml</a>';
+ }
+}
diff --git a/pkg/analysis_server/test/performance/driver.dart b/pkg/analysis_server/test/performance/driver.dart
index b84aa8c..4418227 100644
--- a/pkg/analysis_server/test/performance/driver.dart
+++ b/pkg/analysis_server/test/performance/driver.dart
@@ -148,27 +148,37 @@
*/
class Measurement {
final String tag;
+ final bool notification;
final List<Duration> elapsedTimes = new List<Duration>();
int errorCount = 0;
+ int unexpectedResultCount = 0;
- Measurement(this.tag);
+ Measurement(this.tag, this.notification);
+
+ int get count => elapsedTimes.length;
void printSummary(int keyLen) {
int count = 0;
+ Duration maxTime = elapsedTimes[0];
+ Duration minTime = elapsedTimes[0];
int totalTimeMicros = 0;
for (Duration elapsed in elapsedTimes) {
++count;
- totalTimeMicros += elapsed.inMicroseconds;
+ int timeMicros = elapsed.inMicroseconds;
+ maxTime = maxTime.compareTo(elapsed) > 0 ? maxTime : elapsed;
+ minTime = minTime.compareTo(elapsed) < 0 ? minTime : elapsed;
+ totalTimeMicros += timeMicros;
}
int averageTimeMicros = (totalTimeMicros / count).round();
StringBuffer sb = new StringBuffer();
_printColumn(sb, tag, keyLen);
- _printColumn(sb, count.toString(), 5, rightJustified: true);
- _printColumn(sb, errorCount.toString(), 5, rightJustified: true);
- sb.write(' ');
- sb.write(new Duration(microseconds: averageTimeMicros));
- sb.write(', ');
- sb.write(new Duration(microseconds: totalTimeMicros));
+ _printColumn(sb, count.toString(), 6, rightJustified: true);
+ _printColumn(sb, errorCount.toString(), 6, rightJustified: true);
+ _printColumn(sb, unexpectedResultCount.toString(), 6, rightJustified: true);
+ _printDuration(sb, minTime);
+ _printDuration(sb, new Duration(microseconds: averageTimeMicros));
+ _printDuration(sb, maxTime);
+ _printDuration(sb, new Duration(microseconds: totalTimeMicros));
print(sb.toString());
}
@@ -178,6 +188,16 @@
}
elapsedTimes.add(elapsed);
}
+
+ void recordUnexpectedResults() {
+ ++unexpectedResultCount;
+ }
+
+ void _printDuration(StringBuffer sb, Duration duration) {
+ sb.write(' ');
+ sb.write(duration);
+ sb.write(',');
+ }
}
/**
@@ -191,39 +211,79 @@
* Display results on stdout.
*/
void printResults() {
+ print('');
print('==================================================================');
+ print('');
List<String> keys = measurements.keys.toList()..sort();
int keyLen = keys.fold(0, (int len, String key) => max(len, key.length));
- StringBuffer sb = new StringBuffer();
- _printColumn(sb, 'Results', keyLen);
- _printColumn(sb, 'count', 5);
- _printColumn(sb, 'errors', 5);
- sb.write(' average, total,');
- print(sb.toString());
+ _printGroupHeader('Request/Response', keyLen);
int totalCount = 0;
int totalErrorCount = 0;
+ int totalUnexpectedResultCount = 0;
for (String tag in keys) {
Measurement m = measurements[tag];
- m.printSummary(keyLen);
- totalCount += m.elapsedTimes.length;
- totalErrorCount += m.errorCount;
+ if (!m.notification) {
+ m.printSummary(keyLen);
+ totalCount += m.count;
+ totalErrorCount += m.errorCount;
+ totalUnexpectedResultCount += m.unexpectedResultCount;
+ }
}
- sb.clear();
- _printColumn(sb, 'Totals', keyLen);
- _printColumn(sb, totalCount.toString(), 5);
- _printColumn(sb, totalErrorCount.toString(), 5);
- print(sb.toString());
+ _printTotals(keyLen, totalCount, totalErrorCount, totalUnexpectedResultCount);
+ print('');
+ _printGroupHeader('Notifications', keyLen);
+ for (String tag in keys) {
+ Measurement m = measurements[tag];
+ if (m.notification) {
+ m.printSummary(keyLen);
+ }
+ }
+ /// TODO(danrubel) *** print warnings if driver caches are not empty ****
+ print('');
+ print(
+ '(1) uxr = UneXpected Results, or responses received from the server');
+ print(
+ ' that do not match the recorded response for that request.');
}
/**
* Record the elapsed time for the given operation.
*/
- void record(String tag, Duration elapsed, {bool success: true}) {
+ void record(String tag, Duration elapsed,
+ {bool notification: false, bool success: true}) {
Measurement measurement = measurements[tag];
if (measurement == null) {
- measurement = new Measurement(tag);
+ measurement = new Measurement(tag, notification);
measurements[tag] = measurement;
}
measurement.record(success, elapsed);
}
+
+ void recordUnexpectedResults(String tag) {
+ measurements[tag].recordUnexpectedResults();
+ }
+
+ void _printGroupHeader(String groupName, int keyLen) {
+ StringBuffer sb = new StringBuffer();
+ _printColumn(sb, groupName, keyLen);
+ _printColumn(sb, 'count', 6, rightJustified: true);
+ _printColumn(sb, 'error', 6, rightJustified: true);
+ _printColumn(sb, 'uxr(1)', 6, rightJustified: true);
+ sb.write(' ');
+ _printColumn(sb, 'minimum', 15);
+ _printColumn(sb, 'average', 15);
+ _printColumn(sb, 'maximum', 15);
+ _printColumn(sb, 'total', 15);
+ print(sb.toString());
+ }
+
+ void _printTotals(int keyLen, int totalCount, int totalErrorCount, int totalUnexpectedResultCount) {
+ StringBuffer sb = new StringBuffer();
+ _printColumn(sb, 'Totals', keyLen);
+ _printColumn(sb, totalCount.toString(), 6, rightJustified: true);
+ _printColumn(sb, totalErrorCount.toString(), 6, rightJustified: true);
+ _printColumn(sb, totalUnexpectedResultCount.toString(), 6,
+ rightJustified: true);
+ print(sb.toString());
+ }
}
diff --git a/pkg/analysis_server/test/performance/input_converter.dart b/pkg/analysis_server/test/performance/input_converter.dart
index 9acf61a..ccf598e 100644
--- a/pkg/analysis_server/test/performance/input_converter.dart
+++ b/pkg/analysis_server/test/performance/input_converter.dart
@@ -4,12 +4,12 @@
library input.transformer;
+import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
@@ -26,16 +26,31 @@
final Set<String> eventsSeen = new Set<String>();
/**
- * A mapping from request/response id to expected error message.
+ * A mapping from request/response id to request json
+ * for those requests for which a response has not been processed.
*/
- final Map<String, dynamic> expectedErrors = new Map<String, dynamic>();
+ final Map<String, dynamic> requestMap = {};
+
+ /**
+ * A mapping from request/response id to a completer
+ * for those requests for which a response has not been processed.
+ * The completer is called with the actual json response
+ * when it becomes available.
+ */
+ final Map<String, Completer> responseCompleters = {};
+
+ /**
+ * A mapping from request/response id to the actual response result
+ * for those responses that have not been processed.
+ */
+ final Map<String, dynamic> responseMap = {};
/**
* A mapping of current overlay content
* parallel to what is in the analysis server
* so that we can update the file system.
*/
- final Map<String, String> overlays = new Map<String, String>();
+ final Map<String, String> overlays = {};
/**
* The prefix used to determine if a request parameter is a file path.
@@ -87,54 +102,54 @@
*/
Operation convertRequest(Map<String, dynamic> origJson) {
Map<String, dynamic> json = translateSrcPaths(origJson);
+ requestMap[json['id']] = json;
String method = json['method'];
// Sanity check operations that modify source
// to ensure that the operation is on source in temp space
if (method == ANALYSIS_UPDATE_CONTENT) {
- try {
- validateSrcPaths(json);
- } catch (e, s) {
- throw new AnalysisException('invalid src path in update request\n$json',
- new CaughtException(e, s));
- }
// Track overlays in parallel with the analysis server
// so that when an overlay is removed, the file can be updated on disk
Request request = new Request.fromJson(json);
var params = new AnalysisUpdateContentParams.fromRequest(request);
- params.files.forEach((String path, change) {
+ params.files.forEach((String filePath, change) {
if (change is AddContentOverlay) {
String content = change.content;
if (content == null) {
throw 'expected new overlay content\n$json';
}
- overlays[path] = content;
+ overlays[filePath] = content;
} else if (change is ChangeContentOverlay) {
- String content = overlays[path];
+ String content = overlays[filePath];
if (content == null) {
throw 'expected cached overlay content\n$json';
}
- overlays[path] = SourceEdit.applySequence(content, change.edits);
+ overlays[filePath] = SourceEdit.applySequence(content, change.edits);
} else if (change is RemoveContentOverlay) {
- String content = overlays.remove(path);
+ String content = overlays.remove(filePath);
if (content == null) {
throw 'expected cached overlay content\n$json';
}
- validateSrcPaths(path);
- new File(path).writeAsStringSync(content);
+ if (!path.isWithin(tmpSrcDirPath, filePath)) {
+ throw 'found path referencing source outside temp space\n$filePath\n$json';
+ }
+ new File(filePath).writeAsStringSync(content);
} else {
throw 'unknown overlay change $change\n$json';
}
});
return new RequestOperation(this, json);
}
- // TODO(danrubel) replace this with code
+ // Track performance for completion notifications
+ if (method == COMPLETION_GET_SUGGESTIONS) {
+ return new CompletionRequestOperation(this, json);
+ }
+ // TODO(danrubel) replace this with code
// that just forwards the translated request
if (method == ANALYSIS_GET_HOVER ||
method == ANALYSIS_SET_ANALYSIS_ROOTS ||
method == ANALYSIS_SET_PRIORITY_FILES ||
method == ANALYSIS_SET_SUBSCRIPTIONS ||
method == ANALYSIS_UPDATE_OPTIONS ||
- method == COMPLETION_GET_SUGGESTIONS ||
method == EDIT_GET_ASSISTS ||
method == EDIT_GET_AVAILABLE_REFACTORINGS ||
method == EDIT_GET_FIXES ||
@@ -145,6 +160,7 @@
method == EXECUTION_MAP_URI ||
method == EXECUTION_SET_SUBSCRIPTIONS ||
method == SEARCH_FIND_ELEMENT_REFERENCES ||
+ method == SEARCH_FIND_MEMBER_DECLARATIONS ||
method == SERVER_GET_VERSION ||
method == SERVER_SET_SUBSCRIPTIONS) {
return new RequestOperation(this, json);
@@ -153,49 +169,63 @@
}
/**
- * Determine if the given request is expected to fail
- * and log an exception if not.
+ * Return an operation for the recorded/expected response.
*/
- void recordErrorResponse(Map<String, dynamic> jsonRequest, exception) {
- var actualErr;
- if (exception is UnimplementedError) {
- if (exception.message.startsWith(ERROR_PREFIX)) {
- Map<String, dynamic> jsonResponse =
- JSON.decode(exception.message.substring(ERROR_PREFIX.length));
- actualErr = jsonResponse['error'];
- }
- }
- String id = jsonRequest['id'];
- if (id != null && actualErr != null) {
- var expectedErr = expectedErrors[id];
- if (expectedErr != null && actualErr == expectedErr) {
- return;
- }
-// if (jsonRequest['method'] == EDIT_SORT_MEMBERS) {
-// var params = jsonRequest['params'];
-// if (params is Map) {
-// var filePath = params['file'];
-// if (filePath is String) {
-// var content = overlays[filePath];
-// if (content is String) {
-// logger.log(Level.WARNING, 'sort failed: $filePath\n$content');
-// }
-// }
-// }
-// }
- }
- logger.log(
- Level.SEVERE, 'Send request failed for $id\n$exception\n$jsonRequest');
+ Operation convertResponse(Map<String, dynamic> json) {
+ return new ResponseOperation(
+ this, requestMap.remove(json['id']), translateSrcPaths(json));
}
/**
- * Examine recorded responses and record any expected errors.
+ * Process an error response from the server by either
+ * completing the associated completer in the [responseCompleters]
+ * or stashing it in [responseMap] if no completer exists.
*/
- void recordResponse(Map<String, dynamic> json) {
- var error = json['error'];
- if (error != null) {
- String id = json['id'];
- print('expected error for $id is $error');
+ void processErrorResponse(String id, exception) {
+ var result = exception;
+ if (exception is UnimplementedError) {
+ if (exception.message.startsWith(ERROR_PREFIX)) {
+ result = JSON.decode(exception.message.substring(ERROR_PREFIX.length));
+ }
+ }
+ processResponseResult(id, result);
+ }
+
+ /**
+ * Process the expected response by completing the given completer
+ * with the result if it has alredy been received,
+ * or caching the completer to be completed when the server
+ * returns the associated result.
+ * Return a future that completes when the response is received
+ * or `null` if the response has already been received
+ * and the completer completed.
+ */
+ Future processExpectedResponse(String id, Completer completer) {
+ if (responseMap.containsKey(id)) {
+ logger.log(Level.INFO, 'processing cached response $id');
+ completer.complete(responseMap.remove(id));
+ return null;
+ } else {
+ logger.log(Level.INFO, 'waiting for response $id');
+ responseCompleters[id] = completer;
+ return completer.future;
+ }
+ }
+
+ /**
+ * Process a success response result from the server by either
+ * completing the associated completer in the [responseCompleters]
+ * or stashing it in [responseMap] if no completer exists.
+ * The response result may be `null`.
+ */
+ void processResponseResult(String id, result) {
+ Completer completer = responseCompleters[id];
+ if (completer != null) {
+ logger.log(Level.INFO, 'processing response $id');
+ completer.complete(result);
+ } else {
+ logger.log(Level.INFO, 'caching response $id');
+ responseMap[id] = result;
}
}
@@ -230,29 +260,6 @@
}
return json;
}
-
- /**
- * Recursively verify that the source paths in the specified JSON
- * only reference the temporary source used during performance measurement.
- */
- void validateSrcPaths(json) {
- if (json is String) {
- if (json != null &&
- path.isWithin(rootPrefix, json) &&
- !path.isWithin(tmpSrcDirPath, json)) {
- throw 'found path referencing source outside temp space\n$json';
- }
- } else if (json is List) {
- for (int i = json.length - 1; i >= 0; --i) {
- validateSrcPaths(json[i]);
- }
- } else if (json is Map) {
- json.forEach((String key, value) {
- validateSrcPaths(key);
- validateSrcPaths(value);
- });
- }
- }
}
/**
diff --git a/pkg/analysis_server/test/performance/instrumentation_input_converter.dart b/pkg/analysis_server/test/performance/instrumentation_input_converter.dart
index b0f9c61..32974c2 100644
--- a/pkg/analysis_server/test/performance/instrumentation_input_converter.dart
+++ b/pkg/analysis_server/test/performance/instrumentation_input_converter.dart
@@ -65,8 +65,7 @@
return convertRequest(decodeJson(line, fields[2]));
} else if (opCode == InstrumentationService.TAG_RESPONSE) {
// 1434096937454:Res:{"id"::"0","result"::{"version"::"1.7.0"}}
- recordResponse(decodeJson(line, fields[2]));
- return null;
+ return convertResponse(decodeJson(line, fields[2]));
} else if (opCode == InstrumentationService.TAG_ANALYSIS_TASK) {
// 1434096943208:Task:/Users/
return null;
diff --git a/pkg/analysis_server/test/performance/log_file_input_converter.dart b/pkg/analysis_server/test/performance/log_file_input_converter.dart
index c15c450..6e9e74e 100644
--- a/pkg/analysis_server/test/performance/log_file_input_converter.dart
+++ b/pkg/analysis_server/test/performance/log_file_input_converter.dart
@@ -35,8 +35,9 @@
Map<String, dynamic> json = JSON.decode(data.substring(4));
if (json.containsKey('event')) {
return convertNotification(json);
+ } else {
+ return convertResponse(json);
}
- return null;
} else if (data.startsWith(SENT_FRAGMENT)) {
Map<String, dynamic> json = JSON.decode(data.substring(4));
if (json.containsKey('method')) {
diff --git a/pkg/analysis_server/test/performance/operation.dart b/pkg/analysis_server/test/performance/operation.dart
index 5952252..641cf31 100644
--- a/pkg/analysis_server/test/performance/operation.dart
+++ b/pkg/analysis_server/test/performance/operation.dart
@@ -13,6 +13,53 @@
import 'input_converter.dart';
/**
+ * A [CompletionRequestOperation] tracks response time along with
+ * the first and last completion notifications.
+ */
+class CompletionRequestOperation extends RequestOperation {
+ Driver driver;
+ StreamSubscription<CompletionResultsParams> subscription;
+ String notificationId;
+ Stopwatch stopwatch;
+ bool firstNotification = true;
+
+ CompletionRequestOperation(
+ CommonInputConverter converter, Map<String, dynamic> json)
+ : super(converter, json);
+
+ @override
+ Future perform(Driver driver) {
+ this.driver = driver;
+ subscription = driver.onCompletionResults.listen(processNotification);
+ return super.perform(driver);
+ }
+
+ void processNotification(CompletionResultsParams event) {
+ if (event.id == notificationId) {
+ Duration elapsed = stopwatch.elapsed;
+ if (firstNotification) {
+ firstNotification = false;
+ driver.results.record('completion notification first', elapsed,
+ notification: true);
+ }
+ if (event.isLast) {
+ subscription.cancel();
+ driver.results.record('completion notification last', elapsed,
+ notification: true);
+ }
+ }
+ }
+
+ @override
+ void processResult(
+ String id, Map<String, dynamic> result, Stopwatch stopwatch) {
+ notificationId = result['id'];
+ this.stopwatch = stopwatch;
+ super.processResult(id, result, stopwatch);
+ }
+}
+
+/**
* An [Operation] represents an action such as sending a request to the server.
*/
abstract class Operation {
@@ -31,24 +78,103 @@
@override
Future perform(Driver driver) {
Stopwatch stopwatch = new Stopwatch();
+ String originalId = json['id'];
String method = json['method'];
driver.logger.log(Level.FINE, 'Sending request: $method\n $json');
stopwatch.start();
- void recordResponse(bool success, response) {
- stopwatch.stop();
+
+ void recordResult(bool success, result) {
Duration elapsed = stopwatch.elapsed;
driver.results.record(method, elapsed, success: success);
driver.logger.log(
- Level.FINE, 'Response received: $method : $elapsed\n $response');
+ Level.FINE, 'Response received: $method : $elapsed\n $result');
}
- driver.send(method, json['params']).then((response) {
- recordResponse(true, response);
- }).catchError((e, s) {
- recordResponse(false, e);
- converter.recordErrorResponse(json, e);
+
+ driver.send(method, json['params']).then((Map<String, dynamic> result) {
+ recordResult(true, result);
+ processResult(originalId, result, stopwatch);
+ }).catchError((exception) {
+ recordResult(false, exception);
+ converter.processErrorResponse(originalId, exception);
});
return null;
}
+
+ void processResult(
+ String id, Map<String, dynamic> result, Stopwatch stopwatch) {
+ converter.processResponseResult(id, result);
+ }
+}
+
+/**
+ * A [ResponseOperation] waits for a [JSON] response from the server.
+ */
+class ResponseOperation extends Operation {
+ static final Duration responseTimeout = new Duration(seconds: 5);
+ final CommonInputConverter converter;
+ final Map<String, dynamic> requestJson;
+ final Map<String, dynamic> responseJson;
+ final Completer completer = new Completer();
+ Driver driver;
+
+ ResponseOperation(this.converter, this.requestJson, this.responseJson) {
+ completer.future.then(_processResult).timeout(responseTimeout);
+ }
+
+ @override
+ Future perform(Driver driver) {
+ this.driver = driver;
+ return converter.processExpectedResponse(responseJson['id'], completer);
+ }
+
+ bool _equal(expectedResult, actualResult) {
+ if (expectedResult is Map && actualResult is Map) {
+ if (expectedResult.length == actualResult.length) {
+ return expectedResult.keys.every((String key) {
+ return key ==
+ 'fileStamp' || // fileStamp values will not be the same across runs
+ _equal(expectedResult[key], actualResult[key]);
+ });
+ }
+ } else if (expectedResult is List && actualResult is List) {
+ if (expectedResult.length == actualResult.length) {
+ for (int i = 0; i < expectedResult.length; ++i) {
+ if (!_equal(expectedResult[i], actualResult[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ return expectedResult == actualResult;
+ }
+
+ /**
+ * Compare the expected and actual server response result.
+ */
+ void _processResult(actualResult) {
+ var expectedResult = responseJson['result'];
+ if (!_equal(expectedResult, actualResult)) {
+ var expectedError = responseJson['error'];
+ String format(value) {
+ String text = '\n$value';
+ if (text.endsWith('\n')) {
+ text = text.substring(0, text.length - 1);
+ }
+ return text.replaceAll('\n', '\n ');
+ }
+ String message = 'Request:${format(requestJson)}\n'
+ 'expected result:${format(expectedResult)}\n'
+ 'expected error:${format(expectedError)}\n'
+ 'but received:${format(actualResult)}';
+ driver.results.recordUnexpectedResults(requestJson['method']);
+ if (expectedError == null) {
+ converter.logger.log(Level.SEVERE, message);
+ } else {
+ throw message;
+ }
+ }
+ }
}
class StartServerOperation extends Operation {
@@ -79,7 +205,7 @@
Duration delta = end.difference(start);
driver.logger.log(Level.FINE, 'analysis complete after $delta');
completer.complete();
- driver.results.record('analysis complete', delta);
+ driver.results.record('analysis complete', delta, notification: true);
}
}
});
diff --git a/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart b/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
index 20cdddf..aaf8a0f 100644
--- a/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
+++ b/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
@@ -5,6 +5,7 @@
library test.source.caching_pub_package_map_provider;
import 'dart:convert';
+import 'dart:core' hide Resource;
import 'dart:io' as io;
import 'package:analysis_server/src/source/caching_pub_package_map_provider.dart';
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index 9a41f81..62c158b 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -18,7 +18,7 @@
* Watch for changes to this file
*/
Stream<WatchEvent> get changes;
-
+
/**
* Return the last-modified stamp of the file.
* Throws [FileSystemException] if the file does not exist.
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index a68a225..b0a5469 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -6,6 +6,7 @@
import 'dart:async';
import 'dart:collection';
+import 'dart:core' hide Resource;
import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 9c9d5a6..d9497df 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -5,6 +5,7 @@
library physical_file_system;
import 'dart:async';
+import 'dart:core' hide Resource;
import 'dart:io' as io;
import 'package:analyzer/src/generated/java_io.dart';
@@ -73,7 +74,7 @@
*/
class _PhysicalFile extends _PhysicalResource implements File {
_PhysicalFile(io.File file) : super(file);
-
+
@override
Stream<WatchEvent> get changes => new FileWatcher(_entry.path).events;
diff --git a/pkg/analyzer/lib/source/package_map_resolver.dart b/pkg/analyzer/lib/source/package_map_resolver.dart
index 1b0f82f..82000b9 100644
--- a/pkg/analyzer/lib/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/source/package_map_resolver.dart
@@ -4,6 +4,8 @@
library source.package_map_resolver;
+import 'dart:core' hide Resource;
+
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/util/asserts.dart' as asserts;
diff --git a/pkg/analyzer/lib/source/pub_package_map_provider.dart b/pkg/analyzer/lib/source/pub_package_map_provider.dart
index a78d4ad..3e9936d 100644
--- a/pkg/analyzer/lib/source/pub_package_map_provider.dart
+++ b/pkg/analyzer/lib/source/pub_package_map_provider.dart
@@ -6,6 +6,7 @@
import 'dart:collection';
import 'dart:convert';
+import 'dart:core' hide Resource;
import 'dart:io' as io;
import 'package:analyzer/file_system/file_system.dart';
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 0b93d03..b211067 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -313,6 +313,12 @@
}
/**
+ * Return a list of result descriptors for results whose state is not
+ * [CacheState.INVALID].
+ */
+ List<ResultDescriptor> get nonInvalidResults => _resultMap.keys.toList();
+
+ /**
* Fix the state of the [exception] to match the current state of the entry.
*/
void fixExceptionState() {
@@ -412,7 +418,7 @@
* Set the state of the result represented by the given [descriptor] to the
* given [state].
*/
- void setState(ResultDescriptor descriptor, CacheState state) {
+ void setState(ResultDescriptor descriptor, CacheState state, {Delta delta}) {
if (state == CacheState.ERROR) {
throw new ArgumentError('use setErrorState() to set the state to ERROR');
}
@@ -423,7 +429,7 @@
if (state == CacheState.INVALID) {
ResultData data = _resultMap[descriptor];
if (data != null) {
- _invalidate(descriptor);
+ _invalidate(descriptor, delta);
}
} else {
ResultData data = getResultData(descriptor);
@@ -471,7 +477,7 @@
void setValueIncremental(ResultDescriptor descriptor, dynamic value) {
ResultData data = getResultData(descriptor);
List<TargetedResult> dependedOn = data.dependedOnResults;
- _invalidate(descriptor);
+ _invalidate(descriptor, null);
setValue(descriptor, value, dependedOn);
}
@@ -491,29 +497,42 @@
* Invalidate the result represented by the given [descriptor] and propagate
* invalidation to other results that depend on it.
*/
- void _invalidate(ResultDescriptor descriptor) {
+ void _invalidate(ResultDescriptor descriptor, Delta delta) {
+ DeltaResult deltaResult = null;
+ if (delta != null) {
+ deltaResult = delta.validate(_partition.context, target, descriptor);
+ if (deltaResult == DeltaResult.STOP) {
+// print('not-invalidate $descriptor for $target');
+ return;
+ }
+ }
// print('invalidate $descriptor for $target');
- ResultData thisData = _resultMap.remove(descriptor);
+ ResultData thisData;
+ if (deltaResult == null || deltaResult == DeltaResult.INVALIDATE) {
+ thisData = _resultMap.remove(descriptor);
+ }
+ if (deltaResult == DeltaResult.KEEP_CONTINUE) {
+ thisData = _resultMap[descriptor];
+ }
if (thisData == null) {
return;
}
// Stop depending on other results.
TargetedResult thisResult = new TargetedResult(target, descriptor);
- thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) {
+ for (TargetedResult dependedOnResult in thisData.dependedOnResults) {
ResultData data = _partition._getDataFor(dependedOnResult, orNull: true);
if (data != null) {
data.dependentResults.remove(thisResult);
}
- });
+ }
// Invalidate results that depend on this result.
- Set<TargetedResult> dependentResults = thisData.dependentResults;
- thisData.dependentResults = new Set<TargetedResult>();
- dependentResults.forEach((TargetedResult dependentResult) {
+ List<TargetedResult> dependentResults = thisData.dependentResults.toList();
+ for (TargetedResult dependentResult in dependentResults) {
CacheEntry entry = _partition.get(dependentResult.target);
if (entry != null) {
- entry._invalidate(dependentResult.result);
+ entry._invalidate(dependentResult.result, delta);
}
- });
+ }
// If empty, remove the entry altogether.
if (_resultMap.isEmpty) {
_partition._targetMap.remove(target);
@@ -530,7 +549,7 @@
void _invalidateAll() {
List<ResultDescriptor> results = _resultMap.keys.toList();
for (ResultDescriptor result in results) {
- _invalidate(result);
+ _invalidate(result, null);
}
}
@@ -960,6 +979,29 @@
}
/**
+ * The description for a change.
+ */
+class Delta {
+ final Source source;
+
+ Delta(this.source);
+
+ /**
+ * Check whether this delta affects the result described by the given
+ * [descriptor] and [target].
+ */
+ DeltaResult validate(InternalAnalysisContext context, AnalysisTarget target,
+ ResultDescriptor descriptor) {
+ return DeltaResult.INVALIDATE;
+ }
+}
+
+/**
+ * The possible results of validating analysis results againt a [Delta].
+ */
+enum DeltaResult { INVALIDATE, KEEP_CONTINUE, STOP }
+
+/**
* [InvalidatedResult] describes an invalidated result.
*/
class InvalidatedResult {
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index c7a5c8d..a0e7f1f 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -35,6 +35,7 @@
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/src/task/html_work_manager.dart';
+import 'package:analyzer/src/task/incremental_element_builder.dart';
import 'package:analyzer/src/task/manager.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart';
@@ -156,11 +157,6 @@
new HashMap<Source, ChangeNoticeImpl>();
/**
- * Cached information used in incremental analysis or `null` if none.
- */
- IncrementalAnalysisCache _incrementalAnalysisCache;
-
- /**
* The [TypeProvider] for this context, `null` if not yet created.
*/
TypeProvider _typeProvider;
@@ -423,14 +419,6 @@
return statistics;
}
- IncrementalAnalysisCache get test_incrementalAnalysisCache {
- return _incrementalAnalysisCache;
- }
-
- set test_incrementalAnalysisCache(IncrementalAnalysisCache value) {
- _incrementalAnalysisCache = value;
- }
-
List<Source> get test_priorityOrder => _priorityOrder;
@override
@@ -578,16 +566,16 @@
List<AnalysisError> computeErrors(Source source) {
String name = source.shortName;
if (AnalysisEngine.isDartFileName(name)) {
- return _computeResult(source, DART_ERRORS);
+ return computeResult(source, DART_ERRORS);
} else if (AnalysisEngine.isHtmlFileName(name)) {
- return _computeResult(source, HTML_ERRORS);
+ return computeResult(source, HTML_ERRORS);
}
return AnalysisError.NO_ERRORS;
}
@override
List<Source> computeExportedLibraries(Source source) =>
- _computeResult(source, EXPORTED_LIBRARIES);
+ computeResult(source, EXPORTED_LIBRARIES);
@override
@deprecated
@@ -599,13 +587,13 @@
@override
List<Source> computeImportedLibraries(Source source) =>
- _computeResult(source, EXPLICITLY_IMPORTED_LIBRARIES);
+ computeResult(source, EXPLICITLY_IMPORTED_LIBRARIES);
@override
SourceKind computeKindOf(Source source) {
String name = source.shortName;
if (AnalysisEngine.isDartFileName(name)) {
- return _computeResult(source, SOURCE_KIND);
+ return computeResult(source, SOURCE_KIND);
} else if (AnalysisEngine.isHtmlFileName(name)) {
return SourceKind.HTML;
}
@@ -615,11 +603,11 @@
@override
LibraryElement computeLibraryElement(Source source) {
//_computeResult(source, HtmlEntry.ELEMENT);
- return _computeResult(source, LIBRARY_ELEMENT);
+ return computeResult(source, LIBRARY_ELEMENT);
}
@override
- LineInfo computeLineInfo(Source source) => _computeResult(source, LINE_INFO);
+ LineInfo computeLineInfo(Source source) => computeResult(source, LINE_INFO);
@override
@deprecated
@@ -649,6 +637,21 @@
});
}
+ Object /*V*/ computeResult(
+ AnalysisTarget target, ResultDescriptor /*<V>*/ descriptor) {
+ CacheEntry entry = getCacheEntry(target);
+ CacheState state = entry.getState(descriptor);
+ if (state == CacheState.FLUSHED || state == CacheState.INVALID) {
+ driver.computeResult(target, descriptor);
+ }
+ state = entry.getState(descriptor);
+ if (state == CacheState.ERROR) {
+ throw new AnalysisException(
+ 'Cannot compute $descriptor for $target', entry.exception);
+ }
+ return entry.getValue(descriptor);
+ }
+
/**
* Create an analysis cache based on the given source [factory].
*/
@@ -952,8 +955,6 @@
bool changed = newContents != originalContents;
if (newContents != null) {
if (newContents != originalContents) {
- _incrementalAnalysisCache =
- IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
if (!analysisOptions.incremental ||
!_tryPoorMansIncrementalResolution(source, newContents)) {
_sourceChanged(source);
@@ -964,8 +965,6 @@
entry.modificationTime = _contentCache.getModificationStamp(source);
}
} else if (originalContents != null) {
- _incrementalAnalysisCache =
- IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
changed = newContents != originalContents;
// We are removing the overlay for the file, check if the file's
// contents is the same as it was in the overlay.
@@ -1029,7 +1028,7 @@
throw new AnalysisException('Could not get contents of $source',
new CaughtException(exception, stackTrace));
}
- return _computeResult(source, PARSED_UNIT);
+ return computeResult(source, PARSED_UNIT);
}
@override
@@ -1037,7 +1036,7 @@
if (!AnalysisEngine.isHtmlFileName(source.shortName)) {
return null;
}
- return _computeResult(source, HTML_DOCUMENT);
+ return computeResult(source, HTML_DOCUMENT);
}
@override
@@ -1147,7 +1146,7 @@
!AnalysisEngine.isDartFileName(librarySource.shortName)) {
return null;
}
- return _computeResult(
+ return computeResult(
new LibrarySpecificUnit(librarySource, unitSource), RESOLVED_UNIT);
}
@@ -1248,6 +1247,7 @@
return changedSources.length > 0;
}
+ @deprecated
@override
void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
DataDescriptor rowDesc, CacheState state)) {
@@ -1313,9 +1313,7 @@
// }
}
- /**
- * Visit all entries of the content cache.
- */
+ @override
void visitContentCache(ContentCacheVisitor visitor) {
_contentCache.accept(visitor);
}
@@ -1347,21 +1345,6 @@
}
}
- Object /*V*/ _computeResult(
- AnalysisTarget target, ResultDescriptor /*<V>*/ descriptor) {
- CacheEntry entry = getCacheEntry(target);
- CacheState state = entry.getState(descriptor);
- if (state == CacheState.FLUSHED || state == CacheState.INVALID) {
- driver.computeResult(target, descriptor);
- }
- state = entry.getState(descriptor);
- if (state == CacheState.ERROR) {
- throw new AnalysisException(
- 'Cannot compute $descriptor for $target', entry.exception);
- }
- return entry.getValue(descriptor);
- }
-
/**
* Given the encoded form of a source ([encoding]), use the source factory to
* reconstitute the original source.
@@ -1408,12 +1391,6 @@
String originalContents = _contentCache.setContents(source, contents);
if (contents != null) {
if (contents != originalContents) {
- // TODO(brianwilkerson) Find a better way to do incremental analysis.
-// if (_options.incremental) {
-// _incrementalAnalysisCache = IncrementalAnalysisCache.update(
-// _incrementalAnalysisCache, source, originalContents, contents,
-// offset, oldLength, newLength, _cache.get(source));
-// }
_sourceChanged(source);
changed = true;
CacheEntry entry = _cache.get(source);
@@ -1423,8 +1400,6 @@
}
}
} else if (originalContents != null) {
- _incrementalAnalysisCache =
- IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
_sourceChanged(source);
changed = true;
}
@@ -1720,7 +1695,40 @@
} catch (e) {}
}
// We need to invalidate the cache.
- entry.setState(CONTENT, CacheState.INVALID);
+ {
+ Object delta = null;
+ if (AnalysisEngine.instance.limitInvalidationInTaskModel &&
+ AnalysisEngine.isDartFileName(source.fullName)) {
+ // TODO(scheglov) Incorrect implementation in general.
+ entry.setState(TOKEN_STREAM, CacheState.FLUSHED);
+ entry.setState(PARSED_UNIT, CacheState.FLUSHED);
+ List<Source> librarySources = getLibrariesContaining(source);
+ if (librarySources.length == 1) {
+ Source librarySource = librarySources[0];
+ CompilationUnit oldUnit =
+ getResolvedCompilationUnit2(source, librarySource);
+ if (oldUnit != null) {
+ CompilationUnit newUnit = parseCompilationUnit(source);
+ IncrementalCompilationUnitElementBuilder builder =
+ new IncrementalCompilationUnitElementBuilder(oldUnit, newUnit);
+ builder.build();
+ CompilationUnitElementDelta unitDelta = builder.unitDelta;
+ if (!unitDelta.hasDirectiveChange) {
+ DartDelta dartDelta = new DartDelta(source);
+ dartDelta.hasDirectiveChange = unitDelta.hasDirectiveChange;
+ unitDelta.addedDeclarations.forEach(dartDelta.elementAdded);
+ unitDelta.removedDeclarations.forEach(dartDelta.elementRemoved);
+ print(
+ 'dartDelta: add=${dartDelta.addedNames} remove=${dartDelta.removedNames}');
+ delta = dartDelta;
+ entry.setState(CONTENT, CacheState.INVALID, delta: delta);
+ return;
+ }
+ }
+ }
+ }
+ entry.setState(CONTENT, CacheState.INVALID);
+ }
dartWorkManager.applyChange(
Source.EMPTY_LIST, <Source>[source], Source.EMPTY_LIST);
htmlWorkManager.applyChange(
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index e6d8100..c386c83 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -1245,7 +1245,7 @@
cloneNodeList(node.metadata), cloneToken(node.keyword),
cloneNode(node.type), cloneToken(node.thisKeyword),
cloneToken(node.period), cloneNode(node.identifier),
- cloneNode(node.parameters));
+ cloneNode(node.typeParameters), cloneNode(node.parameters));
@override
ForEachStatement visitForEachStatement(ForEachStatement node) {
@@ -1292,12 +1292,14 @@
@override
FunctionExpression visitFunctionExpression(FunctionExpression node) =>
- new FunctionExpression(cloneNode(node.parameters), cloneNode(node.body));
+ new FunctionExpression(cloneNode(node.typeParameters),
+ cloneNode(node.parameters), cloneNode(node.body));
@override
FunctionExpressionInvocation visitFunctionExpressionInvocation(
FunctionExpressionInvocation node) => new FunctionExpressionInvocation(
- cloneNode(node.function), cloneNode(node.argumentList));
+ cloneNode(node.function), cloneNode(node.typeArguments),
+ cloneNode(node.argumentList));
@override
FunctionTypeAlias visitFunctionTypeAlias(FunctionTypeAlias node) =>
@@ -1312,7 +1314,7 @@
FunctionTypedFormalParameter node) => new FunctionTypedFormalParameter(
cloneNode(node.documentationComment), cloneNodeList(node.metadata),
cloneNode(node.returnType), cloneNode(node.identifier),
- cloneNode(node.parameters));
+ cloneNode(node.typeParameters), cloneNode(node.parameters));
@override
HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator(
@@ -1424,13 +1426,14 @@
cloneNodeList(node.metadata), cloneToken(node.externalKeyword),
cloneToken(node.modifierKeyword), cloneNode(node.returnType),
cloneToken(node.propertyKeyword), cloneToken(node.operatorKeyword),
- cloneNode(node.name), cloneNode(node.parameters),
- cloneNode(node.body));
+ cloneNode(node.name), cloneNode(node.typeParameters),
+ cloneNode(node.parameters), cloneNode(node.body));
@override
MethodInvocation visitMethodInvocation(MethodInvocation node) =>
new MethodInvocation(cloneNode(node.target), cloneToken(node.operator),
- cloneNode(node.methodName), cloneNode(node.argumentList));
+ cloneNode(node.methodName), cloneNode(node.typeArguments),
+ cloneNode(node.argumentList));
@override
NamedExpression visitNamedExpression(NamedExpression node) =>
@@ -7129,7 +7132,7 @@
*
* > fieldFormalParameter ::=
* > ('final' [TypeName] | 'const' [TypeName] | 'var' | [TypeName])?
- * > 'this' '.' [SimpleIdentifier] [FormalParameterList]?
+ * > 'this' '.' [SimpleIdentifier] ([TypeParameterList]? [FormalParameterList])?
*/
class FieldFormalParameter extends NormalFormalParameter {
/**
@@ -7155,6 +7158,12 @@
Token period;
/**
+ * The type parameters associated with the method, or `null` if the method is
+ * not a generic method.
+ */
+ TypeParameterList _typeParameters;
+
+ /**
* The parameters of the function-typed parameter, or `null` if this is not a
* function-typed field formal parameter.
*/
@@ -7171,9 +7180,10 @@
*/
FieldFormalParameter(Comment comment, List<Annotation> metadata, this.keyword,
TypeName type, this.thisKeyword, this.period, SimpleIdentifier identifier,
- FormalParameterList parameters)
+ TypeParameterList typeParameters, FormalParameterList parameters)
: super(comment, metadata, identifier) {
_type = _becomeParentOf(type);
+ _typeParameters = _becomeParentOf(typeParameters);
_parameters = _becomeParentOf(parameters);
}
@@ -7255,6 +7265,20 @@
_type = _becomeParentOf(typeName);
}
+ /**
+ * Return the type parameters associated with this method, or `null` if this
+ * method is not a generic method.
+ */
+ TypeParameterList get typeParameters => _typeParameters;
+
+ /**
+ * Set the type parameters associated with this method to the given
+ * [typeParameters].
+ */
+ void set typeParameters(TypeParameterList typeParameters) {
+ _typeParameters = _becomeParentOf(typeParameters);
+ }
+
@override
accept(AstVisitor visitor) => visitor.visitFieldFormalParameter(this);
@@ -7263,6 +7287,7 @@
super.visitChildren(visitor);
_safelyVisitChild(_type, visitor);
_safelyVisitChild(identifier, visitor);
+ _safelyVisitChild(_typeParameters, visitor);
_safelyVisitChild(_parameters, visitor);
}
}
@@ -8010,10 +8035,16 @@
* A function expression.
*
* > functionExpression ::=
- * > [FormalParameterList] [FunctionBody]
+ * > [TypeParameterList]? [FormalParameterList] [FunctionBody]
*/
class FunctionExpression extends Expression {
/**
+ * The type parameters associated with the method, or `null` if the method is
+ * not a generic method.
+ */
+ TypeParameterList _typeParameters;
+
+ /**
* The parameters associated with the function.
*/
FormalParameterList _parameters;
@@ -8032,14 +8063,18 @@
/**
* Initialize a newly created function declaration.
*/
- FunctionExpression(FormalParameterList parameters, FunctionBody body) {
+ FunctionExpression(TypeParameterList typeParameters,
+ FormalParameterList parameters, FunctionBody body) {
+ _typeParameters = _becomeParentOf(typeParameters);
_parameters = _becomeParentOf(parameters);
_body = _becomeParentOf(body);
}
@override
Token get beginToken {
- if (_parameters != null) {
+ if (_typeParameters != null) {
+ return _typeParameters.beginToken;
+ } else if (_parameters != null) {
return _parameters.beginToken;
} else if (_body != null) {
return _body.beginToken;
@@ -8093,11 +8128,26 @@
@override
int get precedence => 16;
+ /**
+ * Return the type parameters associated with this method, or `null` if this
+ * method is not a generic method.
+ */
+ TypeParameterList get typeParameters => _typeParameters;
+
+ /**
+ * Set the type parameters associated with this method to the given
+ * [typeParameters].
+ */
+ void set typeParameters(TypeParameterList typeParameters) {
+ _typeParameters = _becomeParentOf(typeParameters);
+ }
+
@override
accept(AstVisitor visitor) => visitor.visitFunctionExpression(this);
@override
void visitChildren(AstVisitor visitor) {
+ _safelyVisitChild(_typeParameters, visitor);
_safelyVisitChild(_parameters, visitor);
_safelyVisitChild(_body, visitor);
}
@@ -8110,7 +8160,7 @@
* by either [PrefixedIdentifier] or [PropertyAccess] nodes.
*
* > functionExpressionInvoction ::=
- * > [Expression] [ArgumentList]
+ * > [Expression] [TypeArgumentList]? [ArgumentList]
*/
class FunctionExpressionInvocation extends Expression {
/**
@@ -8119,6 +8169,12 @@
Expression _function;
/**
+ * The type arguments to be applied to the method being invoked, or `null` if
+ * no type arguments were provided.
+ */
+ TypeArgumentList _typeArguments;
+
+ /**
* The list of arguments to the function.
*/
ArgumentList _argumentList;
@@ -8140,8 +8196,10 @@
/**
* Initialize a newly created function expression invocation.
*/
- FunctionExpressionInvocation(Expression function, ArgumentList argumentList) {
+ FunctionExpressionInvocation(Expression function,
+ TypeArgumentList typeArguments, ArgumentList argumentList) {
_function = _becomeParentOf(function);
+ _typeArguments = _becomeParentOf(typeArguments);
_argumentList = _becomeParentOf(argumentList);
}
@@ -8198,12 +8256,27 @@
@override
int get precedence => 15;
+ /**
+ * Return the type arguments to be applied to the method being invoked, or
+ * `null` if no type arguments were provided.
+ */
+ TypeArgumentList get typeArguments => _typeArguments;
+
+ /**
+ * Set the type arguments to be applied to the method being invoked to the
+ * given [typeArguments].
+ */
+ void set typeArguments(TypeArgumentList typeArguments) {
+ _typeArguments = _becomeParentOf(typeArguments);
+ }
+
@override
accept(AstVisitor visitor) => visitor.visitFunctionExpressionInvocation(this);
@override
void visitChildren(AstVisitor visitor) {
_safelyVisitChild(_function, visitor);
+ _safelyVisitChild(_typeArguments, visitor);
_safelyVisitChild(_argumentList, visitor);
}
}
@@ -8323,7 +8396,7 @@
* A function-typed formal parameter.
*
* > functionSignature ::=
- * > [TypeName]? [SimpleIdentifier] [FormalParameterList]
+ * > [TypeName]? [SimpleIdentifier] [TypeParameterList]? [FormalParameterList]
*/
class FunctionTypedFormalParameter extends NormalFormalParameter {
/**
@@ -8333,6 +8406,12 @@
TypeName _returnType;
/**
+ * The type parameters associated with the function, or `null` if the function
+ * is not a generic function.
+ */
+ TypeParameterList _typeParameters;
+
+ /**
* The parameters of the function-typed parameter.
*/
FormalParameterList _parameters;
@@ -8345,9 +8424,10 @@
*/
FunctionTypedFormalParameter(Comment comment, List<Annotation> metadata,
TypeName returnType, SimpleIdentifier identifier,
- FormalParameterList parameters)
+ TypeParameterList typeParameters, FormalParameterList parameters)
: super(comment, metadata, identifier) {
_returnType = _becomeParentOf(returnType);
+ _typeParameters = _becomeParentOf(typeParameters);
_parameters = _becomeParentOf(parameters);
}
@@ -8398,6 +8478,20 @@
_returnType = _becomeParentOf(type);
}
+ /**
+ * Return the type parameters associated with this function, or `null` if
+ * this function is not a generic function.
+ */
+ TypeParameterList get typeParameters => _typeParameters;
+
+ /**
+ * Set the type parameters associated with this method to the given
+ * [typeParameters].
+ */
+ void set typeParameters(TypeParameterList typeParameters) {
+ _typeParameters = _becomeParentOf(typeParameters);
+ }
+
@override
accept(AstVisitor visitor) => visitor.visitFunctionTypedFormalParameter(this);
@@ -8406,6 +8500,7 @@
super.visitChildren(visitor);
_safelyVisitChild(_returnType, visitor);
_safelyVisitChild(identifier, visitor);
+ _safelyVisitChild(_typeParameters, visitor);
_safelyVisitChild(_parameters, visitor);
}
}
@@ -9651,7 +9746,7 @@
_cloneNodeList(node.metadata), _mapToken(node.keyword),
_cloneNode(node.type), _mapToken(node.thisKeyword),
_mapToken(node.period), _cloneNode(node.identifier),
- _cloneNode(node.parameters));
+ _cloneNode(node.typeParameters), _cloneNode(node.parameters));
@override
ForEachStatement visitForEachStatement(ForEachStatement node) {
@@ -9699,7 +9794,8 @@
@override
FunctionExpression visitFunctionExpression(FunctionExpression node) {
FunctionExpression copy = new FunctionExpression(
- _cloneNode(node.parameters), _cloneNode(node.body));
+ _cloneNode(node.typeParameters), _cloneNode(node.parameters),
+ _cloneNode(node.body));
copy.element = node.element;
copy.propagatedType = node.propagatedType;
copy.staticType = node.staticType;
@@ -9710,7 +9806,8 @@
FunctionExpressionInvocation visitFunctionExpressionInvocation(
FunctionExpressionInvocation node) {
FunctionExpressionInvocation copy = new FunctionExpressionInvocation(
- _cloneNode(node.function), _cloneNode(node.argumentList));
+ _cloneNode(node.function), _cloneNode(node.typeArguments),
+ _cloneNode(node.argumentList));
copy.propagatedElement = node.propagatedElement;
copy.propagatedType = node.propagatedType;
copy.staticElement = node.staticElement;
@@ -9731,7 +9828,7 @@
FunctionTypedFormalParameter node) => new FunctionTypedFormalParameter(
_cloneNode(node.documentationComment), _cloneNodeList(node.metadata),
_cloneNode(node.returnType), _cloneNode(node.identifier),
- _cloneNode(node.parameters));
+ _cloneNode(node.typeParameters), _cloneNode(node.parameters));
@override
HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator(
@@ -9873,14 +9970,14 @@
_cloneNodeList(node.metadata), _mapToken(node.externalKeyword),
_mapToken(node.modifierKeyword), _cloneNode(node.returnType),
_mapToken(node.propertyKeyword), _mapToken(node.operatorKeyword),
- _cloneNode(node.name), _cloneNode(node.parameters),
- _cloneNode(node.body));
+ _cloneNode(node.name), _cloneNode(node._typeParameters),
+ _cloneNode(node.parameters), _cloneNode(node.body));
@override
MethodInvocation visitMethodInvocation(MethodInvocation node) {
MethodInvocation copy = new MethodInvocation(_cloneNode(node.target),
_mapToken(node.operator), _cloneNode(node.methodName),
- _cloneNode(node.argumentList));
+ _cloneNode(node.typeArguments), _cloneNode(node.argumentList));
copy.propagatedType = node.propagatedType;
copy.staticType = node.staticType;
return copy;
@@ -11416,7 +11513,7 @@
* >
* > methodSignature ::=
* > 'external'? ('abstract' | 'static')? [Type]? ('get' | 'set')?
- * > methodName [FormalParameterList]
+ * > methodName [TypeParameterList] [FormalParameterList]
* >
* > methodName ::=
* > [SimpleIdentifier]
@@ -11458,6 +11555,12 @@
SimpleIdentifier _name;
/**
+ * The type parameters associated with the method, or `null` if the method is
+ * not a generic method.
+ */
+ TypeParameterList _typeParameters;
+
+ /**
* The parameters associated with the method, or `null` if this method
* declares a getter.
*/
@@ -11482,10 +11585,12 @@
MethodDeclaration(Comment comment, List<Annotation> metadata,
this.externalKeyword, this.modifierKeyword, TypeName returnType,
this.propertyKeyword, this.operatorKeyword, SimpleIdentifier name,
- FormalParameterList parameters, FunctionBody body)
+ TypeParameterList typeParameters, FormalParameterList parameters,
+ FunctionBody body)
: super(comment, metadata) {
_returnType = _becomeParentOf(returnType);
_name = _becomeParentOf(name);
+ _typeParameters = _becomeParentOf(typeParameters);
_parameters = _becomeParentOf(parameters);
_body = _becomeParentOf(body);
}
@@ -11612,6 +11717,20 @@
_returnType = _becomeParentOf(typeName);
}
+ /**
+ * Return the type parameters associated with this method, or `null` if this
+ * method is not a generic method.
+ */
+ TypeParameterList get typeParameters => _typeParameters;
+
+ /**
+ * Set the type parameters associated with this method to the given
+ * [typeParameters].
+ */
+ void set typeParameters(TypeParameterList typeParameters) {
+ _typeParameters = _becomeParentOf(typeParameters);
+ }
+
@override
accept(AstVisitor visitor) => visitor.visitMethodDeclaration(this);
@@ -11620,6 +11739,7 @@
super.visitChildren(visitor);
_safelyVisitChild(_returnType, visitor);
_safelyVisitChild(_name, visitor);
+ _safelyVisitChild(_typeParameters, visitor);
_safelyVisitChild(_parameters, visitor);
_safelyVisitChild(_body, visitor);
}
@@ -11632,7 +11752,7 @@
* represented by either [PrefixedIdentifier] or [PropertyAccess] nodes.
*
* > methodInvoction ::=
- * > ([Expression] '.')? [SimpleIdentifier] [ArgumentList]
+ * > ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]
*/
class MethodInvocation extends Expression {
/**
@@ -11655,6 +11775,12 @@
SimpleIdentifier _methodName;
/**
+ * The type arguments to be applied to the method being invoked, or `null` if
+ * no type arguments were provided.
+ */
+ TypeArgumentList _typeArguments;
+
+ /**
* The list of arguments to the method.
*/
ArgumentList _argumentList;
@@ -11664,9 +11790,11 @@
* can be `null` if there is no target.
*/
MethodInvocation(Expression target, this.operator,
- SimpleIdentifier methodName, ArgumentList argumentList) {
+ SimpleIdentifier methodName, TypeArgumentList typeArguments,
+ ArgumentList argumentList) {
_target = _becomeParentOf(target);
_methodName = _becomeParentOf(methodName);
+ _typeArguments = _becomeParentOf(typeArguments);
_argumentList = _becomeParentOf(argumentList);
}
@@ -11783,6 +11911,20 @@
_target = _becomeParentOf(expression);
}
+ /**
+ * Return the type arguments to be applied to the method being invoked, or
+ * `null` if no type arguments were provided.
+ */
+ TypeArgumentList get typeArguments => _typeArguments;
+
+ /**
+ * Set the type arguments to be applied to the method being invoked to the
+ * given [typeArguments].
+ */
+ void set typeArguments(TypeArgumentList typeArguments) {
+ _typeArguments = _becomeParentOf(typeArguments);
+ }
+
@override
accept(AstVisitor visitor) => visitor.visitMethodInvocation(this);
@@ -11790,6 +11932,7 @@
void visitChildren(AstVisitor visitor) {
_safelyVisitChild(_target, visitor);
_safelyVisitChild(_methodName, visitor);
+ _safelyVisitChild(_typeArguments, visitor);
_safelyVisitChild(_argumentList, visitor);
}
}
@@ -12466,6 +12609,7 @@
bool visitAwaitExpression(AwaitExpression node) {
if (identical(node.expression, _oldNode)) {
node.expression = _newNode as Expression;
+ return true;
}
return visitNode(node);
}
@@ -13492,6 +13636,7 @@
bool visitYieldStatement(YieldStatement node) {
if (identical(node.expression, _oldNode)) {
node.expression = _newNode as Expression;
+ return true;
}
return visitNode(node);
}
@@ -17765,6 +17910,7 @@
_visitNodeWithSuffix(node.type, " ");
_writer.print("this.");
_visitNode(node.identifier);
+ _visitNode(node.typeParameters);
_visitNode(node.parameters);
return null;
}
@@ -17853,6 +17999,7 @@
@override
Object visitFunctionExpression(FunctionExpression node) {
+ _visitNode(node.typeParameters);
_visitNode(node.parameters);
_writer.print(' ');
_visitNode(node.body);
@@ -17862,6 +18009,7 @@
@override
Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
_visitNode(node.function);
+ _visitNode(node.typeArguments);
_visitNode(node.argumentList);
return null;
}
@@ -17882,6 +18030,7 @@
Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
_visitNodeWithSuffix(node.returnType, " ");
_visitNode(node.identifier);
+ _visitNode(node.typeParameters);
_visitNode(node.parameters);
return null;
}
@@ -18055,6 +18204,7 @@
_visitTokenWithSuffix(node.operatorKeyword, " ");
_visitNode(node.name);
if (!node.isGetter) {
+ _visitNode(node.typeParameters);
_visitNode(node.parameters);
}
_visitFunctionWithPrefix(" ", node.body);
@@ -18072,6 +18222,7 @@
}
}
_visitNode(node.methodName);
+ _visitNode(node.typeArguments);
_visitNode(node.argumentList);
return null;
}
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 88bae32..7d3f7e6 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -20,7 +20,6 @@
import 'package:analyzer/src/plugin/options_plugin.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/src/task/task_dart.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart' show Document;
@@ -2639,6 +2638,7 @@
return changedSources.length > 0;
}
+ @deprecated
@override
void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
DataDescriptor rowDesc, CacheState state)) {
@@ -2702,9 +2702,7 @@
}
}
- /**
- * Visit all entries of the content cache.
- */
+ @override
void visitContentCache(ContentCacheVisitor visitor) {
_contentCache.accept(visitor);
}
@@ -4248,28 +4246,6 @@
}
/**
- * Record the results produced by performing a [task] and return the cache
- * entry associated with the results.
- */
- DartEntry _recordBuildUnitElementTask(BuildUnitElementTask task) {
- Source source = task.source;
- Source library = task.library;
- DartEntry dartEntry = _cache.get(source);
- CaughtException thrownException = task.exception;
- if (thrownException != null) {
- dartEntry.recordBuildElementErrorInLibrary(library, thrownException);
- throw new AnalysisException('<rethrow>', thrownException);
- }
- dartEntry.setValueInLibrary(DartEntry.BUILT_UNIT, library, task.unit);
- dartEntry.setValueInLibrary(
- DartEntry.BUILT_ELEMENT, library, task.unitElement);
- ChangeNoticeImpl notice = getNotice(source);
- LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
- notice.setErrors(dartEntry.allErrors, lineInfo);
- return dartEntry;
- }
-
- /**
* Given a [dartEntry] and a [library] element, record the library element and
* other information gleaned from the element in the cache entry.
*/
@@ -4841,10 +4817,6 @@
AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
@override
- DartEntry visitBuildUnitElementTask(BuildUnitElementTask task) =>
- AnalysisContextImpl_this._recordBuildUnitElementTask(task);
-
- @override
DartEntry visitGenerateDartErrorsTask(GenerateDartErrorsTask task) =>
AnalysisContextImpl_this._recordGenerateDartErrorsTask(task);
@@ -5810,6 +5782,12 @@
bool useTaskModel = false;
/**
+ * A flag indicating whether the task model should attempt to limit
+ * invalidation after a change.
+ */
+ bool limitInvalidationInTaskModel = false;
+
+ /**
* The task manager used to manage the tasks used to analyze code.
*/
TaskManager _taskManager;
@@ -6110,6 +6088,11 @@
bool get enableEnum;
/**
+ * Return `true` to enable generic methods (DEP 22).
+ */
+ bool get enableGenericMethods => null;
+
+ /**
* Return `true` to enable null-aware operators (DEP 9).
*/
bool get enableNullAwareOperators;
@@ -6208,6 +6191,11 @@
bool dart2jsHint = true;
/**
+ * A flag indicating whether generic methods are to be supported (DEP 22).
+ */
+ bool enableGenericMethods = false;
+
+ /**
* A flag indicating whether null-aware operators should be parsed (DEP 9).
*/
bool enableNullAwareOperators = false;
@@ -6528,12 +6516,6 @@
* Visit the given [task], returning the result of the visit. This method will
* throw an AnalysisException if the visitor throws an exception.
*/
- E visitBuildUnitElementTask(BuildUnitElementTask task);
-
- /**
- * Visit the given [task], returning the result of the visit. This method will
- * throw an AnalysisException if the visitor throws an exception.
- */
E visitGenerateDartErrorsTask(GenerateDartErrorsTask task);
/**
@@ -9321,8 +9303,14 @@
/**
* Call the given callback function for eache cache item in the context.
*/
+ @deprecated
void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
DataDescriptor rowDesc, CacheState state));
+
+ /**
+ * Visit all entries of the content cache.
+ */
+ void visitContentCache(ContentCacheVisitor visitor);
}
/**
@@ -9554,6 +9542,7 @@
AnalysisOptions options = context.analysisOptions;
parser.parseFunctionBodies =
options.analyzeFunctionBodiesPredicate(source);
+ parser.parseGenericMethods = options.enableGenericMethods;
_unit = parser.parseCompilationUnit(_tokenStream);
_unit.lineInfo = lineInfo;
AnalysisContext analysisContext = context;
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 3a3374a..3cc0626 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -361,17 +361,19 @@
node.name.staticElement = element;
_setLocalElements(element, newElement);
} on _DeclarationMismatchException {
- _addedElements.add(newElement);
_removeElement(element);
// add new element
- if (newElement is MethodElement) {
- List<MethodElement> methods = _enclosingClass.methods;
- methods.add(newElement);
- _enclosingClass.methods = methods;
- } else {
- List<PropertyAccessorElement> accessors = _enclosingClass.accessors;
- accessors.add(newElement);
- _enclosingClass.accessors = accessors;
+ if (newElement != null) {
+ _addedElements.add(newElement);
+ if (newElement is MethodElement) {
+ List<MethodElement> methods = _enclosingClass.methods;
+ methods.add(newElement);
+ _enclosingClass.methods = methods;
+ } else {
+ List<PropertyAccessorElement> accessors = _enclosingClass.accessors;
+ accessors.add(newElement);
+ _enclosingClass.accessors = accessors;
+ }
}
}
}
@@ -520,6 +522,29 @@
}
}
+ /**
+ * Asserts that there is an import with the same prefix as the given
+ * [prefixNode], which exposes the given [element].
+ */
+ void _assertElementVisibleWithPrefix(
+ SimpleIdentifier prefixNode, Element element) {
+ if (prefixNode == null) {
+ return;
+ }
+ String prefixName = prefixNode.name;
+ for (ImportElement import in _enclosingLibrary.imports) {
+ if (import.prefix != null && import.prefix.name == prefixName) {
+ Namespace namespace =
+ new NamespaceBuilder().createImportNamespaceForDirective(import);
+ Iterable<Element> visibleElements = namespace.definedNames.values;
+ if (visibleElements.contains(element)) {
+ return;
+ }
+ }
+ }
+ _assertTrue(false);
+ }
+
void _assertEquals(Object a, Object b) {
if (a != b) {
throw new _DeclarationMismatchException();
@@ -619,29 +644,6 @@
}
}
- /**
- * Asserts that there is an import with the same prefix as the given
- * [prefixNode], which exposes the given [element].
- */
- void _assertElementVisibleWithPrefix(
- SimpleIdentifier prefixNode, Element element) {
- if (prefixNode == null) {
- return;
- }
- String prefixName = prefixNode.name;
- for (ImportElement import in _enclosingLibrary.imports) {
- if (import.prefix != null && import.prefix.name == prefixName) {
- Namespace namespace =
- new NamespaceBuilder().createImportNamespaceForDirective(import);
- Iterable<Element> visibleElements = namespace.definedNames.values;
- if (visibleElements.contains(element)) {
- return;
- }
- }
- }
- _assertTrue(false);
- }
-
void _assertSameTypeParameter(
TypeParameter node, TypeParameterElement element) {
_assertSameType(node.bound, element.bound);
@@ -790,10 +792,12 @@
static void _setLocalElements(
ExecutableElementImpl to, ExecutableElement from) {
- to.functions = from.functions;
- to.labels = from.labels;
- to.localVariables = from.localVariables;
- to.parameters = from.parameters;
+ if (from != null) {
+ to.functions = from.functions;
+ to.labels = from.labels;
+ to.localVariables = from.localVariables;
+ to.parameters = from.parameters;
+ }
}
}
@@ -1395,9 +1399,13 @@
newParent is MethodDeclaration ||
oldParent is ConstructorDeclaration &&
newParent is ConstructorDeclaration) {
- oldNode = oldParent;
- newNode = newParent;
- found = true;
+ Element oldElement = (oldParent as Declaration).element;
+ if (new DeclarationMatcher().matches(newParent, oldElement) ==
+ DeclarationMatchKind.MATCH) {
+ oldNode = oldParent;
+ newNode = newParent;
+ found = true;
+ }
}
if (oldParent is FunctionBody && newParent is FunctionBody) {
oldNode = oldParent;
@@ -1471,6 +1479,8 @@
Token token = _scan(code);
RecordingErrorListener errorListener = new RecordingErrorListener();
Parser parser = new Parser(_unitSource, errorListener);
+ AnalysisOptions options = _unitElement.context.analysisOptions;
+ parser.parseGenericMethods = options.enableGenericMethods;
CompilationUnit unit = parser.parseCompilationUnit(token);
_newParseErrors = errorListener.errors;
return unit;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 2997468..8581fa4 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -7,8 +7,8 @@
library engine.parser;
-import "dart:math" as math;
import 'dart:collection';
+import "dart:math" as math;
import 'ast.dart';
import 'engine.dart' show AnalysisEngine, AnalysisOptionsImpl;
@@ -263,10 +263,10 @@
0, (Parser target) => target._parseLogicalAndExpression()),
'parseMapLiteral_2': new MethodTrampoline(
2, (Parser target, arg0, arg1) => target._parseMapLiteral(arg0, arg1)),
- 'parseMethodDeclarationAfterParameters_6': new MethodTrampoline(6,
- (Parser target, arg0, arg1, arg2, arg3, arg4, arg5) => target
+ 'parseMethodDeclarationAfterParameters_7': new MethodTrampoline(7,
+ (Parser target, arg0, arg1, arg2, arg3, arg4, arg5, arg6) => target
._parseMethodDeclarationAfterParameters(
- arg0, arg1, arg2, arg3, arg4, arg5)),
+ arg0, arg1, arg2, arg3, arg4, arg5, arg6)),
'parseMethodDeclarationAfterReturnType_4': new MethodTrampoline(4,
(Parser target, arg0, arg1, arg2, arg3) => target
._parseMethodDeclarationAfterReturnType(arg0, arg1, arg2, arg3)),
@@ -2080,6 +2080,11 @@
bool _inInitializer = false;
/**
+ * A flag indicating whether the parser is to parse generic method syntax.
+ */
+ bool parseGenericMethods = false;
+
+ /**
* Initialize a newly created parser to parse the content of the given
* [_source] and to report any errors that are found to the given
* [_errorListener].
@@ -2328,7 +2333,8 @@
_peek().matchesAny([
TokenType.OPEN_PAREN,
TokenType.OPEN_CURLY_BRACKET,
- TokenType.FUNCTION
+ TokenType.FUNCTION,
+ TokenType.LT
])) {
_validateModifiersForGetterOrSetterOrMethod(modifiers);
return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
@@ -2440,7 +2446,7 @@
//
return new MethodDeclaration(commentAndMetadata.comment,
commentAndMetadata.metadata, null, null, null, null, null,
- _createSyntheticIdentifier(), new FormalParameterList(
+ _createSyntheticIdentifier(), null, new FormalParameterList(
null, new List<FormalParameter>(), null, null, null),
new EmptyFunctionBody(_createSyntheticToken(TokenType.SEMICOLON)));
}
@@ -2466,7 +2472,7 @@
_validateFormalParameterList(parameters);
return _parseMethodDeclarationAfterParameters(commentAndMetadata,
modifiers.externalKeyword, modifiers.staticKeyword, null, methodName,
- parameters);
+ null, parameters);
} else if (_peek()
.matchesAny([TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
if (modifiers.constKeyword == null &&
@@ -2483,6 +2489,12 @@
// function type alias that was parsed.
_parseFunctionTypeAlias(commentAndMetadata, getAndAdvance());
return null;
+ } else if (parseGenericMethods) {
+ Token token = _skipTypeParameterList(_peek());
+ if (token != null && _tokenMatches(token, TokenType.OPEN_PAREN)) {
+ return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
+ modifiers.externalKeyword, modifiers.staticKeyword, null);
+ }
}
TypeName type = parseTypeName();
if (_matchesKeyword(Keyword.GET) && _tokenMatchesIdentifier(_peek())) {
@@ -2546,7 +2558,10 @@
_validateFormalParameterList(parameters);
return _parseMethodDeclarationAfterParameters(commentAndMetadata,
modifiers.externalKeyword, modifiers.staticKeyword, type, methodName,
- parameters);
+ null, parameters);
+ } else if (parseGenericMethods && _tokenMatches(_peek(), TokenType.LT)) {
+ return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
+ modifiers.externalKeyword, modifiers.staticKeyword, type);
} else if (_tokenMatches(_peek(), TokenType.OPEN_CURLY_BRACKET)) {
// We have found "TypeName identifier {", and are guessing that this is a
// getter without the keyword 'get'.
@@ -3036,14 +3051,18 @@
* parsed.
*
* functionExpression ::=
- * formalParameterList functionExpressionBody
+ * typeParameters? formalParameterList functionExpressionBody
*/
FunctionExpression parseFunctionExpression() {
+ TypeParameterList typeParameters = null;
+ if (parseGenericMethods && _matches(TokenType.LT)) {
+ typeParameters = parseTypeParameterList();
+ }
FormalParameterList parameters = parseFormalParameterList();
_validateFormalParameterList(parameters);
FunctionBody body =
_parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTION_BODY, true);
- return new FunctionExpression(parameters, body);
+ return new FunctionExpression(typeParameters, parameters, body);
}
/**
@@ -3146,7 +3165,7 @@
* | simpleFormalParameter
*
* functionSignature:
- * metadata returnType? identifier formalParameterList
+ * metadata returnType? identifier typeParameters? formalParameterList
*
* fieldFormalParameter ::=
* metadata finalConstVarOrType? 'this' '.' identifier
@@ -3165,6 +3184,10 @@
period = _expect(TokenType.PERIOD);
}
SimpleIdentifier identifier = parseSimpleIdentifier();
+ TypeParameterList typeParameters = null;
+ if (parseGenericMethods && _matches(TokenType.LT)) {
+ typeParameters = parseTypeParameterList();
+ }
if (_matches(TokenType.OPEN_PAREN)) {
FormalParameterList parameters = parseFormalParameterList();
if (thisKeyword == null) {
@@ -3173,12 +3196,17 @@
ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, holder.keyword);
}
return new FunctionTypedFormalParameter(commentAndMetadata.comment,
- commentAndMetadata.metadata, holder.type, identifier, parameters);
+ commentAndMetadata.metadata, holder.type, identifier,
+ typeParameters, parameters);
} else {
return new FieldFormalParameter(commentAndMetadata.comment,
commentAndMetadata.metadata, holder.keyword, holder.type,
- thisKeyword, period, identifier, parameters);
+ thisKeyword, period, identifier, typeParameters, parameters);
}
+ } else if (typeParameters != null) {
+ // TODO(brianwilkerson) Report an error. It looks like a function-typed
+ // parameter with no parameter list.
+ //_reportErrorForToken(ParserErrorCode.MISSING_PARAMETERS, typeParameters.endToken);
}
TypeName type = holder.type;
if (type != null) {
@@ -3191,9 +3219,12 @@
}
}
if (thisKeyword != null) {
+ // TODO(brianwilkerson) If there are type parameters but no parameters,
+ // should we create a synthetic empty parameter list here so we can
+ // capture the type parameters?
return new FieldFormalParameter(commentAndMetadata.comment,
commentAndMetadata.metadata, holder.keyword, holder.type, thisKeyword,
- period, identifier, null);
+ period, identifier, null, null);
}
return new SimpleFormalParameter(commentAndMetadata.comment,
commentAndMetadata.metadata, holder.keyword, holder.type, identifier);
@@ -3482,7 +3513,8 @@
FunctionDeclaration _convertToFunctionDeclaration(MethodDeclaration method) =>
new FunctionDeclaration(method.documentationComment, method.metadata,
method.externalKeyword, method.returnType, method.propertyKeyword,
- method.name, new FunctionExpression(method.parameters, method.body));
+ method.name, new FunctionExpression(
+ method.typeParameters, method.parameters, method.body));
/**
* Return `true` if the current token could be the start of a compilation unit
@@ -3839,7 +3871,11 @@
if (_inInitializer) {
return false;
}
- Token afterParameters = _skipFormalParameterList(token);
+ Token afterTypeParameters = _skipTypeParameterList(token);
+ if (afterTypeParameters == null) {
+ afterTypeParameters = token;
+ }
+ Token afterParameters = _skipFormalParameterList(afterTypeParameters);
if (afterParameters == null) {
return false;
}
@@ -3916,6 +3952,17 @@
_tokenMatchesKeyword(token, Keyword.IN);
}
+ bool _isLikelyParameterList() {
+ if (_matches(TokenType.OPEN_PAREN)) {
+ return true;
+ }
+ if (!parseGenericMethods) {
+ return false;
+ }
+ Token token = _skipTypeArgumentList(_currentToken);
+ return token != null && _tokenMatches(token, TokenType.OPEN_PAREN);
+ }
+
/**
* Given that we have just found bracketed text within the given [comment],
* look to see whether that text is (a) followed by a parenthesized link
@@ -4004,7 +4051,8 @@
// The keyword 'void' isn't a valid identifier, so it should be assumed to
// be a type name.
return true;
- } else if (startToken.next != token) {
+ } else if (startToken.next != token &&
+ !_tokenMatches(token, TokenType.OPEN_PAREN)) {
// The type is more than a simple identifier, so it should be assumed to
// be a type name.
return true;
@@ -4177,22 +4225,27 @@
Expression expression = _parsePrimaryExpression();
bool isOptional = primaryAllowed || expression is SimpleIdentifier;
while (true) {
- while (_matches(TokenType.OPEN_PAREN)) {
+ while (_isLikelyParameterList()) {
+ TypeArgumentList typeArguments = null;
+ if (_matches(TokenType.LT)) {
+ typeArguments = parseTypeArgumentList();
+ }
ArgumentList argumentList = parseArgumentList();
if (expression is SimpleIdentifier) {
- expression = new MethodInvocation(
- null, null, expression as SimpleIdentifier, argumentList);
+ expression = new MethodInvocation(null, null,
+ expression as SimpleIdentifier, typeArguments, argumentList);
} else if (expression is PrefixedIdentifier) {
PrefixedIdentifier identifier = expression as PrefixedIdentifier;
expression = new MethodInvocation(identifier.prefix,
- identifier.period, identifier.identifier, argumentList);
+ identifier.period, identifier.identifier, typeArguments,
+ argumentList);
} else if (expression is PropertyAccess) {
PropertyAccess access = expression as PropertyAccess;
expression = new MethodInvocation(access.target, access.operator,
- access.propertyName, argumentList);
+ access.propertyName, typeArguments, argumentList);
} else {
- expression =
- new FunctionExpressionInvocation(expression, argumentList);
+ expression = new FunctionExpressionInvocation(
+ expression, typeArguments, argumentList);
}
if (!primaryAllowed) {
isOptional = false;
@@ -4344,7 +4397,8 @@
* method invocation.
*
* cascadeSection ::=
- * '..' (cascadeSelector arguments*) (assignableSelector arguments*)* cascadeAssignment?
+ * '..' (cascadeSelector typeArguments? arguments*)
+ * (assignableSelector typeArguments? arguments*)* cascadeAssignment?
*
* cascadeSelector ::=
* '[' expression ']'
@@ -4379,20 +4433,24 @@
}
assert((expression == null && functionName != null) ||
(expression != null && functionName == null));
- if (_currentToken.type == TokenType.OPEN_PAREN) {
- while (_currentToken.type == TokenType.OPEN_PAREN) {
+ if (_isLikelyParameterList()) {
+ while (_isLikelyParameterList()) {
+ TypeArgumentList typeArguments = null;
+ if (_matches(TokenType.LT)) {
+ typeArguments = parseTypeArgumentList();
+ }
if (functionName != null) {
- expression = new MethodInvocation(
- expression, period, functionName, parseArgumentList());
+ expression = new MethodInvocation(expression, period, functionName,
+ typeArguments, parseArgumentList());
period = null;
functionName = null;
} else if (expression == null) {
// It should not be possible to get here.
expression = new MethodInvocation(expression, period,
- _createSyntheticIdentifier(), parseArgumentList());
+ _createSyntheticIdentifier(), typeArguments, parseArgumentList());
} else {
- expression =
- new FunctionExpressionInvocation(expression, parseArgumentList());
+ expression = new FunctionExpressionInvocation(
+ expression, typeArguments, parseArgumentList());
}
}
} else if (functionName != null) {
@@ -4407,15 +4465,19 @@
if (!identical(selector, expression)) {
expression = selector;
progress = true;
- while (_currentToken.type == TokenType.OPEN_PAREN) {
+ while (_isLikelyParameterList()) {
+ TypeArgumentList typeArguments = null;
+ if (_matches(TokenType.LT)) {
+ typeArguments = parseTypeArgumentList();
+ }
if (expression is PropertyAccess) {
PropertyAccess propertyAccess = expression as PropertyAccess;
expression = new MethodInvocation(propertyAccess.target,
propertyAccess.operator, propertyAccess.propertyName,
- parseArgumentList());
+ typeArguments, parseArgumentList());
} else {
expression = new FunctionExpressionInvocation(
- expression, parseArgumentList());
+ expression, typeArguments, parseArgumentList());
}
}
}
@@ -5751,6 +5813,10 @@
keyword = getAndAdvance();
}
SimpleIdentifier name = parseSimpleIdentifier();
+ TypeParameterList typeParameters = null;
+ if (parseGenericMethods && _matches(TokenType.LT)) {
+ typeParameters = parseTypeParameterList();
+ }
FormalParameterList parameters = null;
if (!isGetter) {
if (_matches(TokenType.OPEN_PAREN)) {
@@ -5781,7 +5847,7 @@
// }
return new FunctionDeclaration(commentAndMetadata.comment,
commentAndMetadata.metadata, externalKeyword, returnType, keyword, name,
- new FunctionExpression(parameters, body));
+ new FunctionExpression(typeParameters, parameters, body));
}
/**
@@ -5908,7 +5974,7 @@
}
return new MethodDeclaration(commentAndMetadata.comment,
commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType,
- propertyKeyword, null, name, null, body);
+ propertyKeyword, null, name, null, null, body);
}
/**
@@ -6229,7 +6295,7 @@
MethodDeclaration _parseMethodDeclarationAfterParameters(
CommentAndMetadata commentAndMetadata, Token externalKeyword,
Token staticKeyword, TypeName returnType, SimpleIdentifier name,
- FormalParameterList parameters) {
+ TypeParameterList typeParameters, FormalParameterList parameters) {
FunctionBody body = _parseFunctionBody(
externalKeyword != null || staticKeyword == null,
ParserErrorCode.MISSING_FUNCTION_BODY, false);
@@ -6244,7 +6310,7 @@
}
return new MethodDeclaration(commentAndMetadata.comment,
commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType,
- null, null, name, parameters, body);
+ null, null, name, typeParameters, parameters, body);
}
/**
@@ -6263,6 +6329,10 @@
CommentAndMetadata commentAndMetadata, Token externalKeyword,
Token staticKeyword, TypeName returnType) {
SimpleIdentifier methodName = parseSimpleIdentifier();
+ TypeParameterList typeParameters = null;
+ if (parseGenericMethods && _matches(TokenType.LT)) {
+ typeParameters = parseTypeParameterList();
+ }
FormalParameterList parameters;
if (!_matches(TokenType.OPEN_PAREN) &&
(_matches(TokenType.OPEN_CURLY_BRACKET) ||
@@ -6277,7 +6347,8 @@
}
_validateFormalParameterList(parameters);
return _parseMethodDeclarationAfterParameters(commentAndMetadata,
- externalKeyword, staticKeyword, returnType, methodName, parameters);
+ externalKeyword, staticKeyword, returnType, methodName, typeParameters,
+ parameters);
}
/**
@@ -6633,7 +6704,7 @@
}
return new MethodDeclaration(commentAndMetadata.comment,
commentAndMetadata.metadata, externalKeyword, null, returnType, null,
- operatorKeyword, name, parameters, body);
+ operatorKeyword, name, null, parameters, body);
}
/**
@@ -6704,16 +6775,22 @@
if (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
_matches(TokenType.PERIOD) ||
_matches(TokenType.QUESTION_PERIOD) ||
- _matches(TokenType.OPEN_PAREN)) {
+ _matches(TokenType.OPEN_PAREN) ||
+ (parseGenericMethods && _matches(TokenType.LT))) {
do {
- if (_matches(TokenType.OPEN_PAREN)) {
+ if (_isLikelyParameterList()) {
+ TypeArgumentList typeArguments = null;
+ if (_matches(TokenType.LT)) {
+ typeArguments = parseTypeArgumentList();
+ }
ArgumentList argumentList = parseArgumentList();
if (operand is PropertyAccess) {
PropertyAccess access = operand as PropertyAccess;
operand = new MethodInvocation(access.target, access.operator,
- access.propertyName, argumentList);
+ access.propertyName, typeArguments, argumentList);
} else {
- operand = new FunctionExpressionInvocation(operand, argumentList);
+ operand = new FunctionExpressionInvocation(
+ operand, typeArguments, argumentList);
}
} else {
operand = _parseAssignableSelector(operand, true);
@@ -6971,7 +7048,7 @@
}
return new MethodDeclaration(commentAndMetadata.comment,
commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType,
- propertyKeyword, null, name, parameters, body);
+ propertyKeyword, null, name, null, parameters, body);
}
/**
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index 21dff72..bcdb33d 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -103,11 +103,23 @@
/**
* The name of the directory within the SDK directory that contains the
- * libraries file.
+ * sdk_library_metadata directory.
*/
static String _INTERNAL_DIR = "_internal";
/**
+ * The name of the sdk_library_metadata directory that contains the package
+ * holding the libraries.dart file.
+ */
+ static String _SDK_LIBRARY_METADATA_DIR = "sdk_library_metadata";
+
+ /**
+ * The name of the directory within the sdk_library_metadata that contains
+ * libraries.dart.
+ */
+ static String _SDK_LIBRARY_METADATA_LIB_DIR = "lib";
+
+ /**
* The name of the directory within the SDK directory that contains the
* libraries.
*/
@@ -463,7 +475,11 @@
*/
LibraryMap initialLibraryMap(bool useDart2jsPaths) {
JavaFile librariesFile = new JavaFile.relative(
- new JavaFile.relative(libraryDirectory, _INTERNAL_DIR),
+ new JavaFile.relative(
+ new JavaFile.relative(
+ new JavaFile.relative(libraryDirectory, _INTERNAL_DIR),
+ _SDK_LIBRARY_METADATA_DIR),
+ _SDK_LIBRARY_METADATA_LIB_DIR),
_LIBRARIES_FILE);
try {
String contents = librariesFile.readAsStringSync();
@@ -515,14 +531,15 @@
/**
* An object used to read and parse the libraries file
- * (dart-sdk/lib/_internal/libraries.dart) for information about the libraries
- * in an SDK. The library information is represented as a Dart file containing a
- * single top-level variable whose value is a const map. The keys of the map are
- * the names of libraries defined in the SDK and the values in the map are info
- * objects defining the library. For example, a subset of a typical SDK might
- * have a libraries file that looks like the following:
+ * (dart-sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart) for information
+ * about the libraries in an SDK. The library information is represented as a
+ * Dart file containing a single top-level variable whose value is a const map.
+ * The keys of the map are the names of libraries defined in the SDK and the
+ * values in the map are info objects defining the library. For example, a
+ * subset of a typical SDK might have a libraries file that looks like the
+ * following:
*
- * final Map<String, LibraryInfo> LIBRARIES = const <LibraryInfo> {
+ * final Map<String, LibraryInfo> LIBRARIES = const <LibraryInfo> {
* // Used by VM applications
* "builtin" : const LibraryInfo(
* "builtin/builtin_runtime.dart",
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
index 6125a9c..b0702c7 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
@@ -112,7 +112,7 @@
static MethodInvocation cascadedMethodInvocation(String methodName,
[List<Expression> arguments]) => new MethodInvocation(null,
TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD),
- identifier3(methodName), argumentList(arguments));
+ identifier3(methodName), null, argumentList(arguments));
static PropertyAccess cascadedPropertyAccess(String propertyName) =>
new PropertyAccess(null,
@@ -362,7 +362,7 @@
null, keyword == null ? null : TokenFactory.tokenFromKeyword(keyword),
type, TokenFactory.tokenFromKeyword(Keyword.THIS),
TokenFactory.tokenFromType(TokenType.PERIOD), identifier3(identifier),
- parameterList);
+ null, parameterList);
static FieldFormalParameter fieldFormalParameter2(String identifier) =>
fieldFormalParameter(null, null, identifier);
@@ -417,20 +417,31 @@
functionDeclaration(type, keyword, name, functionExpression));
static FunctionExpression functionExpression() =>
- new FunctionExpression(formalParameterList(), blockFunctionBody2());
+ new FunctionExpression(null, formalParameterList(), blockFunctionBody2());
static FunctionExpression functionExpression2(
FormalParameterList parameters, FunctionBody body) =>
- new FunctionExpression(parameters, body);
+ new FunctionExpression(null, parameters, body);
+
+ static FunctionExpression functionExpression3(
+ TypeParameterList typeParameters, FormalParameterList parameters,
+ FunctionBody body) =>
+ new FunctionExpression(typeParameters, parameters, body);
static FunctionExpressionInvocation functionExpressionInvocation(
Expression function, [List<Expression> arguments]) =>
- new FunctionExpressionInvocation(function, argumentList(arguments));
+ functionExpressionInvocation2(function, null, arguments);
+
+ static FunctionExpressionInvocation functionExpressionInvocation2(
+ Expression function,
+ [TypeArgumentList typeArguments, List<Expression> arguments]) =>
+ new FunctionExpressionInvocation(
+ function, typeArguments, argumentList(arguments));
static FunctionTypedFormalParameter functionTypedFormalParameter(
TypeName returnType, String identifier,
[List<FormalParameter> parameters]) => new FunctionTypedFormalParameter(
- null, null, returnType, identifier3(identifier),
+ null, null, returnType, identifier3(identifier), null,
formalParameterList(parameters));
static HideCombinator hideCombinator(List<SimpleIdentifier> identifiers) =>
@@ -610,7 +621,7 @@
returnType,
property == null ? null : TokenFactory.tokenFromKeyword(property),
operator == null ? null : TokenFactory.tokenFromKeyword(operator), name,
- parameters, emptyFunctionBody());
+ null, parameters, emptyFunctionBody());
static MethodDeclaration methodDeclaration2(Keyword modifier,
TypeName returnType, Keyword property, Keyword operator,
@@ -620,18 +631,36 @@
returnType,
property == null ? null : TokenFactory.tokenFromKeyword(property),
operator == null ? null : TokenFactory.tokenFromKeyword(operator), name,
- parameters, body);
+ null, parameters, body);
+
+ static MethodDeclaration methodDeclaration3(Keyword modifier,
+ TypeName returnType, Keyword property, Keyword operator,
+ SimpleIdentifier name, TypeParameterList typeParameters,
+ FormalParameterList parameters,
+ FunctionBody body) => new MethodDeclaration(null, null, null,
+ modifier == null ? null : TokenFactory.tokenFromKeyword(modifier),
+ returnType,
+ property == null ? null : TokenFactory.tokenFromKeyword(property),
+ operator == null ? null : TokenFactory.tokenFromKeyword(operator), name,
+ typeParameters, parameters, body);
static MethodInvocation methodInvocation(Expression target, String methodName,
[List<Expression> arguments,
TokenType operator = TokenType.PERIOD]) => new MethodInvocation(target,
target == null ? null : TokenFactory.tokenFromType(operator),
- identifier3(methodName), argumentList(arguments));
+ identifier3(methodName), null, argumentList(arguments));
static MethodInvocation methodInvocation2(String methodName,
[List<Expression> arguments]) =>
methodInvocation(null, methodName, arguments);
+ static MethodInvocation methodInvocation3(
+ Expression target, String methodName, TypeArgumentList typeArguments,
+ [List<Expression> arguments,
+ TokenType operator = TokenType.PERIOD]) => new MethodInvocation(target,
+ target == null ? null : TokenFactory.tokenFromType(operator),
+ identifier3(methodName), typeArguments, argumentList(arguments));
+
static NamedExpression namedExpression(Label label, Expression expression) =>
new NamedExpression(label, expression);
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index d95454d..6269cf7 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -70,7 +70,8 @@
registerExtension(taskId, BuildLibraryConstructorsTask.DESCRIPTOR);
registerExtension(taskId, BuildLibraryElementTask.DESCRIPTOR);
registerExtension(taskId, BuildPublicNamespaceTask.DESCRIPTOR);
- registerExtension(taskId, BuildSourceClosuresTask.DESCRIPTOR);
+ registerExtension(taskId, BuildSourceExportClosureTask.DESCRIPTOR);
+ registerExtension(taskId, BuildSourceImportExportClosureTask.DESCRIPTOR);
registerExtension(taskId, BuildTypeProviderTask.DESCRIPTOR);
registerExtension(taskId, ComputeConstantDependenciesTask.DESCRIPTOR);
registerExtension(taskId, ComputeConstantValueTask.DESCRIPTOR);
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index bf53bb2..849ae33 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -172,15 +172,6 @@
new ListResultDescriptor<Source>('IMPORT_EXPORT_SOURCE_CLOSURE', null);
/**
- * The sources representing the import closure of a library.
- * The [Source]s include only library sources, not their units.
- *
- * The result is only available for [Source]s representing a library.
- */
-final ListResultDescriptor<Source> IMPORT_SOURCE_CLOSURE =
- new ListResultDescriptor<Source>('IMPORT_SOURCE_CLOSURE', null);
-
-/**
* The partial [LibraryElement] associated with a library.
*
* The [LibraryElement] and its [CompilationUnitElement]s are attached to each
@@ -282,6 +273,14 @@
'PARSE_ERRORS', AnalysisError.NO_ERRORS);
/**
+ * The names (resolved and not) referenced by a unit.
+ *
+ * The result is only available for [Source]s representing a compilation unit.
+ */
+final ResultDescriptor<ReferencedNames> REFERENCED_NAMES =
+ new ResultDescriptor<ReferencedNames>('REFERENCED_NAMES', null);
+
+/**
* The errors produced while resolving references.
*
* The list will be empty if there were no errors, but will not be `null`.
@@ -1507,21 +1506,65 @@
}
/**
- * A task that builds [IMPORT_SOURCE_CLOSURE] and [EXPORT_SOURCE_CLOSURE] of
- * a library.
+ * A task that builds [EXPORT_SOURCE_CLOSURE] of a library.
*/
-class BuildSourceClosuresTask extends SourceBasedAnalysisTask {
- /**
- * The name of the import closure.
- */
- static const String IMPORT_INPUT = 'IMPORT_INPUT';
-
+class BuildSourceExportClosureTask extends SourceBasedAnalysisTask {
/**
* The name of the export closure.
*/
static const String EXPORT_INPUT = 'EXPORT_INPUT';
/**
+ * The task descriptor describing this kind of task.
+ */
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'BuildSourceExportClosureTask', createTask, buildInputs,
+ <ResultDescriptor>[EXPORT_SOURCE_CLOSURE]);
+
+ BuildSourceExportClosureTask(
+ InternalAnalysisContext context, AnalysisTarget target)
+ : super(context, target);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ void internalPerform() {
+ List<Source> exportClosure = getRequiredInput(EXPORT_INPUT);
+ //
+ // Record output.
+ //
+ outputs[EXPORT_SOURCE_CLOSURE] = exportClosure;
+ }
+
+ /**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the
+ * given library [libSource].
+ */
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+ Source source = target;
+ return <String, TaskInput>{
+ EXPORT_INPUT: new _ExportSourceClosureTaskInput(source, LIBRARY_ELEMENT2)
+ };
+ }
+
+ /**
+ * Create a [BuildSourceExportClosureTask] based on the given [target] in
+ * the given [context].
+ */
+ static BuildSourceExportClosureTask createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new BuildSourceExportClosureTask(context, target);
+ }
+}
+
+/**
+ * A task that builds [IMPORT_EXPORT_SOURCE_CLOSURE] of a library, and also
+ * sets [IS_CLIENT].
+ */
+class BuildSourceImportExportClosureTask extends SourceBasedAnalysisTask {
+ /**
* The name of the import/export closure.
*/
static const String IMPORT_EXPORT_INPUT = 'IMPORT_EXPORT_INPUT';
@@ -1530,14 +1573,10 @@
* The task descriptor describing this kind of task.
*/
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
- 'BuildSourceClosuresTask', createTask, buildInputs, <ResultDescriptor>[
- IMPORT_SOURCE_CLOSURE,
- EXPORT_SOURCE_CLOSURE,
- IMPORT_EXPORT_SOURCE_CLOSURE,
- IS_CLIENT
- ]);
+ 'BuildSourceImportExportClosureTask', createTask, buildInputs,
+ <ResultDescriptor>[IMPORT_EXPORT_SOURCE_CLOSURE, IS_CLIENT]);
- BuildSourceClosuresTask(
+ BuildSourceImportExportClosureTask(
InternalAnalysisContext context, AnalysisTarget target)
: super(context, target);
@@ -1546,15 +1585,11 @@
@override
void internalPerform() {
- List<Source> importClosure = getRequiredInput(IMPORT_INPUT);
- List<Source> exportClosure = getRequiredInput(EXPORT_INPUT);
List<Source> importExportClosure = getRequiredInput(IMPORT_EXPORT_INPUT);
Source htmlSource = context.sourceFactory.forUri(DartSdk.DART_HTML);
//
// Record outputs.
//
- outputs[IMPORT_SOURCE_CLOSURE] = importClosure;
- outputs[EXPORT_SOURCE_CLOSURE] = exportClosure;
outputs[IMPORT_EXPORT_SOURCE_CLOSURE] = importExportClosure;
outputs[IS_CLIENT] = importExportClosure.contains(htmlSource);
}
@@ -1567,19 +1602,18 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
Source source = target;
return <String, TaskInput>{
- IMPORT_INPUT: new _ImportSourceClosureTaskInput(source),
- EXPORT_INPUT: new _ExportSourceClosureTaskInput(source),
- IMPORT_EXPORT_INPUT: new _ImportExportSourceClosureTaskInput(source)
+ IMPORT_EXPORT_INPUT:
+ new _ImportExportSourceClosureTaskInput(source, LIBRARY_ELEMENT2)
};
}
/**
- * Create a [BuildSourceClosuresTask] based on the given [target] in
- * the given [context].
+ * Create a [BuildSourceImportExportClosureTask] based on the given [target]
+ * in the given [context].
*/
- static BuildSourceClosuresTask createTask(
+ static BuildSourceImportExportClosureTask createTask(
AnalysisContext context, AnalysisTarget target) {
- return new BuildSourceClosuresTask(context, target);
+ return new BuildSourceImportExportClosureTask(context, target);
}
}
@@ -1900,6 +1934,102 @@
}
/**
+ * The description for a change in a Dart source.
+ */
+class DartDelta extends Delta {
+ bool hasDirectiveChange = false;
+
+ final Set<String> addedNames = new Set<String>();
+ final Set<String> changedNames = new Set<String>();
+ final Set<String> removedNames = new Set<String>();
+
+ final Set<Source> invalidatedSources = new Set<Source>();
+
+ DartDelta(Source source) : super(source) {
+ invalidatedSources.add(source);
+ }
+
+ void elementAdded(Element element) {
+ addedNames.add(element.name);
+ }
+
+ void elementChanged(Element element) {
+ changedNames.add(element.name);
+ }
+
+ void elementRemoved(Element element) {
+ removedNames.add(element.name);
+ }
+
+ bool isNameAffected(String name) {
+ return addedNames.contains(name) ||
+ changedNames.contains(name) ||
+ removedNames.contains(name);
+ }
+
+ bool nameChanged(String name) {
+ return changedNames.add(name);
+ }
+
+ @override
+ DeltaResult validate(InternalAnalysisContext context, AnalysisTarget target,
+ ResultDescriptor descriptor) {
+ if (hasDirectiveChange) {
+ return DeltaResult.INVALIDATE;
+ }
+ // Prepare target source.
+ Source targetSource = null;
+ if (target is Source) {
+ targetSource = target;
+ }
+ if (target is LibrarySpecificUnit) {
+ targetSource = target.library;
+ }
+ if (target is Element) {
+ targetSource = target.source;
+ }
+ // Keep results that are updated incrementally.
+ // If we want to analyze only some references to the source being changed,
+ // we need to keep the same instances of CompilationUnitElement and
+ // LibraryElement.
+ if (targetSource == source) {
+ if (ParseDartTask.DESCRIPTOR.results.contains(descriptor)) {
+ return DeltaResult.KEEP_CONTINUE;
+ }
+ if (BuildCompilationUnitElementTask.DESCRIPTOR.results
+ .contains(descriptor)) {
+ return DeltaResult.KEEP_CONTINUE;
+ }
+ if (BuildLibraryElementTask.DESCRIPTOR.results.contains(descriptor)) {
+ return DeltaResult.KEEP_CONTINUE;
+ }
+ return DeltaResult.INVALIDATE;
+ }
+ // Use the target library dependency information to decide whether
+ // the delta affects the library.
+ if (targetSource != null) {
+ List<Source> librarySources =
+ context.getLibrariesContaining(targetSource);
+ for (Source librarySource in librarySources) {
+ AnalysisCache cache = context.analysisCache;
+ ReferencedNames referencedNames =
+ cache.getValue(librarySource, REFERENCED_NAMES);
+ if (referencedNames == null) {
+ return DeltaResult.INVALIDATE;
+ }
+ referencedNames.addChangedElements(this);
+ if (referencedNames.isAffectedBy(this)) {
+ return DeltaResult.INVALIDATE;
+ }
+ }
+ return DeltaResult.STOP;
+ }
+ // We don't know what to do with the given target, invalidate it.
+ return DeltaResult.INVALIDATE;
+ }
+}
+
+/**
* A task that merges all of the errors for a single source into a single list
* of errors.
*/
@@ -2606,6 +2736,7 @@
Parser parser = new Parser(source, errorListener);
AnalysisOptions options = context.analysisOptions;
parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source);
+ parser.parseGenericMethods = options.enableGenericMethods;
CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
unit.lineInfo = lineInfo;
@@ -2776,6 +2907,104 @@
}
/**
+ * Information about a library - which names it uses, which names it defines
+ * with their externally visible dependencies.
+ */
+class ReferencedNames {
+ final Set<String> names = new Set<String>();
+ final Map<String, Set<String>> userToDependsOn = <String, Set<String>>{};
+
+ /**
+ * Updates [delta] by adding names that are changed in this library.
+ */
+ void addChangedElements(DartDelta delta) {
+ bool hasProgress = true;
+ while (hasProgress) {
+ hasProgress = false;
+ userToDependsOn.forEach((user, dependencies) {
+ for (String dependency in dependencies) {
+ if (delta.isNameAffected(dependency)) {
+ if (delta.nameChanged(user)) {
+ hasProgress = true;
+ }
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Returns `true` if the library described by this object is affected by
+ * the given [delta].
+ */
+ bool isAffectedBy(DartDelta delta) {
+ for (String name in names) {
+ if (delta.isNameAffected(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+/**
+ * A builder for creating [ReferencedNames].
+ *
+ * TODO(scheglov) Record dependencies for all other top-level declarations.
+ */
+class ReferencedNamesBuilder extends RecursiveAstVisitor {
+ final ReferencedNames names;
+ int bodyLevel = 0;
+ Set<String> dependsOn;
+
+ ReferencedNamesBuilder(this.names);
+
+ ReferencedNames build(CompilationUnit unit) {
+ unit.accept(this);
+ return names;
+ }
+
+ @override
+ visitBlockFunctionBody(BlockFunctionBody node) {
+ try {
+ bodyLevel++;
+ super.visitBlockFunctionBody(node);
+ } finally {
+ bodyLevel--;
+ }
+ }
+
+ @override
+ visitClassDeclaration(ClassDeclaration node) {
+ dependsOn = new Set<String>();
+ super.visitClassDeclaration(node);
+ names.userToDependsOn[node.name.name] = dependsOn;
+ dependsOn = null;
+ }
+
+ @override
+ visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ try {
+ bodyLevel++;
+ super.visitExpressionFunctionBody(node);
+ } finally {
+ bodyLevel--;
+ }
+ }
+
+ @override
+ visitSimpleIdentifier(SimpleIdentifier node) {
+ if (!node.inDeclarationContext()) {
+ String name = node.name;
+ names.names.add(name);
+ if (dependsOn != null && bodyLevel == 0) {
+ dependsOn.add(name);
+ }
+ }
+ }
+}
+
+/**
* A task that finishes resolution by requesting [RESOLVED_UNIT_NO_CONSTANTS] for every
* unit in the libraries closure and produces [LIBRARY_ELEMENT].
*/
@@ -2786,11 +3015,16 @@
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
/**
+ * The name of the list of [RESOLVED_UNIT5] input.
+ */
+ static const String UNITS_INPUT = 'UNITS_INPUT';
+
+ /**
* The task descriptor describing this kind of task.
*/
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
'ResolveLibraryReferencesTask', createTask, buildInputs,
- <ResultDescriptor>[LIBRARY_ELEMENT]);
+ <ResultDescriptor>[LIBRARY_ELEMENT, REFERENCED_NAMES]);
ResolveLibraryReferencesTask(
InternalAnalysisContext context, AnalysisTarget target)
@@ -2801,8 +3035,21 @@
@override
void internalPerform() {
+ //
+ // Prepare inputs.
+ //
LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+ List<CompilationUnit> units = getRequiredInput(UNITS_INPUT);
+ // Compute referenced names.
+ ReferencedNames referencedNames = new ReferencedNames();
+ for (CompilationUnit unit in units) {
+ new ReferencedNamesBuilder(referencedNames).build(unit);
+ }
+ //
+ // Record outputs.
+ //
outputs[LIBRARY_ELEMENT] = library;
+ outputs[REFERENCED_NAMES] = referencedNames;
}
/**
@@ -2814,6 +3061,8 @@
Source source = target;
return <String, TaskInput>{
LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source),
+ UNITS_INPUT: UNITS.of(source).toList((Source unit) =>
+ RESOLVED_UNIT5.of(new LibrarySpecificUnit(source, unit))),
'resolvedUnits': IMPORT_EXPORT_SOURCE_CLOSURE
.of(source)
.toMapOf(UNITS)
@@ -2870,12 +3119,9 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
Source source = target;
return <String, TaskInput>{
- LIBRARY_INPUT: LIBRARY_ELEMENT4.of(source),
- 'resolvedUnits': IMPORT_EXPORT_SOURCE_CLOSURE
- .of(source)
- .toMapOf(UNITS)
- .toFlattenList((Source library, Source unit) =>
- RESOLVED_UNIT3.of(new LibrarySpecificUnit(library, unit))),
+ 'resolvedUnit': UNITS.of(source).toList((Source unit) =>
+ RESOLVED_UNIT3.of(new LibrarySpecificUnit(source, unit))),
+ LIBRARY_INPUT: LIBRARY_ELEMENT4.of(source)
};
}
@@ -2958,6 +3204,9 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
+ 'fullyBuiltLibraryElements': IMPORT_EXPORT_SOURCE_CLOSURE
+ .of(unit.library)
+ .toListOf(LIBRARY_ELEMENT6),
LIBRARY_INPUT: LIBRARY_ELEMENT6.of(unit.library),
UNIT_INPUT: RESOLVED_UNIT4.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
@@ -3042,7 +3291,7 @@
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
'importsExportNamespace':
- IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4),
+ IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4),
LIBRARY_INPUT: LIBRARY_ELEMENT4.of(unit.library),
UNIT_INPUT: RESOLVED_UNIT2.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
@@ -3125,11 +3374,8 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- 'fullyBuiltLibraryElements': IMPORT_EXPORT_SOURCE_CLOSURE
- .of(unit.library)
- .toListOf(LIBRARY_ELEMENT6),
- LIBRARY_INPUT: LIBRARY_ELEMENT6.of(unit.library),
- UNIT_INPUT: RESOLVED_UNIT3.of(unit),
+ LIBRARY_INPUT: LIBRARY_ELEMENT1.of(unit.library),
+ UNIT_INPUT: RESOLVED_UNIT1.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
};
}
@@ -3176,6 +3422,21 @@
@override
void internalPerform() {
Source source = getRequiredSource();
+
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ if (context.getModificationStamp(target.source) < 0) {
+ String message = 'Content could not be read';
+ if (context is InternalAnalysisContext) {
+ CacheEntry entry =
+ (context as InternalAnalysisContext).getCacheEntry(target);
+ CaughtException exception = entry.exception;
+ if (exception != null) {
+ message = exception.toString();
+ }
+ }
+ errorListener.onError(new AnalysisError(
+ source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT, [message]));
+ }
if (target is DartScript) {
DartScript script = target;
List<ScriptFragment> fragments = script.fragments;
@@ -3187,7 +3448,6 @@
}
ScriptFragment fragment = fragments[0];
- RecordingErrorListener errorListener = new RecordingErrorListener();
Scanner scanner = new Scanner(source,
new SubSequenceReader(fragment.content, fragment.offset),
errorListener);
@@ -3202,7 +3462,6 @@
} else if (target is Source) {
String content = getRequiredInput(CONTENT_INPUT_NAME);
- RecordingErrorListener errorListener = new RecordingErrorListener();
Scanner scanner =
new Scanner(source, new CharSequenceReader(content), errorListener);
scanner.preserveComments = context.analysisOptions.preserveComments;
@@ -3374,44 +3633,58 @@
/**
* A [TaskInput] whose value is a list of library sources exported directly
* or indirectly by the target [Source].
+ *
+ * [resultDescriptor] is the type of result which should be produced for each
+ * target [Source].
*/
class _ExportSourceClosureTaskInput extends TaskInputImpl<List<Source>> {
final Source target;
+ final ResultDescriptor resultDescriptor;
- _ExportSourceClosureTaskInput(this.target);
+ _ExportSourceClosureTaskInput(this.target, this.resultDescriptor);
@override
TaskInputBuilder<List<Source>> createBuilder() =>
- new _SourceClosureTaskInputBuilder(target, _SourceClosureKind.EXPORT);
+ new _SourceClosureTaskInputBuilder(
+ target, _SourceClosureKind.EXPORT, resultDescriptor);
}
/**
* A [TaskInput] whose value is a list of library sources imported or exported,
* directly or indirectly by the target [Source].
+ *
+ * [resultDescriptor] is the type of result which should be produced for each
+ * target [Source].
*/
class _ImportExportSourceClosureTaskInput extends TaskInputImpl<List<Source>> {
final Source target;
+ final ResultDescriptor resultDescriptor;
- _ImportExportSourceClosureTaskInput(this.target);
+ _ImportExportSourceClosureTaskInput(this.target, this.resultDescriptor);
@override
TaskInputBuilder<List<Source>> createBuilder() =>
new _SourceClosureTaskInputBuilder(
- target, _SourceClosureKind.IMPORT_EXPORT);
+ target, _SourceClosureKind.IMPORT_EXPORT, resultDescriptor);
}
/**
* A [TaskInput] whose value is a list of library sources imported directly
* or indirectly by the target [Source].
+ *
+ * [resultDescriptor] is the type of result which should be produced for each
+ * target [Source].
*/
class _ImportSourceClosureTaskInput extends TaskInputImpl<List<Source>> {
final Source target;
+ final ResultDescriptor resultDescriptor;
- _ImportSourceClosureTaskInput(this.target);
+ _ImportSourceClosureTaskInput(this.target, this.resultDescriptor);
@override
TaskInputBuilder<List<Source>> createBuilder() =>
- new _SourceClosureTaskInputBuilder(target, _SourceClosureKind.IMPORT);
+ new _SourceClosureTaskInputBuilder(
+ target, _SourceClosureKind.IMPORT, resultDescriptor);
}
/**
@@ -3427,16 +3700,17 @@
final Set<LibraryElement> _libraries = new HashSet<LibraryElement>();
final List<Source> _newSources = <Source>[];
+ @override
+ final ResultDescriptor currentResult;
+
Source currentTarget;
- _SourceClosureTaskInputBuilder(Source librarySource, this.kind) {
+ _SourceClosureTaskInputBuilder(
+ Source librarySource, this.kind, this.currentResult) {
_newSources.add(librarySource);
}
@override
- ResultDescriptor get currentResult => LIBRARY_ELEMENT2;
-
- @override
void set currentValue(Object value) {
LibraryElement library = value;
if (_libraries.add(library)) {
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index b75bad4..0722ed4 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -18,6 +18,9 @@
import 'package:html/dom.dart';
import 'package:html/parser.dart';
import 'package:source_span/source_span.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
/**
* The Dart scripts that are embedded in an HTML file.
@@ -285,19 +288,34 @@
void internalPerform() {
String content = getRequiredInput(CONTENT_INPUT_NAME);
- HtmlParser parser = new HtmlParser(content, generateSpans: true);
- parser.compatMode = 'quirks';
- Document document = parser.parse();
- List<ParseError> parseErrors = parser.errors;
- List<AnalysisError> errors = <AnalysisError>[];
- for (ParseError parseError in parseErrors) {
- SourceSpan span = parseError.span;
- errors.add(new AnalysisError(target.source, span.start.offset,
- span.length, HtmlErrorCode.PARSE_ERROR, [parseError.message]));
- }
+ if (context.getModificationStamp(target.source) < 0) {
+ String message = 'Content could not be read';
+ if (context is InternalAnalysisContext) {
+ CacheEntry entry = (context as InternalAnalysisContext).getCacheEntry(target);
+ CaughtException exception = entry.exception;
+ if (exception != null) {
+ message = exception.toString();
+ }
+ }
- outputs[HTML_DOCUMENT] = document;
- outputs[HTML_DOCUMENT_ERRORS] = errors;
+ outputs[HTML_DOCUMENT] = new Document();
+ outputs[HTML_DOCUMENT_ERRORS] = <AnalysisError>[new AnalysisError(
+ target.source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT, [message])];
+ } else {
+ HtmlParser parser = new HtmlParser(content, generateSpans: true);
+ parser.compatMode = 'quirks';
+ Document document = parser.parse();
+ List<ParseError> parseErrors = parser.errors;
+ List<AnalysisError> errors = <AnalysisError>[];
+ for (ParseError parseError in parseErrors) {
+ SourceSpan span = parseError.span;
+ errors.add(new AnalysisError(target.source, span.start.offset,
+ span.length, HtmlErrorCode.PARSE_ERROR, [parseError.message]));
+ }
+
+ outputs[HTML_DOCUMENT] = document;
+ outputs[HTML_DOCUMENT_ERRORS] = errors;
+ }
}
/**
diff --git a/pkg/analyzer/lib/src/task/incremental_element_builder.dart b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
index 4896b5d..bc562a7 100644
--- a/pkg/analyzer/lib/src/task/incremental_element_builder.dart
+++ b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
@@ -214,8 +214,12 @@
for (VariableDeclaration variable in variableList.variables) {
TopLevelVariableElement element = variable.element;
elements.add(element);
- elements.add(element.getter);
- elements.add(element.setter);
+ if (element.getter != null) {
+ elements.add(element.getter);
+ }
+ if (element.setter != null) {
+ elements.add(element.setter);
+ }
}
}
} else if (node is PartDirective || node is PartOfDirective) {
diff --git a/pkg/analyzer/lib/src/task/task_dart.dart b/pkg/analyzer/lib/src/task/task_dart.dart
deleted file mode 100644
index 9192970..0000000
--- a/pkg/analyzer/lib/src/task/task_dart.dart
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library engine.task.dart;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * A `BuildUnitElementTask` builds a compilation unit element for a single
- * compilation unit.
- */
-class BuildUnitElementTask extends AnalysisTask {
- /**
- * The source for which an element model will be built.
- */
- final Source source;
-
- /**
- * The source of the library in which an element model will be built.
- */
- final Source library;
-
- /**
- * The compilation unit from which an element model will be built.
- */
- final CompilationUnit unit;
-
- /**
- * The element model that was built.
- */
- CompilationUnitElement unitElement;
-
- /**
- * Initialize a newly created task to build a compilation unit element for
- * the given [source] in the given [library] based on the compilation [unit]
- * that was parsed.
- */
- BuildUnitElementTask(
- InternalAnalysisContext context, this.source, this.library, this.unit)
- : super(context);
-
- @override
- String get taskDescription {
- if (source == null) {
- return "build the unit element model for null source";
- }
- return "build the unit element model for " + source.fullName;
- }
-
- @override
- accept(AnalysisTaskVisitor visitor) {
- return visitor.visitBuildUnitElementTask(this);
- }
-
- /**
- * Return the compilation unit from which the element model was built.
- */
- CompilationUnit getCompilationUnit() {
- return unit;
- }
-
- /**
- * Return the source that is to be parsed.
- */
- Source getSource() {
- return source;
- }
-
- /**
- * Return the compilation unit element that was produced, or `null` if the
- * task has not yet been performed or if an exception occurred.
- */
- CompilationUnitElement getUnitElement() {
- return unitElement;
- }
-
- @override
- void internalPerform() {
- CompilationUnitBuilder builder = new CompilationUnitBuilder();
- unitElement = builder.buildCompilationUnit(source, unit, library);
- }
-}
diff --git a/pkg/analyzer/test/file_system/memory_file_system_test.dart b/pkg/analyzer/test/file_system/memory_file_system_test.dart
index 83d3694..8b072fe 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -5,6 +5,7 @@
library test.memory_file_system;
import 'dart:async';
+import 'dart:core' hide Resource;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
index 7d0c141..cd9cfbb 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
@@ -5,6 +5,7 @@
library test.physical_file_system;
import 'dart:async';
+import 'dart:core' hide Resource;
import 'dart:io' as io;
import 'package:analyzer/file_system/file_system.dart';
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 9eafca6..e163fd0 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -7,10 +7,7 @@
library engine.all_the_rest_test;
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/element.dart';
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
index e285058..115a514 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -2132,6 +2132,16 @@
.formalParameterList([AstFactory.simpleFormalParameter3("b")])));
}
+ void test_visitFieldFormalParameter_functionTyped_typeParameters() {
+ _assertSource("A this.a<E, F>(b)", new FieldFormalParameter(null, null,
+ null, AstFactory.typeName4('A'),
+ TokenFactory.tokenFromKeyword(Keyword.THIS),
+ TokenFactory.tokenFromType(TokenType.PERIOD),
+ AstFactory.identifier3('a'), AstFactory.typeParameterList(['E', 'F']),
+ AstFactory
+ .formalParameterList([AstFactory.simpleFormalParameter3("b")])));
+ }
+
void test_visitFieldFormalParameter_keyword() {
_assertSource(
"var this.a", AstFactory.fieldFormalParameter(Keyword.VAR, null, "a"));
@@ -2406,6 +2416,13 @@
null, Keyword.SET, "f", AstFactory.functionExpression()));
}
+ void test_visitFunctionDeclaration_typeParameters() {
+ _assertSource("f<E>() {}", AstFactory.functionDeclaration(null, null, "f",
+ AstFactory.functionExpression3(AstFactory.typeParameterList(['E']),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2())));
+ }
+
void test_visitFunctionDeclaration_withMetadata() {
FunctionDeclaration declaration = AstFactory.functionDeclaration(
null, null, "f", AstFactory.functionExpression());
@@ -2423,11 +2440,23 @@
_assertSource("() {}", AstFactory.functionExpression());
}
- void test_visitFunctionExpressionInvocation() {
+ void test_visitFunctionExpression_typeParameters() {
+ _assertSource("<E>() {}", AstFactory.functionExpression3(
+ AstFactory.typeParameterList(['E']), AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2()));
+ }
+
+ void test_visitFunctionExpressionInvocation_minimal() {
_assertSource("f()",
AstFactory.functionExpressionInvocation(AstFactory.identifier3("f")));
}
+ void test_visitFunctionExpressionInvocation_typeArguments() {
+ _assertSource("f<A>()", AstFactory.functionExpressionInvocation2(
+ AstFactory.identifier3("f"),
+ AstFactory.typeArgumentList([AstFactory.typeName4('A')])));
+ }
+
void test_visitFunctionTypeAlias_generic() {
_assertSource("typedef A F<B>();", AstFactory.typeAlias(
AstFactory.typeName4("A"), "F", AstFactory.typeParameterList(["B"]),
@@ -2457,6 +2486,13 @@
AstFactory.typeName4("T"), "f"));
}
+ void test_visitFunctionTypedFormalParameter_typeParameters() {
+ _assertSource("T f<E>()", new FunctionTypedFormalParameter(null, null,
+ AstFactory.typeName4("T"), AstFactory.identifier3('f'),
+ AstFactory.typeParameterList(['E']),
+ AstFactory.formalParameterList([])));
+ }
+
void test_visitIfStatement_withElse() {
_assertSource("if (c) {} else {}", AstFactory.ifStatement2(
AstFactory.identifier3("c"), AstFactory.block(), AstFactory.block()));
@@ -2758,6 +2794,12 @@
AstFactory.blockFunctionBody2()));
}
+ void test_visitMethodDeclaration_typeParameters() {
+ _assertSource("m<E>() {}", AstFactory.methodDeclaration3(null, null, null,
+ null, AstFactory.identifier3("m"), AstFactory.typeParameterList(['E']),
+ AstFactory.formalParameterList(), AstFactory.blockFunctionBody2()));
+ }
+
void test_visitMethodDeclaration_withMetadata() {
MethodDeclaration declaration = AstFactory.methodDeclaration2(null, null,
null, null, AstFactory.identifier3("m"),
@@ -2781,6 +2823,11 @@
"t.m()", AstFactory.methodInvocation(AstFactory.identifier3("t"), "m"));
}
+ void test_visitMethodInvocation_typeArguments() {
+ _assertSource("m<A>()", AstFactory.methodInvocation3(
+ null, "m", AstFactory.typeArgumentList([AstFactory.typeName4('A')])));
+ }
+
void test_visitNamedExpression() {
_assertSource(
"a: b", AstFactory.namedExpression2("a", AstFactory.identifier3("b")));
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index db8c17d..eb87ea7 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -33,7 +33,6 @@
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/string_source.dart';
-import 'package:analyzer/src/task/task_dart.dart';
import 'package:analyzer/task/model.dart' hide AnalysisTask;
import 'package:html/dom.dart' show Document;
import 'package:path/path.dart' as pathos;
@@ -195,14 +194,6 @@
*/
SourceFactory _sourceFactory;
- void fail_extractContext() {
- fail("Implement this");
- }
-
- void fail_mergeContext() {
- fail("Implement this");
- }
-
void fail_performAnalysisTask_importedLibraryDelete_html() {
Source htmlSource = _addSource("/page.html", r'''
<html><body><script type="application/dart">
@@ -5828,11 +5819,17 @@
return false;
}
+ @deprecated
@override
void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
DataDescriptor rowDesc, CacheState state)) {
fail("Unexpected invocation of visitCacheItems");
}
+
+ @override
+ void visitContentCache(ContentCacheVisitor visitor) {
+ fail("Unexpected invocation of visitContentCache");
+ }
}
class TestAnalysisContext_test_applyChanges extends TestAnalysisContext {
@@ -6384,12 +6381,6 @@
*/
class TestTaskVisitor<E> implements AnalysisTaskVisitor<E> {
@override
- E visitBuildUnitElementTask(BuildUnitElementTask task) {
- fail("Unexpectedly invoked visitGenerateDartErrorsTask");
- return null;
- }
-
- @override
E visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
fail("Unexpectedly invoked visitGenerateDartErrorsTask");
return null;
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 54bb524..98f6d23 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -4,6 +4,7 @@
library engine.incremental_resolver_test;
+import 'package:analyzer/src/context/cache.dart' as task;
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/engine.dart';
@@ -18,6 +19,7 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/task/dart.dart';
import 'package:unittest/unittest.dart';
import '../reflective_tests.dart';
@@ -2473,13 +2475,22 @@
@override
void reset() {
- analysisContext2 = AnalysisContextFactory.oldContextWithCore();
+ if (AnalysisEngine.instance.useTaskModel) {
+ analysisContext2 = AnalysisContextFactory.contextWithCore();
+ } else {
+ analysisContext2 = AnalysisContextFactory.oldContextWithCore();
+ }
}
@override
void resetWithOptions(AnalysisOptions options) {
- analysisContext2 =
- AnalysisContextFactory.oldContextWithCoreAndOptions(options);
+ if (AnalysisEngine.instance.useTaskModel) {
+ analysisContext2 =
+ AnalysisContextFactory.contextWithCoreAndOptions(options);
+ } else {
+ analysisContext2 =
+ AnalysisContextFactory.oldContextWithCoreAndOptions(options);
+ }
}
void setUp() {
@@ -2812,10 +2823,19 @@
int updateOffset = edit.offset;
int updateEndOld = updateOffset + edit.length;
int updateOldNew = updateOffset + edit.replacement.length;
- IncrementalResolver resolver = new IncrementalResolver(
- (analysisContext2 as AnalysisContextImpl)
- .getReadableSourceEntryOrNull(source), null, null, unit.element,
- updateOffset, updateEndOld, updateOldNew);
+ IncrementalResolver resolver;
+ if (AnalysisEngine.instance.useTaskModel) {
+ LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source);
+ task.AnalysisCache cache = analysisContext2.analysisCache;
+ resolver = new IncrementalResolver(null, cache.get(source),
+ cache.get(lsu), unit.element, updateOffset, updateEndOld,
+ updateOldNew);
+ } else {
+ resolver = new IncrementalResolver(
+ (analysisContext2 as AnalysisContextImpl)
+ .getReadableSourceEntryOrNull(source), null, null, unit.element,
+ updateOffset, updateEndOld, updateOldNew);
+ }
bool success = resolver.resolve(newNode);
expect(success, isTrue);
List<AnalysisError> newErrors = analysisContext.computeErrors(source);
@@ -3079,7 +3099,7 @@
/// aaa [main] bbb
/// ccc [int] ddd
main() {
- return 2;
+ return 1;
}
''');
}
@@ -3095,7 +3115,7 @@
_updateAndValidate(r'''
/// aaa bbb
main() {
- return 2;
+ return 1;
}
''');
}
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 89de72c..5816ab8 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -173,6 +173,7 @@
(obj) => obj is MethodInvocation, MethodInvocation,
propertyAccess1.target);
expect(invocation2.methodName.name, "d");
+ expect(invocation2.typeArguments, isNull);
ArgumentList argumentList2 = invocation2.argumentList;
expect(argumentList2, isNotNull);
expect(argumentList2.arguments, hasLength(1));
@@ -182,6 +183,7 @@
FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(
(obj) => obj is FunctionExpressionInvocation,
FunctionExpressionInvocation, invocation2.target);
+ expect(invocation3.typeArguments, isNull);
ArgumentList argumentList3 = invocation3.argumentList;
expect(argumentList3, isNotNull);
expect(argumentList3.arguments, hasLength(1));
@@ -192,6 +194,45 @@
(obj) => obj is MethodInvocation, MethodInvocation,
invocation3.function);
expect(invocation4.methodName.name, "a");
+ expect(invocation4.typeArguments, isNull);
+ ArgumentList argumentList4 = invocation4.argumentList;
+ expect(argumentList4, isNotNull);
+ expect(argumentList4.arguments, hasLength(1));
+ }
+
+ void test_assignableExpression_arguments_normal_chain_typeArguments() {
+ enableGenericMethods = true;
+ PropertyAccess propertyAccess1 = parseExpression("a<E>(b)<F>(c).d<G>(e).f");
+ expect(propertyAccess1.propertyName.name, "f");
+ //
+ // a<E>(b)<F>(c).d>G?(e)
+ //
+ MethodInvocation invocation2 = EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodInvocation, MethodInvocation,
+ propertyAccess1.target);
+ expect(invocation2.methodName.name, "d");
+ expect(invocation2.typeArguments, isNotNull);
+ ArgumentList argumentList2 = invocation2.argumentList;
+ expect(argumentList2, isNotNull);
+ expect(argumentList2.arguments, hasLength(1));
+ //
+ // a<E>(b)<F>(c)
+ //
+ FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(
+ (obj) => obj is FunctionExpressionInvocation,
+ FunctionExpressionInvocation, invocation2.target);
+ expect(invocation3.typeArguments, isNotNull);
+ ArgumentList argumentList3 = invocation3.argumentList;
+ expect(argumentList3, isNotNull);
+ expect(argumentList3.arguments, hasLength(1));
+ //
+ // a(b)
+ //
+ MethodInvocation invocation4 = EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodInvocation, MethodInvocation,
+ invocation3.function);
+ expect(invocation4.methodName.name, "a");
+ expect(invocation4.typeArguments, isNotNull);
ArgumentList argumentList4 = invocation4.argumentList;
expect(argumentList4, isNotNull);
expect(argumentList4.arguments, hasLength(1));
@@ -1750,6 +1791,17 @@
"parseCascadeSection", "..()", [ParserErrorCode.MISSING_IDENTIFIER]);
expect(methodInvocation.target, isNull);
expect(methodInvocation.methodName.name, "");
+ expect(methodInvocation.typeArguments, isNull);
+ expect(methodInvocation.argumentList.arguments, hasLength(0));
+ }
+
+ void test_parseCascadeSection_missingIdentifier_typeArguments() {
+ enableGenericMethods = true;
+ MethodInvocation methodInvocation = parse4(
+ "parseCascadeSection", "..<E>()", [ParserErrorCode.MISSING_IDENTIFIER]);
+ expect(methodInvocation.target, isNull);
+ expect(methodInvocation.methodName.name, "");
+ expect(methodInvocation.typeArguments, isNotNull);
expect(methodInvocation.argumentList.arguments, hasLength(0));
}
@@ -2528,6 +2580,12 @@
static bool parseFunctionBodies = true;
/**
+ * A flag indicating whether generic method support should be enabled for a
+ * specific test.
+ */
+ bool enableGenericMethods = false;
+
+ /**
* If non-null, this value is used to override the default value of
* [Scanner.enableNullAwareOperators] before scanning.
*/
@@ -2585,6 +2643,7 @@
// Parse the source.
//
Parser parser = createParser(listener);
+ parser.parseGenericMethods = enableGenericMethods;
parser.parseFunctionBodies = parseFunctionBodies;
Object result =
invokeParserMethodImpl(parser, methodName, objects, tokenStream);
@@ -2718,6 +2777,7 @@
listener.setLineInfo(new TestSource(), scanner.lineStarts);
Token token = scanner.tokenize();
Parser parser = createParser(listener);
+ parser.parseGenericMethods = enableGenericMethods;
Expression expression = parser.parseExpression(token);
expect(expression, isNotNull);
listener.assertErrorsWithCodes(errorCodes);
@@ -4654,6 +4714,16 @@
expect(_isFunctionDeclaration("f() => e"), isTrue);
}
+ void test_isFunctionDeclaration_nameButNoReturn_typeParameters_block() {
+ enableGenericMethods = true;
+ expect(_isFunctionDeclaration("f<E>() {}"), isTrue);
+ }
+
+ void test_isFunctionDeclaration_nameButNoReturn_typeParameters_expression() {
+ enableGenericMethods = true;
+ expect(_isFunctionDeclaration("f<E>() => e"), isTrue);
+ }
+
void test_isFunctionDeclaration_normalReturn_block() {
expect(_isFunctionDeclaration("C f() {}"), isTrue);
}
@@ -4662,6 +4732,16 @@
expect(_isFunctionDeclaration("C f() => e"), isTrue);
}
+ void test_isFunctionDeclaration_normalReturn_typeParameters_block() {
+ enableGenericMethods = true;
+ expect(_isFunctionDeclaration("C f<E>() {}"), isTrue);
+ }
+
+ void test_isFunctionDeclaration_normalReturn_typeParameters_expression() {
+ enableGenericMethods = true;
+ expect(_isFunctionDeclaration("C f<E>() => e"), isTrue);
+ }
+
void test_isFunctionDeclaration_voidReturn_block() {
expect(_isFunctionDeclaration("void f() {}"), isTrue);
}
@@ -4670,6 +4750,16 @@
expect(_isFunctionDeclaration("void f() => e"), isTrue);
}
+ void test_isFunctionDeclaration_voidReturn_typeParameters_block() {
+ enableGenericMethods = true;
+ expect(_isFunctionDeclaration("void f<E>() {}"), isTrue);
+ }
+
+ void test_isFunctionDeclaration_voidReturn_typeParameters_expression() {
+ enableGenericMethods = true;
+ expect(_isFunctionDeclaration("void f<E>() => e"), isTrue);
+ }
+
void test_isFunctionExpression_false_noBody() {
expect(_isFunctionExpression("f();"), isFalse);
}
@@ -4678,14 +4768,24 @@
expect(_isFunctionExpression("(a + b) {"), isFalse);
}
- void test_isFunctionExpression_noName_block() {
+ void test_isFunctionExpression_noParameters_block() {
expect(_isFunctionExpression("() {}"), isTrue);
}
- void test_isFunctionExpression_noName_expression() {
+ void test_isFunctionExpression_noParameters_expression() {
expect(_isFunctionExpression("() => e"), isTrue);
}
+ void test_isFunctionExpression_noParameters_typeParameters_block() {
+ enableGenericMethods = true;
+ expect(_isFunctionExpression("<E>() {}"), isTrue);
+ }
+
+ void test_isFunctionExpression_noParameters_typeParameters_expression() {
+ enableGenericMethods = true;
+ expect(_isFunctionExpression("<E>() => e"), isTrue);
+ }
+
void test_isFunctionExpression_parameter_final() {
expect(_isFunctionExpression("(final a) {}"), isTrue);
expect(_isFunctionExpression("(final a, b) {}"), isTrue);
@@ -4935,6 +5035,22 @@
FunctionExpressionInvocation invocation =
propertyAccess.target as FunctionExpressionInvocation;
expect(invocation.function, isNotNull);
+ expect(invocation.typeArguments, isNull);
+ ArgumentList argumentList = invocation.argumentList;
+ expect(argumentList, isNotNull);
+ expect(argumentList.arguments, hasLength(1));
+ expect(propertyAccess.operator, isNotNull);
+ expect(propertyAccess.propertyName, isNotNull);
+ }
+
+ void test_parseAssignableExpression_expression_args_dot_typeParameters() {
+ enableGenericMethods = true;
+ PropertyAccess propertyAccess =
+ parse("parseAssignableExpression", <Object>[false], "(x)<F>(y).z");
+ FunctionExpressionInvocation invocation =
+ propertyAccess.target as FunctionExpressionInvocation;
+ expect(invocation.function, isNotNull);
+ expect(invocation.typeArguments, isNotNull);
ArgumentList argumentList = invocation.argumentList;
expect(argumentList, isNotNull);
expect(argumentList.arguments, hasLength(1));
@@ -4979,6 +5095,21 @@
parse("parseAssignableExpression", <Object>[false], "x(y).z");
MethodInvocation invocation = propertyAccess.target as MethodInvocation;
expect(invocation.methodName.name, "x");
+ expect(invocation.typeArguments, isNull);
+ ArgumentList argumentList = invocation.argumentList;
+ expect(argumentList, isNotNull);
+ expect(argumentList.arguments, hasLength(1));
+ expect(propertyAccess.operator, isNotNull);
+ expect(propertyAccess.propertyName, isNotNull);
+ }
+
+ void test_parseAssignableExpression_identifier_args_dot_typeParameters() {
+ enableGenericMethods = true;
+ PropertyAccess propertyAccess =
+ parse("parseAssignableExpression", <Object>[false], "x<E>(y).z");
+ MethodInvocation invocation = propertyAccess.target as MethodInvocation;
+ expect(invocation.methodName.name, "x");
+ expect(invocation.typeArguments, isNotNull);
ArgumentList argumentList = invocation.argumentList;
expect(argumentList, isNotNull);
expect(argumentList.arguments, hasLength(1));
@@ -5193,6 +5324,17 @@
parse4("parseCascadeSection", "..[i](b)");
EngineTestCase.assertInstanceOf(
(obj) => obj is IndexExpression, IndexExpression, section.function);
+ expect(section.typeArguments, isNull);
+ expect(section.argumentList, isNotNull);
+ }
+
+ void test_parseCascadeSection_ia_typeArguments() {
+ enableGenericMethods = true;
+ FunctionExpressionInvocation section =
+ parse4("parseCascadeSection", "..[i]<E>(b)");
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is IndexExpression, IndexExpression, section.function);
+ expect(section.typeArguments, isNotNull);
expect(section.argumentList, isNotNull);
}
@@ -5202,6 +5344,20 @@
(obj) => obj is MethodInvocation, MethodInvocation, section.target);
expect(section.operator, isNotNull);
expect(section.methodName, isNotNull);
+ expect(section.typeArguments, isNull);
+ expect(section.argumentList, isNotNull);
+ expect(section.argumentList.arguments, hasLength(1));
+ }
+
+ void test_parseCascadeSection_ii_typeArguments() {
+ enableGenericMethods = true;
+ MethodInvocation section =
+ parse4("parseCascadeSection", "..a<E>(b).c<F>(d)");
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodInvocation, MethodInvocation, section.target);
+ expect(section.operator, isNotNull);
+ expect(section.methodName, isNotNull);
+ expect(section.typeArguments, isNotNull);
expect(section.argumentList, isNotNull);
expect(section.argumentList.arguments, hasLength(1));
}
@@ -5231,6 +5387,17 @@
(obj) => obj is IntegerLiteral, IntegerLiteral, rhs);
}
+ void test_parseCascadeSection_p_assign_withCascade_typeArguments() {
+ enableGenericMethods = true;
+ AssignmentExpression section =
+ parse4("parseCascadeSection", "..a = 3..m<E>()");
+ expect(section.leftHandSide, isNotNull);
+ expect(section.operator, isNotNull);
+ Expression rhs = section.rightHandSide;
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is IntegerLiteral, IntegerLiteral, rhs);
+ }
+
void test_parseCascadeSection_p_builtIn() {
PropertyAccess section = parse4("parseCascadeSection", "..as");
expect(section.target, isNull);
@@ -5243,6 +5410,18 @@
expect(section.target, isNull);
expect(section.operator, isNotNull);
expect(section.methodName, isNotNull);
+ expect(section.typeArguments, isNull);
+ expect(section.argumentList, isNotNull);
+ expect(section.argumentList.arguments, hasLength(1));
+ }
+
+ void test_parseCascadeSection_pa_typeArguments() {
+ enableGenericMethods = true;
+ MethodInvocation section = parse4("parseCascadeSection", "..a<E>(b)");
+ expect(section.target, isNull);
+ expect(section.operator, isNotNull);
+ expect(section.methodName, isNotNull);
+ expect(section.typeArguments, isNotNull);
expect(section.argumentList, isNotNull);
expect(section.argumentList.arguments, hasLength(1));
}
@@ -5252,6 +5431,18 @@
parse4("parseCascadeSection", "..a(b)(c)");
EngineTestCase.assertInstanceOf(
(obj) => obj is MethodInvocation, MethodInvocation, section.function);
+ expect(section.typeArguments, isNull);
+ expect(section.argumentList, isNotNull);
+ expect(section.argumentList.arguments, hasLength(1));
+ }
+
+ void test_parseCascadeSection_paa_typeArguments() {
+ enableGenericMethods = true;
+ FunctionExpressionInvocation section =
+ parse4("parseCascadeSection", "..a<E>(b)<F>(c)");
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodInvocation, MethodInvocation, section.function);
+ expect(section.typeArguments, isNotNull);
expect(section.argumentList, isNotNull);
expect(section.argumentList.arguments, hasLength(1));
}
@@ -5261,6 +5452,18 @@
parse4("parseCascadeSection", "..a(b)(c).d(e)(f)");
EngineTestCase.assertInstanceOf(
(obj) => obj is MethodInvocation, MethodInvocation, section.function);
+ expect(section.typeArguments, isNull);
+ expect(section.argumentList, isNotNull);
+ expect(section.argumentList.arguments, hasLength(1));
+ }
+
+ void test_parseCascadeSection_paapaa_typeArguments() {
+ enableGenericMethods = true;
+ FunctionExpressionInvocation section =
+ parse4("parseCascadeSection", "..a<E>(b)<F>(c).d<G>(e)<H>(f)");
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is MethodInvocation, MethodInvocation, section.function);
+ expect(section.typeArguments, isNotNull);
expect(section.argumentList, isNotNull);
expect(section.argumentList.arguments, hasLength(1));
}
@@ -5272,6 +5475,14 @@
expect(section.propertyName, isNotNull);
}
+ void test_parseCascadeSection_pap_typeArguments() {
+ enableGenericMethods = true;
+ PropertyAccess section = parse4("parseCascadeSection", "..a<E>(b).c");
+ expect(section.target, isNotNull);
+ expect(section.operator, isNotNull);
+ expect(section.propertyName, isNotNull);
+ }
+
void test_parseClassDeclaration_abstract() {
ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
emptyCommentAndMetadata(),
@@ -5581,6 +5792,7 @@
expect(method.modifierKeyword, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNull);
@@ -5595,11 +5807,60 @@
expect(method.modifierKeyword, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, isNotNull);
}
+ void test_parseClassMember_method_generic_noReturnType() {
+ enableGenericMethods = true;
+ MethodDeclaration method =
+ parse("parseClassMember", <Object>["C"], "m<T>() {}");
+ expect(method.documentationComment, isNull);
+ expect(method.externalKeyword, isNull);
+ expect(method.modifierKeyword, isNull);
+ expect(method.propertyKeyword, isNull);
+ expect(method.returnType, isNull);
+ expect(method.name, isNotNull);
+ expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNotNull);
+ expect(method.parameters, isNotNull);
+ expect(method.body, isNotNull);
+ }
+
+ void test_parseClassMember_method_generic_returnType() {
+ enableGenericMethods = true;
+ MethodDeclaration method =
+ parse("parseClassMember", <Object>["C"], "T m<T>() {}");
+ expect(method.documentationComment, isNull);
+ expect(method.externalKeyword, isNull);
+ expect(method.modifierKeyword, isNull);
+ expect(method.propertyKeyword, isNull);
+ expect(method.returnType, isNotNull);
+ expect(method.name, isNotNull);
+ expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNotNull);
+ expect(method.parameters, isNotNull);
+ expect(method.body, isNotNull);
+ }
+
+ void test_parseClassMember_method_generic_void() {
+ enableGenericMethods = true;
+ MethodDeclaration method =
+ parse("parseClassMember", <Object>["C"], "void m<T>() {}");
+ expect(method.documentationComment, isNull);
+ expect(method.externalKeyword, isNull);
+ expect(method.modifierKeyword, isNull);
+ expect(method.propertyKeyword, isNull);
+ expect(method.returnType, isNotNull);
+ expect(method.name, isNotNull);
+ expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNotNull);
+ expect(method.parameters, isNotNull);
+ expect(method.body, isNotNull);
+ }
+
void test_parseClassMember_method_get_noType() {
MethodDeclaration method =
parse("parseClassMember", <Object>["C"], "get() {}");
@@ -5610,6 +5871,7 @@
expect(method.returnType, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5624,6 +5886,7 @@
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5638,6 +5901,7 @@
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5652,6 +5916,7 @@
expect(method.returnType, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5666,6 +5931,7 @@
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5680,6 +5946,7 @@
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5694,6 +5961,7 @@
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5708,6 +5976,7 @@
expect(method.returnType, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5722,6 +5991,7 @@
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5736,6 +6006,7 @@
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5750,6 +6021,7 @@
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNotNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -5764,6 +6036,7 @@
expect(method.returnType, isNotNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNotNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.body, isNotNull);
}
@@ -6978,6 +7251,7 @@
FunctionExpression expression = invocation.function as FunctionExpression;
expect(expression.parameters, isNotNull);
expect(expression.body, isNotNull);
+ expect(invocation.typeArguments, isNull);
ArgumentList list = invocation.argumentList;
expect(list, isNotNull);
expect(list.arguments, hasLength(1));
@@ -6986,12 +7260,24 @@
void test_parseExpression_nonAwait() {
MethodInvocation expression = parseExpression("await()");
expect(expression.methodName.name, 'await');
+ expect(expression.typeArguments, isNull);
+ expect(expression.argumentList, isNotNull);
}
void test_parseExpression_superMethodInvocation() {
MethodInvocation invocation = parse4("parseExpression", "super.m()");
expect(invocation.target, isNotNull);
expect(invocation.methodName, isNotNull);
+ expect(invocation.typeArguments, isNull);
+ expect(invocation.argumentList, isNotNull);
+ }
+
+ void test_parseExpression_superMethodInvocation_typeArguments() {
+ enableGenericMethods = true;
+ MethodInvocation invocation = parse4("parseExpression", "super.m<E>()");
+ expect(invocation.target, isNotNull);
+ expect(invocation.methodName, isNotNull);
+ expect(invocation.typeArguments, isNotNull);
expect(invocation.argumentList, isNotNull);
}
@@ -7029,6 +7315,17 @@
parse4("parseExpressionWithoutCascade", "super.m()");
expect(invocation.target, isNotNull);
expect(invocation.methodName, isNotNull);
+ expect(invocation.typeArguments, isNull);
+ expect(invocation.argumentList, isNotNull);
+ }
+
+ void test_parseExpressionWithoutCascade_superMethodInvocation_typeArguments() {
+ enableGenericMethods = true;
+ MethodInvocation invocation =
+ parse4("parseExpressionWithoutCascade", "super.m<E>()");
+ expect(invocation.target, isNotNull);
+ expect(invocation.methodName, isNotNull);
+ expect(invocation.typeArguments, isNotNull);
expect(invocation.argumentList, isNotNull);
}
@@ -7765,6 +8062,24 @@
FunctionExpression expression = declaration.functionExpression;
expect(expression, isNotNull);
expect(expression.body, isNotNull);
+ expect(expression.typeParameters, isNull);
+ expect(expression.parameters, isNotNull);
+ expect(declaration.propertyKeyword, isNull);
+ }
+
+ void test_parseFunctionDeclaration_functionWithTypeParameters() {
+ enableGenericMethods = true;
+ Comment comment = Comment.createDocumentationComment(new List<Token>(0));
+ TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+ FunctionDeclaration declaration = parse("parseFunctionDeclaration",
+ <Object>[commentAndMetadata(comment), null, returnType], "f<E>() {}");
+ expect(declaration.documentationComment, comment);
+ expect(declaration.returnType, returnType);
+ expect(declaration.name, isNotNull);
+ FunctionExpression expression = declaration.functionExpression;
+ expect(expression, isNotNull);
+ expect(expression.body, isNotNull);
+ expect(expression.typeParameters, isNotNull);
expect(expression.parameters, isNotNull);
expect(declaration.propertyKeyword, isNull);
}
@@ -7780,6 +8095,7 @@
FunctionExpression expression = declaration.functionExpression;
expect(expression, isNotNull);
expect(expression.body, isNotNull);
+ expect(expression.typeParameters, isNull);
expect(expression.parameters, isNull);
expect(declaration.propertyKeyword, isNotNull);
}
@@ -7795,6 +8111,7 @@
FunctionExpression expression = declaration.functionExpression;
expect(expression, isNotNull);
expect(expression.body, isNotNull);
+ expect(expression.typeParameters, isNull);
expect(expression.parameters, isNotNull);
expect(declaration.propertyKeyword, isNotNull);
}
@@ -7805,10 +8122,28 @@
expect(statement.functionDeclaration, isNotNull);
}
+ void test_parseFunctionDeclarationStatement_typeParameters() {
+ enableGenericMethods = true;
+ FunctionDeclarationStatement statement =
+ parse4("parseFunctionDeclarationStatement", "E f<E>(E p) => p * 2;");
+ expect(statement.functionDeclaration, isNotNull);
+ }
+
void test_parseFunctionExpression_body_inExpression() {
FunctionExpression expression =
parse4("parseFunctionExpression", "(int i) => i++");
expect(expression.body, isNotNull);
+ expect(expression.typeParameters, isNull);
+ expect(expression.parameters, isNotNull);
+ expect((expression.body as ExpressionFunctionBody).semicolon, isNull);
+ }
+
+ void test_parseFunctionExpression_typeParameters() {
+ enableGenericMethods = true;
+ FunctionExpression expression =
+ parse4("parseFunctionExpression", "<E>(E i) => i++");
+ expect(expression.body, isNotNull);
+ expect(expression.typeParameters, isNotNull);
expect(expression.parameters, isNotNull);
expect((expression.body as ExpressionFunctionBody).semicolon, isNull);
}
@@ -7849,6 +8184,7 @@
expect(method.modifierKeyword, staticKeyword);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNull);
expect(method.propertyKeyword, isNotNull);
expect(method.returnType, returnType);
@@ -8433,6 +8769,7 @@
FunctionExpression expression = invocation.function as FunctionExpression;
expect(expression.parameters, isNotNull);
expect(expression.body, isNotNull);
+ expect(invocation.typeArguments, isNull);
ArgumentList list = invocation.argumentList;
expect(list, isNotNull);
expect(list.arguments, hasLength(1));
@@ -8550,6 +8887,17 @@
parse4("parseNormalFormalParameter", "a())");
expect(parameter.returnType, isNull);
expect(parameter.identifier, isNotNull);
+ expect(parameter.typeParameters, isNull);
+ expect(parameter.parameters, isNotNull);
+ }
+
+ void test_parseNormalFormalParameter_function_noType_typeParameters() {
+ enableGenericMethods = true;
+ FunctionTypedFormalParameter parameter =
+ parse4("parseNormalFormalParameter", "a<E>())");
+ expect(parameter.returnType, isNull);
+ expect(parameter.identifier, isNotNull);
+ expect(parameter.typeParameters, isNotNull);
expect(parameter.parameters, isNotNull);
}
@@ -8558,6 +8906,17 @@
parse4("parseNormalFormalParameter", "A a())");
expect(parameter.returnType, isNotNull);
expect(parameter.identifier, isNotNull);
+ expect(parameter.typeParameters, isNull);
+ expect(parameter.parameters, isNotNull);
+ }
+
+ void test_parseNormalFormalParameter_function_type_typeParameters() {
+ enableGenericMethods = true;
+ FunctionTypedFormalParameter parameter =
+ parse4("parseNormalFormalParameter", "A a<E>())");
+ expect(parameter.returnType, isNotNull);
+ expect(parameter.identifier, isNotNull);
+ expect(parameter.typeParameters, isNotNull);
expect(parameter.parameters, isNotNull);
}
@@ -8566,6 +8925,17 @@
parse4("parseNormalFormalParameter", "void a())");
expect(parameter.returnType, isNotNull);
expect(parameter.identifier, isNotNull);
+ expect(parameter.typeParameters, isNull);
+ expect(parameter.parameters, isNotNull);
+ }
+
+ void test_parseNormalFormalParameter_function_void_typeParameters() {
+ enableGenericMethods = true;
+ FunctionTypedFormalParameter parameter =
+ parse4("parseNormalFormalParameter", "void a<E>())");
+ expect(parameter.returnType, isNotNull);
+ expect(parameter.identifier, isNotNull);
+ expect(parameter.typeParameters, isNotNull);
expect(parameter.parameters, isNotNull);
}
@@ -8631,6 +9001,7 @@
expect(method.modifierKeyword, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNotNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.propertyKeyword, isNull);
expect(method.returnType, returnType);
@@ -8682,6 +9053,7 @@
expect(expression.target, isNotNull);
expect(expression.operator.type, TokenType.PERIOD);
expect(expression.methodName, isNotNull);
+ expect(expression.typeArguments, isNull);
expect(expression.argumentList, isNotNull);
}
@@ -8691,6 +9063,28 @@
expect(expression.target, isNotNull);
expect(expression.operator.type, TokenType.QUESTION_PERIOD);
expect(expression.methodName, isNotNull);
+ expect(expression.typeArguments, isNull);
+ expect(expression.argumentList, isNotNull);
+ }
+
+ void test_parsePostfixExpression_none_methodInvocation_question_dot_typeArguments() {
+ enableGenericMethods = true;
+ _enableNullAwareOperators = true;
+ MethodInvocation expression = parse4('parsePostfixExpression', 'a?.m<E>()');
+ expect(expression.target, isNotNull);
+ expect(expression.operator.type, TokenType.QUESTION_PERIOD);
+ expect(expression.methodName, isNotNull);
+ expect(expression.typeArguments, isNotNull);
+ expect(expression.argumentList, isNotNull);
+ }
+
+ void test_parsePostfixExpression_none_methodInvocation_typeArguments() {
+ enableGenericMethods = true;
+ MethodInvocation expression = parse4("parsePostfixExpression", "a.m<E>()");
+ expect(expression.target, isNotNull);
+ expect(expression.operator.type, TokenType.PERIOD);
+ expect(expression.methodName, isNotNull);
+ expect(expression.typeArguments, isNotNull);
expect(expression.argumentList, isNotNull);
}
@@ -8961,6 +9355,7 @@
expect(method.modifierKeyword, isNull);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.propertyKeyword, isNotNull);
expect(method.returnType, returnType);
@@ -8982,6 +9377,7 @@
expect(method.modifierKeyword, staticKeyword);
expect(method.name, isNotNull);
expect(method.operatorKeyword, isNull);
+ expect(method.typeParameters, isNull);
expect(method.parameters, isNotNull);
expect(method.propertyKeyword, isNotNull);
expect(method.returnType, returnType);
@@ -9033,13 +9429,33 @@
expect(argumentList.rightBracket, isNotNull);
}
- void test_parseStatement_functionDeclaration() {
+ void test_parseStatement_functionDeclaration_noReturnType() {
+ FunctionDeclarationStatement statement =
+ parse4("parseStatement", "f(a, b) {};");
+ expect(statement.functionDeclaration, isNotNull);
+ }
+
+ void test_parseStatement_functionDeclaration_noReturnType_typeParameters() {
+ enableGenericMethods = true;
+ FunctionDeclarationStatement statement =
+ parse4("parseStatement", "f(a, b) {};");
+ expect(statement.functionDeclaration, isNotNull);
+ }
+
+ void test_parseStatement_functionDeclaration_returnType() {
// TODO(brianwilkerson) Implement more tests for this method.
FunctionDeclarationStatement statement =
parse4("parseStatement", "int f(a, b) {};");
expect(statement.functionDeclaration, isNotNull);
}
+ void test_parseStatement_functionDeclaration_returnType_typeParameters() {
+ enableGenericMethods = true;
+ FunctionDeclarationStatement statement =
+ parse4("parseStatement", "int f<E>(a, b) {};");
+ expect(statement.functionDeclaration, isNotNull);
+ }
+
void test_parseStatement_mulipleLabels() {
LabeledStatement statement = parse4("parseStatement", "l: m: return x;");
expect(statement.labels, hasLength(2));
diff --git a/pkg/analyzer/test/generated/source_factory_test.dart b/pkg/analyzer/test/generated/source_factory_test.dart
index 67ec71e..26b3942 100644
--- a/pkg/analyzer/test/generated/source_factory_test.dart
+++ b/pkg/analyzer/test/generated/source_factory_test.dart
@@ -31,32 +31,33 @@
void test_creation() {
expect(new SourceFactory([]), isNotNull);
}
+
void test_fromEncoding_invalidUri() {
SourceFactory factory = new SourceFactory([]);
- try {
- factory.fromEncoding("<:&%>");
- fail("Expected IllegalArgumentException");
- } on IllegalArgumentException {}
+ expect(() => factory.fromEncoding("<:&%>"),
+ throwsA(new isInstanceOf<IllegalArgumentException>()));
}
+
void test_fromEncoding_noResolver() {
SourceFactory factory = new SourceFactory([]);
- try {
- factory.fromEncoding("foo:/does/not/exist.dart");
- fail("Expected IllegalArgumentException");
- } on IllegalArgumentException {}
+ expect(() => factory.fromEncoding("foo:/does/not/exist.dart"),
+ throwsA(new isInstanceOf<IllegalArgumentException>()));
}
+
void test_fromEncoding_valid() {
String encoding = "file:///does/not/exist.dart";
SourceFactory factory = new SourceFactory(
[new UriResolver_SourceFactoryTest_test_fromEncoding_valid(encoding)]);
expect(factory.fromEncoding(encoding), isNotNull);
}
+
void test_resolveUri_absolute() {
UriResolver_absolute resolver = new UriResolver_absolute();
SourceFactory factory = new SourceFactory([resolver]);
factory.resolveUri(null, "dart:core");
expect(resolver.invoked, isTrue);
}
+
void test_resolveUri_nonAbsolute_absolute() {
SourceFactory factory =
new SourceFactory([new UriResolver_nonAbsolute_absolute()]);
@@ -67,6 +68,7 @@
expect(result.fullName,
FileUtilities2.createFile(absolutePath).getAbsolutePath());
}
+
void test_resolveUri_nonAbsolute_relative() {
SourceFactory factory =
new SourceFactory([new UriResolver_nonAbsolute_relative()]);
@@ -146,9 +148,7 @@
class UriResolver_restoreUri extends UriResolver {
Source source1;
-
Uri expected1;
-
UriResolver_restoreUri(this.source1, this.expected1);
@override
@@ -166,7 +166,6 @@
class UriResolver_SourceFactoryTest_test_fromEncoding_valid
extends UriResolver {
String encoding;
-
UriResolver_SourceFactoryTest_test_fromEncoding_valid(this.encoding);
@override
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 2552ea7..666b233 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -551,7 +551,7 @@
class TestSource extends Source {
String _name;
String _contents;
- int modificationStamp = 0;
+ int _modificationStamp = 0;
bool exists2 = true;
/**
@@ -560,6 +560,9 @@
*/
bool generateExceptionOnRead = false;
+ @override
+ int get modificationStamp => generateExceptionOnRead ? -1 : _modificationStamp;
+
/**
* The number of times that the contents of this source have been requested.
*/
@@ -611,7 +614,8 @@
return new Uri(scheme: 'file', path: _name).resolveUri(uri);
}
void setContents(String value) {
- modificationStamp = new DateTime.now().millisecondsSinceEpoch;
+ generateExceptionOnRead = false;
+ _modificationStamp = new DateTime.now().millisecondsSinceEpoch;
_contents = value;
}
@override
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 24d1d96..3219e90 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1943,6 +1943,12 @@
Expression get(AssignmentExpression node) => node.leftHandSide;
}
+class Getter_NodeReplacerTest_test_awaitExpression
+ implements NodeReplacerTest_Getter {
+ @override
+ Expression get(AwaitExpression node) => node.expression;
+}
+
class Getter_NodeReplacerTest_test_binaryExpression
implements NodeReplacerTest_Getter {
@override
@@ -2762,6 +2768,12 @@
StringLiteral get(UriBasedDirective node) => node.uri;
}
+class Getter_NodeReplacerTest_test_yieldStatement
+ implements NodeReplacerTest_Getter {
+ @override
+ Expression get(YieldStatement node) => node.expression;
+}
+
@reflectiveTest
class LineInfoTest {
void test_creation() {
@@ -3278,6 +3290,11 @@
node, new Getter_NodeReplacerTest_test_assignmentExpression());
}
+ void test_awaitExpression() {
+ var node = AstFactory.awaitExpression(AstFactory.identifier3("A"));
+ _assertReplace(node, new Getter_NodeReplacerTest_test_awaitExpression());
+ }
+
void test_binaryExpression() {
BinaryExpression node = AstFactory.binaryExpression(
AstFactory.identifier3("l"), TokenType.PLUS,
@@ -4092,6 +4109,11 @@
_assertReplace(node, new Getter_NodeReplacerTest_testUriBasedDirective());
_testAnnotatedNode(node);
}
+
+ void test_yieldStatement() {
+ var node = AstFactory.yieldStatement(AstFactory.identifier3("A"));
+ _assertReplace(node, new Getter_NodeReplacerTest_test_yieldStatement());
+ }
}
abstract class NodeReplacerTest_Getter<P, C> {
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 60e430c..af84f24 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -29,14 +29,15 @@
IncrementalAnalysisCache,
TimestampedData;
import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht;
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/scanner.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart' show Document;
-import 'package:path/path.dart' as pathos;
import 'package:unittest/unittest.dart';
import 'package:watcher/src/utils.dart';
@@ -48,106 +49,11 @@
main() {
groupSep = ' | ';
runReflectiveTests(AnalysisContextImplTest);
+ runReflectiveTests(LimitedInvalidateTest);
}
@reflectiveTest
class AnalysisContextImplTest extends AbstractContextTest {
- void fail_applyChanges_empty() {
- context.applyChanges(new ChangeSet());
- expect(context.performAnalysisTask().changeNotices, isNull);
- // This test appears to be flaky. If it is named "test_" it fails, if it's
- // named "fail_" it doesn't fail. I'm guessing that it's dependent on
- // whether some other test is run.
- fail('Should have failed');
- }
-
- void fail_extractContext() {
- fail("Implement this");
- }
-
- void fail_mergeContext() {
- fail("Implement this");
- }
-
- void fail_parseHtmlUnit_resolveDirectives() {
- Source libSource = addSource("/lib.dart", r'''
-library lib;
-class ClassA {}''');
- Source source = addSource("/lib.html", r'''
-<!DOCTYPE html>
-<html>
-<head>
- <script type='application/dart'>
- import 'lib.dart';
- ClassA v = null;
- </script>
-</head>
-<body>
-</body>
-</html>''');
- // TODO(brianwilkerson) Rewrite this. We need a way to get the AST for the
- // script.
- ht.HtmlUnit unit = context.parseHtmlUnit(source);
- expect(unit, isNotNull);
- // import directive should be resolved
- ht.XmlTagNode htmlNode = unit.tagNodes[0];
- ht.XmlTagNode headNode = htmlNode.tagNodes[0];
- ht.HtmlScriptTagNode scriptNode = headNode.tagNodes[0];
- CompilationUnit script = scriptNode.script;
- ImportDirective importNode = script.directives[0] as ImportDirective;
- expect(importNode.uriContent, isNotNull);
- expect(importNode.source, libSource);
- }
-
- void fail_performAnalysisTask_getContentException_dart() {
- Source source = _addSourceWithException('test.dart');
- // prepare errors
- _analyzeAll_assertFinished();
- List<AnalysisError> errors = context.getErrors(source).errors;
- // validate errors
- expect(errors, hasLength(1));
- AnalysisError error = errors[0];
- expect(error.source, same(source));
- expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
- }
-
- void fail_performAnalysisTask_getContentException_html() {
- Source source = _addSourceWithException('test.html');
- // prepare errors
- _analyzeAll_assertFinished();
- List<AnalysisError> errors = context.getErrors(source).errors;
- // validate errors
- expect(errors, hasLength(1));
- AnalysisError error = errors[0];
- expect(error.source, same(source));
- expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
- }
-
- void test_performAnalysisTask_importedLibraryAdd_html() {
- Source htmlSource = addSource("/page.html", r'''
-<html><body><script type="application/dart">
- import '/libB.dart';
- main() {print('hello dart');}
-</script></body></html>''');
- _analyzeAll_assertFinished();
- context.computeErrors(htmlSource);
- expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)),
- isTrue, reason: "htmlSource has an error");
- // add libB.dart and analyze
- Source libBSource = addSource("/libB.dart", "library libB;");
- _analyzeAll_assertFinished();
- expect(
- context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
- reason: "libB resolved 2");
- // TODO (danrubel) commented out to fix red bots
-// context.computeErrors(htmlSource);
-// AnalysisErrorInfo errors = _context.getErrors(htmlSource);
-// expect(
-// !_hasAnalysisErrorWithErrorSeverity(errors),
-// isTrue,
-// reason: "htmlSource doesn't have errors");
- }
-
void fail_performAnalysisTask_importedLibraryDelete_html() {
// NOTE: This was failing before converting to the new task model.
Source htmlSource = addSource("/page.html", r'''
@@ -172,111 +78,10 @@
reason: "htmlSource has an error");
}
- void fail_performAnalysisTask_IOException() {
- TestSource source = _addSourceWithException2("/test.dart", "library test;");
- int oldTimestamp = context.getModificationStamp(source);
- source.generateExceptionOnRead = false;
- _analyzeAll_assertFinished();
- expect(source.readCount, 1);
- source.generateExceptionOnRead = true;
- do {
- _changeSource(source, "");
- // Ensure that the timestamp differs,
- // so that analysis engine notices the change
- } while (oldTimestamp == context.getModificationStamp(source));
- _analyzeAll_assertFinished();
- expect(source.readCount, 2);
- }
-
void fail_recordLibraryElements() {
fail("Implement this");
}
- void fail_setAnalysisOptions_reduceAnalysisPriorityOrder() {
- AnalysisOptionsImpl options =
- new AnalysisOptionsImpl.from(context.analysisOptions);
- List<Source> sources = new List<Source>();
- for (int index = 0; index < options.cacheSize; index++) {
- sources.add(addSource("/lib.dart$index", ""));
- }
- context.analysisPriorityOrder = sources;
- int oldPriorityOrderSize = _getPriorityOrder(context).length;
- options.cacheSize = options.cacheSize - 10;
- context.analysisOptions = options;
- expect(oldPriorityOrderSize > _getPriorityOrder(context).length, isTrue);
- }
-
- void fail_setAnalysisPriorityOrder_lessThanCacheSize() {
- AnalysisOptions options = context.analysisOptions;
- List<Source> sources = new List<Source>();
- for (int index = 0; index < options.cacheSize; index++) {
- sources.add(addSource("/lib.dart$index", ""));
- }
- context.analysisPriorityOrder = sources;
- expect(options.cacheSize > _getPriorityOrder(context).length, isTrue);
- }
-
- Future fail_setChangedContents_libraryWithPart() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.incremental = true;
- context.analysisOptions = options;
- SourcesChangedListener listener = new SourcesChangedListener();
- context.onSourcesChanged.listen(listener.onData);
- String oldCode = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
- Source librarySource = addSource("/lib.dart", oldCode);
- String partContents = r'''
-part of lib;
-int b = a;''';
- Source partSource = addSource("/part.dart", partContents);
- LibraryElement element = context.computeLibraryElement(librarySource);
- CompilationUnit unit =
- context.getResolvedCompilationUnit(librarySource, element);
- expect(unit, isNotNull);
- int offset = oldCode.indexOf("int a") + 4;
- String newCode = r'''
-library lib;
-part 'part.dart';
-int ya = 0;''';
- expect(_getIncrementalAnalysisCache(context), isNull);
- context.setChangedContents(librarySource, newCode, offset, 0, 1);
- expect(context.getContents(librarySource).data, newCode);
- IncrementalAnalysisCache incrementalCache =
- _getIncrementalAnalysisCache(context);
- expect(incrementalCache.librarySource, librarySource);
- expect(incrementalCache.resolvedUnit, same(unit));
- expect(
- context.getResolvedCompilationUnit2(partSource, librarySource), isNull);
- expect(incrementalCache.newContents, newCode);
- return pumpEventQueue().then((_) {
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [librarySource]);
- listener.assertEvent(wereSourcesAdded: true);
- listener.assertEvent(changedSources: [partSource]);
- listener.assertEvent(changedSources: [librarySource]);
- listener.assertNoMoreEvents();
- });
- }
-
- void fail_unreadableSource() {
- Source test1 = addSource("/test1.dart", r'''
-import 'test2.dart';
-library test1;''');
- Source test2 = addSource("/test2.dart", r'''
-import 'test1.dart';
-import 'test3.dart';
-library test2;''');
- Source test3 = _addSourceWithException("/test3.dart");
- _analyzeAll_assertFinished();
- // test1 and test2 should have been successfully analyzed
- // despite the fact that test3 couldn't be read.
- expect(context.computeLibraryElement(test1), isNotNull);
- expect(context.computeLibraryElement(test2), isNotNull);
- expect(context.computeLibraryElement(test3), isNull);
- }
-
@override
void tearDown() {
context = null;
@@ -420,6 +225,11 @@
});
}
+ void test_applyChanges_empty() {
+ context.applyChanges(new ChangeSet());
+ expect(context.performAnalysisTask().changeNotices, isNull);
+ }
+
void test_applyChanges_overriddenSource() {
// Note: addSource adds the source to the contentCache.
Source source = addSource("/test.dart", "library test;");
@@ -1446,6 +1256,32 @@
expect(document, isNotNull);
}
+ void test_parseHtmlUnit_resolveDirectives() {
+ Source libSource = addSource("/lib.dart", r'''
+library lib;
+class ClassA {}''');
+ Source source = addSource("/lib.html", r'''
+<!DOCTYPE html>
+<html>
+<head>
+ <script type='application/dart'>
+ import 'lib.dart';
+ ClassA v = null;
+ </script>
+</head>
+<body>
+</body>
+</html>''');
+ Document document = context.parseHtmlDocument(source);
+ expect(document, isNotNull);
+ List<DartScript> scripts = context.computeResult(source, DART_SCRIPTS);
+ expect(scripts, hasLength(1));
+ CompilationUnit unit = context.computeResult(scripts[0], PARSED_UNIT);
+ ImportDirective importNode = unit.directives[0] as ImportDirective;
+ expect(importNode.uriContent, isNotNull);
+ expect(importNode.source, libSource);
+ }
+
void test_performAnalysisTask_addPart() {
Source libSource = addSource("/lib.dart", r'''
library lib;
@@ -1604,28 +1440,72 @@
reason: "part resolved 1");
// update and analyze #1
context.setContents(partSource, "part of lib; // 1");
- expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
- reason: "library changed 2");
- expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part changed 2");
- _analyzeAll_assertFinished();
- expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 2");
- expect(
- context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
- reason: "part resolved 2");
+ if (AnalysisEngine.instance.limitInvalidationInTaskModel) {
+ expect(
+ context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
+ reason: "library changed 2");
+ expect(
+ context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
+ reason: "part changed 2");
+ } else {
+ expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
+ reason: "library changed 2");
+ expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
+ reason: "part changed 2");
+ _analyzeAll_assertFinished();
+ expect(
+ context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
+ reason: "library resolved 2");
+ expect(
+ context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
+ reason: "part resolved 2");
+ }
// update and analyze #2
context.setContents(partSource, "part of lib; // 12");
- expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
- reason: "library changed 3");
- expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
- reason: "part changed 3");
+ if (AnalysisEngine.instance.limitInvalidationInTaskModel) {
+ expect(
+ context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
+ reason: "library changed 3");
+ expect(
+ context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
+ reason: "part changed 3");
+ } else {
+ expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
+ reason: "library changed 3");
+ expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
+ reason: "part changed 3");
+ _analyzeAll_assertFinished();
+ expect(
+ context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
+ reason: "library resolved 3");
+ expect(
+ context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
+ reason: "part resolved 3");
+ }
+ }
+
+ void test_performAnalysisTask_getContentException_dart() {
+ Source source = _addSourceWithException('test.dart');
+ // prepare errors
_analyzeAll_assertFinished();
- expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
- reason: "library resolved 3");
- expect(
- context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
- reason: "part resolved 3");
+ List<AnalysisError> errors = context.getErrors(source).errors;
+ // validate errors
+ expect(errors, hasLength(1));
+ AnalysisError error = errors[0];
+ expect(error.source, same(source));
+ expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
+ }
+
+ void test_performAnalysisTask_getContentException_html() {
+ Source source = _addSourceWithException('test.html');
+ // prepare errors
+ _analyzeAll_assertFinished();
+ List<AnalysisError> errors = context.getErrors(source).errors;
+ // validate errors
+ expect(errors, hasLength(1));
+ AnalysisError error = errors[0];
+ expect(error.source, same(source));
+ expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
}
void test_performAnalysisTask_importedLibraryAdd() {
@@ -1650,6 +1530,31 @@
isFalse, reason: "libA doesn't have errors");
}
+ void test_performAnalysisTask_importedLibraryAdd_html() {
+ Source htmlSource = addSource("/page.html", r'''
+<html><body><script type="application/dart">
+ import '/libB.dart';
+ main() {print('hello dart');}
+</script></body></html>''');
+ _analyzeAll_assertFinished();
+ context.computeErrors(htmlSource);
+ expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)),
+ isTrue, reason: "htmlSource has an error");
+ // add libB.dart and analyze
+ Source libBSource = addSource("/libB.dart", "library libB;");
+ _analyzeAll_assertFinished();
+ expect(
+ context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
+ reason: "libB resolved 2");
+ // TODO (danrubel) commented out to fix red bots
+// context.computeErrors(htmlSource);
+// AnalysisErrorInfo errors = _context.getErrors(htmlSource);
+// expect(
+// !_hasAnalysisErrorWithErrorSeverity(errors),
+// isTrue,
+// reason: "htmlSource doesn't have errors");
+ }
+
void test_performAnalysisTask_importedLibraryDelete() {
Source libASource =
addSource("/libA.dart", "library libA; import 'libB.dart';");
@@ -1673,6 +1578,21 @@
isTrue, reason: "libA has an error");
}
+ void test_performAnalysisTask_IOException() {
+ TestSource source = _addSourceWithException2("/test.dart", "library test;");
+ source.generateExceptionOnRead = false;
+ _analyzeAll_assertFinished();
+ expect(source.readCount, 1);
+ _changeSource(source, "");
+ source.generateExceptionOnRead = true;
+ _analyzeAll_assertFinished();
+ if (AnalysisEngine.instance.limitInvalidationInTaskModel) {
+ expect(source.readCount, 5);
+ } else {
+ expect(source.readCount, 3);
+ }
+ }
+
void test_performAnalysisTask_missingPart() {
Source source =
addSource("/test.dart", "library lib; part 'no-such-file.dart';");
@@ -1729,17 +1649,6 @@
expect(resolvedUnitUris, contains('file:///test.dart'));
}
-// void test_resolveCompilationUnit_sourceChangeDuringResolution() {
-// _context = new _AnalysisContext_sourceChangeDuringResolution();
-// AnalysisContextFactory.initContextWithCore(_context);
-// _sourceFactory = _context.sourceFactory;
-// Source source = _addSource("/lib.dart", "library lib;");
-// CompilationUnit compilationUnit =
-// _context.resolveCompilationUnit2(source, source);
-// expect(compilationUnit, isNotNull);
-// expect(_context.getLineInfo(source), isNotNull);
-// }
-
void test_resolveCompilationUnit_import_relative() {
Source sourceA =
addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
@@ -1780,6 +1689,17 @@
]);
}
+// void test_resolveCompilationUnit_sourceChangeDuringResolution() {
+// _context = new _AnalysisContext_sourceChangeDuringResolution();
+// AnalysisContextFactory.initContextWithCore(_context);
+// _sourceFactory = _context.sourceFactory;
+// Source source = _addSource("/lib.dart", "library lib;");
+// CompilationUnit compilationUnit =
+// _context.resolveCompilationUnit2(source, source);
+// expect(compilationUnit, isNotNull);
+// expect(_context.getLineInfo(source), isNotNull);
+// }
+
void test_resolveCompilationUnit_library() {
Source source = addSource("/lib.dart", "library lib;");
LibraryElement library = context.computeLibraryElement(source);
@@ -1808,6 +1728,16 @@
expect(result.hint, options.hint);
}
+ void test_setAnalysisPriorityOrder() {
+ int priorityCount = 4;
+ List<Source> sources = new List<Source>();
+ for (int index = 0; index < priorityCount; index++) {
+ sources.add(addSource("/lib.dart$index", ""));
+ }
+ context.analysisPriorityOrder = sources;
+ expect(_getPriorityOrder(context).length, priorityCount);
+ }
+
void test_setAnalysisPriorityOrder_empty() {
context.analysisPriorityOrder = new List<Source>();
}
@@ -1818,6 +1748,42 @@
context.analysisPriorityOrder = sources;
}
+ Future test_setChangedContents_libraryWithPart() {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.incremental = true;
+ context.analysisOptions = options;
+ SourcesChangedListener listener = new SourcesChangedListener();
+ context.onSourcesChanged.listen(listener.onData);
+ String oldCode = r'''
+library lib;
+part 'part.dart';
+int a = 0;''';
+ Source librarySource = addSource("/lib.dart", oldCode);
+ String partContents = r'''
+part of lib;
+int b = a;''';
+ Source partSource = addSource("/part.dart", partContents);
+ LibraryElement element = context.computeLibraryElement(librarySource);
+ CompilationUnit unit =
+ context.resolveCompilationUnit(librarySource, element);
+ expect(unit, isNotNull);
+ int offset = oldCode.indexOf("int a") + 4;
+ String newCode = r'''
+library lib;
+part 'part.dart';
+int ya = 0;''';
+ context.setChangedContents(librarySource, newCode, offset, 0, 1);
+ expect(context.getContents(librarySource).data, newCode);
+ expect(
+ context.getResolvedCompilationUnit2(partSource, librarySource), isNull);
+ return pumpEventQueue().then((_) {
+ listener.assertEvent(wereSourcesAdded: true);
+ listener.assertEvent(wereSourcesAdded: true);
+ listener.assertEvent(changedSources: [librarySource]);
+ listener.assertNoMoreEvents();
+ });
+ }
+
void test_setChangedContents_notResolved() {
AnalysisOptionsImpl options =
new AnalysisOptionsImpl.from(context.analysisOptions);
@@ -1833,7 +1799,6 @@
int ya = 0;''';
context.setChangedContents(librarySource, newCode, offset, 0, 1);
expect(context.getContents(librarySource).data, newCode);
- expect(_getIncrementalAnalysisCache(context), isNull);
}
Future test_setContents_libraryWithPart() {
@@ -1849,10 +1814,6 @@
int b = a;''';
Source partSource = addSource("/part.dart", partContents1);
context.computeLibraryElement(librarySource);
- IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
- librarySource, librarySource, null, null, null, 0, 0, 0);
- _setIncrementalAnalysisCache(context, incrementalCache);
- expect(_getIncrementalAnalysisCache(context), same(incrementalCache));
String libraryContents2 = r'''
library lib;
part 'part.dart';
@@ -1860,7 +1821,6 @@
context.setContents(librarySource, libraryContents2);
expect(
context.getResolvedCompilationUnit2(partSource, librarySource), isNull);
- expect(_getIncrementalAnalysisCache(context), isNull);
return pumpEventQueue().then((_) {
listener.assertEvent(wereSourcesAdded: true);
listener.assertEvent(wereSourcesAdded: true);
@@ -1875,14 +1835,9 @@
int a = 0;''');
context.setContents(librarySource, '// different');
context.computeLibraryElement(librarySource);
- IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
- librarySource, librarySource, null, null, null, 0, 0, 0);
- _setIncrementalAnalysisCache(context, incrementalCache);
- expect(_getIncrementalAnalysisCache(context), same(incrementalCache));
context.setContents(librarySource, null);
expect(context.getResolvedCompilationUnit2(librarySource, librarySource),
isNull);
- expect(_getIncrementalAnalysisCache(context), isNull);
}
void test_setContents_unchanged_consistentModificationTime() {
@@ -2009,11 +1964,6 @@
entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
}
- IncrementalAnalysisCache _getIncrementalAnalysisCache(
- AnalysisContextImpl context2) {
- return context2.test_incrementalAnalysisCache;
- }
-
List<Source> _getPriorityOrder(AnalysisContextImpl context2) {
return context2.test_priorityOrder;
}
@@ -2033,11 +1983,6 @@
context.applyChanges(changeSet);
}
- void _setIncrementalAnalysisCache(
- AnalysisContextImpl context, IncrementalAnalysisCache incrementalCache) {
- context.test_incrementalAnalysisCache = incrementalCache;
- }
-
/**
* Returns `true` if there is an [AnalysisError] with [ErrorSeverity.ERROR] in
* the given [AnalysisErrorInfo].
@@ -2053,6 +1998,278 @@
}
}
+@reflectiveTest
+class LimitedInvalidateTest extends AbstractContextTest {
+ @override
+ void setUp() {
+ AnalysisEngine.instance.limitInvalidationInTaskModel = true;
+ super.setUp();
+ AnalysisOptionsImpl options =
+ new AnalysisOptionsImpl.from(context.analysisOptions);
+ options.incremental = true;
+ context.analysisOptions = options;
+ }
+
+ @override
+ void tearDown() {
+ AnalysisEngine.instance.limitInvalidationInTaskModel = false;
+ super.tearDown();
+ }
+
+ void test_noChange_thenChange() {
+ Source sourceA = addSource("/a.dart", r'''
+library lib_a;
+
+class A {
+ A();
+}
+class B {
+ B();
+}
+''');
+ Source sourceB = addSource("/b.dart", r'''
+library lib_b;
+import 'a.dart';
+main() {
+ new A();
+}
+''');
+ _performPendingAnalysisTasks();
+ expect(context.getErrors(sourceA).errors, hasLength(0));
+ expect(context.getErrors(sourceB).errors, hasLength(0));
+ var unitA = context.getResolvedCompilationUnit2(sourceA, sourceA);
+ var unitElementA = unitA.element;
+ var libraryElementA = unitElementA.library;
+ // Update a.dart, no declaration changes.
+ context.setContents(sourceA, r'''
+library lib_a;
+class A {
+ A();
+}
+class B {
+ B();
+}
+''');
+ _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+ _assertValid(sourceB, LIBRARY_ERRORS_READY);
+ // The a.dart's unit and element are updated incrementally.
+ // They are the same instances as initially.
+ // So, all the references from other units are still valid.
+ {
+ LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA);
+ expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA));
+ expect(unitA.element, same(unitElementA));
+ expect(unitElementA.library, same(libraryElementA));
+ }
+ // Analyze.
+ _performPendingAnalysisTasks();
+ expect(context.getErrors(sourceA).errors, hasLength(0));
+ expect(context.getErrors(sourceB).errors, hasLength(0));
+ // The a.dart's unit and element are the same.
+ {
+ LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA);
+ expect(analysisCache.getValue(target, RESOLVED_UNIT), same(unitA));
+ expect(unitA.element, same(unitElementA));
+ expect(unitElementA.library, same(libraryElementA));
+ }
+ // Update a.dart, rename A to A2, invalidates b.dart, so
+ // we know that the previous update did not damage dependencies.
+ context.setContents(sourceA, r'''
+library lib_a;
+class A {
+ A();
+ m() {}
+}
+class B {
+ B();
+}
+''');
+ _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+ _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+ // The a.dart's unit and element are the same.
+ {
+ LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA);
+ expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA));
+ expect(unitA.element, same(unitElementA));
+ expect(unitElementA.library, same(libraryElementA));
+ }
+ // Analyze.
+ _performPendingAnalysisTasks();
+ expect(context.getErrors(sourceA).errors, hasLength(0));
+ expect(context.getErrors(sourceB).errors, hasLength(0));
+ }
+
+ void test_unusedName() {
+ Source sourceA = addSource("/a.dart", r'''
+library lib_a;
+class A {}
+class B {}
+class C {}
+''');
+ Source sourceB = addSource("/b.dart", r'''
+library lib_b;
+import 'a.dart';
+main() {
+ new A();
+ new C();
+}
+''');
+ _performPendingAnalysisTasks();
+ // Update A.
+ context.setContents(sourceA, r'''
+library lib_a;
+class A {}
+class B2 {}
+class C {}
+''');
+ // Only a.dart is invalidated.
+ // Because b.dart does not use B, so it is valid.
+ _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+ _assertValid(sourceB, LIBRARY_ERRORS_READY);
+ }
+
+ void test_usedName_directUser() {
+ Source sourceA = addSource("/a.dart", r'''
+library lib_a;
+class A {}
+class B {}
+class C {}
+''');
+ Source sourceB = addSource("/b.dart", r'''
+library lib_b;
+import 'a.dart';
+main() {
+ new A();
+ new C2();
+}
+''');
+ _performPendingAnalysisTasks();
+ expect(context.getErrors(sourceB).errors, hasLength(1));
+ // Update a.dart, invalidates b.dart because it references "C2".
+ context.setContents(sourceA, r'''
+library lib_a;
+class A {}
+class B {}
+class C2 {}
+''');
+ _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+ _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+ // Now b.dart is analyzed and the error is fixed.
+ _performPendingAnalysisTasks();
+ expect(context.getErrors(sourceB).errors, hasLength(0));
+ // Update a.dart, invalidates b.dart because it references "C".
+ context.setContents(sourceA, r'''
+library lib_a;
+class A {}
+class B {}
+class C {}
+''');
+ _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+ _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+ _performPendingAnalysisTasks();
+ // Now b.dart is analyzed and it again has the error.
+ expect(context.getErrors(sourceB).errors, hasLength(1));
+ }
+
+ void test_usedName_directUser_withIncremental() {
+ Source sourceA = addSource("/a.dart", r'''
+library lib_a;
+class A {
+ m() {}
+}
+''');
+ Source sourceB = addSource("/b.dart", r'''
+library lib_b;
+import 'a.dart';
+main() {
+ A a = new A();
+ a.m();
+}
+''');
+ _performPendingAnalysisTasks();
+ // Update A.
+ context.setContents(sourceA, r'''
+library lib_a;
+class A {
+ m2() {}
+}
+''');
+ _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+ _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+ }
+
+ void test_usedName_indirectUser() {
+ Source sourceA = addSource("/a.dart", r'''
+library lib_a;
+class A {
+ m() {}
+}
+''');
+ Source sourceB = addSource("/b.dart", r'''
+library lib_b;
+import 'a.dart';
+class B extends A {}
+''');
+ Source sourceC = addSource("/c.dart", r'''
+library lib_c;
+import 'b.dart';
+class C extends B {
+ main() {
+ m();
+ }
+}
+''');
+ // No errors, "A.m" exists.
+ _performPendingAnalysisTasks();
+ expect(context.getErrors(sourceC).errors, hasLength(0));
+ // Replace "A.m" with "A.m2", invalidate both b.dart and c.dart files.
+ context.setContents(sourceA, r'''
+library lib_a;
+class A {
+ m2() {}
+}
+''');
+ _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+ _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+ _assertInvalid(sourceC, LIBRARY_ERRORS_READY);
+ // There is an error in c.dart, "A.m" does not exist.
+ _performPendingAnalysisTasks();
+ expect(context.getErrors(sourceB).errors, hasLength(0));
+ expect(context.getErrors(sourceC).errors, hasLength(1));
+ // Restore "A.m", invalidate both b.dart and c.dart files.
+ context.setContents(sourceA, r'''
+library lib_a;
+class A {
+ m() {}
+}
+''');
+ _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+ _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+ _assertInvalid(sourceC, LIBRARY_ERRORS_READY);
+ // No errors, "A.m" exists.
+ _performPendingAnalysisTasks();
+ expect(context.getErrors(sourceC).errors, hasLength(0));
+ }
+
+ void _assertInvalid(AnalysisTarget target, ResultDescriptor descriptor) {
+ CacheState state = analysisCache.getState(target, descriptor);
+ expect(state, CacheState.INVALID);
+ }
+
+ void _assertValid(AnalysisTarget target, ResultDescriptor descriptor) {
+ CacheState state = analysisCache.getState(target, descriptor);
+ expect(state, CacheState.VALID);
+ }
+
+ void _performPendingAnalysisTasks([int maxTasks = 512]) {
+ for (int i = 0; context.performAnalysisTask().hasMoreWork; i++) {
+ if (i > maxTasks) {
+ fail('Analysis did not terminate.');
+ }
+ }
+ }
+}
+
class _AnalysisContextImplTest_test_applyChanges_removeContainer
implements SourceContainer {
Source libB;
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index e8b5813..c89e6e9 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -32,7 +32,8 @@
runReflectiveTests(BuildCompilationUnitElementTaskTest);
runReflectiveTests(BuildDirectiveElementsTaskTest);
runReflectiveTests(BuildEnumMemberElementsTaskTest);
- runReflectiveTests(BuildSourceClosuresTaskTest);
+ runReflectiveTests(BuildSourceExportClosureTaskTest);
+ runReflectiveTests(BuildSourceImportExportClosureTaskTest);
runReflectiveTests(BuildExportNamespaceTaskTest);
runReflectiveTests(BuildLibraryConstructorsTaskTest);
runReflectiveTests(BuildLibraryElementTaskTest);
@@ -1098,7 +1099,7 @@
}
@reflectiveTest
-class BuildSourceClosuresTaskTest extends _AbstractDartTaskTest {
+class BuildSourceExportClosureTaskTest extends _AbstractDartTaskTest {
test_perform_exportClosure() {
Source sourceA = newSource('/a.dart', '''
library lib_a;
@@ -1118,73 +1119,29 @@
// a.dart
{
computeResult(sourceA, EXPORT_SOURCE_CLOSURE);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+ expect(task, new isInstanceOf<BuildSourceExportClosureTask>());
List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
}
// c.dart
{
computeResult(sourceC, EXPORT_SOURCE_CLOSURE);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+ expect(task, new isInstanceOf<BuildSourceExportClosureTask>());
List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
}
// d.dart
{
computeResult(sourceD, EXPORT_SOURCE_CLOSURE);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+ expect(task, new isInstanceOf<BuildSourceExportClosureTask>());
List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
expect(closure, unorderedEquals([sourceD]));
}
}
+}
- test_perform_importClosure() {
- Source sourceA = newSource('/a.dart', '''
-library lib_a;
-import 'b.dart';
-''');
- Source sourceB = newSource('/b.dart', '''
-library lib_b;
-import 'c.dart';
-''');
- Source sourceC = newSource('/c.dart', '''
-library lib_c;
-import 'a.dart';
-''');
- Source sourceD = newSource('/d.dart', '''
-library lib_d;
-''');
- Source coreSource = context.sourceFactory.resolveUri(null, 'dart:core');
- // a.dart
- {
- computeResult(sourceA, IMPORT_SOURCE_CLOSURE);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
- List<Source> closure = outputs[IMPORT_SOURCE_CLOSURE];
- expect(closure, contains(sourceA));
- expect(closure, contains(sourceB));
- expect(closure, contains(sourceC));
- expect(closure, contains(coreSource));
- }
- // c.dart
- {
- computeResult(sourceC, IMPORT_SOURCE_CLOSURE);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
- List<Source> closure = outputs[IMPORT_SOURCE_CLOSURE];
- expect(closure, contains(sourceA));
- expect(closure, contains(sourceB));
- expect(closure, contains(sourceC));
- expect(closure, contains(coreSource));
- }
- // d.dart
- {
- computeResult(sourceD, IMPORT_SOURCE_CLOSURE);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
- List<Source> closure = outputs[IMPORT_SOURCE_CLOSURE];
- expect(closure, contains(sourceD));
- expect(closure, contains(coreSource));
- }
- }
-
+@reflectiveTest
+class BuildSourceImportExportClosureTaskTest extends _AbstractDartTaskTest {
test_perform_importExportClosure() {
Source sourceA = newSource('/a.dart', '''
library lib_a;
@@ -1201,7 +1158,7 @@
// c.dart
{
computeResult(sourceC, IMPORT_EXPORT_SOURCE_CLOSURE);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+ expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE];
expect(closure, contains(sourceA));
expect(closure, contains(sourceB));
@@ -1211,7 +1168,7 @@
// b.dart
{
computeResult(sourceB, IMPORT_EXPORT_SOURCE_CLOSURE);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+ expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE];
expect(closure, contains(sourceA));
expect(closure, contains(sourceB));
@@ -1228,7 +1185,7 @@
library lib_b;
''');
computeResult(sourceA, IS_CLIENT);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+ expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
expect(outputs[IS_CLIENT], isFalse);
}
@@ -1241,7 +1198,7 @@
import 'exports_html.dart';
''');
computeResult(source, IS_CLIENT);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+ expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
expect(outputs[IS_CLIENT], isTrue);
}
@@ -1251,7 +1208,7 @@
import 'dart:html';
''');
computeResult(sourceA, IS_CLIENT);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+ expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
expect(outputs[IS_CLIENT], isTrue);
}
@@ -1265,7 +1222,7 @@
import 'dart:html';
''');
computeResult(sourceA, IS_CLIENT);
- expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+ expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
expect(outputs[IS_CLIENT], isTrue);
}
}
@@ -2338,7 +2295,7 @@
}
}
- test_perform_deep() {
+ test_perform_external() {
Source sourceA = newSource('/a.dart', '''
library a;
import 'b.dart';
@@ -2346,18 +2303,10 @@
''');
newSource('/b.dart', '''
library b;
-import 'c.dart';
-part 'b2.dart';
-class B extends B2 {}
+class B {}
''');
- newSource('/b2.dart', '''
-part of b;
-class B2 extends C {}
-''');
- newSource('/c.dart', '''
-library c;
-class C {}
-''');
+ // The reference A to B should be resolved, but there's no requirement that
+ // the full class hierarchy be resolved.
computeResult(sourceA, LIBRARY_ELEMENT5);
expect(task, new isInstanceOf<ResolveLibraryTypeNamesTask>());
// validate
@@ -2367,13 +2316,6 @@
expect(clazz.displayName, 'A');
clazz = clazz.supertype.element;
expect(clazz.displayName, 'B');
- clazz = clazz.supertype.element;
- expect(clazz.displayName, 'B2');
- clazz = clazz.supertype.element;
- expect(clazz.displayName, 'C');
- clazz = clazz.supertype.element;
- expect(clazz.displayName, 'Object');
- expect(clazz.supertype, isNull);
}
}
}
diff --git a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
index 415e031..cc6e95b 100644
--- a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
+++ b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
@@ -543,6 +543,54 @@
expect(unitDelta.removedDeclarations, unorderedEquals([]));
}
+ test_unitMembers_topLevelVariable() {
+ _buildOldUnit(r'''
+bool a = 1, b = 2;
+int c = 3;
+''');
+ List<CompilationUnitMember> oldNodes = oldUnit.declarations.toList();
+ _buildNewUnit(r'''
+int c = 3;
+
+bool a =1, b = 2;
+''');
+ List<CompilationUnitMember> newNodes = newUnit.declarations;
+ {
+ TopLevelVariableDeclaration newNode = newNodes[0];
+ expect(newNode, same(oldNodes[1]));
+ expect(getNodeText(newNode), 'int c = 3;');
+ {
+ TopLevelVariableElement element =
+ newNode.variables.variables[0].element;
+ expect(element, isNotNull);
+ expect(element.name, 'c');
+ expect(element.nameOffset, newCode.indexOf('c = 3'));
+ }
+ }
+ {
+ TopLevelVariableDeclaration newNode = newNodes[1];
+ expect(newNode, same(oldNodes[0]));
+ expect(getNodeText(newNode), 'bool a =1, b = 2;');
+ {
+ TopLevelVariableElement element =
+ newNode.variables.variables[0].element;
+ expect(element, isNotNull);
+ expect(element.name, 'a');
+ expect(element.nameOffset, newCode.indexOf('a =1'));
+ }
+ {
+ TopLevelVariableElement element =
+ newNode.variables.variables[1].element;
+ expect(element, isNotNull);
+ expect(element.name, 'b');
+ expect(element.nameOffset, newCode.indexOf('b = 2'));
+ }
+ }
+ // verify delta
+ expect(unitDelta.addedDeclarations, unorderedEquals([]));
+ expect(unitDelta.removedDeclarations, unorderedEquals([]));
+ }
+
test_unitMembers_topLevelVariable_add() {
_buildOldUnit(r'''
int a, b;
@@ -585,47 +633,25 @@
]));
}
- test_unitMembers_topLevelVariableDeclaration() {
+ test_unitMembers_topLevelVariable_final() {
_buildOldUnit(r'''
-bool a = 1, b = 2;
-int c = 3;
+final int a = 1;
''');
List<CompilationUnitMember> oldNodes = oldUnit.declarations.toList();
_buildNewUnit(r'''
-int c = 3;
-
-bool a =1, b = 2;
+final int a = 1;
''');
List<CompilationUnitMember> newNodes = newUnit.declarations;
{
TopLevelVariableDeclaration newNode = newNodes[0];
- expect(newNode, same(oldNodes[1]));
- expect(getNodeText(newNode), 'int c = 3;');
- {
- TopLevelVariableElement element =
- newNode.variables.variables[0].element;
- expect(element, isNotNull);
- expect(element.name, 'c');
- expect(element.nameOffset, newCode.indexOf('c = 3'));
- }
- }
- {
- TopLevelVariableDeclaration newNode = newNodes[1];
expect(newNode, same(oldNodes[0]));
- expect(getNodeText(newNode), 'bool a =1, b = 2;');
+ expect(getNodeText(newNode), 'final int a = 1;');
{
TopLevelVariableElement element =
newNode.variables.variables[0].element;
expect(element, isNotNull);
expect(element.name, 'a');
- expect(element.nameOffset, newCode.indexOf('a =1'));
- }
- {
- TopLevelVariableElement element =
- newNode.variables.variables[1].element;
- expect(element, isNotNull);
- expect(element.name, 'b');
- expect(element.nameOffset, newCode.indexOf('b = 2'));
+ expect(element.nameOffset, newCode.indexOf('a = 1'));
}
}
// verify delta
diff --git a/pkg/analyzer/test/task/task_dart_test.dart b/pkg/analyzer/test/task/task_dart_test.dart
deleted file mode 100644
index e7c03be..0000000
--- a/pkg/analyzer/test/task/task_dart_test.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.engine.task.dart;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/task/task_dart.dart';
-import 'package:unittest/unittest.dart';
-
-import '../generated/engine_test.dart';
-import '../generated/resolver_test.dart';
-import '../generated/test_support.dart';
-
-main() {
- groupSep = ' | ';
-// runReflectiveTests(BuildUnitElementTaskTest);
-}
-
-class BuildUnitElementTaskTest extends EngineTestCase {
- CompilationUnit parseUnit(
- InternalAnalysisContext context, Source source, String content) {
- ScanDartTask scanTask = new ScanDartTask(context, source, content);
- scanTask.perform(new ScanDartTaskTestTV_accept());
- ParseDartTask parseTask = new ParseDartTask(
- context, source, scanTask.tokenStream, scanTask.lineInfo);
- parseTask.perform(new ParseDartTaskTestTV_accept());
- return parseTask.compilationUnit;
- }
-
- void test_accept() {
- BuildUnitElementTask task =
- new BuildUnitElementTask(null, null, null, null);
- expect(task.accept(new BuildUnitElementTaskTV_accept()), isTrue);
- }
-
- void test_getException() {
- BuildUnitElementTask task =
- new BuildUnitElementTask(null, null, null, null);
- expect(task.exception, isNull);
- }
-
- void test_getLibrarySource() {
- Source source = new TestSource('/part.dart');
- Source library = new TestSource('/lib.dart');
- BuildUnitElementTask task =
- new BuildUnitElementTask(null, source, library, null);
- expect(task.library, equals(library));
- }
-
- void test_getUnitSource() {
- Source source = new TestSource('/part.dart');
- Source library = new TestSource('/lib.dart');
- BuildUnitElementTask task =
- new BuildUnitElementTask(null, source, library, null);
- expect(task.source, equals(source));
- }
-
- void test_perform_exception() {
- TestSource source = new TestSource();
- source.generateExceptionOnRead = true;
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- CompilationUnit unit = parseUnit(context, source, "");
- BuildUnitElementTask task =
- new BuildUnitElementTask(context, null, source, unit);
- task.perform(new BuildUnitElementTaskTV_perform_exception());
- }
-
- void test_perform_valid() {
- var content = """
-library lib;
-class A {}""";
- Source source = new TestSource('/test.dart', content);
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- CompilationUnit unit = parseUnit(context, source, content);
- BuildUnitElementTask task =
- new BuildUnitElementTask(context, source, source, unit);
- task.perform(new BuildUnitElementTaskTV_perform_valid(source, unit));
- }
-}
-
-class BuildUnitElementTaskTV_accept extends TestTaskVisitor<bool> {
- @override
- bool visitBuildUnitElementTask(BuildUnitElementTask task) => true;
-}
-
-class BuildUnitElementTaskTV_perform_exception extends TestTaskVisitor<bool> {
- @override
- bool visitBuildUnitElementTask(BuildUnitElementTask task) {
- expect(task.exception, isNotNull);
- return true;
- }
-}
-
-class BuildUnitElementTaskTV_perform_valid extends TestTaskVisitor<bool> {
- Source source;
-
- CompilationUnit unit;
-
- BuildUnitElementTaskTV_perform_valid(this.source, this.unit);
-
- @override
- bool visitBuildUnitElementTask(BuildUnitElementTask task) {
- CaughtException exception = task.exception;
- if (exception != null) {
- throw exception;
- }
- expect(task.source, equals(source));
- expect(task.library, equals(source));
- expect(task.unit, equals(unit));
- expect(task.unitElement, isNotNull);
- return true;
- }
-}
diff --git a/pkg/analyzer/test/task/test_all.dart b/pkg/analyzer/test/task/test_all.dart
deleted file mode 100644
index 9ecd162..0000000
--- a/pkg/analyzer/test/task/test_all.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.task;
-
-import 'package:unittest/unittest.dart';
-
-import 'task_dart_test.dart' as task_dart_test;
-
-/// Utility for manually running all tests.
-main() {
- groupSep = ' | ';
- group('generated tests', () {
- task_dart_test.main();
- });
-}
diff --git a/pkg/analyzer/test/test_all.dart b/pkg/analyzer/test/test_all.dart
index 222beb8..cde1f38 100644
--- a/pkg/analyzer/test/test_all.dart
+++ b/pkg/analyzer/test/test_all.dart
@@ -14,7 +14,6 @@
import 'parse_compilation_unit_test.dart' as parse_compilation_unit;
import 'source/test_all.dart' as source;
import 'src/test_all.dart' as src;
-import 'task/test_all.dart' as task;
/// Utility for manually running all tests.
main() {
@@ -28,6 +27,5 @@
parse_compilation_unit.main();
source.main();
src.main();
- task.main();
});
}
diff --git a/pkg/analyzer2dart/lib/src/cps_generator.dart b/pkg/analyzer2dart/lib/src/cps_generator.dart
index 8bd4c0a..1e5bb6d 100644
--- a/pkg/analyzer2dart/lib/src/cps_generator.dart
+++ b/pkg/analyzer2dart/lib/src/cps_generator.dart
@@ -1,589 +1,589 @@
-// 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 analyzer2dart.cps_generator;
-
-import 'package:analyzer/analyzer.dart';
-
-import 'package:compiler/src/dart_types.dart' as dart2js;
-import 'package:compiler/src/elements/elements.dart' as dart2js;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/element.dart' as analyzer;
-
-import 'package:compiler/src/constant_system_dart.dart'
- show DART_CONSTANT_SYSTEM;
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
-import 'package:compiler/src/cps_ir/cps_ir_builder.dart';
-import 'package:compiler/src/universe/universe.dart';
-
-import 'semantic_visitor.dart';
-import 'element_converter.dart';
-import 'util.dart';
-import 'identifier_semantics.dart';
-
-/// Visitor that converts the AST node of an analyzer element into a CPS ir
-/// node.
-class CpsElementVisitor extends analyzer.SimpleElementVisitor<ir.Node> {
- final ElementConverter converter;
- final AstNode node;
-
- CpsElementVisitor(this.converter, this.node);
-
- @override
- ir.FunctionDefinition visitFunctionElement(analyzer.FunctionElement element) {
- CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
- FunctionDeclaration functionDeclaration = node;
- return visitor.handleFunctionDeclaration(
- element, functionDeclaration.functionExpression.body);
- }
-
- @override
- ir.FunctionDefinition visitMethodElement(analyzer.MethodElement element) {
- CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
- MethodDeclaration methodDeclaration = node;
- return visitor.handleFunctionDeclaration(element, methodDeclaration.body);
- }
-
- @override
- ir.FieldDefinition visitTopLevelVariableElement(
- analyzer.TopLevelVariableElement element) {
- CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
- VariableDeclaration variableDeclaration = node;
- return visitor.handleFieldDeclaration(element, variableDeclaration);
- }
-
- @override
- ir.RootNode visitConstructorElement(analyzer.ConstructorElement element) {
- CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
- if (!element.isFactory) {
- ConstructorDeclaration constructorDeclaration = node;
- FunctionBody body;
- if (constructorDeclaration != null) {
- body = constructorDeclaration.body;
- } else {
- assert(element.isSynthetic);
- }
- return visitor.handleConstructorDeclaration(element, body);
- }
- // TODO(johnniwinther): Support factory constructors.
- return null;
- }
-}
-
-/// Visitor that converts analyzer AST nodes into CPS ir nodes.
-class CpsGeneratingVisitor extends SemanticVisitor<ir.Node>
- with IrBuilderMixin<AstNode> {
- /// Promote the type of [irBuilder] to [DartIrBuilder].
- /// The JS backend requires closure conversion which we do not support yet.
- DartIrBuilder get irBuilder => super.irBuilder;
- final analyzer.Element element;
- final ElementConverter converter;
-
- CpsGeneratingVisitor(this.converter, this.element);
-
- Source get currentSource => element.source;
-
- analyzer.LibraryElement get currentLibrary => element.library;
-
- ir.Node visit(AstNode node) => node.accept(this);
-
- ir.ConstructorDefinition handleConstructorDeclaration(
- analyzer.ConstructorElement constructor, FunctionBody body) {
- dart2js.ConstructorElement element = converter.convertElement(constructor);
- return withBuilder(
- new DartIrBuilder(DART_CONSTANT_SYSTEM,
- element,
- // TODO(johnniwinther): Support closure variables.
- new Set<dart2js.Local>()),
- () {
- irBuilder.buildFunctionHeader(
- constructor.parameters.map(converter.convertElement));
- // Visit the body directly to avoid processing the signature as
- // expressions.
- // Call to allow for `body == null` in case of synthesized constructors.
- build(body);
- return irBuilder.makeConstructorDefinition(const [], const []);
- });
- }
-
- ir.FieldDefinition handleFieldDeclaration(
- analyzer.PropertyInducingElement field, VariableDeclaration node) {
- dart2js.FieldElement element = converter.convertElement(field);
- return withBuilder(
- new DartIrBuilder(DART_CONSTANT_SYSTEM,
- element,
- // TODO(johnniwinther): Support closure variables.
- new Set<dart2js.Local>()),
- () {
- irBuilder.buildFieldInitializerHeader();
- ir.Primitive initializer = build(node.initializer);
- return irBuilder.makeFieldDefinition(initializer);
- });
- }
-
- ir.FunctionDefinition handleFunctionDeclaration(
- analyzer.ExecutableElement function, FunctionBody body) {
- dart2js.FunctionElement element = converter.convertElement(function);
- return withBuilder(
- new DartIrBuilder(DART_CONSTANT_SYSTEM,
- element,
- // TODO(johnniwinther): Support closure variables.
- new Set<dart2js.Local>()),
- () {
- irBuilder.buildFunctionHeader(
- function.parameters.map(converter.convertElement));
- // Visit the body directly to avoid processing the signature as
- // expressions.
- visit(body);
- return irBuilder.makeFunctionDefinition(const []);
- });
- }
-
- @override
- ir.Primitive visitFunctionExpression(FunctionExpression node) {
- return irBuilder.buildFunctionExpression(
- handleFunctionDeclaration(node.element, node.body));
- }
-
- @override
- ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) {
- return handleFunctionDeclaration(
- node.element, node.functionExpression.body);
- }
-
- @override
- visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
- FunctionDeclaration functionDeclaration = node.functionDeclaration;
- analyzer.FunctionElement function = functionDeclaration.element;
- dart2js.FunctionElement element = converter.convertElement(function);
- ir.FunctionDefinition definition = handleFunctionDeclaration(
- function, functionDeclaration.functionExpression.body);
- irBuilder.declareLocalFunction(element, definition);
- }
-
- List<ir.Primitive> visitArguments(ArgumentList argumentList) {
- List<ir.Primitive> arguments = <ir.Primitive>[];
- for (Expression argument in argumentList.arguments) {
- ir.Primitive value = build(argument);
- if (value == null) {
- giveUp(argument,
- 'Unsupported argument: $argument (${argument.runtimeType}).');
- }
- arguments.add(value);
- }
- return arguments;
- }
-
- @override
- ir.Node visitMethodInvocation(MethodInvocation node) {
- // Overridden to avoid eager visits of the receiver and arguments.
- return handleMethodInvocation(node);
- }
-
- @override
- ir.Primitive visitDynamicInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- // TODO(johnniwinther): Handle implicit `this`.
- ir.Primitive receiver = build(semantics.target);
- List<ir.Primitive> arguments = visitArguments(node.argumentList);
- return irBuilder.buildDynamicInvocation(
- receiver,
- createSelectorFromMethodInvocation(
- node.argumentList, node.methodName.name),
- arguments);
- }
-
- @override
- ir.Primitive visitStaticMethodInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- analyzer.Element staticElement = semantics.element;
- dart2js.Element element = converter.convertElement(staticElement);
- List<ir.Primitive> arguments = visitArguments(node.argumentList);
- return irBuilder.buildStaticFunctionInvocation(
- element,
- createCallStructureFromMethodInvocation(node.argumentList),
- arguments);
- }
-
- @override
- ir.Node visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
- return handleLocalAccess(node, semantics);
- }
-
- ir.Primitive handleLocalInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- analyzer.Element staticElement = semantics.element;
- dart2js.Element element = converter.convertElement(staticElement);
- List<ir.Definition> arguments = visitArguments(node.argumentList);
- CallStructure callStructure = createCallStructureFromMethodInvocation(
- node.argumentList);
- if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
- return irBuilder.buildLocalFunctionInvocation(
- element, callStructure, arguments);
- } else {
- return irBuilder.buildLocalVariableInvocation(
- element, callStructure, arguments);
- }
- }
-
- @override
- ir.Node visitLocalVariableInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return handleLocalInvocation(node, semantics);
- }
-
- @override
- ir.Primitive visitLocalFunctionInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return handleLocalInvocation(node, semantics);
- }
-
- @override
- ir.Primitive visitFunctionExpressionInvocation(
- FunctionExpressionInvocation node) {
- ir.Primitive target = build(node.function);
- List<ir.Definition> arguments = visitArguments(node.argumentList);
- return irBuilder.buildCallInvocation(
- target,
- createCallStructureFromMethodInvocation(node.argumentList),
- arguments);
- }
-
- @override
- ir.Primitive visitInstanceCreationExpression(
- InstanceCreationExpression node) {
- analyzer.Element staticElement = node.staticElement;
- if (staticElement != null) {
- dart2js.Element element = converter.convertElement(staticElement);
- dart2js.DartType type = converter.convertType(node.staticType);
- List<ir.Primitive> arguments = visitArguments(node.argumentList);
- return irBuilder.buildConstructorInvocation(
- element,
- createCallStructureFromMethodInvocation(node.argumentList),
- type,
- arguments);
- }
- return giveUp(node, "Unresolved constructor invocation.");
- }
-
- @override
- ir.Constant visitNullLiteral(NullLiteral node) {
- return irBuilder.buildNullConstant();
- }
-
- @override
- ir.Constant visitBooleanLiteral(BooleanLiteral node) {
- return irBuilder.buildBooleanConstant(node.value);
- }
-
- @override
- ir.Constant visitDoubleLiteral(DoubleLiteral node) {
- return irBuilder.buildDoubleConstant(node.value);
- }
-
- @override
- ir.Constant visitIntegerLiteral(IntegerLiteral node) {
- return irBuilder.buildIntegerConstant(node.value);
- }
-
- @override
- visitAdjacentStrings(AdjacentStrings node) {
- String value = node.stringValue;
- if (value != null) {
- return irBuilder.buildStringConstant(value);
- }
- giveUp(node, "Non constant adjacent strings.");
- }
-
- @override
- ir.Constant visitSimpleStringLiteral(SimpleStringLiteral node) {
- return irBuilder.buildStringConstant(node.value);
- }
-
- @override
- visitStringInterpolation(StringInterpolation node) {
- giveUp(node, "String interpolation.");
- }
-
- @override
- visitReturnStatement(ReturnStatement node) {
- irBuilder.buildReturn(build(node.expression));
- }
-
- @override
- ir.Node visitPropertyAccess(PropertyAccess node) {
- // Overridden to avoid eager visits of the receiver.
- return handlePropertyAccess(node);
- }
-
- @override
- ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
- return handleLocalAccess(node, semantics);
- }
-
- @override
- ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) {
- return handleLocalAccess(node, semantics);
- }
-
- @override
- visitVariableDeclaration(VariableDeclaration node) {
- // TODO(johnniwinther): Handle constant local variables.
- ir.Node initialValue = build(node.initializer);
- irBuilder.declareLocalVariable(
- converter.convertElement(node.element),
- initialValue: initialValue);
- }
-
- dart2js.Element getLocal(AstNode node, AccessSemantics semantics) {
- analyzer.Element element = semantics.element;
- dart2js.Element target = converter.convertElement(element);
- assert(invariant(node, target.isLocal, '$target expected to be local.'));
- return target;
- }
-
- ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) {
- dart2js.Element local = getLocal(node, semantics);
- if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
- return irBuilder.buildLocalFunctionGet(local);
- } else {
- return irBuilder.buildLocalVariableGet(local);
- }
- }
-
- ir.Primitive handleLocalAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- if (node.operator.lexeme != '=') {
- return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
- }
- return irBuilder.buildLocalVariableSet(
- getLocal(node, semantics),
- build(node.rightHandSide));
- }
-
- @override
- ir.Node visitAssignmentExpression(AssignmentExpression node) {
- // Avoid eager visiting of left and right hand side.
- return handleAssignmentExpression(node);
- }
-
- @override
- ir.Node visitLocalVariableAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return handleLocalAssignment(node, semantics);
- }
-
- @override
- ir.Node visitParameterAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return handleLocalAssignment(node, semantics);
- }
-
- @override
- ir.Node visitStaticFieldAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- if (node.operator.lexeme != '=') {
- return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
- }
- analyzer.Element element = semantics.element;
- dart2js.Element target = converter.convertElement(element);
- // TODO(johnniwinther): Selector information should be computed in the
- // [TreeShaker] and shared with the [CpsGeneratingVisitor].
- assert(invariant(node, target.isTopLevel || target.isStatic,
- '$target expected to be top-level or static.'));
- return irBuilder.buildStaticFieldSet(target, build(node.rightHandSide));
- }
-
- @override
- ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) {
- // TODO(johnniwinther): Handle implicit `this`.
- ir.Primitive receiver = build(semantics.target);
- return irBuilder.buildDynamicGet(receiver,
- new Selector.getter(semantics.identifier.name,
- converter.convertElement(element.library)));
- }
-
- @override
- ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
- analyzer.Element element = semantics.element;
- dart2js.Element target = converter.convertElement(element);
- // TODO(johnniwinther): Selector information should be computed in the
- // [TreeShaker] and shared with the [CpsGeneratingVisitor].
- assert(invariant(node, target.isTopLevel || target.isStatic,
- '$target expected to be top-level or static.'));
- return irBuilder.buildStaticFieldLazyGet(target, null);
- }
-
- ir.Primitive handleBinaryExpression(BinaryExpression node,
- String op) {
- ir.Primitive left = build(node.leftOperand);
- ir.Primitive right = build(node.rightOperand);
- Selector selector = new Selector.binaryOperator(op);
- return irBuilder.buildDynamicInvocation(
- left, selector, <ir.Primitive>[right]);
- }
-
- ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) {
- return irBuilder.buildLogicalOperator(
- build(node.leftOperand),
- subbuild(node.rightOperand),
- isLazyOr: isLazyOr);
- }
-
- @override
- ir.Node visitBinaryExpression(BinaryExpression node) {
- // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be
- // available through an enum.
- String op = node.operator.lexeme;
- switch (op) {
- case '||':
- case '&&':
- return handleLazyOperator(node, isLazyOr: op == '||');
- case '!=':
- return irBuilder.buildNegation(handleBinaryExpression(node, '=='));
- default:
- return handleBinaryExpression(node, op);
- }
- }
-
- @override
- ir.Node visitConditionalExpression(ConditionalExpression node) {
- return irBuilder.buildConditional(
- build(node.condition),
- subbuild(node.thenExpression),
- subbuild(node.elseExpression));
- }
-
- @override
- visitIfStatement(IfStatement node) {
- irBuilder.buildIf(
- build(node.condition),
- subbuild(node.thenStatement),
- subbuild(node.elseStatement));
- }
-
- @override
- visitBlock(Block node) {
- irBuilder.buildBlock(node.statements, build);
- }
-
- @override
- ir.Node visitListLiteral(ListLiteral node) {
- dart2js.InterfaceType type = converter.convertType(node.staticType);
- // TODO(johnniwinther): Use `build` instead of `(e) => build(e)` when issue
- // 18630 has been resolved.
- Iterable<ir.Primitive> values = node.elements.map((e) => build(e));
- return irBuilder.buildListLiteral(type, values);
- }
-
- @override
- ir.Node visitMapLiteral(MapLiteral node) {
- dart2js.InterfaceType type = converter.convertType(node.staticType);
- return irBuilder.buildMapLiteral(
- type,
- node.entries.map((e) => e.key),
- node.entries.map((e) => e.value),
- build);
- }
-
- @override
- visitForStatement(ForStatement node) {
- // TODO(johnniwinther): Support `for` as a jump target.
- List<dart2js.LocalElement> loopVariables = <dart2js.LocalElement>[];
- SubbuildFunction buildInitializer;
- if (node.variables != null) {
- buildInitializer = subbuild(node.variables);
- for (VariableDeclaration variable in node.variables.variables) {
- loopVariables.add(converter.convertElement(variable.element));
- }
- } else {
- buildInitializer = subbuild(node.initialization);
- }
- irBuilder.buildFor(buildInitializer: buildInitializer,
- buildCondition: subbuild(node.condition),
- buildBody: subbuild(node.body),
- buildUpdate: subbuildSequence(node.updaters),
- loopVariables: loopVariables);
- }
-
- @override
- visitWhileStatement(WhileStatement node) {
- // TODO(johnniwinther): Support `while` as a jump target.
- irBuilder.buildWhile(buildCondition: subbuild(node.condition),
- buildBody: subbuild(node.body));
- }
-
- @override
- visitDeclaredIdentifier(DeclaredIdentifier node) {
- giveUp(node, "Unexpected node: DeclaredIdentifier");
- }
-
- @override
- visitForEachStatement(ForEachStatement node) {
- SubbuildFunction buildVariableDeclaration;
- dart2js.Element variableElement;
- Selector variableSelector;
- if (node.identifier != null) {
- AccessSemantics accessSemantics =
- node.identifier.accept(ACCESS_SEMANTICS_VISITOR);
- if (accessSemantics.kind == AccessKind.DYNAMIC) {
- variableSelector = new Selector.setter(
- node.identifier.name, converter.convertElement(currentLibrary));
- } else if (accessSemantics.element != null) {
- variableElement = converter.convertElement(accessSemantics.element);
- variableSelector = new Selector.setter(
- variableElement.name,
- converter.convertElement(accessSemantics.element.library));
- } else {
- giveUp(node, 'For-in of unresolved variable: $accessSemantics');
- }
- } else {
- assert(invariant(
- node, node.loopVariable != null, "Loop variable expected"));
- variableElement = converter.convertElement(node.loopVariable.element);
- buildVariableDeclaration = (IrBuilder builder) {
- builder.declareLocalVariable(variableElement);
- };
- }
- // TODO(johnniwinther): Support `for-in` as a jump target.
- irBuilder.buildForIn(
- buildExpression: subbuild(node.iterable),
- buildVariableDeclaration: buildVariableDeclaration,
- variableElement: variableElement,
- variableSelector: variableSelector,
- buildBody: subbuild(node.body));
- }
- @override
- ir.Primitive visitIsExpression(IsExpression node) {
- return irBuilder.buildTypeOperator(
- visit(node.expression),
- converter.convertType(node.type.type),
- isTypeTest: true,
- isNotCheck: node.notOperator != null);
- }
-
- @override
- ir.Primitive visitAsExpression(AsExpression node) {
- return irBuilder.buildTypeOperator(
- visit(node.expression),
- converter.convertType(node.type.type),
- isTypeTest: false);
- }
-
- @override
- visitTryStatement(TryStatement node) {
- List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
- for (CatchClause catchClause in node.catchClauses) {
- catchClauseInfos.add(new CatchClauseInfo(
- exceptionVariable: converter.convertElement(
- catchClause.exceptionParameter.staticElement),
- buildCatchBlock: subbuild(catchClause.body)));
-
- }
- irBuilder.buildTry(
- tryStatementInfo: new TryStatementInfo(),
- buildTryBlock: subbuild(node.body),
- catchClauseInfos: catchClauseInfos);
- }
-}
+// 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 analyzer2dart.cps_generator;
+
+import 'package:analyzer/analyzer.dart';
+
+import 'package:compiler/src/dart_types.dart' as dart2js;
+import 'package:compiler/src/elements/elements.dart' as dart2js;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/element.dart' as analyzer;
+
+import 'package:compiler/src/constant_system_dart.dart'
+ show DART_CONSTANT_SYSTEM;
+import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
+import 'package:compiler/src/cps_ir/cps_ir_builder.dart';
+import 'package:compiler/src/universe/universe.dart';
+
+import 'semantic_visitor.dart';
+import 'element_converter.dart';
+import 'util.dart';
+import 'identifier_semantics.dart';
+
+/// Visitor that converts the AST node of an analyzer element into a CPS ir
+/// node.
+class CpsElementVisitor extends analyzer.SimpleElementVisitor<ir.Node> {
+ final ElementConverter converter;
+ final AstNode node;
+
+ CpsElementVisitor(this.converter, this.node);
+
+ @override
+ ir.FunctionDefinition visitFunctionElement(analyzer.FunctionElement element) {
+ CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
+ FunctionDeclaration functionDeclaration = node;
+ return visitor.handleFunctionDeclaration(
+ element, functionDeclaration.functionExpression.body);
+ }
+
+ @override
+ ir.FunctionDefinition visitMethodElement(analyzer.MethodElement element) {
+ CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
+ MethodDeclaration methodDeclaration = node;
+ return visitor.handleFunctionDeclaration(element, methodDeclaration.body);
+ }
+
+ @override
+ ir.FieldDefinition visitTopLevelVariableElement(
+ analyzer.TopLevelVariableElement element) {
+ CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
+ VariableDeclaration variableDeclaration = node;
+ return visitor.handleFieldDeclaration(element, variableDeclaration);
+ }
+
+ @override
+ ir.RootNode visitConstructorElement(analyzer.ConstructorElement element) {
+ CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
+ if (!element.isFactory) {
+ ConstructorDeclaration constructorDeclaration = node;
+ FunctionBody body;
+ if (constructorDeclaration != null) {
+ body = constructorDeclaration.body;
+ } else {
+ assert(element.isSynthetic);
+ }
+ return visitor.handleConstructorDeclaration(element, body);
+ }
+ // TODO(johnniwinther): Support factory constructors.
+ return null;
+ }
+}
+
+/// Visitor that converts analyzer AST nodes into CPS ir nodes.
+class CpsGeneratingVisitor extends SemanticVisitor<ir.Node>
+ with IrBuilderMixin<AstNode> {
+ /// Promote the type of [irBuilder] to [DartIrBuilder].
+ /// The JS backend requires closure conversion which we do not support yet.
+ DartIrBuilder get irBuilder => super.irBuilder;
+ final analyzer.Element element;
+ final ElementConverter converter;
+
+ CpsGeneratingVisitor(this.converter, this.element);
+
+ Source get currentSource => element.source;
+
+ analyzer.LibraryElement get currentLibrary => element.library;
+
+ ir.Node visit(AstNode node) => node.accept(this);
+
+ ir.ConstructorDefinition handleConstructorDeclaration(
+ analyzer.ConstructorElement constructor, FunctionBody body) {
+ dart2js.ConstructorElement element = converter.convertElement(constructor);
+ return withBuilder(
+ new DartIrBuilder(DART_CONSTANT_SYSTEM,
+ element,
+ // TODO(johnniwinther): Support closure variables.
+ new Set<dart2js.Local>()),
+ () {
+ irBuilder.buildFunctionHeader(
+ constructor.parameters.map(converter.convertElement));
+ // Visit the body directly to avoid processing the signature as
+ // expressions.
+ // Call to allow for `body == null` in case of synthesized constructors.
+ build(body);
+ return irBuilder.makeConstructorDefinition(const [], const []);
+ });
+ }
+
+ ir.FieldDefinition handleFieldDeclaration(
+ analyzer.PropertyInducingElement field, VariableDeclaration node) {
+ dart2js.FieldElement element = converter.convertElement(field);
+ return withBuilder(
+ new DartIrBuilder(DART_CONSTANT_SYSTEM,
+ element,
+ // TODO(johnniwinther): Support closure variables.
+ new Set<dart2js.Local>()),
+ () {
+ irBuilder.buildFieldInitializerHeader();
+ ir.Primitive initializer = build(node.initializer);
+ return irBuilder.makeFieldDefinition(initializer);
+ });
+ }
+
+ ir.FunctionDefinition handleFunctionDeclaration(
+ analyzer.ExecutableElement function, FunctionBody body) {
+ dart2js.FunctionElement element = converter.convertElement(function);
+ return withBuilder(
+ new DartIrBuilder(DART_CONSTANT_SYSTEM,
+ element,
+ // TODO(johnniwinther): Support closure variables.
+ new Set<dart2js.Local>()),
+ () {
+ irBuilder.buildFunctionHeader(
+ function.parameters.map(converter.convertElement));
+ // Visit the body directly to avoid processing the signature as
+ // expressions.
+ visit(body);
+ return irBuilder.makeFunctionDefinition(const []);
+ });
+ }
+
+ @override
+ ir.Primitive visitFunctionExpression(FunctionExpression node) {
+ return irBuilder.buildFunctionExpression(
+ handleFunctionDeclaration(node.element, node.body));
+ }
+
+ @override
+ ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) {
+ return handleFunctionDeclaration(
+ node.element, node.functionExpression.body);
+ }
+
+ @override
+ visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+ FunctionDeclaration functionDeclaration = node.functionDeclaration;
+ analyzer.FunctionElement function = functionDeclaration.element;
+ dart2js.FunctionElement element = converter.convertElement(function);
+ ir.FunctionDefinition definition = handleFunctionDeclaration(
+ function, functionDeclaration.functionExpression.body);
+ irBuilder.declareLocalFunction(element, definition);
+ }
+
+ List<ir.Primitive> visitArguments(ArgumentList argumentList) {
+ List<ir.Primitive> arguments = <ir.Primitive>[];
+ for (Expression argument in argumentList.arguments) {
+ ir.Primitive value = build(argument);
+ if (value == null) {
+ giveUp(argument,
+ 'Unsupported argument: $argument (${argument.runtimeType}).');
+ }
+ arguments.add(value);
+ }
+ return arguments;
+ }
+
+ @override
+ ir.Node visitMethodInvocation(MethodInvocation node) {
+ // Overridden to avoid eager visits of the receiver and arguments.
+ return handleMethodInvocation(node);
+ }
+
+ @override
+ ir.Primitive visitDynamicInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ // TODO(johnniwinther): Handle implicit `this`.
+ ir.Primitive receiver = build(semantics.target);
+ List<ir.Primitive> arguments = visitArguments(node.argumentList);
+ return irBuilder.buildDynamicInvocation(
+ receiver,
+ createSelectorFromMethodInvocation(
+ node.argumentList, node.methodName.name),
+ arguments);
+ }
+
+ @override
+ ir.Primitive visitStaticMethodInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ analyzer.Element staticElement = semantics.element;
+ dart2js.Element element = converter.convertElement(staticElement);
+ List<ir.Primitive> arguments = visitArguments(node.argumentList);
+ return irBuilder.buildStaticFunctionInvocation(
+ element,
+ createCallStructureFromMethodInvocation(node.argumentList),
+ arguments);
+ }
+
+ @override
+ ir.Node visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
+ return handleLocalAccess(node, semantics);
+ }
+
+ ir.Primitive handleLocalInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ analyzer.Element staticElement = semantics.element;
+ dart2js.Element element = converter.convertElement(staticElement);
+ List<ir.Definition> arguments = visitArguments(node.argumentList);
+ CallStructure callStructure = createCallStructureFromMethodInvocation(
+ node.argumentList);
+ if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
+ return irBuilder.buildLocalFunctionInvocation(
+ element, callStructure, arguments);
+ } else {
+ return irBuilder.buildLocalVariableInvocation(
+ element, callStructure, arguments);
+ }
+ }
+
+ @override
+ ir.Node visitLocalVariableInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ return handleLocalInvocation(node, semantics);
+ }
+
+ @override
+ ir.Primitive visitLocalFunctionInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ return handleLocalInvocation(node, semantics);
+ }
+
+ @override
+ ir.Primitive visitFunctionExpressionInvocation(
+ FunctionExpressionInvocation node) {
+ ir.Primitive target = build(node.function);
+ List<ir.Definition> arguments = visitArguments(node.argumentList);
+ return irBuilder.buildCallInvocation(
+ target,
+ createCallStructureFromMethodInvocation(node.argumentList),
+ arguments);
+ }
+
+ @override
+ ir.Primitive visitInstanceCreationExpression(
+ InstanceCreationExpression node) {
+ analyzer.Element staticElement = node.staticElement;
+ if (staticElement != null) {
+ dart2js.Element element = converter.convertElement(staticElement);
+ dart2js.DartType type = converter.convertType(node.staticType);
+ List<ir.Primitive> arguments = visitArguments(node.argumentList);
+ return irBuilder.buildConstructorInvocation(
+ element,
+ createCallStructureFromMethodInvocation(node.argumentList),
+ type,
+ arguments);
+ }
+ return giveUp(node, "Unresolved constructor invocation.");
+ }
+
+ @override
+ ir.Constant visitNullLiteral(NullLiteral node) {
+ return irBuilder.buildNullConstant();
+ }
+
+ @override
+ ir.Constant visitBooleanLiteral(BooleanLiteral node) {
+ return irBuilder.buildBooleanConstant(node.value);
+ }
+
+ @override
+ ir.Constant visitDoubleLiteral(DoubleLiteral node) {
+ return irBuilder.buildDoubleConstant(node.value);
+ }
+
+ @override
+ ir.Constant visitIntegerLiteral(IntegerLiteral node) {
+ return irBuilder.buildIntegerConstant(node.value);
+ }
+
+ @override
+ visitAdjacentStrings(AdjacentStrings node) {
+ String value = node.stringValue;
+ if (value != null) {
+ return irBuilder.buildStringConstant(value);
+ }
+ giveUp(node, "Non constant adjacent strings.");
+ }
+
+ @override
+ ir.Constant visitSimpleStringLiteral(SimpleStringLiteral node) {
+ return irBuilder.buildStringConstant(node.value);
+ }
+
+ @override
+ visitStringInterpolation(StringInterpolation node) {
+ giveUp(node, "String interpolation.");
+ }
+
+ @override
+ visitReturnStatement(ReturnStatement node) {
+ irBuilder.buildReturn(build(node.expression));
+ }
+
+ @override
+ ir.Node visitPropertyAccess(PropertyAccess node) {
+ // Overridden to avoid eager visits of the receiver.
+ return handlePropertyAccess(node);
+ }
+
+ @override
+ ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
+ return handleLocalAccess(node, semantics);
+ }
+
+ @override
+ ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) {
+ return handleLocalAccess(node, semantics);
+ }
+
+ @override
+ visitVariableDeclaration(VariableDeclaration node) {
+ // TODO(johnniwinther): Handle constant local variables.
+ ir.Node initialValue = build(node.initializer);
+ irBuilder.declareLocalVariable(
+ converter.convertElement(node.element),
+ initialValue: initialValue);
+ }
+
+ dart2js.Element getLocal(AstNode node, AccessSemantics semantics) {
+ analyzer.Element element = semantics.element;
+ dart2js.Element target = converter.convertElement(element);
+ assert(invariant(node, target.isLocal, '$target expected to be local.'));
+ return target;
+ }
+
+ ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) {
+ dart2js.Element local = getLocal(node, semantics);
+ if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
+ return irBuilder.buildLocalFunctionGet(local);
+ } else {
+ return irBuilder.buildLocalVariableGet(local);
+ }
+ }
+
+ ir.Primitive handleLocalAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ if (node.operator.lexeme != '=') {
+ return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
+ }
+ return irBuilder.buildLocalVariableSet(
+ getLocal(node, semantics),
+ build(node.rightHandSide));
+ }
+
+ @override
+ ir.Node visitAssignmentExpression(AssignmentExpression node) {
+ // Avoid eager visiting of left and right hand side.
+ return handleAssignmentExpression(node);
+ }
+
+ @override
+ ir.Node visitLocalVariableAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ return handleLocalAssignment(node, semantics);
+ }
+
+ @override
+ ir.Node visitParameterAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ return handleLocalAssignment(node, semantics);
+ }
+
+ @override
+ ir.Node visitStaticFieldAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ if (node.operator.lexeme != '=') {
+ return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
+ }
+ analyzer.Element element = semantics.element;
+ dart2js.Element target = converter.convertElement(element);
+ // TODO(johnniwinther): Selector information should be computed in the
+ // [TreeShaker] and shared with the [CpsGeneratingVisitor].
+ assert(invariant(node, target.isTopLevel || target.isStatic,
+ '$target expected to be top-level or static.'));
+ return irBuilder.buildStaticFieldSet(target, build(node.rightHandSide));
+ }
+
+ @override
+ ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) {
+ // TODO(johnniwinther): Handle implicit `this`.
+ ir.Primitive receiver = build(semantics.target);
+ return irBuilder.buildDynamicGet(receiver,
+ new Selector.getter(semantics.identifier.name,
+ converter.convertElement(element.library)));
+ }
+
+ @override
+ ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
+ analyzer.Element element = semantics.element;
+ dart2js.Element target = converter.convertElement(element);
+ // TODO(johnniwinther): Selector information should be computed in the
+ // [TreeShaker] and shared with the [CpsGeneratingVisitor].
+ assert(invariant(node, target.isTopLevel || target.isStatic,
+ '$target expected to be top-level or static.'));
+ return irBuilder.buildStaticFieldLazyGet(target, null);
+ }
+
+ ir.Primitive handleBinaryExpression(BinaryExpression node,
+ String op) {
+ ir.Primitive left = build(node.leftOperand);
+ ir.Primitive right = build(node.rightOperand);
+ Selector selector = new Selector.binaryOperator(op);
+ return irBuilder.buildDynamicInvocation(
+ left, selector, <ir.Primitive>[right]);
+ }
+
+ ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) {
+ return irBuilder.buildLogicalOperator(
+ build(node.leftOperand),
+ subbuild(node.rightOperand),
+ isLazyOr: isLazyOr);
+ }
+
+ @override
+ ir.Node visitBinaryExpression(BinaryExpression node) {
+ // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be
+ // available through an enum.
+ String op = node.operator.lexeme;
+ switch (op) {
+ case '||':
+ case '&&':
+ return handleLazyOperator(node, isLazyOr: op == '||');
+ case '!=':
+ return irBuilder.buildNegation(handleBinaryExpression(node, '=='));
+ default:
+ return handleBinaryExpression(node, op);
+ }
+ }
+
+ @override
+ ir.Node visitConditionalExpression(ConditionalExpression node) {
+ return irBuilder.buildConditional(
+ build(node.condition),
+ subbuild(node.thenExpression),
+ subbuild(node.elseExpression));
+ }
+
+ @override
+ visitIfStatement(IfStatement node) {
+ irBuilder.buildIf(
+ build(node.condition),
+ subbuild(node.thenStatement),
+ subbuild(node.elseStatement));
+ }
+
+ @override
+ visitBlock(Block node) {
+ irBuilder.buildBlock(node.statements, build);
+ }
+
+ @override
+ ir.Node visitListLiteral(ListLiteral node) {
+ dart2js.InterfaceType type = converter.convertType(node.staticType);
+ // TODO(johnniwinther): Use `build` instead of `(e) => build(e)` when issue
+ // 18630 has been resolved.
+ Iterable<ir.Primitive> values = node.elements.map((e) => build(e));
+ return irBuilder.buildListLiteral(type, values);
+ }
+
+ @override
+ ir.Node visitMapLiteral(MapLiteral node) {
+ dart2js.InterfaceType type = converter.convertType(node.staticType);
+ return irBuilder.buildMapLiteral(
+ type,
+ node.entries.map((e) => e.key),
+ node.entries.map((e) => e.value),
+ build);
+ }
+
+ @override
+ visitForStatement(ForStatement node) {
+ // TODO(johnniwinther): Support `for` as a jump target.
+ List<dart2js.LocalElement> loopVariables = <dart2js.LocalElement>[];
+ SubbuildFunction buildInitializer;
+ if (node.variables != null) {
+ buildInitializer = subbuild(node.variables);
+ for (VariableDeclaration variable in node.variables.variables) {
+ loopVariables.add(converter.convertElement(variable.element));
+ }
+ } else {
+ buildInitializer = subbuild(node.initialization);
+ }
+ irBuilder.buildFor(buildInitializer: buildInitializer,
+ buildCondition: subbuild(node.condition),
+ buildBody: subbuild(node.body),
+ buildUpdate: subbuildSequence(node.updaters),
+ loopVariables: loopVariables);
+ }
+
+ @override
+ visitWhileStatement(WhileStatement node) {
+ // TODO(johnniwinther): Support `while` as a jump target.
+ irBuilder.buildWhile(buildCondition: subbuild(node.condition),
+ buildBody: subbuild(node.body));
+ }
+
+ @override
+ visitDeclaredIdentifier(DeclaredIdentifier node) {
+ giveUp(node, "Unexpected node: DeclaredIdentifier");
+ }
+
+ @override
+ visitForEachStatement(ForEachStatement node) {
+ SubbuildFunction buildVariableDeclaration;
+ dart2js.Element variableElement;
+ Selector variableSelector;
+ if (node.identifier != null) {
+ AccessSemantics accessSemantics =
+ node.identifier.accept(ACCESS_SEMANTICS_VISITOR);
+ if (accessSemantics.kind == AccessKind.DYNAMIC) {
+ variableSelector = new Selector.setter(
+ node.identifier.name, converter.convertElement(currentLibrary));
+ } else if (accessSemantics.element != null) {
+ variableElement = converter.convertElement(accessSemantics.element);
+ variableSelector = new Selector.setter(
+ variableElement.name,
+ converter.convertElement(accessSemantics.element.library));
+ } else {
+ giveUp(node, 'For-in of unresolved variable: $accessSemantics');
+ }
+ } else {
+ assert(invariant(
+ node, node.loopVariable != null, "Loop variable expected"));
+ variableElement = converter.convertElement(node.loopVariable.element);
+ buildVariableDeclaration = (IrBuilder builder) {
+ builder.declareLocalVariable(variableElement);
+ };
+ }
+ // TODO(johnniwinther): Support `for-in` as a jump target.
+ irBuilder.buildForIn(
+ buildExpression: subbuild(node.iterable),
+ buildVariableDeclaration: buildVariableDeclaration,
+ variableElement: variableElement,
+ variableSelector: variableSelector,
+ buildBody: subbuild(node.body));
+ }
+ @override
+ ir.Primitive visitIsExpression(IsExpression node) {
+ return irBuilder.buildTypeOperator(
+ visit(node.expression),
+ converter.convertType(node.type.type),
+ isTypeTest: true,
+ isNotCheck: node.notOperator != null);
+ }
+
+ @override
+ ir.Primitive visitAsExpression(AsExpression node) {
+ return irBuilder.buildTypeOperator(
+ visit(node.expression),
+ converter.convertType(node.type.type),
+ isTypeTest: false);
+ }
+
+ @override
+ visitTryStatement(TryStatement node) {
+ List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
+ for (CatchClause catchClause in node.catchClauses) {
+ catchClauseInfos.add(new CatchClauseInfo(
+ exceptionVariable: converter.convertElement(
+ catchClause.exceptionParameter.staticElement),
+ buildCatchBlock: subbuild(catchClause.body)));
+
+ }
+ irBuilder.buildTry(
+ tryStatementInfo: new TryStatementInfo(),
+ buildTryBlock: subbuild(node.body),
+ catchClauseInfos: catchClauseInfos);
+ }
+}
diff --git a/pkg/analyzer2dart/lib/src/semantic_visitor.dart b/pkg/analyzer2dart/lib/src/semantic_visitor.dart
index 2e1c170..b5edd6a 100644
--- a/pkg/analyzer2dart/lib/src/semantic_visitor.dart
+++ b/pkg/analyzer2dart/lib/src/semantic_visitor.dart
@@ -1,271 +1,271 @@
-// 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 analyzer2dart.semantic_visitor;
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-import 'util.dart';
-import 'identifier_semantics.dart';
-
-/// An AST visitor which uses the [AccessSemantics] of invocations and accesses
-/// to fine-grain visitor methods.
-abstract class SemanticVisitor<R> extends RecursiveAstVisitor<R> {
-
- Source get currentSource;
-
- void reportMessage(AstNode node, String message) {
- reportSourceMessage(currentSource, node, message);
- }
-
- giveUp(AstNode node, String message) {
- reportMessage(node, message);
- throw new UnimplementedError(message);
- }
-
- bool invariant(AstNode node, condition, String message) {
- if (condition is Function) {
- condition = condition();
- }
- if (!condition) {
- reportMessage(node, message);
- return false;
- }
- return true;
- }
-
- R visitDynamicInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitDynamicInvocation of $semantics');
- }
-
- R visitLocalFunctionInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitLocalFunctionInvocation of $semantics');
- }
-
- R visitLocalVariableInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitLocalVariableInvocation of $semantics');
- }
-
- R visitParameterInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitParameterInvocation of $semantics');
- }
-
- R visitStaticFieldInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticFieldInvocation of $semantics');
- }
-
- R visitStaticMethodInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticMethodInvocation of $semantics');
- }
-
- R visitStaticPropertyInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticPropertyInvocation of $semantics');
- }
-
- @override
- R visitMethodInvocation(MethodInvocation node) {
- if (node.target != null) {
- node.target.accept(this);
- }
- node.argumentList.accept(this);
- return handleMethodInvocation(node);
- }
-
- R handleMethodInvocation(MethodInvocation node) {
- AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
- switch (semantics.kind) {
- case AccessKind.DYNAMIC:
- return visitDynamicInvocation(node, semantics);
- case AccessKind.LOCAL_FUNCTION:
- return visitLocalFunctionInvocation(node, semantics);
- case AccessKind.LOCAL_VARIABLE:
- return visitLocalVariableInvocation(node, semantics);
- case AccessKind.PARAMETER:
- return visitParameterInvocation(node, semantics);
- case AccessKind.STATIC_FIELD:
- return visitStaticFieldInvocation(node, semantics);
- case AccessKind.STATIC_METHOD:
- return visitStaticMethodInvocation(node, semantics);
- case AccessKind.STATIC_PROPERTY:
- return visitStaticPropertyInvocation(node, semantics);
- default:
- // Unexpected access kind.
- return giveUp(node,
- 'Unexpected ${semantics} in visitMethodInvocation.');
- }
- }
-
- @override
- R visitPropertyAccess(PropertyAccess node) {
- if (node.target != null) {
- node.target.accept(this);
- }
- return handlePropertyAccess(node);
- }
-
- R handlePropertyAccess(PropertyAccess node) {
- return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
- }
-
- @override
- R visitPrefixedIdentifier(PrefixedIdentifier node) {
- node.prefix.accept(this);
- return handlePrefixedIdentifier(node);
- }
-
- R handlePrefixedIdentifier(PrefixedIdentifier node) {
- return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
- }
-
- @override
- R visitSimpleIdentifier(SimpleIdentifier node) {
- AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
- if (semantics != null) {
- return _handlePropertyAccess(node, semantics);
- } else {
- return null;
- }
- }
-
- R visitDynamicAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitDynamicAccess of $semantics');
- }
-
- R visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitLocalFunctionAccess of $semantics');
- }
-
- R visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitLocalVariableAccess of $semantics');
- }
-
- R visitParameterAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitParameterAccess of $semantics');
- }
-
- R visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitStaticFieldAccess of $semantics');
- }
-
- R visitStaticMethodAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitStaticMethodAccess of $semantics');
- }
-
- R visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitStaticPropertyAccess of $semantics');
- }
-
- R visitToplevelClassAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitToplevelClassAccess of $semantics');
- }
-
- R visitTypeParameterAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitTypeParameterAccess of $semantics');
- }
-
- R _handlePropertyAccess(AstNode node, AccessSemantics semantics) {
- switch (semantics.kind) {
- case AccessKind.DYNAMIC:
- return visitDynamicAccess(node, semantics);
- case AccessKind.LOCAL_FUNCTION:
- return visitLocalFunctionAccess(node, semantics);
- case AccessKind.LOCAL_VARIABLE:
- return visitLocalVariableAccess(node, semantics);
- case AccessKind.PARAMETER:
- return visitParameterAccess(node, semantics);
- case AccessKind.STATIC_FIELD:
- return visitStaticFieldAccess(node, semantics);
- case AccessKind.STATIC_METHOD:
- return visitStaticMethodAccess(node, semantics);
- case AccessKind.STATIC_PROPERTY:
- return visitStaticPropertyAccess(node, semantics);
- case AccessKind.TOPLEVEL_TYPE:
- return visitToplevelClassAccess(node, semantics);
- case AccessKind.TYPE_PARAMETER:
- return visitTypeParameterAccess(node, semantics);
- default:
- // Unexpected access kind.
- return giveUp(node,
- 'Unexpected ${semantics} in _handlePropertyAccess.');
- }
- }
-
- R visitDynamicPropertyAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitDynamicPropertyAssignment of $semantics');
- }
-
- R visitLocalFunctionAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitLocalFunctionAssignment of $semantics');
- }
-
- R visitLocalVariableAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitLocalVariableAssignment of $semantics');
- }
-
- R visitParameterAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitParameterAssignment of $semantics');
- }
-
- R visitStaticFieldAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticFieldAssignment of $semantics');
- }
-
- R visitStaticMethodAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticMethodAssignment of $semantics');
- }
-
- R visitStaticPropertyAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticPropertyAssignment of $semantics');
- }
-
- @override
- R visitAssignmentExpression(AssignmentExpression node) {
- super.visitAssignmentExpression(node);
- return handleAssignmentExpression(node);
- }
-
- R handleAssignmentExpression(AssignmentExpression node) {
- AccessSemantics semantics =
- node.leftHandSide.accept(ACCESS_SEMANTICS_VISITOR);
- if (semantics == null) {
- return giveUp(node, 'handleAssignmentExpression with no AccessSemantics');
- } else {
- switch (semantics.kind) {
- case AccessKind.DYNAMIC:
- return visitDynamicPropertyAssignment(node, semantics);
- case AccessKind.LOCAL_FUNCTION:
- return visitLocalFunctionAssignment(node, semantics);
- case AccessKind.LOCAL_VARIABLE:
- return visitLocalVariableAssignment(node, semantics);
- case AccessKind.PARAMETER:
- return visitParameterAssignment(node, semantics);
- case AccessKind.STATIC_FIELD:
- return visitStaticFieldAssignment(node, semantics);
- case AccessKind.STATIC_METHOD:
- return visitStaticMethodAssignment(node, semantics);
- case AccessKind.STATIC_PROPERTY:
- return visitStaticPropertyAssignment(node, semantics);
- default:
- // Unexpected access kind.
- return giveUp(node,
- 'Unexpected ${semantics} in _handlePropertyAccess.');
- }
- }
- }
-}
+// 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 analyzer2dart.semantic_visitor;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+import 'util.dart';
+import 'identifier_semantics.dart';
+
+/// An AST visitor which uses the [AccessSemantics] of invocations and accesses
+/// to fine-grain visitor methods.
+abstract class SemanticVisitor<R> extends RecursiveAstVisitor<R> {
+
+ Source get currentSource;
+
+ void reportMessage(AstNode node, String message) {
+ reportSourceMessage(currentSource, node, message);
+ }
+
+ giveUp(AstNode node, String message) {
+ reportMessage(node, message);
+ throw new UnimplementedError(message);
+ }
+
+ bool invariant(AstNode node, condition, String message) {
+ if (condition is Function) {
+ condition = condition();
+ }
+ if (!condition) {
+ reportMessage(node, message);
+ return false;
+ }
+ return true;
+ }
+
+ R visitDynamicInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitDynamicInvocation of $semantics');
+ }
+
+ R visitLocalFunctionInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitLocalFunctionInvocation of $semantics');
+ }
+
+ R visitLocalVariableInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitLocalVariableInvocation of $semantics');
+ }
+
+ R visitParameterInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitParameterInvocation of $semantics');
+ }
+
+ R visitStaticFieldInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitStaticFieldInvocation of $semantics');
+ }
+
+ R visitStaticMethodInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitStaticMethodInvocation of $semantics');
+ }
+
+ R visitStaticPropertyInvocation(MethodInvocation node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitStaticPropertyInvocation of $semantics');
+ }
+
+ @override
+ R visitMethodInvocation(MethodInvocation node) {
+ if (node.target != null) {
+ node.target.accept(this);
+ }
+ node.argumentList.accept(this);
+ return handleMethodInvocation(node);
+ }
+
+ R handleMethodInvocation(MethodInvocation node) {
+ AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC:
+ return visitDynamicInvocation(node, semantics);
+ case AccessKind.LOCAL_FUNCTION:
+ return visitLocalFunctionInvocation(node, semantics);
+ case AccessKind.LOCAL_VARIABLE:
+ return visitLocalVariableInvocation(node, semantics);
+ case AccessKind.PARAMETER:
+ return visitParameterInvocation(node, semantics);
+ case AccessKind.STATIC_FIELD:
+ return visitStaticFieldInvocation(node, semantics);
+ case AccessKind.STATIC_METHOD:
+ return visitStaticMethodInvocation(node, semantics);
+ case AccessKind.STATIC_PROPERTY:
+ return visitStaticPropertyInvocation(node, semantics);
+ default:
+ // Unexpected access kind.
+ return giveUp(node,
+ 'Unexpected ${semantics} in visitMethodInvocation.');
+ }
+ }
+
+ @override
+ R visitPropertyAccess(PropertyAccess node) {
+ if (node.target != null) {
+ node.target.accept(this);
+ }
+ return handlePropertyAccess(node);
+ }
+
+ R handlePropertyAccess(PropertyAccess node) {
+ return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
+ }
+
+ @override
+ R visitPrefixedIdentifier(PrefixedIdentifier node) {
+ node.prefix.accept(this);
+ return handlePrefixedIdentifier(node);
+ }
+
+ R handlePrefixedIdentifier(PrefixedIdentifier node) {
+ return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
+ }
+
+ @override
+ R visitSimpleIdentifier(SimpleIdentifier node) {
+ AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
+ if (semantics != null) {
+ return _handlePropertyAccess(node, semantics);
+ } else {
+ return null;
+ }
+ }
+
+ R visitDynamicAccess(AstNode node, AccessSemantics semantics) {
+ return giveUp(node, 'visitDynamicAccess of $semantics');
+ }
+
+ R visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
+ return giveUp(node, 'visitLocalFunctionAccess of $semantics');
+ }
+
+ R visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
+ return giveUp(node, 'visitLocalVariableAccess of $semantics');
+ }
+
+ R visitParameterAccess(AstNode node, AccessSemantics semantics) {
+ return giveUp(node, 'visitParameterAccess of $semantics');
+ }
+
+ R visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
+ return giveUp(node, 'visitStaticFieldAccess of $semantics');
+ }
+
+ R visitStaticMethodAccess(AstNode node, AccessSemantics semantics) {
+ return giveUp(node, 'visitStaticMethodAccess of $semantics');
+ }
+
+ R visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) {
+ return giveUp(node, 'visitStaticPropertyAccess of $semantics');
+ }
+
+ R visitToplevelClassAccess(AstNode node, AccessSemantics semantics) {
+ return giveUp(node, 'visitToplevelClassAccess of $semantics');
+ }
+
+ R visitTypeParameterAccess(AstNode node, AccessSemantics semantics) {
+ return giveUp(node, 'visitTypeParameterAccess of $semantics');
+ }
+
+ R _handlePropertyAccess(AstNode node, AccessSemantics semantics) {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC:
+ return visitDynamicAccess(node, semantics);
+ case AccessKind.LOCAL_FUNCTION:
+ return visitLocalFunctionAccess(node, semantics);
+ case AccessKind.LOCAL_VARIABLE:
+ return visitLocalVariableAccess(node, semantics);
+ case AccessKind.PARAMETER:
+ return visitParameterAccess(node, semantics);
+ case AccessKind.STATIC_FIELD:
+ return visitStaticFieldAccess(node, semantics);
+ case AccessKind.STATIC_METHOD:
+ return visitStaticMethodAccess(node, semantics);
+ case AccessKind.STATIC_PROPERTY:
+ return visitStaticPropertyAccess(node, semantics);
+ case AccessKind.TOPLEVEL_TYPE:
+ return visitToplevelClassAccess(node, semantics);
+ case AccessKind.TYPE_PARAMETER:
+ return visitTypeParameterAccess(node, semantics);
+ default:
+ // Unexpected access kind.
+ return giveUp(node,
+ 'Unexpected ${semantics} in _handlePropertyAccess.');
+ }
+ }
+
+ R visitDynamicPropertyAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitDynamicPropertyAssignment of $semantics');
+ }
+
+ R visitLocalFunctionAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitLocalFunctionAssignment of $semantics');
+ }
+
+ R visitLocalVariableAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitLocalVariableAssignment of $semantics');
+ }
+
+ R visitParameterAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitParameterAssignment of $semantics');
+ }
+
+ R visitStaticFieldAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitStaticFieldAssignment of $semantics');
+ }
+
+ R visitStaticMethodAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitStaticMethodAssignment of $semantics');
+ }
+
+ R visitStaticPropertyAssignment(AssignmentExpression node,
+ AccessSemantics semantics) {
+ return giveUp(node, 'visitStaticPropertyAssignment of $semantics');
+ }
+
+ @override
+ R visitAssignmentExpression(AssignmentExpression node) {
+ super.visitAssignmentExpression(node);
+ return handleAssignmentExpression(node);
+ }
+
+ R handleAssignmentExpression(AssignmentExpression node) {
+ AccessSemantics semantics =
+ node.leftHandSide.accept(ACCESS_SEMANTICS_VISITOR);
+ if (semantics == null) {
+ return giveUp(node, 'handleAssignmentExpression with no AccessSemantics');
+ } else {
+ switch (semantics.kind) {
+ case AccessKind.DYNAMIC:
+ return visitDynamicPropertyAssignment(node, semantics);
+ case AccessKind.LOCAL_FUNCTION:
+ return visitLocalFunctionAssignment(node, semantics);
+ case AccessKind.LOCAL_VARIABLE:
+ return visitLocalVariableAssignment(node, semantics);
+ case AccessKind.PARAMETER:
+ return visitParameterAssignment(node, semantics);
+ case AccessKind.STATIC_FIELD:
+ return visitStaticFieldAssignment(node, semantics);
+ case AccessKind.STATIC_METHOD:
+ return visitStaticMethodAssignment(node, semantics);
+ case AccessKind.STATIC_PROPERTY:
+ return visitStaticPropertyAssignment(node, semantics);
+ default:
+ // Unexpected access kind.
+ return giveUp(node,
+ 'Unexpected ${semantics} in _handlePropertyAccess.');
+ }
+ }
+ }
+}
diff --git a/pkg/analyzer2dart/lib/src/util.dart b/pkg/analyzer2dart/lib/src/util.dart
index 67ee97e..fd1c20b 100644
--- a/pkg/analyzer2dart/lib/src/util.dart
+++ b/pkg/analyzer2dart/lib/src/util.dart
@@ -1,42 +1,42 @@
-// 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.
-
-// Utility function shared between different parts of analyzer2dart.
-
-library analyzer2dart.util;
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:compiler/src/elements/elements.dart' show PublicName;
-import 'package:compiler/src/universe/universe.dart';
-import 'package:compiler/src/io/source_file.dart';
-
-CallStructure createCallStructureFromMethodInvocation(ArgumentList node) {
- int arity = 0;
- List<String> namedArguments = <String>[];
- for (Expression argument in node.arguments) {
- if (argument is NamedExpression) {
- namedArguments.add(argument.name.label.name);
- } else {
- arity++;
- }
- }
- return new CallStructure(arity, namedArguments);
-}
-
-Selector createSelectorFromMethodInvocation(ArgumentList node,
- String name) {
- CallStructure callStructure = createCallStructureFromMethodInvocation(node);
- // TODO(johnniwinther): Support private names.
- return new Selector(SelectorKind.CALL, new PublicName(name), callStructure);
-}
-
-/// Prints [message] together with source code pointed to by [node] from
-/// [source].
-void reportSourceMessage(Source source, AstNode node, String message) {
- SourceFile sourceFile =
- new StringSourceFile.fromName(source.fullName, source.contents.data);
-
- print(sourceFile.getLocationMessage(message, node.offset, node.end));
-}
+// 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.
+
+// Utility function shared between different parts of analyzer2dart.
+
+library analyzer2dart.util;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:compiler/src/elements/elements.dart' show PublicName;
+import 'package:compiler/src/universe/universe.dart';
+import 'package:compiler/src/io/source_file.dart';
+
+CallStructure createCallStructureFromMethodInvocation(ArgumentList node) {
+ int arity = 0;
+ List<String> namedArguments = <String>[];
+ for (Expression argument in node.arguments) {
+ if (argument is NamedExpression) {
+ namedArguments.add(argument.name.label.name);
+ } else {
+ arity++;
+ }
+ }
+ return new CallStructure(arity, namedArguments);
+}
+
+Selector createSelectorFromMethodInvocation(ArgumentList node,
+ String name) {
+ CallStructure callStructure = createCallStructureFromMethodInvocation(node);
+ // TODO(johnniwinther): Support private names.
+ return new Selector(SelectorKind.CALL, new PublicName(name), callStructure);
+}
+
+/// Prints [message] together with source code pointed to by [node] from
+/// [source].
+void reportSourceMessage(Source source, AstNode node, String message) {
+ SourceFile sourceFile =
+ new StringSourceFile.fromName(source.fullName, source.contents.data);
+
+ print(sourceFile.getLocationMessage(message, node.offset, node.end));
+}
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index a36ee9a..a940dbf 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -11,8 +11,8 @@
import 'dart2jslib.dart' as leg;
import 'tree/tree.dart' as tree;
import 'elements/elements.dart' as elements;
-import 'package:_internal/libraries.dart' hide LIBRARIES;
-import 'package:_internal/libraries.dart' as library_info show LIBRARIES;
+import 'package:sdk_library_metadata/libraries.dart' hide LIBRARIES;
+import 'package:sdk_library_metadata/libraries.dart' as library_info show LIBRARIES;
import 'io/source_file.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart' as pkgs;
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index b0c7502..4b0be2d 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -779,7 +779,7 @@
Node node,
CallStructure callStructure,
Link<Node> arguments,
- FunctionElement target,
+ ConstructorElement target,
{AstConstant compileArgument(Node node)}) {
assert(invariant(node, target.isImplementation));
@@ -790,7 +790,8 @@
}
target.computeType(compiler);
- if (!callStructure.signatureApplies(target)) {
+ FunctionSignature signature = target.functionSignature;
+ if (!callStructure.signatureApplies(signature)) {
String name = Elements.constructorNameForDiagnostics(
target.enclosingClass.name, target.name);
compiler.reportError(
@@ -1028,8 +1029,10 @@
"effective target: $constructor"));
return new ErroneousAstConstant(context, node);
}
- assert(invariant(node, callStructure.signatureApplies(constructor) ||
- compiler.compilationFailed,
+ assert(invariant(
+ node,
+ callStructure.signatureApplies(constructor.functionSignature) ||
+ compiler.compilationFailed,
message: "Call structure $callStructure does not apply to constructor "
"$constructor."));
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 7e42649..88368dd 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -1196,7 +1196,7 @@
} else if (node is Element) {
return spanFromElement(node);
} else if (node is MetadataAnnotation) {
- Uri uri = node.annotatedElement.compilationUnit.script.readableUri;
+ Uri uri = node.annotatedElement.compilationUnit.script.resourceUri;
return spanFromTokens(node.beginToken, node.endToken, uri);
} else if (node is Local) {
Local local = node;
@@ -1922,7 +1922,7 @@
throw 'Cannot find tokens to produce error message.';
}
if (uri == null && currentElement != null) {
- uri = currentElement.compilationUnit.script.readableUri;
+ uri = currentElement.compilationUnit.script.resourceUri;
}
return SourceSpan.withCharacterOffsets(begin, end,
(beginOffset, endOffset) => new SourceSpan(uri, beginOffset, endOffset));
@@ -1962,7 +1962,7 @@
return element.sourcePosition;
}
Token position = element.position;
- Uri uri = element.compilationUnit.script.readableUri;
+ Uri uri = element.compilationUnit.script.resourceUri;
return (position == null)
? new SourceSpan(uri, 0, 0)
: spanFromTokens(position, position, uri);
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 5644b0f..dc0a3d9 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -18,6 +18,7 @@
import '../resolution/operators.dart';
import '../tree/tree.dart' show DartString;
import '../universe/universe.dart' show CallStructure;
+import '../util/util.dart';
import 'values.dart';
enum ConstantExpressionKind {
@@ -141,6 +142,23 @@
return appliedFieldMap;
}
+ int get hashCode {
+ int hash = Hashing.objectHash(type);
+ hash = Hashing.mapHash(defaultValues, hash);
+ hash = Hashing.mapHash(fieldMap, hash);
+ return Hashing.objectHash(superConstructorInvocation, hash);
+ }
+
+ bool operator ==(other) {
+ if (identical(this, other)) return true;
+ if (other is! GenerativeConstantConstructor) return false;
+ return
+ type == other.type &&
+ superConstructorInvocation == other.superConstructorInvocation &&
+ mapEquals(defaultValues, other.defaultValues) &&
+ mapEquals(fieldMap, other.fieldMap);
+ }
+
String toString() {
StringBuffer sb = new StringBuffer();
sb.write("{'type': $type");
@@ -157,6 +175,16 @@
return sb.toString();
}
+ static bool mapEquals(Map map1, Map map2) {
+ if (map1.length != map1.length) return false;
+ for (var key in map1.keys) {
+ if (map1[key] != map2[key]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
/// Creates the field-to-constant map from applying [args] to
/// [constructorInvocation]. If [constructorInvocation] is `null`, an empty
/// map is created.
@@ -205,6 +233,20 @@
return appliedFieldMap;
}
+ int get hashCode {
+ int hash = Hashing.objectHash(thisConstructorInvocation);
+ return Hashing.mapHash(defaultValues, hash);
+ }
+
+ bool operator ==(other) {
+ if (identical(this, other)) return true;
+ if (other is! RedirectingGenerativeConstantConstructor) return false;
+ return
+ thisConstructorInvocation == other.thisConstructorInvocation &&
+ GenerativeConstantConstructor.mapEquals(
+ defaultValues, other.defaultValues);
+ }
+
String toString() {
StringBuffer sb = new StringBuffer();
sb.write("{'type': ${thisConstructorInvocation.type}");
@@ -240,6 +282,16 @@
return constantConstructor.computeInstanceFields(arguments, callStructure);
}
+ int get hashCode {
+ return Hashing.objectHash(targetConstructorInvocation);
+ }
+
+ bool operator ==(other) {
+ if (identical(this, other)) return true;
+ if (other is! RedirectingFactoryConstantConstructor) return false;
+ return targetConstructorInvocation == other.targetConstructorInvocation;
+ }
+
String toString() {
StringBuffer sb = new StringBuffer();
sb.write("{");
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index f5e5cc9..dd10751 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -31,7 +31,7 @@
import '../types/types.dart' show TypeMask;
import '../util/util.dart';
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
+import 'package:js_runtime/shared/embedded_names.dart'
show JsBuiltin, JsGetName;
import '../constants/values.dart';
@@ -339,24 +339,19 @@
ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) {
assert(irBuilder.isOpen);
- if (node.modifiers.isConst) {
- // Do nothing.
- // handleLocalConstantGet inlines the constant at use-site.
- } else {
- for (ast.Node definition in node.definitions.nodes) {
- Element element = elements[definition];
- ir.Primitive initialValue;
- // Definitions are either SendSets if there is an initializer, or
- // Identifiers if there is no initializer.
- if (definition is ast.SendSet) {
- assert(!definition.arguments.isEmpty);
- assert(definition.arguments.tail.isEmpty);
- initialValue = visit(definition.arguments.head);
- } else {
- assert(definition is ast.Identifier);
- }
- irBuilder.declareLocalVariable(element, initialValue: initialValue);
+ for (ast.Node definition in node.definitions.nodes) {
+ Element element = elements[definition];
+ ir.Primitive initialValue;
+ // Definitions are either SendSets if there is an initializer, or
+ // Identifiers if there is no initializer.
+ if (definition is ast.SendSet) {
+ assert(!definition.arguments.isEmpty);
+ assert(definition.arguments.tail.isEmpty);
+ initialValue = visit(definition.arguments.head);
+ } else {
+ assert(definition is ast.Identifier);
}
+ irBuilder.declareLocalVariable(element, initialValue: initialValue);
}
return null;
}
@@ -2528,6 +2523,14 @@
}
});
}
+ // If this is a mixin constructor, it does not have its own parameter list
+ // or initializer list. Directly forward to the super constructor.
+ // Note that the declaration-site initializers originating from the
+ // mixed-in class were handled above.
+ if (enclosingClass.isMixinApplication) {
+ forwardSynthesizedMixinConstructor(constructor, supers, fieldValues);
+ return;
+ }
// Evaluate initializing parameters, e.g. `Foo(this.x)`.
constructor.functionSignature.orderedForEachParameter(
(ParameterElement parameter) {
@@ -2594,12 +2597,32 @@
List<ConstructorElement> supers,
Map<FieldElement, ir.Primitive> fieldValues) {
JsIrBuilderVisitor visitor = makeVisitorForContext(target);
- return visitor.withBuilder(irBuilder, () {
+ visitor.withBuilder(irBuilder, () {
visitor.loadArguments(target, call, arguments);
visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
});
}
+ /// Evaluate the implicit super call in the given mixin constructor.
+ void forwardSynthesizedMixinConstructor(
+ ConstructorElement constructor,
+ List<ConstructorElement> supers,
+ Map<FieldElement, ir.Primitive> fieldValues) {
+ assert(constructor.enclosingClass.implementation.isMixinApplication);
+ assert(constructor.isSynthesized);
+ ConstructorElement target =
+ constructor.definingConstructor.implementation;
+ // The resolver gives us the exact same FunctionSignature for the two
+ // constructors. The parameters for the synthesized constructor
+ // are already in the environment, so the target constructor's parameters
+ // are also in the environment since their elements are the same.
+ assert(constructor.functionSignature == target.functionSignature);
+ JsIrBuilderVisitor visitor = makeVisitorForContext(target);
+ visitor.withBuilder(irBuilder, () {
+ visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
+ });
+ }
+
/// Loads the type variables for all super classes of [superClass] into the
/// IR builder's environment with their corresponding values.
///
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index fa33169..fec259b 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -289,9 +289,7 @@
final SourceInformation sourceInformation;
/// If true, it is known that the receiver cannot be `null`.
- ///
- /// This field is `null` until initialized by optimization phases.
- bool receiverIsNotNull;
+ bool receiverIsNotNull = false;
InvokeMethod(Primitive receiver,
this.selector,
@@ -616,7 +614,7 @@
final Reference<Primitive> object;
FieldElement field;
- /// True if the receiver is known not to be null.
+ /// True if the object is known not to be null.
// TODO(asgerf): This is a placeholder until we agree on how to track
// side effects.
bool objectIsNotNull = false;
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
index 56d5896..1c5adcf 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
@@ -371,8 +371,8 @@
String arguments = node.arguments.map(formatReference).join(', ');
String continuation = node.continuation == null ? ''
: ' ${formatReference(node.continuation)}';
- printStmt(id, "ForeignCode ${node.type} ${node.codeTemplate} $arguments"
- "$continuation");
+ printStmt(id, "ForeignCode ${node.type} ${node.codeTemplate.source} "
+ "$arguments $continuation");
}
}
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index a8a7ee2..f93f493 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -53,6 +53,11 @@
return mask.locateSingleElement(selector, mask, classWorld.compiler);
}
+ TypeMask getReceiverType(MethodElement method) {
+ assert(method.isInstanceMember);
+ return nonNullSubclass(method.enclosingClass);
+ }
+
TypeMask getParameterType(ParameterElement parameter) {
return inferrer.getGuaranteedTypeOfElement(parameter);
}
@@ -82,7 +87,12 @@
// closure conversion, so just treat those as a subtypes of Function.
// TODO(asgerf): Maybe closure conversion should create a new ClassWorld?
if (element.isClosure) return functionType;
- return new TypeMask.nonNullExact(element, classWorld);
+ return new TypeMask.nonNullExact(element.declaration, classWorld);
+ }
+
+ TypeMask nonNullSubclass(ClassElement element) {
+ if (element.isClosure) return functionType;
+ return new TypeMask.nonNullSubclass(element.declaration, classWorld);
}
bool isDefinitelyBool(TypeMask t, {bool allowNull: false}) {
@@ -502,6 +512,7 @@
InvokeContinuation invoke =
new InvokeContinuation(continuation, <Primitive>[primitive]);
letPrim.body = invoke;
+ values[primitive] = values[continuation.parameters.single];
primitive.hint = continuation.parameters.single.hint;
return letPrim;
@@ -566,7 +577,6 @@
/// True if all uses of [prim] only use its value after boolean conversion.
bool isAlwaysBoolified(Primitive prim) {
for (Reference ref = prim.firstRef; ref != null; ref = ref.next) {
- Node use = ref.parent;
if (!isBoolifyingUse(ref)) return false;
}
return true;
@@ -1045,8 +1055,8 @@
void visitFunctionDefinition(FunctionDefinition node) {
if (node.thisParameter != null) {
- // TODO(asgerf): Use a more precise type for 'this'.
- setValue(node.thisParameter, nonConstant(typeSystem.nonNullType));
+ setValue(node.thisParameter,
+ nonConstant(typeSystem.getReceiverType(node.element)));
}
node.parameters.forEach(visit);
setReachable(node.body);
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 9db2af5..3b351af 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -18,7 +18,7 @@
import 'util/uri_extras.dart';
import 'util/util.dart' show stackTraceFilePrefix;
import 'util/command_line.dart';
-import 'package:_internal/libraries.dart';
+import 'package:sdk_library_metadata/libraries.dart';
import 'package:package_config/discovery.dart' show findPackages;
const String LIBRARY_ROOT = '../../../../../sdk';
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
index 13ea3b6..8c8c4ff 100644
--- a/pkg/compiler/lib/src/elements/common.dart
+++ b/pkg/compiler/lib/src/elements/common.dart
@@ -1,472 +1,472 @@
-// 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 '../dart2jslib.dart' show Compiler, isPrivateName;
-import '../dart_types.dart' show DartType, InterfaceType, FunctionType;
-import '../util/util.dart' show Link;
-
-import 'elements.dart';
-
-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;
-
- @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 isParameter => kind == ElementKind.PARAMETER;
-
- @override
- bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;
-
- @override
- bool get isErroneous => kind == ElementKind.ERROR;
-
- @override
- bool get isAmbiguous => kind == ElementKind.AMBIGUOUS;
-
- @override
- bool get isWarnOnUse => kind == ElementKind.WARN_ON_USE;
-
- @override
- bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
-
- @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');
- }
-}
-
-abstract class LibraryElementCommon implements LibraryElement {
- @override
- bool get isDartCore => canonicalUri == Compiler.DART_CORE;
-
- @override
- bool get isPlatformLibrary => canonicalUri.scheme == 'dart';
-
- @override
- bool get isPackageLibrary => canonicalUri.scheme == 'package';
-
- @override
- bool get isInternalLibrary =>
- isPlatformLibrary && canonicalUri.path.startsWith('_');
-}
-
-abstract class ClassElementCommon implements ClassElement {
-
- @override
- Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes;
-
- @override
- int get hierarchyDepth => allSupertypesAndSelf.maxDepth;
-
- @override
- InterfaceType asInstanceOf(ClassElement cls) {
- if (cls == this) return thisType;
- return allSupertypesAndSelf.asInstanceOf(cls);
- }
-
- @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.
- */
- Element lookupByName(Name memberName) {
- return internalLookupByName(memberName, isSuperLookup: false);
- }
-
- Element lookupSuperByName(Name memberName) {
- return internalLookupByName(memberName, isSuperLookup: true);
- }
-
- Element internalLookupByName(Name memberName, {bool isSuperLookup}) {
- String name = memberName.text;
- bool isPrivate = memberName.isPrivate;
- LibraryElement library = memberName.library;
- for (ClassElement current = isSuperLookup ? superclass : this;
- current != null;
- 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;
- FunctionElement getter = field.getter;
- FunctionElement 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) {
- 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 = 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.forEachBackendMember((e) => f(classElement, e));
- }
- if (includeInjectedMembers) {
- if (classElement.patch != null) {
- 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(Element fieldMember) {
- assert(fieldMember.isField);
- String fieldName = fieldMember.name;
- bool isPrivate = 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 intrface) {
- for (DartType implementedInterfaceType in allSupertypes) {
- ClassElement implementedInterface = implementedInterfaceType.element;
- if (identical(implementedInterface, intrface)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if [this] is a subclass of [cls].
- *
- * 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) {
- // 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;
- }
-
- FunctionType get callType {
- MemberSignature member =
- lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
- return member != null && member.isMethod ? member.type : null;
- }
-}
-
-abstract class FunctionSignatureCommon implements FunctionSignature {
- void forEachRequiredParameter(void function(Element parameter)) {
- requiredParameters.forEach(function);
- }
-
- void forEachOptionalParameter(void function(Element parameter)) {
- optionalParameters.forEach(function);
- }
-
- Element get firstOptionalParameter => optionalParameters.first;
-
- void forEachParameter(void function(Element parameter)) {
- forEachRequiredParameter(function);
- forEachOptionalParameter(function);
- }
-
- void orderedForEachParameter(void function(Element 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;
- }
-}
+// 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 '../dart2jslib.dart' show Compiler, isPrivateName;
+import '../dart_types.dart' show DartType, InterfaceType, FunctionType;
+import '../util/util.dart' show Link;
+
+import 'elements.dart';
+
+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;
+
+ @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 isParameter => kind == ElementKind.PARAMETER;
+
+ @override
+ bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;
+
+ @override
+ bool get isErroneous => kind == ElementKind.ERROR;
+
+ @override
+ bool get isAmbiguous => kind == ElementKind.AMBIGUOUS;
+
+ @override
+ bool get isWarnOnUse => kind == ElementKind.WARN_ON_USE;
+
+ @override
+ bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
+
+ @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');
+ }
+}
+
+abstract class LibraryElementCommon implements LibraryElement {
+ @override
+ bool get isDartCore => canonicalUri == Compiler.DART_CORE;
+
+ @override
+ bool get isPlatformLibrary => canonicalUri.scheme == 'dart';
+
+ @override
+ bool get isPackageLibrary => canonicalUri.scheme == 'package';
+
+ @override
+ bool get isInternalLibrary =>
+ isPlatformLibrary && canonicalUri.path.startsWith('_');
+}
+
+abstract class ClassElementCommon implements ClassElement {
+
+ @override
+ Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes;
+
+ @override
+ int get hierarchyDepth => allSupertypesAndSelf.maxDepth;
+
+ @override
+ InterfaceType asInstanceOf(ClassElement cls) {
+ if (cls == this) return thisType;
+ return allSupertypesAndSelf.asInstanceOf(cls);
+ }
+
+ @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.
+ */
+ Element lookupByName(Name memberName) {
+ return internalLookupByName(memberName, isSuperLookup: false);
+ }
+
+ Element lookupSuperByName(Name memberName) {
+ return internalLookupByName(memberName, isSuperLookup: true);
+ }
+
+ Element internalLookupByName(Name memberName, {bool isSuperLookup}) {
+ String name = memberName.text;
+ bool isPrivate = memberName.isPrivate;
+ LibraryElement library = memberName.library;
+ for (ClassElement current = isSuperLookup ? superclass : this;
+ current != null;
+ 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;
+ FunctionElement getter = field.getter;
+ FunctionElement 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) {
+ 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 = 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.forEachBackendMember((e) => f(classElement, e));
+ }
+ if (includeInjectedMembers) {
+ if (classElement.patch != null) {
+ 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(Element fieldMember) {
+ assert(fieldMember.isField);
+ String fieldName = fieldMember.name;
+ bool isPrivate = 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 intrface) {
+ for (DartType implementedInterfaceType in allSupertypes) {
+ ClassElement implementedInterface = implementedInterfaceType.element;
+ if (identical(implementedInterface, intrface)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if [this] is a subclass of [cls].
+ *
+ * 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) {
+ // 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;
+ }
+
+ FunctionType get callType {
+ MemberSignature member =
+ lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
+ return member != null && member.isMethod ? member.type : null;
+ }
+}
+
+abstract class FunctionSignatureCommon implements FunctionSignature {
+ void forEachRequiredParameter(void function(Element parameter)) {
+ requiredParameters.forEach(function);
+ }
+
+ void forEachOptionalParameter(void function(Element parameter)) {
+ optionalParameters.forEach(function);
+ }
+
+ Element get firstOptionalParameter => optionalParameters.first;
+
+ void forEachParameter(void function(Element parameter)) {
+ forEachRequiredParameter(function);
+ forEachOptionalParameter(function);
+ }
+
+ void orderedForEachParameter(void function(Element 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;
+ }
+}
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index cf96f4e..fc1f93b 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -8,6 +8,7 @@
import 'elements.dart';
import '../constants/expressions.dart';
import '../constants/constructors.dart';
+import '../helpers/helpers.dart';
import '../tree/tree.dart';
import '../util/util.dart';
import '../resolution/resolution.dart';
@@ -114,7 +115,7 @@
SourceSpan get sourcePosition {
if (position == null) return null;
- Uri uri = compilationUnit.script.readableUri;
+ Uri uri = compilationUnit.script.resourceUri;
return new SourceSpan(
uri, position.charOffset, position.charOffset + position.charCount);
}
@@ -1248,16 +1249,16 @@
}
abstract class ConstantVariableMixin implements VariableElement {
- ConstantExpression _constant;
+ ConstantExpression constantCache;
ConstantExpression get constant {
if (isPatch) {
ConstantVariableMixin originVariable = origin;
return originVariable.constant;
}
- assert(invariant(this, _constant != null,
+ assert(invariant(this, constantCache != null,
message: "Constant has not been computed for $this."));
- return _constant;
+ return constantCache;
}
void set constant(ConstantExpression value) {
@@ -1266,9 +1267,9 @@
originVariable.constant = value;
return null;
}
- assert(invariant(this, _constant == null || _constant == value,
+ assert(invariant(this, constantCache == null || constantCache == value,
message: "Constant has already been computed for $this."));
- _constant = value;
+ constantCache = value;
}
}
@@ -1966,6 +1967,25 @@
return _constantConstructor;
}
+ void set constantConstructor(ConstantConstructor value) {
+ if (isPatch) {
+ ConstantConstructorMixin originConstructor = origin;
+ originConstructor.constantConstructor = value;
+ } else {
+ assert(invariant(this, isConst,
+ message: "Constant constructor set on non-constant "
+ "constructor $this."));
+ assert(invariant(this, !isFromEnvironmentConstructor,
+ message: "Constant constructor set on fromEnvironment "
+ "constructor: $this."));
+ assert(invariant(this,
+ _constantConstructor == null || _constantConstructor == value,
+ message: "Constant constructor already computed for $this:"
+ "Existing: $_constantConstructor, new: $value"));
+ _constantConstructor = value;
+ }
+ }
+
bool get isFromEnvironmentConstructor {
return name == 'fromEnvironment' &&
library.isDartCore &&
diff --git a/pkg/compiler/lib/src/io/line_column_provider.dart b/pkg/compiler/lib/src/io/line_column_provider.dart
index 4d17583..fb3d5db 100644
--- a/pkg/compiler/lib/src/io/line_column_provider.dart
+++ b/pkg/compiler/lib/src/io/line_column_provider.dart
@@ -1,77 +1,77 @@
-// 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.io.line_column;
-
-import 'code_output.dart';
-
-/// Interface for providing line/column information.
-abstract class LineColumnProvider {
- /// Returns the line number (0-based) for [offset].
- int getLine(int offset);
-
- /// Returns the column number (0-based) for [offset] at the given [line].
- int getColumn(int line, int offset);
-}
-
-/// [CodeOutputListener] that collects line information.
-class LineColumnCollector extends CodeOutputListener
- implements LineColumnProvider {
- int length = 0;
- List<int> lineStarts = <int>[0];
-
- void _collect(String text) {
- int index = 0;
- while (index < text.length) {
- // Unix uses '\n' and Windows uses '\r\n', so this algorithm works for
- // both platforms.
- index = text.indexOf('\n', index) + 1;
- if (index <= 0) break;
- lineStarts.add(length + index);
- }
- length += text.length;
- }
-
- @override
- void onText(String text) {
- _collect(text);
- }
-
- @override
- int getLine(int offset) {
- List<int> starts = lineStarts;
- if (offset < 0 || starts.last <= offset) {
- throw 'bad position #$offset in buffer with length ${length}.';
- }
- int first = 0;
- int count = starts.length;
- while (count > 1) {
- int step = count ~/ 2;
- int middle = first + step;
- int lineStart = starts[middle];
- if (offset < lineStart) {
- count = step;
- } else {
- first = middle;
- count -= step;
- }
- }
- return first;
- }
-
- @override
- int getColumn(int line, int offset) {
- return offset - lineStarts[line];
- }
-
- @override
- void onDone(int length) {
- lineStarts.add(length + 1);
- this.length = length;
- }
-
- String toString() {
- return 'lineStarts=$lineStarts,length=$length';
- }
-}
+// 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.io.line_column;
+
+import 'code_output.dart';
+
+/// Interface for providing line/column information.
+abstract class LineColumnProvider {
+ /// Returns the line number (0-based) for [offset].
+ int getLine(int offset);
+
+ /// Returns the column number (0-based) for [offset] at the given [line].
+ int getColumn(int line, int offset);
+}
+
+/// [CodeOutputListener] that collects line information.
+class LineColumnCollector extends CodeOutputListener
+ implements LineColumnProvider {
+ int length = 0;
+ List<int> lineStarts = <int>[0];
+
+ void _collect(String text) {
+ int index = 0;
+ while (index < text.length) {
+ // Unix uses '\n' and Windows uses '\r\n', so this algorithm works for
+ // both platforms.
+ index = text.indexOf('\n', index) + 1;
+ if (index <= 0) break;
+ lineStarts.add(length + index);
+ }
+ length += text.length;
+ }
+
+ @override
+ void onText(String text) {
+ _collect(text);
+ }
+
+ @override
+ int getLine(int offset) {
+ List<int> starts = lineStarts;
+ if (offset < 0 || starts.last <= offset) {
+ throw 'bad position #$offset in buffer with length ${length}.';
+ }
+ int first = 0;
+ int count = starts.length;
+ while (count > 1) {
+ int step = count ~/ 2;
+ int middle = first + step;
+ int lineStart = starts[middle];
+ if (offset < lineStart) {
+ count = step;
+ } else {
+ first = middle;
+ count -= step;
+ }
+ }
+ return first;
+ }
+
+ @override
+ int getColumn(int line, int offset) {
+ return offset - lineStarts[line];
+ }
+
+ @override
+ void onDone(int length) {
+ lineStarts.add(length + 1);
+ this.length = length;
+ }
+
+ String toString() {
+ return 'lineStarts=$lineStarts,length=$length';
+ }
+}
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index e29c104..41a8466 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -7,7 +7,7 @@
import "dart:math" show max;
import 'dart:collection';
-import 'package:_internal/compiler/js_lib/shared/async_await_error_codes.dart'
+import 'package:js_runtime/shared/async_await_error_codes.dart'
as error_codes;
import "js.dart" as js;
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index bd40919..cbead55 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -46,10 +46,7 @@
/// Variable names that have already been used. Used to avoid name clashes.
Set<String> usedVariableNames = new Set<String>();
- /// Input to [visitStatement]. Denotes the statement that will execute next
- /// if the statements produced by [visitStatement] complete normally.
- /// Set to null if control will fall over the end of the method.
- tree_ir.Statement fallthrough = null;
+ final tree_ir.FallthroughStack fallthrough = new tree_ir.FallthroughStack();
Set<tree_ir.Label> usedLabels = new Set<tree_ir.Label>();
@@ -341,6 +338,14 @@
glue.registerIsCheck(type, registry);
ClassElement clazz = type.element;
+ // Handle some special checks against classes that exist only in
+ // the compile-time class hierarchy, not at runtime.
+ if (clazz == glue.jsExtendableArrayClass) {
+ return js.js(r'!#.fixed$length', <js.Expression>[value]);
+ } else if (clazz == glue.jsMutableArrayClass) {
+ return js.js(r'!#.immutable$list', <js.Expression>[value]);
+ }
+
// We use one of the two helpers:
//
// checkSubtype(value, $isT, typeArgs, $asT)
@@ -400,12 +405,13 @@
@override
void visitContinue(tree_ir.Continue node) {
- tree_ir.Statement fallthrough = this.fallthrough;
- if (node.target.binding == fallthrough) {
+ tree_ir.Statement next = fallthrough.target;
+ if (node.target.binding == next) {
// Fall through to continue target
- } else if (fallthrough is tree_ir.Continue &&
- fallthrough.target == node.target) {
+ fallthrough.use();
+ } else if (next is tree_ir.Continue && next.target == node.target) {
// Fall through to equivalent continue
+ fallthrough.use();
} else {
usedLabels.add(node.target);
accumulator.add(new js.Continue(node.target.name));
@@ -413,6 +419,21 @@
}
@override
+ void visitBreak(tree_ir.Break node) {
+ tree_ir.Statement next = fallthrough.target;
+ if (node.target.binding.next == next) {
+ // Fall through to break target
+ fallthrough.use();
+ } else if (next is tree_ir.Break && next.target == node.target) {
+ // Fall through to equivalent break
+ fallthrough.use();
+ } else {
+ usedLabels.add(node.target);
+ accumulator.add(new js.Break(node.target.name));
+ }
+ }
+
+ @override
void visitExpressionStatement(tree_ir.ExpressionStatement node) {
accumulator.add(new js.ExpressionStatement(
visitExpression(node.expression)));
@@ -421,9 +442,19 @@
@override
void visitIf(tree_ir.If node) {
- accumulator.add(new js.If(visitExpression(node.condition),
- buildBodyStatement(node.thenStatement),
- buildBodyStatement(node.elseStatement)));
+ js.Expression condition = visitExpression(node.condition);
+ int usesBefore = fallthrough.useCount;
+ js.Statement thenBody = buildBodyStatement(node.thenStatement);
+ bool thenHasFallthrough = (fallthrough.useCount > usesBefore);
+ if (thenHasFallthrough) {
+ js.Statement elseBody = buildBodyStatement(node.elseStatement);
+ accumulator.add(new js.If(condition, thenBody, elseBody));
+ } else {
+ // The 'then' body cannot complete normally, so emit a short 'if'
+ // and put the 'else' body after it.
+ accumulator.add(new js.If.noElse(condition, thenBody));
+ visitStatement(node.elseStatement);
+ }
}
@override
@@ -435,32 +466,17 @@
}
js.Statement buildLabeled(js.Statement buildBody(),
- tree_ir.Label label,
- tree_ir.Statement fallthroughStatement) {
- tree_ir.Statement savedFallthrough = fallthrough;
- fallthrough = fallthroughStatement;
+ tree_ir.Label label,
+ tree_ir.Statement fallthroughStatement) {
+ fallthrough.push(fallthroughStatement);
js.Statement result = buildBody();
if (usedLabels.remove(label)) {
result = new js.LabeledStatement(label.name, result);
}
- fallthrough = savedFallthrough;
+ fallthrough.pop();
return result;
}
- @override
- void visitBreak(tree_ir.Break node) {
- tree_ir.Statement fallthrough = this.fallthrough;
- if (node.target.binding.next == fallthrough) {
- // Fall through to break target
- } else if (fallthrough is tree_ir.Break &&
- fallthrough.target == node.target) {
- // Fall through to equivalent break
- } else {
- usedLabels.add(node.target);
- accumulator.add(new js.Break(node.target.name));
- }
- }
-
/// Returns the current [accumulator] wrapped in a block if neccessary.
js.Statement _bodyAsStatement() {
if (accumulator.length == 0) {
@@ -516,9 +532,19 @@
buildWhile(new js.LiteralBool(true), node.body, node.label, node));
}
+ bool isNull(tree_ir.Expression node) {
+ return node is tree_ir.Constant && node.value.isNull;
+ }
+
@override
void visitReturn(tree_ir.Return node) {
- accumulator.add(new js.Return(visitExpression(node.value)));
+ if (isNull(node.value) && fallthrough.target == null) {
+ // Do nothing. Implicitly return JS undefined by falling over the end.
+ registry.registerCompileTimeConstant(new NullConstantValue());
+ fallthrough.use();
+ } else {
+ accumulator.add(new js.Return(visitExpression(node.value)));
+ }
}
@override
@@ -609,6 +635,7 @@
@override
js.Expression visitGetField(tree_ir.GetField node) {
+ registry.registerFieldGetter(node.field);
return new js.PropertyAccess(
visitExpression(node.object),
glue.instanceFieldPropertyName(node.field));
@@ -616,6 +643,7 @@
@override
js.Assignment visitSetField(tree_ir.SetField node) {
+ registry.registerFieldSetter(node.field);
js.PropertyAccess field =
new js.PropertyAccess(
visitExpression(node.object),
@@ -701,8 +729,8 @@
}
@override
- visitForeignStatement(tree_ir.ForeignStatement node) {
- return handleForeignCode(node);
+ void visitForeignStatement(tree_ir.ForeignStatement node) {
+ accumulator.add(handleForeignCode(node));
}
@override
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index bb7ce13..641660b 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -234,4 +234,7 @@
bool hasStrictSubtype(ClassElement element) {
return _compiler.world.hasAnyStrictSubtype(element);
}
+
+ ClassElement get jsExtendableArrayClass => _backend.jsExtendableArrayClass;
+ ClassElement get jsMutableArrayClass => _backend.jsMutableArrayClass;
}
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
new file mode 100644
index 0000000..1666ca5
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -0,0 +1,238 @@
+// 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 js_backend;
+
+abstract class _MinifiedFieldNamer implements Namer {
+ _FieldNamingRegistry get fieldRegistry;
+
+ // Returns a minimal name for the field that is globally unique along
+ // the given element's class inheritance chain.
+ //
+ // The inheritance scope based naming might not yield a name. For instance,
+ // this could be because the field belongs to a mixin. In such a case this
+ // will return `null` and a normal field name has to be used.
+ jsAst.Name _minifiedInstanceFieldPropertyName(Element element) {
+ if (element.hasFixedBackendName) {
+ return new StringBackedName(element.fixedBackendName);
+ }
+
+ _FieldNamingScope names;
+ if (element is BoxFieldElement) {
+ names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
+ } else {
+ ClassElement cls = element is ClosureFieldElement
+ ? element.closureClass
+ : element.enclosingClass;
+ names =
+ new _FieldNamingScope.forClass(cls, compiler.world, fieldRegistry);
+ }
+
+ if (names.containsField(element)) {
+ return names[element];
+ }
+ return null;
+ }
+}
+
+/**
+ * Encapsulates the global state of field naming.
+ *
+ * The field naming registry allocates names to be used along a path in the
+ * inheritance hierarchy of fields, starting with the object class. The actual
+ * hierarchy is encoded using instances of [_FieldNamingScope].
+ */
+class _FieldNamingRegistry {
+ final MinifyNamer namer;
+
+ final Map<Entity, _FieldNamingScope> scopes =
+ new Map<Entity, _FieldNamingScope>();
+
+ final Map<Entity, jsAst.Name> globalNames = new Map<Entity, jsAst.Name>();
+
+ int globalCount = 0;
+
+ final List<jsAst.Name> nameStore = new List<jsAst.Name>();
+
+ _FieldNamingRegistry(this.namer);
+
+ // Returns the name to be used for a field with distance [index] from the
+ // root of the object hierarchy. The distance thereby is computed as the
+ // number of fields preceding the current field in its classes inheritance
+ // chain.
+ //
+ // The implementation assumes that names are requedsted in order, that is the
+ // name at position i+1 is requested after the name at position i was
+ // requested.
+ jsAst.Name getName(int index) {
+ if (index >= nameStore.length) {
+ // The namer usually does not use certain names as they clash with
+ // existing properties on JS objects (see [_reservedNativeProperties]).
+ // However, some of them are really short and safe to use for fields.
+ // Thus, we shortcut the namer to use those first.
+ assert(index == nameStore.length);
+ if (index < MinifyNamer._reservedNativeProperties.length &&
+ MinifyNamer._reservedNativeProperties[index].length <= 2) {
+ nameStore.add(
+ new StringBackedName(MinifyNamer._reservedNativeProperties[index]));
+ } else {
+ nameStore.add(namer.getFreshName("field$index", namer.usedInstanceNames,
+ namer.suggestedInstanceNames));
+ }
+ }
+
+ return nameStore[index];
+ }
+}
+
+/**
+ * A [_FieldNamingScope] encodes a node in the inheritance tree of the current
+ * class hierarchy. The root node typically is the node corresponding to the
+ * `Object` class. It is used to assign a unique name to each field of a class.
+ * Unique here means unique wrt. all fields along the path back to the root.
+ * This is achieved at construction time via the [_fieldNameCounter] field that
+ * counts the number of fields on the path to the root node that have been
+ * encountered so far.
+ *
+ * Obviously, this only works if no fields are added to a parent node after its
+ * children have added their first field.
+ */
+class _FieldNamingScope {
+ final _FieldNamingScope superScope;
+ final Entity container;
+ final Map<Element, jsAst.Name> names = new Maplet<Element, jsAst.Name>();
+ final _FieldNamingRegistry registry;
+
+ /// Naming counter used for fields of ordinary classes.
+ int _fieldNameCounter;
+
+ /// The number of fields along the superclass chain that use inheritance
+ /// based naming, including the ones allocated for this scope.
+ int get inheritanceBasedFieldNameCounter => _fieldNameCounter;
+
+ /// The number of locally used fields. Depending on the naming source
+ /// (e.g. inheritance based or globally unique for mixixns) this
+ /// might be different from [inheritanceBasedFieldNameCounter].
+ int get _localFieldNameCounter => _fieldNameCounter;
+ void set _localFieldNameCounter(int val) {
+ _fieldNameCounter = val;
+ }
+
+ factory _FieldNamingScope.forClass(
+ ClassElement cls, ClassWorld world, _FieldNamingRegistry registry) {
+ _FieldNamingScope result = registry.scopes[cls];
+ if (result != null) return result;
+
+ if (world.isUsedAsMixin(cls)) {
+ result = new _MixinFieldNamingScope.mixin(cls, registry);
+ } else {
+ if (cls.superclass == null) {
+ result = new _FieldNamingScope.rootScope(cls, registry);
+ } else {
+ _FieldNamingScope superScope =
+ new _FieldNamingScope.forClass(cls.superclass, world, registry);
+ if (cls.isMixinApplication) {
+ result =
+ new _MixinFieldNamingScope.mixedIn(cls, superScope, registry);
+ } else {
+ result = new _FieldNamingScope.inherit(cls, superScope, registry);
+ }
+ }
+ }
+
+ cls.forEachInstanceField((cls, field) => result.add(field));
+
+ registry.scopes[cls] = result;
+ return result;
+ }
+
+ factory _FieldNamingScope.forBox(Local box, _FieldNamingRegistry registry) {
+ return registry.scopes.putIfAbsent(
+ box, () => new _BoxFieldNamingScope(box, registry));
+ }
+
+ _FieldNamingScope.rootScope(this.container, this.registry)
+ : superScope = null,
+ _fieldNameCounter = 0;
+
+ _FieldNamingScope.inherit(this.container, this.superScope, this.registry) {
+ _fieldNameCounter = superScope.inheritanceBasedFieldNameCounter;
+ }
+
+ /**
+ * Checks whether [name] is already used in the current scope chain.
+ */
+ _isNameUnused(jsAst.Name name) {
+ return !names.values.contains(name) &&
+ ((superScope == null) || superScope._isNameUnused(name));
+ }
+
+ jsAst.Name _nextName() => registry.getName(_localFieldNameCounter++);
+
+ jsAst.Name operator [](Element field) {
+ jsAst.Name name = names[field];
+ if (name == null && superScope != null) return superScope[field];
+ return name;
+ }
+
+ void add(Element field) {
+ if (names.containsKey(field)) return;
+
+ jsAst.Name value = _nextName();
+ assert(invariant(field, _isNameUnused(value)));
+ names[field] = value;
+ }
+
+ bool containsField(Element field) => names.containsKey(field);
+}
+
+/**
+ * Field names for mixins have two constraints: They need to be unique in the
+ * hierarchy of each application of a mixin and they need to be the same for
+ * all applications of a mixin. To achieve this, we use global naming for
+ * mixins from the same name pool as fields and add a `$` at the end to ensure
+ * they do not collide with normal field names. The `$` sign is typically used
+ * as a separator between method names and argument counts and does not appear
+ * in generated names themselves.
+ */
+class _MixinFieldNamingScope extends _FieldNamingScope {
+ int get _localFieldNameCounter => registry.globalCount;
+ void set _localFieldNameCounter(int val) {
+ registry.globalCount = val;
+ }
+
+ @override
+ Map<Entity, jsAst.Name> get names => registry.globalNames;
+
+ _MixinFieldNamingScope.mixin(ClassElement cls, _FieldNamingRegistry registry)
+ : super.rootScope(cls, registry);
+
+ _MixinFieldNamingScope.mixedIn(MixinApplicationElement container,
+ _FieldNamingScope superScope, _FieldNamingRegistry registry)
+ : super.inherit(container, superScope, registry);
+
+ jsAst.Name _nextName() {
+ jsAst.Name proposed = super._nextName();
+ return new CompoundName([proposed, Namer._literalDollar]);
+ }
+}
+
+/**
+ * [BoxFieldElement] fields work differently in that they do not belong to an
+ * actual class but an anonymous box associated to a [Local]. As there is no
+ * inheritance chain, we do not need to compute fields a priori but can assign
+ * names on the fly.
+ */
+class _BoxFieldNamingScope extends _FieldNamingScope {
+ _BoxFieldNamingScope(Local box, _FieldNamingRegistry registry)
+ : super.rootScope(box, registry);
+
+ @override
+ bool containsField(_) => true;
+
+ jsAst.Name operator [](Element field) {
+ if (!names.containsKey(field)) add(field);
+ return names[field];
+ }
+}
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index d44688a..36e75ab 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -7,10 +7,8 @@
import 'dart:async' show EventSink, Future;
import 'dart:collection' show HashMap;
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
- as embeddedNames;
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
- show JsGetName;
+import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
+import 'package:js_runtime/shared/embedded_names.dart' show JsGetName;
import '../closure.dart';
import '../compile_time_constants.dart';
@@ -55,6 +53,7 @@
part 'constant_emitter.dart';
part 'constant_handler_javascript.dart';
part 'custom_elements_analysis.dart';
+part 'field_naming_mixin.dart';
part 'minify_namer.dart';
part 'namer.dart';
part 'no_such_method_registry.dart';
diff --git a/pkg/compiler/lib/src/js_backend/minify_namer.dart b/pkg/compiler/lib/src/js_backend/minify_namer.dart
index 2f0b37c..9a2d1e3 100644
--- a/pkg/compiler/lib/src/js_backend/minify_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/minify_namer.dart
@@ -7,12 +7,14 @@
/**
* Assigns JavaScript identifiers to Dart variables, class-names and members.
*/
-class MinifyNamer extends Namer {
+class MinifyNamer extends Namer with _MinifiedFieldNamer {
MinifyNamer(Compiler compiler) : super(compiler) {
reserveBackendNames();
fieldRegistry = new _FieldNamingRegistry(this);
}
+ _FieldNamingRegistry fieldRegistry;
+
String get isolateName => 'I';
String get isolatePropertiesName => 'p';
bool get shouldMinify => true;
@@ -24,18 +26,17 @@
final ALPHABET_CHARACTERS = 52; // a-zA-Z.
final ALPHANUMERIC_CHARACTERS = 62; // a-zA-Z0-9.
- _FieldNamingRegistry fieldRegistry;
-
/// You can pass an invalid identifier to this and unlike its non-minifying
/// counterpart it will never return the proposedName as the new fresh name.
///
/// [sanitizeForNatives] and [sanitizeForAnnotations] are ignored because the
/// minified names will always avoid clashing with annotated names or natives.
+ @override
jsAst.Name getFreshName(String proposedName,
- Set<String> usedNames,
- Map<String, String> suggestedNames,
- {bool sanitizeForNatives: false,
- bool sanitizeForAnnotations: false}) {
+ Set<String> usedNames,
+ Map<String, String> suggestedNames,
+ {bool sanitizeForNatives: false,
+ bool sanitizeForAnnotations: false}) {
String freshName;
String suggestion = suggestedNames[proposedName];
if (suggestion != null && !usedNames.contains(suggestion)) {
@@ -244,209 +245,13 @@
return $0 + x - 52;
}
+ @override
jsAst.Name instanceFieldPropertyName(Element element) {
- if (element.hasFixedBackendName) {
- return new StringBackedName(element.fixedBackendName);
+ jsAst.Name proposed = _minifiedInstanceFieldPropertyName(element);
+ if (proposed != null) {
+ return proposed;
}
-
- _FieldNamingScope names;
- if (element is BoxFieldElement) {
- names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
- } else {
- ClassElement cls = element is ClosureFieldElement
- ? element.closureClass : element.enclosingClass;
- names = new _FieldNamingScope.forClass(cls, compiler.world,
- fieldRegistry);
- }
-
- // The inheritance scope based naming did not yield a name. For instance,
- // this could be because the field belongs to a mixin.
- if (!names.containsField(element)) {
- return super.instanceFieldPropertyName(element);
- }
-
- return names[element];
+ return super.instanceFieldPropertyName(element);
}
}
-/**
- * Encapsulates the global state of field naming.
- */
-class _FieldNamingRegistry {
- final MinifyNamer namer;
-
- final Map<Entity, _FieldNamingScope> scopes =
- new Map<Entity, _FieldNamingScope>();
-
- final Map<Entity, jsAst.Name> globalNames = new Map<Entity, jsAst.Name>();
-
- int globalCount = 0;
-
- final List<jsAst.Name> nameStore = new List<jsAst.Name>();
-
- _FieldNamingRegistry(this.namer);
-
- jsAst.Name getName(int count) {
- if (count >= nameStore.length) {
- // The namer usually does not use certain names as they clash with
- // existing properties on JS objects (see [_reservedNativeProperties]).
- // However, some of them are really short and safe to use for fields.
- // Thus, we shortcut the namer to use those first.
- if (count < MinifyNamer._reservedNativeProperties.length &&
- MinifyNamer._reservedNativeProperties[count].length <= 2) {
- nameStore.add(new StringBackedName(
- MinifyNamer._reservedNativeProperties[count]));
- } else {
- nameStore.add(namer.getFreshName("field$count",
- namer.usedInstanceNames, namer.suggestedInstanceNames));
- }
- }
-
- return nameStore[count];
- }
-}
-
-/**
- * A [_FieldNamingScope] encodes a node in the inheritance tree of the current
- * class hierarchy. The root node typically is the node corresponding to the
- * `Object` class. It is used to assign a unique name to each field of a class.
- * Unique here means unique wrt. all fields along the path back to the root.
- * This is achieved at construction time via the [_fieldNameCounter] field that
- * counts the number of fields on the path to the root node that have been
- * encountered so far.
- *
- * Obviously, this only works if no fields are added to a parent node after its
- * children have added their first field.
- */
-class _FieldNamingScope {
- final _FieldNamingScope superScope;
- final Entity container;
- final Map<Element, jsAst.Name> names = new Maplet<Element, jsAst.Name>();
- final _FieldNamingRegistry registry;
-
- /// Naming counter used for fields of ordinary classes.
- int _fieldNameCounter;
-
- /// The number of fields along the superclass chain that use inheritance
- /// based naming, including the ones allocated for this scope.
- int get inheritanceBasedFieldNameCounter => _fieldNameCounter;
-
- /// The number of locally used fields. Depending on the naming source
- /// (e.g. inheritance based or globally unique for mixixns) this
- /// might be different from [inheritanceBasedFieldNameCounter].
- int get _localFieldNameCounter => _fieldNameCounter;
- void set _localFieldNameCounter(int val) { _fieldNameCounter = val; }
-
- factory _FieldNamingScope.forClass(ClassElement cls, ClassWorld world,
- _FieldNamingRegistry registry) {
- _FieldNamingScope result = registry.scopes[cls];
- if (result != null) return result;
-
- if (world.isUsedAsMixin(cls)) {
- result = new _MixinFieldNamingScope.mixin(cls, registry);
- } else {
- if (cls.superclass == null) {
- result = new _FieldNamingScope.rootScope(cls, registry);
- } else {
- _FieldNamingScope superScope = new _FieldNamingScope.forClass(
- cls.superclass, world, registry);
- if (cls.isMixinApplication) {
- result = new _MixinFieldNamingScope.mixedIn(cls, superScope,
- registry);
- } else {
- result = new _FieldNamingScope.inherit(cls, superScope, registry);
- }
- }
- }
-
- cls.forEachInstanceField((cls, field) => result.add(field));
-
- registry.scopes[cls] = result;
- return result;
- }
-
- factory _FieldNamingScope.forBox(Local box, _FieldNamingRegistry registry) {
- return registry.scopes.putIfAbsent(box,
- () => new _BoxFieldNamingScope(box, registry));
- }
-
- _FieldNamingScope.rootScope(this.container, this.registry)
- : superScope = null,
- _fieldNameCounter = 0;
-
- _FieldNamingScope.inherit(this.container, this.superScope, this.registry) {
- _fieldNameCounter = superScope.inheritanceBasedFieldNameCounter;
- }
-
- /**
- * Checks whether [name] is already used in the current scope chain.
- */
- _isNameUnused(jsAst.Name name) {
- return !names.values.contains(name) &&
- ((superScope == null) || superScope._isNameUnused(name));
- }
-
- jsAst.Name _nextName() => registry.getName(_localFieldNameCounter++);
-
- jsAst.Name operator[](Element field) {
- jsAst.Name name = names[field];
- if (name == null && superScope != null) return superScope[field];
- return name;
- }
-
- void add(Element field) {
- if (names.containsKey(field)) return;
-
- jsAst.Name value = _nextName();
- assert(invariant(field, _isNameUnused(value)));
- names[field] = value;
- }
-
- bool containsField(Element field) => names.containsKey(field);
-}
-
-/**
- * Field names for mixins have two constraints: They need to be unique in the
- * hierarchy of each application of a mixin and they need to be the same for
- * all applications of a mixin. To achieve this, we use global naming for
- * mixins from the same name pool as fields and add a `$` at the end to ensure
- * they do not collide with normal field names. The `$` sign is typically used
- * as a separator between method names and argument counts and does not appear
- * in generated names themselves.
- */
-class _MixinFieldNamingScope extends _FieldNamingScope {
- int get _localFieldNameCounter => registry.globalCount;
- void set _localFieldNameCounter(int val) { registry.globalCount = val; }
-
- Map<Entity, jsAst.Name> get names => registry.globalNames;
-
- _MixinFieldNamingScope.mixin(ClassElement cls, _FieldNamingRegistry registry)
- : super.rootScope(cls, registry);
-
- _MixinFieldNamingScope.mixedIn(MixinApplicationElement container,
- _FieldNamingScope superScope, _FieldNamingRegistry registry)
- : super.inherit(container, superScope, registry);
-
- jsAst.Name _nextName() {
- jsAst.Name proposed = super._nextName();
- return new CompoundName([proposed, Namer._literalDollar]);
- }
-}
-
-/**
- * [BoxFieldElement] fields work differently in that they do not belong to an
- * actual class but an anonymous box associated to a [Local]. As there is no
- * inheritance chain, we do not need to compute fields a priori but can assign
- * names on the fly.
- */
-class _BoxFieldNamingScope extends _FieldNamingScope {
- _BoxFieldNamingScope(Local box, _FieldNamingRegistry registry) :
- super.rootScope(box, registry);
-
- bool containsField(_) => true;
-
- jsAst.Name operator[](Element field) {
- if (!names.containsKey(field)) add(field);
- return names[field];
- }
-}
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index 45604fde1..366d769 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -12,7 +12,7 @@
ClassStubGenerator(this.compiler, this.namer, this.backend);
jsAst.Expression generateClassConstructor(ClassElement classElement,
- Iterable<String> fields) {
+ Iterable<jsAst.Name> fields) {
// TODO(sra): Implement placeholders in VariableDeclaration position:
//
// String constructorName = namer.getNameOfClass(classElement);
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index 89b615d..09d9d18 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -93,10 +93,8 @@
import '../deferred_load.dart' show
OutputUnit;
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
- as embeddedNames;
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show
- JsBuiltin;
+import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
+import 'package:js_runtime/shared/embedded_names.dart' show JsBuiltin;
import '../native/native.dart' as native;
part 'class_stub_generator.dart';
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart
index d3425bf..b431c6d 100644
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart
@@ -4,7 +4,7 @@
library dart2js.new_js_emitter.emitter;
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show
+import 'package:js_runtime/shared/embedded_names.dart' show
JsBuiltin,
METADATA,
TYPES;
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
index 8ccd680..f34051c1 100644
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
@@ -15,7 +15,7 @@
import '../js_emitter.dart' show AstContainer, NativeEmitter;
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show
+import 'package:js_runtime/shared/embedded_names.dart' show
CREATE_NEW_ISOLATE,
DEFERRED_LIBRARY_URIS,
DEFERRED_LIBRARY_HASHES,
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
index a4417c1..47bd9ff 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
@@ -60,7 +60,7 @@
* Emits the precompiled constructor when in CSP mode.
*/
void emitConstructorsForCSP(Class cls) {
- List<String> fieldNames = <String>[];
+ List<jsAst.Name> fieldNames = <jsAst.Name>[];
if (!compiler.useContentSecurityPolicy) return;
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
index 2749850..552fd27 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
@@ -1018,14 +1018,19 @@
void assemblePrecompiledConstructor(OutputUnit outputUnit,
jsAst.Name constructorName,
jsAst.Expression constructorAst,
- List<String> fields) {
+ List<jsAst.Name> fields) {
cspPrecompiledFunctionFor(outputUnit).add(
new jsAst.FunctionDeclaration(constructorName, constructorAst));
String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
bool hasIsolateSupport = compiler.hasIsolateSupport;
- jsAst.Node fieldNamesArray =
- hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull();
+ jsAst.Node fieldNamesArray;
+ if (hasIsolateSupport) {
+ fieldNamesArray =
+ new jsAst.ArrayInitializer(fields.map(js.quoteName).toList());
+ } else {
+ fieldNamesArray = new jsAst.LiteralNull();
+ }
cspPrecompiledFunctionFor(outputUnit).add(js.statement(r'''
{
@@ -1084,7 +1089,7 @@
// Also emit a trivial constructor for CSP mode.
jsAst.Name constructorName = mangledName;
jsAst.Expression constructorAst = js('function() {}');
- List<String> fieldNames = [];
+ List<jsAst.Name> fieldNames = [];
assemblePrecompiledConstructor(mainOutputUnit,
constructorName,
constructorAst,
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index a566d3f..227030a 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -102,9 +102,10 @@
* 'dart:core' and 'dart:_js_helper' are not readable themselves but are instead
* resolved into a readable URI using the library root URI provided from the
* command line and the list of platform libraries found in
- * 'sdk/lib/_internal/libraries.dart'. This is done through the
- * [Compiler.translateResolvedUri] method which checks whether a library by that
- * name exists and in case of internal libraries whether access is granted.
+ * 'sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart'. This is done
+ * through the [Compiler.translateResolvedUri] method which checks whether a
+ * library by that name exists and in case of internal libraries whether access
+ * is granted.
*
* ## Resource URI ##
*
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
index 51ab110..5bf4b1e 100644
--- a/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
+++ b/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
@@ -193,11 +193,11 @@
Script script = getScript();
SourceSpan span;
if (beginToken == null) {
- span = new SourceSpan(script.readableUri, 0, 0);
+ span = new SourceSpan(script.resourceUri, 0, 0);
} else {
Token endToken = getEndToken();
span = mirrorSystem.compiler.spanFromTokens(
- beginToken, endToken, script.readableUri);
+ beginToken, endToken, script.resourceUri);
}
return new Dart2JsSourceLocation(script, span);
}
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index f64c5de..b0bde83 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -9,7 +9,7 @@
* [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/libraries.dart:].
+ * 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
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 977b688..bcf6113 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -6,12 +6,18 @@
class InitializerResolver {
final ResolverVisitor visitor;
- final Map<Element, Node> initialized;
+ 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;
+ bool hasSuper = false;
+ bool isValidAsConstant = true;
- InitializerResolver(this.visitor)
- : initialized = new Map<Element, Node>(), hasSuper = false;
+ bool get isConst => constructor.isConst;
+
+ InitializerResolver(this.visitor, this.constructor, this.functionNode);
ResolutionRegistry get registry => visitor.registry;
@@ -37,6 +43,7 @@
visitor.compiler.reportInfo(
existing,
MessageKind.ALREADY_INITIALIZED, {'fieldName': field.name});
+ isValidAsConstant = false;
}
void checkForDuplicateInitializers(FieldElementX field, Node init) {
@@ -54,12 +61,13 @@
initialized[field] = init;
}
- void resolveFieldInitializer(FunctionElement constructor, SendSet 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)) {
target = constructor.enclosingClass.lookupLocalMember(name);
if (target == null) {
@@ -72,6 +80,8 @@
selector.asIdentifier(), constructor.enclosingClass);
} else if (!target.isInstanceMember) {
error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
+ } else {
+ field = target;
}
} else {
error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
@@ -80,38 +90,44 @@
registry.registerStaticUse(target);
checkForDuplicateInitializers(target, init);
// Resolve initializing value.
- visitor.visitInStaticContext(init.arguments.head);
- }
-
- ClassElement getSuperOrThisLookupTarget(FunctionElement constructor,
- bool isSuperCall,
- Node diagnosticNode) {
- ClassElement lookupTarget = constructor.enclosingClass;
- if (isSuperCall) {
- // Calculate correct lookup target and constructor name.
- if (identical(lookupTarget, visitor.compiler.objectClass)) {
- error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
+ 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 {
- return lookupTarget.supertype.element;
+ isValidAsConstant = false;
}
}
- return lookupTarget;
}
- Element resolveSuperOrThisForSend(FunctionElement constructor,
- FunctionExpression functionNode,
- Send call) {
- // Resolve the selector and the arguments.
- visitor.inStaticContext(() {
- visitor.resolveSelector(call, null);
- visitor.resolveArguments(call.argumentsNode);
- });
- Selector selector = registry.getSelector(call);
- bool isSuperCall = Initializers.isSuperConstructorCall(call);
+ InterfaceType getSuperOrThisLookupTarget(Node diagnosticNode,
+ {bool isSuperCall}) {
+ if (isSuperCall) {
+ // Calculate correct lookup target and constructor name.
+ if (identical(constructor.enclosingClass, visitor.compiler.objectClass)) {
+ error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
+ isValidAsConstant = false;
+ } else {
+ return constructor.enclosingClass.supertype;
+ }
+ }
+ return constructor.enclosingClass.thisType;
+ }
- ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
- isSuperCall,
- call);
+ ResolutionResult resolveSuperOrThisForSend(Send call) {
+ // Resolve the selector and the arguments.
+ ArgumentsResult argumentsResult = visitor.inStaticContext(() {
+ visitor.resolveSelector(call, null);
+ return visitor.resolveArguments(call.argumentsNode);
+ }, inConstantInitializer: isConst);
+
+ bool isSuperCall = Initializers.isSuperConstructorCall(call);
+ InterfaceType targetType =
+ getSuperOrThisLookupTarget(call, isSuperCall: isSuperCall);
+ ClassElement lookupTarget = targetType.element;
Selector constructorSelector =
visitor.getRedirectingThisOrSuperConstructorSelector(call);
FunctionElement calledConstructor =
@@ -119,9 +135,8 @@
final bool isImplicitSuperCall = false;
final String className = lookupTarget.name;
- verifyThatConstructorMatchesCall(constructor,
- calledConstructor,
- selector.callStructure,
+ verifyThatConstructorMatchesCall(calledConstructor,
+ argumentsResult.callStructure,
isImplicitSuperCall,
call,
className,
@@ -129,11 +144,28 @@
registry.useElement(call, calledConstructor);
registry.registerStaticUse(calledConstructor);
- return calledConstructor;
+ if (isConst) {
+ if (isValidAsConstant &&
+ calledConstructor.isConst &&
+ argumentsResult.isValidAsConstant) {
+ CallStructure callStructure = argumentsResult.callStructure;
+ List<ConstantExpression> arguments = argumentsResult.constantArguments;
+ return new ConstantResult(
+ call,
+ new ConstructedConstantExpression(
+ targetType,
+ calledConstructor,
+ callStructure,
+ arguments),
+ element: calledConstructor);
+ } else {
+ isValidAsConstant = false;
+ }
+ }
+ return new ResolutionResult.forElement(calledConstructor);
}
- void resolveImplicitSuperConstructorSend(FunctionElement constructor,
- FunctionExpression functionNode) {
+ ConstructedConstantExpression resolveImplicitSuperConstructorSend() {
// If the class has a super resolve the implicit super call.
ClassElement classElement = constructor.enclosingClass;
ClassElement superClass = classElement.superclass;
@@ -141,18 +173,16 @@
assert(superClass != null);
assert(superClass.isResolved);
- final bool isSuperCall = true;
- ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
- isSuperCall,
- functionNode);
+ InterfaceType targetType =
+ getSuperOrThisLookupTarget(functionNode, isSuperCall: true);
+ ClassElement lookupTarget = targetType.element;
Selector constructorSelector = new Selector.callDefaultConstructor();
Element calledConstructor = lookupTarget.lookupConstructor(
constructorSelector.name);
final String className = lookupTarget.name;
final bool isImplicitSuperCall = true;
- verifyThatConstructorMatchesCall(constructor,
- calledConstructor,
+ verifyThatConstructorMatchesCall(calledConstructor,
CallStructure.NO_ARGS,
isImplicitSuperCall,
functionNode,
@@ -160,19 +190,27 @@
constructorSelector);
registry.registerImplicitSuperCall(calledConstructor);
registry.registerStaticUse(calledConstructor);
+
+ if (isConst && isValidAsConstant) {
+ return new ConstructedConstantExpression(
+ targetType,
+ calledConstructor,
+ CallStructure.NO_ARGS,
+ const <ConstantExpression>[]);
+ }
}
+ return null;
}
void verifyThatConstructorMatchesCall(
- FunctionElement caller,
ConstructorElementX lookedupConstructor,
CallStructure call,
bool isImplicitSuperCall,
Node diagnosticNode,
String className,
Selector constructorSelector) {
- if (lookedupConstructor == null
- || !lookedupConstructor.isGenerativeConstructor) {
+ if (lookedupConstructor == null ||
+ !lookedupConstructor.isGenerativeConstructor) {
String fullConstructorName = Elements.constructorNameForDiagnostics(
className,
constructorSelector.name);
@@ -181,19 +219,22 @@
: MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
visitor.compiler.reportError(
diagnosticNode, kind, {'constructorName': fullConstructorName});
+ isValidAsConstant = false;
} else {
lookedupConstructor.computeSignature(visitor.compiler);
- if (!call.signatureApplies(lookedupConstructor)) {
+ if (!call.signatureApplies(lookedupConstructor.functionSignature)) {
MessageKind kind = isImplicitSuperCall
? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
: MessageKind.NO_MATCHING_CONSTRUCTOR;
visitor.compiler.reportError(diagnosticNode, kind);
- } else if (caller.isConst
+ isValidAsConstant = false;
+ } else if (constructor.isConst
&& !lookedupConstructor.isConst) {
MessageKind kind = isImplicitSuperCall
? MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT
: MessageKind.CONST_CALLS_NON_CONST;
visitor.compiler.reportError(diagnosticNode, kind);
+ isValidAsConstant = false;
}
}
}
@@ -202,16 +243,50 @@
* Resolve all initializers of this constructor. In the case of a redirecting
* constructor, the resolved constructor's function element is returned.
*/
- ConstructorElement resolveInitializers(ConstructorElementX constructor,
- FunctionExpression functionNode) {
+ 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;
- functionParameters.forEachParameter((ParameterElement element) {
+ functionParameters.forEachParameter((ParameterElementX element) {
+ 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) {
- InitializingFormalElement initializingFormal = element;
- checkForDuplicateInitializers(initializingFormal.fieldElement,
- element.initializer);
+ InitializingFormalElementX initializingFormal = element;
+ FieldElement field = initializingFormal.fieldElement;
+ checkForDuplicateInitializers(field, element.initializer);
+ 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;
+ }
}
});
@@ -224,7 +299,7 @@
for (Link<Node> link = initializers; !link.isEmpty; link = link.tail) {
if (link.head.asSendSet() != null) {
final SendSet init = link.head.asSendSet();
- resolveFieldInitializer(constructor, init);
+ resolveFieldInitializer(init);
} else if (link.head.asSend() != null) {
final Send call = link.head.asSend();
if (call.argumentsNode == null) {
@@ -235,7 +310,14 @@
if (resolvedSuper) {
error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER);
}
- resolveSuperOrThisForSend(constructor, functionNode, call);
+ 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
@@ -256,9 +338,24 @@
if (parameter.isInitializingFormal) {
Node node = parameter.node;
error(node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED);
+ isValidAsConstant = false;
}
});
- return resolveSuperOrThisForSend(constructor, functionNode, call);
+ 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 {
visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED);
return null;
@@ -268,7 +365,14 @@
}
}
if (!resolvedSuper) {
- resolveImplicitSuperConstructorSend(constructor, functionNode);
+ constructorInvocation = resolveImplicitSuperConstructorSend();
+ }
+ if (isConst && isValidAsConstant) {
+ constructor.constantConstructor = new GenerativeConstantConstructor(
+ constructor.enclosingClass.thisType,
+ defaultValues,
+ fieldInitializers,
+ constructorInvocation);
}
return null; // If there was no redirection always return null.
}
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 5e5bf53..7c1bdf9 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -4,6 +4,24 @@
part of resolution;
+/// 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.
*
@@ -23,6 +41,7 @@
bool inInstanceContext;
bool inCheckContext;
bool inCatchBlock;
+ ConstantState constantState;
Scope scope;
ClassElement currentClass;
@@ -100,6 +119,8 @@
!element.isTypedef &&
!element.enclosingElement.isTypedef,
inCatchBlock = false,
+ constantState = element.isConst
+ ? ConstantState.CONSTANT : ConstantState.NON_CONSTANT,
super(compiler, registry);
CoreTypes get coreTypes => compiler.coreTypes;
@@ -153,14 +174,6 @@
return result;
}
- inStaticContext(action()) {
- bool wasInstanceContext = inInstanceContext;
- inInstanceContext = false;
- var result = action();
- inInstanceContext = wasInstanceContext;
- return result;
- }
-
doInPromotionScope(Node node, action()) {
promotionScope = promotionScope.prepend(node);
var result = action();
@@ -168,8 +181,47 @@
return result;
}
- ResolutionResult visitInStaticContext(Node node) {
- return inStaticContext(() => visit(node));
+ 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(invariant(node, result != null,
+ message: "No resolution result for $node."));
+
+ return result;
}
ErroneousElement reportAndCreateErroneousElement(
@@ -324,7 +376,7 @@
FunctionSignature functionParameters = function.functionSignature;
Link<Node> parameterNodes = (node.parameters == null)
? const Link<Node>() : node.parameters.nodes;
- functionParameters.forEachParameter((ParameterElement element) {
+ functionParameters.forEachParameter((ParameterElementX element) {
// TODO(karlklose): should be a list of [FormalElement]s, but the actual
// implementation uses [Element].
List<Element> optionals = functionParameters.optionalParameters;
@@ -332,7 +384,16 @@
NodeList nodes = parameterNodes.head;
parameterNodes = nodes.nodes;
}
- visit(element.initializer);
+ if (element.isOptional) {
+ if (element.initializer != null) {
+ ResolutionResult result = visitInConstantContext(element.initializer);
+ if (result.isConstant) {
+ element.constant = result.constant;
+ }
+ } else {
+ 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
@@ -340,7 +401,7 @@
if (element.isInitializingFormal) {
registry.useElement(parameterNode, element);
} else {
- LocalParameterElement parameterElement = element;
+ LocalParameterElementX parameterElement = element;
defineLocalVariable(parameterNode, parameterElement);
addToScope(parameterElement);
}
@@ -715,8 +776,10 @@
return selector;
}
- CallStructure resolveArguments(NodeList list) {
+ 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>();
@@ -724,7 +787,12 @@
List<String> namedArguments = <String>[];
for (Link<Node> link = list.nodes; !link.isEmpty; link = link.tail) {
Expression argument = link.head;
- visit(argument);
+ ResolutionResult result = visit(argument);
+ if (!result.isConstant) {
+ isValidAsConstant = false;
+ }
+ argumentResults.add(result);
+
NamedArgument namedArgument = argument.asNamedArgument();
if (namedArgument != null) {
String source = namedArgument.name.source;
@@ -734,16 +802,21 @@
source,
argument,
seenNamedArguments[source]);
+ isValidAsConstant = false;
} else {
seenNamedArguments[source] = namedArgument;
}
} else if (!seenNamedArguments.isEmpty) {
error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED);
+ isValidAsConstant = false;
}
argumentCount++;
}
sendIsMemberAccess = oldSendIsMemberAccess;
- return new CallStructure(argumentCount, namedArguments);
+ return new ArgumentsResult(
+ new CallStructure(argumentCount, namedArguments),
+ argumentResults,
+ isValidAsConstant: isValidAsConstant);
}
void registerTypeLiteralAccess(Send node, Element target) {
@@ -1380,7 +1453,8 @@
message: "Unexpected expression: $node"));
Node expression = node.selector;
visitExpression(expression);
- CallStructure callStructure = resolveArguments(node.argumentsNode);
+ CallStructure callStructure =
+ resolveArguments(node.argumentsNode).callStructure;
Selector selector = callStructure.callSelector;
// TODO(johnniwinther): Remove this when all information goes through the
// [SendStructure].
@@ -1398,7 +1472,8 @@
// If this send is of the form "assert(expr);", then
// this is an assertion.
- CallStructure callStructure = resolveArguments(node.argumentsNode);
+ CallStructure callStructure =
+ resolveArguments(node.argumentsNode).callStructure;
SendStructure sendStructure = const AssertStructure();
if (callStructure.argumentCount != 1) {
compiler.reportError(
@@ -1430,7 +1505,8 @@
ResolutionResult handleThisAccess(Send node) {
AccessSemantics accessSemantics = new AccessSemantics.thisAccess();
if (node.isCall) {
- CallStructure callStructure = resolveArguments(node.argumentsNode);
+ CallStructure callStructure =
+ resolveArguments(node.argumentsNode).callStructure;
Selector selector = callStructure.callSelector;
// TODO(johnniwinther): Handle invalid this access as an
// [AccessSemantics].
@@ -1456,7 +1532,8 @@
Selector selector;
CallStructure callStructure = CallStructure.NO_ARGS;
if (node.isCall) {
- callStructure = resolveArguments(node.argumentsNode);
+ callStructure =
+ resolveArguments(node.argumentsNode).callStructure;
selector = new Selector(SelectorKind.CALL, name, callStructure);
} else {
selector = new Selector(SelectorKind.GETTER, name, callStructure);
@@ -1470,7 +1547,8 @@
case AccessKind.SUPER_METHOD:
MethodElementX superMethod = semantics.element;
superMethod.computeSignature(compiler);
- if (!callStructure.signatureApplies(superMethod)) {
+ if (!callStructure.signatureApplies(
+ superMethod.functionSignature)) {
registry.registerThrowNoSuchMethod();
registry.registerDynamicInvocation(
new UniverseSelector(selector, null));
@@ -1710,7 +1788,8 @@
SendStructure sendStructure;
Selector selector;
if (node.isCall) {
- CallStructure callStructure = resolveArguments(node.argumentsNode);
+ CallStructure callStructure =
+ resolveArguments(node.argumentsNode).callStructure;
selector = new Selector(SelectorKind.CALL, name, callStructure);
registry.registerDynamicInvocation(
new UniverseSelector(selector, null));
@@ -1802,7 +1881,8 @@
SendStructure sendStructure;
Selector selector;
if (node.isCall) {
- CallStructure callStructure = resolveArguments(node.argumentsNode);
+ CallStructure callStructure =
+ resolveArguments(node.argumentsNode).callStructure;
selector = new Selector(SelectorKind.CALL, name, callStructure);
registry.registerDynamicInvocation(
new UniverseSelector(selector, null));
@@ -1863,22 +1943,19 @@
/// 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;
- CallStructure callStructure = CallStructure.NO_ARGS;
if (node.isCall) {
- callStructure = resolveArguments(node.argumentsNode);
+ CallStructure callStructure =
+ resolveArguments(node.argumentsNode).callStructure;
selector = new Selector(SelectorKind.CALL, name, callStructure);
- } else {
- selector = new Selector(SelectorKind.GETTER, name, callStructure);
- }
- if (node.isCall) {
bool isIncompatibleInvoke = false;
switch (semantics.kind) {
case AccessKind.LOCAL_FUNCTION:
LocalFunctionElementX function = semantics.element;
function.computeSignature(compiler);
- if (!callStructure.signatureApplies(function)) {
+ if (!callStructure.signatureApplies(function.functionSignature)) {
registry.registerThrowNoSuchMethod();
registry.registerDynamicInvocation(
new UniverseSelector(selector, null));
@@ -1903,6 +1980,48 @@
? 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) {
+ result = new ConstantResult(
+ node,
+ new VariableConstantExpression(element),
+ element: element);
+ } else {
+ result = new ElementResult(element);
+ }
+ break;
+ default:
+ internalError(node,
+ "Unexpected local access $semantics.");
+ break;
+ }
+ selector = new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS);
registry.registerSendStructure(node,
new GetStructure(semantics, selector));
}
@@ -1914,14 +2033,13 @@
registerPotentialAccessInClosure(node, element);
- return node.isPropertyAccess
- ? new ElementResult(element) : const NoneResult();
+ 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;
@@ -1938,23 +2056,21 @@
member.computeType(compiler);
Selector selector;
- CallStructure callStructure = CallStructure.NO_ARGS;
- if (node.isCall) {
- callStructure = resolveArguments(node.argumentsNode);
- selector = new Selector(SelectorKind.CALL, name, callStructure);
- } else {
- selector = new Selector(SelectorKind.GETTER, name, callStructure);
- }
AccessSemantics semantics =
computeStaticOrTopLevelAccessSemantics(node, member);
if (node.isCall) {
+ ArgumentsResult argumentsResult =
+ resolveArguments(node.argumentsNode);
+ CallStructure callStructure = argumentsResult.callStructure;
+ selector = new Selector(SelectorKind.CALL, name, callStructure);
+
bool isIncompatibleInvoke = false;
switch (semantics.kind) {
case AccessKind.STATIC_METHOD:
case AccessKind.TOPLEVEL_METHOD:
MethodElementX method = semantics.element;
method.computeSignature(compiler);
- if (!callStructure.signatureApplies(method)) {
+ if (!callStructure.signatureApplies(method.functionSignature)) {
registry.registerThrowNoSuchMethod();
registry.registerDynamicInvocation(
new UniverseSelector(selector, null));
@@ -1962,6 +2078,13 @@
} else {
registry.registerStaticUse(semantics.element);
handleForeignCall(node, semantics.element, selector);
+ if (method == compiler.identicalFunction &&
+ argumentsResult.isValidAsConstant) {
+ result = new ConstantResult(node,
+ new IdenticalConstantExpression(
+ argumentsResult.argumentResults[0].constant,
+ argumentsResult.argumentResults[1].constant));
+ }
}
break;
case AccessKind.STATIC_FIELD:
@@ -1993,6 +2116,7 @@
? new IncompatibleInvokeStructure(semantics, selector)
: new InvokeStructure(semantics, selector));
} else {
+ selector = new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS);
switch (semantics.kind) {
case AccessKind.STATIC_METHOD:
case AccessKind.TOPLEVEL_METHOD:
@@ -2024,6 +2148,13 @@
}
registry.registerSendStructure(node,
new GetStructure(semantics, selector));
+ if (member.isConst) {
+ FieldElement field = member;
+ result = new ConstantResult(
+ node, new VariableConstantExpression(field), element: field);
+ } else {
+ result = new ElementResult(member);
+ }
}
// TODO(johnniwinther): Remove these when all information goes through
@@ -2031,8 +2162,7 @@
registry.useElement(node, member);
registry.setSelector(node, selector);
- return node.isPropertyAccess
- ? new ElementResult(member) : const NoneResult();
+ return result;
}
/// Handle access to resolved [element].
@@ -2534,6 +2664,7 @@
}
ConstructorElementX constructor = enclosingElement;
bool isConstConstructor = constructor.isConst;
+ bool isValidAsConstant = isConstConstructor;
ConstructorElement redirectionTarget = resolveRedirectingFactory(
node, inConstContext: isConstConstructor);
constructor.immediateRedirectionTarget = redirectionTarget;
@@ -2553,9 +2684,13 @@
if (isConstConstructor &&
!redirectionTarget.isConst) {
compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
+ isValidAsConstant = false;
}
if (redirectionTarget == constructor) {
compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
+ // TODO(johnniwinther): Create constant constructor for this case and
+ // let evaluation detect the cyclicity.
+ isValidAsConstant = false;
}
}
@@ -2570,6 +2705,8 @@
if (!isSubtype) {
warning(node, MessageKind.NOT_ASSIGNABLE,
{'fromType': targetType, 'toType': constructorType});
+ // TODO(johnniwinther): Handle this (potentially) erroneous case.
+ isValidAsConstant = false;
}
redirectionTarget.computeType(compiler);
@@ -2579,6 +2716,7 @@
if (!targetSignature.isCompatibleWith(constructorSignature)) {
assert(!isSubtype);
registry.registerThrowNoSuchMethod();
+ isValidAsConstant = false;
}
// Register a post process to check for cycles in the redirection chain and
@@ -2594,6 +2732,30 @@
if (isSymbolConstructor) {
registry.registerSymbolConstructor();
}
+ if (isValidAsConstant) {
+ List<String> names = <String>[];
+ List<ConstantExpression> arguments = <ConstantExpression>[];
+ int index = 0;
+ constructorSignature.forEachParameter((ParameterElement 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();
}
@@ -2681,12 +2843,19 @@
}
ResolutionResult visitNewExpression(NewExpression node) {
+ bool isValidAsConstant = true;
FunctionElement constructor = resolveConstructor(node);
final bool isSymbolConstructor = constructor == compiler.symbolConstructor;
final bool isMirrorsUsedConstant =
node.isConst && (constructor == compiler.mirrorsUsedConstructor);
Selector callSelector = resolveSelector(node.send, constructor);
- resolveArguments(node.send.argumentsNode);
+ ArgumentsResult argumentsResult;
+ if (node.isConst) {
+ argumentsResult =
+ inConstantContext(() => resolveArguments(node.send.argumentsNode));
+ } else {
+ argumentsResult = resolveArguments(node.send.argumentsNode);
+ }
registry.useElement(node.send, constructor);
if (Elements.isUnresolved(constructor)) {
return new ResolutionResult.forElement(constructor);
@@ -2704,12 +2873,14 @@
compiler.reportError(node,
MessageKind.CANNOT_INSTANTIATE_ENUM,
{'enumName': cls.name});
+ isValidAsConstant = false;
}
InterfaceType type = registry.getType(node);
if (node.isConst && type.containsTypeVariables) {
compiler.reportError(node.send.selector,
MessageKind.TYPE_VARIABLE_IN_CONSTANT);
+ isValidAsConstant = false;
}
// TODO(johniwinther): Avoid registration of `type` in face of redirecting
// factory constructors.
@@ -2717,6 +2888,7 @@
if (constructor.isGenerativeConstructor && cls.isAbstract) {
warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
registry.registerAbstractClassInstantiation();
+ isValidAsConstant = false;
}
if (isSymbolConstructor) {
@@ -2751,6 +2923,19 @@
}
if (node.isConst) {
analyzeConstantDeferred(node);
+ if (isValidAsConstant &&
+ constructor.isConst &&
+ argumentsResult.isValidAsConstant) {
+ CallStructure callStructure = argumentsResult.callStructure;
+ List<ConstantExpression> arguments = argumentsResult.constantArguments;
+ ConstructedConstantExpression constant =
+ new ConstructedConstantExpression(
+ type,
+ constructor,
+ callStructure,
+ arguments);
+ return new ConstantResult(node, constant);
+ }
}
return const NoneResult();
@@ -2897,14 +3082,16 @@
registry.registerRequiredType(listType, enclosingElement);
if (node.isConst) {
List<ConstantExpression> constantExpressions = <ConstantExpression>[];
- for (Node element in node.elements) {
- ResolutionResult elementResult = visit(element);
- if (isValidAsConstant && elementResult.isConstant) {
- constantExpressions.add(elementResult.constant);
- } else {
- isValidAsConstant = false;
+ 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) {
@@ -3196,20 +3383,23 @@
registry.registerMapLiteral(node, mapType, node.isConst);
registry.registerRequiredType(mapType, enclosingElement);
if (node.isConst) {
+
List<ConstantExpression> keyExpressions = <ConstantExpression>[];
List<ConstantExpression> valueExpressions = <ConstantExpression>[];
- 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;
+ 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) {
diff --git a/pkg/compiler/lib/src/resolution/resolution_common.dart b/pkg/compiler/lib/src/resolution/resolution_common.dart
index cb045cf..0f1a778 100644
--- a/pkg/compiler/lib/src/resolution/resolution_common.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_common.dart
@@ -160,9 +160,9 @@
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);
- FunctionElement redirection =
- resolver.resolveInitializers(element, tree);
+ InitializerResolver resolver =
+ new InitializerResolver(visitor, element, tree);
+ FunctionElement redirection = resolver.resolveInitializers();
if (redirection != null) {
resolveRedirectingConstructor(resolver, tree, element, redirection);
}
diff --git a/pkg/compiler/lib/src/resolution/resolution_result.dart b/pkg/compiler/lib/src/resolution/resolution_result.dart
index 5426fe3..ba2b74c 100644
--- a/pkg/compiler/lib/src/resolution/resolution_result.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_result.dart
@@ -23,6 +23,7 @@
}
ResultKind get kind;
+ Node get node => null;
Element get element => null;
DartType get type => null;
ConstantExpression get constant => null;
@@ -64,11 +65,16 @@
String toString() => 'AssertResult()';
}
+/// The result for resolving a constant expression.
class ConstantResult extends ResolutionResult {
final Node node;
final ConstantExpression constant;
+ final Element element;
- ConstantResult(this.node, this.constant);
+ /// 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;
@@ -83,4 +89,31 @@
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();
+ }
}
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
index fa8cacc..d3f4e61 100644
--- a/pkg/compiler/lib/src/resolution/send_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/send_resolver.dart
@@ -333,7 +333,9 @@
case AccessKind.SUPER_METHOD:
case AccessKind.TOPLEVEL_METHOD:
// TODO(johnniwinther): Should local function also be handled here?
- if (!selector.callStructure.signatureApplies(semantics.element)) {
+ FunctionElement function = semantics.element;
+ FunctionSignature signature = function.functionSignature;
+ if (!selector.callStructure.signatureApplies(signature)) {
return new IncompatibleInvokeStructure(semantics, selector);
}
break;
@@ -586,7 +588,7 @@
type,
effectiveTargetSemantics);
} else {
- if (!callStructure.signatureApplies(constructor)) {
+ if (!callStructure.signatureApplies(constructor.functionSignature)) {
return new ConstructorAccessSemantics(
ConstructorAccessKind.INCOMPATIBLE,
constructor,
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 50fa510..07e7793 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -1019,12 +1019,18 @@
/**
* This class builds SSA nodes for functions represented in AST.
*/
-class SsaBuilder extends NewResolvedVisitor {
+class SsaBuilder extends ast.Visitor
+ with BaseImplementationOfCompoundsMixin,
+ SendResolverMixin,
+ SemanticSendResolvedMixin,
+ NewBulkMixin
+ implements SemanticSendVisitor {
final Compiler compiler;
final JavaScriptBackend backend;
final ConstantSystem constantSystem;
final CodegenWorkItem work;
final RuntimeTypes rti;
+ TreeElements elements;
SourceInformationBuilder sourceInformationBuilder;
bool inLazyInitializerExpression = false;
@@ -1119,13 +1125,26 @@
this.constantSystem = backend.constantSystem,
this.work = work,
this.rti = backend.rti,
- super(work.resolutionTree) {
+ this.elements = work.resolutionTree {
localsHandler = new LocalsHandler(this, work.element, null);
sourceElementStack.add(work.element);
sourceInformationBuilder =
sourceInformationFactory.forContext(work.element.implementation);
}
+ @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);
+ }
+
CodegenRegistry get registry => work.registry;
/// Returns the current source element.
@@ -1940,12 +1959,13 @@
}
Element target = constructor.definingConstructor.implementation;
- bool match = CallStructure.addForwardingElementArgumentsToList(
- constructor,
- arguments,
- target,
- compileArgument,
- handleConstantForOptionalParameter);
+ bool match = !target.isErroneous &&
+ CallStructure.addForwardingElementArgumentsToList(
+ constructor,
+ arguments,
+ target,
+ compileArgument,
+ handleConstantForOptionalParameter);
if (!match) {
if (compiler.elementHasCompileTimeError(constructor)) {
return;
@@ -3123,9 +3143,14 @@
localsHandler.updateLocal(localFunction, pop());
}
+ @override
+ void visitThisGet(ast.Identifier node, [_]) {
+ stack.add(localsHandler.readThis());
+ }
+
visitIdentifier(ast.Identifier node) {
if (node.isThis()) {
- stack.add(localsHandler.readThis());
+ visitThisGet(node);
} else {
compiler.internalError(node,
"SsaFromAstMixin.visitIdentifier on non-this.");
@@ -3401,8 +3426,6 @@
// TODO(5346): Try to avoid the need for calling [declaration] before
// creating an [HStatic].
push(new HStatic(function.declaration, backend.nonNullType));
- // TODO(ahe): This should be registered in codegen.
- registry.registerGetOfStaticFunction(function.declaration);
}
/// Read a local variable, function or parameter.
@@ -4401,18 +4424,6 @@
generateSuperNoSuchMethodSend(node, selector, arguments);
}
- /// Handle super constructor invocation.
- @override
- void handleSuperConstructorInvoke(ast.Send node) {
- Selector selector = elements.getSelector(node);
- Element element = elements[node];
- if (selector.applies(element, compiler.world)) {
- generateSuperInvoke(node, element);
- } else {
- generateWrongArgumentCountError(node, element, node.arguments);
- }
- }
-
@override
void visitUnresolvedSuperIndex(
ast.Send node,
@@ -4575,6 +4586,20 @@
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);
@@ -4760,7 +4785,7 @@
return pop();
}
- handleNewSend(ast.NewExpression node) {
+ void handleNewSend(ast.NewExpression node) {
ast.Send send = node.send;
generateIsDeferredLoadedCheckOfSend(send);
@@ -4860,13 +4885,16 @@
}
// TODO(5347): Try to avoid the need for calling [implementation] before
// calling [makeStaticArgumentList].
- if (!callStructure.signatureApplies(constructor.implementation)) {
+ constructorImplementation = constructor.implementation;
+ if (constructorImplementation.isErroneous ||
+ !callStructure.signatureApplies(
+ constructorImplementation.functionSignature)) {
generateWrongArgumentCountError(send, constructor, send.arguments);
return;
}
inputs.addAll(makeStaticArgumentList(callStructure,
send.arguments,
- constructor.implementation));
+ constructorImplementation));
TypeMask elementType = computeType(constructor);
if (isFixedListConstructorCall) {
@@ -5427,7 +5455,12 @@
}
@override
- handleNewExpression(ast.NewExpression node) {
+ 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];
final bool isSymbolConstructor = element == compiler.symbolConstructor;
if (!Elements.isErroneous(element)) {
@@ -5463,6 +5496,17 @@
}
}
+ @override
+ void errorNonConstantConstructorInvoke(
+ ast.NewExpression node,
+ Element element,
+ DartType type,
+ ast.NodeList arguments,
+ CallStructure callStructure,
+ _) {
+ bulkHandleNew(node);
+ }
+
void pushInvokeDynamic(ast.Node node,
Selector selector,
TypeMask mask,
@@ -5690,6 +5734,369 @@
}
@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.Send 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.Send node,
+ Element 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.Send node,
+ Element element,
+ MethodElement setter,
+ ast.Node index,
+ IncDecOperator operator,
+ _) {
+ handleSuperSendSet(node);
+ }
+
+ @override
+ void visitUnresolvedSuperGetterIndexPostfix(
+ ast.Send node,
+ Element element,
+ MethodElement setter,
+ ast.Node index,
+ IncDecOperator operator,
+ _) {
+ handleSuperSendSet(node);
+ }
+
+ @override
+ void visitUnresolvedSuperSetterIndexPrefix(
+ ast.Send node,
+ MethodElement indexFunction,
+ Element element,
+ ast.Node index,
+ IncDecOperator operator,
+ _) {
+ handleSuperSendSet(node);
+ }
+
+ @override
+ void visitUnresolvedSuperSetterIndexPostfix(
+ ast.Send 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.Send node,
+ Element element,
+ MethodElement setter,
+ ast.Node index,
+ AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
+ handleSuperSendSet(node);
+ }
+
+ @override
+ void visitUnresolvedSuperSetterCompoundIndexSet(
+ ast.Send node,
+ MethodElement getter,
+ Element element,
+ ast.Node index,
+ AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
+ handleSuperSendSet(node);
+ }
+
+ @override
+ void visitUnresolvedSuperCompoundIndexSet(
+ ast.Send 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.Send node,
+ Element element,
+ IncDecOperator operator,
+ _) {
+ handleSuperSendSet(node);
+ }
+
+ @override
+ void visitUnresolvedSuperPostfix(
+ ast.Send 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,
+ FunctionElement method,
+ AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
+ handleSuperSendSet(node);
+ }
+
+ @override
+ void visitUnresolvedSuperGetterCompound(
+ ast.Send node,
+ Element element,
+ MethodElement setter,
+ AssignmentOperator operator,
+ ast.Node rhs,
+ _) {
+ handleSuperSendSet(node);
+ }
+
+ @override
+ void visitUnresolvedSuperSetterCompound(
+ ast.Send node,
+ MethodElement 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,
@@ -5699,6 +6106,40 @@
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) {
@@ -6108,27 +6549,36 @@
}
@override
- handleSendSet(ast.SendSet node) {
- ast.Operator op = node.assignmentOperator;
- generateIsDeferredLoadedCheckOfSend(node);
- Element element = elements[node];
- if (!Elements.isUnresolved(element) && element.impliesType) {
- ast.Identifier selector = node.selector;
- generateThrowNoSuchMethod(node, selector.source,
- argumentNodes: node.arguments);
- } else if (node.isSuperCall) {
- handleSuperSendSet(node);
- } else if (node.isIndex) {
- handleIndexSendSet(node);
- } else if ("=" == op.source) {
- internalError(node, "Unexpected assignment.");
- } else if (identical(op.source, "is")) {
- compiler.internalError(op, "is-operator as SendSet.");
- } else {
- assert("++" == op.source || "--" == op.source ||
- node.assignmentOperator.source.endsWith("="));
- handleCompoundSendSet(node);
- }
+ void handleDynamicCompounds(
+ ast.Send node,
+ ast.Node receiver,
+ CompoundRhs rhs,
+ Selector getterSelector,
+ Selector setterSelector,
+ _) {
+ 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);
}
void visitLiteralInt(ast.LiteralInt node) {
@@ -7571,6 +8021,80 @@
localsHandler.updateLocal(returnLocal, value);
}
}
+
+ @override
+ void handleTypeLiteralConstantCompounds(
+ ast.SendSet node,
+ ConstantExpression constant,
+ CompoundRhs rhs,
+ _) {
+ if (rhs.operator.kind == BinaryOperatorKind.IF_NULL) {
+ handleCompoundSendSet(node);
+ } else {
+ 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 errorInvalidAssert(
+ ast.Send node,
+ ast.NodeList arguments,
+ _) {
+ 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);
+ }
}
/**
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index c588a00..2524fdf 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -2136,9 +2136,10 @@
Element element = node.element;
assert(element.isFunction || element.isField);
if (element.isFunction) {
- push(backend.emitter.isolateStaticClosureAccess(node.element));
+ push(backend.emitter.isolateStaticClosureAccess(element));
+ registry.registerGetOfStaticFunction(element);
} else {
- push(backend.emitter.staticFieldAccess(node.element));
+ push(backend.emitter.staticFieldAccess(element));
}
registry.registerStaticUse(element);
}
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index a40d75e..c1d4dac 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -25,13 +25,14 @@
import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
import '../native/native.dart' as native;
import '../resolution/operators.dart';
+import '../resolution/semantic_visitor.dart';
import '../tree/tree.dart' as ast;
import '../types/types.dart';
import '../types/constants.dart' show computeTypeMask;
import '../universe/universe.dart';
import '../util/util.dart';
import '../js/rewrite_async.dart';
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart';
+import 'package:js_runtime/shared/embedded_names.dart';
part 'builder.dart';
part 'codegen.dart';
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
index 65ca23a..2b614ae 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
@@ -61,27 +61,41 @@
node.body = visitStatement(node.body);
}
- /// Statement to be executed next by natural fallthrough. Although fallthrough
- /// is not introduced in this phase, we need to reason about fallthrough when
- /// evaluating the benefit of swapping the branches of an [If].
- Statement fallthrough;
+ final FallthroughStack fallthrough = new FallthroughStack();
@override
void visitInnerFunction(FunctionDefinition node) {
new LogicalRewriter().rewrite(node);
}
- Statement visitLabeledStatement(LabeledStatement node) {
- Statement savedFallthrough = fallthrough;
- fallthrough = node.next;
- node.body = visitStatement(node.body);
- fallthrough = savedFallthrough;
- node.next = visitStatement(node.next);
- return node;
+ /// True if the given statement is equivalent to its fallthrough semantics.
+ ///
+ /// This means it will ultimately translate to an empty statement.
+ bool isFallthrough(Statement node) {
+ return node is Break && isFallthroughBreak(node) ||
+ node is Continue && isFallthroughContinue(node) ||
+ node is Return && isFallthroughReturn(node);
}
- bool isFallthroughBreak(Statement node) {
- return node is Break && node.target.binding.next == fallthrough;
+ bool isFallthroughBreak(Break node) {
+ Statement target = fallthrough.target;
+ return node.target.binding.next == target ||
+ target is Break && target.target == node.target;
+ }
+
+ bool isFallthroughContinue(Continue node) {
+ Statement target = fallthrough.target;
+ return node.target.binding == target ||
+ target is Continue && target.target == node.target;
+ }
+
+ bool isFallthroughReturn(Return node) {
+ return isNull(node.value) && fallthrough.target == null;
+ }
+
+ bool isTerminator(Statement node) {
+ return (node is Jump || node is Return) && !isFallthrough(node) ||
+ (node is ExpressionStatement && node.next is Unreachable);
}
Statement visitIf(If node) {
@@ -94,27 +108,64 @@
// In the tree language, empty statements do not exist yet, so we must check
// if one branch contains a break that can be eliminated by fallthrough.
- // Swap branches if then is a fallthrough break.
- if (isFallthroughBreak(node.thenStatement)) {
+ // Rewrite each branch and keep track of which ones might fall through.
+ int usesBefore = fallthrough.useCount;
+ node.thenStatement = visitStatement(node.thenStatement);
+ int usesAfterThen = fallthrough.useCount;
+ node.elseStatement = visitStatement(node.elseStatement);
+ bool thenHasFallthrough = (fallthrough.useCount > usesBefore);
+ bool elseHasFallthrough = (fallthrough.useCount > usesAfterThen);
+
+ // Determine which branch is most beneficial as 'then' branch.
+ const int THEN = 1;
+ const int NEITHER = 0;
+ const int ELSE = -1;
+ int bestThenBranch = NEITHER;
+ if (isFallthrough(node.thenStatement) &&
+ !isFallthrough(node.elseStatement)) {
+ // Put the empty statement in the 'else' branch.
+ // if (E) {} else {S} ==> if (!E) {S}
+ bestThenBranch = ELSE;
+ } else if (isFallthrough(node.elseStatement) &&
+ !isFallthrough(node.thenStatement)) {
+ // Keep the empty statement in the 'else' branch.
+ // if (E) {S} else {}
+ bestThenBranch = THEN;
+ } else if (thenHasFallthrough && !elseHasFallthrough) {
+ // Put abrupt termination in the 'then' branch to omit 'else'.
+ // if (E) {S1} else {S2; return v} ==> if (!E) {S2; return v}; S1
+ bestThenBranch = ELSE;
+ } else if (!thenHasFallthrough && elseHasFallthrough) {
+ // Keep abrupt termination in the 'then' branch to omit 'else'.
+ // if (E) {S1; return v}; S2
+ bestThenBranch = THEN;
+ } else if (isTerminator(node.elseStatement) &&
+ !isTerminator(node.thenStatement)) {
+ // Put early termination in the 'then' branch to reduce nesting depth.
+ // if (E) {S}; return v ==> if (!E) return v; S
+ bestThenBranch = ELSE;
+ } else if (isTerminator(node.thenStatement) &&
+ !isTerminator(node.elseStatement)) {
+ // Keep early termination in the 'then' branch to reduce nesting depth.
+ // if (E) {return v;} S
+ bestThenBranch = THEN;
+ }
+
+ // Swap branches if 'else' is better as 'then'
+ if (bestThenBranch == ELSE) {
node.condition = new Not(node.condition);
Statement tmp = node.thenStatement;
node.thenStatement = node.elseStatement;
node.elseStatement = tmp;
}
- // Can the else part be eliminated?
- // (Either due to the above swap or if the break was already there).
- bool emptyElse = isFallthroughBreak(node.elseStatement);
-
- node.condition = makeCondition(node.condition, true, liftNots: !emptyElse);
- node.thenStatement = visitStatement(node.thenStatement);
- node.elseStatement = visitStatement(node.elseStatement);
-
- // If neither branch is empty, eliminate a negation in the condition
+ // If neither branch is better, eliminate a negation in the condition
// if (!E) S1 else S2
// ==>
// if (E) S2 else S1
- if (!emptyElse && node.condition is Not) {
+ node.condition = makeCondition(node.condition, true,
+ liftNots: bestThenBranch == NEITHER);
+ if (bestThenBranch == NEITHER && node.condition is Not) {
node.condition = (node.condition as Not).operand;
Statement tmp = node.thenStatement;
node.thenStatement = node.elseStatement;
@@ -124,13 +175,52 @@
return node;
}
+ Statement visitLabeledStatement(LabeledStatement node) {
+ fallthrough.push(node.next);
+ node.body = visitStatement(node.body);
+ fallthrough.pop();
+ node.next = visitStatement(node.next);
+ return node;
+ }
+
+ Statement visitWhileTrue(WhileTrue node) {
+ fallthrough.push(node);
+ node.body = visitStatement(node.body);
+ fallthrough.pop();
+ return node;
+ }
+
Statement visitWhileCondition(WhileCondition node) {
+ fallthrough.push(node);
node.condition = makeCondition(node.condition, true, liftNots: false);
node.body = visitStatement(node.body);
+ fallthrough.pop();
node.next = visitStatement(node.next);
return node;
}
+ Statement visitBreak(Break node) {
+ if (isFallthroughBreak(node)) {
+ fallthrough.use();
+ }
+ return node;
+ }
+
+ Statement visitContinue(Continue node) {
+ if (isFallthroughContinue(node)) {
+ fallthrough.use();
+ }
+ return node;
+ }
+
+ Statement visitReturn(Return node) {
+ node.value = visitExpression(node.value);
+ if (isFallthroughReturn(node)) {
+ fallthrough.use();
+ }
+ return node;
+ }
+
Expression visitNot(Not node) {
return toBoolean(makeCondition(node.operand, false, liftNots: false));
}
@@ -391,6 +481,10 @@
return polarity ? e : new Not(e);
}
+ bool isNull(Expression e) {
+ return e is Constant && e.value.isNull;
+ }
+
bool isTrue(Expression e) {
return e is Constant && e.value.isTrue;
}
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index 68b8459..bad7690 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -307,7 +307,7 @@
// Handle constant assignments specially.
// They are always safe to propagate (though we should avoid duplication).
// Moreover, they should not prevent other expressions from propagating.
- if (assign.variable.readCount <= 1) {
+ if (assign.variable.readCount == 1) {
// A single-use constant should always be propagted to its use site.
constantEnvironment[assign.variable] = assign.value;
--assign.variable.writeCount;
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
index 0d663c5..6e39aae 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -320,7 +320,7 @@
// Introduce labels for continuations that need them.
int safeForInliningLengthOnEntry = safeForInlining.length;
for (cps_ir.Continuation continuation in node.continuations) {
- if (continuation.hasMultipleUses) {
+ if (continuation.hasMultipleUses || continuation.isRecursive) {
labels[continuation] = new Label();
} else {
safeForInlining.add(continuation);
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
index 3c937f1..ab549e2 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -1341,3 +1341,39 @@
return node;
}
}
+
+class FallthroughTarget {
+ final Statement target;
+ int useCount = 0;
+
+ FallthroughTarget(this.target);
+}
+
+/// A stack machine for tracking fallthrough while traversing the Tree IR.
+class FallthroughStack {
+ final List<FallthroughTarget> _stack =
+ <FallthroughTarget>[new FallthroughTarget(null)];
+
+ /// Set a new fallthrough target.
+ void push(Statement newFallthrough) {
+ _stack.add(new FallthroughTarget(newFallthrough));
+ }
+
+ /// Remove the current fallthrough target.
+ void pop() {
+ _stack.removeLast();
+ }
+
+ /// The current fallthrough target, or `null` if control will fall over
+ /// the end of the method.
+ Statement get target => _stack.last.target;
+
+ /// Number of uses of the current fallthrough target.
+ int get useCount => _stack.last.useCount;
+
+ /// Indicate that a statement will fall through to the current fallthrough
+ /// target.
+ void use() {
+ ++_stack.last.useCount;
+ }
+}
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
index ab4b5b0..caffb4a 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
@@ -328,7 +328,7 @@
@override
visitForeignStatement(ForeignStatement node) {
- printStatement(null, 'foreign');
+ printStatement(null, 'foreign ${node.codeTemplate.source}');
}
}
@@ -522,7 +522,7 @@
@override
String visitForeignExpression(ForeignExpression node) {
String arguments = node.arguments.map(visitExpression).join(', ');
- return 'Foreign "${node.codeTemplate}"($arguments)';
+ return 'Foreign "${node.codeTemplate.source}"($arguments)';
}
@override
diff --git a/pkg/compiler/lib/src/types/constants.dart b/pkg/compiler/lib/src/types/constants.dart
index 1bcc1be..27b21c8 100644
--- a/pkg/compiler/lib/src/types/constants.dart
+++ b/pkg/compiler/lib/src/types/constants.dart
@@ -1,114 +1,114 @@
-// 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 types.constants;
-
-import '../constants/values.dart';
-import '../dart2jslib.dart';
-import 'types.dart';
-import '../js_backend/js_backend.dart' show SyntheticConstantKind;
-
-/// Computes the [TypeMask] for the constant [value].
-TypeMask computeTypeMask(Compiler compiler, ConstantValue value) {
- return value.accept(const ConstantValueTypeMasks(), compiler);
-}
-
-class ConstantValueTypeMasks extends ConstantValueVisitor<TypeMask, Compiler> {
- const ConstantValueTypeMasks();
-
- @override
- TypeMask visitConstructed(ConstructedConstantValue constant,
- Compiler compiler) {
- if (compiler.backend.isInterceptorClass(constant.type.element)) {
- return compiler.typesTask.nonNullType;
- }
- return new TypeMask.nonNullExact(constant.type.element, compiler.world);
- }
-
- @override
- TypeMask visitDeferred(DeferredConstantValue constant, Compiler compiler) {
- return constant.referenced.accept(this, compiler);
- }
-
- @override
- TypeMask visitDouble(DoubleConstantValue constant, Compiler compiler) {
- // We have to distinguish -0.0 from 0, but for all practical purposes
- // -0.0 is an integer.
- // TODO(17235): this kind of special casing should only happen in the
- // backend.
- if (constant.isMinusZero &&
- compiler.backend.constantSystem.isInt(constant)) {
- return compiler.typesTask.uint31Type;
- }
- assert(!compiler.backend.constantSystem.isInt(constant));
- return compiler.typesTask.doubleType;
- }
-
- @override
- TypeMask visitSynthetic(SyntheticConstantValue constant, Compiler compiler) {
- switch (constant.kind) {
- case SyntheticConstantKind.DUMMY_INTERCEPTOR:
- return constant.payload;
- case SyntheticConstantKind.EMPTY_VALUE:
- return constant.payload;
- case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
- return compiler.typesTask.intType;
- case SyntheticConstantKind.NAME:
- return compiler.typesTask.stringType;
- default:
- compiler.internalError(compiler.currentElement,
- "Unexpected DummyConstantKind.");
- return null;
- }
- }
-
- @override
- TypeMask visitBool(BoolConstantValue constant, Compiler compiler) {
- return compiler.typesTask.boolType;
- }
-
- @override
- TypeMask visitFunction(FunctionConstantValue constant, Compiler compiler) {
- return compiler.typesTask.functionType;
- }
-
- @override
- TypeMask visitInt(IntConstantValue constant, Compiler compiler) {
- if (constant.isUInt31()) return compiler.typesTask.uint31Type;
- if (constant.isUInt32()) return compiler.typesTask.uint32Type;
- if (constant.isPositive()) return compiler.typesTask.positiveIntType;
- return compiler.typesTask.intType;
- }
-
- @override
- TypeMask visitInterceptor(InterceptorConstantValue constant,
- Compiler compiler) {
- return compiler.typesTask.nonNullType;
- }
-
- @override
- TypeMask visitList(ListConstantValue constant, Compiler compiler) {
- return compiler.typesTask.constListType;
- }
-
- @override
- TypeMask visitMap(MapConstantValue constant, Compiler compiler) {
- return compiler.typesTask.constMapType;
- }
-
- @override
- TypeMask visitNull(NullConstantValue constant, Compiler compiler) {
- return compiler.typesTask.nullType;
- }
-
- @override
- TypeMask visitString(StringConstantValue constant, Compiler compiler) {
- return compiler.typesTask.stringType;
- }
-
- @override
- TypeMask visitType(TypeConstantValue constant, Compiler compiler) {
- return compiler.typesTask.typeType;
- }
-}
+// 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 types.constants;
+
+import '../constants/values.dart';
+import '../dart2jslib.dart';
+import 'types.dart';
+import '../js_backend/js_backend.dart' show SyntheticConstantKind;
+
+/// Computes the [TypeMask] for the constant [value].
+TypeMask computeTypeMask(Compiler compiler, ConstantValue value) {
+ return value.accept(const ConstantValueTypeMasks(), compiler);
+}
+
+class ConstantValueTypeMasks extends ConstantValueVisitor<TypeMask, Compiler> {
+ const ConstantValueTypeMasks();
+
+ @override
+ TypeMask visitConstructed(ConstructedConstantValue constant,
+ Compiler compiler) {
+ if (compiler.backend.isInterceptorClass(constant.type.element)) {
+ return compiler.typesTask.nonNullType;
+ }
+ return new TypeMask.nonNullExact(constant.type.element, compiler.world);
+ }
+
+ @override
+ TypeMask visitDeferred(DeferredConstantValue constant, Compiler compiler) {
+ return constant.referenced.accept(this, compiler);
+ }
+
+ @override
+ TypeMask visitDouble(DoubleConstantValue constant, Compiler compiler) {
+ // We have to distinguish -0.0 from 0, but for all practical purposes
+ // -0.0 is an integer.
+ // TODO(17235): this kind of special casing should only happen in the
+ // backend.
+ if (constant.isMinusZero &&
+ compiler.backend.constantSystem.isInt(constant)) {
+ return compiler.typesTask.uint31Type;
+ }
+ assert(!compiler.backend.constantSystem.isInt(constant));
+ return compiler.typesTask.doubleType;
+ }
+
+ @override
+ TypeMask visitSynthetic(SyntheticConstantValue constant, Compiler compiler) {
+ switch (constant.kind) {
+ case SyntheticConstantKind.DUMMY_INTERCEPTOR:
+ return constant.payload;
+ case SyntheticConstantKind.EMPTY_VALUE:
+ return constant.payload;
+ case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
+ return compiler.typesTask.intType;
+ case SyntheticConstantKind.NAME:
+ return compiler.typesTask.stringType;
+ default:
+ compiler.internalError(compiler.currentElement,
+ "Unexpected DummyConstantKind.");
+ return null;
+ }
+ }
+
+ @override
+ TypeMask visitBool(BoolConstantValue constant, Compiler compiler) {
+ return compiler.typesTask.boolType;
+ }
+
+ @override
+ TypeMask visitFunction(FunctionConstantValue constant, Compiler compiler) {
+ return compiler.typesTask.functionType;
+ }
+
+ @override
+ TypeMask visitInt(IntConstantValue constant, Compiler compiler) {
+ if (constant.isUInt31()) return compiler.typesTask.uint31Type;
+ if (constant.isUInt32()) return compiler.typesTask.uint32Type;
+ if (constant.isPositive()) return compiler.typesTask.positiveIntType;
+ return compiler.typesTask.intType;
+ }
+
+ @override
+ TypeMask visitInterceptor(InterceptorConstantValue constant,
+ Compiler compiler) {
+ return compiler.typesTask.nonNullType;
+ }
+
+ @override
+ TypeMask visitList(ListConstantValue constant, Compiler compiler) {
+ return compiler.typesTask.constListType;
+ }
+
+ @override
+ TypeMask visitMap(MapConstantValue constant, Compiler compiler) {
+ return compiler.typesTask.constMapType;
+ }
+
+ @override
+ TypeMask visitNull(NullConstantValue constant, Compiler compiler) {
+ return compiler.typesTask.nullType;
+ }
+
+ @override
+ TypeMask visitString(StringConstantValue constant, Compiler compiler) {
+ return compiler.typesTask.stringType;
+ }
+
+ @override
+ TypeMask visitType(TypeConstantValue constant, Compiler compiler) {
+ return compiler.typesTask.typeType;
+ }
+}
diff --git a/pkg/compiler/lib/src/universe/universe.dart b/pkg/compiler/lib/src/universe/universe.dart
index 8af7763..28715e6 100644
--- a/pkg/compiler/lib/src/universe/universe.dart
+++ b/pkg/compiler/lib/src/universe/universe.dart
@@ -421,9 +421,7 @@
return match(other);
}
- bool signatureApplies(FunctionElement function) {
- if (Elements.isUnresolved(function)) return false;
- FunctionSignature parameters = function.functionSignature;
+ bool signatureApplies(FunctionSignature parameters) {
if (argumentCount > parameters.parameterCount) return false;
int requiredParameterCount = parameters.requiredParameterCount;
int optionalParameterCount = parameters.optionalParameterCount;
@@ -529,6 +527,9 @@
ConstructorElement callee,
/*T*/ compileArgument(ParameterElement element),
/*T*/ compileConstant(ParameterElement element)) {
+ assert(invariant(caller, !callee.isErroneous,
+ message: "Cannot compute arguments to erroneous constructor: "
+ "$caller calling $callee."));
FunctionSignature signature = caller.functionSignature;
Map<Node, ParameterElement> mapping = <Node, ParameterElement>{};
@@ -572,7 +573,7 @@
}
CallStructure callStructure =
new CallStructure(signature.parameterCount, namedParameters);
- if (!callStructure.signatureApplies(callee)) {
+ if (!callStructure.signatureApplies(signature)) {
return false;
}
list.addAll(callStructure.makeArgumentsList(
@@ -853,7 +854,8 @@
}
bool signatureApplies(FunctionElement function) {
- return callStructure.signatureApplies(function);
+ if (Elements.isUnresolved(function)) return false;
+ return callStructure.signatureApplies(function.functionSignature);
}
bool sameNameHack(Element element, World world) {
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart
index a15b716..215bfa5 100644
--- a/pkg/compiler/lib/src/use_unused_api.dart
+++ b/pkg/compiler/lib/src/use_unused_api.dart
@@ -290,7 +290,9 @@
}
useSemanticVisitor() {
- new semantic_visitor.BulkSendVisitor().apply(null, null);
+ new semantic_visitor.BulkSendVisitor()
+ ..apply(null, null)
+ ..visitSuperFieldFieldCompound(null, null, null, null, null, null);
new semantic_visitor.TraversalVisitor(null).apply(null, null);
new semantic_visitor.BulkDeclarationVisitor().apply(null, null);
}
diff --git a/pkg/compiler/lib/src/warnings.dart b/pkg/compiler/lib/src/warnings.dart
index eb32045..f144262 100644
--- a/pkg/compiler/lib/src/warnings.dart
+++ b/pkg/compiler/lib/src/warnings.dart
@@ -640,10 +640,11 @@
"Not a compile-time constant.");
static const MessageKind DEFERRED_COMPILE_TIME_CONSTANT = const MessageKind(
- "A Deferred value cannot be used as a compile-time constant.");
+ "A deferred value cannot be used as a compile-time constant.");
static const MessageKind DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION =
- const MessageKind("A deferred class cannot be used to create a"
+ const MessageKind(
+ "A deferred class cannot be used to create a "
"compile-time constant.");
static const MessageKind CYCLIC_COMPILE_TIME_CONSTANTS = const MessageKind(
@@ -2203,7 +2204,7 @@
static const MessageKind PREAMBLE = const MessageKind(
"When run on the command-line, the compiled output might"
" require a preamble file located in:\n"
- " <sdk>/lib/_internal/compiler/js_lib/preambles.");
+ " <sdk>/lib/_internal/js_runtime/lib/preambles.");
static const MessageKind INVALID_SYNC_MODIFIER = const MessageKind(
"Invalid modifier 'sync'.",
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
new file mode 100644
index 0000000..a078492
--- /dev/null
+++ b/pkg/compiler/pubspec.yaml
@@ -0,0 +1,23 @@
+# This pubspec is currently mainly used to make it easier to develop on dart2js
+# by making it a standalone package.
+name: compiler
+#version: do-not-upload
+dependencies:
+ package_config: ^0.0.4
+ js_ast:
+ path: ../js_ast
+ js_runtime:
+ path: ../../sdk/lib/_internal/js_runtime
+ sdk_library_metadata:
+ path: ../../sdk/lib/_internal/sdk_library_metadata
+
+# Uncomment if running gclient, so you can depend directly on the downloaded
+# versions of dart2js's transitive dependencies:
+#
+# dependency_overrides:
+# package_config:
+# path: ../../third_party/pkg/package_config
+# path:
+# path: ../../third_party/pkg/path
+# charcode:
+# path: ../../third_party/pkg/charcode
diff --git a/pkg/compiler/samples/darttags/darttags.dart b/pkg/compiler/samples/darttags/darttags.dart
index d675463..0653a09 100644
--- a/pkg/compiler/samples/darttags/darttags.dart
+++ b/pkg/compiler/samples/darttags/darttags.dart
@@ -32,7 +32,7 @@
import 'dart:mirrors';
-import 'package:_internal/libraries.dart'
+import 'package:sdk_library_metadata/libraries.dart'
show LIBRARIES, LibraryInfo;
import 'package:compiler/src/mirrors/analyze.dart'
diff --git a/pkg/compiler/samples/jsonify/jsonify.dart b/pkg/compiler/samples/jsonify/jsonify.dart
index 54a6e18..0d0c7e6 100644
--- a/pkg/compiler/samples/jsonify/jsonify.dart
+++ b/pkg/compiler/samples/jsonify/jsonify.dart
@@ -7,7 +7,7 @@
import 'dart:mirrors';
-import 'package:_internal/libraries.dart'
+import 'package:sdk_library_metadata/libraries.dart'
show LIBRARIES, LibraryInfo;
import '../../lib/src/mirrors/analyze.dart'
diff --git a/pkg/dart2js_incremental/lib/library_updater.dart b/pkg/dart2js_incremental/lib/library_updater.dart
index 6b08832..924f2f4 100644
--- a/pkg/dart2js_incremental/lib/library_updater.dart
+++ b/pkg/dart2js_incremental/lib/library_updater.dart
@@ -73,7 +73,7 @@
import 'package:compiler/src/js_emitter/program_builder.dart' show
ProgramBuilder;
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
+import 'package:js_runtime/shared/embedded_names.dart'
as embeddedNames;
import 'package:compiler/src/js_backend/js_backend.dart' show
diff --git a/pkg/docgen/lib/src/exports/libraries.dart b/pkg/docgen/lib/src/exports/libraries.dart
index 00163df..7e48c79 100644
--- a/pkg/docgen/lib/src/exports/libraries.dart
+++ b/pkg/docgen/lib/src/exports/libraries.dart
@@ -4,4 +4,4 @@
library docgen.exports.libraries;
-export '../../../../../sdk/lib/_internal/libraries.dart';
+export 'package:sdk_library_metadata/libraries.dart';
diff --git a/pkg/js_ast/test/printer_callback_test.dart b/pkg/js_ast/test/printer_callback_test.dart
index 1a1db35..b4ff074 100644
--- a/pkg/js_ast/test/printer_callback_test.dart
+++ b/pkg/js_ast/test/printer_callback_test.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// Note: This test relies on LF line endings in the source file.
+
// Test that JS printer callbacks occur when expected.
library js_ast.printer.callback_test;
diff --git a/pkg/pkg.gyp b/pkg/pkg.gyp
index 4afbb19..771152c 100644
--- a/pkg/pkg.gyp
+++ b/pkg/pkg.gyp
@@ -19,7 +19,8 @@
'"../third_party/pkg_tested"])',
'<!@(["python", "../tools/list_pkg_directories.py", '
'"../runtime"])',
- '../sdk/lib/_internal',
+ '../sdk/lib/_internal/js_runtime/lib',
+ '../sdk/lib/_internal/sdk_library_metadata/lib',
'../site/try',
],
'outputs': [
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 86cc7f1..5bb70dc 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -150,7 +150,6 @@
analyzer/test/*: PubGetError
[ $compiler == dart2js && $cps_ir ]
-analysis_server/tool/spec/check_all_test: Crash # Invalid argument(s)
analyzer/test/cancelable_future_test: Crash # Invalid argument(s)
analyzer/test/enum_test: Crash # Invalid argument(s)
analyzer/test/file_system/memory_file_system_test: Crash # Invalid argument(s)
@@ -162,8 +161,7 @@
analyzer/test/generated/element_test: Crash # Invalid argument(s)
analyzer/test/generated/incremental_resolver_test: Crash # Invalid argument(s)
analyzer/test/generated/incremental_scanner_test: Crash # Invalid argument(s)
-analyzer/test/generated/java_core_test: Crash # Invalid argument(s)
-analyzer/test/generated/java_io_test: Crash # Invalid argument(s)
+analyzer/test/generated/java_core_test : RuntimeError # TypeError: receiver.get$_nums is not a function
analyzer/test/generated/non_error_resolver_test: Crash # Invalid argument(s)
analyzer/test/generated/parser_test: Crash # Invalid argument(s)
analyzer/test/generated/resolver_test: Crash # Invalid argument(s)
@@ -190,10 +188,9 @@
analyzer/test/src/task/model_test: Crash # Invalid argument(s)
analyzer/test/src/util/asserts_test: Crash # Invalid argument(s)
analyzer/test/src/util/lru_map_test: Crash # Invalid argument(s)
-fixnum/test/int_32_test: Crash # Invalid argument(s)
-fixnum/test/int_64_test: Crash # Invalid argument(s)
-js_ast/test/printer_callback_test: RuntimeError # Please triage this failure.
-microlytics/test/dart_microlytics_test: RuntimeError # Please triage this failure.
+fixnum/test/int_32_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+fixnum/test/int_64_test : RuntimeError # TypeError: receiver.get$_nums is not a function
typed_data/test/typed_buffers_test/01: Crash # Invalid argument(s)
-typed_data/test/typed_buffers_test/none: Crash # Invalid argument(s)
-typed_mock/test/typed_mock_test: Crash # Invalid argument(s)
+typed_data/test/typed_buffers_test/none : RuntimeError # TypeError: receiver.get$_nums is not a function
+typed_mock/test/typed_mock_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+analyzer/test/generated/source_factory_test : Crash # Invalid argument(s)
diff --git a/pkg/pkgbuild.status b/pkg/pkgbuild.status
index 7484d4a..a2c33a4 100644
--- a/pkg/pkgbuild.status
+++ b/pkg/pkgbuild.status
@@ -8,16 +8,20 @@
[ $use_repository_packages ]
pkg/analyzer: PubGetError
+pkg/compiler: PubGetError # Issue 23750
samples/third_party/angular_todo: Fail # angular needs to be updated
samples/third_party/todomvc_performance: Skip # dependencies are not in the repo
+third_party/pkg/package_config: PubGetError # Issue 23750
[ $use_public_packages ]
+pkg/compiler: PubGetError # Issue 23750
samples/third_party/angular_todo: Pass, Slow
third_party/pkg/async_await: Skip # Uses expect package.
samples/third_party/todomvc_performance: Pass, Slow
[ $builder_tag == russian ]
samples/third_party/angular_todo: Fail # Issue 16356
+samples/third_party/dromaeo: Fail # Issue 23750
[ $use_public_packages && $system == windows ]
samples/third_party/todomvc_performance: Fail # Issue 18086
diff --git a/runtime/lib/bigint.dart b/runtime/lib/bigint.dart
index adfb0db..ce151cf 100644
--- a/runtime/lib/bigint.dart
+++ b/runtime/lib/bigint.dart
@@ -267,7 +267,9 @@
return r_used;
}
- // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n.
+ // r_digits[ds..x_used+ds] = x_digits[0..x_used-1] << (n % _DIGIT_BITS)
+ // where ds = ceil(n / _DIGIT_BITS)
+ // Doesn't clear digits below ds.
static void _lsh(Uint32List x_digits, int x_used, int n,
Uint32List r_digits) {
final ds = n ~/ _DIGIT_BITS;
@@ -292,7 +294,7 @@
return _dlShift(ds);
}
var r_used = _used + ds + 1;
- var r_digits = new Uint32List(r_used + 2 + (r_used & 1)); // +2 for 64-bit.
+ var r_digits = new Uint32List(r_used + 2 - (r_used & 1)); // for 64-bit.
_lsh(_digits, _used, n, r_digits);
return new _Bigint(_neg, r_used, r_digits);
}
@@ -307,7 +309,7 @@
return _dlShiftDigits(x_digits, x_used, ds, r_digits);
}
var r_used = x_used + ds + 1;
- assert(r_digits.length >= r_used + 2 + (r_used & 1)); // +2 for 64-bit.
+ assert(r_digits.length >= r_used + 2 - (r_used & 1)); // for 64-bit.
_lsh(x_digits, x_used, n, r_digits);
var i = ds;
while (--i >= 0) {
@@ -1404,7 +1406,7 @@
if (e == 0) return 1;
m = m._toBigint();
final m_used = m._used;
- final m_used2p4 = 2*m_used + 4;
+ final m_used2p4 = 2 * m_used + 4;
final e_bitlen = e.bitLength;
if (e_bitlen <= 0) return 1;
final bool cannotUseMontgomery = m.isEven || _abs() >= m;
@@ -1562,7 +1564,7 @@
if (((x_used == 1) && (x_digits[0] == 1)) ||
((y_used == 1) && (y_digits[0] == 1))) return 1;
bool xy_cloned = false;
- while (x.isEven && y.isEven) {
+ while (((x_digits[0] & 1) == 0) && ((y_digits[0] & 1) == 0)) {
_rsh(x_digits, x_used, 1, x_digits);
_rsh(y_digits, y_used, 1, y_digits);
s++;
@@ -1583,7 +1585,7 @@
}
}
var u_digits = _cloneDigits(x_digits, 0, x_used, m_len);
- var v_digits = _cloneDigits(y_digits, 0, y_used, m_len);
+ var v_digits = _cloneDigits(y_digits, 0, y_used, m_len + 2); // +2 for lsh.
final bool ac = (x_digits[0] & 1) == 0;
// Variables a, b, c, and d require one more digit.
@@ -1747,7 +1749,7 @@
}
if (!inv) {
if (s > 0) {
- _lsh(v_digits, m_used, s, v_digits);
+ m_used = _lShiftDigits(v_digits, m_used, s, v_digits);
}
return new _Bigint(false, m_used, v_digits)._toValidInt();
}
diff --git a/runtime/lib/core_patch.dart b/runtime/lib/core_patch.dart
index 2a45ae7..0358cc2 100644
--- a/runtime/lib/core_patch.dart
+++ b/runtime/lib/core_patch.dart
@@ -205,3 +205,27 @@
}
}
}
+
+patch class Resource {
+ /* patch */ const factory Resource(String uri) = _Resource;
+}
+
+class _Resource implements Resource {
+ final String _location;
+
+ const _Resource(String uri) : _location = uri;
+
+ Uri get uri => Uri.base.resolve(_location);
+
+ Stream<List<int>> openRead() {
+ throw new UnimplementedError("openRead");
+ }
+
+ Future<List<int>> readAsBytes() {
+ throw new UnimplementedError("readAsBytes");
+ }
+
+ Future<String> readAsString({Encoding encoding}) {
+ throw new UnimplementedError("readAsString");
+ }
+}
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index 86c4a5a..ce44229 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.dart
@@ -21,4 +21,4 @@
final bool is64Bit = _inquireIs64Bit();
-bool _inquireIs64Bit() native "Internal_inquireIs64Bit";
\ No newline at end of file
+bool _inquireIs64Bit() native "Internal_inquireIs64Bit";
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index e43b658..5a25ea3 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -24,8 +24,10 @@
export 'package:observatory/src/elements/heap_map.dart';
export 'package:observatory/src/elements/heap_profile.dart';
export 'package:observatory/src/elements/heap_snapshot.dart';
+export 'package:observatory/src/elements/icdata_view.dart';
export 'package:observatory/src/elements/instance_ref.dart';
export 'package:observatory/src/elements/instance_view.dart';
+export 'package:observatory/src/elements/instructions_view.dart';
export 'package:observatory/src/elements/io_view.dart';
export 'package:observatory/src/elements/isolate_reconnect.dart';
export 'package:observatory/src/elements/isolate_ref.dart';
@@ -38,6 +40,7 @@
export 'package:observatory/src/elements/nav_bar.dart';
export 'package:observatory/src/elements/object_common.dart';
export 'package:observatory/src/elements/object_view.dart';
+export 'package:observatory/src/elements/objectpool_view.dart';
export 'package:observatory/src/elements/observatory_application.dart';
export 'package:observatory/src/elements/observatory_element.dart';
export 'package:observatory/src/elements/ports.dart';
diff --git a/runtime/observatory/lib/elements.html b/runtime/observatory/lib/elements.html
index 0eeabc9..c64656a 100644
--- a/runtime/observatory/lib/elements.html
+++ b/runtime/observatory/lib/elements.html
@@ -20,6 +20,8 @@
<link rel="import" href="src/elements/instance_ref.html">
<link rel="import" href="src/elements/instance_view.html">
<link rel="import" href="src/elements/io_view.html">
+<link rel="import" href="src/elements/icdata_view.html">
+<link rel="import" href="src/elements/instructions_view.html">
<link rel="import" href="src/elements/isolate_reconnect.html">
<link rel="import" href="src/elements/isolate_ref.html">
<link rel="import" href="src/elements/isolate_summary.html">
@@ -31,6 +33,7 @@
<link rel="import" href="src/elements/nav_bar.html">
<link rel="import" href="src/elements/object_common.html">
<link rel="import" href="src/elements/object_view.html">
+<link rel="import" href="src/elements/objectpool_view.html">
<link rel="import" href="src/elements/observatory_application.html">
<link rel="import" href="src/elements/observatory_element.html">
<link rel="import" href="src/elements/ports.html">
diff --git a/runtime/observatory/lib/src/elements/class_view.html b/runtime/observatory/lib/src/elements/class_view.html
index 10f67fc..ad85d16 100644
--- a/runtime/observatory/lib/src/elements/class_view.html
+++ b/runtime/observatory/lib/src/elements/class_view.html
@@ -196,7 +196,7 @@
</template>
<template if="{{ mostRetained != null }}">
<template repeat="{{ most in mostRetained }}">
- {{ most.retainedSize | formatSize }}<instance-ref ref="{{ most }}"></instance-ref><br>
+ {{ most.retainedSize | formatSize }}<any-service-ref ref="{{ most }}"></any-service-ref><br>
</template>
</template>
</div>
diff --git a/runtime/observatory/lib/src/elements/code_view.dart b/runtime/observatory/lib/src/elements/code_view.dart
index 4995996..7c6ddef 100644
--- a/runtime/observatory/lib/src/elements/code_view.dart
+++ b/runtime/observatory/lib/src/elements/code_view.dart
@@ -197,9 +197,10 @@
}
void _fillDisassemblyDOMRow(TableRowElement tr, int rowIndex) {
- var row = disassemblyTable.rows[rowIndex];
- for (var i = 0; i < row.values.length; i++) {
- var cell = tr.children[i];
+ final row = disassemblyTable.rows[rowIndex];
+ final n = row.values.length;
+ for (var i = 0; i < n; i++) {
+ final cell = tr.children[i];
cell.title = row.values[i].toString();
cell.text = row.values[i].toString();
}
@@ -226,11 +227,13 @@
}
assert(tableBody.children.length == disassemblyTable.sortedRows.length);
+
// Fill table.
- for (var i = 0; i < disassemblyTable.sortedRows.length; i++) {
+ var i = 0;
+ for (var tr in tableBody.children) {
var rowIndex = disassemblyTable.sortedRows[i];
- var tr = tableBody.children[i];
_fillDisassemblyDOMRow(tr, rowIndex);
+ i++;
}
}
diff --git a/runtime/observatory/lib/src/elements/code_view.html b/runtime/observatory/lib/src/elements/code_view.html
index ddb3d98..7b1c057 100644
--- a/runtime/observatory/lib/src/elements/code_view.html
+++ b/runtime/observatory/lib/src/elements/code_view.html
@@ -55,6 +55,10 @@
<template if="{{ !(code.isDartCode && code.isOptimized) }}">
<h1>Code for {{ code.name }}</h1>
</template>
+ <object-common object="{{ code }}"></object-common>
+
+ <br><br>
+
<div class="memberList">
<div class="memberItem">
<div class="memberName">Kind</div>
@@ -107,32 +111,34 @@
</template>
</div>
</div>
- <hr>
- <table id="inlineRangeTable" class="table">
- <thead id="inlineRangeTableHead">
- <tr>
- <th class="address" title="Address range">Address Range</th>
- <th class="tick" title="Inclusive">Inclusive</th>
- <th class="tick" title="Exclusive">Exclusive</th>
- <th title="Functions">Functions</th>
- </tr>
- </thead>
- <tbody class="monospace" id="inlineRangeTableBody">
- </tbody>
- </table>
- <hr>
- <table id="disassemblyTable" class="table">
- <thead id="disassemblyTableHead">
- <tr>
- <th class="address" title="Address">Address</th>
- <th class="tick" title="Inclusive">Inclusive</th>
- <th class="tick" title="Exclusive">Exclusive</th>
- <th class="disassembly" title="Disassembly">Disassembly</th>
- </tr>
- </thead>
- <tbody class="monospace" id="disassemblyTableBody">
- </tbody>
- </table>
+ <div class="content-centered-big">
+ <hr>
+ <table id="inlineRangeTable" class="table">
+ <thead id="inlineRangeTableHead">
+ <tr>
+ <th class="address" title="Address range">Address Range</th>
+ <th class="tick" title="Inclusive">Inclusive</th>
+ <th class="tick" title="Exclusive">Exclusive</th>
+ <th title="Functions">Functions</th>
+ </tr>
+ </thead>
+ <tbody class="monospace" id="inlineRangeTableBody">
+ </tbody>
+ </table>
+ <hr>
+ <table id="disassemblyTable" class="table">
+ <thead id="disassemblyTableHead">
+ <tr>
+ <th class="address" title="Address">Address</th>
+ <th class="tick" title="Inclusive">Inclusive</th>
+ <th class="tick" title="Exclusive">Exclusive</th>
+ <th class="disassembly" title="Disassembly">Disassembly</th>
+ </tr>
+ </thead>
+ <tbody class="monospace" id="disassemblyTableBody">
+ </tbody>
+ </table>
+ </div>
<view-footer></view-footer>
</template>
</polymer-element>
diff --git a/runtime/observatory/lib/src/elements/function_ref.dart b/runtime/observatory/lib/src/elements/function_ref.dart
index 53920b9..1f4d06f 100644
--- a/runtime/observatory/lib/src/elements/function_ref.dart
+++ b/runtime/observatory/lib/src/elements/function_ref.dart
@@ -26,24 +26,20 @@
if (ref == null) {
return;
}
- if (function.isDart) {
- if (qualified) {
- if (function.dartOwner is ServiceFunction) {
- var functionRef = new Element.tag('function-ref');
- functionRef.ref = function.dartOwner;
- functionRef.qualified = true;
- shadowRoot.children.add(functionRef);
- insertTextSpanIntoShadowRoot('.');
- } else if (function.dartOwner is Class) {
- var classRef = new Element.tag('class-ref');
- classRef.ref = function.dartOwner;
- shadowRoot.children.add(classRef);
- insertTextSpanIntoShadowRoot('.');
- }
+ if (qualified) {
+ if (function.dartOwner is ServiceFunction) {
+ var functionRef = new Element.tag('function-ref');
+ functionRef.ref = function.dartOwner;
+ functionRef.qualified = true;
+ shadowRoot.children.add(functionRef);
+ insertTextSpanIntoShadowRoot('.');
+ } else if (function.dartOwner is Class) {
+ var classRef = new Element.tag('class-ref');
+ classRef.ref = function.dartOwner;
+ shadowRoot.children.add(classRef);
+ insertTextSpanIntoShadowRoot('.');
}
- insertLinkIntoShadowRoot(name, url, hoverText);
- } else {
- insertTextSpanIntoShadowRoot(name);
}
+ insertLinkIntoShadowRoot(name, url, hoverText);
}
}
diff --git a/runtime/observatory/lib/src/elements/function_view.html b/runtime/observatory/lib/src/elements/function_view.html
index 4b75325..fee4cb4 100644
--- a/runtime/observatory/lib/src/elements/function_view.html
+++ b/runtime/observatory/lib/src/elements/function_view.html
@@ -27,7 +27,6 @@
<div class="content">
<h1>function {{ function.qualifiedName }}</h1>
-
<div class="memberList">
<div class="memberItem">
<div class="memberName">kind</div>
@@ -74,6 +73,12 @@
</div>
</template>
<div class="memberItem">
+ <div class="memberName">ic data array</div>
+ <div class="memberValue">
+ <instance-ref ref="{{ function.icDataArray }}"></instance-ref>
+ </div>
+ </div>
+ <div class="memberItem">
<div class="memberName">deoptimizations</div>
<div class="memberValue">{{ function.deoptimizations }}</div>
</div>
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
index 53b8a52..f75726f 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -65,7 +65,7 @@
percentNode.text = Utils.formatPercentNormalized(percentRetained);
percentNode.style.minWidth = '5em';
percentNode.style.textAlign = 'right';
- percentNode.title = "Retaining x of y.";
+ percentNode.title = "Percent of heap being retained";
percentNode.style.display = 'inline-block';
firstColumn.children.add(percentNode);
diff --git a/runtime/observatory/lib/src/elements/icdata_view.dart b/runtime/observatory/lib/src/elements/icdata_view.dart
new file mode 100644
index 0000000..d69f672
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/icdata_view.dart
@@ -0,0 +1,21 @@
+// 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 icdata_view;
+
+import 'dart:async';
+import 'observatory_element.dart';
+import 'package:observatory/service.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('icdata-view')
+class ICDataViewElement extends ObservatoryElement {
+ @published ICData icData;
+
+ ICDataViewElement.created() : super.created();
+
+ Future refresh() {
+ return icData.reload();
+ }
+}
diff --git a/runtime/observatory/lib/src/elements/icdata_view.html b/runtime/observatory/lib/src/elements/icdata_view.html
new file mode 100644
index 0000000..d31f14f
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/icdata_view.html
@@ -0,0 +1,63 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="class_ref.html">
+<link rel="import" href="error_view.html">
+<link rel="import" href="field_ref.html">
+<link rel="import" href="function_ref.html">
+<link rel="import" href="inbound_reference.html">
+<link rel="import" href="instance_ref.html">
+<link rel="import" href="observatory_element.html">
+<link rel="import" href="object_common.html">
+<link rel="import" href="nav_bar.html">
+<link rel="import" href="eval_link.html">
+
+<polymer-element name="icdata-view" extends="observatory-element">
+ <template>
+ <link rel="stylesheet" href="css/shared.css">
+ <nav-bar>
+ <top-nav-menu></top-nav-menu>
+ <vm-nav-menu vm="{{ icData.isolate.vm }}"></vm-nav-menu>
+ <isolate-nav-menu isolate="{{ icData.isolate }}"></isolate-nav-menu>
+ <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
+ <nav-refresh callback="{{ refresh }}"></nav-refresh>
+ </nav-bar>
+
+ <div class="content">
+ <object-common object="{{ icData }}"></object-common>
+
+ <br><br>
+
+ <div class="memberList">
+ <div class="memberItem">
+ <div class="memberName">selector</div>
+ <div class="memberValue">
+ {{ icData.selector }}
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">owner</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ icData.dartOwner }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">argumentsDescriptor</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ icData.argumentsDescriptor }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">entries</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ icData.entries }}"></any-service-ref>
+ </div>
+ </div>
+ </div>
+
+ </div>
+
+ <hr>
+ <view-footer></view-footer>
+ </template>
+</polymer-element>
+
+<script type="application/dart" src="icdata_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/instance_ref.html b/runtime/observatory/lib/src/elements/instance_ref.html
index 10782d5..d8a1def 100644
--- a/runtime/observatory/lib/src/elements/instance_ref.html
+++ b/runtime/observatory/lib/src/elements/instance_ref.html
@@ -42,6 +42,10 @@
</a>
</template>
+ <template if="{{ ref.isRegExp }}">
+ <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}({{ ref.pattern.valueAsString }})</em></a>
+ </template>
+
<template if="{{ ref.isPlainInstance }}">
<a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}</em></a>
<curly-block callback="{{ expander() }}">
diff --git a/runtime/observatory/lib/src/elements/instance_view.html b/runtime/observatory/lib/src/elements/instance_view.html
index 76a8bce..4e718d9 100644
--- a/runtime/observatory/lib/src/elements/instance_view.html
+++ b/runtime/observatory/lib/src/elements/instance_view.html
@@ -60,16 +60,6 @@
</div>
</template>
- <template if="{{ instance.isMirrorReference }}">
- <div class="memberItem">
- <div class="memberName">referent</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.referent }}">
- </any-service-ref>
- </div>
- </div>
- </template>
-
<template if="{{ instance.typeClass != null }}">
<div class="memberItem">
<div class="memberName">type class</div>
@@ -113,23 +103,6 @@
</div>
</template>
- <template if="{{ instance.isWeakProperty }}">
- <div class="memberItem">
- <div class="memberName">key</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.key }}">
- </any-service-ref>
- </div>
- </div>
- <div class="memberItem">
- <div class="memberName">value</div>
- <div class="memberValue">
- <any-service-ref ref="{{ instance.value }}">
- </any-service-ref>
- </div>
- </div>
- </template>
-
<div class="memberItem">
<div class="memberName">toString()</div>
<div class="memberValue">
@@ -228,6 +201,67 @@
</div>
</curly-block><br><br>
</template>
+
+ <template if="{{ instance.isRegExp }}">
+ <div class="memberList">
+ <div class="memberItem">
+ <div class="memberName">pattern</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.pattern }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">oneByteFunction</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.oneByteFunction }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">twoByteFunction</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.twoByteFunction }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">externalOneByteFunction</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.externalOneByteFunction }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">externalTwoByteFunction</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.externalTwoByteFunction }}"></any-service-ref>
+ </div>
+ </div>
+ </div>
+ </template>
+
+ <template if="{{ instance.isMirrorReference }}">
+ <div class="memberItem">
+ <div class="memberName">referent</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.referent }}">
+ </any-service-ref>
+ </div>
+ </div>
+ </template>
+
+ <template if="{{ instance.isWeakProperty }}">
+ <div class="memberItem">
+ <div class="memberName">key</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.key }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">value</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instance.value }}"></any-service-ref>
+ </div>
+ </div>
+ </template>
+
</div>
<div class="content-centered-big">
diff --git a/runtime/observatory/lib/src/elements/instructions_view.dart b/runtime/observatory/lib/src/elements/instructions_view.dart
new file mode 100644
index 0000000..e5c1fb2
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/instructions_view.dart
@@ -0,0 +1,21 @@
+// 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 instructions_view;
+
+import 'dart:async';
+import 'observatory_element.dart';
+import 'package:observatory/service.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('instructions-view')
+class InstructionsViewElement extends ObservatoryElement {
+ @published Instructions instructions;
+
+ InstructionsViewElement.created() : super.created();
+
+ Future refresh() {
+ return instructions.reload();
+ }
+}
diff --git a/runtime/observatory/lib/src/elements/instructions_view.html b/runtime/observatory/lib/src/elements/instructions_view.html
new file mode 100644
index 0000000..feb108c
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/instructions_view.html
@@ -0,0 +1,51 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="class_ref.html">
+<link rel="import" href="error_view.html">
+<link rel="import" href="field_ref.html">
+<link rel="import" href="function_ref.html">
+<link rel="import" href="inbound_reference.html">
+<link rel="import" href="instance_ref.html">
+<link rel="import" href="observatory_element.html">
+<link rel="import" href="object_common.html">
+<link rel="import" href="nav_bar.html">
+<link rel="import" href="eval_link.html">
+
+<polymer-element name="instructions-view" extends="observatory-element">
+ <template>
+ <link rel="stylesheet" href="css/shared.css">
+ <nav-bar>
+ <top-nav-menu></top-nav-menu>
+ <vm-nav-menu vm="{{ instructions.isolate.vm }}"></vm-nav-menu>
+ <isolate-nav-menu isolate="{{ instructions.isolate }}"></isolate-nav-menu>
+ <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
+ <nav-refresh callback="{{ refresh }}"></nav-refresh>
+ </nav-bar>
+
+ <div class="content">
+ <object-common object="{{ instructions }}"></object-common>
+
+ <br><br>
+
+ <div class="memberList">
+ <div class="memberItem">
+ <div class="memberName">code</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instructions.code }}"></any-service-ref>
+ </div>
+ </div>
+ <div class="memberItem">
+ <div class="memberName">objectPool</div>
+ <div class="memberValue">
+ <any-service-ref ref="{{ instructions.objectPool }}"></any-service-ref>
+ </div>
+ </div>
+ </div>
+
+ </div>
+
+ <hr>
+ <view-footer></view-footer>
+ </template>
+</polymer-element>
+
+<script type="application/dart" src="instructions_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/objectpool_view.dart b/runtime/observatory/lib/src/elements/objectpool_view.dart
new file mode 100644
index 0000000..9bc5a4e
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/objectpool_view.dart
@@ -0,0 +1,43 @@
+// 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 objectpool_view;
+
+import 'dart:async';
+import 'observatory_element.dart';
+import 'package:observatory/service.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('objectpool-view')
+class ObjectPoolViewElement extends ObservatoryElement {
+ @published ObjectPool pool;
+ @published List annotatedEntries;
+
+ ObjectPoolViewElement.created() : super.created();
+
+ bool isServiceObject(o) => o is ServiceObject;
+
+ void poolChanged(oldValue) {
+ annotateRawEntries();
+ }
+
+ Future annotateRawEntries() {
+ var tasks = pool.entries.map((entry) {
+ if (entry is int) {
+ var addr = entry.toRadixString(16);
+ return pool.isolate.getObjectByAddress(addr).then((result) {
+ return result is ServiceObject ? result : null;
+ });
+ } else {
+ return new Future.value(null);
+ }
+ });
+
+ return Future.wait(tasks).then((results) => annotatedEntries = results);
+ }
+
+ Future refresh() {
+ return pool.reload().then((_) => annotateRawEntries());
+ }
+}
diff --git a/runtime/observatory/lib/src/elements/objectpool_view.html b/runtime/observatory/lib/src/elements/objectpool_view.html
new file mode 100644
index 0000000..a928531
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/objectpool_view.html
@@ -0,0 +1,57 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="class_ref.html">
+<link rel="import" href="error_view.html">
+<link rel="import" href="field_ref.html">
+<link rel="import" href="function_ref.html">
+<link rel="import" href="inbound_reference.html">
+<link rel="import" href="instance_ref.html">
+<link rel="import" href="observatory_element.html">
+<link rel="import" href="object_common.html">
+<link rel="import" href="nav_bar.html">
+<link rel="import" href="eval_link.html">
+
+<polymer-element name="objectpool-view" extends="observatory-element">
+ <template>
+ <link rel="stylesheet" href="css/shared.css">
+ <nav-bar>
+ <top-nav-menu></top-nav-menu>
+ <vm-nav-menu vm="{{ pool.isolate.vm }}"></vm-nav-menu>
+ <isolate-nav-menu isolate="{{ pool.isolate }}"></isolate-nav-menu>
+ <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
+ <nav-refresh callback="{{ refresh }}"></nav-refresh>
+ </nav-bar>
+
+ <div class="content">
+ <object-common object="{{ pool }}"></object-common>
+
+ <br><br>
+
+ entries ({{ pool.entries.length }})
+ <div class="memberList">
+ <template repeat="{{ index in pool.entries.asMap().keys }}">
+ <div class="memberItem">
+ <div class="memberName">[{{ index }}]</div>
+ <div class="memberValue">
+ <template if="{{ isServiceObject(pool.entries[index]) }}">
+ <any-service-ref ref="{{ pool.entries[index] }}">
+ </any-service-ref>
+ </template>
+ <template if="{{ !isServiceObject(pool.entries[index]) }}">
+ 0x{{ pool.entries[index].toRadixString(16) }}
+ <template if="{{ annotatedEntries != null && annotatedEntries[index] != null }}">
+ (<any-service-ref ref="{{ annotatedEntries[index] }}"></any-service-ref>)
+ </template>
+ </template>
+ </div>
+ </div>
+ </template>
+ </div>
+
+ </div>
+
+ <hr>
+ <view-footer></view-footer>
+ </template>
+</polymer-element>
+
+<script type="application/dart" src="objectpool_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 791534f..66b125c 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -439,8 +439,12 @@
? script.tokenToLine(currentPos)
: null);
_currentCol = (currentPos != null
- ? (script.tokenToCol(currentPos) - 1) // make this 0-based.
+ ? (script.tokenToCol(currentPos))
: null);
+ if (_currentCol != null) {
+ _currentCol--; // make this 0-based.
+ }
+
_endLine = (endPos != null
? script.tokenToLine(endPos)
: script.lines.length + script.lineOffset);
@@ -564,6 +568,10 @@
var table = new DivElement();
table.classes.add("sourceTable");
+ if (_startLine == null || _endLine == null) {
+ return table;
+ }
+
annotationsCursor = 0;
int blankLineCount = 0;
diff --git a/runtime/observatory/lib/src/elements/service_ref.html b/runtime/observatory/lib/src/elements/service_ref.html
index 097e90c..839b4c5 100644
--- a/runtime/observatory/lib/src/elements/service_ref.html
+++ b/runtime/observatory/lib/src/elements/service_ref.html
@@ -9,13 +9,31 @@
<polymer-element name="object-ref" extends="service-ref">
<template><link rel="stylesheet" href="css/shared.css">
- <template if="{{ nameIsEmpty }}">
- <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.vmType }}</em></a>
+
+ <template if="{{ ref.isObjectPool }}">
+ <a on-click="{{ goto }}" _href="{{ url }}">
+ <em>{{ ref.vmType }}</em> ({{ ref.length }})
+ </a>
</template>
- <template if="{{ !nameIsEmpty }}">
- <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ name }}</em></a>
+ <template if="{{ ref.isICData }}">
+ <a on-click="{{ goto }}" _href="{{ url }}">
+ <em>{{ ref.vmType }}</em> ({{ ref.selector }})
+ </a>
+ </template>
+ <template if="{{ ref.isInstructions }}">
+ <a on-click="{{ goto }}" _href="{{ url }}">
+ <em>{{ ref.vmType }}</em> ({{ ref.code.name }})
+ </a>
+ </template>
+ <template if="{{ !(ref.isObjectPool || ref.isICData || ref.isInstructions) }}">
+ <template if="{{ nameIsEmpty }}">
+ <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.vmType }}</em></a>
+ </template>
+ <template if="{{ !nameIsEmpty }}">
+ <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ name }}</em></a>
+ </template>
</template>
</template>
</polymer-element>
-<script type="application/dart" src="service_ref.dart"></script>
\ No newline at end of file
+<script type="application/dart" src="service_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/service_view.dart b/runtime/observatory/lib/src/elements/service_view.dart
index afedd62..f0c2062 100644
--- a/runtime/observatory/lib/src/elements/service_view.dart
+++ b/runtime/observatory/lib/src/elements/service_view.dart
@@ -78,9 +78,25 @@
element.connection = object;
return element;
case 'Object':
- ObjectViewElement element = new Element.tag('object-view');
- element.object = object;
- return element;
+ switch (object.vmType) {
+ case 'ICData':
+ ICDataViewElement element = new Element.tag('icdata-view');
+ element.icData = object;
+ return element;
+ case 'Instructions':
+ InstructionsViewElement element =
+ new Element.tag('instructions-view');
+ element.instructions = object;
+ return element;
+ case 'ObjectPool':
+ ObjectPoolViewElement element = new Element.tag('objectpool-view');
+ element.pool = object;
+ return element;
+ default:
+ ObjectViewElement element = new Element.tag('object-view');
+ element.object = object;
+ return element;
+ }
case 'SocketList':
IOSocketListViewElement element =
new Element.tag('io-socket-list-view');
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 4a7ad32..f3ebd19 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -102,6 +102,9 @@
@reflectable String get vmType => _vmType;
String _vmType;
+ bool get isICData => vmType == 'ICData';
+ bool get isInstructions => vmType == 'Instructions';
+ bool get isObjectPool => vmType == 'ObjectPool';
bool get isContext => type == 'Context';
bool get isError => type == 'Error';
bool get isInstance => type == 'Instance';
@@ -118,6 +121,7 @@
bool get isList => false;
bool get isMap => false;
bool get isTypedData => false;
+ bool get isRegExp => false;
bool get isMirrorReference => false;
bool get isWeakProperty => false;
bool get isClosure => false;
@@ -202,12 +206,21 @@
break;
case 'Object':
switch (vmType) {
- case 'PcDescriptors':
- obj = new PcDescriptors._empty(owner);
+ case 'ICData':
+ obj = new ICData._empty(owner);
+ break;
+ case 'Instructions':
+ obj = new Instructions._empty(owner);
break;
case 'LocalVarDescriptors':
obj = new LocalVarDescriptors._empty(owner);
break;
+ case 'ObjectPool':
+ obj = new ObjectPool._empty(owner);
+ break;
+ case 'PcDescriptors':
+ obj = new PcDescriptors._empty(owner);
+ break;
case 'TokenStream':
obj = new TokenStream._empty(owner);
break;
@@ -335,6 +348,14 @@
}
}
+abstract class HeapObject extends ServiceObject {
+ @observable Class clazz;
+ @observable int size;
+ @observable int retainedSize;
+
+ HeapObject._empty(ServiceObjectOwner owner) : super._empty(owner);
+}
+
abstract class Coverage {
// Following getters and functions will be provided by [ServiceObject].
String get id;
@@ -1875,6 +1896,7 @@
@observable Context context; // If a closure.
@observable String name; // If a Type.
@observable int length; // If a List, Map or TypedData.
+ @observable String pattern; // If a RegExp.
@observable var typeClass;
@observable var fields;
@@ -1886,6 +1908,10 @@
@observable Instance key; // If a WeakProperty.
@observable Instance value; // If a WeakProperty.
@observable Breakpoint activationBreakpoint; // If a Closure.
+ @observable Function oneByteFunction; // If a RegExp.
+ @observable Function twoByteFunction; // If a RegExp.
+ @observable Function externalOneByteFunction; // If a RegExp.
+ @observable Function externalTwoByteFunction; // If a RegExp.
bool get isAbstractType {
return (kind == 'Type' || kind == 'TypeRef' ||
@@ -1914,6 +1940,7 @@
|| kind == 'Float32x4List'
|| kind == 'Float64x2List';
}
+ bool get isRegExp => kind == 'RegExp';
bool get isMirrorReference => kind == 'MirrorReference';
bool get isWeakProperty => kind == 'WeakProperty';
bool get isClosure => kind == 'Closure';
@@ -1930,7 +1957,6 @@
kind = map['kind'];
clazz = map['class'];
- size = map['size'];
valueAsString = map['valueAsString'];
// Coerce absence to false.
valueAsStringIsTruncated = map['valueAsStringIsTruncated'] == true;
@@ -1938,11 +1964,19 @@
context = map['closureContext'];
name = map['name'];
length = map['length'];
+ pattern = map['pattern'];
if (mapIsRef) {
return;
}
+ size = map['size'];
+
+ oneByteFunction = map['_oneByteFunction'];
+ twoByteFunction = map['_twoByteFunction'];
+ externalOneByteFunction = map['_externalOneByteFunction'];
+ externalTwoByteFunction = map['_externalTwoByteFunction'];
+
nativeFields = map['_nativeFields'];
fields = map['fields'];
elements = map['elements'];
@@ -2022,7 +2056,6 @@
// Extract full properties.
_upgradeCollection(map, isolate);
- size = map['size'];
length = map['length'];
parentContext = map['parent'];
@@ -2030,6 +2063,7 @@
return;
}
+ size = map['size'];
clazz = map['class'];
variables = map['variables'];
@@ -2111,6 +2145,7 @@
@observable int usageCounter;
@observable bool isDart;
@observable ProfileFunction profile;
+ @observable Instance icDataArray;
bool get immutable => false;
@@ -2124,7 +2159,7 @@
dartOwner = map['owner'];
kind = FunctionKind.fromJSON(map['_kind']);
- isDart = !kind.isSynthetic();
+ isDart = kind.isDart();
if (dartOwner is ServiceFunction) {
ServiceFunction ownerFunction = dartOwner;
@@ -2155,6 +2190,7 @@
unoptimizedCode = map['_unoptimizedCode'];
deoptimizations = map['_deoptimizations'];
usageCounter = map['_usageCounter'];
+ icDataArray = map['_icDataArray'];
}
}
@@ -2749,9 +2785,74 @@
}
}
-class TokenStream extends ServiceObject {
- @observable Class clazz;
- @observable int size;
+class ObjectPool extends HeapObject {
+ bool get canCache => false;
+ bool get immutable => false;
+
+ @observable int length;
+ @observable List entries;
+
+ ObjectPool._empty(ServiceObjectOwner owner) : super._empty(owner);
+
+ void _update(ObservableMap m, bool mapIsRef) {
+ _upgradeCollection(m, isolate);
+ clazz = m['class'];
+ length = m['length'];
+ if (mapIsRef) {
+ return;
+ }
+ size = m['size'];
+ entries = m['_entries'];
+ }
+}
+
+class ICData extends HeapObject {
+ @observable ServiceObject dartOwner;
+ @observable String selector;
+ @observable Instance argumentsDescriptor;
+ @observable Instance entries;
+
+ bool get canCache => false;
+ bool get immutable => false;
+
+ ICData._empty(ServiceObjectOwner owner) : super._empty(owner);
+
+ void _update(ObservableMap m, bool mapIsRef) {
+ _upgradeCollection(m, isolate);
+ clazz = m['class'];
+ dartOwner = m['_owner'];
+ selector = m['_selector'];
+ if (mapIsRef) {
+ return;
+ }
+ size = m['size'];
+ argumentsDescriptor = m['_argumentsDescriptor'];
+ entries = m['_entries'];
+ }
+}
+
+class Instructions extends HeapObject {
+ bool get canCache => false;
+ bool get immutable => true;
+
+ @observable Code code;
+ @observable ObjectPool objectPool;
+
+ Instructions._empty(ServiceObjectOwner owner) : super._empty(owner);
+
+ void _update(ObservableMap m, bool mapIsRef) {
+ _upgradeCollection(m, isolate);
+ clazz = m['class'];
+ code = m['_code'];
+ if (mapIsRef) {
+ return;
+ }
+ size = m['size'];
+ objectPool = m['_objectPool'];
+ }
+}
+
+class TokenStream extends HeapObject {
bool get canCache => false;
bool get immutable => true;
@@ -2807,7 +2908,8 @@
}
}
- void _resolveJumpTarget(List<CodeInstruction> instructions) {
+ void _resolveJumpTarget(List<CodeInstruction> instructionsByAddressOffset,
+ int startAddress) {
if (!_isJumpInstruction()) {
return;
}
@@ -2815,13 +2917,8 @@
if (address == 0) {
return;
}
- for (var i = 0; i < instructions.length; i++) {
- var instruction = instructions[i];
- if (instruction.address == address) {
- jumpTarget = instruction;
- return;
- }
- }
+
+ jumpTarget = instructionsByAddressOffset[address - startAddress];
}
}
@@ -2861,7 +2958,7 @@
CodeInlineInterval(this.start, this.end);
}
-class Code extends ServiceObject {
+class Code extends HeapObject {
@observable CodeKind kind;
@observable ServiceObject objectPool;
@observable ServiceFunction function;
@@ -2870,6 +2967,8 @@
@reflectable int startAddress = 0;
@reflectable int endAddress = 0;
@reflectable final instructions = new ObservableList<CodeInstruction>();
+ List<CodeInstruction> instructionsByAddressOffset;
+
@observable ProfileCode profile;
final List<CodeInlineInterval> inlineIntervals =
new List<CodeInlineInterval>();
@@ -2938,6 +3037,7 @@
return;
}
_loaded = true;
+ size = m['size'];
startAddress = int.parse(m['_startAddress'], radix:16);
endAddress = int.parse(m['_endAddress'], radix:16);
function = isolate.getFromMap(m['function']);
@@ -3008,6 +3108,8 @@
void _processDisassembly(List<String> disassembly){
assert(disassembly != null);
instructions.clear();
+ instructionsByAddressOffset = new List(endAddress - startAddress);
+
assert((disassembly.length % 3) == 0);
for (var i = 0; i < disassembly.length; i += 3) {
var address = 0; // Assume code comment.
@@ -3021,37 +3123,37 @@
}
var instruction = new CodeInstruction(address, pcOffset, machine, human);
instructions.add(instruction);
+ if (disassembly[i] != '') {
+ // Not a code comment.
+ instructionsByAddressOffset[pcOffset] = instruction;
+ }
}
for (var instruction in instructions) {
- instruction._resolveJumpTarget(instructions);
+ instruction._resolveJumpTarget(instructionsByAddressOffset, startAddress);
}
}
- void _processDescriptor(Map d) {
- var pcOffset = int.parse(d['pcOffset'], radix:16);
- var address = startAddress + pcOffset;
- var deoptId = d['deoptId'];
- var tokenPos = d['tokenPos'];
- var tryIndex = d['tryIndex'];
- var kind = d['kind'].trim();
- for (var instruction in instructions) {
- if (instruction.address == address) {
+ void _processDescriptors(List<Map> descriptors) {
+ for (Map descriptor in descriptors) {
+ var pcOffset = int.parse(descriptor['pcOffset'], radix:16);
+ var address = startAddress + pcOffset;
+ var deoptId = descriptor['deoptId'];
+ var tokenPos = descriptor['tokenPos'];
+ var tryIndex = descriptor['tryIndex'];
+ var kind = descriptor['kind'].trim();
+
+ var instruction = instructionsByAddressOffset[address - startAddress];
+ if (instruction != null) {
instruction.descriptors.add(new PcDescriptor(pcOffset,
deoptId,
tokenPos,
tryIndex,
kind));
- return;
+ } else {
+ Logger.root.warning(
+ 'Could not find instruction with pc descriptor address: $address');
}
}
- Logger.root.warning(
- 'Could not find instruction with pc descriptor address: $address');
- }
-
- void _processDescriptors(List<Map> descriptors) {
- for (Map descriptor in descriptors) {
- _processDescriptor(descriptor);
- }
}
/// Returns true if [address] is contained inside [this].
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index 7b5f63d..9445912 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -77,12 +77,16 @@
'lib/src/elements/heap_profile.html',
'lib/src/elements/heap_snapshot.dart',
'lib/src/elements/heap_snapshot.html',
+ 'lib/src/elements/icdata_view.dart',
+ 'lib/src/elements/icdata_view.html',
'lib/src/elements/inbound_reference.dart',
'lib/src/elements/inbound_reference.html',
'lib/src/elements/instance_ref.dart',
'lib/src/elements/instance_ref.html',
'lib/src/elements/instance_view.dart',
'lib/src/elements/instance_view.html',
+ 'lib/src/elements/instructions_view.dart',
+ 'lib/src/elements/instructions_view.html',
'lib/src/elements/io_view.dart',
'lib/src/elements/io_view.html',
'lib/src/elements/isolate_reconnect.dart',
@@ -107,6 +111,8 @@
'lib/src/elements/object_common.html',
'lib/src/elements/object_view.dart',
'lib/src/elements/object_view.html',
+ 'lib/src/elements/objectpool_view.dart',
+ 'lib/src/elements/objectpool_view.html',
'lib/src/elements/observatory_application.dart',
'lib/src/elements/observatory_application.html',
'lib/src/elements/observatory_element.dart',
diff --git a/runtime/vm/disassembler_x64.cc b/runtime/vm/disassembler_x64.cc
index be31deb..0b87662 100644
--- a/runtime/vm/disassembler_x64.cc
+++ b/runtime/vm/disassembler_x64.cc
@@ -1089,6 +1089,8 @@
// if (rex_w()) AppendToBuffer("REX.W ");
} else if ((current & 0xFE) == 0xF2) { // Group 1 prefix (0xF2 or 0xF3).
group_1_prefix_ = current;
+ } else if (current == 0xF0) {
+ AppendToBuffer("lock ");
} else { // Not a prefix - an opcode.
break;
}
@@ -1515,8 +1517,9 @@
current = data + JumpConditional(data);
} else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 ||
- opcode == 0xB7 || opcode == 0xAF) {
- // Size-extending moves, IMUL.
+ opcode == 0xB7 || opcode == 0xAF || opcode == 0xB0 ||
+ opcode == 0xB1) {
+ // Size-extending moves, IMUL, cmpxchg.
current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current);
} else if ((opcode & 0xF0) == 0x90) {
@@ -1581,6 +1584,9 @@
return "shrd";
case 0xAF:
return "imul";
+ case 0xB0:
+ case 0xB1:
+ return "cmpxchg";
case 0xB6:
return "movzxb";
case 0xB7:
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 0cc4f2b3..d493fa3 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -83,7 +83,7 @@
FLAG_deoptimize_alot = false; // Used in some tests.
FLAG_deoptimize_every = 0; // Used in some tests.
FLAG_collect_code = false;
- FLAG_guess_other_cid = false;
+ FLAG_guess_other_cid = true;
Compiler::set_always_optimize(true);
// TODO(srdjan): Enable CHA deoptimization when eager class finalization is
// implemented, either with precompilation or as a special pass.
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 6f2f635..abdb548 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -27,9 +27,7 @@
DEFINE_FLAG(int, getter_setter_ratio, 13,
"Ratio of getter/setter usage used for double field unboxing heuristics");
-// Setting 'guess_other_cid' to true causes issue 23693 crash.
-// TODO(srdjan): Evaluate if that optimization is wrong.
-DEFINE_FLAG(bool, guess_other_cid, false,
+DEFINE_FLAG(bool, guess_other_cid, true,
"Artificially create type feedback for arithmetic etc. operations"
" by guessing the other unknown argument cid");
DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination.");
@@ -197,8 +195,6 @@
Token::IsBinaryOperator(op_kind)) {
// Guess cid: if one of the inputs is a number assume that the other
// is a number of same type.
- // Issue 23693. It is potentially wrong to assign types here that may
- // conflict with other graph analysis.
if (FLAG_guess_other_cid) {
const intptr_t cid_0 = class_ids[0];
const intptr_t cid_1 = class_ids[1];
diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
index 59d2cd3..5fec37b 100644
--- a/runtime/vm/flow_graph_range_analysis.cc
+++ b/runtime/vm/flow_graph_range_analysis.cc
@@ -621,11 +621,10 @@
static RangeBoundary NarrowMin(const Range* range,
const Range* new_range,
RangeBoundary::RangeSize size) {
-#ifdef DEBUG
const RangeBoundary min = Range::ConstantMin(range, size);
const RangeBoundary new_min = Range::ConstantMin(new_range, size);
- ASSERT(min.ConstantValue() <= new_min.ConstantValue());
-#endif
+ if (min.ConstantValue() > new_min.ConstantValue()) return range->min();
+
// TODO(vegorov): consider using negative infinity to indicate widened bound.
return range->min().IsMinimumOrBelow(size) ? new_range->min() : range->min();
}
@@ -640,11 +639,10 @@
static RangeBoundary NarrowMax(const Range* range,
const Range* new_range,
RangeBoundary::RangeSize size) {
-#ifdef DEBUG
const RangeBoundary max = Range::ConstantMax(range, size);
const RangeBoundary new_max = Range::ConstantMax(new_range, size);
- ASSERT(max.ConstantValue() >= new_max.ConstantValue());
-#endif
+ if (max.ConstantValue() < new_max.ConstantValue()) return range->max();
+
// TODO(vegorov): consider using positive infinity to indicate widened bound.
return range->max().IsMaximumOrAbove(size) ? new_range->max() : range->max();
}
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 4274060..150be3e 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2736,7 +2736,7 @@
set_state_bits(
TraceAllocationBit::update(trace_allocation, raw_ptr()->state_bits_));
if (changed) {
- // TODO(johnmccutchan): Deoptimize the world?
+ DisableAllocationStub();
}
}
@@ -3633,6 +3633,14 @@
void Class::DisableAllocationStub() const {
+ const Code& existing_stub = Code::Handle(allocation_stub());
+ if (existing_stub.IsNull()) {
+ return;
+ }
+ ASSERT(!CodePatcher::IsEntryPatched(existing_stub));
+ // Patch the stub so that the next caller will regenerate the stub.
+ CodePatcher::PatchEntry(existing_stub);
+ // Disassociate the existing stub from class.
StorePointer(&raw_ptr()->allocation_stub_, Code::null());
}
@@ -6979,6 +6987,10 @@
if (!code.IsNull()) {
jsobj.AddProperty("code", code);
}
+ Array& ics = Array::Handle(ic_data_array());
+ if (!ics.IsNull()) {
+ jsobj.AddProperty("_icDataArray", ics);
+ }
jsobj.AddProperty("_optimizable", is_optimizable());
jsobj.AddProperty("_inlinable", is_inlinable());
code = unoptimized_code();
@@ -10709,7 +10721,14 @@
void Instructions::PrintJSONImpl(JSONStream* stream, bool ref) const {
- Object::PrintJSONImpl(stream, ref);
+ JSONObject jsobj(stream);
+ AddCommonObjectProperties(&jsobj, "Object", ref);
+ jsobj.AddServiceId(*this);
+ jsobj.AddProperty("_code", Code::Handle(code()));
+ if (ref) {
+ return;
+ }
+ jsobj.AddProperty("_objectPool", ObjectPool::Handle(object_pool()));
}
@@ -10800,7 +10819,35 @@
void ObjectPool::PrintJSONImpl(JSONStream* stream, bool ref) const {
- Object::PrintJSONImpl(stream, ref);
+ JSONObject jsobj(stream);
+ AddCommonObjectProperties(&jsobj, "Object", ref);
+ jsobj.AddServiceId(*this);
+ jsobj.AddProperty("length", Length());
+ if (ref) {
+ return;
+ }
+
+ {
+ JSONArray jsarr(&jsobj, "_entries");
+ uword imm;
+ Object& obj = Object::Handle();
+ for (intptr_t i = 0; i < Length(); i++) {
+ switch (InfoAt(i)) {
+ case ObjectPool::kTaggedObject:
+ obj = ObjectAt(i);
+ jsarr.AddValue(obj);
+ break;
+ case ObjectPool::kImmediate:
+ // We might want to distingiush between immediates and addresses
+ // in the future.
+ imm = RawValueAt(i);
+ jsarr.AddValue64(imm);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
}
@@ -12212,7 +12259,17 @@
void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const {
- Object::PrintJSONImpl(stream, ref);
+ JSONObject jsobj(stream);
+ AddCommonObjectProperties(&jsobj, "Object", ref);
+ jsobj.AddServiceId(*this);
+ jsobj.AddProperty("_owner", Object::Handle(owner()));
+ jsobj.AddProperty("_selector", String::Handle(target_name()).ToCString());
+ if (ref) {
+ return;
+ }
+ jsobj.AddProperty("_argumentsDescriptor",
+ Object::Handle(arguments_descriptor()));
+ jsobj.AddProperty("_entries", Object::Handle(ic_data()));
}
@@ -12974,7 +13031,7 @@
// Generate a fake function reference.
JSONObject func(&jsobj, "function");
func.AddProperty("type", "@Function");
- func.AddProperty("kind", "Stub");
+ func.AddProperty("_kind", "Stub");
func.AddProperty("name", user_name.ToCString());
AddNameProperties(&func, user_name, vm_name);
}
@@ -20850,7 +20907,26 @@
void JSRegExp::PrintJSONImpl(JSONStream* stream, bool ref) const {
- Instance::PrintJSONImpl(stream, ref);
+ JSONObject jsobj(stream);
+ PrintSharedInstanceJSON(&jsobj, ref);
+ jsobj.AddProperty("kind", "RegExp");
+ jsobj.AddServiceId(*this);
+
+ jsobj.AddProperty("pattern", String::Handle(pattern()));
+
+ if (ref) {
+ return;
+ }
+
+ Function& func = Function::Handle();
+ func = function(kOneByteStringCid);
+ jsobj.AddProperty("_oneByteFunction", func);
+ func = function(kTwoByteStringCid);
+ jsobj.AddProperty("_twoByteFunction", func);
+ func = function(kExternalOneByteStringCid);
+ jsobj.AddProperty("_externalOneByteFunction", func);
+ func = function(kExternalTwoByteStringCid);
+ jsobj.AddProperty("_externalTwoByteFunction", func);
}
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index a8fc76a..6cc8e54 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -9599,14 +9599,17 @@
bool is_yield_each = false;
const intptr_t yield_pos = TokenPos();
ConsumeToken(); // yield reserved word.
- ASSERT(innermost_function().IsGenerator() ||
- innermost_function().IsSyncGenClosure() ||
- innermost_function().IsAsyncGenerator() ||
- innermost_function().IsAsyncGenClosure());
if (CurrentToken() == Token::kMUL) {
is_yield_each = true;
ConsumeToken();
}
+ if (!innermost_function().IsGenerator() &&
+ !innermost_function().IsGeneratorClosure()) {
+ ReportError(yield_pos,
+ "yield%s statement only allowed in generator functions",
+ is_yield_each ? "*" : "");
+ }
+
AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
LetNode* yield = new(Z) LetNode(yield_pos);
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 188d7cd..5e8940a 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -19,12 +19,6 @@
DEFINE_FLAG(bool, trace_profiler, false, "Trace profiler.");
-// Forward declarations.
-class CodeRegion;
-class ProfileFunction;
-class ProfileFunctionTable;
-
-
class DeoptimizedCodeSet : public ZoneAllocated {
public:
explicit DeoptimizedCodeSet(Isolate* isolate)
@@ -92,156 +86,361 @@
const GrowableObjectArray& current_;
};
-class ProfileFunction : public ZoneAllocated {
- public:
- enum Kind {
- kDartFunction, // Dart function.
- kNativeFunction, // Synthetic function for Native (C/C++).
- kTagFunction, // Synthetic function for a VM or User tag.
- kStubFunction, // Synthetic function for stub code.
- kUnkownFunction, // A singleton function for unknown objects.
- };
- ProfileFunction(Kind kind,
+
+ProfileFunction::ProfileFunction(Kind kind,
const char* name,
const Function& function,
const intptr_t table_index)
- : kind_(kind),
- name_(name),
- function_(Function::ZoneHandle(function.raw())),
- table_index_(table_index),
- code_objects_(new ZoneGrowableArray<intptr_t>()),
- exclusive_ticks_(0),
- inclusive_ticks_(0),
- inclusive_tick_serial_(0) {
- ASSERT((kind_ != kDartFunction) || !function_.IsNull());
- ASSERT((kind_ != kDartFunction) || (table_index_ >= 0));
- ASSERT(code_objects_->length() == 0);
- }
+ : kind_(kind),
+ name_(name),
+ function_(Function::ZoneHandle(function.raw())),
+ table_index_(table_index),
+ profile_codes_(0),
+ exclusive_ticks_(0),
+ inclusive_ticks_(0) {
+ ASSERT((kind_ != kDartFunction) || !function_.IsNull());
+ ASSERT((kind_ != kDartFunction) || (table_index_ >= 0));
+ ASSERT(profile_codes_.length() == 0);
+}
- const char* name() const {
- ASSERT(name_ != NULL);
+
+const char* ProfileFunction::Name() const {
+ if (name_ != NULL) {
return name_;
}
+ ASSERT(!function_.IsNull());
+ const String& func_name =
+ String::Handle(function_.QualifiedUserVisibleName());
+ return func_name.ToCString();
+}
- RawFunction* function() const {
- return function_.raw();
- }
-
- intptr_t index() const {
- return table_index_;
- }
-
- Kind kind() const {
- return kind_;
- }
-
- const char* KindToCString(Kind kind) {
- switch (kind) {
- case kDartFunction:
- return "Dart";
- case kNativeFunction:
- return "Native";
- case kTagFunction:
- return "Tag";
- case kStubFunction:
- return "Stub";
- case kUnkownFunction:
- return "Collected";
- default:
- UNIMPLEMENTED();
- return "";
- }
- }
-
- void Dump() {
- const char* n = (name_ == NULL) ? "<NULL>" : name_;
- const char* fn = "";
- if (!function_.IsNull()) {
- fn = function_.ToQualifiedCString();
- }
- OS::Print("%s %s [%s]", KindToCString(kind()), n, fn);
- }
-
- void AddCodeObjectIndex(intptr_t index) {
- for (intptr_t i = 0; i < code_objects_->length(); i++) {
- if ((*code_objects_)[i] == index) {
- return;
- }
- }
- code_objects_->Add(index);
- }
-
- intptr_t inclusive_ticks() const {
- return inclusive_ticks_;
- }
- void inc_inclusive_ticks() {
- inclusive_ticks_++;
- }
- intptr_t exclusive_ticks() const {
- return exclusive_ticks_;
- }
-
- void Tick(bool exclusive, intptr_t serial) {
- // Assert that exclusive ticks are never passed a valid serial number.
- ASSERT((exclusive && (serial == -1)) || (!exclusive && (serial != -1)));
- if (!exclusive && (inclusive_tick_serial_ == serial)) {
- // We've already given this object an inclusive tick for this sample.
+void ProfileFunction::Tick(bool exclusive, intptr_t inclusive_serial) {
+ if (exclusive) {
+ exclusive_ticks_++;
+ } else {
+ if (inclusive_serial_ == inclusive_serial) {
+ // Already ticket.
return;
}
- if (exclusive) {
- exclusive_ticks_++;
- } else {
- inclusive_ticks_++;
- // Mark the last serial we ticked the inclusive count.
- inclusive_tick_serial_ = serial;
+ inclusive_serial_ = inclusive_serial;
+ inclusive_ticks_++;
+ }
+}
+
+
+const char* ProfileFunction::KindToCString(Kind kind) {
+ switch (kind) {
+ case kDartFunction:
+ return "Dart";
+ case kNativeFunction:
+ return "Native";
+ case kTagFunction:
+ return "Tag";
+ case kStubFunction:
+ return "Stub";
+ case kUnknownFunction:
+ return "Collected";
+ default:
+ UNIMPLEMENTED();
+ return "";
+ }
+}
+
+
+void ProfileFunction::PrintToJSONObject(JSONObject* func) {
+ func->AddProperty("type", "@Function");
+ func->AddProperty("name", name());
+ func->AddProperty("_kind", KindToCString(kind()));
+}
+
+
+void ProfileFunction::PrintToJSONArray(JSONArray* functions) {
+ JSONObject obj(functions);
+ obj.AddProperty("kind", KindToCString(kind()));
+ obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
+ obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
+ if (kind() == kDartFunction) {
+ ASSERT(!function_.IsNull());
+ obj.AddProperty("function", function_);
+ } else {
+ JSONObject func(&obj, "function");
+ PrintToJSONObject(&func);
+ }
+ {
+ JSONArray codes(&obj, "codes");
+ for (intptr_t i = 0; i < profile_codes_.length(); i++) {
+ intptr_t code_index = profile_codes_[i];
+ codes.AddValue(code_index);
+ }
+ }
+}
+
+
+void ProfileFunction::AddProfileCode(intptr_t code_table_index) {
+ for (intptr_t i = 0; i < profile_codes_.length(); i++) {
+ if (profile_codes_[i] == code_table_index) {
+ return;
+ }
+ }
+ profile_codes_.Add(code_table_index);
+}
+
+
+ProfileCodeAddress::ProfileCodeAddress(uword pc)
+ : pc_(pc),
+ exclusive_ticks_(0),
+ inclusive_ticks_(0) {
+}
+
+
+void ProfileCodeAddress::Tick(bool exclusive) {
+ if (exclusive) {
+ exclusive_ticks_++;
+ } else {
+ inclusive_ticks_++;
+ }
+}
+
+
+ProfileCode::ProfileCode(Kind kind,
+ uword start,
+ uword end,
+ int64_t timestamp,
+ const Code& code)
+ : kind_(kind),
+ start_(start),
+ end_(end),
+ exclusive_ticks_(0),
+ inclusive_ticks_(0),
+ inclusive_serial_(-1),
+ code_(code),
+ name_(NULL),
+ compile_timestamp_(0),
+ function_(NULL),
+ code_table_index_(-1),
+ address_ticks_(0) {
+}
+
+
+void ProfileCode::AdjustExtent(uword start, uword end) {
+ if (start < start_) {
+ start_ = start;
+ }
+ if (end > end_) {
+ end_ = end;
+ }
+ ASSERT(start_ < end_);
+}
+
+
+bool ProfileCode::Overlaps(const ProfileCode* other) const {
+ ASSERT(other != NULL);
+ return other->Contains(start_) ||
+ other->Contains(end_ - 1) ||
+ Contains(other->start()) ||
+ Contains(other->end() - 1);
+}
+
+
+bool ProfileCode::IsOptimizedDart() const {
+ return !code_.IsNull() && code_.is_optimized();
+}
+
+
+void ProfileCode::SetName(const char* name) {
+ if (name == NULL) {
+ name_ = NULL;
+ }
+ intptr_t len = strlen(name);
+ name_ = Isolate::Current()->current_zone()->Alloc<const char>(len + 1);
+ strncpy(const_cast<char*>(name_), name, len);
+ const_cast<char*>(name_)[len] = '\0';
+}
+
+
+void ProfileCode::GenerateAndSetSymbolName(const char* prefix) {
+ const intptr_t kBuffSize = 512;
+ char buff[kBuffSize];
+ OS::SNPrint(&buff[0], kBuffSize-1, "%s [%" Px ", %" Px ")",
+ prefix, start(), end());
+ SetName(buff);
+}
+
+
+void ProfileCode::Tick(uword pc, bool exclusive, intptr_t serial) {
+ if (exclusive) {
+ exclusive_ticks_++;
+ } else {
+ if (inclusive_serial_ == serial) {
+ // Already ticked for this sample.
+ return;
+ }
+ inclusive_serial_ = serial;
+ inclusive_ticks_++;
+ }
+ TickAddress(pc, exclusive);
+}
+
+
+void ProfileCode::TickAddress(uword pc, bool exclusive) {
+ const intptr_t length = address_ticks_.length();
+
+ intptr_t i = 0;
+ for (; i < length; i++) {
+ ProfileCodeAddress& entry = address_ticks_[i];
+ if (entry.pc() == pc) {
+ // Tick the address entry.
+ entry.Tick(exclusive);
+ return;
+ }
+ if (entry.pc() > pc) {
+ break;
}
}
- void PrintToJSONObject(JSONObject* func) {
- func->AddProperty("type", "@Function");
- func->AddProperty("name", name());
- func->AddProperty("_kind", KindToCString(kind()));
- }
+ // New address, add entry.
+ ProfileCodeAddress entry(pc);
- void PrintToJSONArray(JSONArray* functions) {
- JSONObject obj(functions);
- obj.AddProperty("kind", KindToCString(kind()));
- obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
- obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
- if (kind() == kDartFunction) {
- ASSERT(!function_.IsNull());
- obj.AddProperty("function", function_);
- } else {
- JSONObject func(&obj, "function");
- PrintToJSONObject(&func);
- }
- {
- JSONArray codes(&obj, "codes");
- for (intptr_t i = 0; i < code_objects_->length(); i++) {
- intptr_t code_index = (*code_objects_)[i];
- codes.AddValue(code_index);
- }
+ entry.Tick(exclusive);
+
+ if (i < length) {
+ // Insert at i.
+ address_ticks_.InsertAt(i, entry);
+ } else {
+ // Add to end.
+ address_ticks_.Add(entry);
+ }
+}
+
+
+void ProfileCode::PrintNativeCode(JSONObject* profile_code_obj) {
+ ASSERT(kind() == kNativeCode);
+ JSONObject obj(profile_code_obj, "code");
+ obj.AddProperty("type", "@Code");
+ obj.AddProperty("kind", "Native");
+ obj.AddProperty("name", name());
+ obj.AddProperty("_optimized", false);
+ obj.AddPropertyF("start", "%" Px "", start());
+ obj.AddPropertyF("end", "%" Px "", end());
+ {
+ // Generate a fake function entry.
+ JSONObject func(&obj, "function");
+ ASSERT(function_ != NULL);
+ function_->PrintToJSONObject(&func);
+ }
+}
+
+
+void ProfileCode::PrintCollectedCode(JSONObject* profile_code_obj) {
+ ASSERT(kind() == kCollectedCode);
+ JSONObject obj(profile_code_obj, "code");
+ obj.AddProperty("type", "@Code");
+ obj.AddProperty("kind", "Collected");
+ obj.AddProperty("name", name());
+ obj.AddProperty("_optimized", false);
+ obj.AddPropertyF("start", "%" Px "", start());
+ obj.AddPropertyF("end", "%" Px "", end());
+ {
+ // Generate a fake function entry.
+ JSONObject func(&obj, "function");
+ ASSERT(function_ != NULL);
+ function_->PrintToJSONObject(&func);
+ }
+}
+
+
+void ProfileCode::PrintOverwrittenCode(JSONObject* profile_code_obj) {
+ ASSERT(kind() == kReusedCode);
+ JSONObject obj(profile_code_obj, "code");
+ obj.AddProperty("type", "@Code");
+ obj.AddProperty("kind", "Collected");
+ obj.AddProperty("name", name());
+ obj.AddProperty("_optimized", false);
+ obj.AddPropertyF("start", "%" Px "", start());
+ obj.AddPropertyF("end", "%" Px "", end());
+ {
+ // Generate a fake function entry.
+ JSONObject func(&obj, "function");
+ ASSERT(function_ != NULL);
+ function_->PrintToJSONObject(&func);
+ }
+}
+
+
+void ProfileCode::PrintTagCode(JSONObject* profile_code_obj) {
+ ASSERT(kind() == kTagCode);
+ JSONObject obj(profile_code_obj, "code");
+ obj.AddProperty("type", "@Code");
+ obj.AddProperty("kind", "Tag");
+ obj.AddProperty("name", name());
+ obj.AddPropertyF("start", "%" Px "", start());
+ obj.AddPropertyF("end", "%" Px "", end());
+ obj.AddProperty("_optimized", false);
+ {
+ // Generate a fake function entry.
+ JSONObject func(&obj, "function");
+ ASSERT(function_ != NULL);
+ function_->PrintToJSONObject(&func);
+ }
+}
+
+
+const char* ProfileCode::KindToCString(Kind kind) {
+ switch (kind) {
+ case kDartCode:
+ return "Dart";
+ case kCollectedCode:
+ return "Collected";
+ case kNativeCode:
+ return "Native";
+ case kReusedCode:
+ return "Overwritten";
+ case kTagCode:
+ return "Tag";
+ }
+ UNREACHABLE();
+ return NULL;
+}
+
+
+void ProfileCode::PrintToJSONArray(JSONArray* codes) {
+ JSONObject obj(codes);
+ obj.AddProperty("kind", ProfileCode::KindToCString(kind()));
+ obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
+ obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
+ if (kind() == kDartCode) {
+ ASSERT(!code_.IsNull());
+ obj.AddProperty("code", code_);
+ } else if (kind() == kCollectedCode) {
+ PrintCollectedCode(&obj);
+ } else if (kind() == kReusedCode) {
+ PrintOverwrittenCode(&obj);
+ } else if (kind() == kTagCode) {
+ PrintTagCode(&obj);
+ } else {
+ ASSERT(kind() == kNativeCode);
+ PrintNativeCode(&obj);
+ }
+ {
+ JSONArray ticks(&obj, "ticks");
+ for (intptr_t i = 0; i < address_ticks_.length(); i++) {
+ const ProfileCodeAddress& entry = address_ticks_[i];
+ ticks.AddValueF("%" Px "", entry.pc());
+ ticks.AddValueF("%" Pd "", entry.exclusive_ticks());
+ ticks.AddValueF("%" Pd "", entry.inclusive_ticks());
}
}
-
- private:
- const Kind kind_;
- const char* name_;
- const Function& function_;
- const intptr_t table_index_;
- ZoneGrowableArray<intptr_t>* code_objects_;
- intptr_t exclusive_ticks_;
- intptr_t inclusive_ticks_;
- intptr_t inclusive_tick_serial_;
-};
+}
-class ProfileFunctionTable : public ValueObject {
+class ProfileFunctionTable : public ZoneAllocated {
public:
ProfileFunctionTable()
: null_function_(Function::ZoneHandle()),
- table_(new ZoneGrowableArray<ProfileFunction*>()),
+ table_(8),
unknown_function_(NULL) {
+ unknown_function_ = Add(ProfileFunction::kUnknownFunction,
+ "<unknown Dart function>");
}
ProfileFunction* LookupOrAdd(const Function& function) {
@@ -255,8 +454,8 @@
intptr_t LookupIndex(const Function& function) {
ASSERT(!function.IsNull());
- for (intptr_t i = 0; i < table_->length(); i++) {
- ProfileFunction* profile_function = (*table_)[i];
+ for (intptr_t i = 0; i < table_.length(); i++) {
+ ProfileFunction* profile_function = table_[i];
if (profile_function->function() == function.raw()) {
return i;
}
@@ -265,11 +464,6 @@
}
ProfileFunction* GetUnknown() {
- if (unknown_function_ == NULL) {
- // Construct.
- unknown_function_ = Add(ProfileFunction::kUnkownFunction,
- "<unknown Dart function>");
- }
ASSERT(unknown_function_ != NULL);
return unknown_function_;
}
@@ -292,14 +486,14 @@
return Add(ProfileFunction::kStubFunction, name);
}
- intptr_t Length() const {
- return table_->length();
+ intptr_t length() const {
+ return table_.length();
}
ProfileFunction* At(intptr_t i) const {
ASSERT(i >= 0);
- ASSERT(i < Length());
- return (*table_)[i];
+ ASSERT(i < length());
+ return table_[i];
}
private:
@@ -310,8 +504,8 @@
new ProfileFunction(kind,
name,
null_function_,
- table_->length());
- table_->Add(profile_function);
+ table_.length());
+ table_.Add(profile_function);
return profile_function;
}
@@ -321,8 +515,8 @@
new ProfileFunction(ProfileFunction::kDartFunction,
NULL,
function,
- table_->length());
- table_->Add(profile_function);
+ table_.length());
+ table_.Add(profile_function);
return profile_function;
}
@@ -332,559 +526,189 @@
if (index == -1) {
return NULL;
}
- return (*table_)[index];
+ return table_[index];
}
const Function& null_function_;
- ZoneGrowableArray<ProfileFunction*>* table_;
-
+ ZoneGrowableArray<ProfileFunction*> table_;
ProfileFunction* unknown_function_;
};
-struct AddressEntry {
- uword pc;
- intptr_t exclusive_ticks;
- intptr_t inclusive_ticks;
+ProfileFunction* ProfileCode::SetFunctionAndName(ProfileFunctionTable* table) {
+ ASSERT(function_ == NULL);
- void tick(bool exclusive) {
- if (exclusive) {
- exclusive_ticks++;
+ ProfileFunction* function = NULL;
+ if ((kind() == kReusedCode) || (kind() == kCollectedCode)) {
+ if (name() == NULL) {
+ // Lazily set generated name.
+ GenerateAndSetSymbolName("[Collected]");
+ }
+ // Map these to a canonical unknown function.
+ function = table->GetUnknown();
+ } else if (kind() == kDartCode) {
+ ASSERT(!code_.IsNull());
+ const Object& obj = Object::Handle(code_.owner());
+ if (obj.IsFunction()) {
+ const String& user_name = String::Handle(code_.PrettyName());
+ function = table->LookupOrAdd(Function::Cast(obj));
+ SetName(user_name.ToCString());
} else {
- inclusive_ticks++;
+ // A stub.
+ const String& user_name = String::Handle(code_.PrettyName());
+ function = table->AddStub(start(), user_name.ToCString());
+ SetName(user_name.ToCString());
}
- }
-};
-
-typedef bool (*RegionCompare)(uword pc, uword region_start, uword region_end);
-
-// A contiguous address region that holds code. Each CodeRegion has a "kind"
-// which describes the type of code contained inside the region. Each
-// region covers the following interval: [start, end).
-class CodeRegion : public ZoneAllocated {
- public:
- enum Kind {
- kDartCode, // Live Dart code.
- kCollectedCode, // Dead Dart code.
- kNativeCode, // Native code.
- kReusedCode, // Dead Dart code that has been reused by new kDartCode.
- kTagCode, // A special kind of code representing a tag.
- };
-
- CodeRegion(Kind kind,
- uword start,
- uword end,
- int64_t timestamp,
- const Code& code)
- : kind_(kind),
- start_(start),
- end_(end),
- inclusive_ticks_(0),
- exclusive_ticks_(0),
- inclusive_tick_serial_(0),
- name_(NULL),
- compile_timestamp_(timestamp),
- code_(Code::ZoneHandle(code.raw())),
- profile_function_(NULL),
- code_table_index_(-1) {
- ASSERT(start_ < end_);
- // Ensure all kDartCode have a valid code_ object.
- ASSERT((kind != kDartCode) || (!code_.IsNull()));
- }
-
- uword start() const { return start_; }
- void set_start(uword start) {
- start_ = start;
- }
-
- uword end() const { return end_; }
- void set_end(uword end) {
- end_ = end;
- }
-
- void AdjustExtent(uword start, uword end) {
- if (start < start_) {
- start_ = start;
+ } else if (kind() == kNativeCode) {
+ if (name() == NULL) {
+ // Lazily set generated name.
+ GenerateAndSetSymbolName("[Native]");
}
- if (end > end_) {
- end_ = end;
- }
- ASSERT(start_ < end_);
- }
-
- bool contains(uword pc) const {
- return (pc >= start_) && (pc < end_);
- }
-
- bool overlaps(const CodeRegion* other) const {
- ASSERT(other != NULL);
- return other->contains(start_) ||
- other->contains(end_ - 1) ||
- contains(other->start()) ||
- contains(other->end() - 1);
- }
-
- int64_t compile_timestamp() const { return compile_timestamp_; }
- void set_compile_timestamp(int64_t timestamp) {
- compile_timestamp_ = timestamp;
- }
-
- intptr_t inclusive_ticks() const { return inclusive_ticks_; }
- void set_inclusive_ticks(intptr_t inclusive_ticks) {
- inclusive_ticks_ = inclusive_ticks;
- }
- void inc_inclusive_ticks() {
- inclusive_ticks_++;
- }
-
- intptr_t exclusive_ticks() const { return exclusive_ticks_; }
- void set_exclusive_ticks(intptr_t exclusive_ticks) {
- exclusive_ticks_ = exclusive_ticks;
- }
-
- const char* name() const { return name_; }
- void SetName(const char* name) {
- if (name == NULL) {
- name_ = NULL;
- }
- intptr_t len = strlen(name);
- name_ = Isolate::Current()->current_zone()->Alloc<const char>(len + 1);
- strncpy(const_cast<char*>(name_), name, len);
- const_cast<char*>(name_)[len] = '\0';
- }
-
- bool IsOptimizedDart() const {
- return !code_.IsNull() && code_.is_optimized();
- }
-
- RawCode* code() const {
- return code_.raw();
- }
-
- ProfileFunction* SetFunctionAndName(ProfileFunctionTable* table) {
- ASSERT(profile_function_ == NULL);
-
- ProfileFunction* function = NULL;
- if ((kind() == kReusedCode) || (kind() == kCollectedCode)) {
- if (name() == NULL) {
- // Lazily set generated name.
- GenerateAndSetSymbolName("[Collected]");
- }
- // Map these to a canonical unknown function.
- function = table->GetUnknown();
- } else if (kind() == kDartCode) {
- ASSERT(!code_.IsNull());
- const Object& obj = Object::Handle(code_.owner());
- if (obj.IsFunction()) {
- const String& user_name = String::Handle(code_.PrettyName());
- function = table->LookupOrAdd(Function::Cast(obj));
- SetName(user_name.ToCString());
+ function = table->AddNative(start(), name());
+ } else if (kind() == kTagCode) {
+ if (name() == NULL) {
+ if (UserTags::IsUserTag(start())) {
+ const char* tag_name = UserTags::TagName(start());
+ ASSERT(tag_name != NULL);
+ SetName(tag_name);
+ } else if (VMTag::IsVMTag(start()) ||
+ VMTag::IsRuntimeEntryTag(start()) ||
+ VMTag::IsNativeEntryTag(start())) {
+ const char* tag_name = VMTag::TagName(start());
+ ASSERT(tag_name != NULL);
+ SetName(tag_name);
} else {
- // A stub.
- const String& user_name = String::Handle(code_.PrettyName());
- function = table->AddStub(start(), user_name.ToCString());
- SetName(user_name.ToCString());
- }
- } else if (kind() == kNativeCode) {
- if (name() == NULL) {
- // Lazily set generated name.
- GenerateAndSetSymbolName("[Native]");
- }
- function = table->AddNative(start(), name());
- } else if (kind() == kTagCode) {
- if (name() == NULL) {
- if (UserTags::IsUserTag(start())) {
- const char* tag_name = UserTags::TagName(start());
- ASSERT(tag_name != NULL);
- SetName(tag_name);
- } else if (VMTag::IsVMTag(start()) ||
- VMTag::IsRuntimeEntryTag(start()) ||
- VMTag::IsNativeEntryTag(start())) {
- const char* tag_name = VMTag::TagName(start());
- ASSERT(tag_name != NULL);
- SetName(tag_name);
+ if (start() == VMTag::kRootTagId) {
+ SetName("Root");
} else {
- if (start() == VMTag::kRootTagId) {
- SetName("Root");
- } else {
- ASSERT(start() == VMTag::kTruncatedTagId);
- SetName("[Truncated]");
- }
+ ASSERT(start() == VMTag::kTruncatedTagId);
+ SetName("[Truncated]");
}
}
- function = table->AddTag(start(), name());
- } else {
- UNREACHABLE();
}
- ASSERT(function != NULL);
- // Register this CodeRegion with this function.
- function->AddCodeObjectIndex(code_table_index());
- profile_function_ = function;
- return profile_function_;
- }
-
- ProfileFunction* function() const {
- ASSERT(profile_function_ != NULL);
- return profile_function_;
- }
-
- void set_code_table_index(intptr_t code_table_index) {
- ASSERT(code_table_index_ == -1);
- ASSERT(code_table_index != -1);
- code_table_index_ = code_table_index;
- }
- intptr_t code_table_index() const {
- ASSERT(code_table_index_ != -1);
- return code_table_index_;
- }
-
- Kind kind() const { return kind_; }
-
- static const char* KindToCString(Kind kind) {
- switch (kind) {
- case kDartCode:
- return "Dart";
- case kCollectedCode:
- return "Collected";
- case kNativeCode:
- return "Native";
- case kReusedCode:
- return "Overwritten";
- case kTagCode:
- return "Tag";
- }
+ function = table->AddTag(start(), name());
+ } else {
UNREACHABLE();
- return NULL;
}
+ ASSERT(function != NULL);
- void DebugPrint() const {
- OS::Print("%s [%" Px ", %" Px ") %" Pd64 "\n",
- KindToCString(kind_),
- start(),
- end(),
- compile_timestamp_);
- }
+ function->AddProfileCode(code_table_index());
- void Tick(uword pc, bool exclusive, intptr_t serial) {
- // Assert that exclusive ticks are never passed a valid serial number.
- ASSERT((exclusive && (serial == -1)) || (!exclusive && (serial != -1)));
- if (!exclusive && (inclusive_tick_serial_ == serial)) {
- // We've already given this code object an inclusive tick for this sample.
- return;
- }
- // Tick the code object.
- if (exclusive) {
- exclusive_ticks_++;
- } else {
- inclusive_ticks_++;
- // Mark the last serial we ticked the inclusive count.
- inclusive_tick_serial_ = serial;
- }
- TickAddress(pc, exclusive);
- }
-
- void PrintNativeCode(JSONObject* profile_code_obj) {
- ASSERT(kind() == kNativeCode);
- JSONObject obj(profile_code_obj, "code");
- obj.AddProperty("type", "@Code");
- obj.AddProperty("kind", "Native");
- obj.AddProperty("name", name());
- obj.AddProperty("_optimized", false);
- obj.AddPropertyF("start", "%" Px "", start());
- obj.AddPropertyF("end", "%" Px "", end());
- {
- // Generate a fake function entry.
- JSONObject func(&obj, "function");
- profile_function_->PrintToJSONObject(&func);
- }
- }
-
- void PrintCollectedCode(JSONObject* profile_code_obj) {
- ASSERT(kind() == kCollectedCode);
- JSONObject obj(profile_code_obj, "code");
- obj.AddProperty("type", "@Code");
- obj.AddProperty("kind", "Collected");
- obj.AddProperty("name", name());
- obj.AddProperty("_optimized", false);
- obj.AddPropertyF("start", "%" Px "", start());
- obj.AddPropertyF("end", "%" Px "", end());
- {
- // Generate a fake function entry.
- JSONObject func(&obj, "function");
- profile_function_->PrintToJSONObject(&func);
- }
- }
-
- void PrintOverwrittenCode(JSONObject* profile_code_obj) {
- ASSERT(kind() == kReusedCode);
- JSONObject obj(profile_code_obj, "code");
- obj.AddProperty("type", "@Code");
- obj.AddProperty("kind", "Collected");
- obj.AddProperty("name", name());
- obj.AddProperty("_optimized", false);
- obj.AddPropertyF("start", "%" Px "", start());
- obj.AddPropertyF("end", "%" Px "", end());
- {
- // Generate a fake function entry.
- JSONObject func(&obj, "function");
- ASSERT(profile_function_ != NULL);
- profile_function_->PrintToJSONObject(&func);
- }
- }
-
- void PrintTagCode(JSONObject* profile_code_obj) {
- ASSERT(kind() == kTagCode);
- JSONObject obj(profile_code_obj, "code");
- obj.AddProperty("type", "@Code");
- obj.AddProperty("kind", "Tag");
- obj.AddProperty("name", name());
- obj.AddPropertyF("start", "%" Px "", start());
- obj.AddPropertyF("end", "%" Px "", end());
- obj.AddProperty("_optimized", false);
- {
- // Generate a fake function entry.
- JSONObject func(&obj, "function");
- ASSERT(profile_function_ != NULL);
- profile_function_->PrintToJSONObject(&func);
- }
- }
-
- void PrintToJSONArray(JSONArray* codes) {
- JSONObject obj(codes);
- obj.AddProperty("kind", KindToCString(kind()));
- obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
- obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
- if (kind() == kDartCode) {
- ASSERT(!code_.IsNull());
- obj.AddProperty("code", code_);
- } else if (kind() == kCollectedCode) {
- PrintCollectedCode(&obj);
- } else if (kind() == kReusedCode) {
- PrintOverwrittenCode(&obj);
- } else if (kind() == kTagCode) {
- PrintTagCode(&obj);
- } else {
- ASSERT(kind() == kNativeCode);
- PrintNativeCode(&obj);
- }
- {
- JSONArray ticks(&obj, "ticks");
- for (intptr_t i = 0; i < address_table_.length(); i++) {
- const AddressEntry& entry = address_table_[i];
- ticks.AddValueF("%" Px "", entry.pc);
- ticks.AddValueF("%" Pd "", entry.exclusive_ticks);
- ticks.AddValueF("%" Pd "", entry.inclusive_ticks);
- }
- }
- }
-
- private:
- void TickAddress(uword pc, bool exclusive) {
- const intptr_t length = address_table_.length();
- intptr_t i = 0;
- for (; i < length; i++) {
- AddressEntry& entry = address_table_[i];
- if (entry.pc == pc) {
- // Tick the address entry.
- entry.tick(exclusive);
- return;
- }
- if (entry.pc > pc) {
- break;
- }
- }
- // New address, add entry.
- AddressEntry entry;
- entry.pc = pc;
- entry.exclusive_ticks = 0;
- entry.inclusive_ticks = 0;
- entry.tick(exclusive);
- if (i < length) {
- // Insert at i.
- address_table_.InsertAt(i, entry);
- } else {
- // Add to end.
- address_table_.Add(entry);
- }
- }
-
- void GenerateAndSetSymbolName(const char* prefix) {
- const intptr_t kBuffSize = 512;
- char buff[kBuffSize];
- OS::SNPrint(&buff[0], kBuffSize-1, "%s [%" Px ", %" Px ")",
- prefix, start(), end());
- SetName(buff);
- }
-
- // CodeRegion kind.
- const Kind kind_;
- // CodeRegion start address.
- uword start_;
- // CodeRegion end address.
- uword end_;
- // Inclusive ticks.
- intptr_t inclusive_ticks_;
- // Exclusive ticks.
- intptr_t exclusive_ticks_;
- // Inclusive tick serial number, ensures that each CodeRegion is only given
- // a single inclusive tick per sample.
- intptr_t inclusive_tick_serial_;
- // Name of code region.
- const char* name_;
- // The compilation timestamp associated with this code region.
- int64_t compile_timestamp_;
- // Dart code object (may be null).
- const Code& code_;
- // Pointer to ProfileFunction.
- ProfileFunction* profile_function_;
- // Final code table index.
- intptr_t code_table_index_;
- ZoneGrowableArray<AddressEntry> address_table_;
- DISALLOW_COPY_AND_ASSIGN(CodeRegion);
-};
+ function_ = function;
+ return function_;
+}
-// A sorted table of CodeRegions. Does not allow for overlap.
-class CodeRegionTable : public ValueObject {
+typedef bool (*RangeCompare)(uword pc, uword region_start, uword region_end);
+
+class ProfileCodeTable : public ZoneAllocated {
public:
- enum TickResult {
- kTicked = 0, // CodeRegion found and ticked.
- kNotFound = -1, // No CodeRegion found.
- kNewerCode = -2, // CodeRegion found but it was compiled after sample.
- };
-
- CodeRegionTable() :
- code_region_table_(new ZoneGrowableArray<CodeRegion*>(64)) {
+ ProfileCodeTable()
+ : table_(8) {
}
- // Ticks the CodeRegion containing pc if it is alive at timestamp.
- TickResult Tick(uword pc,
- bool exclusive,
- intptr_t serial,
- int64_t timestamp) {
- intptr_t index = FindIndex(pc);
- if (index < 0) {
- // Not found.
- return kNotFound;
- }
- ASSERT(index < code_region_table_->length());
- CodeRegion* region = At(index);
- if (region->compile_timestamp() > timestamp) {
- // Compiled after tick.
- return kNewerCode;
- }
- region->Tick(pc, exclusive, serial);
- return kTicked;
+ intptr_t length() const { return table_.length(); }
+
+ ProfileCode* At(intptr_t index) const {
+ ASSERT(index >= 0);
+ ASSERT(index < length());
+ return table_[index];
}
- // Table length.
- intptr_t Length() const { return code_region_table_->length(); }
-
- // Get the CodeRegion at index.
- CodeRegion* At(intptr_t index) const {
- return (*code_region_table_)[index];
- }
-
- // Find the table index to the CodeRegion containing pc.
+ // Find the table index to the ProfileCode containing pc.
// Returns < 0 if not found.
- intptr_t FindIndex(uword pc) const {
- intptr_t index = FindRegionIndex(pc, &CompareLowerBound);
- const CodeRegion* code_region = NULL;
- if (index == code_region_table_->length()) {
+ intptr_t FindCodeIndexForPC(uword pc) const {
+ intptr_t index = FindCodeIndex(pc, &CompareLowerBound);
+ if (index == length()) {
// Not present.
return -1;
}
- code_region = At(index);
- if (code_region->contains(pc)) {
- // Found at index.
- return index;
+ const ProfileCode* code = At(index);
+ if (!code->Contains(pc)) {
+ // Not present.
+ return -1;
}
- return -2;
+ // Found at index.
+ return index;
}
- // Insert code_region into the table. Returns the table index where the
- // CodeRegion was inserted. Will merge with an overlapping CodeRegion if
- // one is present.
- intptr_t InsertCodeRegion(CodeRegion* code_region) {
- const uword start = code_region->start();
- const uword end = code_region->end();
- const intptr_t length = code_region_table_->length();
+ ProfileCode* FindCodeForPC(uword pc) const {
+ intptr_t index = FindCodeIndexForPC(pc);
+ if (index < 0) {
+ return NULL;
+ }
+ return At(index);
+ }
+
+ // Insert |new_code| into the table. Returns the table index where |new_code|
+ // was inserted. Will merge with an overlapping ProfileCode if one is present.
+ intptr_t InsertCode(ProfileCode* new_code) {
+ const uword start = new_code->start();
+ const uword end = new_code->end();
+ const intptr_t length = table_.length();
if (length == 0) {
- code_region_table_->Add(code_region);
+ table_.Add(new_code);
return length;
}
- // Determine the correct place to insert or merge code_region into table.
- intptr_t lo = FindRegionIndex(start, &CompareLowerBound);
- intptr_t hi = FindRegionIndex(end - 1, &CompareUpperBound);
+ // Determine the correct place to insert or merge |new_code| into table.
+ intptr_t lo = FindCodeIndex(start, &CompareLowerBound);
+ intptr_t hi = FindCodeIndex(end - 1, &CompareUpperBound);
// TODO(johnmccutchan): Simplify below logic.
if ((lo == length) && (hi == length)) {
lo = length - 1;
}
if (lo == length) {
- CodeRegion* region = At(hi);
- if (region->overlaps(code_region)) {
- HandleOverlap(region, code_region, start, end);
+ ProfileCode* code = At(hi);
+ if (code->Overlaps(new_code)) {
+ HandleOverlap(code, new_code, start, end);
return hi;
}
- code_region_table_->Add(code_region);
+ table_.Add(new_code);
return length;
} else if (hi == length) {
- CodeRegion* region = At(lo);
- if (region->overlaps(code_region)) {
- HandleOverlap(region, code_region, start, end);
+ ProfileCode* code = At(lo);
+ if (code->Overlaps(new_code)) {
+ HandleOverlap(code, new_code, start, end);
return lo;
}
- code_region_table_->Add(code_region);
+ table_.Add(new_code);
return length;
} else if (lo == hi) {
- CodeRegion* region = At(lo);
- if (region->overlaps(code_region)) {
- HandleOverlap(region, code_region, start, end);
+ ProfileCode* code = At(lo);
+ if (code->Overlaps(new_code)) {
+ HandleOverlap(code, new_code, start, end);
return lo;
}
- code_region_table_->InsertAt(lo, code_region);
+ table_.InsertAt(lo, new_code);
return lo;
} else {
- CodeRegion* region = At(lo);
- if (region->overlaps(code_region)) {
- HandleOverlap(region, code_region, start, end);
+ ProfileCode* code = At(lo);
+ if (code->Overlaps(new_code)) {
+ HandleOverlap(code, new_code, start, end);
return lo;
}
- region = At(hi);
- if (region->overlaps(code_region)) {
- HandleOverlap(region, code_region, start, end);
+ code = At(hi);
+ if (code->Overlaps(new_code)) {
+ HandleOverlap(code, new_code, start, end);
return hi;
}
- code_region_table_->InsertAt(hi, code_region);
+ table_.InsertAt(hi, new_code);
return hi;
}
UNREACHABLE();
}
- void Verify() {
- VerifyOrder();
- VerifyOverlap();
- }
-
- void DebugPrint() {
- OS::Print("Dumping CodeRegionTable:\n");
- for (intptr_t i = 0; i < code_region_table_->length(); i++) {
- CodeRegion* region = At(i);
- region->DebugPrint();
- }
- }
-
private:
- intptr_t FindRegionIndex(uword pc, RegionCompare comparator) const {
+ intptr_t FindCodeIndex(uword pc, RangeCompare comparator) const {
ASSERT(comparator != NULL);
- intptr_t count = code_region_table_->length();
+ intptr_t count = table_.length();
intptr_t first = 0;
while (count > 0) {
intptr_t it = first;
intptr_t step = count / 2;
it += step;
- const CodeRegion* code_region = At(it);
- if (comparator(pc, code_region->start(), code_region->end())) {
+ const ProfileCode* code = At(it);
+ if (comparator(pc, code->start(), code->end())) {
first = ++it;
count -= (step + 1);
} else {
@@ -902,375 +726,124 @@
return end <= pc;
}
- void HandleOverlap(CodeRegion* region, CodeRegion* code_region,
+ void HandleOverlap(ProfileCode* existing, ProfileCode* code,
uword start, uword end) {
// We should never see overlapping Dart code regions.
- ASSERT(region->kind() != CodeRegion::kDartCode);
+ ASSERT(existing->kind() != ProfileCode::kDartCode);
// We should never see overlapping Tag code regions.
- ASSERT(region->kind() != CodeRegion::kTagCode);
+ ASSERT(existing->kind() != ProfileCode::kTagCode);
// When code regions overlap, they should be of the same kind.
- ASSERT(region->kind() == code_region->kind());
- region->AdjustExtent(start, end);
+ ASSERT(existing->kind() == code->kind());
+ existing->AdjustExtent(start, end);
}
void VerifyOrder() {
- const intptr_t length = code_region_table_->length();
+ const intptr_t length = table_.length();
if (length == 0) {
return;
}
- uword last = (*code_region_table_)[0]->end();
+ uword last = table_[0]->end();
for (intptr_t i = 1; i < length; i++) {
- CodeRegion* a = (*code_region_table_)[i];
+ ProfileCode* a = table_[i];
ASSERT(last <= a->start());
last = a->end();
}
}
void VerifyOverlap() {
- const intptr_t length = code_region_table_->length();
+ const intptr_t length = table_.length();
for (intptr_t i = 0; i < length; i++) {
- CodeRegion* a = (*code_region_table_)[i];
+ ProfileCode* a = table_[i];
for (intptr_t j = i+1; j < length; j++) {
- CodeRegion* b = (*code_region_table_)[j];
- ASSERT(!a->contains(b->start()) &&
- !a->contains(b->end() - 1) &&
- !b->contains(a->start()) &&
- !b->contains(a->end() - 1));
+ ProfileCode* b = table_[j];
+ ASSERT(!a->Contains(b->start()) &&
+ !a->Contains(b->end() - 1) &&
+ !b->Contains(a->start()) &&
+ !b->Contains(a->end() - 1));
}
}
}
- ZoneGrowableArray<CodeRegion*>* code_region_table_;
+ ZoneGrowableArray<ProfileCode*> table_;
};
-class CodeRegionTableBuilder {
+ProfileTrieNode::ProfileTrieNode(intptr_t table_index)
+ : table_index_(table_index),
+ count_(0),
+ children_(0) {
+ ASSERT(table_index_ >= 0);
+}
+
+
+ProfileTrieNode::~ProfileTrieNode() {
+}
+
+
+void ProfileTrieNode::SortChildren() {
+ children_.Sort(ProfileTrieNodeCompare);
+ // Recurse.
+ for (intptr_t i = 0; i < children_.length(); i++) {
+ children_[i]->SortChildren();
+ }
+}
+
+
+intptr_t ProfileTrieNode::IndexOf(ProfileTrieNode* node) {
+ for (intptr_t i = 0; i < children_.length(); i++) {
+ if (children_[i] == node) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+class ProfileCodeTrieNode : public ProfileTrieNode {
public:
- CodeRegionTableBuilder(Isolate* isolate,
- CodeRegionTable* live_code_table,
- CodeRegionTable* dead_code_table,
- CodeRegionTable* tag_code_table,
- DeoptimizedCodeSet* deoptimized_code)
- : live_code_table_(live_code_table),
- dead_code_table_(dead_code_table),
- tag_code_table_(tag_code_table),
- isolate_(isolate),
- vm_isolate_(Dart::vm_isolate()),
- null_code_(Code::ZoneHandle()),
- deoptimized_code_(deoptimized_code) {
- ASSERT(live_code_table_ != NULL);
- ASSERT(dead_code_table_ != NULL);
- ASSERT(tag_code_table_ != NULL);
- ASSERT(isolate_ != NULL);
- ASSERT(vm_isolate_ != NULL);
- ASSERT(null_code_.IsNull());
- frames_ = 0;
- min_time_ = kMaxInt64;
- max_time_ = 0;
+ explicit ProfileCodeTrieNode(intptr_t table_index)
+ : ProfileTrieNode(table_index) {
}
- void Build(ProcessedSampleBuffer* buffer) {
- for (intptr_t i = 0; i < buffer->length(); i++) {
- ProcessedSample* sample = buffer->At(i);
- VisitSample(i, sample);
+ void PrintToJSONArray(JSONArray* array) const {
+ ASSERT(array != NULL);
+ // Write CodeRegion index.
+ array->AddValue(table_index());
+ // Write count.
+ array->AddValue(count());
+ // Write number of children.
+ intptr_t child_count = NumChildren();
+ array->AddValue(child_count);
+ // Recurse.
+ for (intptr_t i = 0; i < child_count; i++) {
+ children_[i]->PrintToJSONArray(array);
}
}
- intptr_t frames() const { return frames_; }
-
- intptr_t TimeDeltaMicros() const {
- return static_cast<intptr_t>(max_time_ - min_time_);
- }
- int64_t max_time() const { return max_time_; }
-
- private:
- void VisitSample(intptr_t serial, ProcessedSample* sample) {
- int64_t timestamp = sample->timestamp();
- if (timestamp > max_time_) {
- max_time_ = timestamp;
- }
- if (timestamp < min_time_) {
- min_time_ = timestamp;
- }
-
- // Make sure VM tag is created.
- if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
- CreateTag(VMTag::kNativeTagId);
- } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
- CreateTag(VMTag::kRuntimeTagId);
- }
- CreateTag(sample->vm_tag());
-
- // Make sure user tag is created.
- CreateUserTag(sample->user_tag());
-
- // Exclusive tick for top frame if the first frame was executing.
- if (!sample->first_frame_executing()) {
- Tick(sample->At(0), true, serial, timestamp);
- }
-
- // Inclusive tick for all frames.
- for (intptr_t i = 0; i < sample->length(); i++) {
- ASSERT(sample->At(i) != 0);
- frames_++;
- Tick(sample->At(i), false, serial, timestamp);
- }
- }
-
- void CreateTag(uword tag) {
- intptr_t index = tag_code_table_->FindIndex(tag);
- if (index >= 0) {
- // Already created.
- return;
- }
- CodeRegion* region = new CodeRegion(CodeRegion::kTagCode,
- tag,
- tag + 1,
- 0,
- null_code_);
- index = tag_code_table_->InsertCodeRegion(region);
- ASSERT(index >= 0);
- }
-
- void CreateUserTag(uword tag) {
- if (tag == 0) {
- // None set.
- return;
- }
- return CreateTag(tag);
- }
-
- void Tick(uword pc, bool exclusive, intptr_t serial, int64_t timestamp) {
- CodeRegionTable::TickResult r;
- if (exclusive) {
- // Exclusive ticks do not have an associated serial.
- serial = -1;
- }
-
- r = live_code_table_->Tick(pc, exclusive, serial, timestamp);
- if (r == CodeRegionTable::kTicked) {
- // Live code found and ticked.
- return;
- }
-
- if (r == CodeRegionTable::kNewerCode) {
- // Code has been overwritten by newer code.
- // Update shadow table of dead code regions.
- r = dead_code_table_->Tick(pc, exclusive, serial, timestamp);
- ASSERT(r != CodeRegionTable::kNewerCode);
- if (r == CodeRegionTable::kTicked) {
- // Dead code found and ticked.
- return;
+ ProfileCodeTrieNode* GetChild(intptr_t child_table_index) {
+ const intptr_t length = NumChildren();
+ intptr_t i = 0;
+ while (i < length) {
+ ProfileCodeTrieNode* child =
+ reinterpret_cast<ProfileCodeTrieNode*>(children_[i]);
+ if (child->table_index() == child_table_index) {
+ return child;
}
- ASSERT(r == CodeRegionTable::kNotFound);
- CreateAndTickDeadCodeRegion(pc, exclusive, serial);
- return;
- }
-
- // Create new live CodeRegion.
- ASSERT(r == CodeRegionTable::kNotFound);
- CodeRegion* region = CreateCodeRegion(pc);
- intptr_t index = live_code_table_->InsertCodeRegion(region);
- ASSERT(index >= 0);
- region = live_code_table_->At(index);
- if (region->compile_timestamp() <= timestamp) {
- region->Tick(pc, exclusive, serial);
- return;
- }
-
- // We have created a new code region but it's for a CodeRegion
- // compiled after the sample.
- ASSERT(region->kind() == CodeRegion::kDartCode);
- CreateAndTickDeadCodeRegion(pc, exclusive, serial);
- }
-
- void CreateAndTickDeadCodeRegion(uword pc, bool exclusive, intptr_t serial) {
- // Need to create dead code.
- CodeRegion* region = new CodeRegion(CodeRegion::kReusedCode,
- pc,
- pc + 1,
- 0,
- null_code_);
- intptr_t index = dead_code_table_->InsertCodeRegion(region);
- ASSERT(index >= 0);
- dead_code_table_->At(index)->Tick(pc, exclusive, serial);
- }
-
- CodeRegion* CreateCodeRegion(uword pc) {
- const intptr_t kDartCodeAlignment = OS::PreferredCodeAlignment();
- const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1);
- Code& code = Code::Handle(isolate_);
-
- // Check current isolate for pc.
- if (isolate_->heap()->CodeContains(pc)) {
- code ^= Code::LookupCode(pc);
- if (!code.IsNull()) {
- deoptimized_code_->Add(code);
- return new CodeRegion(CodeRegion::kDartCode,
- code.EntryPoint(),
- code.EntryPoint() + code.Size(),
- code.compile_timestamp(),
- code);
+ if (child->table_index() > child_table_index) {
+ break;
}
- return new CodeRegion(CodeRegion::kCollectedCode,
- pc,
- (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
- 0,
- code);
+ i++;
}
-
- // Check VM isolate for pc.
- if (vm_isolate_->heap()->CodeContains(pc)) {
- code ^= Code::LookupCodeInVmIsolate(pc);
- if (!code.IsNull()) {
- return new CodeRegion(CodeRegion::kDartCode,
- code.EntryPoint(),
- code.EntryPoint() + code.Size(),
- code.compile_timestamp(),
- code);
- }
- return new CodeRegion(CodeRegion::kCollectedCode,
- pc,
- (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
- 0,
- code);
+ ProfileCodeTrieNode* child = new ProfileCodeTrieNode(child_table_index);
+ if (i < length) {
+ // Insert at i.
+ children_.InsertAt(i, reinterpret_cast<ProfileTrieNode*>(child));
+ } else {
+ // Add to end.
+ children_.Add(reinterpret_cast<ProfileTrieNode*>(child));
}
-
- // Check NativeSymbolResolver for pc.
- uintptr_t native_start = 0;
- char* native_name = NativeSymbolResolver::LookupSymbolName(pc,
- &native_start);
- if (native_name == NULL) {
- // No native name found.
- return new CodeRegion(CodeRegion::kNativeCode,
- pc,
- pc + 1,
- 0,
- code);
- }
- ASSERT(pc >= native_start);
- CodeRegion* code_region =
- new CodeRegion(CodeRegion::kNativeCode,
- native_start,
- pc + 1,
- 0,
- code);
- code_region->SetName(native_name);
- free(native_name);
- return code_region;
+ return child;
}
-
- intptr_t frames_;
- int64_t min_time_;
- int64_t max_time_;
- CodeRegionTable* live_code_table_;
- CodeRegionTable* dead_code_table_;
- CodeRegionTable* tag_code_table_;
- Isolate* isolate_;
- Isolate* vm_isolate_;
- const Code& null_code_;
- DeoptimizedCodeSet* deoptimized_code_;
-};
-
-
-class CodeRegionFunctionMapper : public ValueObject {
- public:
- CodeRegionFunctionMapper(Isolate* isolate,
- CodeRegionTable* live_code_table,
- CodeRegionTable* dead_code_table,
- CodeRegionTable* tag_code_table,
- ProfileFunctionTable* function_table)
- : isolate_(isolate),
- live_code_table_(live_code_table),
- dead_code_table_(dead_code_table),
- tag_code_table_(tag_code_table),
- function_table_(function_table) {
- ASSERT(isolate_ != NULL);
- ASSERT(live_code_table_ != NULL);
- ASSERT(dead_code_table_ != NULL);
- ASSERT(tag_code_table_ != NULL);
- dead_code_table_offset_ = live_code_table_->Length();
- tag_code_table_offset_ = dead_code_table_offset_ +
- dead_code_table_->Length();
-
- const Code& null_code = Code::ZoneHandle();
-
- // Create the truncated tag.
- intptr_t truncated_index =
- tag_code_table_->FindIndex(VMTag::kTruncatedTagId);
- ASSERT(truncated_index < 0);
- CodeRegion* truncated =
- new CodeRegion(CodeRegion::kTagCode,
- VMTag::kTruncatedTagId,
- VMTag::kTruncatedTagId + 1,
- 0,
- null_code);
- truncated_index = tag_code_table_->InsertCodeRegion(truncated);
- ASSERT(truncated_index >= 0);
-
- // Create the root tag.
- intptr_t root_index = tag_code_table_->FindIndex(VMTag::kRootTagId);
- ASSERT(root_index < 0);
- CodeRegion* root = new CodeRegion(CodeRegion::kTagCode,
- VMTag::kRootTagId,
- VMTag::kRootTagId + 1,
- 0,
- null_code);
- root_index = tag_code_table_->InsertCodeRegion(root);
- ASSERT(root_index >= 0);
- }
-
- void Map() {
- // Calculate final indexes in code table for each CodeRegion.
- for (intptr_t i = 0; i < live_code_table_->Length(); i++) {
- const intptr_t index = i;
- CodeRegion* region = live_code_table_->At(i);
- ASSERT(region != NULL);
- region->set_code_table_index(index);
- }
-
- for (intptr_t i = 0; i < dead_code_table_->Length(); i++) {
- const intptr_t index = dead_code_table_offset_ + i;
- CodeRegion* region = dead_code_table_->At(i);
- ASSERT(region != NULL);
- region->set_code_table_index(index);
- }
-
- for (intptr_t i = 0; i < tag_code_table_->Length(); i++) {
- const intptr_t index = tag_code_table_offset_ + i;
- CodeRegion* region = tag_code_table_->At(i);
- ASSERT(region != NULL);
- region->set_code_table_index(index);
- }
-
- // Associate a ProfileFunction with each CodeRegion.
- for (intptr_t i = 0; i < live_code_table_->Length(); i++) {
- CodeRegion* region = live_code_table_->At(i);
- ASSERT(region != NULL);
- region->SetFunctionAndName(function_table_);
- }
-
- for (intptr_t i = 0; i < dead_code_table_->Length(); i++) {
- CodeRegion* region = dead_code_table_->At(i);
- ASSERT(region != NULL);
- region->SetFunctionAndName(function_table_);
- }
-
- for (intptr_t i = 0; i < tag_code_table_->Length(); i++) {
- CodeRegion* region = tag_code_table_->At(i);
- ASSERT(region != NULL);
- region->SetFunctionAndName(function_table_);
- }
- }
-
- private:
- Isolate* isolate_;
- CodeRegionTable* live_code_table_;
- CodeRegionTable* dead_code_table_;
- CodeRegionTable* tag_code_table_;
- ProfileFunctionTable* function_table_;
- intptr_t dead_code_table_offset_;
- intptr_t tag_code_table_offset_;
};
@@ -1299,90 +872,26 @@
};
-class ProfileFunctionTrieNode : public ZoneAllocated {
+class ProfileFunctionTrieNode : public ProfileTrieNode {
public:
- explicit ProfileFunctionTrieNode(intptr_t profile_function_table_index)
- : profile_function_table_index_(profile_function_table_index),
- count_(0),
- code_objects_(new ZoneGrowableArray<ProfileFunctionTrieNodeCode>()) {
- }
-
- void Tick() {
- count_++;
- }
-
- intptr_t count() const {
- return count_;
- }
-
- intptr_t profile_function_table_index() const {
- return profile_function_table_index_;
- }
-
-
- ProfileFunctionTrieNode* GetChild(intptr_t child_index) {
- const intptr_t length = children_.length();
- intptr_t i = 0;
- while (i < length) {
- ProfileFunctionTrieNode* child = children_[i];
- if (child->profile_function_table_index() == child_index) {
- return child;
- }
- if (child->profile_function_table_index() > child_index) {
- break;
- }
- i++;
- }
- // Add new ProfileFunctionTrieNode, sorted by index.
- ProfileFunctionTrieNode* child =
- new ProfileFunctionTrieNode(child_index);
- if (i < length) {
- // Insert at i.
- children_.InsertAt(i, child);
- } else {
- // Add to end.
- children_.Add(child);
- }
- return child;
- }
-
- void AddCodeObjectIndex(intptr_t index) {
- for (intptr_t i = 0; i < code_objects_->length(); i++) {
- ProfileFunctionTrieNodeCode& code_object = (*code_objects_)[i];
- if (code_object.index() == index) {
- code_object.Tick();
- return;
- }
- }
- ProfileFunctionTrieNodeCode code_object(index);
- code_object.Tick();
- code_objects_->Add(code_object);
- }
-
- // This should only be called after the trie is completely built.
- void SortByCount() {
- code_objects_->Sort(ProfileFunctionTrieNodeCodeCompare);
- children_.Sort(ProfileFunctionTrieNodeCompare);
- intptr_t child_count = children_.length();
- // Recurse.
- for (intptr_t i = 0; i < child_count; i++) {
- children_[i]->SortByCount();
- }
+ explicit ProfileFunctionTrieNode(intptr_t table_index)
+ : ProfileTrieNode(table_index),
+ code_objects_(1) {
}
void PrintToJSONArray(JSONArray* array) const {
ASSERT(array != NULL);
// Write CodeRegion index.
- array->AddValue(profile_function_table_index_);
+ array->AddValue(table_index());
// Write count.
- array->AddValue(count_);
+ array->AddValue(count());
// Write number of code objects.
- intptr_t code_count = code_objects_->length();
+ intptr_t code_count = code_objects_.length();
array->AddValue(code_count);
// Write each code object index and ticks.
for (intptr_t i = 0; i < code_count; i++) {
- array->AddValue((*code_objects_)[i].index());
- array->AddValue((*code_objects_)[i].ticks());
+ array->AddValue(code_objects_[i].index());
+ array->AddValue(code_objects_[i].ticks());
}
// Write number of children.
intptr_t child_count = children_.length();
@@ -1393,377 +902,397 @@
}
}
- private:
- static int ProfileFunctionTrieNodeCodeCompare(
- const ProfileFunctionTrieNodeCode* a,
- const ProfileFunctionTrieNodeCode* b) {
- ASSERT(a != NULL);
- ASSERT(b != NULL);
- return b->ticks() - a->ticks();
- }
-
- static int ProfileFunctionTrieNodeCompare(ProfileFunctionTrieNode* const* a,
- ProfileFunctionTrieNode* const* b) {
- ASSERT(a != NULL);
- ASSERT(b != NULL);
- return (*b)->count() - (*a)->count();
- }
-
- const intptr_t profile_function_table_index_;
- intptr_t count_;
- ZoneGrowableArray<ProfileFunctionTrieNode*> children_;
- ZoneGrowableArray<ProfileFunctionTrieNodeCode>* code_objects_;
-};
-
-
-class TrieBuilder : public ValueObject {
- public:
- TrieBuilder(CodeRegionTable* live_code_table,
- CodeRegionTable* dead_code_table,
- CodeRegionTable* tag_code_table)
- : live_code_table_(live_code_table),
- dead_code_table_(dead_code_table),
- tag_code_table_(tag_code_table) {
- ASSERT(live_code_table_ != NULL);
- ASSERT(dead_code_table_ != NULL);
- ASSERT(tag_code_table_ != NULL);
- }
-
- ProfilerService::TagOrder tag_order() const {
- return tag_order_;
- }
-
- void set_tag_order(ProfilerService::TagOrder tag_order) {
- tag_order_ = tag_order;
- }
-
- protected:
- intptr_t FindTagIndex(uword tag) const {
- if (tag == 0) {
- UNREACHABLE();
- return -1;
- }
- intptr_t index = tag_code_table_->FindIndex(tag);
- if (index < 0) {
- UNREACHABLE();
- return -1;
- }
- ASSERT(index >= 0);
- CodeRegion* region = tag_code_table_->At(index);
- ASSERT(region->contains(tag));
- return region->code_table_index();
- }
-
- intptr_t FindDeadIndex(uword pc, int64_t timestamp) const {
- intptr_t index = dead_code_table_->FindIndex(pc);
- if (index < 0) {
- OS::Print("%" Px " cannot be found\n", pc);
- return -1;
- }
- CodeRegion* region = dead_code_table_->At(index);
- ASSERT(region->contains(pc));
- ASSERT(region->compile_timestamp() <= timestamp);
- return region->code_table_index();
- }
-
- intptr_t FindFinalIndex(uword pc, int64_t timestamp) const {
- intptr_t index = live_code_table_->FindIndex(pc);
- if (index < 0) {
- // Try dead code table.
- return FindDeadIndex(pc, timestamp);
- }
- CodeRegion* region = live_code_table_->At(index);
- ASSERT(region->contains(pc));
- if (region->compile_timestamp() > timestamp) {
- // Overwritten code, find in dead code table.
- return FindDeadIndex(pc, timestamp);
- }
- ASSERT(region->compile_timestamp() <= timestamp);
- return region->code_table_index();
- }
-
- bool vm_tags_emitted() const {
- return (tag_order_ == ProfilerService::kUserVM) ||
- (tag_order_ == ProfilerService::kVMUser) ||
- (tag_order_ == ProfilerService::kVM);
- }
-
- CodeRegion* FindCodeObject(uword pc, int64_t timestamp) const {
- intptr_t index = live_code_table_->FindIndex(pc);
- if (index < 0) {
- return NULL;
- }
- CodeRegion* region = live_code_table_->At(index);
- ASSERT(region->contains(pc));
- if (region->compile_timestamp() > timestamp) {
- // Overwritten code, find in dead code table.
- index = dead_code_table_->FindIndex(pc);
- if (index < 0) {
- return NULL;
+ ProfileFunctionTrieNode* GetChild(intptr_t child_table_index) {
+ const intptr_t length = NumChildren();
+ intptr_t i = 0;
+ while (i < length) {
+ ProfileFunctionTrieNode* child =
+ reinterpret_cast<ProfileFunctionTrieNode*>(children_[i]);
+ if (child->table_index() == child_table_index) {
+ return child;
}
- region = dead_code_table_->At(index);
- ASSERT(region->contains(pc));
- ASSERT(region->compile_timestamp() <= timestamp);
- return region;
+ if (child->table_index() > child_table_index) {
+ break;
+ }
+ i++;
}
- ASSERT(region->compile_timestamp() <= timestamp);
- return region;
- }
-
- CodeRegionTable* live_code_table_;
- CodeRegionTable* dead_code_table_;
- CodeRegionTable* tag_code_table_;
- ProfilerService::TagOrder tag_order_;
-};
-
-
-class ProfileFunctionTrieBuilder : public TrieBuilder {
- public:
- ProfileFunctionTrieBuilder(CodeRegionTable* live_code_table,
- CodeRegionTable* dead_code_table,
- CodeRegionTable* tag_code_table,
- ProfileFunctionTable* function_table)
- : TrieBuilder(live_code_table, dead_code_table, tag_code_table),
- function_table_(function_table),
- inclusive_tree_(false) {
- ASSERT(function_table_ != NULL);
- set_tag_order(ProfilerService::kUserVM);
-
- // Verify that the truncated tag exists.
- ASSERT(tag_code_table_->FindIndex(VMTag::kTruncatedTagId) >= 0);
-
- // Verify that the root tag exists.
- intptr_t root_index = tag_code_table_->FindIndex(VMTag::kRootTagId);
- ASSERT(root_index >= 0);
-
- // Setup root.
- CodeRegion* region = tag_code_table_->At(root_index);
- ASSERT(region != NULL);
- ProfileFunction* function = region->function();
- ASSERT(function != NULL);
-
- exclusive_root_ = new ProfileFunctionTrieNode(function->index());
- inclusive_root_ = new ProfileFunctionTrieNode(function->index());
- }
-
- void VisitSample(intptr_t sample_idx, ProcessedSample* sample) {
- inclusive_tree_ = false;
- ProcessSampleExclusive(sample_idx, sample);
- inclusive_tree_ = true;
- ProcessSampleInclusive(sample_idx, sample);
- }
-
- void Build(ProcessedSampleBuffer* buffer) {
- for (intptr_t i = 0; i < buffer->length(); i++) {
- ProcessedSample* sample = buffer->At(i);
- VisitSample(i, sample);
- }
- }
-
- ProfileFunctionTrieNode* exclusive_root() const {
- return exclusive_root_;
- }
-
- ProfileFunctionTrieNode* inclusive_root() const {
- return inclusive_root_;
- }
-
- ProfilerService::TagOrder tag_order() const {
- return tag_order_;
- }
-
- bool vm_tags_emitted() const {
- return (tag_order_ == ProfilerService::kUserVM) ||
- (tag_order_ == ProfilerService::kVMUser) ||
- (tag_order_ == ProfilerService::kVM);
- }
-
- void set_tag_order(ProfilerService::TagOrder tag_order) {
- tag_order_ = tag_order;
- }
-
- private:
- void ProcessSampleInclusive(intptr_t sample_idx, ProcessedSample* sample) {
- // Give the root a tick.
- inclusive_root_->Tick();
- ProfileFunctionTrieNode* current = inclusive_root_;
- current = AppendTags(sample, current);
- if (sample->truncated()) {
- InclusiveTickTruncatedTag();
- current = AppendTruncatedTag(current);
- }
- // Walk the sampled PCs.
- for (intptr_t i = sample->length() - 1; i >= 0; i--) {
- ASSERT(sample->At(i) != 0);
- current = ProcessPC(sample->At(i),
- sample->timestamp(),
- current,
- sample_idx,
- (i == 0),
- !sample->first_frame_executing() && (i == 0));
- }
- }
-
- void ProcessSampleExclusive(intptr_t sample_idx, ProcessedSample* sample) {
- // Give the root a tick.
- exclusive_root_->Tick();
- ProfileFunctionTrieNode* current = exclusive_root_;
- current = AppendTags(sample, current);
- // Walk the sampled PCs.
- for (intptr_t i = 0; i < sample->length(); i++) {
- ASSERT(sample->At(i) != 0);
- current = ProcessPC(sample->At(i),
- sample->timestamp(),
- current,
- sample_idx,
- (i == 0),
- !sample->first_frame_executing() && (i == 0));
- }
- if (sample->truncated()) {
- current = AppendTruncatedTag(current);
- }
- }
-
- ProfileFunctionTrieNode* AppendUserTag(ProcessedSample* sample,
- ProfileFunctionTrieNode* current) {
- intptr_t user_tag_index = FindTagFunctionIndex(sample->user_tag());
- if (user_tag_index >= 0) {
- current = current->GetChild(user_tag_index);
- // Give the tag a tick.
- current->Tick();
- }
- return current;
- }
-
-
- ProfileFunctionTrieNode* AppendTruncatedTag(
- ProfileFunctionTrieNode* current) {
- intptr_t truncated_tag_index = FindTagFunctionIndex(VMTag::kTruncatedTagId);
- ASSERT(truncated_tag_index >= 0);
- current = current->GetChild(truncated_tag_index);
- current->Tick();
- return current;
- }
-
- void InclusiveTickTruncatedTag() {
- intptr_t index = tag_code_table_->FindIndex(VMTag::kTruncatedTagId);
- CodeRegion* region = tag_code_table_->At(index);
- ProfileFunction* function = region->function();
- function->inc_inclusive_ticks();
- }
-
- ProfileFunctionTrieNode* AppendVMTag(ProcessedSample* sample,
- ProfileFunctionTrieNode* current) {
- if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
- // Insert a dummy kNativeTagId node.
- intptr_t tag_index = FindTagFunctionIndex(VMTag::kNativeTagId);
- current = current->GetChild(tag_index);
- // Give the tag a tick.
- current->Tick();
- } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
- // Insert a dummy kRuntimeTagId node.
- intptr_t tag_index = FindTagFunctionIndex(VMTag::kRuntimeTagId);
- current = current->GetChild(tag_index);
- // Give the tag a tick.
- current->Tick();
+ ProfileFunctionTrieNode* child =
+ new ProfileFunctionTrieNode(child_table_index);
+ if (i < length) {
+ // Insert at i.
+ children_.InsertAt(i, reinterpret_cast<ProfileTrieNode*>(child));
} else {
- intptr_t tag_index = FindTagFunctionIndex(sample->vm_tag());
- current = current->GetChild(tag_index);
- // Give the tag a tick.
- current->Tick();
+ // Add to end.
+ children_.Add(reinterpret_cast<ProfileTrieNode*>(child));
}
- return current;
+ return child;
}
- ProfileFunctionTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
- ProcessedSample* sample, ProfileFunctionTrieNode* current) {
- // Only Native and Runtime entries have a second VM tag.
- if (!VMTag::IsNativeEntryTag(sample->vm_tag()) &&
- !VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
- return current;
- }
- intptr_t tag_index = FindTagFunctionIndex(sample->vm_tag());
- current = current->GetChild(tag_index);
- // Give the tag a tick.
- current->Tick();
- return current;
- }
-
- ProfileFunctionTrieNode* AppendVMTags(ProcessedSample* sample,
- ProfileFunctionTrieNode* current) {
- current = AppendVMTag(sample, current);
- current = AppendSpecificNativeRuntimeEntryVMTag(sample, current);
- return current;
- }
-
- ProfileFunctionTrieNode* AppendTags(ProcessedSample* sample,
- ProfileFunctionTrieNode* current) {
- // None.
- if (tag_order() == ProfilerService::kNoTags) {
- return current;
- }
- // User first.
- if ((tag_order() == ProfilerService::kUserVM) ||
- (tag_order() == ProfilerService::kUser)) {
- current = AppendUserTag(sample, current);
- // Only user.
- if (tag_order() == ProfilerService::kUser) {
- return current;
+ void AddCodeObjectIndex(intptr_t index) {
+ for (intptr_t i = 0; i < code_objects_.length(); i++) {
+ ProfileFunctionTrieNodeCode& code_object = code_objects_[i];
+ if (code_object.index() == index) {
+ code_object.Tick();
+ return;
}
- return AppendVMTags(sample, current);
}
- // VM first.
- ASSERT((tag_order() == ProfilerService::kVMUser) ||
- (tag_order() == ProfilerService::kVM));
- current = AppendVMTags(sample, current);
- // Only VM.
- if (tag_order() == ProfilerService::kVM) {
- return current;
- }
- return AppendUserTag(sample, current);
+ ProfileFunctionTrieNodeCode code_object(index);
+ code_object.Tick();
+ code_objects_.Add(code_object);
}
- intptr_t FindTagFunctionIndex(uword tag) const {
- if (tag == 0) {
- UNREACHABLE();
- return -1;
- }
- intptr_t index = tag_code_table_->FindIndex(tag);
- if (index < 0) {
- UNREACHABLE();
- return -1;
- }
- ASSERT(index >= 0);
- CodeRegion* region = tag_code_table_->At(index);
- ASSERT(region->contains(tag));
- ProfileFunction* function = region->function();
- ASSERT(function != NULL);
- return function->index();
+ private:
+ ZoneGrowableArray<ProfileFunctionTrieNodeCode> code_objects_;
+};
+
+
+class ProfileBuilder : public ValueObject {
+ public:
+ ProfileBuilder(Isolate* isolate,
+ SampleFilter* filter,
+ Profile::TagOrder tag_order,
+ Profile* profile)
+ : isolate_(isolate),
+ vm_isolate_(Dart::vm_isolate()),
+ filter_(filter),
+ tag_order_(tag_order),
+ profile_(profile),
+ deoptimized_code_(new DeoptimizedCodeSet(isolate)),
+ null_code_(Code::ZoneHandle()),
+ null_function_(Function::ZoneHandle()),
+ tick_functions_(false),
+ samples_(NULL) {
+ ASSERT(profile_ != NULL);
}
- void Dump(ProfileFunctionTrieNode* current) {
- int current_index = current->profile_function_table_index();
- ProfileFunction* function = function_table_->At(current_index);
- function->Dump();
- OS::Print("\n");
+ void Build() {
+ ScopeTimer sw("ProfileBuilder::Build", FLAG_trace_profiler);
+ FilterSamples();
+
+ Setup();
+ BuildCodeTable();
+ FinalizeCodeIndexes();
+ BuildFunctionTable();
+
+ BuildCodeTrie(Profile::kExclusiveCode);
+ BuildCodeTrie(Profile::kInclusiveCode);
+
+ BuildFunctionTrie(Profile::kExclusiveFunction);
+ BuildFunctionTrie(Profile::kInclusiveFunction);
}
- ProfileFunctionTrieNode* ProcessPC(uword pc,
- int64_t timestamp,
- ProfileFunctionTrieNode* current,
- intptr_t inclusive_serial,
- bool top_frame,
- bool exit_frame) {
- CodeRegion* region = FindCodeObject(pc, timestamp);
- if (region == NULL) {
- return current;
+ private:
+ static bool IsInclusiveTrie(Profile::TrieKind kind) {
+ return (kind == Profile::kInclusiveFunction) ||
+ (kind == Profile::kInclusiveCode);
+ }
+
+ void Setup() {
+ profile_->live_code_ = new ProfileCodeTable();
+ profile_->dead_code_ = new ProfileCodeTable();
+ profile_->tag_code_ = new ProfileCodeTable();
+ profile_->functions_ = new ProfileFunctionTable();
+ // Register some synthetic tags.
+ RegisterProfileCodeTag(VMTag::kRootTagId);
+ RegisterProfileCodeTag(VMTag::kTruncatedTagId);
+ }
+
+ void FilterSamples() {
+ ScopeTimer sw("ProfileBuilder::FilterSamples", FLAG_trace_profiler);
+ MutexLocker profiler_data_lock(isolate_->profiler_data_mutex());
+ IsolateProfilerData* profiler_data = isolate_->profiler_data();
+ if (profiler_data == NULL) {
+ return;
}
- const char* region_name = region->name();
- if (region_name == NULL) {
- region_name = "";
+ SampleBuffer* sample_buffer = profiler_data->sample_buffer();
+ if (sample_buffer == NULL) {
+ return;
}
- intptr_t code_index = region->code_table_index();
- const Code& code = Code::ZoneHandle(region->code());
+ samples_ = sample_buffer->BuildProcessedSampleBuffer(filter_);
+ profile_->sample_count_ = samples_->length();
+ }
+
+ void UpdateMinMaxTimes(int64_t timestamp) {
+ profile_->min_time_ =
+ timestamp < profile_->min_time_ ? timestamp : profile_->min_time_;
+ profile_->max_time_ =
+ timestamp > profile_->max_time_ ? timestamp : profile_->max_time_;
+ }
+
+ void BuildCodeTable() {
+ ScopeTimer sw("ProfileBuilder::BuildCodeTable", FLAG_trace_profiler);
+ for (intptr_t i = 0; i < samples_->length(); i++) {
+ ProcessedSample* sample = samples_->At(i);
+ const int64_t timestamp = sample->timestamp();
+
+ // This is our first pass over the sample buffer, use this as an
+ // opportunity to determine the min and max time ranges of this profile.
+ UpdateMinMaxTimes(timestamp);
+
+ // Make sure VM tag exists.
+ if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
+ RegisterProfileCodeTag(VMTag::kNativeTagId);
+ } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
+ RegisterProfileCodeTag(VMTag::kRuntimeTagId);
+ }
+ RegisterProfileCodeTag(sample->vm_tag());
+ // Make sure user tag exists.
+ RegisterProfileCodeTag(sample->user_tag());
+
+ // Make sure that a ProfileCode objects exist for all pcs in the sample
+ // and tick each one.
+ for (intptr_t i = 0; i < sample->length(); i++) {
+ const uword pc = sample->At(i);
+ ASSERT(pc != 0);
+ ProfileCode* code = RegisterProfileCode(pc, timestamp);
+ ASSERT(code != NULL);
+ code->Tick(pc, (i == 0), i);
+ }
+ }
+ }
+
+ void FinalizeCodeIndexes() {
+ ScopeTimer sw("ProfileBuilder::FinalizeCodeIndexes", FLAG_trace_profiler);
+ ProfileCodeTable* live_table = profile_->live_code_;
+ ProfileCodeTable* dead_table = profile_->dead_code_;
+ ProfileCodeTable* tag_table = profile_->tag_code_;
+ const intptr_t dead_code_index_offset = live_table->length();
+ const intptr_t tag_code_index_offset =
+ dead_table->length() + dead_code_index_offset;
+
+ profile_->dead_code_index_offset_ = dead_code_index_offset;
+ profile_->tag_code_index_offset_ = tag_code_index_offset;
+
+ for (intptr_t i = 0; i < live_table->length(); i++) {
+ const intptr_t index = i;
+ ProfileCode* code = live_table->At(i);
+ ASSERT(code != NULL);
+ code->set_code_table_index(index);
+ }
+
+ for (intptr_t i = 0; i < dead_table->length(); i++) {
+ const intptr_t index = dead_code_index_offset + i;
+ ProfileCode* code = dead_table->At(i);
+ ASSERT(code != NULL);
+ code->set_code_table_index(index);
+ }
+
+ for (intptr_t i = 0; i < tag_table->length(); i++) {
+ const intptr_t index = tag_code_index_offset + i;
+ ProfileCode* code = tag_table->At(i);
+ ASSERT(code != NULL);
+ code->set_code_table_index(index);
+ }
+ }
+
+ void BuildFunctionTable() {
+ ScopeTimer sw("ProfileBuilder::BuildFunctionTable", FLAG_trace_profiler);
+ ProfileCodeTable* live_table = profile_->live_code_;
+ ProfileCodeTable* dead_table = profile_->dead_code_;
+ ProfileCodeTable* tag_table = profile_->tag_code_;
+ ProfileFunctionTable* function_table = profile_->functions_;
+ for (intptr_t i = 0; i < live_table->length(); i++) {
+ ProfileCode* code = live_table->At(i);
+ ASSERT(code != NULL);
+ code->SetFunctionAndName(function_table);
+ }
+
+ for (intptr_t i = 0; i < dead_table->length(); i++) {
+ ProfileCode* code = dead_table->At(i);
+ ASSERT(code != NULL);
+ code->SetFunctionAndName(function_table);
+ }
+
+ for (intptr_t i = 0; i < tag_table->length(); i++) {
+ ProfileCode* code = tag_table->At(i);
+ ASSERT(code != NULL);
+ code->SetFunctionAndName(function_table);
+ }
+ }
+
+ void BuildCodeTrie(Profile::TrieKind kind) {
+ ProfileCodeTrieNode* root =
+ new ProfileCodeTrieNode(GetProfileCodeTagIndex(VMTag::kRootTagId));
+ if (IsInclusiveTrie(kind)) {
+ BuildInclusiveCodeTrie(root);
+ } else {
+ BuildExclusiveCodeTrie(root);
+ }
+ root->SortChildren();
+ profile_->roots_[static_cast<intptr_t>(kind)] = root;
+ }
+
+ void BuildInclusiveCodeTrie(ProfileCodeTrieNode* root) {
+ ScopeTimer sw("ProfileBuilder::BuildInclusiveCodeTrie",
+ FLAG_trace_profiler);
+ for (intptr_t i = 0; i < samples_->length(); i++) {
+ ProcessedSample* sample = samples_->At(i);
+
+ // Tick the root.
+ ProfileCodeTrieNode* current = root;
+ current->Tick();
+
+ // VM & User tags.
+ current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+
+ // Truncated tag.
+ if (sample->truncated()) {
+ current = AppendTruncatedTag(current);
+ }
+
+ // Walk the sampled PCs.
+ for (intptr_t j = sample->length() - 1; j >= 0; j--) {
+ ASSERT(sample->At(j) != 0);
+ intptr_t index =
+ GetProfileCodeIndex(sample->At(j), sample->timestamp());
+ ASSERT(index >= 0);
+ current = current->GetChild(index);
+ current->Tick();
+ }
+ }
+ }
+
+ void BuildExclusiveCodeTrie(ProfileCodeTrieNode* root) {
+ ScopeTimer sw("ProfileBuilder::BuildExclusiveCodeTrie",
+ FLAG_trace_profiler);
+ for (intptr_t i = 0; i < samples_->length(); i++) {
+ ProcessedSample* sample = samples_->At(i);
+
+ // Tick the root.
+ ProfileCodeTrieNode* current = root;
+ current->Tick();
+
+ // VM & User tags.
+ current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+
+ // Walk the sampled PCs.
+ for (intptr_t j = 0; j < sample->length(); j++) {
+ ASSERT(sample->At(j) != 0);
+ intptr_t index =
+ GetProfileCodeIndex(sample->At(j), sample->timestamp());
+ ASSERT(index >= 0);
+ current = current->GetChild(index);
+
+ if (j == 0) {
+ // Executing PC.
+ if (!sample->first_frame_executing() || vm_tags_emitted()) {
+ // Only tick if this isn't an exit frame or VM tags are emitted.
+ current->Tick();
+ }
+ } else {
+ // Caller PCs.
+ current->Tick();
+ }
+
+ current->Tick();
+ }
+
+ // Truncated tag.
+ if (sample->truncated()) {
+ current = AppendTruncatedTag(current);
+ }
+ }
+ }
+
+ void BuildFunctionTrie(Profile::TrieKind kind) {
+ ProfileFunctionTrieNode* root =
+ new ProfileFunctionTrieNode(
+ GetProfileFunctionTagIndex(VMTag::kRootTagId));
+ // We tick the functions while building the trie, but, we don't want to do
+ // it for both tries, just one.
+ tick_functions_ = IsInclusiveTrie(kind);
+ if (IsInclusiveTrie(kind)) {
+ BuildInclusiveFunctionTrie(root);
+ } else {
+ BuildExclusiveFunctionTrie(root);
+ }
+ root->SortChildren();
+ profile_->roots_[static_cast<intptr_t>(kind)] = root;
+ }
+
+ void BuildInclusiveFunctionTrie(ProfileFunctionTrieNode* root) {
+ ScopeTimer sw("ProfileBuilder::BuildInclusiveFunctionTrie",
+ FLAG_trace_profiler);
+ for (intptr_t i = 0; i < samples_->length(); i++) {
+ ProcessedSample* sample = samples_->At(i);
+
+ // Tick the root.
+ ProfileFunctionTrieNode* current = root;
+ current->Tick();
+
+ // VM & User tags.
+ current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+
+ // Truncated tag.
+ if (sample->truncated()) {
+ current = AppendTruncatedTag(current);
+ InclusiveTickTruncatedTag();
+ }
+
+ // Walk the sampled PCs.
+ for (intptr_t j = sample->length() - 1; j >= 0; j--) {
+ ASSERT(sample->At(j) != 0);
+ current = ProcessFunctionPC(
+ sample->At(j),
+ sample->timestamp(),
+ current,
+ i,
+ (j == 0),
+ sample->first_frame_executing(),
+ true);
+ }
+ }
+ }
+
+ void BuildExclusiveFunctionTrie(ProfileFunctionTrieNode* root) {
+ ScopeTimer sw("ProfileBuilder::BuildExclusiveFunctionTrie",
+ FLAG_trace_profiler);
+ for (intptr_t i = 0; i < samples_->length(); i++) {
+ ProcessedSample* sample = samples_->At(i);
+
+ // Tick the root.
+ ProfileFunctionTrieNode* current = root;
+ current->Tick();
+
+ // VM & User tags.
+ current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+
+ // Walk the sampled PCs.
+ for (intptr_t j = 0; j < sample->length(); j++) {
+ ASSERT(sample->At(j) != 0);
+ current = ProcessFunctionPC(
+ sample->At(j),
+ sample->timestamp(),
+ current,
+ i,
+ (j == 0),
+ sample->first_frame_executing(),
+ false);
+ }
+
+ // Truncated tag.
+ if (sample->truncated()) {
+ current = AppendTruncatedTag(current);
+ }
+ }
+ }
+
+ ProfileFunctionTrieNode* ProcessFunctionPC(
+ uword pc,
+ int64_t timestamp,
+ ProfileFunctionTrieNode* current,
+ intptr_t inclusive_serial,
+ bool top_frame,
+ bool top_frame_executing,
+ bool inclusive_tree) {
+ ProfileCode* profile_code = GetProfileCode(pc, timestamp);
+ ASSERT(profile_code != NULL);
+ const char* code_name = profile_code->name();
+ if (code_name == NULL) {
+ code_name = "";
+ }
+ intptr_t code_index = profile_code->code_table_index();
+ const Code& code = Code::ZoneHandle(profile_code->code());
GrowableArray<Function*> inlined_functions;
if (!code.IsNull()) {
intptr_t offset = pc - code.EntryPoint();
@@ -1771,18 +1300,18 @@
}
if (code.IsNull() || (inlined_functions.length() == 0)) {
// No inlined functions.
- ProfileFunction* function = region->function();
+ ProfileFunction* function = profile_code->function();
ASSERT(function != NULL);
current = ProcessFunction(function,
current,
inclusive_serial,
top_frame,
- exit_frame,
+ top_frame_executing,
code_index);
return current;
}
- if (inclusive_tree_) {
+ if (inclusive_tree) {
for (intptr_t i = inlined_functions.length() - 1; i >= 0; i--) {
Function* inlined_function = inlined_functions[i];
ASSERT(inlined_function != NULL);
@@ -1791,7 +1320,7 @@
current,
inclusive_serial,
top_frame,
- exit_frame,
+ top_frame_executing,
code_index);
top_frame = false;
}
@@ -1804,7 +1333,7 @@
current,
inclusive_serial,
top_frame,
- exit_frame,
+ top_frame_executing,
code_index);
top_frame = false;
}
@@ -1818,16 +1347,16 @@
ProfileFunctionTrieNode* current,
intptr_t inclusive_serial,
bool top_frame,
- bool exit_frame,
+ bool top_frame_executing,
intptr_t code_index) {
- ProfileFunction* function =
- function_table_->LookupOrAdd(*inlined_function);
+ ProfileFunctionTable* function_table = profile_->functions_;
+ ProfileFunction* function = function_table->LookupOrAdd(*inlined_function);
ASSERT(function != NULL);
return ProcessFunction(function,
current,
inclusive_serial,
top_frame,
- exit_frame,
+ top_frame_executing,
code_index);
}
@@ -1835,20 +1364,18 @@
ProfileFunctionTrieNode* current,
intptr_t inclusive_serial,
bool top_frame,
- bool exit_frame,
+ bool top_frame_executing,
intptr_t code_index) {
- const bool exclusive = top_frame && !exit_frame;
- if (!inclusive_tree_) {
- // We process functions for the inclusive and exclusive trees.
- // Only tick the function for the exclusive tree.
+ const bool exclusive = top_frame && top_frame_executing;
+ if (tick_functions_) {
function->Tick(exclusive, exclusive ? -1 : inclusive_serial);
}
- function->AddCodeObjectIndex(code_index);
- current = current->GetChild(function->index());
+ function->AddProfileCode(code_index);
+ current = current->GetChild(function->table_index());
current->AddCodeObjectIndex(code_index);
if (top_frame) {
- if (!exit_frame || vm_tags_emitted()) {
- // Only tick if this isn't an exit frame or VM tags are emitted.
+ if (top_frame_executing || vm_tags_emitted()) {
+ // Only tick if this function is using CPU time or VM tags are emitted.
current->Tick();
}
} else {
@@ -1857,232 +1384,58 @@
return current;
}
- ProfileFunctionTrieNode* exclusive_root_;
- ProfileFunctionTrieNode* inclusive_root_;
- ProfileFunctionTable* function_table_;
- bool inclusive_tree_;
-};
-
-
-class CodeRegionTrieNode : public ZoneAllocated {
- public:
- explicit CodeRegionTrieNode(intptr_t code_region_index)
- : code_region_index_(code_region_index),
- count_(0),
- children_(new ZoneGrowableArray<CodeRegionTrieNode*>()) {
+ // Tick the truncated tag's inclusive tick count.
+ void InclusiveTickTruncatedTag() {
+ ProfileCodeTable* tag_table = profile_->tag_code_;
+ intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId);
+ ASSERT(index >= 0);
+ ProfileCode* code = tag_table->At(index);
+ code->IncInclusiveTicks();
+ ASSERT(code != NULL);
+ ProfileFunction* function = code->function();
+ function->IncInclusiveTicks();
}
- void Tick() {
- ASSERT(code_region_index_ >= 0);
- count_++;
- }
- intptr_t count() const {
- ASSERT(code_region_index_ >= 0);
- return count_;
- }
+ // Tag append functions are overloaded for |ProfileCodeTrieNode| and
+ // |ProfileFunctionTrieNode| types.
- intptr_t code_region_index() const {
- return code_region_index_;
- }
-
- ZoneGrowableArray<CodeRegionTrieNode*>& children() const {
- return *children_;
- }
-
- CodeRegionTrieNode* GetChild(intptr_t child_code_region_index) {
- const intptr_t length = children_->length();
- intptr_t i = 0;
- while (i < length) {
- CodeRegionTrieNode* child = (*children_)[i];
- if (child->code_region_index() == child_code_region_index) {
- return child;
- }
- if (child->code_region_index() > child_code_region_index) {
- break;
- }
- i++;
- }
- // Add new CodeRegion, sorted by CodeRegionTable index.
- CodeRegionTrieNode* child = new CodeRegionTrieNode(child_code_region_index);
- if (i < length) {
- // Insert at i.
- children_->InsertAt(i, child);
- } else {
- // Add to end.
- children_->Add(child);
- }
- return child;
- }
-
- // This should only be called after the trie is completely built.
- void SortByCount() {
- children_->Sort(CodeRegionTrieNodeCompare);
- ZoneGrowableArray<CodeRegionTrieNode*>& kids = children();
- intptr_t child_count = kids.length();
- // Recurse.
- for (intptr_t i = 0; i < child_count; i++) {
- kids[i]->SortByCount();
- }
- }
-
- void PrintToJSONArray(JSONArray* array) const {
- ASSERT(array != NULL);
- // Write CodeRegion index.
- array->AddValue(code_region_index_);
- // Write count.
- array->AddValue(count_);
- // Write number of children.
- ZoneGrowableArray<CodeRegionTrieNode*>& kids = children();
- intptr_t child_count = kids.length();
- array->AddValue(child_count);
- // Recurse.
- for (intptr_t i = 0; i < child_count; i++) {
- kids[i]->PrintToJSONArray(array);
- }
- }
-
- private:
- static int CodeRegionTrieNodeCompare(CodeRegionTrieNode* const* a,
- CodeRegionTrieNode* const* b) {
- ASSERT(a != NULL);
- ASSERT(b != NULL);
- return (*b)->count() - (*a)->count();
- }
-
- const intptr_t code_region_index_;
- intptr_t count_;
- ZoneGrowableArray<CodeRegionTrieNode*>* children_;
-};
-
-
-class CodeRegionTrieBuilder : public TrieBuilder {
- public:
- CodeRegionTrieBuilder(Isolate* isolate,
- CodeRegionTable* live_code_table,
- CodeRegionTable* dead_code_table,
- CodeRegionTable* tag_code_table)
- : TrieBuilder(live_code_table, dead_code_table, tag_code_table) {
- set_tag_order(ProfilerService::kUserVM);
-
- // Verify that the truncated tag exists.
- ASSERT(tag_code_table_->FindIndex(VMTag::kTruncatedTagId) >= 0);
-
- // Verify that the root tag exists.
- intptr_t root_index = tag_code_table_->FindIndex(VMTag::kRootTagId);
- ASSERT(root_index >= 0);
- CodeRegion* region = tag_code_table_->At(root_index);
- ASSERT(region != NULL);
-
- exclusive_root_ = new CodeRegionTrieNode(region->code_table_index());
- inclusive_root_ = new CodeRegionTrieNode(region->code_table_index());
- }
-
- void Build(ProcessedSampleBuffer* buffer) {
- for (intptr_t i = 0; i < buffer->length(); i++) {
- ProcessedSample* sample = buffer->At(i);
- VisitSample(sample);
- }
- }
-
- CodeRegionTrieNode* inclusive_root() const {
- return inclusive_root_;
- }
-
- CodeRegionTrieNode* exclusive_root() const {
- return exclusive_root_;
- }
-
- private:
- void VisitSample(ProcessedSample* sample) {
- ProcessSampleExclusive(sample);
- ProcessSampleInclusive(sample);
- }
-
- void ProcessSampleInclusive(ProcessedSample* sample) {
- // Give the root a tick.
- inclusive_root_->Tick();
- CodeRegionTrieNode* current = inclusive_root_;
- current = AppendTags(sample, current);
- if (sample->truncated()) {
- current = AppendTruncatedTag(current);
- }
- // Walk the sampled PCs.
- for (intptr_t i = sample->length() - 1; i >= 0; i--) {
- ASSERT(sample->At(i) != 0);
- intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp());
- if (index < 0) {
- continue;
- }
- current = current->GetChild(index);
- current->Tick();
- }
- }
-
- void ProcessSampleExclusive(ProcessedSample* sample) {
- // Give the root a tick.
- exclusive_root_->Tick();
- CodeRegionTrieNode* current = exclusive_root_;
- current = AppendTags(sample, current);
- // Walk the sampled PCs.
- for (intptr_t i = 0; i < sample->length(); i++) {
- ASSERT(sample->At(i) != 0);
- intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp());
- if (index < 0) {
- continue;
- }
- current = current->GetChild(index);
- if (i == 0) {
- // Executing PC.
- if (!sample->first_frame_executing() || vm_tags_emitted()) {
- // Only tick if this isn't an exit frame or VM tags are emitted.
- current->Tick();
- }
- } else {
- // Caller PCs.
- current->Tick();
- }
- }
- if (sample->truncated()) {
- current = AppendTruncatedTag(current);
- }
- }
-
- CodeRegionTrieNode* AppendUserTag(ProcessedSample* sample,
- CodeRegionTrieNode* current) {
- intptr_t user_tag_index = FindTagIndex(sample->user_tag());
+ // ProfileCodeTrieNode
+ ProfileCodeTrieNode* AppendUserTag(uword user_tag,
+ ProfileCodeTrieNode* current) {
+ intptr_t user_tag_index = GetProfileCodeTagIndex(user_tag);
if (user_tag_index >= 0) {
current = current->GetChild(user_tag_index);
- // Give the tag a tick.
current->Tick();
}
return current;
}
- CodeRegionTrieNode* AppendTruncatedTag(CodeRegionTrieNode* current) {
- intptr_t truncated_tag_index = FindTagIndex(VMTag::kTruncatedTagId);
+ ProfileCodeTrieNode* AppendTruncatedTag(ProfileCodeTrieNode* current) {
+ intptr_t truncated_tag_index =
+ GetProfileCodeTagIndex(VMTag::kTruncatedTagId);
ASSERT(truncated_tag_index >= 0);
current = current->GetChild(truncated_tag_index);
current->Tick();
return current;
}
- CodeRegionTrieNode* AppendVMTag(ProcessedSample* sample,
- CodeRegionTrieNode* current) {
- if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
+ ProfileCodeTrieNode* AppendVMTag(uword vm_tag,
+ ProfileCodeTrieNode* current) {
+ if (VMTag::IsNativeEntryTag(vm_tag)) {
// Insert a dummy kNativeTagId node.
- intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId);
+ intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kNativeTagId);
current = current->GetChild(tag_index);
// Give the tag a tick.
current->Tick();
- } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
+ } else if (VMTag::IsRuntimeEntryTag(vm_tag)) {
// Insert a dummy kRuntimeTagId node.
- intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId);
+ intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kRuntimeTagId);
current = current->GetChild(tag_index);
// Give the tag a tick.
current->Tick();
} else {
- intptr_t tag_index = FindTagIndex(sample->vm_tag());
+ intptr_t tag_index = GetProfileCodeTagIndex(vm_tag);
current = current->GetChild(tag_index);
// Give the tag a tick.
current->Tick();
@@ -2090,59 +1443,527 @@
return current;
}
- CodeRegionTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
- ProcessedSample* sample, CodeRegionTrieNode* current) {
+ ProfileCodeTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
+ uword vm_tag, ProfileCodeTrieNode* current) {
// Only Native and Runtime entries have a second VM tag.
- if (!VMTag::IsNativeEntryTag(sample->vm_tag()) &&
- !VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
+ if (!VMTag::IsNativeEntryTag(vm_tag) &&
+ !VMTag::IsRuntimeEntryTag(vm_tag)) {
return current;
}
- intptr_t tag_index = FindTagIndex(sample->vm_tag());
+ intptr_t tag_index = GetProfileCodeTagIndex(vm_tag);
current = current->GetChild(tag_index);
// Give the tag a tick.
current->Tick();
return current;
}
- CodeRegionTrieNode* AppendVMTags(ProcessedSample* sample,
- CodeRegionTrieNode* current) {
- current = AppendVMTag(sample, current);
- current = AppendSpecificNativeRuntimeEntryVMTag(sample, current);
+ ProfileCodeTrieNode* AppendVMTags(uword vm_tag,
+ ProfileCodeTrieNode* current) {
+ current = AppendVMTag(vm_tag, current);
+ current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current);
return current;
}
- CodeRegionTrieNode* AppendTags(ProcessedSample* sample,
- CodeRegionTrieNode* current) {
+ ProfileCodeTrieNode* AppendTags(uword vm_tag,
+ uword user_tag,
+ ProfileCodeTrieNode* current) {
// None.
- if (tag_order() == ProfilerService::kNoTags) {
+ if (tag_order() == Profile::kNoTags) {
return current;
}
// User first.
- if ((tag_order() == ProfilerService::kUserVM) ||
- (tag_order() == ProfilerService::kUser)) {
- current = AppendUserTag(sample, current);
+ if ((tag_order() == Profile::kUserVM) ||
+ (tag_order() == Profile::kUser)) {
+ current = AppendUserTag(user_tag, current);
// Only user.
- if (tag_order() == ProfilerService::kUser) {
+ if (tag_order() == Profile::kUser) {
return current;
}
- return AppendVMTags(sample, current);
+ return AppendVMTags(vm_tag, current);
}
// VM first.
- ASSERT((tag_order() == ProfilerService::kVMUser) ||
- (tag_order() == ProfilerService::kVM));
- current = AppendVMTags(sample, current);
+ ASSERT((tag_order() == Profile::kVMUser) ||
+ (tag_order() == Profile::kVM));
+ current = AppendVMTags(vm_tag, current);
// Only VM.
- if (tag_order() == ProfilerService::kVM) {
+ if (tag_order() == Profile::kVM) {
return current;
}
- return AppendUserTag(sample, current);
+ return AppendUserTag(user_tag, current);
}
- CodeRegionTrieNode* exclusive_root_;
- CodeRegionTrieNode* inclusive_root_;
+ // ProfileFunctionTrieNode
+ ProfileFunctionTrieNode* AppendUserTag(uword user_tag,
+ ProfileFunctionTrieNode* current) {
+ intptr_t user_tag_index = GetProfileFunctionTagIndex(user_tag);
+ if (user_tag_index >= 0) {
+ current = current->GetChild(user_tag_index);
+ current->Tick();
+ }
+ return current;
+ }
+
+ ProfileFunctionTrieNode* AppendTruncatedTag(
+ ProfileFunctionTrieNode* current) {
+ intptr_t truncated_tag_index =
+ GetProfileFunctionTagIndex(VMTag::kTruncatedTagId);
+ ASSERT(truncated_tag_index >= 0);
+ current = current->GetChild(truncated_tag_index);
+ current->Tick();
+ return current;
+ }
+
+ ProfileFunctionTrieNode* AppendVMTag(uword vm_tag,
+ ProfileFunctionTrieNode* current) {
+ if (VMTag::IsNativeEntryTag(vm_tag)) {
+ // Insert a dummy kNativeTagId node.
+ intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kNativeTagId);
+ current = current->GetChild(tag_index);
+ // Give the tag a tick.
+ current->Tick();
+ } else if (VMTag::IsRuntimeEntryTag(vm_tag)) {
+ // Insert a dummy kRuntimeTagId node.
+ intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kRuntimeTagId);
+ current = current->GetChild(tag_index);
+ // Give the tag a tick.
+ current->Tick();
+ } else {
+ intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag);
+ current = current->GetChild(tag_index);
+ // Give the tag a tick.
+ current->Tick();
+ }
+ return current;
+ }
+
+ ProfileFunctionTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
+ uword vm_tag, ProfileFunctionTrieNode* current) {
+ // Only Native and Runtime entries have a second VM tag.
+ if (!VMTag::IsNativeEntryTag(vm_tag) &&
+ !VMTag::IsRuntimeEntryTag(vm_tag)) {
+ return current;
+ }
+ intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag);
+ current = current->GetChild(tag_index);
+ // Give the tag a tick.
+ current->Tick();
+ return current;
+ }
+
+ ProfileFunctionTrieNode* AppendVMTags(uword vm_tag,
+ ProfileFunctionTrieNode* current) {
+ current = AppendVMTag(vm_tag, current);
+ current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current);
+ return current;
+ }
+
+ ProfileFunctionTrieNode* AppendTags(uword vm_tag,
+ uword user_tag,
+ ProfileFunctionTrieNode* current) {
+ // None.
+ if (tag_order() == Profile::kNoTags) {
+ return current;
+ }
+ // User first.
+ if ((tag_order() == Profile::kUserVM) ||
+ (tag_order() == Profile::kUser)) {
+ current = AppendUserTag(user_tag, current);
+ // Only user.
+ if (tag_order() == Profile::kUser) {
+ return current;
+ }
+ return AppendVMTags(vm_tag, current);
+ }
+ // VM first.
+ ASSERT((tag_order() == Profile::kVMUser) ||
+ (tag_order() == Profile::kVM));
+ current = AppendVMTags(vm_tag, current);
+ // Only VM.
+ if (tag_order() == Profile::kVM) {
+ return current;
+ }
+ return AppendUserTag(user_tag, current);
+ }
+
+ intptr_t GetProfileCodeTagIndex(uword tag) {
+ ProfileCodeTable* tag_table = profile_->tag_code_;
+ intptr_t index = tag_table->FindCodeIndexForPC(tag);
+ ASSERT(index >= 0);
+ ProfileCode* code = tag_table->At(index);
+ ASSERT(code != NULL);
+ return code->code_table_index();
+ }
+
+ intptr_t GetProfileFunctionTagIndex(uword tag) {
+ ProfileCodeTable* tag_table = profile_->tag_code_;
+ intptr_t index = tag_table->FindCodeIndexForPC(tag);
+ ASSERT(index >= 0);
+ ProfileCode* code = tag_table->At(index);
+ ASSERT(code != NULL);
+ ProfileFunction* function = code->function();
+ ASSERT(function != NULL);
+ return function->table_index();
+ }
+
+ intptr_t GetProfileCodeIndex(uword pc, int64_t timestamp) {
+ return GetProfileCode(pc, timestamp)->code_table_index();
+ }
+
+ ProfileCode* GetProfileCode(uword pc, int64_t timestamp) {
+ ProfileCodeTable* live_table = profile_->live_code_;
+ ProfileCodeTable* dead_table = profile_->dead_code_;
+
+ intptr_t index = live_table->FindCodeIndexForPC(pc);
+ ProfileCode* code = NULL;
+ if (index < 0) {
+ index = dead_table->FindCodeIndexForPC(pc);
+ ASSERT(index >= 0);
+ code = dead_table->At(index);
+ } else {
+ code = live_table->At(index);
+ ASSERT(code != NULL);
+ if (code->compile_timestamp() > timestamp) {
+ // Code is newer than sample. Fall back to dead code table.
+ index = dead_table->FindCodeIndexForPC(pc);
+ ASSERT(index >= 0);
+ code = dead_table->At(index);
+ }
+ }
+
+ ASSERT(code != NULL);
+ ASSERT(code->Contains(pc));
+ ASSERT(code->compile_timestamp() <= timestamp);
+ return code;
+ }
+
+ void RegisterProfileCodeTag(uword tag) {
+ if (tag == 0) {
+ // No tag.
+ return;
+ }
+ ProfileCodeTable* tag_table = profile_->tag_code_;
+ intptr_t index = tag_table->FindCodeIndexForPC(tag);
+ if (index >= 0) {
+ // Already created.
+ return;
+ }
+ ProfileCode* code = new ProfileCode(ProfileCode::kTagCode,
+ tag,
+ tag + 1,
+ 0,
+ null_code_);
+ index = tag_table->InsertCode(code);
+ ASSERT(index >= 0);
+ }
+
+ ProfileCode* CreateProfileCodeReused(uword pc) {
+ ProfileCode* code = new ProfileCode(ProfileCode::kReusedCode,
+ pc,
+ pc + 1,
+ 0,
+ null_code_);
+ return code;
+ }
+
+ ProfileCode* CreateProfileCode(uword pc) {
+ const intptr_t kDartCodeAlignment = OS::PreferredCodeAlignment();
+ const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1);
+ Code& code = Code::Handle(isolate_);
+
+ // Check current isolate for pc.
+ if (isolate_->heap()->CodeContains(pc)) {
+ code ^= Code::LookupCode(pc);
+ if (!code.IsNull()) {
+ deoptimized_code_->Add(code);
+ return new ProfileCode(ProfileCode::kDartCode,
+ code.EntryPoint(),
+ code.EntryPoint() + code.Size(),
+ code.compile_timestamp(),
+ code);
+ }
+ return new ProfileCode(ProfileCode::kCollectedCode,
+ pc,
+ (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
+ 0,
+ code);
+ }
+
+ // Check VM isolate for pc.
+ if (vm_isolate_->heap()->CodeContains(pc)) {
+ code ^= Code::LookupCodeInVmIsolate(pc);
+ if (!code.IsNull()) {
+ return new ProfileCode(ProfileCode::kDartCode,
+ code.EntryPoint(),
+ code.EntryPoint() + code.Size(),
+ code.compile_timestamp(),
+ code);
+ }
+ return new ProfileCode(ProfileCode::kCollectedCode,
+ pc,
+ (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
+ 0,
+ code);
+ }
+
+ // Check NativeSymbolResolver for pc.
+ uintptr_t native_start = 0;
+ char* native_name = NativeSymbolResolver::LookupSymbolName(pc,
+ &native_start);
+ if (native_name == NULL) {
+ // No native name found.
+ return new ProfileCode(ProfileCode::kNativeCode,
+ pc,
+ pc + 1,
+ 0,
+ code);
+ }
+ ASSERT(pc >= native_start);
+ ProfileCode* profile_code =
+ new ProfileCode(ProfileCode::kNativeCode,
+ native_start,
+ pc + 1,
+ 0,
+ code);
+ profile_code->SetName(native_name);
+ free(native_name);
+ return profile_code;
+ }
+
+ ProfileCode* RegisterProfileCode(uword pc, int64_t timestamp) {
+ ProfileCodeTable* live_table = profile_->live_code_;
+ ProfileCodeTable* dead_table = profile_->dead_code_;
+
+ ProfileCode* code = live_table->FindCodeForPC(pc);
+ if (code == NULL) {
+ // Code not found.
+ intptr_t index = live_table->InsertCode(CreateProfileCode(pc));
+ ASSERT(index >= 0);
+ code = live_table->At(index);
+ if (code->compile_timestamp() <= timestamp) {
+ // Code was compiled before sample was taken.
+ return code;
+ }
+ // Code was compiled after the sample was taken. Insert code object into
+ // the dead code table.
+ index = dead_table->InsertCode(CreateProfileCodeReused(pc));
+ ASSERT(index >= 0);
+ return dead_table->At(index);
+ }
+ // Existing code found.
+ if (code->compile_timestamp() <= timestamp) {
+ // Code was compiled before sample was taken.
+ return code;
+ }
+ // Code was compiled after the sample was taken. Check if we have an entry
+ // in the dead code table.
+ code = dead_table->FindCodeForPC(pc);
+ if (code != NULL) {
+ return code;
+ }
+ // Create a new dead code entry.
+ intptr_t index = dead_table->InsertCode(CreateProfileCodeReused(pc));
+ ASSERT(index >= 0);
+ return dead_table->At(index);
+ }
+
+ Profile::TagOrder tag_order() const {
+ return tag_order_;
+ }
+
+ bool vm_tags_emitted() const {
+ return (tag_order_ == Profile::kUserVM) ||
+ (tag_order_ == Profile::kVMUser) ||
+ (tag_order_ == Profile::kVM);
+ }
+
+ Isolate* isolate_;
+ Isolate* vm_isolate_;
+ SampleFilter* filter_;
+ Profile::TagOrder tag_order_;
+ Profile* profile_;
+ DeoptimizedCodeSet* deoptimized_code_;
+ const Code& null_code_;
+ const Function& null_function_;
+ bool tick_functions_;
+
+ ProcessedSampleBuffer* samples_;
};
+Profile::Profile(Isolate* isolate)
+ : isolate_(isolate),
+ live_code_(NULL),
+ dead_code_(NULL),
+ tag_code_(NULL),
+ functions_(NULL),
+ dead_code_index_offset_(-1),
+ tag_code_index_offset_(-1),
+ min_time_(kMaxInt64),
+ max_time_(0) {
+ ASSERT(isolate_ != NULL);
+ for (intptr_t i = 0; i < kNumTrieKinds; i++) {
+ roots_[i] = NULL;
+ }
+}
+
+
+void Profile::Build(SampleFilter* filter, TagOrder tag_order) {
+ ProfileBuilder builder(isolate_, filter, tag_order, this);
+ builder.Build();
+}
+
+
+ProfileFunction* Profile::GetFunction(intptr_t index) {
+ ASSERT(functions_ != NULL);
+ return functions_->At(index);
+}
+
+
+ProfileCode* Profile::GetCode(intptr_t index) {
+ ASSERT(live_code_ != NULL);
+ ASSERT(dead_code_ != NULL);
+ ASSERT(tag_code_ != NULL);
+ ASSERT(dead_code_index_offset_ >= 0);
+ ASSERT(tag_code_index_offset_ >= 0);
+
+ // Code indexes span three arrays.
+ // 0 ... |live_code|
+ // |live_code| ... |dead_code|
+ // |dead_code| ... |tag_code|
+
+ if (index < dead_code_index_offset_) {
+ return live_code_->At(index);
+ }
+
+ if (index < tag_code_index_offset_) {
+ index -= dead_code_index_offset_;
+ return dead_code_->At(index);
+ }
+
+ index -= tag_code_index_offset_;
+ return tag_code_->At(index);
+}
+
+
+ProfileTrieNode* Profile::GetTrieRoot(TrieKind trie_kind) {
+ return roots_[static_cast<intptr_t>(trie_kind)];
+}
+
+
+void Profile::PrintJSON(JSONStream* stream) {
+ ScopeTimer sw("Profile::PrintJSON", FLAG_trace_profiler);
+ JSONObject obj(stream);
+ obj.AddProperty("type", "_CpuProfile");
+ obj.AddProperty("samplePeriod",
+ static_cast<intptr_t>(FLAG_profile_period));
+ obj.AddProperty("stackDepth",
+ static_cast<intptr_t>(FLAG_profile_depth));
+ obj.AddProperty("sampleCount", sample_count());
+ obj.AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
+ {
+ JSONArray codes(&obj, "codes");
+ for (intptr_t i = 0; i < live_code_->length(); i++) {
+ ProfileCode* code = live_code_->At(i);
+ ASSERT(code != NULL);
+ code->PrintToJSONArray(&codes);
+ }
+ for (intptr_t i = 0; i < dead_code_->length(); i++) {
+ ProfileCode* code = dead_code_->At(i);
+ ASSERT(code != NULL);
+ code->PrintToJSONArray(&codes);
+ }
+ for (intptr_t i = 0; i < tag_code_->length(); i++) {
+ ProfileCode* code = tag_code_->At(i);
+ ASSERT(code != NULL);
+ code->PrintToJSONArray(&codes);
+ }
+ }
+
+ {
+ JSONArray functions(&obj, "functions");
+ for (intptr_t i = 0; i < functions_->length(); i++) {
+ ProfileFunction* function = functions_->At(i);
+ ASSERT(function != NULL);
+ function->PrintToJSONArray(&functions);
+ }
+ }
+ {
+ JSONArray code_trie(&obj, "exclusiveCodeTrie");
+ ProfileTrieNode* root = roots_[static_cast<intptr_t>(kExclusiveCode)];
+ ASSERT(root != NULL);
+ root->PrintToJSONArray(&code_trie);
+ }
+ {
+ JSONArray code_trie(&obj, "inclusiveCodeTrie");
+ ProfileTrieNode* root = roots_[static_cast<intptr_t>(kInclusiveCode)];
+ ASSERT(root != NULL);
+ root->PrintToJSONArray(&code_trie);
+ }
+ {
+ JSONArray function_trie(&obj, "exclusiveFunctionTrie");
+ ProfileTrieNode* root = roots_[static_cast<intptr_t>(kExclusiveFunction)];
+ ASSERT(root != NULL);
+ root->PrintToJSONArray(&function_trie);
+ }
+ {
+ JSONArray function_trie(&obj, "inclusiveFunctionTrie");
+ ProfileTrieNode* root = roots_[static_cast<intptr_t>(kInclusiveFunction)];
+ ASSERT(root != NULL);
+ root->PrintToJSONArray(&function_trie);
+ }
+}
+
+
+void ProfileTrieWalker::Reset(Profile::TrieKind trie_kind) {
+ code_trie_ = Profile::IsCodeTrie(trie_kind);
+ parent_ = NULL;
+ current_ = profile_->GetTrieRoot(trie_kind);
+ ASSERT(current_ != NULL);
+}
+
+
+const char* ProfileTrieWalker::CurrentName() {
+ if (current_ == NULL) {
+ return NULL;
+ }
+ if (code_trie_) {
+ ProfileCode* code = profile_->GetCode(current_->table_index());
+ return code->name();
+ } else {
+ ProfileFunction* func = profile_->GetFunction(current_->table_index());
+ return func->Name();
+ }
+ UNREACHABLE();
+}
+
+
+bool ProfileTrieWalker::Down() {
+ if ((current_ == NULL) || (current_->NumChildren() == 0)) {
+ return false;
+ }
+ parent_ = current_;
+ current_ = current_->At(0);
+ return true;
+}
+
+
+bool ProfileTrieWalker::NextSibling() {
+ if (parent_ == NULL) {
+ return false;
+ }
+ intptr_t current_index = parent_->IndexOf(current_);
+ if (current_index < 0) {
+ return false;
+ }
+ current_index++;
+ if (current_index >= parent_->NumChildren()) {
+ return false;
+ }
+ current_ = parent_->At(current_index);
+ return true;
+}
+
+
class NoAllocationSampleFilter : public SampleFilter {
public:
explicit NoAllocationSampleFilter(Isolate* isolate)
@@ -2155,189 +1976,30 @@
};
-void ProfilerService::PrintJSON(JSONStream* stream, TagOrder tag_order) {
+void ProfilerService::PrintJSON(JSONStream* stream,
+ Profile::TagOrder tag_order) {
Isolate* isolate = Isolate::Current();
// Disable profile interrupts while processing the buffer.
Profiler::EndExecution(isolate);
- MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
- IsolateProfilerData* profiler_data = isolate->profiler_data();
- if (profiler_data == NULL) {
- stream->PrintError(kFeatureDisabled, NULL);
- return;
+
+ {
+ MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
+ IsolateProfilerData* profiler_data = isolate->profiler_data();
+ if (profiler_data == NULL) {
+ stream->PrintError(kFeatureDisabled, NULL);
+ return;
+ }
}
- SampleBuffer* sample_buffer = profiler_data->sample_buffer();
- ASSERT(sample_buffer != NULL);
- ScopeTimer sw("ProfilerService::PrintJSON", FLAG_trace_profiler);
+
{
StackZone zone(isolate);
HANDLESCOPE(isolate);
-
- ProcessedSampleBuffer* processed_samples = NULL;
- {
- ScopeTimer sw("BuildProcessedSampleBuffer", FLAG_trace_profiler);
- NoAllocationSampleFilter filter(isolate);
- processed_samples = sample_buffer->BuildProcessedSampleBuffer(&filter);
- }
-
- {
- // Live code holds Dart, Native, and Collected CodeRegions.
- CodeRegionTable live_code_table;
- // Dead code holds Overwritten CodeRegions.
- CodeRegionTable dead_code_table;
- // Tag code holds Tag CodeRegions.
- CodeRegionTable tag_code_table;
- // Table holding all ProfileFunctions.
- ProfileFunctionTable function_table;
- // Set of deoptimized code still referenced by the profiler.
- DeoptimizedCodeSet* deoptimized_code = new DeoptimizedCodeSet(isolate);
-
- // Build CodeRegion tables.
- CodeRegionTableBuilder builder(isolate,
- &live_code_table,
- &dead_code_table,
- &tag_code_table,
- deoptimized_code);
- {
- ScopeTimer sw("CodeRegionTableBuilder::Build", FLAG_trace_profiler);
- builder.Build(processed_samples);
- }
- intptr_t samples = processed_samples->length();
- intptr_t frames = builder.frames();
- if (FLAG_trace_profiler) {
- intptr_t total_live_code_objects = live_code_table.Length();
- intptr_t total_dead_code_objects = dead_code_table.Length();
- intptr_t total_tag_code_objects = tag_code_table.Length();
- OS::Print(
- "Processed %" Pd " samples with %" Pd " frames\n", samples, frames);
- OS::Print("CodeTables: live=%" Pd " dead=%" Pd " tag=%" Pd "\n",
- total_live_code_objects,
- total_dead_code_objects,
- total_tag_code_objects);
- }
-
- if (FLAG_trace_profiler) {
- ScopeTimer sw("CodeRegionTableVerify", FLAG_trace_profiler);
- live_code_table.Verify();
- dead_code_table.Verify();
- tag_code_table.Verify();
- }
-
- {
- ScopeTimer st("CodeRegionFunctionMapping", FLAG_trace_profiler);
- CodeRegionFunctionMapper mapper(isolate, &live_code_table,
- &dead_code_table,
- &tag_code_table,
- &function_table);
- mapper.Map();
- }
- if (FLAG_trace_profiler) {
- intptr_t total_functions = function_table.Length();
- OS::Print("FunctionTable: size=%" Pd "\n", total_functions);
- }
- CodeRegionTrieBuilder code_trie_builder(isolate,
- &live_code_table,
- &dead_code_table,
- &tag_code_table);
- code_trie_builder.set_tag_order(tag_order);
- {
- // Build CodeRegion trie.
- ScopeTimer sw("CodeRegionTrieBuilder::Build", FLAG_trace_profiler);
- code_trie_builder.Build(processed_samples);
- code_trie_builder.exclusive_root()->SortByCount();
- code_trie_builder.inclusive_root()->SortByCount();
- }
- if (FLAG_trace_profiler) {
- OS::Print("Code Trie Root Count: E: %" Pd " I: %" Pd "\n",
- code_trie_builder.exclusive_root()->count(),
- code_trie_builder.inclusive_root()->count());
- }
- ProfileFunctionTrieBuilder function_trie_builder(&live_code_table,
- &dead_code_table,
- &tag_code_table,
- &function_table);
- function_trie_builder.set_tag_order(tag_order);
- {
- // Build ProfileFunction trie.
- ScopeTimer sw("ProfileFunctionTrieBuilder::Build",
- FLAG_trace_profiler);
- function_trie_builder.Build(processed_samples);
- function_trie_builder.exclusive_root()->SortByCount();
- function_trie_builder.inclusive_root()->SortByCount();
- }
- if (FLAG_trace_profiler) {
- OS::Print("Function Trie Root Count: E: %" Pd " I: %" Pd "\n",
- function_trie_builder.exclusive_root()->count(),
- function_trie_builder.inclusive_root()->count());
- }
- {
- ScopeTimer sw("CpuProfileJSONStream", FLAG_trace_profiler);
- // Serialize to JSON.
- JSONObject obj(stream);
- obj.AddProperty("type", "_CpuProfile");
- obj.AddProperty("sampleCount", samples);
- obj.AddProperty("samplePeriod",
- static_cast<intptr_t>(FLAG_profile_period));
- obj.AddProperty("stackDepth",
- static_cast<intptr_t>(FLAG_profile_depth));
- obj.AddProperty("timeSpan",
- MicrosecondsToSeconds(builder.TimeDeltaMicros()));
- {
- JSONArray code_trie(&obj, "exclusiveCodeTrie");
- CodeRegionTrieNode* root = code_trie_builder.exclusive_root();
- ASSERT(root != NULL);
- root->PrintToJSONArray(&code_trie);
- }
- {
- JSONArray code_trie(&obj, "inclusiveCodeTrie");
- CodeRegionTrieNode* root = code_trie_builder.inclusive_root();
- ASSERT(root != NULL);
- root->PrintToJSONArray(&code_trie);
- }
- {
- JSONArray function_trie(&obj, "exclusiveFunctionTrie");
- ProfileFunctionTrieNode* root =
- function_trie_builder.exclusive_root();
- ASSERT(root != NULL);
- root->PrintToJSONArray(&function_trie);
- }
- {
- JSONArray function_trie(&obj, "inclusiveFunctionTrie");
- ProfileFunctionTrieNode* root =
- function_trie_builder.inclusive_root();
- ASSERT(root != NULL);
- root->PrintToJSONArray(&function_trie);
- }
- {
- JSONArray codes(&obj, "codes");
- for (intptr_t i = 0; i < live_code_table.Length(); i++) {
- CodeRegion* region = live_code_table.At(i);
- ASSERT(region != NULL);
- region->PrintToJSONArray(&codes);
- }
- for (intptr_t i = 0; i < dead_code_table.Length(); i++) {
- CodeRegion* region = dead_code_table.At(i);
- ASSERT(region != NULL);
- region->PrintToJSONArray(&codes);
- }
- for (intptr_t i = 0; i < tag_code_table.Length(); i++) {
- CodeRegion* region = tag_code_table.At(i);
- ASSERT(region != NULL);
- region->PrintToJSONArray(&codes);
- }
- }
- {
- JSONArray functions(&obj, "functions");
- for (intptr_t i = 0; i < function_table.Length(); i++) {
- ProfileFunction* function = function_table.At(i);
- ASSERT(function != NULL);
- function->PrintToJSONArray(&functions);
- }
- }
- }
- // Update the isolates set of dead code.
- deoptimized_code->UpdateIsolate(isolate);
- }
+ Profile profile(isolate);
+ NoAllocationSampleFilter filter(isolate);
+ profile.Build(&filter, tag_order);
+ profile.PrintJSON(stream);
}
+
// Enable profile interrupts.
Profiler::BeginExecution(isolate);
}
diff --git a/runtime/vm/profiler_service.h b/runtime/vm/profiler_service.h
index 19f01b6..d281a84 100644
--- a/runtime/vm/profiler_service.h
+++ b/runtime/vm/profiler_service.h
@@ -8,20 +8,270 @@
#include "vm/allocation.h"
#include "vm/code_observers.h"
#include "vm/globals.h"
+#include "vm/growable_array.h"
+#include "vm/object.h"
#include "vm/tags.h"
#include "vm/thread_interrupter.h"
-// Profile VM Service.
+// CPU Profile model and service protocol bits.
// NOTE: For sampling and stack walking related code, see profiler.h.
namespace dart {
// Forward declarations.
+class Code;
+class Function;
class JSONArray;
class JSONStream;
-class ProfilerCodeRegionTable;
+class ProfileFunctionTable;
+class ProfileCodeTable;
+class RawCode;
+class RawFunction;
+class SampleFilter;
-class ProfilerService : public AllStatic {
+// Profile data related to a |Function|.
+class ProfileFunction : public ZoneAllocated {
+ public:
+ enum Kind {
+ kDartFunction, // Dart function.
+ kNativeFunction, // Synthetic function for Native (C/C++).
+ kTagFunction, // Synthetic function for a VM or User tag.
+ kStubFunction, // Synthetic function for stub code.
+ kUnknownFunction, // A singleton function for unknown objects.
+ };
+
+ ProfileFunction(Kind kind,
+ const char* name,
+ const Function& function,
+ const intptr_t table_index);
+
+ const char* name() const {
+ ASSERT(name_ != NULL);
+ return name_;
+ }
+
+ const char* Name() const;
+
+ RawFunction* function() const {
+ return function_.raw();
+ }
+
+ intptr_t table_index() const {
+ return table_index_;
+ }
+
+ Kind kind() const {
+ return kind_;
+ }
+
+ intptr_t exclusive_ticks() const { return exclusive_ticks_; }
+ intptr_t inclusive_ticks() const { return inclusive_ticks_; }
+
+ void IncInclusiveTicks() {
+ inclusive_ticks_++;
+ }
+
+ void Tick(bool exclusive, intptr_t inclusive_serial);
+
+ static const char* KindToCString(Kind kind);
+
+ void PrintToJSONArray(JSONArray* functions);
+
+ private:
+ const Kind kind_;
+ const char* name_;
+ const Function& function_;
+ const intptr_t table_index_;
+ ZoneGrowableArray<intptr_t> profile_codes_;
+
+ intptr_t exclusive_ticks_;
+ intptr_t inclusive_ticks_;
+ intptr_t inclusive_serial_;
+
+ void PrintToJSONObject(JSONObject* func);
+ // A |ProfileCode| that contains this function.
+ void AddProfileCode(intptr_t code_table_index);
+
+ friend class ProfileCode;
+ friend class ProfileBuilder;
+};
+
+
+class ProfileCodeAddress {
+ public:
+ explicit ProfileCodeAddress(uword pc);
+
+ void Tick(bool exclusive);
+
+ uword pc() const { return pc_; }
+ intptr_t exclusive_ticks() const { return exclusive_ticks_; }
+ intptr_t inclusive_ticks() const { return inclusive_ticks_; }
+
+ private:
+ uword pc_;
+ intptr_t exclusive_ticks_;
+ intptr_t inclusive_ticks_;
+};
+
+
+// Profile data related to a |Code|.
+class ProfileCode : public ZoneAllocated {
+ public:
+ enum Kind {
+ kDartCode, // Live Dart code.
+ kCollectedCode, // Dead Dart code.
+ kNativeCode, // Native code.
+ kReusedCode, // Dead Dart code that has been reused by new kDartCode.
+ kTagCode, // A special kind of code representing a tag.
+ };
+
+ ProfileCode(Kind kind,
+ uword start,
+ uword end,
+ int64_t timestamp,
+ const Code& code);
+
+ Kind kind() const { return kind_; }
+
+ uword start() const { return start_; }
+ void set_start(uword start) { start_ = start; }
+
+ uword end() const { return end_; }
+ void set_end(uword end) { end_ = end; }
+
+ void AdjustExtent(uword start, uword end);
+
+ bool Contains(uword pc) const {
+ return (pc >= start_) && (pc < end_);
+ }
+
+ bool Overlaps(const ProfileCode* other) const;
+
+ int64_t compile_timestamp() const { return compile_timestamp_; }
+ void set_compile_timestamp(int64_t timestamp) {
+ compile_timestamp_ = timestamp;
+ }
+
+ intptr_t exclusive_ticks() const { return exclusive_ticks_; }
+ void set_exclusive_ticks(intptr_t exclusive_ticks) {
+ exclusive_ticks_ = exclusive_ticks;
+ }
+ void IncExclusiveTicks() {
+ exclusive_ticks_++;
+ }
+
+ intptr_t inclusive_ticks() const { return inclusive_ticks_; }
+ void set_inclusive_ticks(intptr_t inclusive_ticks) {
+ inclusive_ticks_ = inclusive_ticks;
+ }
+ void IncInclusiveTicks() {
+ inclusive_ticks_++;
+ }
+
+ bool IsOptimizedDart() const;
+ RawCode* code() const {
+ return code_.raw();
+ }
+
+ const char* name() const { return name_; }
+ void SetName(const char* name);
+ void GenerateAndSetSymbolName(const char* prefix);
+
+ static const char* KindToCString(Kind kind);
+
+ void PrintToJSONArray(JSONArray* codes);
+
+ private:
+ void Tick(uword pc, bool exclusive, intptr_t serial);
+ void TickAddress(uword pc, bool exclusive);
+
+ ProfileFunction* SetFunctionAndName(ProfileFunctionTable* table);
+
+ ProfileFunction* function() const {
+ return function_;
+ }
+
+ void PrintNativeCode(JSONObject* profile_code_obj);
+ void PrintCollectedCode(JSONObject* profile_code_obj);
+ void PrintOverwrittenCode(JSONObject* profile_code_obj);
+ void PrintTagCode(JSONObject* profile_code_obj);
+
+ void set_code_table_index(intptr_t index) { code_table_index_ = index; }
+ intptr_t code_table_index() const { return code_table_index_; }
+
+ const Kind kind_;
+ uword start_;
+ uword end_;
+ intptr_t exclusive_ticks_;
+ intptr_t inclusive_ticks_;
+ intptr_t inclusive_serial_;
+
+ const Code& code_;
+ const char* name_;
+ int64_t compile_timestamp_;
+ ProfileFunction* function_;
+ intptr_t code_table_index_;
+ ZoneGrowableArray<ProfileCodeAddress> address_ticks_;
+
+ friend class ProfileBuilder;
+};
+
+
+// Stack traces are organized in a trie. This holds information about one node
+// in the trie. A node in a tree represents a stack frame and a path in the tree
+// represents a stack trace. Each unique stack trace appears in the tree once
+// and each node has a count indicating how many times this has been observed.
+// The index can be used to look up a |ProfileFunction| or |ProfileCode|.
+// A node can have zero or more children. Depending on the kind of trie the
+// children are callers or callees of the current node.
+class ProfileTrieNode : public ZoneAllocated {
+ public:
+ explicit ProfileTrieNode(intptr_t index);
+ virtual ~ProfileTrieNode();
+
+ virtual void PrintToJSONArray(JSONArray* array) const = 0;
+
+ // Index into function or code tables.
+ intptr_t table_index() const { return table_index_; }
+
+ intptr_t count() const { return count_; }
+
+ void Tick() {
+ count_++;
+ }
+
+ intptr_t NumChildren() const {
+ return children_.length();
+ }
+
+ ProfileTrieNode* At(intptr_t i) {
+ return children_.At(i);
+ }
+
+ intptr_t IndexOf(ProfileTrieNode* node);
+
+ protected:
+ void SortChildren();
+
+ static int ProfileTrieNodeCompare(ProfileTrieNode* const* a,
+ ProfileTrieNode* const* b) {
+ ASSERT(a != NULL);
+ ASSERT(b != NULL);
+ return (*b)->count() - (*a)->count();
+ }
+
+
+ intptr_t table_index_;
+ intptr_t count_;
+ ZoneGrowableArray<ProfileTrieNode*> children_;
+
+ friend class ProfileBuilder;
+};
+
+
+// The model for a profile. Most of the model is zone allocated, therefore
+// a zone must be created that lives longer than this object.
+class Profile : public ValueObject {
public:
enum TagOrder {
kNoTags,
@@ -31,8 +281,90 @@
kVMUser
};
+ enum TrieKind {
+ kExclusiveCode,
+ kExclusiveFunction,
+ kInclusiveCode,
+ kInclusiveFunction,
+ kNumTrieKinds,
+ };
+
+ static bool IsCodeTrie(TrieKind kind) {
+ return (kind == kExclusiveCode) || (kind == kInclusiveCode);
+ }
+
+ static bool IsFunctionTrie(TrieKind kind) {
+ return !IsCodeTrie(kind);
+ }
+
+ explicit Profile(Isolate* isolate);
+
+ // Build a filtered model using |filter| with the specified |tag_order|.
+ void Build(SampleFilter* filter, TagOrder tag_order);
+
+ // After building:
+ int64_t min_time() const { return min_time_; }
+ int64_t max_time() const { return max_time_; }
+ int64_t GetTimeSpan() const {
+ return max_time() - min_time();
+ }
+ intptr_t sample_count() const { return sample_count_; }
+
+ ProfileFunction* GetFunction(intptr_t index);
+ ProfileCode* GetCode(intptr_t index);
+ ProfileTrieNode* GetTrieRoot(TrieKind trie_kind);
+
+ void PrintJSON(JSONStream* stream);
+
+ private:
+ Isolate* isolate_;
+ ProfileCodeTable* live_code_;
+ ProfileCodeTable* dead_code_;
+ ProfileCodeTable* tag_code_;
+ ProfileFunctionTable* functions_;
+ intptr_t dead_code_index_offset_;
+ intptr_t tag_code_index_offset_;
+
+ ProfileTrieNode* roots_[kNumTrieKinds];
+
+ int64_t min_time_;
+ int64_t max_time_;
+
+ intptr_t sample_count_;
+
+ friend class ProfileBuilder;
+};
+
+
+class ProfileTrieWalker : public ValueObject {
+ public:
+ explicit ProfileTrieWalker(Profile* profile)
+ : profile_(profile),
+ parent_(NULL),
+ current_(NULL),
+ code_trie_(false) {
+ ASSERT(profile_ != NULL);
+ }
+
+ void Reset(Profile::TrieKind trie_kind);
+
+ const char* CurrentName();
+
+ bool Down();
+ bool NextSibling();
+
+ private:
+ Profile* profile_;
+ ProfileTrieNode* parent_;
+ ProfileTrieNode* current_;
+ bool code_trie_;
+};
+
+
+class ProfilerService : public AllStatic {
+ public:
static void PrintJSON(JSONStream* stream,
- TagOrder tag_order);
+ Profile::TagOrder tag_order);
static void ClearSamples();
};
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 561bb69..4f1ea87 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -8,6 +8,7 @@
#include "vm/dart_api_state.h"
#include "vm/globals.h"
#include "vm/profiler.h"
+#include "vm/profiler_service.h"
#include "vm/unit_test.h"
namespace dart {
@@ -108,15 +109,35 @@
}
+class AllocationFilter : public SampleFilter {
+ public:
+ explicit AllocationFilter(Isolate* isolate, intptr_t cid)
+ : SampleFilter(isolate),
+ cid_(cid) {
+ }
+
+ bool FilterSample(Sample* sample) {
+ return sample->is_allocation_sample() && (sample->allocation_cid() == cid_);
+ }
+
+ private:
+ intptr_t cid_;
+};
+
+
TEST_CASE(Profiler_TrivialRecordAllocation) {
const char* kScript =
"class A {\n"
" var a;\n"
" var b;\n"
"}\n"
+ "class B {\n"
+ " static boo() {\n"
+ " return new A();\n"
+ " }\n"
+ "}\n"
"main() {\n"
- " var z = new A();\n"
- " return z;\n"
+ " return B.boo();\n"
"}\n";
Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
@@ -130,6 +151,166 @@
Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
EXPECT_VALID(result);
+
+
+ {
+ Isolate* isolate = Isolate::Current();
+ StackZone zone(isolate);
+ HANDLESCOPE(isolate);
+ Profile profile(isolate);
+ AllocationFilter filter(isolate, class_a.id());
+ profile.Build(&filter, Profile::kNoTags);
+ // We should have 1 allocation sample.
+ EXPECT_EQ(1, profile.sample_count());
+ ProfileTrieWalker walker(&profile);
+
+ // Exclusive code: B.boo -> main.
+ walker.Reset(Profile::kExclusiveCode);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_STREQ("B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT(!walker.Down());
+
+ // Inclusive code: main -> B.boo.
+ walker.Reset(Profile::kInclusiveCode);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("B.boo", walker.CurrentName());
+ EXPECT(!walker.Down());
+
+ // Exclusive function: B.boo -> main.
+ walker.Reset(Profile::kExclusiveFunction);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_STREQ("B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT(!walker.Down());
+
+ // Inclusive function: main -> B.boo.
+ walker.Reset(Profile::kInclusiveFunction);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("B.boo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
+}
+
+
+TEST_CASE(Profiler_ToggleRecordAllocation) {
+ const char* kScript =
+ "class A {\n"
+ " var a;\n"
+ " var b;\n"
+ "}\n"
+ "class B {\n"
+ " static boo() {\n"
+ " return new A();\n"
+ " }\n"
+ "}\n"
+ "main() {\n"
+ " return B.boo();\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ EXPECT_VALID(lib);
+ Library& root_library = Library::Handle();
+ root_library ^= Api::UnwrapHandle(lib);
+
+ const Class& class_a = Class::Handle(GetClass(root_library, "A"));
+ EXPECT(!class_a.IsNull());
+
+ Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+ EXPECT_VALID(result);
+
+
+ {
+ Isolate* isolate = Isolate::Current();
+ StackZone zone(isolate);
+ HANDLESCOPE(isolate);
+ Profile profile(isolate);
+ AllocationFilter filter(isolate, class_a.id());
+ profile.Build(&filter, Profile::kNoTags);
+ // We should have no allocation samples.
+ EXPECT_EQ(0, profile.sample_count());
+ }
+
+ // Turn on allocation tracing for A.
+ class_a.SetTraceAllocation(true);
+
+ result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+ EXPECT_VALID(result);
+
+ {
+ Isolate* isolate = Isolate::Current();
+ StackZone zone(isolate);
+ HANDLESCOPE(isolate);
+ Profile profile(isolate);
+ AllocationFilter filter(isolate, class_a.id());
+ profile.Build(&filter, Profile::kNoTags);
+ // We should have one allocation sample.
+ EXPECT_EQ(1, profile.sample_count());
+ ProfileTrieWalker walker(&profile);
+
+ // Exclusive code: B.boo -> main.
+ walker.Reset(Profile::kExclusiveCode);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_STREQ("B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT(!walker.Down());
+
+ // Inclusive code: main -> B.boo.
+ walker.Reset(Profile::kInclusiveCode);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("B.boo", walker.CurrentName());
+ EXPECT(!walker.Down());
+
+ // Exclusive function: boo -> main.
+ walker.Reset(Profile::kExclusiveFunction);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_STREQ("B.boo", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT(!walker.Down());
+
+ // Inclusive function: main -> boo.
+ walker.Reset(Profile::kInclusiveFunction);
+ // Move down from the root.
+ EXPECT(walker.Down());
+ EXPECT_STREQ("main", walker.CurrentName());
+ EXPECT(walker.Down());
+ EXPECT_STREQ("B.boo", walker.CurrentName());
+ EXPECT(!walker.Down());
+ }
+
+ // Turn off allocation tracing for A.
+ class_a.SetTraceAllocation(false);
+
+ result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+ EXPECT_VALID(result);
+
+ {
+ Isolate* isolate = Isolate::Current();
+ StackZone zone(isolate);
+ HANDLESCOPE(isolate);
+ Profile profile(isolate);
+ AllocationFilter filter(isolate, class_a.id());
+ profile.Build(&filter, Profile::kNoTags);
+ // We should still only have one allocation sample.
+ EXPECT_EQ(1, profile.sample_count());
+ }
}
} // namespace dart
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 25de978..c40f71e 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -1521,6 +1521,8 @@
}
return true;
}
+ // TODO(rmacnak): There is no way to get the size retained by a class object.
+ // SizeRetainedByClass should be a separate RPC.
if (obj.IsClass()) {
const Class& cls = Class::Cast(obj);
ObjectGraph graph(isolate);
@@ -1529,18 +1531,11 @@
result.PrintJSON(js, true);
return true;
}
- if (obj.IsInstance() || obj.IsNull()) {
- // We don't use Instance::Cast here because it doesn't allow null.
- ObjectGraph graph(isolate);
- intptr_t retained_size = graph.SizeRetainedByInstance(obj);
- const Object& result = Object::Handle(Integer::New(retained_size));
- result.PrintJSON(js, true);
- return true;
- }
- js->PrintError(kInvalidParams,
- "%s: invalid 'targetId' parameter: "
- "id '%s' does not correspond to a "
- "library, class, or instance", js->method(), target_id);
+
+ ObjectGraph graph(isolate);
+ intptr_t retained_size = graph.SizeRetainedByInstance(obj);
+ const Object& result = Object::Handle(Integer::New(retained_size));
+ result.PrintJSON(js, true);
return true;
}
@@ -2224,13 +2219,13 @@
};
-static ProfilerService::TagOrder tags_enum_values[] = {
- ProfilerService::kNoTags,
- ProfilerService::kUserVM,
- ProfilerService::kUser,
- ProfilerService::kVMUser,
- ProfilerService::kVM,
- ProfilerService::kNoTags, // Default value.
+static Profile::TagOrder tags_enum_values[] = {
+ Profile::kNoTags,
+ Profile::kUserVM,
+ Profile::kUser,
+ Profile::kVMUser,
+ Profile::kVM,
+ Profile::kNoTags, // Default value.
};
@@ -2242,7 +2237,7 @@
static bool GetCpuProfile(Isolate* isolate, JSONStream* js) {
- ProfilerService::TagOrder tag_order =
+ Profile::TagOrder tag_order =
EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
ProfilerService::PrintJSON(js, tag_order);
return true;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index d764864..f0bbf8f 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -796,7 +796,9 @@
@Class super [optional];
// A list of interface types for this class.
- @Type[] interfaces;
+ //
+ // The value will be of the kind: Type.
+ @Instance[] interfaces;
// A list of fields in this class. Does not include fields from
// superclasses.
@@ -836,7 +838,7 @@
_@Code_ is a reference to a _Code_ object.
```
-class @Code extends @Object {
+class Code extends @Object {
// A name for this code object.
string name;
@@ -1061,7 +1063,10 @@
@Object owner;
// The declared type of this field.
- @Type declaredType;
+ //
+ // The value will always be of one of the kinds:
+ // Type, TypeRef, TypeParameter, BoundedType.
+ @Instance declaredType;
// Is this field const?
bool const;
@@ -1086,7 +1091,10 @@
@Object owner;
// The declared type of this field.
- @Type declaredType;
+ //
+ // The value will always be of one of the kinds:
+ // Type, TypeRef, TypeParameter, BoundedType.
+ @Instance declaredType;
// Is this field const?
bool const;
@@ -1136,10 +1144,10 @@
```
class FlagList extends Response {
// A list of all flags which are set to default values.
- unmodifiedFlags []Flag
+ Flag[] unmodifiedFlags;
// A list of all flags which have been modified by the user.
- modifiedFlags []Flag
+ Flag[] modifiedFlags;
}
```
@@ -1170,11 +1178,10 @@
@Library|@Class|@Function owner;
// Is this function static?
- bool static
+ bool static;
// Is this function const?
bool const;
-
}
```
@@ -1182,7 +1189,6 @@
```
-// A Dart language function.
class Function extends Object {
// The name of this function.
string name;
@@ -1263,6 +1269,13 @@
// Provided for instance kinds:
// TypeParameter
@Class parameterizedClass [optional];
+
+
+ // The pattern of a RegExp instance.
+ //
+ // Provided for instance kinds:
+ // RegExp
+ String pattern [optional];
}
```
@@ -1379,13 +1392,19 @@
// Provided for instance kinds:
// MirrorReference
@Instance mirrorReferent [optional];
-
+
+ // The pattern of a RegExp instance.
+ //
+ // Provided for instance kinds:
+ // RegExp
+ String pattern [optional];
+
// The key for a WeakProperty instance.
//
// Provided for instance kinds:
// WeakProperty
@Instance propertyKey [optional];
-
+
// The key for a WeakProperty instance.
//
// Provided for instance kinds:
@@ -1408,7 +1427,7 @@
// - or -
// the referent of a TypeRef instance.
//
- // The value will always be one of:
+ // The value will always be of one of the kinds:
// Type, TypeRef, TypeParameter, BoundedType.
//
// Provided for instance kinds:
@@ -1418,7 +1437,7 @@
// The bound of a TypeParameter or BoundedType.
//
- // The value will always be one of:
+ // The value will always be of one of the kinds:
// Type, TypeRef, TypeParameter, BoundedType.
//
// Provided for instance kinds:
@@ -1433,7 +1452,7 @@
### InstanceKind
```
-enum {
+enum InstanceKind {
// A general instance of the Dart class Object.
PlainInstance,
@@ -1484,6 +1503,9 @@
// An instance of the Dart class MirrorReference.
MirrorReference,
+ // An instance of the Dart class RegExp.
+ RegExp,
+
// An instance of the Dart class WeakProperty.
WeakProperty,
@@ -1682,7 +1704,7 @@
class @Object extends Response {
// A unique identifier for an Object. Passed to the
// getObject RPC to load this Object.
- string id
+ string id;
}
```
@@ -1816,7 +1838,7 @@
```
class SourceLocation extends Response {
- // The script contaiinging the source location.
+ // The script containing the source location.
@Script script;
// The first token of the location.
@@ -1833,7 +1855,7 @@
### Stack
```
-class Stack {
+class Stack extends Response {
Frame[] frames;
Message[] messages;
}
@@ -1877,7 +1899,10 @@
string name;
// A list of types.
- @Type[] types;
+ //
+ // The value will always be one of the kinds:
+ // Type, TypeRef, TypeParameter, BoundedType.
+ @Instance[] types;
}
```
@@ -1937,10 +1962,10 @@
// The time that the VM started in milliseconds since the epoch.
//
// Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
- int startTime
+ int startTime;
// A list of isolates running in the VM.
- @Isolate[] isolates
+ @Isolate[] isolates;
}
```
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index d657120..0d876d3 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1083,7 +1083,8 @@
const int kInlineInstanceSize = 12;
const intptr_t instance_size = cls.instance_size();
ASSERT(instance_size > 0);
- if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+ if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
+ !cls.trace_allocation()) {
Label slow_case;
// Allocate the object and update top to point to
// next object start and initialize the allocated object.
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 5d07451..10e2411 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -1128,7 +1128,8 @@
__ ldr(R1, Address(SP));
// R1: instantiated type arguments.
}
- if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+ if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
+ !cls.trace_allocation()) {
Label slow_case;
// Allocate the object and update top to point to
// next object start and initialize the allocated object.
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index e6f8818..95ba111 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1055,7 +1055,8 @@
__ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset));
// EDX: instantiated type arguments.
}
- if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+ if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
+ !cls.trace_allocation()) {
Label slow_case;
// Allocate the object and update top to point to
// next object start and initialize the allocated object.
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index a65cb5b..eb53d7f 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -1178,7 +1178,8 @@
__ lw(T1, Address(SP, 0 * kWordSize));
// T1: type arguments.
}
- if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+ if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
+ !cls.trace_allocation()) {
Label slow_case;
// Allocate the object and update top to point to
// next object start and initialize the allocated object.
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 2a15822..c844e1f 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1089,7 +1089,8 @@
__ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset));
// RDX: instantiated type arguments.
}
- if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+ if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
+ !cls.trace_allocation()) {
Label slow_case;
// Allocate the object and update top to point to
// next object start and initialize the allocated object.
diff --git a/samples/samples.status b/samples/samples.status
index 92b4837..224e573 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -25,4 +25,3 @@
*: Skip
[ $compiler == dart2js && $cps_ir ]
-sample_extension/test/sample_extension_test: Crash # Invalid argument(s)
diff --git a/sdk/lib/_internal/compiler/js_lib/annotations.dart b/sdk/lib/_internal/js_runtime/lib/annotations.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/annotations.dart
rename to sdk/lib/_internal/js_runtime/lib/annotations.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/async_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/async_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/collection_patch.dart b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/collection_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/collection_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/constant_map.dart b/sdk/lib/_internal/js_runtime/lib/constant_map.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/constant_map.dart
rename to sdk/lib/_internal/js_runtime/lib/constant_map.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/convert_patch.dart b/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/convert_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/convert_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
similarity index 87%
rename from sdk/lib/_internal/compiler/js_lib/core_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 7045e05..4e2e714 100644
--- a/sdk/lib/_internal/compiler/js_lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -510,3 +510,71 @@
throw new UnsupportedError("'Uri.base' is not supported");
}
}
+
+@patch
+class Resource {
+ @patch
+ const factory Resource(String uri) = _Resource;
+}
+
+Uri _resolvePackageUri(Uri packageUri) {
+ assert(packageUri.scheme == "package");
+ if (packageUri.hasAuthority) {
+ throw new ArgumentError("Package-URI must not have a host: $packageUri");
+ }
+ var resolved = Uri.base.resolve("packages/${packageUri.path}");
+ return resolved;
+}
+
+class _Resource implements Resource {
+ final String _location;
+
+ const _Resource(String uri) : _location = uri;
+
+ Uri get uri => Uri.base.resolve(_location);
+
+ Stream<List<int>> openRead() {
+ Uri uri = this.uri;
+ if (uri.scheme == "package") {
+ uri = _resolvePackageUri(uri);
+ }
+ if (uri.scheme == "http" || uri.scheme == "https") {
+ return _readAsStream(uri);
+ }
+ throw new StateError("Unable to find resource, unknown scheme: $_location");
+ }
+
+ Future<List<int>> readAsBytes() {
+ Uri uri = this.uri;
+ if (uri.scheme == "package") {
+ uri = _resolvePackageUri(uri);
+ }
+ if (uri.scheme == "http" || uri.scheme == "https") {
+ return _readAsBytes(uri);
+ }
+ throw new StateError("Unable to find resource, unknown scheme: $_location");
+ }
+
+ Future<String> readAsString({Encoding encoding: UTF8}) {
+ Uri uri = this.uri;
+ if (uri.scheme == "package") {
+ uri = _resolvePackageUri(uri);
+ }
+ if (uri.scheme == "http" || uri.scheme == "https") {
+ return _readAsString(uri);
+ }
+ throw new StateError("Unable to find resource, unknown scheme: $_location");
+ }
+
+ Stream<List<int>> _readAsStream(Uri uri) {
+ throw new UnimplementedError("Streaming bytes via HTTP");
+ }
+
+ Future<List<int>> _readAsBytes(Uri uri) {
+ throw new UnimplementedError("Reading bytes via HTTP");
+ }
+
+ Future<String> _readAsString(Uri uri) {
+ throw new UnimplementedError("Reading string via HTTP");
+ }
+}
diff --git a/sdk/lib/_internal/compiler/js_lib/developer_patch.dart b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/developer_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/developer_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/foreign_helper.dart b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/foreign_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/interceptors.dart b/sdk/lib/_internal/js_runtime/lib/interceptors.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/interceptors.dart
rename to sdk/lib/_internal/js_runtime/lib/interceptors.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/internal_patch.dart b/sdk/lib/_internal/js_runtime/lib/internal_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/internal_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/internal_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/io_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/io_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/isolate_helper.dart b/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/isolate_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/isolate_patch.dart b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/isolate_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/isolate_serialization.dart b/sdk/lib/_internal/js_runtime/lib/isolate_serialization.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/isolate_serialization.dart
rename to sdk/lib/_internal/js_runtime/lib/isolate_serialization.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_array.dart b/sdk/lib/_internal/js_runtime/lib/js_array.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_array.dart
rename to sdk/lib/_internal/js_runtime/lib/js_array.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/js_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_mirrors.dart b/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_mirrors.dart
rename to sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_names.dart b/sdk/lib/_internal/js_runtime/lib/js_names.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_names.dart
rename to sdk/lib/_internal/js_runtime/lib/js_names.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_number.dart
rename to sdk/lib/_internal/js_runtime/lib/js_number.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_primitives.dart b/sdk/lib/_internal/js_runtime/lib/js_primitives.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_primitives.dart
rename to sdk/lib/_internal/js_runtime/lib/js_primitives.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_rti.dart
rename to sdk/lib/_internal/js_runtime/lib/js_rti.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_string.dart b/sdk/lib/_internal/js_runtime/lib/js_string.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_string.dart
rename to sdk/lib/_internal/js_runtime/lib/js_string.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/linked_hash_map.dart b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/linked_hash_map.dart
rename to sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/math_patch.dart b/sdk/lib/_internal/js_runtime/lib/math_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/math_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/math_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/mirror_helper.dart b/sdk/lib/_internal/js_runtime/lib/mirror_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/mirror_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/mirror_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/mirrors_patch.dart b/sdk/lib/_internal/js_runtime/lib/mirrors_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/mirrors_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/mirrors_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/native_helper.dart b/sdk/lib/_internal/js_runtime/lib/native_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/native_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/native_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/native_typed_data.dart b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/native_typed_data.dart
rename to sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/preambles/README b/sdk/lib/_internal/js_runtime/lib/preambles/README
similarity index 75%
rename from sdk/lib/_internal/compiler/js_lib/preambles/README
rename to sdk/lib/_internal/js_runtime/lib/preambles/README
index 7eb614e..4465012 100644
--- a/sdk/lib/_internal/compiler/js_lib/preambles/README
+++ b/sdk/lib/_internal/js_runtime/lib/preambles/README
@@ -4,10 +4,10 @@
=Usage=
- d8:
- d8 <sdk>/lib/_internal/compiler/js_lib/preambles/d8.js <output>.js
+ d8 <sdk>/lib/_internal/js_runtime/lib/preambles/d8.js <output>.js
- jsshell:
- jsshell -f <sdk>/lib/_internal/compiler/js_lib/preambles/d8.js -f <output>.js
+ jsshell -f <sdk>/lib/_internal/js_runtime/lib/preambles/d8.js -f <output>.js
- node.js:
The d8 preamble file works for most programs.
diff --git a/sdk/lib/_internal/compiler/js_lib/preambles/d8.js b/sdk/lib/_internal/js_runtime/lib/preambles/d8.js
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/preambles/d8.js
rename to sdk/lib/_internal/js_runtime/lib/preambles/d8.js
diff --git a/sdk/lib/_internal/compiler/js_lib/preambles/jsshell.js b/sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/preambles/jsshell.js
rename to sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js
diff --git a/sdk/lib/_internal/compiler/js_lib/regexp_helper.dart b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/regexp_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/shared/async_await_error_codes.dart b/sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/shared/async_await_error_codes.dart
rename to sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
rename to sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/string_helper.dart b/sdk/lib/_internal/js_runtime/lib/string_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/string_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/string_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/typed_data_patch.dart b/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/typed_data_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart
diff --git a/sdk/lib/_internal/js_runtime/pubspec.yaml b/sdk/lib/_internal/js_runtime/pubspec.yaml
new file mode 100644
index 0000000..058f035
--- /dev/null
+++ b/sdk/lib/_internal/js_runtime/pubspec.yaml
@@ -0,0 +1,4 @@
+# Note: This package is not meant to be uploaded to pub. This file is used to
+# make it easer to develop on dart2js.
+name: js_runtime
+# version: do-not-upload
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index 7cd70c2..daeea77 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -2,339 +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.
+/// This file moved under `sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart`.
+@deprecated
library libraries;
-/**
- * A bit flag used by [LibraryInfo] indicating that a library is used by dart2js
- */
-const int DART2JS_PLATFORM = 1;
-
-/**
- * A bit flag used by [LibraryInfo] indicating that a library is used by the VM
- */
-const int VM_PLATFORM = 2;
-
-/**
- * Mapping of "dart:" library name (e.g. "core") to information about that library.
- * This information is structured such that Dart Editor can parse this file
- * and extract the necessary information without executing it
- * while other tools can access via execution.
- */
-const Map<String, LibraryInfo> LIBRARIES = const {
-
- "async": const LibraryInfo(
- "async/async.dart",
- maturity: Maturity.STABLE,
- dart2jsPatchPath: "_internal/compiler/js_lib/async_patch.dart"),
-
- "_blink": const LibraryInfo(
- "_blink/dartium/_blink_dartium.dart",
- category: "Client",
- implementation: true,
- documented: false,
- platforms: VM_PLATFORM),
-
- "_chrome": const LibraryInfo(
- "_chrome/dart2js/chrome_dart2js.dart",
- documented: false,
- category: "Client"),
-
- "collection": const LibraryInfo(
- "collection/collection.dart",
- maturity: Maturity.STABLE,
- dart2jsPatchPath: "_internal/compiler/js_lib/collection_patch.dart"),
-
- "convert": const LibraryInfo(
- "convert/convert.dart",
- maturity: Maturity.STABLE,
- dart2jsPatchPath: "_internal/compiler/js_lib/convert_patch.dart"),
-
- "core": const LibraryInfo(
- "core/core.dart",
- maturity: Maturity.STABLE,
- dart2jsPatchPath: "_internal/compiler/js_lib/core_patch.dart"),
-
- "developer": const LibraryInfo(
- "developer/developer.dart",
- maturity: Maturity.UNSTABLE,
- dart2jsPatchPath: "_internal/compiler/js_lib/developer_patch.dart"),
-
- "html": const LibraryInfo(
- "html/dartium/html_dartium.dart",
- category: "Client",
- maturity: Maturity.WEB_STABLE,
- dart2jsPath: "html/dart2js/html_dart2js.dart"),
-
- "html_common": const LibraryInfo(
- "html/html_common/html_common.dart",
- category: "Client",
- maturity: Maturity.WEB_STABLE,
- dart2jsPath: "html/html_common/html_common_dart2js.dart",
- documented: false,
- implementation: true),
-
- "indexed_db": const LibraryInfo(
- "indexed_db/dartium/indexed_db_dartium.dart",
- category: "Client",
- maturity: Maturity.WEB_STABLE,
- dart2jsPath: "indexed_db/dart2js/indexed_db_dart2js.dart"),
-
- "io": const LibraryInfo(
- "io/io.dart",
- category: "Server",
- maturity: Maturity.STABLE,
- dart2jsPatchPath: "_internal/compiler/js_lib/io_patch.dart"),
-
- "isolate": const LibraryInfo(
- "isolate/isolate.dart",
- maturity: Maturity.STABLE,
- dart2jsPatchPath: "_internal/compiler/js_lib/isolate_patch.dart"),
-
- "js": const LibraryInfo(
- "js/dartium/js_dartium.dart",
- category: "Client",
- maturity: Maturity.STABLE,
- dart2jsPath: "js/dart2js/js_dart2js.dart"),
-
- "math": const LibraryInfo(
- "math/math.dart",
- maturity: Maturity.STABLE,
- dart2jsPatchPath: "_internal/compiler/js_lib/math_patch.dart"),
-
- "mirrors": const LibraryInfo(
- "mirrors/mirrors.dart",
- maturity: Maturity.UNSTABLE,
- dart2jsPatchPath: "_internal/compiler/js_lib/mirrors_patch.dart"),
-
- "profiler": const LibraryInfo(
- "profiler/profiler.dart",
- maturity: Maturity.UNSTABLE),
-
- "nativewrappers": const LibraryInfo(
- "html/dartium/nativewrappers.dart",
- category: "Client",
- implementation: true,
- documented: false,
- platforms: VM_PLATFORM),
-
- "typed_data": const LibraryInfo(
- "typed_data/typed_data.dart",
- maturity: Maturity.STABLE,
- dart2jsPatchPath: "_internal/compiler/js_lib/typed_data_patch.dart"),
-
- "_native_typed_data": const LibraryInfo(
- "_internal/compiler/js_lib/native_typed_data.dart",
- category: "Internal",
- implementation: true,
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- "svg": const LibraryInfo(
- "svg/dartium/svg_dartium.dart",
- category: "Client",
- maturity: Maturity.WEB_STABLE,
- dart2jsPath: "svg/dart2js/svg_dart2js.dart"),
-
- "web_audio": const LibraryInfo(
- "web_audio/dartium/web_audio_dartium.dart",
- category: "Client",
- maturity: Maturity.WEB_STABLE,
- dart2jsPath: "web_audio/dart2js/web_audio_dart2js.dart"),
-
- "web_gl": const LibraryInfo(
- "web_gl/dartium/web_gl_dartium.dart",
- category: "Client",
- maturity: Maturity.WEB_STABLE,
- dart2jsPath: "web_gl/dart2js/web_gl_dart2js.dart"),
-
- "web_sql": const LibraryInfo(
- "web_sql/dartium/web_sql_dartium.dart",
- category: "Client",
- maturity: Maturity.WEB_STABLE,
- dart2jsPath: "web_sql/dart2js/web_sql_dart2js.dart"),
-
- "_internal": const LibraryInfo(
- "internal/internal.dart",
- category: "Internal",
- documented: false,
- dart2jsPatchPath:
- "_internal/compiler/js_lib/internal_patch.dart"),
-
- "_js_helper": const LibraryInfo(
- "_internal/compiler/js_lib/js_helper.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- "_interceptors": const LibraryInfo(
- "_internal/compiler/js_lib/interceptors.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- "_foreign_helper": const LibraryInfo(
- "_internal/compiler/js_lib/foreign_helper.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- "_isolate_helper": const LibraryInfo(
- "_internal/compiler/js_lib/isolate_helper.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- "_js_mirrors": const LibraryInfo(
- "_internal/compiler/js_lib/js_mirrors.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- "_js_names": const LibraryInfo(
- "_internal/compiler/js_lib/js_names.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- "_js_primitives": const LibraryInfo(
- "_internal/compiler/js_lib/js_primitives.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- // TODO(ahe): This library is only for dart2dart, perhaps it should use a
- // different platform.
- "_mirror_helper": const LibraryInfo(
- "_internal/compiler/js_lib/mirror_helper.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- "_js_embedded_names": const LibraryInfo(
- "_internal/compiler/js_lib/shared/embedded_names.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- "_async_await_error_codes": const LibraryInfo(
- "_internal/compiler/js_lib/shared/async_await_error_codes.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-
- "_metadata": const LibraryInfo(
- "html/html_common/metadata.dart",
- category: "Internal",
- documented: false,
- platforms: DART2JS_PLATFORM),
-};
-
-/**
- * Information about a "dart:" library.
- */
-class LibraryInfo {
-
- /**
- * Path to the library's *.dart file relative to this file.
- */
- final String path;
-
- /**
- * The category in which the library should appear in the editor
- * (e.g. "Shared", "Client", "Server", ...).
- * If a category is not specified it defaults to "Shared".
- */
- final String category;
-
- /**
- * Path to the dart2js library's *.dart file relative to this file
- * or null if dart2js uses the common library path defined above.
- * Access using the [#getDart2JsPath()] method.
- */
- final String dart2jsPath;
-
- /**
- * Path to the dart2js library's patch file relative to this file
- * or null if no dart2js patch file associated with this library.
- * Access using the [#getDart2JsPatchPath()] method.
- */
- final String dart2jsPatchPath;
-
- /**
- * True if this library is documented and should be shown to the user.
- */
- final bool documented;
-
- /**
- * Bit flags indicating which platforms consume this library.
- * See [DART2JS_LIBRARY] and [VM_LIBRARY].
- */
- final int platforms;
-
- /**
- * True if the library contains implementation details for another library.
- * The implication is that these libraries are less commonly used
- * and that tools like Dart Editor should not show these libraries
- * in a list of all libraries unless the user specifically asks the tool to
- * do so.
- */
- final bool implementation;
-
- /**
- * States the current maturity of this library.
- */
- final Maturity maturity;
-
- const LibraryInfo(this.path, {
- this.category: "Shared",
- this.dart2jsPath,
- this.dart2jsPatchPath,
- this.implementation: false,
- this.documented: true,
- this.maturity: Maturity.UNSPECIFIED,
- this.platforms: DART2JS_PLATFORM | VM_PLATFORM});
-
- bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0;
- bool get isVmLibrary => (platforms & VM_PLATFORM) != 0;
-}
-
-
-
-/**
- * Abstraction to capture the maturity of a library.
- */
-class Maturity {
- final int level;
- final String name;
- final String description;
-
- const Maturity(this.level, this.name, this.description);
-
- String toString() => "$name: $level\n$description\n";
-
- static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
- "This library will be remove before next major release.");
-
- static const Maturity EXPERIMENTAL = const Maturity(1, "Experimental",
- "This library is experimental and will likely change or be removed\n"
- "in future versions.");
-
- static const Maturity UNSTABLE = const Maturity(2, "Unstable",
- "This library is in still changing and have not yet endured\n"
- "sufficient real-world testing.\n"
- "Backwards-compatibility is NOT guaranteed.");
-
- static const Maturity WEB_STABLE = const Maturity(3, "Web Stable",
- "This library is tracking the DOM evolution as defined by WC3.\n"
- "Backwards-compatibility is NOT guaranteed.");
-
- static const Maturity STABLE = const Maturity(4, "Stable",
- "The library is stable. API backwards-compatibility is guaranteed.\n"
- "However implementation details might change.");
-
- static const Maturity LOCKED = const Maturity(5, "Locked",
- "This library will not change except when serious bugs are encountered.");
-
- static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
- "The maturity for this library has not been specified.");
-}
+export 'sdk_library_metadata/lib/libraries.dart';
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
new file mode 100644
index 0000000..1a2e3eb
--- /dev/null
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -0,0 +1,340 @@
+// 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 libraries;
+
+/**
+ * A bit flag used by [LibraryInfo] indicating that a library is used by dart2js
+ */
+const int DART2JS_PLATFORM = 1;
+
+/**
+ * A bit flag used by [LibraryInfo] indicating that a library is used by the VM
+ */
+const int VM_PLATFORM = 2;
+
+/**
+ * Mapping of "dart:" library name (e.g. "core") to information about that library.
+ * This information is structured such that Dart Editor can parse this file
+ * and extract the necessary information without executing it
+ * while other tools can access via execution.
+ */
+const Map<String, LibraryInfo> LIBRARIES = const {
+
+ "async": const LibraryInfo(
+ "async/async.dart",
+ maturity: Maturity.STABLE,
+ dart2jsPatchPath: "_internal/js_runtime/lib/async_patch.dart"),
+
+ "_blink": const LibraryInfo(
+ "_blink/dartium/_blink_dartium.dart",
+ category: "Client",
+ implementation: true,
+ documented: false,
+ platforms: VM_PLATFORM),
+
+ "_chrome": const LibraryInfo(
+ "_chrome/dart2js/chrome_dart2js.dart",
+ documented: false,
+ category: "Client"),
+
+ "collection": const LibraryInfo(
+ "collection/collection.dart",
+ maturity: Maturity.STABLE,
+ dart2jsPatchPath: "_internal/js_runtime/lib/collection_patch.dart"),
+
+ "convert": const LibraryInfo(
+ "convert/convert.dart",
+ maturity: Maturity.STABLE,
+ dart2jsPatchPath: "_internal/js_runtime/lib/convert_patch.dart"),
+
+ "core": const LibraryInfo(
+ "core/core.dart",
+ maturity: Maturity.STABLE,
+ dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"),
+
+ "developer": const LibraryInfo(
+ "developer/developer.dart",
+ maturity: Maturity.UNSTABLE,
+ dart2jsPatchPath: "_internal/js_runtime/lib/developer_patch.dart"),
+
+ "html": const LibraryInfo(
+ "html/dartium/html_dartium.dart",
+ category: "Client",
+ maturity: Maturity.WEB_STABLE,
+ dart2jsPath: "html/dart2js/html_dart2js.dart"),
+
+ "html_common": const LibraryInfo(
+ "html/html_common/html_common.dart",
+ category: "Client",
+ maturity: Maturity.WEB_STABLE,
+ dart2jsPath: "html/html_common/html_common_dart2js.dart",
+ documented: false,
+ implementation: true),
+
+ "indexed_db": const LibraryInfo(
+ "indexed_db/dartium/indexed_db_dartium.dart",
+ category: "Client",
+ maturity: Maturity.WEB_STABLE,
+ dart2jsPath: "indexed_db/dart2js/indexed_db_dart2js.dart"),
+
+ "io": const LibraryInfo(
+ "io/io.dart",
+ category: "Server",
+ maturity: Maturity.STABLE,
+ dart2jsPatchPath: "_internal/js_runtime/lib/io_patch.dart"),
+
+ "isolate": const LibraryInfo(
+ "isolate/isolate.dart",
+ maturity: Maturity.STABLE,
+ dart2jsPatchPath: "_internal/js_runtime/lib/isolate_patch.dart"),
+
+ "js": const LibraryInfo(
+ "js/dartium/js_dartium.dart",
+ category: "Client",
+ maturity: Maturity.STABLE,
+ dart2jsPath: "js/dart2js/js_dart2js.dart"),
+
+ "math": const LibraryInfo(
+ "math/math.dart",
+ maturity: Maturity.STABLE,
+ dart2jsPatchPath: "_internal/js_runtime/lib/math_patch.dart"),
+
+ "mirrors": const LibraryInfo(
+ "mirrors/mirrors.dart",
+ maturity: Maturity.UNSTABLE,
+ dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch.dart"),
+
+ "profiler": const LibraryInfo(
+ "profiler/profiler.dart",
+ maturity: Maturity.UNSTABLE),
+
+ "nativewrappers": const LibraryInfo(
+ "html/dartium/nativewrappers.dart",
+ category: "Client",
+ implementation: true,
+ documented: false,
+ platforms: VM_PLATFORM),
+
+ "typed_data": const LibraryInfo(
+ "typed_data/typed_data.dart",
+ maturity: Maturity.STABLE,
+ dart2jsPatchPath: "_internal/js_runtime/lib/typed_data_patch.dart"),
+
+ "_native_typed_data": const LibraryInfo(
+ "_internal/js_runtime/lib/native_typed_data.dart",
+ category: "Internal",
+ implementation: true,
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ "svg": const LibraryInfo(
+ "svg/dartium/svg_dartium.dart",
+ category: "Client",
+ maturity: Maturity.WEB_STABLE,
+ dart2jsPath: "svg/dart2js/svg_dart2js.dart"),
+
+ "web_audio": const LibraryInfo(
+ "web_audio/dartium/web_audio_dartium.dart",
+ category: "Client",
+ maturity: Maturity.WEB_STABLE,
+ dart2jsPath: "web_audio/dart2js/web_audio_dart2js.dart"),
+
+ "web_gl": const LibraryInfo(
+ "web_gl/dartium/web_gl_dartium.dart",
+ category: "Client",
+ maturity: Maturity.WEB_STABLE,
+ dart2jsPath: "web_gl/dart2js/web_gl_dart2js.dart"),
+
+ "web_sql": const LibraryInfo(
+ "web_sql/dartium/web_sql_dartium.dart",
+ category: "Client",
+ maturity: Maturity.WEB_STABLE,
+ dart2jsPath: "web_sql/dart2js/web_sql_dart2js.dart"),
+
+ "_internal": const LibraryInfo(
+ "internal/internal.dart",
+ category: "Internal",
+ documented: false,
+ dart2jsPatchPath:
+ "_internal/js_runtime/lib/internal_patch.dart"),
+
+ "_js_helper": const LibraryInfo(
+ "_internal/js_runtime/lib/js_helper.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ "_interceptors": const LibraryInfo(
+ "_internal/js_runtime/lib/interceptors.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ "_foreign_helper": const LibraryInfo(
+ "_internal/js_runtime/lib/foreign_helper.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ "_isolate_helper": const LibraryInfo(
+ "_internal/js_runtime/lib/isolate_helper.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ "_js_mirrors": const LibraryInfo(
+ "_internal/js_runtime/lib/js_mirrors.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ "_js_names": const LibraryInfo(
+ "_internal/js_runtime/lib/js_names.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ "_js_primitives": const LibraryInfo(
+ "_internal/js_runtime/lib/js_primitives.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ // TODO(ahe): This library is only for dart2dart, perhaps it should use a
+ // different platform.
+ "_mirror_helper": const LibraryInfo(
+ "_internal/js_runtime/lib/mirror_helper.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ "_js_embedded_names": const LibraryInfo(
+ "_internal/js_runtime/lib/shared/embedded_names.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ "_async_await_error_codes": const LibraryInfo(
+ "_internal/js_runtime/lib/shared/async_await_error_codes.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+
+ "_metadata": const LibraryInfo(
+ "html/html_common/metadata.dart",
+ category: "Internal",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
+};
+
+/**
+ * Information about a "dart:" library.
+ */
+class LibraryInfo {
+
+ /**
+ * Path to the library's *.dart file relative to this file.
+ */
+ final String path;
+
+ /**
+ * The category in which the library should appear in the editor
+ * (e.g. "Shared", "Client", "Server", ...).
+ * If a category is not specified it defaults to "Shared".
+ */
+ final String category;
+
+ /**
+ * Path to the dart2js library's *.dart file relative to this file
+ * or null if dart2js uses the common library path defined above.
+ * Access using the [#getDart2JsPath()] method.
+ */
+ final String dart2jsPath;
+
+ /**
+ * Path to the dart2js library's patch file relative to this file
+ * or null if no dart2js patch file associated with this library.
+ * Access using the [#getDart2JsPatchPath()] method.
+ */
+ final String dart2jsPatchPath;
+
+ /**
+ * True if this library is documented and should be shown to the user.
+ */
+ final bool documented;
+
+ /**
+ * Bit flags indicating which platforms consume this library.
+ * See [DART2JS_LIBRARY] and [VM_LIBRARY].
+ */
+ final int platforms;
+
+ /**
+ * True if the library contains implementation details for another library.
+ * The implication is that these libraries are less commonly used
+ * and that tools like Dart Editor should not show these libraries
+ * in a list of all libraries unless the user specifically asks the tool to
+ * do so.
+ */
+ final bool implementation;
+
+ /**
+ * States the current maturity of this library.
+ */
+ final Maturity maturity;
+
+ const LibraryInfo(this.path, {
+ this.category: "Shared",
+ this.dart2jsPath,
+ this.dart2jsPatchPath,
+ this.implementation: false,
+ this.documented: true,
+ this.maturity: Maturity.UNSPECIFIED,
+ this.platforms: DART2JS_PLATFORM | VM_PLATFORM});
+
+ bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0;
+ bool get isVmLibrary => (platforms & VM_PLATFORM) != 0;
+}
+
+
+
+/**
+ * Abstraction to capture the maturity of a library.
+ */
+class Maturity {
+ final int level;
+ final String name;
+ final String description;
+
+ const Maturity(this.level, this.name, this.description);
+
+ String toString() => "$name: $level\n$description\n";
+
+ static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
+ "This library will be remove before next major release.");
+
+ static const Maturity EXPERIMENTAL = const Maturity(1, "Experimental",
+ "This library is experimental and will likely change or be removed\n"
+ "in future versions.");
+
+ static const Maturity UNSTABLE = const Maturity(2, "Unstable",
+ "This library is in still changing and have not yet endured\n"
+ "sufficient real-world testing.\n"
+ "Backwards-compatibility is NOT guaranteed.");
+
+ static const Maturity WEB_STABLE = const Maturity(3, "Web Stable",
+ "This library is tracking the DOM evolution as defined by WC3.\n"
+ "Backwards-compatibility is NOT guaranteed.");
+
+ static const Maturity STABLE = const Maturity(4, "Stable",
+ "The library is stable. API backwards-compatibility is guaranteed.\n"
+ "However implementation details might change.");
+
+ static const Maturity LOCKED = const Maturity(5, "Locked",
+ "This library will not change except when serious bugs are encountered.");
+
+ static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
+ "The maturity for this library has not been specified.");
+}
diff --git a/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml b/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml
new file mode 100644
index 0000000..4d09374
--- /dev/null
+++ b/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml
@@ -0,0 +1,4 @@
+# Note: This package is not meant to be uploaded to pub. This file is used to
+# make it easer to depend on libraries.dart from sdk packages like dart2js.
+name: sdk_library_metadata
+# version: do-not-upload
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index 4b11edc..a33c8fa 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -157,6 +157,7 @@
import "dart:_internal" as internal show Symbol;
import "dart:convert" show UTF8, LATIN1, Encoding;
import "dart:math" show Random; // Used by List.shuffle.
+import "dart:async" show Stream, Future; // Used by Resource.
part "annotations.dart";
part "bool.dart";
@@ -181,6 +182,7 @@
part "pattern.dart";
part "print.dart";
part "regexp.dart";
+part "resource.dart";
part "set.dart";
part "sink.dart";
part "stacktrace.dart";
diff --git a/sdk/lib/core/core_sources.gypi b/sdk/lib/core/core_sources.gypi
index 2c12762..6cd311f 100644
--- a/sdk/lib/core/core_sources.gypi
+++ b/sdk/lib/core/core_sources.gypi
@@ -29,6 +29,7 @@
'pattern.dart',
'print.dart',
'regexp.dart',
+ 'resource.dart',
'set.dart',
'sink.dart',
'stacktrace.dart',
diff --git a/sdk/lib/core/resource.dart b/sdk/lib/core/resource.dart
new file mode 100644
index 0000000..9bb88d1
--- /dev/null
+++ b/sdk/lib/core/resource.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart.core;
+
+/**
+ * A resource that can be read into the program.
+ *
+ * A resource is data that can be located using a URI and read into
+ * the program at runtime.
+ * The URI may use the `package` scheme to read resources provided
+ * along with package sources.
+ */
+abstract class Resource {
+ /**
+ * Creates a resource object with the given [uri] as location.
+ *
+ * The `uri` is a string containing a valid URI.
+ * If the string is not a valid URI, using any of the functions on
+ * the resource object will fail.
+ *
+ * The URI may be relative, in which case it will be resolved
+ * against [Uri.base] before being used.
+ *
+ * The URI may use the `package` scheme, which is always supported.
+ * Other schemes may also be supported where possible.
+ */
+ external const factory Resource(String uri);
+
+ /**
+ * The location `uri` of this resource.
+ *
+ * This is a [Uri] of the `uri` parameter given to the constructor.
+ * If the parameter was not a valid URI, reading `uri` may fail.
+ */
+ Uri get uri;
+
+ /** Read the resource content as a stream of bytes. */
+ Stream<List<int>> openRead();
+
+ /** Read the resource content. */
+ Future<List<int>> readAsBytes();
+
+ /**
+ * Read the resource content as a string.
+ *
+ * The content is decoded into a string using an [Encoding].
+ * If no other encoding is provided, it defaults to UTF-8.
+ */
+ Future<String> readAsString({Encoding encoding});
+}
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 1de3e1c..9e07f31 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -120,9 +120,9 @@
'_DOMWindowCrossFrame': () => _DOMWindowCrossFrame,
// FIXME: Move these to better locations.
'DateTime': () => DateTime,
- 'JsObject': () => js.JsObject,
- 'JsFunction': () => js.JsFunction,
- 'JsArray': () => js.JsArray,
+ 'JsObject': () => js.JsObjectImpl,
+ 'JsFunction': () => js.JsFunctionImpl,
+ 'JsArray': () => js.JsArrayImpl,
'AbstractWorker': () => AbstractWorker,
'Animation': () => Animation,
'AnimationEffect': () => AnimationEffect,
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index e7f3004..0bb53c3 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -89,11 +89,388 @@
import 'dart:collection' show ListMixin;
import 'dart:nativewrappers';
+import 'dart:math' as math;
+import 'dart:mirrors' as mirrors;
+
+// Pretend we are always in checked mode as we aren't interested in users
+// running Dartium code outside of checked mode.
+final bool CHECK_JS_INVOCATIONS = true;
+
+final _allowedMethods = new Map<Symbol, _DeclarationSet>();
+final _allowedGetters = new Map<Symbol, _DeclarationSet>();
+final _allowedSetters = new Map<Symbol, _DeclarationSet>();
+
+final _jsInterfaceTypes = new Set<Type>();
+Iterable<Type> get jsInterfaceTypes => _jsInterfaceTypes;
+
+/// A collection of methods where all methods have the same name.
+/// This class is intended to optimize whether a specific invocation is
+/// appropritate for at least some of the methods in the collection.
+class _DeclarationSet {
+ _DeclarationSet() : _members = <mirrors.DeclarationMirror>[];
+
+ static bool _checkType(obj, mirrors.TypeMirror type) {
+ if (obj == null) return true;
+ return mirrors.reflectType(obj.runtimeType).isSubtypeOf(type);
+ }
+
+ /// Returns whether the return [value] has a type is consistent with the
+ /// return type from at least one of the members matching the DeclarationSet.
+ bool _checkReturnType(value) {
+ if (value == null) return true;
+ var valueMirror = mirrors.reflectType(value.runtimeType);
+ for (var member in _members) {
+ if (member is mirrors.VariableMirror || member.isGetter) {
+ // TODO(jacobr): actually check return types for getters that return
+ // function types.
+ return true;
+ } else {
+ if (valueMirror.isSubtypeOf(member.returnType)) return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check whether the [invocation] is consistent with the [member] mirror.
+ */
+ bool _checkDeclaration(
+ Invocation invocation, mirrors.DeclarationMirror member) {
+ if (member is mirrors.VariableMirror || (member as dynamic).isGetter) {
+ // TODO(jacobr): actually check method types against the function type
+ // returned by the getter or field.
+ return true;
+ }
+ var parameters = (member as dynamic).parameters;
+ var positionalArguments = invocation.positionalArguments;
+ // Too many arguments
+ if (parameters.length < positionalArguments.length) return false;
+ // Too few required arguments.
+ if (parameters.length > positionalArguments.length &&
+ !parameters[positionalArguments.length].isOptional) return false;
+ for (var i = 0; i < positionalArguments.length; i++) {
+ if (parameters[i].isNamed) {
+ // Not enough positional arguments.
+ return false;
+ }
+ if (!_checkType(
+ invocation.positionalArguments[i], parameters[i].type)) return false;
+ }
+ if (invocation.namedArguments.isNotEmpty) {
+ var startNamed;
+ for (startNamed = parameters.length - 1; startNamed >= 0; startNamed--) {
+ if (!parameters[startNamed].isNamed) break;
+ }
+ startNamed++;
+
+ // TODO(jacobr): we are unneccessarily using an O(n^2) algorithm here.
+ // If we have JS APIs with a lange number of named parameters we should
+ // optimize this. Either use a HashSet or invert this, walking over
+ // parameters, querying invocation, and making sure we match
+ //invocation.namedArguments.size keys.
+ for (var name in invocation.namedArguments.keys) {
+ bool match = false;
+ for (var j = startNamed; j < parameters.length; j++) {
+ var p = parameters[j];
+ if (p.simpleName == name) {
+ if (!_checkType(invocation.namedArguments[name],
+ parameters[j].type)) return false;
+ match = true;
+ break;
+ }
+ }
+ if (match == false) return false;
+ }
+ }
+ return true;
+ }
+
+ bool checkInvocation(Invocation invocation) {
+ for (var member in _members) {
+ if (_checkDeclaration(invocation, member)) return true;
+ }
+ return false;
+ }
+
+ void add(mirrors.DeclarationMirror mirror) {
+ _members.add(mirror);
+ }
+
+ final List<mirrors.DeclarationMirror> _members;
+}
+
+/**
+ * Temporary method that we hope to remove at some point. This method should
+ * generally only be called by machine generated code.
+ */
+void registerJsInterfaces(List<Type> classes) {
+ if (_finalized == true) {
+ throw 'JSInterop class registration already finalized';
+ }
+ for (Type type in classes) {
+ if (!_jsInterfaceTypes.add(type)) continue; // Already registered.
+ mirrors.ClassMirror typeMirror = mirrors.reflectType(type);
+ typeMirror.declarations.forEach((symbol, declaration) {
+ if (declaration is mirrors.MethodMirror ||
+ declaration is mirrors.VariableMirror && !declaration.isStatic) {
+ bool treatAsGetter = false;
+ bool treatAsSetter = false;
+ if (declaration is mirrors.VariableMirror) {
+ treatAsGetter = true;
+ if (!declaration.isConst && !declaration.isFinal) {
+ treatAsSetter = true;
+ }
+ } else {
+ if (declaration.isGetter) {
+ treatAsGetter = true;
+ } else if (declaration.isSetter) {
+ treatAsSetter = true;
+ } else if (!declaration.isConstructor) {
+ _allowedMethods
+ .putIfAbsent(symbol, () => new _DeclarationSet())
+ .add(declaration);
+ }
+ }
+ if (treatAsGetter) {
+ _allowedGetters
+ .putIfAbsent(symbol, () => new _DeclarationSet())
+ .add(declaration);
+ _allowedMethods
+ .putIfAbsent(symbol, () => new _DeclarationSet())
+ .add(declaration);
+ }
+ if (treatAsSetter) {
+ _allowedSetters
+ .putIfAbsent(symbol, () => new _DeclarationSet())
+ .add(declaration);
+ }
+ }
+ });
+ }
+}
+
+_finalizeJsInterfaces() native "Js_finalizeJsInterfaces";
+
+/**
+ * Generates a part file defining source code for JsObjectImpl and related
+ * classes. This calass is needed so that type checks for all registered JavaScript
+ * interop classes pass.
+ */
+String _generateJsObjectImplPart() {
+ Iterable<Type> types = jsInterfaceTypes;
+ var libraryPrefixes = new Map<mirrors.LibraryMirror, String>();
+ var prefixNames = new Set<String>();
+ var sb = new StringBuffer();
+
+ var implements = <String>[];
+ for (var type in types) {
+ mirrors.ClassMirror typeMirror = mirrors.reflectType(type);
+ mirrors.LibraryMirror libraryMirror = typeMirror.owner;
+ var prefixName;
+ if (libraryPrefixes.containsKey(libraryMirror)) {
+ prefixName = libraryPrefixes[libraryMirror];
+ } else {
+ var basePrefixName =
+ mirrors.MirrorSystem.getName(libraryMirror.simpleName);
+ basePrefixName = basePrefixName.replaceAll('.', '_');
+ if (basePrefixName.isEmpty) basePrefixName = "lib";
+ prefixName = basePrefixName;
+ var i = 1;
+ while (prefixNames.contains(prefixName)) {
+ prefixName = '$basePrefixName$i';
+ i++;
+ }
+ prefixNames.add(prefixName);
+ libraryPrefixes[libraryMirror] = prefixName;
+ }
+ implements.add(
+ '${prefixName}.${mirrors.MirrorSystem.getName(typeMirror.simpleName)}');
+ }
+ libraryPrefixes.forEach((libraryMirror, prefix) {
+ sb.writeln('import "${libraryMirror.uri}" as $prefix;');
+ });
+ var implementsClause =
+ implements.isEmpty ? "" : "implements ${implements.join(', ')}";
+ // TODO(jacobr): only certain classes need to be implemented by
+ // Function and Array.
+ sb.write('''
+class JsObjectImpl extends JsObject $implementsClause {
+ JsObjectImpl.internal() : super.internal();
+}
+
+class JsFunctionImpl extends JsFunction $implementsClause {
+ JsFunctionImpl.internal() : super.internal();
+}
+
+class JsArrayImpl<E> extends JsArray<E> $implementsClause {
+ JsArrayImpl.internal() : super.internal();
+}
+''');
+ return sb.toString();
+}
+
+// Start of block of helper methods facilitating emulating JavaScript Array
+// methods on Dart List objects passed to JavaScript via JS interop.
+// TODO(jacobr): match JS more closely.
+String _toStringJs(obj) => '$obj';
+
+// TODO(jacobr): this might not exactly match JS semantics but should be
+// adequate for now.
+int _toIntJs(obj) {
+ if (obj is int) return obj;
+ if (obj is num) return obj.toInt();
+ return num.parse('$obj'.trim(), (_) => 0).toInt();
+}
+
+// TODO(jacobr): this might not exactly match JS semantics but should be
+// adequate for now.
+num _toNumJs(obj) {
+ return obj is num ? obj : num.parse('$obj'.trim(), (_) => 0);
+}
+
+/// Match the behavior of setting List length in JavaScript with the exception
+/// that Dart does not distinguish undefined and null.
+_setListLength(List list, rawlen) {
+ num len = _toNumJs(rawlen);
+ if (len is! int || len < 0) {
+ throw new RangeError("Invalid array length");
+ }
+ if (len > list.length) {
+ _arrayExtend(list, len);
+ } else if (len < list.length) {
+ list.removeRange(len, list.length);
+ }
+ return rawlen;
+}
+
+// TODO(jacobr): should we really bother with this method instead of just
+// shallow copying to a JS array and calling the JavaScript join method?
+String _arrayJoin(List list, sep) {
+ if (sep == null) {
+ sep = ",";
+ }
+ return list.map((e) => e == null ? "" : e.toString()).join(sep.toString());
+}
+
+// TODO(jacobr): should we really bother with this method instead of just
+// shallow copying to a JS array and using the toString method?
+String _arrayToString(List list) => _arrayJoin(list, ",");
+
+int _arrayPush(List list, List args) {
+ for(var e in args) {
+ list.add(e);
+ }
+ return list.length;
+}
+
+_arrayPop(List list) {
+ if (list.length > 0) return list.removeLast();
+}
+
+// TODO(jacobr): would it be better to just copy input to a JS List
+// and call Array.concat?
+List _arrayConcat(List input, List args) {
+ var ret = new List.from(input);
+ for (var e in args) {
+ // TODO(jacobr): technically in ES6 we should use
+ // Symbol.isConcatSpreadable to determine whether call addAll. Once v8
+ // supports it, we can make all Dart classes implementing Iterable
+ // specify isConcatSpreadable and tweak this behavior to allow Iterable.
+ if (e is List) {
+ ret.addAll(e);
+ } else {
+ ret.add(e);
+ }
+ }
+ return ret;
+}
+
+List _arraySplice(List input, List args) {
+ int start = 0;
+ if (args.length > 0) {
+ var rawStart = _toIntJs(args[0]);
+ if (rawStart < 0) {
+ start = math.max(0, input.length - rawStart);
+ } else {
+ start = math.min(input.length, rawStart);
+ }
+ }
+ var end = start;
+ if (args.length > 1) {
+ var rawDeleteCount = _toIntJs(args[1]);
+ if (rawDeleteCount < 0) rawDeleteCount = 0;
+ end = math.min(input.length, start + rawDeleteCount);
+ }
+ var replacement = [];
+ var removedElements = input.getRange(start, end).toList();
+ if (args.length > 2) {
+ replacement = args.getRange(2, args.length);
+ }
+ input.replaceRange(start, end, replacement);
+ return removedElements;
+}
+
+List _arrayReverse(List l) {
+ for (var i = 0, j = l.length - 1; i < j; i++, j--) {
+ var tmp = l[i];
+ l[i] = l[j];
+ l[j] = tmp;
+ }
+ return l;
+}
+
+_arrayShift(List l) {
+ if (l.isEmpty) return null; // Technically we should return undefined.
+ return l.removeAt(0);
+}
+
+int _arrayUnshift(List l, List args) {
+ l.insertAll(0, args);
+ return l.length;
+}
+
+_arrayExtend(List l, int newLength) {
+ for (var i = l.length; i < newLength; i++) {
+ // TODO(jacobr): we'd really like to add undefined to better match
+ // JavaScript semantics.
+ l.add(null);
+ }
+}
+
+List _arraySort(List l, rawCompare) {
+ // TODO(jacobr): alternately we could just copy the Array to JavaScript,
+ // invoke the JS sort method and then copy the result back to Dart.
+ Comparator compare;
+ if (rawCompare == null) {
+ compare = (a, b) => _toStringJs(a).compareTo(_toStringJs(b));
+ } else if (rawCompare is JsFunction) {
+ compare = (a, b) => rawCompare.apply([a, b]);
+ } else {
+ compare = rawCompare;
+ }
+ l.sort(compare);
+ return l;
+}
+// End of block of helper methods to emulate JavaScript Array methods on Dart List.
+
+/**
+ * Can be called to provide a predictable point where no more JS interfaces can
+ * be added. Creating an instance of JsObject will also automatically trigger
+ * all JsObjects to be finalized.
+ */
+void finalizeJsInterfaces() {
+ if (_finalized == true) {
+ throw 'JSInterop class registration already finalized';
+ }
+ _finalizeJsInterfaces();
+}
JsObject _cachedContext;
JsObject get _context native "Js_context_Callback";
+bool get _finalized native "Js_interfacesFinalized_Callback";
+
JsObject get context {
if (_cachedContext == null) {
_cachedContext = _context;
@@ -114,9 +491,24 @@
* Constructs a new JavaScript object from [constructor] and returns a proxy
* to it.
*/
- factory JsObject(JsFunction constructor, [List arguments]) => _create(constructor, arguments);
+ factory JsObject(JsFunction constructor, [List arguments]) =>
+ _create(constructor, arguments);
- static JsObject _create(JsFunction constructor, arguments) native "JsObject_constructorCallback";
+ static JsObject _create(
+ JsFunction constructor, arguments) native "JsObject_constructorCallback";
+
+ _buildArgs(Invocation invocation) {
+ if (invocation.namedArguments.isEmpty) {
+ return invocation.positionalArguments;
+ } else {
+ var varArgs = new Map<String, Object>();
+ invocation.namedArguments.forEach((symbol, val) {
+ varArgs[mirrors.MirrorSystem.getName(symbol)] = val;
+ });
+ return invocation.positionalArguments.toList()
+ ..add(new JsObject.jsify(varArgs));
+ }
+ }
/**
* Constructs a [JsObject] that proxies a native Dart object; _for expert use
@@ -131,8 +523,7 @@
*/
factory JsObject.fromBrowserObject(object) {
if (object is num || object is String || object is bool || object == null) {
- throw new ArgumentError(
- "object cannot be a num, string, bool, or null");
+ throw new ArgumentError("object cannot be a num, string, bool, or null");
}
return _fromBrowserObject(object);
}
@@ -155,7 +546,8 @@
static JsObject _jsify(object) native "JsObject_jsify";
- static JsObject _fromBrowserObject(object) native "JsObject_fromBrowserObject";
+ static JsObject _fromBrowserObject(
+ object) native "JsObject_fromBrowserObject";
/**
* Returns the value associated with [property] from the proxied JavaScript
@@ -163,7 +555,7 @@
*
* The type of [property] must be either [String] or [num].
*/
- operator[](property) native "JsObject_[]";
+ operator [](property) native "JsObject_[]";
/**
* Sets the value associated with [property] on the proxied JavaScript
@@ -171,13 +563,14 @@
*
* The type of [property] must be either [String] or [num].
*/
- operator[]=(property, value) native "JsObject_[]=";
+ operator []=(property, value) native "JsObject_[]=";
int get hashCode native "JsObject_hashCode";
- operator==(other) => other is JsObject && _identityEquality(this, other);
+ operator ==(other) => other is JsObject && _identityEquality(this, other);
- static bool _identityEquality(JsObject a, JsObject b) native "JsObject_identityEquality";
+ static bool _identityEquality(
+ JsObject a, JsObject b) native "JsObject_identityEquality";
/**
* Returns `true` if the JavaScript object contains the specified property
@@ -207,7 +600,7 @@
String toString() {
try {
return _toString();
- } catch(e) {
+ } catch (e) {
return super.toString();
}
}
@@ -223,7 +616,7 @@
callMethod(String method, [List args]) {
try {
return _callMethod(method, args);
- } catch(e) {
+ } catch (e) {
if (hasProperty(method)) {
rethrow;
} else {
@@ -232,13 +625,63 @@
}
}
+ noSuchMethod(Invocation invocation) {
+ throwError() {
+ throw new NoSuchMethodError(this, invocation.memberName,
+ invocation.positionalArguments, invocation.namedArguments);
+ }
+
+ String name = mirrors.MirrorSystem.getName(invocation.memberName);
+ if (invocation.isGetter) {
+ if (CHECK_JS_INVOCATIONS) {
+ var matches = _allowedGetters[invocation.memberName];
+ if (matches == null &&
+ !_allowedMethods.containsKey(invocation.memberName)) {
+ throwError();
+ }
+ var ret = this[name];
+ if (matches != null && matches._checkReturnType(ret)) return ret;
+ if (ret is Function ||
+ (ret is JsFunction /* shouldn't be needed in the future*/) &&
+ _allowedMethods.containsKey(
+ invocation.memberName)) return ret; // Warning: we have not bound "this"... we could type check on the Function but that is of little value in Dart.
+ throwError();
+ } else {
+ // TODO(jacobr): should we throw if the JavaScript object doesn't have the property?
+ return this[name];
+ }
+ } else if (invocation.isSetter) {
+ if (CHECK_JS_INVOCATIONS) {
+ var matches = _allowedSetters[invocation.memberName];
+ if (matches == null ||
+ !matches.checkInvocation(invocation)) throwError();
+ }
+ assert(name.endsWith("="));
+ name = name.substring(0, name.length - 1);
+ return this[name] = invocation.positionalArguments.first;
+ } else {
+ // TODO(jacobr): also allow calling getters that look like functions.
+ var matches;
+ if (CHECK_JS_INVOCATIONS) {
+ matches = _allowedMethods[invocation.memberName];
+ if (matches == null ||
+ !matches.checkInvocation(invocation)) throwError();
+ }
+ var ret = this.callMethod(name, _buildArgs(invocation));
+ if (CHECK_JS_INVOCATIONS) {
+ if (!matches._checkReturnType(ret)) throwError();
+ }
+ return ret;
+ }
+ }
+
_callMethod(String name, List args) native "JsObject_callMethod";
}
/**
* Proxies a JavaScript Function object.
*/
-class JsFunction extends JsObject {
+class JsFunction extends JsObject implements Function {
JsFunction.internal() : super.internal();
/**
@@ -253,13 +696,21 @@
*/
dynamic apply(List args, {thisArg}) native "JsFunction_apply";
+ noSuchMethod(Invocation invocation) {
+ if (invocation.isMethod && invocation.memberName == #call) {
+ return apply(_buildArgs(invocation));
+ }
+ return super.noSuchMethod(invocation);
+ }
+
/**
* Internal only version of apply which uses debugger proxies of Dart objects
* rather than opaque handles. This method is private because it cannot be
* efficiently implemented in Dart2Js so should only be used by internal
* tools.
*/
- _applyDebuggerOnly(List args, {thisArg}) native "JsFunction_applyDebuggerOnly";
+ _applyDebuggerOnly(List args,
+ {thisArg}) native "JsFunction_applyDebuggerOnly";
static JsFunction _withThis(Function f) native "JsFunction_withThis";
}
@@ -268,14 +719,17 @@
* A [List] proxying a JavaScript Array.
*/
class JsArray<E> extends JsObject with ListMixin<E> {
+ JsArray.internal() : super.internal();
factory JsArray() => _newJsArray();
static JsArray _newJsArray() native "JsArray_newJsArray";
- factory JsArray.from(Iterable<E> other) => _newJsArrayFromSafeList(new List.from(other));
+ factory JsArray.from(Iterable<E> other) =>
+ _newJsArrayFromSafeList(new List.from(other));
- static JsArray _newJsArrayFromSafeList(List list) native "JsArray_newJsArrayFromSafeList";
+ static JsArray _newJsArrayFromSafeList(
+ List list) native "JsArray_newJsArrayFromSafeList";
_checkIndex(int index, {bool insert: false}) {
int length = insert ? this.length + 1 : this.length;
@@ -304,7 +758,7 @@
}
void operator []=(index, E value) {
- if(index is int) {
+ if (index is int) {
_checkIndex(index);
}
super[index] = value;
@@ -312,7 +766,9 @@
int get length native "JsArray_length";
- void set length(int length) { super['length'] = length; }
+ void set length(int length) {
+ super['length'] = length;
+ }
// Methods overriden for better performance
@@ -326,7 +782,7 @@
}
void insert(int index, E element) {
- _checkIndex(index, insert:true);
+ _checkIndex(index, insert: true);
callMethod('splice', [index, 0, element]);
}
@@ -365,7 +821,7 @@
*/
const _UNDEFINED = const Object();
-// FIXME(jacobr): this method is a hack to work around the lack of proper dart
+// TODO(jacobr): this method is a hack to work around the lack of proper dart
// support for varargs methods.
List _stripUndefinedArgs(List args) =>
args.takeWhile((i) => i != _UNDEFINED).toList();
@@ -375,8 +831,7 @@
* than 11) of arguments without violating Dart type checks.
*/
Function _wrapAsDebuggerVarArgsFunction(JsFunction jsFunction) =>
- ([a1=_UNDEFINED, a2=_UNDEFINED, a3=_UNDEFINED, a4=_UNDEFINED,
- a5=_UNDEFINED, a6=_UNDEFINED, a7=_UNDEFINED, a8=_UNDEFINED,
- a9=_UNDEFINED, a10=_UNDEFINED]) =>
- jsFunction._applyDebuggerOnly(_stripUndefinedArgs(
- [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10]));
+ ([a1 = _UNDEFINED, a2 = _UNDEFINED, a3 = _UNDEFINED, a4 = _UNDEFINED,
+ a5 = _UNDEFINED, a6 = _UNDEFINED, a7 = _UNDEFINED, a8 = _UNDEFINED,
+ a9 = _UNDEFINED, a10 = _UNDEFINED]) => jsFunction._applyDebuggerOnly(
+ _stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));
diff --git a/tests/benchmark_smoke/benchmark_smoke.status b/tests/benchmark_smoke/benchmark_smoke.status
index 7eef00b..fea516e0 100644
--- a/tests/benchmark_smoke/benchmark_smoke.status
+++ b/tests/benchmark_smoke/benchmark_smoke.status
@@ -9,4 +9,3 @@
*: Fail, Pass # TODO(ahe): Triage these tests.
[ $compiler == dart2js && $cps_ir ]
-benchmark_smoke_test: Crash # Invalid argument(s)
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 4a74533..de69117 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -9602,13 +9602,9 @@
WebPlatformTest/webstorage/storage_session_setitem_t01: RuntimeError # Please triage this failure
[ $compiler == dart2js && $cps_ir ]
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A02_t01: RuntimeError # Please triage this failure.
Language/12_Expressions/05_Strings/1_String_Interpolation_A01_t12: RuntimeError # Cannot read property 'prototype' of undefined
Language/12_Expressions/05_Strings/1_String_Interpolation_A02_t02: RuntimeError # Cannot read property 'prototype' of undefined
Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: RuntimeError # Please triage this failure.
-Language/12_Expressions/12_Instance_Creation/1_New_A08_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/12_Instance_Creation/1_New_A08_t02: RuntimeError # Please triage this failure.
-Language/12_Expressions/12_Instance_Creation/1_New_A08_t03: RuntimeError # Please triage this failure.
Language/12_Expressions/13_Property_Extraction_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
Language/12_Expressions/13_Property_Extraction_A01_t02: RuntimeError # Cannot read property 'prototype' of undefined
Language/12_Expressions/13_Property_Extraction_A01_t03: RuntimeError # Cannot read property 'prototype' of undefined
@@ -9616,43 +9612,19 @@
Language/12_Expressions/13_Property_Extraction_A03_t02: RuntimeError # Cannot read property 'call' of undefined
Language/12_Expressions/13_Property_Extraction_A03_t03: RuntimeError # Cannot read property 'call' of undefined
Language/12_Expressions/13_Spawning_an_Isolate_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: RuntimeError # Please triage this failure.
Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t04: RuntimeError # Cannot read property 'prototype' of undefined
Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: RuntimeError # Cannot read property 'prototype' of undefined
Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A01_t01: RuntimeError # Cannot read property 'call' of undefined
Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A03_t04: RuntimeError # Cannot read property 'prototype' of undefined
-Language/12_Expressions/18_Assignment_A05_t02: RuntimeError # Please triage this failure.
-Language/12_Expressions/18_Assignment_A05_t05: RuntimeError # Please triage this failure.
-Language/12_Expressions/26_Multiplicative_Expressions_A02_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/26_Multiplicative_Expressions_A03_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/28_Postfix_Expressions_A05_t02: RuntimeError # Please triage this failure.
-Language/12_Expressions/28_Postfix_Expressions_A09_t02: RuntimeError # Please triage this failure.
Language/12_Expressions/29_Assignable_Expressions_A01_t08: RuntimeError # receiver.get$_first is not a function
Language/12_Expressions/30_Identifier_Reference_A09_t03: Crash # (i=0): For-loop variable captured in loop header
-Language/12_Expressions/30_Identifier_Reference_A09_t04: RuntimeError # Please triage this failure.
Language/12_Expressions/30_Identifier_Reference_A10_t01: RuntimeError # Cannot read property 'prototype' of undefined
Language/12_Expressions/30_Identifier_Reference_A10_t02: RuntimeError # Cannot read property 'prototype' of undefined
Language/13_Statements/02_Expression_Statements_A01_t06: RuntimeError # Cannot read property 'prototype' of undefined
-Language/13_Statements/06_For/1_For_Loop_A01_t09: RuntimeError # Please triage this failure.
Language/13_Statements/06_For_A01_t07: Crash # unsupported operation on erroneous element
Language/13_Statements/12_Labels_A03_t04: Crash # (switch (i){L:case 0:flag=true;break;case 2:continue L;}): continue to a labeled switch case
-Language/13_Statements/13_Break_A03_t01: RuntimeError # Issue 23708.
-Language/13_Statements/13_Break_A03_t03: RuntimeError # Issue 23708.
-Language/13_Statements/13_Break_A03_t04: RuntimeError # Please triage this failure.
-Language/13_Statements/13_Break_A03_t06: RuntimeError # Issue 23708.
-Language/13_Statements/13_Break_A03_t07: RuntimeError # Please triage this failure.
-Language/13_Statements/13_Break_A03_t08: RuntimeError # Please triage this failure.
-Language/13_Statements/13_Break_A03_t09: RuntimeError # Issue 23708.
Language/13_Statements/14_Continue_A02_t12: Crash # (switch (2){L:case 1:flag=true;break;case 2:continue L;}): continue to a labeled switch case
Language/13_Statements/14_Continue_A02_t13: Crash # (switch (2){case 2:continue L;L:case 1:flag=true;}): continue to a labeled switch case
-Language/13_Statements/14_Continue_A03_t01: RuntimeError # Issue 23708.
-Language/13_Statements/14_Continue_A03_t02: RuntimeError # Please triage this failure.
-Language/13_Statements/14_Continue_A03_t03: RuntimeError # Please triage this failure.
-Language/13_Statements/14_Continue_A03_t04: RuntimeError # Issue 23708.
-Language/13_Statements/14_Continue_A03_t05: RuntimeError # Please triage this failure.
-Language/13_Statements/14_Continue_A03_t06: RuntimeError # Issue 23708.
-Language/13_Statements/14_Continue_A03_t07: RuntimeError # Issue 23708.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t06: RuntimeError # Please triage this failure.
Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: RuntimeError # receiver.get$_collection$_nums is not a function
Language/15_Types/3_Type_Declarations/1_Typedef_A02_t01: RuntimeError # Cannot read property 'prototype' of undefined
Language/15_Types/3_Type_Declarations/1_Typedef_A02_t02: RuntimeError # Cannot read property 'prototype' of undefined
@@ -9689,12 +9661,6 @@
Language/15_Types/5_Function_Types_A05_t02: RuntimeError # Cannot read property 'prototype' of undefined
Language/15_Types/5_Function_Types_A05_t05: RuntimeError # Cannot read property 'prototype' of undefined
Language/15_Types/5_Function_Types_A06_t01: RuntimeError # Cannot read property 'prototype' of undefined
-Language/16_Reference/1_Lexical_Rules/2_Comments_A02_t10: RuntimeError # Please triage this failure.
-LayoutTests/fast/canvas/webgl/compressed-tex-image_t01: Crash # Invalid argument(s)
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: Crash # Invalid argument(s)
-LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Crash # Internal Error: No default constructor available.
-LayoutTests/fast/forms/date/date-interactive-validation-required_t01: Crash # Invalid argument(s)
-LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Crash # Invalid argument(s)
LibTest/async/Completer/Completer.sync_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Completer/completeError_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Completer/completeError_A01_t02: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -9777,7 +9743,7 @@
LibTest/async/Stream/Stream.fromIterable_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Stream/Stream.fromIterable_A01_t02: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Stream/Stream.fromIterable_A02_t01: RuntimeError # receiver.get$_collection$_nums is not a function
-LibTest/async/Stream/Stream.periodic_A01_t01: Crash # Invalid argument(s)
+LibTest/async/Stream/Stream.periodic_A01_t01 : RuntimeError # TypeError: receiver.get$_nums is not a function
LibTest/async/Stream/Stream.periodic_A02_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Stream/Stream.periodic_A03_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Stream/Stream_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -9800,7 +9766,7 @@
LibTest/async/Stream/distinct_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Stream/distinct_A01_t02: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Stream/drain_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
-LibTest/async/Stream/drain_A02_t01: Crash # Invalid argument(s)
+LibTest/async/Stream/drain_A02_t01 : RuntimeError # TypeError: receiver.get$_nums is not a function
LibTest/async/Stream/drain_A02_t02: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Stream/elementAt_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Stream/elementAt_A01_t02: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -9977,94 +9943,29 @@
LibTest/async/Zone/run_A01_t01: RuntimeError # receiver.get$_nums is not a function
LibTest/async/Zone/scheduleMicrotask_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/async/Zone/scheduleMicrotask_A01_t02: RuntimeError # receiver.get$_nums is not a function
-LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/every_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/expand_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/forEachEntry_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/forEach_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/iterator_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/join_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/map_A03_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/remove_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/skipWhile_A03_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/toList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/HashMap/allTests_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/HashSet/HashSet.from_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/HashSet/HashSet_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/IterableBase/IterableBase_class_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedHashMap/LinkedHashMap_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/addAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/expand_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/expand_A02_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/forEach_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/map_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/map_A02_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/map_A03_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/single_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/skipWhile_A03_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/toList_A01_t02: RuntimeError # Please triage this failure.
LibTest/collection/ListBase/ListBase_class_A01_t02: Crash # Stack Overflow
LibTest/collection/ListMixin/ListMixin_class_A01_t02: Crash # Stack Overflow
-LibTest/collection/ListQueue/ListQueue.from_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/ListQueue/ListQueue.from_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/ListQueue/ListQueue_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/Maps/forEach_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/Maps/mapToString_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/Queue/Queue.from_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/Queue/Queue.from_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/Queue/Queue_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/SplayTreeMap/allTests_A01_t01: RuntimeError # Please triage this failure.
-LibTest/convert/JsonCodec/JsonCodec.withReviver_A01_t01: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonCodec/JsonCodec_A01_t01: Crash # Internal Error: No default constructor available.
LibTest/convert/JsonCodec/encode_A01_t01: Crash # Internal Error: No default constructor available.
LibTest/convert/JsonCodec/encode_A01_t02: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonCodec/encode_A02_t01: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonCodec/encode_A02_t02: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonCodec/encode_A02_t03: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonCodec/encode_A03_t01: Crash # Internal Error: No default constructor available.
LibTest/convert/JsonDecoder/fuse_A01_t01: Crash # Internal Error: No default constructor available.
LibTest/convert/JsonEncoder/convert_A01_t01: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonEncoder/convert_A02_t01: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonEncoder/fuse_A01_t01: Crash # Internal Error: No default constructor available.
LibTest/core/DateTime/parse_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
LibTest/core/DateTime/parse_A01_t02: RuntimeError # Cannot read property 'prototype' of undefined
LibTest/core/DateTime/parse_A03_t01: Pass # Please triage this failure.
LibTest/core/DateTime/timeZoneName_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
-LibTest/core/Function/apply_A01_t01: RuntimeError # Please triage this failure.
LibTest/core/Invocation/isAccessor_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
-LibTest/core/Invocation/isGetter_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Invocation/isGetter_A01_t02: RuntimeError # Please triage this failure.
+LibTest/core/Invocation/isGetter_A01_t01 : RuntimeError #
+LibTest/core/Invocation/isGetter_A01_t02 : RuntimeError #
LibTest/core/Invocation/isMethod_A01_t02: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
LibTest/core/Invocation/isSetter_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
-LibTest/core/Invocation/isSetter_A01_t02: RuntimeError # Please triage this failure.
+LibTest/core/Invocation/isSetter_A01_t02 : RuntimeError #
LibTest/core/Invocation/memberName_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
-LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List.from_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List.from_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/List/List.generate_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List.generate_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/List/List.generate_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/List/List_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/List/List_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List_A03_t01: RuntimeError # Please triage this failure.
+LibTest/core/Invocation/positionalArguments_A01_t01 : RuntimeError #
LibTest/core/List/List_class_A01_t02: Crash # Stack Overflow
-LibTest/core/Map/allTests_A01_t01: RuntimeError # Please triage this failure.
LibTest/core/Match/end_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
LibTest/core/Match/groupCount_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
-LibTest/core/Match/groups_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Match/groups_A02_t01: RuntimeError # Please triage this failure.
LibTest/core/NoSuchMethodError/toString_A01_t01: RuntimeError # receiver.get$_first is not a function
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A03_t02: RuntimeError # Please triage this failure.
LibTest/core/RegExp/stringMatch_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
-LibTest/core/Runes/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/core/Set/IterableBase_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Set/Set.from_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Set/forEach_A01_t01: RuntimeError # Please triage this failure.
LibTest/core/Stopwatch/Stopwatch_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
LibTest/core/Stopwatch/elapsedInMs_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/core/Stopwatch/elapsedInUs_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -10081,44 +9982,6 @@
LibTest/core/Stopwatch/stop_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Please triage this failure.
LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Please triage this failure.
-LibTest/core/Uri/Uri.http_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/Uri.https_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/Uri_A03_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/authority_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/decodeComponent_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/decodeFull_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/decodeQueryComponent_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/decodeQueryComponent_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/hasAuthority_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/host_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/isAbsolute_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/operator_eq_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/origin_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/parse_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/parse_A02_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/parse_A03_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/pathSegments_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/pathSegments_A01_t02: Crash # Invalid argument(s)
-LibTest/core/Uri/pathSegments_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/Uri/pathSegments_A02_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/path_A02_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/port_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/queryParameters_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/queryParameters_A01_t02: Crash # Invalid argument(s)
-LibTest/core/Uri/queryParameters_A01_t03: Crash # Invalid argument(s)
-LibTest/core/Uri/query_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/query_A01_t02: Crash # Invalid argument(s)
-LibTest/core/Uri/resolveUri_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/resolve_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/scheme_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/splitQueryString_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/toFilePath_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/toFilePath_A01_t02: Crash # Invalid argument(s)
-LibTest/core/Uri/toFilePath_A01_t03: Crash # Invalid argument(s)
-LibTest/core/Uri/toFilePath_A02_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/toFilePath_A03_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/toFilePath_A04_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/userInfo_A01_t01: Crash # Invalid argument(s)
LibTest/core/double/INFINITY_A01_t04: Pass # Please triage this failure.
LibTest/core/double/NEGATIVE_INFINITY_A01_t04: Pass # Please triage this failure.
LibTest/core/int/parse_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
@@ -10156,7 +10019,7 @@
LibTest/isolate/ReceivePort/contains_A01_t01: RuntimeError # receiver.get$_nums is not a function
LibTest/isolate/ReceivePort/distinct_A01_t01: RuntimeError # receiver.get$_nums is not a function
LibTest/isolate/ReceivePort/distinct_A01_t02: RuntimeError # receiver.get$_nums is not a function
-LibTest/isolate/ReceivePort/drain_A02_t01: Crash # Invalid argument(s)
+LibTest/isolate/ReceivePort/drain_A02_t01 : RuntimeError # TypeError: receiver.get$_nums is not a function
LibTest/isolate/ReceivePort/drain_A02_t02: RuntimeError # receiver.get$_nums is not a function
LibTest/isolate/ReceivePort/elementAt_A01_t01: RuntimeError # receiver.get$_nums is not a function
LibTest/isolate/ReceivePort/elementAt_A03_t01: RuntimeError # receiver.get$_nums is not a function
@@ -10208,130 +10071,31 @@
LibTest/isolate/SendPort/operator_equality_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/isolate/SendPort/send_A01_t04: RuntimeError # receiver.get$_collection$_nums is not a function
LibTest/isolate/SendPort/send_A02_t01: RuntimeError # receiver.get$_collection$_nums is not a function
-LibTest/math/atan2_A01_t01: RuntimeError # Please triage this failure.
-LibTest/math/exp_A01_t01: RuntimeError # Please triage this failure.
-LibTest/math/log_A01_t01: RuntimeError # Please triage this failure.
-LibTest/math/pow_A01_t01: RuntimeError # Please triage this failure.
-LibTest/math/sin_A01_t01: RuntimeError # Please triage this failure.
-LibTest/math/sqrt_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/reversed_A01_t02: RuntimeError # Please triage this failure.
LibTest/typed_data/Float32List/setAll_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Float32List/setRange_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Float32List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Float32List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/reversed_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/reversed_A01_t02: RuntimeError # Please triage this failure.
LibTest/typed_data/Float64List/setAll_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Float64List/setRange_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Float64List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Float64List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/reversed_A01_t02: RuntimeError # Please triage this failure.
LibTest/typed_data/Int16List/setAll_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Int16List/setRange_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Int16List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Int16List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/Int32List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/reversed_A01_t02: RuntimeError # Please triage this failure.
LibTest/typed_data/Int32List/setAll_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Int32List/setRange_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Int32List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Int32List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/Int8List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/reversed_A01_t02: RuntimeError # Please triage this failure.
LibTest/typed_data/Int8List/setAll_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Int8List/setRange_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Int8List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Int8List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/reversed_A01_t02: RuntimeError # Please triage this failure.
LibTest/typed_data/Uint16List/setAll_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Uint16List/setRange_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Uint16List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Uint16List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/reversed_A01_t02: RuntimeError # Please triage this failure.
LibTest/typed_data/Uint32List/setAll_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Uint32List/setRange_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Uint32List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Uint32List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/reversed_A01_t02: RuntimeError # Please triage this failure.
LibTest/typed_data/Uint8ClampedList/setAll_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Uint8ClampedList/setRange_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Uint8ClampedList/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Uint8ClampedList/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/reversed_A01_t02: RuntimeError # Please triage this failure.
LibTest/typed_data/Uint8List/setAll_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Uint8List/setRange_A01_t01: RuntimeError # this.get$length is not a function
LibTest/typed_data/Uint8List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Uint8List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/toList_A02_t02: RuntimeError # Please triage this failure.
-Utils/tests/Expect/setEquals_A01_t01: RuntimeError # Please triage this failure.
-Utils/tests/Expect/setEquals_A01_t02: RuntimeError # Please triage this failure.
+LibTest/core/Invocation/namedArguments_A01_t01 : RuntimeError #
diff --git a/tests/compiler/dart2js/analyze_api_test.dart b/tests/compiler/dart2js/analyze_api_test.dart
index de48a2e..faeebaa 100644
--- a/tests/compiler/dart2js/analyze_api_test.dart
+++ b/tests/compiler/dart2js/analyze_api_test.dart
@@ -4,7 +4,7 @@
library analyze_api;
-import '../../../sdk/lib/_internal/libraries.dart';
+import 'package:sdk_library_metadata/libraries.dart';
import 'analyze_helper.dart';
import "package:async_helper/async_helper.dart";
diff --git a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
index e5c9deb..07f049c 100644
--- a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
+++ b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
@@ -26,7 +26,7 @@
// Uncalled methods in SemanticSendVisitor and subclasses.
"lib/src/resolution/semantic_visitor.dart": const [
- "The method 'error", "The method 'visit"],
+ "The method 'error"],
"lib/src/resolution/semantic_visitor_mixins.dart": const [
"The class 'Base", "The method 'error", "The method 'visit"],
diff --git a/tests/compiler/dart2js/async_await_syntax_test.dart b/tests/compiler/dart2js/async_await_syntax_test.dart
index 336a7cd..fd21a0d 100644
--- a/tests/compiler/dart2js/async_await_syntax_test.dart
+++ b/tests/compiler/dart2js/async_await_syntax_test.dart
@@ -1,22 +1,22 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that dart2js produces the expected static type warnings and
-// compile-time errors for these tests.
-
-import 'frontend_checker.dart';
-
-/// Map of test files to run together with their associated whitelist.
-///
-/// For instance
-/// 'language/async_await_syntax_test.dart': const ['a03b', 'a04b']
-/// includes the multitest in 'language/async_await_syntax_test.dart' but
-/// expects the subtests 'a03b' and 'a04c' to fail.
-const Map<String, List<String>> TESTS = const <String, List<String>>{
- 'language/async_await_syntax_test.dart': const [],
-};
-
-void main(List<String> arguments) {
- check(TESTS, arguments: arguments, options: ['--enable-async']);
-}
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that dart2js produces the expected static type warnings and
+// compile-time errors for these tests.
+
+import 'frontend_checker.dart';
+
+/// Map of test files to run together with their associated whitelist.
+///
+/// For instance
+/// 'language/async_await_syntax_test.dart': const ['a03b', 'a04b']
+/// includes the multitest in 'language/async_await_syntax_test.dart' but
+/// expects the subtests 'a03b' and 'a04c' to fail.
+const Map<String, List<String>> TESTS = const <String, List<String>>{
+ 'language/async_await_syntax_test.dart': const ['a05h', 'c11a', 'c11b'],
+};
+
+void main(List<String> arguments) {
+ check(TESTS, arguments: arguments, options: ['--enable-async']);
+}
diff --git a/tests/compiler/dart2js/backend_dart/end2end_test.dart b/tests/compiler/dart2js/backend_dart/end2end_test.dart
index a2a2520..3a7f902 100644
--- a/tests/compiler/dart2js/backend_dart/end2end_test.dart
+++ b/tests/compiler/dart2js/backend_dart/end2end_test.dart
@@ -1,37 +1,37 @@
-// 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.
-
-/// End-to-end test of the dart2dart compiler.
-library dart_backend.end2end_test;
-
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/dart2jslib.dart';
-import 'package:compiler/src/dart_backend/dart_backend.dart';
-import 'package:expect/expect.dart';
-
-import '../../../../pkg/analyzer2dart/test/test_helper.dart' hide TestSpec;
-import '../../../../pkg/analyzer2dart/test/end2end_data.dart';
-
-import 'test_helper.dart';
-import '../output_collector.dart';
-
-main(List<String> args) {
- performTests(TEST_DATA, asyncTester, runTest, args);
-}
-
-runTest(TestSpec result) {
- OutputCollector outputCollector = new OutputCollector();
- asyncTest(() => compilerFor(result.input, outputProvider: outputCollector)
- .then((Compiler compiler) {
- String expectedOutput = result.output.trim();
- compiler.phase = Compiler.PHASE_COMPILING;
- DartBackend backend = compiler.backend;
- backend.assembleProgram();
- String output = outputCollector.getOutput('', 'dart').trim();
- Expect.equals(expectedOutput, output,
- '\nInput:\n${result.input}\n'
- 'Expected:\n$expectedOutput\n'
- 'Actual:\n$output\n');
- }));
+// 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.
+
+/// End-to-end test of the dart2dart compiler.
+library dart_backend.end2end_test;
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/dart2jslib.dart';
+import 'package:compiler/src/dart_backend/dart_backend.dart';
+import 'package:expect/expect.dart';
+
+import '../../../../pkg/analyzer2dart/test/test_helper.dart' hide TestSpec;
+import '../../../../pkg/analyzer2dart/test/end2end_data.dart';
+
+import 'test_helper.dart';
+import '../output_collector.dart';
+
+main(List<String> args) {
+ performTests(TEST_DATA, asyncTester, runTest, args);
+}
+
+runTest(TestSpec result) {
+ OutputCollector outputCollector = new OutputCollector();
+ asyncTest(() => compilerFor(result.input, outputProvider: outputCollector)
+ .then((Compiler compiler) {
+ String expectedOutput = result.output.trim();
+ compiler.phase = Compiler.PHASE_COMPILING;
+ DartBackend backend = compiler.backend;
+ backend.assembleProgram();
+ String output = outputCollector.getOutput('', 'dart').trim();
+ Expect.equals(expectedOutput, output,
+ '\nInput:\n${result.input}\n'
+ 'Expected:\n$expectedOutput\n'
+ 'Actual:\n$output\n');
+ }));
}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/backend_dart/sexpr2_test.dart b/tests/compiler/dart2js/backend_dart/sexpr2_test.dart
index 35c3185..71d294b 100644
--- a/tests/compiler/dart2js/backend_dart/sexpr2_test.dart
+++ b/tests/compiler/dart2js/backend_dart/sexpr2_test.dart
@@ -1,62 +1,62 @@
-// 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.
-
-/// Unittest test of the CPS ir generated by the dart2dart compiler.
-library dart_backend.sexpr2_test;
-
-import 'package:compiler/src/dart2jslib.dart';
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart';
-import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:expect/expect.dart';
-
-import '../../../../pkg/analyzer2dart/test/test_helper.dart';
-import '../../../../pkg/analyzer2dart/test/sexpr_data.dart';
-
-import 'test_helper.dart';
-
-main(List<String> args) {
- performTests(TEST_DATA, asyncTester, runTest, args);
-}
-
-runTest(TestSpec result) {
- return compilerFor(result.input).then((Compiler compiler) {
- void checkOutput(String elementName,
- Element element,
- String expectedOutput) {
- FunctionDefinition ir = compiler.irBuilder.getIr(element);
- if (expectedOutput == null) {
- Expect.isNull(ir, "\nInput:\n${result.input}\n"
- "No CPS IR expected for $element");
- } else {
- Expect.isNotNull(ir, "\nInput:\n${result.input}\n"
- "No CPS IR for $element");
- expectedOutput = expectedOutput.trim();
- String output = ir.accept(new SExpressionStringifier()).trim();
- Expect.equals(expectedOutput, output,
- "\nInput:\n${result.input}\n"
- "Expected for '$elementName':\n$expectedOutput\n"
- "Actual for '$elementName':\n$output\n");
- }
- }
-
- if (result.output is String) {
- checkOutput('main', compiler.mainFunction, result.output);
- } else {
- assert(result.output is Map<String, String>);
- result.output.forEach((String elementName, String output) {
- Element element;
- if (elementName.contains('.')) {
- ClassElement cls = compiler.mainApp.localLookup(
- elementName.substring(0, elementName.indexOf('.')));
- element = cls.localLookup(
- elementName.substring(elementName.indexOf('.') + 1));
- } else {
- element = compiler.mainApp.localLookup(elementName);
- }
- checkOutput(elementName, element, output);
- });
- }
- });
+// 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.
+
+/// Unittest test of the CPS ir generated by the dart2dart compiler.
+library dart_backend.sexpr2_test;
+
+import 'package:compiler/src/dart2jslib.dart';
+import 'package:compiler/src/cps_ir/cps_ir_nodes.dart';
+import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:expect/expect.dart';
+
+import '../../../../pkg/analyzer2dart/test/test_helper.dart';
+import '../../../../pkg/analyzer2dart/test/sexpr_data.dart';
+
+import 'test_helper.dart';
+
+main(List<String> args) {
+ performTests(TEST_DATA, asyncTester, runTest, args);
+}
+
+runTest(TestSpec result) {
+ return compilerFor(result.input).then((Compiler compiler) {
+ void checkOutput(String elementName,
+ Element element,
+ String expectedOutput) {
+ FunctionDefinition ir = compiler.irBuilder.getIr(element);
+ if (expectedOutput == null) {
+ Expect.isNull(ir, "\nInput:\n${result.input}\n"
+ "No CPS IR expected for $element");
+ } else {
+ Expect.isNotNull(ir, "\nInput:\n${result.input}\n"
+ "No CPS IR for $element");
+ expectedOutput = expectedOutput.trim();
+ String output = ir.accept(new SExpressionStringifier()).trim();
+ Expect.equals(expectedOutput, output,
+ "\nInput:\n${result.input}\n"
+ "Expected for '$elementName':\n$expectedOutput\n"
+ "Actual for '$elementName':\n$output\n");
+ }
+ }
+
+ if (result.output is String) {
+ checkOutput('main', compiler.mainFunction, result.output);
+ } else {
+ assert(result.output is Map<String, String>);
+ result.output.forEach((String elementName, String output) {
+ Element element;
+ if (elementName.contains('.')) {
+ ClassElement cls = compiler.mainApp.localLookup(
+ elementName.substring(0, elementName.indexOf('.')));
+ element = cls.localLookup(
+ elementName.substring(elementName.indexOf('.') + 1));
+ } else {
+ element = compiler.mainApp.localLookup(elementName);
+ }
+ checkOutput(elementName, element, output);
+ });
+ }
+ });
}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/backend_dart/test_helper.dart b/tests/compiler/dart2js/backend_dart/test_helper.dart
index 3e43cd9..a355d7e 100644
--- a/tests/compiler/dart2js/backend_dart/test_helper.dart
+++ b/tests/compiler/dart2js/backend_dart/test_helper.dart
@@ -1,46 +1,46 @@
-// 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 dart_backend.test_helper;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/compiler.dart' as api;
-import 'package:compiler/src/dart2jslib.dart';
-import '../../../../pkg/analyzer2dart/test/test_helper.dart';
-import '../compiler_helper.dart';
-
-/// Compiles the given dart code (which must include a 'main' function) and
-/// returns the compiler.
-Future<Compiler> compilerFor(String code,
- {api.CompilerOutputProvider outputProvider}) {
- MockCompiler compiler = new MockCompiler.internal(
- emitJavaScript: false,
- enableMinification: false,
- outputProvider: outputProvider);
- compiler.diagnosticHandler = createHandler(compiler, code);
- return compiler.init().then((_) {
- compiler.parseScript(code);
-
- Element element = compiler.mainApp.find('main');
- if (element == null) return null;
-
- compiler.mainFunction = element;
- compiler.phase = Compiler.PHASE_RESOLVING;
- compiler.backend.enqueueHelpers(compiler.enqueuer.resolution,
- compiler.globalDependencies);
- compiler.processQueue(compiler.enqueuer.resolution, element);
- compiler.world.populate();
- compiler.backend.onResolutionComplete();
-
- compiler.irBuilder.buildNodes();
-
- return compiler;
- });
-}
-
-/// Test group using async_helper.
-asyncTester(Group group, RunTest runTest) {
- asyncTest(() => Future.forEach(group.results, runTest));
-}
+// 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 dart_backend.test_helper;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/compiler.dart' as api;
+import 'package:compiler/src/dart2jslib.dart';
+import '../../../../pkg/analyzer2dart/test/test_helper.dart';
+import '../compiler_helper.dart';
+
+/// Compiles the given dart code (which must include a 'main' function) and
+/// returns the compiler.
+Future<Compiler> compilerFor(String code,
+ {api.CompilerOutputProvider outputProvider}) {
+ MockCompiler compiler = new MockCompiler.internal(
+ emitJavaScript: false,
+ enableMinification: false,
+ outputProvider: outputProvider);
+ compiler.diagnosticHandler = createHandler(compiler, code);
+ return compiler.init().then((_) {
+ compiler.parseScript(code);
+
+ Element element = compiler.mainApp.find('main');
+ if (element == null) return null;
+
+ compiler.mainFunction = element;
+ compiler.phase = Compiler.PHASE_RESOLVING;
+ compiler.backend.enqueueHelpers(compiler.enqueuer.resolution,
+ compiler.globalDependencies);
+ compiler.processQueue(compiler.enqueuer.resolution, element);
+ compiler.world.populate();
+ compiler.backend.onResolutionComplete();
+
+ compiler.irBuilder.buildNodes();
+
+ return compiler;
+ });
+}
+
+/// Test group using async_helper.
+asyncTester(Group group, RunTest runTest) {
+ asyncTest(() => Future.forEach(group.results, runTest));
+}
diff --git a/tests/compiler/dart2js/check_members_test.dart b/tests/compiler/dart2js/check_members_test.dart
index 023e849..fff8a93 100644
--- a/tests/compiler/dart2js/check_members_test.dart
+++ b/tests/compiler/dart2js/check_members_test.dart
@@ -1,53 +1,53 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that dart2js produces the expected static type warnings for least upper
-// bound language tests. This ensures that the analyzer and dart2js agrees
-// on these tests.
-
-import 'warnings_checker.dart';
-
-/// Map from test files to a map of their expected status. If the status map is
-/// `null` no warnings must be missing or unexpected, otherwise the status map
-/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
-/// the warnings of each category.
-const Map<String, dynamic> TESTS = const {
- // Instance methods.
- 'co19/src/Language/07_Classes/1_Instance_Methods_A01_t01.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A01_t02.dart': null,
-
- 'language/check_method_override_test.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A06_t01.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A06_t02.dart': null,
-
- 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t01.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t02.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t03.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t04.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t05.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t06.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t01.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t02.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t03.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t04.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t05.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t06.dart': null,
-
- 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t01.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t02.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t04.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t05.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t06.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t07.dart': null,
- 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t08.dart': null,
- // Getters.
- 'co19/src/Language/07_Classes/2_Getters_A05_t01.dart': null,
- 'co19/src/Language/07_Classes/2_Getters_A05_t02.dart': null,
- 'co19/src/Language/07_Classes/2_Getters_A05_t03.dart': null,
- 'co19/src/Language/07_Classes/2_Getters_A05_t04.dart': null,
-};
-
-void main() {
- checkWarnings(TESTS);
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that dart2js produces the expected static type warnings for least upper
+// bound language tests. This ensures that the analyzer and dart2js agrees
+// on these tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+ // Instance methods.
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A01_t01.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A01_t02.dart': null,
+
+ 'language/check_method_override_test.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A06_t01.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A06_t02.dart': null,
+
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t01.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t02.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t03.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t04.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t05.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A02_t06.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t01.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t02.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t03.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t04.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t05.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A03_t06.dart': null,
+
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t01.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t02.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t04.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t05.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t06.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t07.dart': null,
+ 'co19/src/Language/07_Classes/1_Instance_Methods_A05_t08.dart': null,
+ // Getters.
+ 'co19/src/Language/07_Classes/2_Getters_A05_t01.dart': null,
+ 'co19/src/Language/07_Classes/2_Getters_A05_t02.dart': null,
+ 'co19/src/Language/07_Classes/2_Getters_A05_t03.dart': null,
+ 'co19/src/Language/07_Classes/2_Getters_A05_t04.dart': null,
+};
+
+void main() {
+ checkWarnings(TESTS);
+}
diff --git a/tests/compiler/dart2js/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/constant_expression_evaluate_test.dart
index 2e82412..94a0213e 100644
--- a/tests/compiler/dart2js/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/constant_expression_evaluate_test.dart
@@ -1,237 +1,237 @@
-// 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.constants.expressions.evaluate_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/constants/expressions.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/constant_system_dart.dart';
-import 'package:compiler/src/core_types.dart';
-import 'package:compiler/src/dart2jslib.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'memory_compiler.dart';
-
-class TestData {
- /// Declarations needed for the [constants].
- final String declarations;
- /// Tested constants.
- final List constants;
-
- const TestData(this.declarations, this.constants);
-}
-
-class ConstantData {
- /// Source code for the constant expression.
- final String code;
- /// Map from environment to expected constant value as structured text.
- final Map<Map<String, String>, String> expectedValues;
-
- const ConstantData(this.code,
- this.expectedValues);
-}
-
-class MemoryEnvironment implements Environment {
- final Compiler compiler;
- final Map<String, String> env;
-
- MemoryEnvironment(this.compiler,
- [this.env = const <String, String>{}]);
-
- @override
- String readFromEnvironment(String name) => env[name];
-}
-
-const List<TestData> DATA = const [
- const TestData('', const [
- const ConstantData('null', const { const {} : 'NullConstant' }),
- const ConstantData('false', const { const {} : 'BoolConstant(false)' }),
- const ConstantData('true', const { const {} : 'BoolConstant(true)' }),
- const ConstantData('0', const { const {} : 'IntConstant(0)' }),
- const ConstantData('0.0', const { const {} : 'DoubleConstant(0.0)' }),
- const ConstantData('"foo"', const { const {} : 'StringConstant("foo")' }),
- const ConstantData('1 + 2', const { const {} : 'IntConstant(3)' }),
- const ConstantData('-(1)', const { const {} : 'IntConstant(-1)' }),
- const ConstantData('"foo".length', const { const {} : 'IntConstant(3)' }),
- const ConstantData('identical(0, 1)',
- const { const {} : 'BoolConstant(false)' }),
- const ConstantData('"a" "b"', const { const {} : 'StringConstant("ab")' }),
- const ConstantData('identical',
- const { const {} : 'FunctionConstant(identical)' }),
- const ConstantData('true ? 0 : 1', const { const {} : 'IntConstant(0)' }),
- const ConstantData('proxy',
- const { const {} : 'ConstructedConstant(_Proxy())' }),
- const ConstantData('Object', const { const {} : 'TypeConstant(Object)' }),
- const ConstantData('const [0, 1]',
- const { const {} : 'ListConstant([IntConstant(0), IntConstant(1)])' }),
- const ConstantData('const <int>[0, 1]', const {
- const {} : 'ListConstant(<int>[IntConstant(0), IntConstant(1)])' }),
- const ConstantData('const {0: 1, 2: 3}',
- const { const {} :
- 'MapConstant({IntConstant(0): IntConstant(1), '
- 'IntConstant(2): IntConstant(3)})' }),
- const ConstantData('const <int, int>{0: 1, 2: 3}',
- const { const {} :
- 'MapConstant(<int, int>{IntConstant(0): IntConstant(1), '
- 'IntConstant(2): IntConstant(3)})' }),
- const ConstantData(
- 'const bool.fromEnvironment("foo", defaultValue: false)',
- const { const {} : 'BoolConstant(false)',
- const {'foo': 'true'} : 'BoolConstant(true)'}),
- const ConstantData(
- 'const int.fromEnvironment("foo", defaultValue: 42)',
- const { const {} : 'IntConstant(42)',
- const {'foo': '87'} : 'IntConstant(87)'}),
- const ConstantData(
- 'const String.fromEnvironment("foo", defaultValue: "bar")',
- const { const {} : 'StringConstant("bar")',
- const {'foo': 'foo'} : 'StringConstant("foo")'}),
- ]),
- const TestData('''
-const a = const bool.fromEnvironment("foo", defaultValue: true);
-const b = const int.fromEnvironment("bar", defaultValue: 42);
-
-class A {
- const A();
-}
-class B {
- final field1;
- const B(this.field1);
-}
-class C extends B {
- final field2;
- const C({field1: 42, this.field2: false}) : super(field1);
- const C.named([field = false]) : this(field1: field, field2: field);
-}
-''', const [
- const ConstantData('const Object()',
- const { const {} : 'ConstructedConstant(Object())' }),
- const ConstantData('const A()',
- const { const {} : 'ConstructedConstant(A())' }),
- const ConstantData('const B(0)',
- const { const {} : 'ConstructedConstant(B(field1=IntConstant(0)))' }),
- const ConstantData('const B(const A())',
- const { const {} :
- 'ConstructedConstant(B(field1=ConstructedConstant(A())))' }),
- const ConstantData('const C()', const { const {} :
- 'ConstructedConstant(C(field1=IntConstant(42),'
- 'field2=BoolConstant(false)))' }),
- const ConstantData('const C(field1: 87)', const { const {} :
- 'ConstructedConstant(C(field1=IntConstant(87),'
- 'field2=BoolConstant(false)))' }),
- const ConstantData('const C(field2: true)', const { const {} :
- 'ConstructedConstant(C(field1=IntConstant(42),'
- 'field2=BoolConstant(true)))' }),
- const ConstantData('const C.named()', const { const {} :
- 'ConstructedConstant(C(field1=BoolConstant(false),'
- 'field2=BoolConstant(false)))' }),
- const ConstantData('const C.named(87)', const { const {} :
- 'ConstructedConstant(C(field1=IntConstant(87),'
- 'field2=IntConstant(87)))' }),
- const ConstantData('const C(field1: a, field2: b)', const {
- const {} :
- 'ConstructedConstant(C(field1=BoolConstant(true),'
- 'field2=IntConstant(42)))',
- const {'foo': 'false', 'bar': '87'} :
- 'ConstructedConstant(C(field1=BoolConstant(false),'
- 'field2=IntConstant(87)))', }),
- ]),
- const TestData('''
-class A<T> implements B {
- final field1;
- const A({this.field1:42});
-}
-class B<S> implements C {
- const factory B({field1}) = A<B<S>>;
- const factory B.named() = A<S>;
-}
-class C<U> {
- const factory C({field1}) = A<B<double>>;
-}
-''', const [
- const ConstantData('const A()',
- const { const {} :
- 'ConstructedConstant(A<dynamic>(field1=IntConstant(42)))' }),
- const ConstantData('const A<int>(field1: 87)',
- const { const {} :
- 'ConstructedConstant(A<int>(field1=IntConstant(87)))' }),
- const ConstantData('const B()',
- const { const {} :
- 'ConstructedConstant(A<B<dynamic>>(field1=IntConstant(42)))' }),
- const ConstantData('const B<int>()',
- const { const {} :
- 'ConstructedConstant(A<B<int>>(field1=IntConstant(42)))' }),
- const ConstantData('const B<int>(field1: 87)',
- const { const {} :
- 'ConstructedConstant(A<B<int>>(field1=IntConstant(87)))' }),
- const ConstantData('const C<int>(field1: 87)',
- const { const {} :
- 'ConstructedConstant(A<B<double>>(field1=IntConstant(87)))' }),
- const ConstantData('const B<int>.named()',
- const { const {} :
- 'ConstructedConstant(A<int>(field1=IntConstant(42)))' }),
- ]),
- const TestData('''
-const c = const int.fromEnvironment("foo", defaultValue: 5);
-const d = const int.fromEnvironment("bar", defaultValue: 10);
-
-class A {
- final field;
- const A(a, b) : field = a + b;
-}
-
-class B extends A {
- const B(a) : super(a, a * 2);
-}
-''', const [
- const ConstantData('const A(c, d)', const {
- const {} :
- 'ConstructedConstant(A(field=IntConstant(15)))',
- const {'foo': '7', 'bar': '11'} :
- 'ConstructedConstant(A(field=IntConstant(18)))', }),
- const ConstantData('const B(d)', const {
- const {} :
- 'ConstructedConstant(B(field=IntConstant(30)))',
- const {'bar': '42'} :
- 'ConstructedConstant(B(field=IntConstant(126)))', }),
- ]),
-];
-
-main() {
- asyncTest(() => Future.forEach(DATA, testData));
-}
-
-Future testData(TestData data) {
- StringBuffer sb = new StringBuffer();
- sb.write('${data.declarations}\n');
- Map constants = {};
- data.constants.forEach((ConstantData constantData) {
- String name = 'c${constants.length}';
- sb.write('const $name = ${constantData.code};\n');
- constants[name] = constantData;
- });
- sb.write('main() {}\n');
- String source = sb.toString();
- Compiler compiler = compilerFor(
- {'main.dart': source}, options: ['--analyze-all']);
- return compiler.runCompiler(Uri.parse('memory:main.dart')).then((_) {
- var library = compiler.mainApp;
- constants.forEach((String name, ConstantData data) {
- FieldElement field = library.localLookup(name);
- ConstantExpression constant = field.constant;
- data.expectedValues.forEach(
- (Map<String, String> env, String expectedText) {
- Environment environment = new MemoryEnvironment(compiler, env);
- ConstantValue value =
- constant.evaluate(environment, DART_CONSTANT_SYSTEM);
- String valueText = value.toStructuredString();
- Expect.equals(expectedText, valueText,
- "Unexpected value '${valueText}' for contant "
- "`${constant.getText()}`, expected '${expectedText}'.");
- });
- });
- });
-}
+// 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.constants.expressions.evaluate_test;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/constants/expressions.dart';
+import 'package:compiler/src/constants/values.dart';
+import 'package:compiler/src/constant_system_dart.dart';
+import 'package:compiler/src/core_types.dart';
+import 'package:compiler/src/dart2jslib.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'memory_compiler.dart';
+
+class TestData {
+ /// Declarations needed for the [constants].
+ final String declarations;
+ /// Tested constants.
+ final List constants;
+
+ const TestData(this.declarations, this.constants);
+}
+
+class ConstantData {
+ /// Source code for the constant expression.
+ final String code;
+ /// Map from environment to expected constant value as structured text.
+ final Map<Map<String, String>, String> expectedValues;
+
+ const ConstantData(this.code,
+ this.expectedValues);
+}
+
+class MemoryEnvironment implements Environment {
+ final Compiler compiler;
+ final Map<String, String> env;
+
+ MemoryEnvironment(this.compiler,
+ [this.env = const <String, String>{}]);
+
+ @override
+ String readFromEnvironment(String name) => env[name];
+}
+
+const List<TestData> DATA = const [
+ const TestData('', const [
+ const ConstantData('null', const { const {} : 'NullConstant' }),
+ const ConstantData('false', const { const {} : 'BoolConstant(false)' }),
+ const ConstantData('true', const { const {} : 'BoolConstant(true)' }),
+ const ConstantData('0', const { const {} : 'IntConstant(0)' }),
+ const ConstantData('0.0', const { const {} : 'DoubleConstant(0.0)' }),
+ const ConstantData('"foo"', const { const {} : 'StringConstant("foo")' }),
+ const ConstantData('1 + 2', const { const {} : 'IntConstant(3)' }),
+ const ConstantData('-(1)', const { const {} : 'IntConstant(-1)' }),
+ const ConstantData('"foo".length', const { const {} : 'IntConstant(3)' }),
+ const ConstantData('identical(0, 1)',
+ const { const {} : 'BoolConstant(false)' }),
+ const ConstantData('"a" "b"', const { const {} : 'StringConstant("ab")' }),
+ const ConstantData('identical',
+ const { const {} : 'FunctionConstant(identical)' }),
+ const ConstantData('true ? 0 : 1', const { const {} : 'IntConstant(0)' }),
+ const ConstantData('proxy',
+ const { const {} : 'ConstructedConstant(_Proxy())' }),
+ const ConstantData('Object', const { const {} : 'TypeConstant(Object)' }),
+ const ConstantData('const [0, 1]',
+ const { const {} : 'ListConstant([IntConstant(0), IntConstant(1)])' }),
+ const ConstantData('const <int>[0, 1]', const {
+ const {} : 'ListConstant(<int>[IntConstant(0), IntConstant(1)])' }),
+ const ConstantData('const {0: 1, 2: 3}',
+ const { const {} :
+ 'MapConstant({IntConstant(0): IntConstant(1), '
+ 'IntConstant(2): IntConstant(3)})' }),
+ const ConstantData('const <int, int>{0: 1, 2: 3}',
+ const { const {} :
+ 'MapConstant(<int, int>{IntConstant(0): IntConstant(1), '
+ 'IntConstant(2): IntConstant(3)})' }),
+ const ConstantData(
+ 'const bool.fromEnvironment("foo", defaultValue: false)',
+ const { const {} : 'BoolConstant(false)',
+ const {'foo': 'true'} : 'BoolConstant(true)'}),
+ const ConstantData(
+ 'const int.fromEnvironment("foo", defaultValue: 42)',
+ const { const {} : 'IntConstant(42)',
+ const {'foo': '87'} : 'IntConstant(87)'}),
+ const ConstantData(
+ 'const String.fromEnvironment("foo", defaultValue: "bar")',
+ const { const {} : 'StringConstant("bar")',
+ const {'foo': 'foo'} : 'StringConstant("foo")'}),
+ ]),
+ const TestData('''
+const a = const bool.fromEnvironment("foo", defaultValue: true);
+const b = const int.fromEnvironment("bar", defaultValue: 42);
+
+class A {
+ const A();
+}
+class B {
+ final field1;
+ const B(this.field1);
+}
+class C extends B {
+ final field2;
+ const C({field1: 42, this.field2: false}) : super(field1);
+ const C.named([field = false]) : this(field1: field, field2: field);
+}
+''', const [
+ const ConstantData('const Object()',
+ const { const {} : 'ConstructedConstant(Object())' }),
+ const ConstantData('const A()',
+ const { const {} : 'ConstructedConstant(A())' }),
+ const ConstantData('const B(0)',
+ const { const {} : 'ConstructedConstant(B(field1=IntConstant(0)))' }),
+ const ConstantData('const B(const A())',
+ const { const {} :
+ 'ConstructedConstant(B(field1=ConstructedConstant(A())))' }),
+ const ConstantData('const C()', const { const {} :
+ 'ConstructedConstant(C(field1=IntConstant(42),'
+ 'field2=BoolConstant(false)))' }),
+ const ConstantData('const C(field1: 87)', const { const {} :
+ 'ConstructedConstant(C(field1=IntConstant(87),'
+ 'field2=BoolConstant(false)))' }),
+ const ConstantData('const C(field2: true)', const { const {} :
+ 'ConstructedConstant(C(field1=IntConstant(42),'
+ 'field2=BoolConstant(true)))' }),
+ const ConstantData('const C.named()', const { const {} :
+ 'ConstructedConstant(C(field1=BoolConstant(false),'
+ 'field2=BoolConstant(false)))' }),
+ const ConstantData('const C.named(87)', const { const {} :
+ 'ConstructedConstant(C(field1=IntConstant(87),'
+ 'field2=IntConstant(87)))' }),
+ const ConstantData('const C(field1: a, field2: b)', const {
+ const {} :
+ 'ConstructedConstant(C(field1=BoolConstant(true),'
+ 'field2=IntConstant(42)))',
+ const {'foo': 'false', 'bar': '87'} :
+ 'ConstructedConstant(C(field1=BoolConstant(false),'
+ 'field2=IntConstant(87)))', }),
+ ]),
+ const TestData('''
+class A<T> implements B {
+ final field1;
+ const A({this.field1:42});
+}
+class B<S> implements C {
+ const factory B({field1}) = A<B<S>>;
+ const factory B.named() = A<S>;
+}
+class C<U> {
+ const factory C({field1}) = A<B<double>>;
+}
+''', const [
+ const ConstantData('const A()',
+ const { const {} :
+ 'ConstructedConstant(A<dynamic>(field1=IntConstant(42)))' }),
+ const ConstantData('const A<int>(field1: 87)',
+ const { const {} :
+ 'ConstructedConstant(A<int>(field1=IntConstant(87)))' }),
+ const ConstantData('const B()',
+ const { const {} :
+ 'ConstructedConstant(A<B<dynamic>>(field1=IntConstant(42)))' }),
+ const ConstantData('const B<int>()',
+ const { const {} :
+ 'ConstructedConstant(A<B<int>>(field1=IntConstant(42)))' }),
+ const ConstantData('const B<int>(field1: 87)',
+ const { const {} :
+ 'ConstructedConstant(A<B<int>>(field1=IntConstant(87)))' }),
+ const ConstantData('const C<int>(field1: 87)',
+ const { const {} :
+ 'ConstructedConstant(A<B<double>>(field1=IntConstant(87)))' }),
+ const ConstantData('const B<int>.named()',
+ const { const {} :
+ 'ConstructedConstant(A<int>(field1=IntConstant(42)))' }),
+ ]),
+ const TestData('''
+const c = const int.fromEnvironment("foo", defaultValue: 5);
+const d = const int.fromEnvironment("bar", defaultValue: 10);
+
+class A {
+ final field;
+ const A(a, b) : field = a + b;
+}
+
+class B extends A {
+ const B(a) : super(a, a * 2);
+}
+''', const [
+ const ConstantData('const A(c, d)', const {
+ const {} :
+ 'ConstructedConstant(A(field=IntConstant(15)))',
+ const {'foo': '7', 'bar': '11'} :
+ 'ConstructedConstant(A(field=IntConstant(18)))', }),
+ const ConstantData('const B(d)', const {
+ const {} :
+ 'ConstructedConstant(B(field=IntConstant(30)))',
+ const {'bar': '42'} :
+ 'ConstructedConstant(B(field=IntConstant(126)))', }),
+ ]),
+];
+
+main() {
+ asyncTest(() => Future.forEach(DATA, testData));
+}
+
+Future testData(TestData data) {
+ StringBuffer sb = new StringBuffer();
+ sb.write('${data.declarations}\n');
+ Map constants = {};
+ data.constants.forEach((ConstantData constantData) {
+ String name = 'c${constants.length}';
+ sb.write('const $name = ${constantData.code};\n');
+ constants[name] = constantData;
+ });
+ sb.write('main() {}\n');
+ String source = sb.toString();
+ Compiler compiler = compilerFor(
+ {'main.dart': source}, options: ['--analyze-all']);
+ return compiler.runCompiler(Uri.parse('memory:main.dart')).then((_) {
+ var library = compiler.mainApp;
+ constants.forEach((String name, ConstantData data) {
+ FieldElement field = library.localLookup(name);
+ ConstantExpression constant = field.constant;
+ data.expectedValues.forEach(
+ (Map<String, String> env, String expectedText) {
+ Environment environment = new MemoryEnvironment(compiler, env);
+ ConstantValue value =
+ constant.evaluate(environment, DART_CONSTANT_SYSTEM);
+ String valueText = value.toStructuredString();
+ Expect.equals(expectedText, valueText,
+ "Unexpected value '${valueText}' for contant "
+ "`${constant.getText()}`, expected '${expectedText}'.");
+ });
+ });
+ });
+}
diff --git a/tests/compiler/dart2js/exit_code_helper.dart b/tests/compiler/dart2js/exit_code_helper.dart
index d3c6121..52794b1 100644
--- a/tests/compiler/dart2js/exit_code_helper.dart
+++ b/tests/compiler/dart2js/exit_code_helper.dart
@@ -1,3 +1,3 @@
-void main() {
-
+void main() {
+
}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/frontend_checker.dart b/tests/compiler/dart2js/frontend_checker.dart
index b4bd3a0..91fb719 100644
--- a/tests/compiler/dart2js/frontend_checker.dart
+++ b/tests/compiler/dart2js/frontend_checker.dart
@@ -1,110 +1,110 @@
-// 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.
-
-// Checks that dart2js produces the expected static type warnings and
-// compile-time errors for the provided multitests.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/util/uri_extras.dart'
- show relativize;
-import 'memory_compiler.dart';
-
-import '../../../tools/testing/dart/multitest.dart'
- show ExtractTestsFromMultitest;
-import '../../../tools/testing/dart/path.dart'
- show Path;
-
-
-/// Check the analysis of the multitests in [testFiles] to result in the
-/// expected static warnings and compile-time errors.
-///
-/// [testFiles] is a map of the test files to be checked together with their
-/// associated white listing.
-///
-/// For instance if [testFiles] contain the mapping
-/// 'language/async_await_syntax_test.dart': const ['a03b', 'a04b']
-/// the multitests in 'language/async_await_syntax_test.dart' are checked but
-/// the subtests 'a03b' and 'a04c' are expected to fail.
-void check(Map<String, List<String>> testFiles,
- {List<String> arguments: const <String>[],
- List<String> options: const <String>[]}) {
- bool outcomeMismatch = false;
- bool verbose = arguments.contains('-v');
- var cachedCompiler;
- asyncTest(() => Future.forEach(testFiles.keys, (String testFile) {
- Map<String, String> testSources = {};
- Map<String, Set<String>> testOutcomes = {};
- String fileName = 'tests/$testFile';
- ExtractTestsFromMultitest(new Path(fileName), testSources, testOutcomes);
- return Future.forEach(testSources.keys, (String testName) {
- String testFileName = '$fileName/$testName';
- Set<String> expectedOutcome = testOutcomes[testName];
- bool expectFailure = testFiles[testFile].contains(testName);
- DiagnosticCollector collector = new DiagnosticCollector();
- var compiler = compilerFor(
- {testFileName: testSources[testName]},
- diagnosticHandler: collector,
- options: ['--analyze-only']..addAll(options),
- showDiagnostics: verbose,
- cachedCompiler: cachedCompiler);
- return compiler.run(Uri.parse('memory:$testFileName')).then((_) {
- bool unexpectedResult = false;
- if (expectedOutcome.contains('compile-time error')) {
- if (collector.errors.isEmpty) {
- print('$testFileName: Missing compile-time error.');
- unexpectedResult = true;
- }
- } else if (expectedOutcome.contains('static type warning')) {
- if (collector.warnings.isEmpty) {
- print('$testFileName: Missing static type warning.');
- unexpectedResult = true;
- }
- } else {
- // Expect ok.
- if (!collector.errors.isEmpty ||
- !collector.warnings.isEmpty) {
- collector.errors.forEach((message) {
- print('$testFileName: Unexpected error: ${message.message}');
- });
- collector.warnings.forEach((message) {
- print('$testFileName: Unexpected warning: ${message.message}');
- });
- unexpectedResult = true;
- }
- }
- if (expectFailure) {
- if (unexpectedResult) {
- unexpectedResult = false;
- } else {
- print('$testFileName: The test is white-listed '
- 'and therefore expected to fail.');
- unexpectedResult = true;
- }
- }
- if (unexpectedResult) {
- outcomeMismatch = true;
- }
- cachedCompiler = compiler;
- });
- });
- }).then((_) {
- if (outcomeMismatch) {
- String testFileName =
- relativize(Uri.base, Platform.script, Platform.isWindows);
- print('''
-
-===
-=== ERROR: Unexpected result of analysis.
-===
-=== Please update the white-listing in $testFileName
-===
-
-''');
- exit(1);
- }
- }));
-}
+// 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.
+
+// Checks that dart2js produces the expected static type warnings and
+// compile-time errors for the provided multitests.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/util/uri_extras.dart'
+ show relativize;
+import 'memory_compiler.dart';
+
+import '../../../tools/testing/dart/multitest.dart'
+ show ExtractTestsFromMultitest;
+import '../../../tools/testing/dart/path.dart'
+ show Path;
+
+
+/// Check the analysis of the multitests in [testFiles] to result in the
+/// expected static warnings and compile-time errors.
+///
+/// [testFiles] is a map of the test files to be checked together with their
+/// associated white listing.
+///
+/// For instance if [testFiles] contain the mapping
+/// 'language/async_await_syntax_test.dart': const ['a03b', 'a04b']
+/// the multitests in 'language/async_await_syntax_test.dart' are checked but
+/// the subtests 'a03b' and 'a04c' are expected to fail.
+void check(Map<String, List<String>> testFiles,
+ {List<String> arguments: const <String>[],
+ List<String> options: const <String>[]}) {
+ bool outcomeMismatch = false;
+ bool verbose = arguments.contains('-v');
+ var cachedCompiler;
+ asyncTest(() => Future.forEach(testFiles.keys, (String testFile) {
+ Map<String, String> testSources = {};
+ Map<String, Set<String>> testOutcomes = {};
+ String fileName = 'tests/$testFile';
+ ExtractTestsFromMultitest(new Path(fileName), testSources, testOutcomes);
+ return Future.forEach(testSources.keys, (String testName) {
+ String testFileName = '$fileName/$testName';
+ Set<String> expectedOutcome = testOutcomes[testName];
+ bool expectFailure = testFiles[testFile].contains(testName);
+ DiagnosticCollector collector = new DiagnosticCollector();
+ var compiler = compilerFor(
+ {testFileName: testSources[testName]},
+ diagnosticHandler: collector,
+ options: ['--analyze-only']..addAll(options),
+ showDiagnostics: verbose,
+ cachedCompiler: cachedCompiler);
+ return compiler.run(Uri.parse('memory:$testFileName')).then((_) {
+ bool unexpectedResult = false;
+ if (expectedOutcome.contains('compile-time error')) {
+ if (collector.errors.isEmpty) {
+ print('$testFileName: Missing compile-time error.');
+ unexpectedResult = true;
+ }
+ } else if (expectedOutcome.contains('static type warning')) {
+ if (collector.warnings.isEmpty) {
+ print('$testFileName: Missing static type warning.');
+ unexpectedResult = true;
+ }
+ } else {
+ // Expect ok.
+ if (!collector.errors.isEmpty ||
+ !collector.warnings.isEmpty) {
+ collector.errors.forEach((message) {
+ print('$testFileName: Unexpected error: ${message.message}');
+ });
+ collector.warnings.forEach((message) {
+ print('$testFileName: Unexpected warning: ${message.message}');
+ });
+ unexpectedResult = true;
+ }
+ }
+ if (expectFailure) {
+ if (unexpectedResult) {
+ unexpectedResult = false;
+ } else {
+ print('$testFileName: The test is white-listed '
+ 'and therefore expected to fail.');
+ unexpectedResult = true;
+ }
+ }
+ if (unexpectedResult) {
+ outcomeMismatch = true;
+ }
+ cachedCompiler = compiler;
+ });
+ });
+ }).then((_) {
+ if (outcomeMismatch) {
+ String testFileName =
+ relativize(Uri.base, Platform.script, Platform.isWindows);
+ print('''
+
+===
+=== ERROR: Unexpected result of analysis.
+===
+=== Please update the white-listing in $testFileName
+===
+
+''');
+ exit(1);
+ }
+ }));
+}
diff --git a/tests/compiler/dart2js/import_mirrors_test.dart b/tests/compiler/dart2js/import_mirrors_test.dart
index f5f799b..1b16f76 100644
--- a/tests/compiler/dart2js/import_mirrors_test.dart
+++ b/tests/compiler/dart2js/import_mirrors_test.dart
@@ -1,413 +1,413 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that the compiler emits a warning on import of 'dart:mirrors' unless
-// the flag --enable-experimental-mirrors is used.
-
-library dart2js.test.import;
-
-import 'dart:async';
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/dart2jslib.dart' show MessageKind;
-import 'memory_compiler.dart';
-
-const DIRECT_IMPORT = const {
- '/main.dart': '''
-import 'dart:mirrors';
-
-main() {}
-''',
-
- 'paths':
- "main.dart => dart:mirrors",
-};
-
-const INDIRECT_IMPORT1 = const {
- '/main.dart': '''
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths':
- "first.dart => dart:mirrors",
- 'verbosePaths':
- "main.dart => first.dart => dart:mirrors",
-};
-
-const INDIRECT_IMPORT2 = const {
- '/main.dart': '''
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'second.dart';
-''',
- '/second.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths':
- "second.dart => dart:mirrors",
- 'verbosePaths':
- "main.dart => first.dart => second.dart => dart:mirrors",
-};
-
-const INDIRECT_PACKAGE_IMPORT1 = const {
- '/main.dart': '''
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'package:second/second.dart';
-''',
- '/pkg/second/second.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths':
- "first.dart => package:second => dart:mirrors",
- 'verbosePaths':
- "main.dart => first.dart => package:second/second.dart => dart:mirrors",
-};
-
-const INDIRECT_PACKAGE_IMPORT2 = const {
- '/main.dart': '''
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'package:packagename/second.dart';
-''',
- '/pkg/packagename/second.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths':
- "first.dart => package:packagename => dart:mirrors",
- 'verbosePaths':
- "main.dart => first.dart => package:packagename/second.dart "
- "=> dart:mirrors",
-};
-
-const INDIRECT_PACKAGE_IMPORT3 = const {
- '/main.dart': '''
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'package:package1/second.dart';
-''',
- '/pkg/package1/second.dart': '''
-import 'package:package2/third.dart';
-''',
- '/pkg/package2/third.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths':
- "first.dart => package:package1 => package:package2 => dart:mirrors",
- 'verbosePaths':
- "main.dart => first.dart => package:package1/second.dart "
- "=> package:package2/third.dart => dart:mirrors",
-};
-
-const INDIRECT_PACKAGE_IMPORT4 = const {
- '/main.dart': '''
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'package:package1/second.dart';
-''',
- '/pkg/package1/second.dart': '''
-import 'sub/third.dart';
-''',
- '/pkg/package1/sub/third.dart': '''
-import 'package:package2/fourth.dart';
-''',
- '/pkg/package2/fourth.dart': '''
-import 'lib/src/fifth.dart';
-''',
- '/pkg/package2/lib/src/fifth.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths':
- "first.dart => package:package1 => package:package2 => dart:mirrors",
- 'verbosePaths':
- "main.dart => first.dart => package:package1/second.dart "
- "=> package:package1/sub/third.dart => package:package2/fourth.dart "
- "=> package:package2/lib/src/fifth.dart => dart:mirrors",
-};
-
-const DUAL_DIRECT_IMPORT = const {
- '/main.dart': '''
-import 'dart:mirrors';
-import 'dart:mirrors';
-
-main() {}
-''',
-
- 'paths':
- "main.dart => dart:mirrors",
-};
-
-const DUAL_INDIRECT_IMPORT1 = const {
- '/main.dart': '''
-import 'dart:mirrors';
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths': const
- ["main.dart => dart:mirrors",
- "first.dart => dart:mirrors"],
- 'verbosePaths': const
- ["main.dart => dart:mirrors",
- "main.dart => first.dart => dart:mirrors"],
-};
-
-const DUAL_INDIRECT_IMPORT2 = const {
- '/main.dart': '''
-import 'first.dart';
-import 'second.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'dart:mirrors';
-''',
- '/second.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths': const
- ["first.dart => dart:mirrors",
- "second.dart => dart:mirrors"],
- 'verbosePaths': const
- ["main.dart => first.dart => dart:mirrors",
- "main.dart => second.dart => dart:mirrors"],
-};
-
-const DUAL_INDIRECT_IMPORT3 = const {
- '/main.dart': '''
-import 'first.dart';
-import 'second.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'third.dart';
-''',
- '/second.dart': '''
-import 'third.dart';
-''',
- '/third.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths':
- "third.dart => dart:mirrors",
- 'verbosePaths': const
- ["main.dart => first.dart => third.dart => dart:mirrors",
- "main.dart => second.dart => third.dart => dart:mirrors"],
-};
-
-const DUAL_INDIRECT_PACKAGE_IMPORT1 = const {
- '/main.dart': '''
-import 'package:package1/second.dart';
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'package:package2/third.dart';
-''',
- '/pkg/package1/second.dart': '''
-import 'dart:mirrors';
-''',
- '/pkg/package2/third.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths': const
- ["main.dart => package:package1 => dart:mirrors",
- "first.dart => package:package2 => dart:mirrors"],
- 'verbosePaths': const
- ["main.dart => package:package1/second.dart => dart:mirrors",
- "main.dart => first.dart => package:package2/third.dart => dart:mirrors"]
-};
-
-const DIRECT_EXPORT = const {
- '/main.dart': '''
-export 'dart:mirrors';
-
-main() {}
-''',
-
- 'paths':
- "main.dart => dart:mirrors",
-};
-
-const INDIRECT_EXPORT1 = const {
- '/main.dart': '''
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-export 'dart:mirrors';
-''',
-
- 'paths':
- "first.dart => dart:mirrors",
- 'verbosePaths':
- "main.dart => first.dart => dart:mirrors",
-};
-
-const INDIRECT_EXPORT2 = const {
- '/main.dart': '''
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'second.dart';
-''',
- '/second.dart': '''
-export 'dart:mirrors';
-''',
-
- 'paths':
- "second.dart => dart:mirrors",
- 'verbosePaths':
- "main.dart => first.dart => second.dart => dart:mirrors",
-};
-
-const INDIRECT_PACKAGE_EXPORT1 = const {
- '/main.dart': '''
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-import 'package:packagename/second.dart';
-''',
- '/pkg/packagename/second.dart': '''
-export 'dart:mirrors';
-''',
-
- 'paths':
- "first.dart => package:packagename => dart:mirrors",
- 'verbosePaths':
- "main.dart => first.dart => package:packagename/second.dart "
- "=> dart:mirrors",
-};
-
-const INDIRECT_PACKAGE_EXPORT2 = const {
- '/main.dart': '''
-import 'first.dart';
-
-main() {}
-''',
- '/first.dart': '''
-export 'package:packagename/second.dart';
-''',
- '/pkg/packagename/second.dart': '''
-import 'dart:mirrors';
-''',
-
- 'paths':
- "first.dart => package:packagename => dart:mirrors",
- 'verbosePaths':
- "main.dart => first.dart => package:packagename/second.dart "
- "=> dart:mirrors",
-};
-
-Future test(Map sourceFiles,
- {expectedPaths,
- bool verbose: false,
- bool enableExperimentalMirrors: false}) {
- if (expectedPaths is! List) {
- expectedPaths = [expectedPaths];
- }
- var collector = new DiagnosticCollector();
- var options = [];
- if (verbose) {
- options.add('--verbose');
- }
- if (enableExperimentalMirrors) {
- options.add('--enable-experimental-mirrors');
- }
- var compiler = compilerFor(sourceFiles, diagnosticHandler: collector,
- packageRoot: Uri.parse('memory:/pkg/'),
- options: options);
- return compiler.run(Uri.parse('memory:/main.dart')).then((_) {
- Expect.equals(0, collector.errors.length, 'Errors: ${collector.errors}');
- if (enableExperimentalMirrors) {
- Expect.equals(0, collector.warnings.length,
- 'Warnings: ${collector.errors}');
- } else {
- Expect.equals(1, collector.warnings.length,
- 'Warnings: ${collector.errors}');
- Expect.equals(
- MessageKind.IMPORT_EXPERIMENTAL_MIRRORS.message(
- {'importChain': expectedPaths.join(
- MessageKind.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)}).toString(),
- collector.warnings.first.message);
- }
- });
-}
-
-Future checkPaths(Map sourceData) {
- Map sourceFiles = sourceData;
- var expectedPaths = sourceData['paths'];
- var expectedVerbosePaths = sourceData['verbosePaths'];
- if (expectedVerbosePaths == null) {
- expectedVerbosePaths = expectedPaths;
- }
- return test(sourceFiles, expectedPaths: expectedPaths).then((_) {
- return test(
- sourceFiles, expectedPaths: expectedVerbosePaths, verbose: true);
- }).then((_) {
- return test(sourceFiles, enableExperimentalMirrors: true);
- });
-}
-
-void main() {
- asyncTest(() => Future.forEach([
- DIRECT_IMPORT,
- INDIRECT_IMPORT1,
- INDIRECT_IMPORT2,
- INDIRECT_PACKAGE_IMPORT1,
- INDIRECT_PACKAGE_IMPORT2,
- INDIRECT_PACKAGE_IMPORT3,
- INDIRECT_PACKAGE_IMPORT4,
- DUAL_DIRECT_IMPORT,
- DUAL_INDIRECT_IMPORT1,
- DUAL_INDIRECT_IMPORT2,
- DUAL_INDIRECT_IMPORT3,
- DUAL_INDIRECT_PACKAGE_IMPORT1,
- DIRECT_EXPORT,
- INDIRECT_EXPORT1,
- INDIRECT_EXPORT2,
- INDIRECT_PACKAGE_EXPORT1,
- INDIRECT_PACKAGE_EXPORT2],
- (map) => checkPaths(map)
- ));
-}
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that the compiler emits a warning on import of 'dart:mirrors' unless
+// the flag --enable-experimental-mirrors is used.
+
+library dart2js.test.import;
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/dart2jslib.dart' show MessageKind;
+import 'memory_compiler.dart';
+
+const DIRECT_IMPORT = const {
+ '/main.dart': '''
+import 'dart:mirrors';
+
+main() {}
+''',
+
+ 'paths':
+ "main.dart => dart:mirrors",
+};
+
+const INDIRECT_IMPORT1 = const {
+ '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths':
+ "first.dart => dart:mirrors",
+ 'verbosePaths':
+ "main.dart => first.dart => dart:mirrors",
+};
+
+const INDIRECT_IMPORT2 = const {
+ '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'second.dart';
+''',
+ '/second.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths':
+ "second.dart => dart:mirrors",
+ 'verbosePaths':
+ "main.dart => first.dart => second.dart => dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_IMPORT1 = const {
+ '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'package:second/second.dart';
+''',
+ '/pkg/second/second.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths':
+ "first.dart => package:second => dart:mirrors",
+ 'verbosePaths':
+ "main.dart => first.dart => package:second/second.dart => dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_IMPORT2 = const {
+ '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'package:packagename/second.dart';
+''',
+ '/pkg/packagename/second.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths':
+ "first.dart => package:packagename => dart:mirrors",
+ 'verbosePaths':
+ "main.dart => first.dart => package:packagename/second.dart "
+ "=> dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_IMPORT3 = const {
+ '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'package:package1/second.dart';
+''',
+ '/pkg/package1/second.dart': '''
+import 'package:package2/third.dart';
+''',
+ '/pkg/package2/third.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths':
+ "first.dart => package:package1 => package:package2 => dart:mirrors",
+ 'verbosePaths':
+ "main.dart => first.dart => package:package1/second.dart "
+ "=> package:package2/third.dart => dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_IMPORT4 = const {
+ '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'package:package1/second.dart';
+''',
+ '/pkg/package1/second.dart': '''
+import 'sub/third.dart';
+''',
+ '/pkg/package1/sub/third.dart': '''
+import 'package:package2/fourth.dart';
+''',
+ '/pkg/package2/fourth.dart': '''
+import 'lib/src/fifth.dart';
+''',
+ '/pkg/package2/lib/src/fifth.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths':
+ "first.dart => package:package1 => package:package2 => dart:mirrors",
+ 'verbosePaths':
+ "main.dart => first.dart => package:package1/second.dart "
+ "=> package:package1/sub/third.dart => package:package2/fourth.dart "
+ "=> package:package2/lib/src/fifth.dart => dart:mirrors",
+};
+
+const DUAL_DIRECT_IMPORT = const {
+ '/main.dart': '''
+import 'dart:mirrors';
+import 'dart:mirrors';
+
+main() {}
+''',
+
+ 'paths':
+ "main.dart => dart:mirrors",
+};
+
+const DUAL_INDIRECT_IMPORT1 = const {
+ '/main.dart': '''
+import 'dart:mirrors';
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths': const
+ ["main.dart => dart:mirrors",
+ "first.dart => dart:mirrors"],
+ 'verbosePaths': const
+ ["main.dart => dart:mirrors",
+ "main.dart => first.dart => dart:mirrors"],
+};
+
+const DUAL_INDIRECT_IMPORT2 = const {
+ '/main.dart': '''
+import 'first.dart';
+import 'second.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'dart:mirrors';
+''',
+ '/second.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths': const
+ ["first.dart => dart:mirrors",
+ "second.dart => dart:mirrors"],
+ 'verbosePaths': const
+ ["main.dart => first.dart => dart:mirrors",
+ "main.dart => second.dart => dart:mirrors"],
+};
+
+const DUAL_INDIRECT_IMPORT3 = const {
+ '/main.dart': '''
+import 'first.dart';
+import 'second.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'third.dart';
+''',
+ '/second.dart': '''
+import 'third.dart';
+''',
+ '/third.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths':
+ "third.dart => dart:mirrors",
+ 'verbosePaths': const
+ ["main.dart => first.dart => third.dart => dart:mirrors",
+ "main.dart => second.dart => third.dart => dart:mirrors"],
+};
+
+const DUAL_INDIRECT_PACKAGE_IMPORT1 = const {
+ '/main.dart': '''
+import 'package:package1/second.dart';
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'package:package2/third.dart';
+''',
+ '/pkg/package1/second.dart': '''
+import 'dart:mirrors';
+''',
+ '/pkg/package2/third.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths': const
+ ["main.dart => package:package1 => dart:mirrors",
+ "first.dart => package:package2 => dart:mirrors"],
+ 'verbosePaths': const
+ ["main.dart => package:package1/second.dart => dart:mirrors",
+ "main.dart => first.dart => package:package2/third.dart => dart:mirrors"]
+};
+
+const DIRECT_EXPORT = const {
+ '/main.dart': '''
+export 'dart:mirrors';
+
+main() {}
+''',
+
+ 'paths':
+ "main.dart => dart:mirrors",
+};
+
+const INDIRECT_EXPORT1 = const {
+ '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+export 'dart:mirrors';
+''',
+
+ 'paths':
+ "first.dart => dart:mirrors",
+ 'verbosePaths':
+ "main.dart => first.dart => dart:mirrors",
+};
+
+const INDIRECT_EXPORT2 = const {
+ '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'second.dart';
+''',
+ '/second.dart': '''
+export 'dart:mirrors';
+''',
+
+ 'paths':
+ "second.dart => dart:mirrors",
+ 'verbosePaths':
+ "main.dart => first.dart => second.dart => dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_EXPORT1 = const {
+ '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+import 'package:packagename/second.dart';
+''',
+ '/pkg/packagename/second.dart': '''
+export 'dart:mirrors';
+''',
+
+ 'paths':
+ "first.dart => package:packagename => dart:mirrors",
+ 'verbosePaths':
+ "main.dart => first.dart => package:packagename/second.dart "
+ "=> dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_EXPORT2 = const {
+ '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+ '/first.dart': '''
+export 'package:packagename/second.dart';
+''',
+ '/pkg/packagename/second.dart': '''
+import 'dart:mirrors';
+''',
+
+ 'paths':
+ "first.dart => package:packagename => dart:mirrors",
+ 'verbosePaths':
+ "main.dart => first.dart => package:packagename/second.dart "
+ "=> dart:mirrors",
+};
+
+Future test(Map sourceFiles,
+ {expectedPaths,
+ bool verbose: false,
+ bool enableExperimentalMirrors: false}) {
+ if (expectedPaths is! List) {
+ expectedPaths = [expectedPaths];
+ }
+ var collector = new DiagnosticCollector();
+ var options = [];
+ if (verbose) {
+ options.add('--verbose');
+ }
+ if (enableExperimentalMirrors) {
+ options.add('--enable-experimental-mirrors');
+ }
+ var compiler = compilerFor(sourceFiles, diagnosticHandler: collector,
+ packageRoot: Uri.parse('memory:/pkg/'),
+ options: options);
+ return compiler.run(Uri.parse('memory:/main.dart')).then((_) {
+ Expect.equals(0, collector.errors.length, 'Errors: ${collector.errors}');
+ if (enableExperimentalMirrors) {
+ Expect.equals(0, collector.warnings.length,
+ 'Warnings: ${collector.errors}');
+ } else {
+ Expect.equals(1, collector.warnings.length,
+ 'Warnings: ${collector.errors}');
+ Expect.equals(
+ MessageKind.IMPORT_EXPERIMENTAL_MIRRORS.message(
+ {'importChain': expectedPaths.join(
+ MessageKind.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)}).toString(),
+ collector.warnings.first.message);
+ }
+ });
+}
+
+Future checkPaths(Map sourceData) {
+ Map sourceFiles = sourceData;
+ var expectedPaths = sourceData['paths'];
+ var expectedVerbosePaths = sourceData['verbosePaths'];
+ if (expectedVerbosePaths == null) {
+ expectedVerbosePaths = expectedPaths;
+ }
+ return test(sourceFiles, expectedPaths: expectedPaths).then((_) {
+ return test(
+ sourceFiles, expectedPaths: expectedVerbosePaths, verbose: true);
+ }).then((_) {
+ return test(sourceFiles, enableExperimentalMirrors: true);
+ });
+}
+
+void main() {
+ asyncTest(() => Future.forEach([
+ DIRECT_IMPORT,
+ INDIRECT_IMPORT1,
+ INDIRECT_IMPORT2,
+ INDIRECT_PACKAGE_IMPORT1,
+ INDIRECT_PACKAGE_IMPORT2,
+ INDIRECT_PACKAGE_IMPORT3,
+ INDIRECT_PACKAGE_IMPORT4,
+ DUAL_DIRECT_IMPORT,
+ DUAL_INDIRECT_IMPORT1,
+ DUAL_INDIRECT_IMPORT2,
+ DUAL_INDIRECT_IMPORT3,
+ DUAL_INDIRECT_PACKAGE_IMPORT1,
+ DIRECT_EXPORT,
+ INDIRECT_EXPORT1,
+ INDIRECT_EXPORT2,
+ INDIRECT_PACKAGE_EXPORT1,
+ INDIRECT_PACKAGE_EXPORT2],
+ (map) => checkPaths(map)
+ ));
+}
diff --git a/tests/compiler/dart2js/instantiated_classes_test.dart b/tests/compiler/dart2js/instantiated_classes_test.dart
index d125ff9..ea90156 100644
--- a/tests/compiler/dart2js/instantiated_classes_test.dart
+++ b/tests/compiler/dart2js/instantiated_classes_test.dart
@@ -1,85 +1,85 @@
-// 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 instantiated_classes_test;
-
-import 'dart:async';
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/elements/elements.dart'
- show ClassElement;
-import 'type_test_helper.dart';
-
-void main() {
- asyncTest(() => Future.forEach([
- () => test("class Class {}", ["Class"]),
- () => test("""abstract class A {}
- class Class extends A {}""",
- ["Class"]),
- () => test("""class A {}
- class Class extends A {}""",
- ["Class"]),
- () => test("""class A {}
- class B {}
- class Class extends A {}""",
- ["Class"]),
- () => test("""class A {}
- class Class implements A {}""",
- ["Class"]),
- () => test("""class A {}
- class Class extends Object with A {}""",
- ["Class"]),
- () => test("""class A {}
- class B {}
- class Class extends Object with B implements A {}""",
- ["Class"]),
-
- () => test("""class A {}
- class Class {}""",
- ["Class", "A"], ["Class", "A"]),
- () => test("""class A {}
- class Class extends A {}""",
- ["Class", "A"], ["Class", "A"]),
- () => test("""class A {}
- class Class implements A {}""",
- ["Class", "A"], ["Class", "A"]),
- () => test("""class A {}
- class B extends A {}
- class Class extends B {}""",
- ["Class", "A"], ["Class", "A"]),
- () => test("""class A {}
- class B {}
- class Class extends B with A {}""",
- ["Class", "A"], ["Class", "A"]),
-
- // TODO(johnniwinther): Avoid registration of `Class` as instantiated.
- () => test("""class A {}
- class Class implements A {
- factory Class() = A;
- }""",
- ["Class", "A"], ["Class"]),
- ], (f) => f()));
-}
-
-Future test(String source, List<String> directlyInstantiatedClasses,
- [List<String> newClasses = const <String>["Class"]]) {
- StringBuffer mainSource = new StringBuffer();
- mainSource.write('main() {\n');
- for (String newClass in newClasses) {
- mainSource.write(' new $newClass();\n');
- }
- mainSource.write('}');
- return TypeEnvironment.create(source,
- mainSource: mainSource.toString(),
- useMockCompiler: true).then((env) {
- Iterable<ClassElement> expectedClasses =
- directlyInstantiatedClasses.map(env.getElement);
- Iterable<ClassElement> actualClasses =
- env.compiler.resolverWorld.directlyInstantiatedClasses.where(
- (c) => c.library == env.compiler.mainApp);
- Expect.setEquals(expectedClasses, actualClasses);
- });
-}
-
-
+// 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 instantiated_classes_test;
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/elements/elements.dart'
+ show ClassElement;
+import 'type_test_helper.dart';
+
+void main() {
+ asyncTest(() => Future.forEach([
+ () => test("class Class {}", ["Class"]),
+ () => test("""abstract class A {}
+ class Class extends A {}""",
+ ["Class"]),
+ () => test("""class A {}
+ class Class extends A {}""",
+ ["Class"]),
+ () => test("""class A {}
+ class B {}
+ class Class extends A {}""",
+ ["Class"]),
+ () => test("""class A {}
+ class Class implements A {}""",
+ ["Class"]),
+ () => test("""class A {}
+ class Class extends Object with A {}""",
+ ["Class"]),
+ () => test("""class A {}
+ class B {}
+ class Class extends Object with B implements A {}""",
+ ["Class"]),
+
+ () => test("""class A {}
+ class Class {}""",
+ ["Class", "A"], ["Class", "A"]),
+ () => test("""class A {}
+ class Class extends A {}""",
+ ["Class", "A"], ["Class", "A"]),
+ () => test("""class A {}
+ class Class implements A {}""",
+ ["Class", "A"], ["Class", "A"]),
+ () => test("""class A {}
+ class B extends A {}
+ class Class extends B {}""",
+ ["Class", "A"], ["Class", "A"]),
+ () => test("""class A {}
+ class B {}
+ class Class extends B with A {}""",
+ ["Class", "A"], ["Class", "A"]),
+
+ // TODO(johnniwinther): Avoid registration of `Class` as instantiated.
+ () => test("""class A {}
+ class Class implements A {
+ factory Class() = A;
+ }""",
+ ["Class", "A"], ["Class"]),
+ ], (f) => f()));
+}
+
+Future test(String source, List<String> directlyInstantiatedClasses,
+ [List<String> newClasses = const <String>["Class"]]) {
+ StringBuffer mainSource = new StringBuffer();
+ mainSource.write('main() {\n');
+ for (String newClass in newClasses) {
+ mainSource.write(' new $newClass();\n');
+ }
+ mainSource.write('}');
+ return TypeEnvironment.create(source,
+ mainSource: mainSource.toString(),
+ useMockCompiler: true).then((env) {
+ Iterable<ClassElement> expectedClasses =
+ directlyInstantiatedClasses.map(env.getElement);
+ Iterable<ClassElement> actualClasses =
+ env.compiler.resolverWorld.directlyInstantiatedClasses.where(
+ (c) => c.library == env.compiler.mainApp);
+ Expect.setEquals(expectedClasses, actualClasses);
+ });
+}
+
+
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
index 264dc65..8ba0f45 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
@@ -34,7 +34,6 @@
P.print("(1)");
P.print("(" + H.S(l) + ")");
P.print("(" + H.S(m) + ")");
- return null;
}"""),
const TestEntry("""
foo(a, [b = "b"]) => b;
@@ -56,7 +55,6 @@
V.bar(4, 5, "c");
V.bar(6, "b", 7);
V.bar(8, 9, 10);
- return null;
}"""),
const TestEntry(
"""
@@ -83,7 +81,6 @@
P.print(a);
P.print(a);
P.print(V.foo(b));
- return null;
}"""),
const TestEntry(
"""
@@ -97,7 +94,6 @@
const TestEntry("main() { return 42; }"),
const TestEntry("main() { return; }", """
function() {
- return null;
}"""),
// Constructor invocation
const TestEntry("""
@@ -108,7 +104,6 @@
function() {
P.print(P.LinkedHashSet_LinkedHashSet(null, null, null, null));
P.print(P.LinkedHashSet_LinkedHashSet$from([1, 2, 3], null));
- return null;
}"""),
// Call synthetic constructor.
const TestEntry("""
@@ -123,7 +118,6 @@
}""", r"""
function() {
P.print(P.DateTime$now().isBefore$1(P.DateTime$now()));
- return null;
}"""),
// Static calls
const TestEntry("""
@@ -132,7 +126,6 @@
""", r"""
function() {
V.foo();
- return null;
}"""),
// Static getters
const TestEntry("""
@@ -141,7 +134,6 @@
""", r"""
function() {
P.print($.foo);
- return null;
}"""),
const TestEntry("""
get foo { print(42); }
@@ -149,7 +141,6 @@
""", r"""
function() {
V.foo();
- return null;
}"""),
// Static setters
const TestEntry("""
@@ -160,7 +151,6 @@
var v0 = 42;
$.foo = v0;
P.print(v0);
- return null;
}"""),
const TestEntry("""
set foo(x) { print(x); }
@@ -168,7 +158,6 @@
""", r"""
function() {
V.foo(42);
- return null;
}"""),
// Assert
const TestEntry("""
@@ -181,7 +170,6 @@
}""", r"""
function() {
P.print("Done");
- return null;
}""")
];
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
index e58e474..97b53e7 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
@@ -24,7 +24,6 @@
_box_0._captured_x_0 = x;
_box_0._captured_x_0 = J.getInterceptor$ns(x = _box_0._captured_x_0).$add(x, "1");
P.print(a.call$0());
- return null;
}"""),
const TestEntry("""
@@ -38,7 +37,6 @@
r"""
function(x) {
P.print(new V.main_a(x).call$0());
- return null;
}"""),
const TestEntry("""
@@ -55,7 +53,6 @@
_box_0._captured_x_0 = 122;
_box_0._captured_x_0 = _box_0._captured_x_0 + 1;
P.print(a.call$0());
- return null;
}"""),
const TestEntry("""
@@ -75,7 +72,6 @@
_box_0._captured_x_0 = 122;
_box_0._captured_x_0 = _box_0._captured_x_0 + 1;
P.print(a.call$0().call$0());
- return null;
}"""),
const TestEntry("""
@@ -95,7 +91,6 @@
i = i + 1;
}
P.print(a.call$0());
- return null;
}"""),
const TestEntry.forMethod('function(A#b)', """
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
index ff798ac..b724218 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
@@ -43,7 +43,6 @@
r"""
function(x, y) {
P.print(x);
- return null;
}"""),
const TestEntry.forMethod('generative_constructor(Sub#)', """
@@ -163,7 +162,6 @@
}""", r"""
function() {
P.print(V.C$(P.$int).foo$0());
- return null;
}"""),
const TestEntry(r"""
class C<T> {
@@ -174,7 +172,6 @@
}""", r"""
function() {
P.print(V.C$().foo$0());
- return null;
}"""),
const TestEntry.forMethod('generative_constructor(C#)', r"""
class C<T> {
@@ -246,7 +243,6 @@
}""", r"""
function() {
P.print(V.Foo$create(5));
- return null;
}"""),
const TestEntry(r"""
class A {
@@ -264,7 +260,6 @@
}""", r"""
function() {
V.B$(5, P.$int).get$typevar();
- return null;
}"""),
];
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
index 0e5808a..b6fc9ad 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
@@ -60,13 +60,11 @@
L1:
while (P.identical(V.foo(true), true)) {
P.print(1);
- if (!P.identical(V.foo(false), true))
- i = V.foo(i);
- else
+ if (P.identical(V.foo(false), true))
break L1;
+ i = V.foo(i);
}
P.print(2);
- return null;
}"""),
const TestEntry("""
foo(a) => a;
@@ -82,7 +80,6 @@
function() {
V.foo(true) ? P.print(1) : P.print(2);
P.print(3);
- return null;
}"""),
const TestEntry("""
foo(a) => a;
@@ -106,7 +103,6 @@
P.print(2);
}
P.print(3);
- return null;
}"""),
const TestEntry("""
main() {
@@ -118,7 +114,6 @@
}""","""
function() {
P.print("good");
- return null;
}"""),
const TestEntry("""
foo() => 2;
@@ -132,7 +127,6 @@
function() {
V.foo();
P.print("good");
- return null;
}"""),
];
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
index 41073af..60f9717 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
@@ -19,7 +19,6 @@
r"""
function() {
P.print(4);
- return null;
}"""),
const TestEntry("""
main() {
@@ -45,7 +44,6 @@
}
i = i + 1;
}
- return null;
}"""),
];
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart
index 5664553..ad9d2e7 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart
@@ -29,7 +29,6 @@
P.print(P.LinkedHashMap_LinkedHashMap$_empty());
P.print(P.LinkedHashMap_LinkedHashMap$_literal([1, 2]));
P.print(P.LinkedHashMap_LinkedHashMap$_literal([[1, 2], [3, 4]]));
- return null;
}"""),
];
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart
index 486bcc7..577dca0 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart
@@ -18,7 +18,6 @@
"""function() {
V.foo();
P.print("bad bad");
- return null;
}"""),
const TestEntry("""
foo() => null;
@@ -28,7 +27,6 @@
"""function() {
V.foo();
P.print("bad bad");
- return null;
}"""),
const TestEntry("""
get foo => foo;
@@ -38,7 +36,6 @@
"""function() {
V.foo();
P.print("bad bad");
- return null;
}"""),
const TestEntry("""
get foo => foo;
@@ -46,7 +43,6 @@
"""function() {
V.foo();
P.print(false);
- return null;
}"""),
const TestEntry("""
get foo => foo;
@@ -55,7 +51,6 @@
V.foo();
V.foo();
P.print(false);
- return null;
}"""),
// Needs interceptor calling convention
@@ -84,7 +79,6 @@
var list = [1, 2, 3];
J.getInterceptor$a(list).$indexSet(list, 1, 6);
P.print(list);
- return null;
}"""),
];
diff --git a/tests/compiler/dart2js/least_upper_bound_language_test.dart b/tests/compiler/dart2js/least_upper_bound_language_test.dart
index f75c32c..ad01ad0 100644
--- a/tests/compiler/dart2js/least_upper_bound_language_test.dart
+++ b/tests/compiler/dart2js/least_upper_bound_language_test.dart
@@ -1,22 +1,22 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that dart2js produces the expected static type warnings for least upper
-// bound language tests. This ensures that the analyzer and dart2js agrees
-// on these tests.
-
-import 'warnings_checker.dart';
-
-/// Map from test files to a map of their expected status. If the status map is
-/// `null` no warnings must be missing or unexpected, otherwise the status map
-/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
-/// the warnings of each category.
-const Map<String, dynamic> TESTS = const {
- 'language/least_upper_bound_test.dart': null,
- 'language/least_upper_bound_expansive_test.dart': null,
-};
-
-void main() {
- checkWarnings(TESTS);
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that dart2js produces the expected static type warnings for least upper
+// bound language tests. This ensures that the analyzer and dart2js agrees
+// on these tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+ 'language/least_upper_bound_test.dart': null,
+ 'language/least_upper_bound_expansive_test.dart': null,
+};
+
+void main() {
+ checkWarnings(TESTS);
+}
diff --git a/tests/compiler/dart2js/least_upper_bound_test.dart b/tests/compiler/dart2js/least_upper_bound_test.dart
index 804b803..23aa02b 100644
--- a/tests/compiler/dart2js/least_upper_bound_test.dart
+++ b/tests/compiler/dart2js/least_upper_bound_test.dart
@@ -1,852 +1,852 @@
-// 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 subtype_test;
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'type_test_helper.dart';
-import 'package:compiler/src/dart_types.dart';
-import "package:compiler/src/elements/elements.dart"
- show Element, ClassElement;
-import 'package:compiler/src/util/util.dart';
-
-void main() {
- testInterface1();
- testInterface2();
- testGeneric();
- testMixin();
- testFunction();
- testTypeVariable();
-}
-
-void testInterface1() {
- asyncTest(() => TypeEnvironment.create(r"""
- class A {} // A and B have equal depth.
- class B {}
- class I implements A, B {}
- class J implements A, B {}
- """).then((env) {
-
- DartType Object_ = env['Object'];
- DartType A = env['A'];
- DartType B = env['B'];
- DartType I = env['I'];
- DartType J = env['J'];
-
- checkLub(DartType a, DartType b, DartType expect) {
- DartType lub = env.computeLeastUpperBound(a, b);
- Expect.equals(expect, lub,
- 'Unexpected lub($a,$b) = $lub, expected $expect.');
- }
-
- checkLub(Object_, Object_, Object_);
- checkLub(Object_, A, Object_);
- checkLub(Object_, B, Object_);
- checkLub(Object_, I, Object_);
- checkLub(Object_, J, Object_);
-
- checkLub(A, Object_, Object_);
- checkLub(A, A, A);
- checkLub(A, B, Object_);
- checkLub(A, I, A);
- checkLub(A, J, A);
-
- checkLub(B, Object_, Object_);
- checkLub(B, A, Object_);
- checkLub(B, B, B);
- checkLub(B, I, B);
- checkLub(B, J, B);
-
- checkLub(I, Object_, Object_);
- checkLub(I, A, A);
- checkLub(I, B, B);
- checkLub(I, I, I);
- checkLub(I, J, Object_);
-
- checkLub(J, Object_, Object_);
- checkLub(J, A, A);
- checkLub(J, B, B);
- checkLub(J, I, Object_);
- checkLub(J, J, J);
- }));
-}
-
-void testInterface2() {
- asyncTest(() => TypeEnvironment.create(r"""
- class A {}
- class B {}
- class C extends B {} // This makes C have higher depth than A.
- class I implements A, C {}
- class J implements A, C {}
- """).then((env) {
-
- DartType Object_ = env['Object'];
- DartType A = env['A'];
- DartType B = env['B'];
- DartType C = env['C'];
- DartType I = env['I'];
- DartType J = env['J'];
-
- checkLub(DartType a, DartType b, DartType expectedLub) {
- DartType lub = env.computeLeastUpperBound(a, b);
- Expect.equals(expectedLub, lub,
- 'Unexpected lub($a,$b) = $lub, expected $expectedLub');
- }
-
- checkLub(Object_, Object_, Object_);
- checkLub(Object_, A, Object_);
- checkLub(Object_, B, Object_);
- checkLub(Object_, C, Object_);
- checkLub(Object_, I, Object_);
- checkLub(Object_, J, Object_);
-
- checkLub(A, Object_, Object_);
- checkLub(A, A, A);
- checkLub(A, B, Object_);
- checkLub(A, C, Object_);
- checkLub(A, I, A);
- checkLub(A, J, A);
-
- checkLub(B, Object_, Object_);
- checkLub(B, A, Object_);
- checkLub(B, B, B);
- checkLub(B, C, B);
- checkLub(B, I, B);
- checkLub(B, J, B);
-
- checkLub(C, Object_, Object_);
- checkLub(C, A, Object_);
- checkLub(C, B, B);
- checkLub(C, C, C);
- checkLub(C, I, C);
- checkLub(C, J, C);
-
- checkLub(I, Object_, Object_);
- checkLub(I, A, A);
- checkLub(I, B, B);
- checkLub(I, C, C);
- checkLub(I, I, I);
- checkLub(I, J, C);
-
- checkLub(J, Object_, Object_);
- checkLub(J, A, A);
- checkLub(J, B, B);
- checkLub(J, C, C);
- checkLub(J, I, C);
- checkLub(J, J, J);
- }));
-}
-
-void testGeneric() {
- asyncTest(() => TypeEnvironment.create(r"""
- class A {}
- class B {}
- class C extends B {}
- class I<T> {}
- """).then((env) {
-
- DartType Object_ = env['Object'];
- DartType A = env['A'];
- DartType B = env['B'];
- DartType C = env['C'];
- ClassElement I = env.getElement('I');
- DartType I_A = instantiate(I, [A]);
- DartType I_B = instantiate(I, [B]);
- DartType I_C = instantiate(I, [C]);
-
- checkLub(DartType a, DartType b, DartType expectedLub) {
- DartType lub = env.computeLeastUpperBound(a, b);
- Expect.equals(expectedLub, lub,
- 'Unexpected lub($a,$b) = $lub, expected $expectedLub');
- }
-
- checkLub(Object_, Object_, Object_);
- checkLub(Object_, A, Object_);
- checkLub(Object_, B, Object_);
- checkLub(Object_, C, Object_);
- checkLub(Object_, I_A, Object_);
- checkLub(Object_, I_B, Object_);
- checkLub(Object_, I_C, Object_);
-
- checkLub(A, Object_, Object_);
- checkLub(A, A, A);
- checkLub(A, B, Object_);
- checkLub(A, C, Object_);
- checkLub(A, I_A, Object_);
- checkLub(A, I_B, Object_);
- checkLub(A, I_C, Object_);
-
- checkLub(B, Object_, Object_);
- checkLub(B, A, Object_);
- checkLub(B, B, B);
- checkLub(B, C, B);
- checkLub(B, I_A, Object_);
- checkLub(B, I_B, Object_);
- checkLub(B, I_C, Object_);
-
- checkLub(C, Object_, Object_);
- checkLub(C, A, Object_);
- checkLub(C, B, B);
- checkLub(C, C, C);
- checkLub(C, I_A, Object_);
- checkLub(C, I_B, Object_);
- checkLub(C, I_C, Object_);
-
- checkLub(I_A, Object_, Object_);
- checkLub(I_A, A, Object_);
- checkLub(I_A, B, Object_);
- checkLub(I_A, C, Object_);
- checkLub(I_A, I_A, I_A);
- checkLub(I_A, I_B, Object_);
- checkLub(I_A, I_C, Object_);
-
- checkLub(I_B, Object_, Object_);
- checkLub(I_B, A, Object_);
- checkLub(I_B, B, Object_);
- checkLub(I_B, C, Object_);
- checkLub(I_B, I_A, Object_);
- checkLub(I_B, I_B, I_B);
- checkLub(I_B, I_C, Object_);
-
- checkLub(I_C, Object_, Object_);
- checkLub(I_C, A, Object_);
- checkLub(I_C, B, Object_);
- checkLub(I_C, C, Object_);
- checkLub(I_C, I_A, Object_);
- checkLub(I_C, I_B, Object_);
- checkLub(I_C, I_C, I_C);
- }));
-}
-
-void testMixin() {
- asyncTest(() => TypeEnvironment.create(r"""
- class A {}
- class B {}
- class C extends B {}
- class D extends C {} // This makes D have higher depth than Object+A.
- class I extends Object with A, B implements A, D {}
- class I2 extends Object with A, B implements A, D {}
- class J extends Object with B, A implements A, D {}
- """).then((env) {
-
- DartType Object_ = env['Object'];
- DartType A = env['A'];
- DartType B = env['B'];
- DartType C = env['C'];
- DartType D = env['D'];
- DartType I = env['I'];
- DartType I2 = env['I2'];
- DartType J = env['J'];
-
- checkLub(DartType a, DartType b, DartType expectedLub) {
- DartType lub = env.computeLeastUpperBound(a, b);
- Expect.equals(expectedLub, lub,
- 'Unexpected lub($a,$b) = $lub, expected $expectedLub');
- }
-
- checkLub(Object_, Object_, Object_);
- checkLub(Object_, A, Object_);
- checkLub(Object_, B, Object_);
- checkLub(Object_, C, Object_);
- checkLub(Object_, D, Object_);
- checkLub(Object_, I, Object_);
- checkLub(Object_, I2, Object_);
- checkLub(Object_, J, Object_);
-
- checkLub(A, Object_, Object_);
- checkLub(A, A, A);
- checkLub(A, B, Object_);
- checkLub(A, C, Object_);
- checkLub(A, D, Object_);
- checkLub(A, I, A);
- checkLub(A, I2, A);
- checkLub(A, J, A);
-
- checkLub(B, Object_, Object_);
- checkLub(B, A, Object_);
- checkLub(B, B, B);
- checkLub(B, C, B);
- checkLub(B, D, B);
- checkLub(B, I, B);
- checkLub(B, I2, B);
- checkLub(B, J, B);
-
- checkLub(C, Object_, Object_);
- checkLub(C, A, Object_);
- checkLub(C, B, B);
- checkLub(C, C, C);
- checkLub(C, D, C);
- checkLub(C, I, C);
- checkLub(C, I2, C);
- checkLub(C, J, C);
-
- checkLub(D, Object_, Object_);
- checkLub(D, A, Object_);
- checkLub(D, B, B);
- checkLub(D, C, C);
- checkLub(D, D, D);
- checkLub(D, I, D);
- checkLub(D, I2, D);
- checkLub(D, J, D);
-
- checkLub(I, Object_, Object_);
- checkLub(I, A, A);
- checkLub(I, B, B);
- checkLub(I, C, C);
- checkLub(I, D, D);
- checkLub(I, I, I);
- checkLub(I, I2, D);
- checkLub(I, J, D);
-
- checkLub(I2, Object_, Object_);
- checkLub(I2, A, A);
- checkLub(I2, B, B);
- checkLub(I2, C, C);
- checkLub(I2, D, D);
- checkLub(I2, I, D);
- checkLub(I2, I2, I2);
- checkLub(I2, J, D);
-
- checkLub(J, Object_, Object_);
- checkLub(J, A, A);
- checkLub(J, B, B);
- checkLub(J, C, C);
- checkLub(J, D, D);
- checkLub(J, I, D);
- checkLub(J, I2, D);
- checkLub(J, J, J);
- }));
-}
-
-void testFunction() {
- asyncTest(() => TypeEnvironment.create(r"""
- class A {}
- class B {}
- class C extends B {}
-
- typedef dynamic__();
- typedef void void__();
- typedef A A__();
- typedef B B__();
- typedef C C__();
-
- typedef void void__A_B(A a, B b);
- typedef void void__A_C(A a, C b);
- typedef void void__B_A(B a, A b);
- typedef void void__B_C(B a, C b);
-
- typedef void void___B([B a]);
- typedef void void___B_C([B a, C b]);
- typedef void void___C_C([C a, C b]);
-
- typedef void void____B({B a});
- typedef void void____B_C({B a, C b});
- typedef void void____C_C({C a, C b});
- """).then((env) {
-
- DartType Object_ = env['Object'];
- DartType Function_ = env['Function'];
- DartType dynamic__ = env['dynamic__'];
- DartType void__ = env['void__'];
- DartType A__ = env['A__'];
- DartType B__ = env['B__'];
- DartType C__ = env['C__'];
- DartType void__A_B = env['void__A_B'];
- DartType void__A_C = env['void__A_C'];
- DartType void__B_A = env['void__B_A'];
- DartType void__B_C = env['void__B_C'];
- DartType void___B = env['void___B'];
- DartType void___B_C = env['void___B_C'];
- DartType void___C_C = env['void___C_C'];
- DartType void____B = env['void____B'];
- DartType void____B_C = env['void____B_C'];
- DartType void____C_C = env['void____C_C'];
-
- // Types used only for checking results.
- DartType void_ = env['void'];
- DartType B = env['B'];
- DartType C = env['C'];
- FunctionType Object__ = env.functionType(Object_, []);
- FunctionType void__Object_Object =
- env.functionType(void_, [Object_, Object_]);
- FunctionType void__Object_B =
- env.functionType(void_, [Object_, B]);
- FunctionType void__Object_C =
- env.functionType(void_, [Object_, C]);
- FunctionType void__B_Object =
- env.functionType(void_, [B, Object_]);
-
- checkLub(DartType a, DartType b, DartType expectedLub) {
- DartType lub = env.computeLeastUpperBound(a, b);
- if (a != b) {
- expectedLub = expectedLub.unalias(env.compiler);
- lub = lub.unalias(env.compiler);
- }
- Expect.equals(expectedLub, lub,
- 'Unexpected lub(${a.unalias(env.compiler)},'
- '${b.unalias(env.compiler)}) = '
- '${lub}, expected ${expectedLub}');
- }
-
- checkLub(Object_, Object_, Object_);
- checkLub(Object_, Function_, Object_);
- checkLub(Object_, dynamic__, Object_);
- checkLub(Object_, void__, Object_);
- checkLub(Object_, A__, Object_);
- checkLub(Object_, B__, Object_);
- checkLub(Object_, C__, Object_);
- checkLub(Object_, void__A_B, Object_);
- checkLub(Object_, void__A_C, Object_);
- checkLub(Object_, void__B_A, Object_);
- checkLub(Object_, void__B_C, Object_);
- checkLub(Object_, void___B, Object_);
- checkLub(Object_, void___B_C, Object_);
- checkLub(Object_, void___C_C, Object_);
- checkLub(Object_, void____B, Object_);
- checkLub(Object_, void____B_C, Object_);
- checkLub(Object_, void____C_C, Object_);
-
- checkLub(Function_, Object_, Object_);
- checkLub(Function_, Function_, Function_);
- checkLub(Function_, dynamic__, Function_);
- checkLub(Function_, void__, Function_);
- checkLub(Function_, A__, Function_);
- checkLub(Function_, B__, Function_);
- checkLub(Function_, C__, Function_);
- checkLub(Function_, void__A_B, Function_);
- checkLub(Function_, void__A_C, Function_);
- checkLub(Function_, void__B_A, Function_);
- checkLub(Function_, void__B_C, Function_);
- checkLub(Function_, void___B, Function_);
- checkLub(Function_, void___B_C, Function_);
- checkLub(Function_, void___C_C, Function_);
- checkLub(Function_, void____B, Function_);
- checkLub(Function_, void____B_C, Function_);
- checkLub(Function_, void____C_C, Function_);
-
- checkLub(dynamic__, Object_, Object_);
- checkLub(dynamic__, Function_, Function_);
- checkLub(dynamic__, dynamic__, dynamic__);
- checkLub(dynamic__, void__, dynamic__);
- checkLub(dynamic__, A__, dynamic__);
- checkLub(dynamic__, B__, dynamic__);
- checkLub(dynamic__, C__, dynamic__);
- checkLub(dynamic__, void__A_B, Function_);
- checkLub(dynamic__, void__A_C, Function_);
- checkLub(dynamic__, void__B_A, Function_);
- checkLub(dynamic__, void__B_C, Function_);
- checkLub(dynamic__, void___B, dynamic__);
- checkLub(dynamic__, void___B_C, dynamic__);
- checkLub(dynamic__, void___C_C, dynamic__);
- checkLub(dynamic__, void____B, dynamic__);
- checkLub(dynamic__, void____B_C, dynamic__);
- checkLub(dynamic__, void____C_C, dynamic__);
-
- checkLub(void__, Object_, Object_);
- checkLub(void__, Function_, Function_);
- checkLub(void__, dynamic__, dynamic__);
- checkLub(void__, void__, void__);
- checkLub(void__, A__, void__);
- checkLub(void__, B__, void__);
- checkLub(void__, C__, void__);
- checkLub(void__, void__A_B, Function_);
- checkLub(void__, void__A_C, Function_);
- checkLub(void__, void__B_A, Function_);
- checkLub(void__, void__B_C, Function_);
- checkLub(void__, void___B, void__);
- checkLub(void__, void___B_C, void__);
- checkLub(void__, void___C_C, void__);
- checkLub(void__, void____B, void__);
- checkLub(void__, void____B_C, void__);
- checkLub(void__, void____C_C, void__);
-
- checkLub(A__, Object_, Object_);
- checkLub(A__, Function_, Function_);
- checkLub(A__, dynamic__, dynamic__);
- checkLub(A__, void__, void__);
- checkLub(A__, A__, A__);
- checkLub(A__, B__, Object__);
- checkLub(A__, C__, Object__);
- checkLub(A__, void__A_B, Function_);
- checkLub(A__, void__A_C, Function_);
- checkLub(A__, void__B_A, Function_);
- checkLub(A__, void__B_C, Function_);
- checkLub(A__, void___B, void__);
- checkLub(A__, void___B_C, void__);
- checkLub(A__, void___C_C, void__);
- checkLub(A__, void____B, void__);
- checkLub(A__, void____B_C, void__);
- checkLub(A__, void____C_C, void__);
-
- checkLub(B__, Object_, Object_);
- checkLub(B__, Function_, Function_);
- checkLub(B__, dynamic__, dynamic__);
- checkLub(B__, void__, void__);
- checkLub(B__, A__, Object__);
- checkLub(B__, B__, B__);
- checkLub(B__, C__, B__);
- checkLub(B__, void__A_B, Function_);
- checkLub(B__, void__A_C, Function_);
- checkLub(B__, void__B_A, Function_);
- checkLub(B__, void__B_C, Function_);
- checkLub(B__, void___B, void__);
- checkLub(B__, void___B_C, void__);
- checkLub(B__, void___C_C, void__);
- checkLub(B__, void____B, void__);
- checkLub(B__, void____B_C, void__);
- checkLub(B__, void____C_C, void__);
-
- checkLub(C__, Object_, Object_);
- checkLub(C__, Function_, Function_);
- checkLub(C__, dynamic__, dynamic__);
- checkLub(C__, void__, void__);
- checkLub(C__, A__, Object__);
- checkLub(C__, B__, B__);
- checkLub(C__, C__, C__);
- checkLub(C__, void__A_B, Function_);
- checkLub(C__, void__A_C, Function_);
- checkLub(C__, void__B_A, Function_);
- checkLub(C__, void__B_C, Function_);
- checkLub(C__, void___B, void__);
- checkLub(C__, void___B_C, void__);
- checkLub(C__, void___C_C, void__);
- checkLub(C__, void____B, void__);
- checkLub(C__, void____B_C, void__);
- checkLub(C__, void____C_C, void__);
-
- checkLub(void__A_B, Object_, Object_);
- checkLub(void__A_B, Function_, Function_);
- checkLub(void__A_B, dynamic__, Function_);
- checkLub(void__A_B, void__, Function_);
- checkLub(void__A_B, A__, Function_);
- checkLub(void__A_B, B__, Function_);
- checkLub(void__A_B, C__, Function_);
- checkLub(void__A_B, void__A_B, void__A_B);
- checkLub(void__A_B, void__A_C, void__A_B);
- checkLub(void__A_B, void__B_A, void__Object_Object);
- checkLub(void__A_B, void__B_C, void__Object_B);
- checkLub(void__A_B, void___B, Function_);
- checkLub(void__A_B, void___B_C, Function_);
- checkLub(void__A_B, void___C_C, Function_);
- checkLub(void__A_B, void____B, Function_);
- checkLub(void__A_B, void____B_C, Function_);
- checkLub(void__A_B, void____C_C, Function_);
-
- checkLub(void__A_C, Object_, Object_);
- checkLub(void__A_C, Function_, Function_);
- checkLub(void__A_C, dynamic__, Function_);
- checkLub(void__A_C, void__, Function_);
- checkLub(void__A_C, A__, Function_);
- checkLub(void__A_C, B__, Function_);
- checkLub(void__A_C, C__, Function_);
- checkLub(void__A_C, void__A_B, void__A_B);
- checkLub(void__A_C, void__A_C, void__A_C);
- checkLub(void__A_C, void__B_A, void__Object_Object);
- checkLub(void__A_C, void__B_C, void__Object_C);
- checkLub(void__A_C, void___B, Function_);
- checkLub(void__A_C, void___B_C, Function_);
- checkLub(void__A_C, void___C_C, Function_);
- checkLub(void__A_C, void____B, Function_);
- checkLub(void__A_C, void____B_C, Function_);
- checkLub(void__A_C, void____C_C, Function_);
-
- checkLub(void__B_A, Object_, Object_);
- checkLub(void__B_A, Function_, Function_);
- checkLub(void__B_A, dynamic__, Function_);
- checkLub(void__B_A, void__, Function_);
- checkLub(void__B_A, A__, Function_);
- checkLub(void__B_A, B__, Function_);
- checkLub(void__B_A, C__, Function_);
- checkLub(void__B_A, void__A_B, void__Object_Object);
- checkLub(void__B_A, void__A_C, void__Object_Object);
- checkLub(void__B_A, void__B_A, void__B_A);
- checkLub(void__B_A, void__B_C, void__B_Object);
- checkLub(void__B_A, void___B, Function_);
- checkLub(void__B_A, void___B_C, Function_);
- checkLub(void__B_A, void___C_C, Function_);
- checkLub(void__B_A, void____B, Function_);
- checkLub(void__B_A, void____B_C, Function_);
- checkLub(void__B_A, void____C_C, Function_);
-
- checkLub(void__B_C, Object_, Object_);
- checkLub(void__B_C, Function_, Function_);
- checkLub(void__B_C, dynamic__, Function_);
- checkLub(void__B_C, void__, Function_);
- checkLub(void__B_C, A__, Function_);
- checkLub(void__B_C, B__, Function_);
- checkLub(void__B_C, C__, Function_);
- checkLub(void__B_C, void__A_B, void__Object_B);
- checkLub(void__B_C, void__A_C, void__Object_C);
- checkLub(void__B_C, void__B_A, void__B_Object);
- checkLub(void__B_C, void__B_C, void__B_C);
- checkLub(void__B_C, void___B, Function_);
- checkLub(void__B_C, void___B_C, Function_);
- checkLub(void__B_C, void___C_C, Function_);
- checkLub(void__B_C, void____B, Function_);
- checkLub(void__B_C, void____B_C, Function_);
- checkLub(void__B_C, void____C_C, Function_);
-
- checkLub(void___B, Object_, Object_);
- checkLub(void___B, Function_, Function_);
- checkLub(void___B, dynamic__, dynamic__);
- checkLub(void___B, void__, void__);
- checkLub(void___B, A__, void__);
- checkLub(void___B, B__, void__);
- checkLub(void___B, C__, void__);
- checkLub(void___B, void__A_B, Function_);
- checkLub(void___B, void__A_C, Function_);
- checkLub(void___B, void__B_A, Function_);
- checkLub(void___B, void__B_C, Function_);
- checkLub(void___B, void___B, void___B);
- checkLub(void___B, void___B_C, void___B);
- checkLub(void___B, void___C_C, void___B);
- checkLub(void___B, void____B, void__);
- checkLub(void___B, void____B_C, void__);
- checkLub(void___B, void____C_C, void__);
-
- checkLub(void___B_C, Object_, Object_);
- checkLub(void___B_C, Function_, Function_);
- checkLub(void___B_C, dynamic__, dynamic__);
- checkLub(void___B_C, void__, void__);
- checkLub(void___B_C, A__, void__);
- checkLub(void___B_C, B__, void__);
- checkLub(void___B_C, C__, void__);
- checkLub(void___B_C, void__A_B, Function_);
- checkLub(void___B_C, void__A_C, Function_);
- checkLub(void___B_C, void__B_A, Function_);
- checkLub(void___B_C, void__B_C, Function_);
- checkLub(void___B_C, void___B, void___B);
- checkLub(void___B_C, void___B_C, void___B_C);
- checkLub(void___B_C, void___C_C, void___B_C);
- checkLub(void___B_C, void____B, void__);
- checkLub(void___B_C, void____B_C, void__);
- checkLub(void___B_C, void____C_C, void__);
-
- checkLub(void___C_C, Object_, Object_);
- checkLub(void___C_C, Function_, Function_);
- checkLub(void___C_C, dynamic__, dynamic__);
- checkLub(void___C_C, void__, void__);
- checkLub(void___C_C, A__, void__);
- checkLub(void___C_C, B__, void__);
- checkLub(void___C_C, C__, void__);
- checkLub(void___C_C, void__A_B, Function_);
- checkLub(void___C_C, void__A_C, Function_);
- checkLub(void___C_C, void__B_A, Function_);
- checkLub(void___C_C, void__B_C, Function_);
- checkLub(void___C_C, void___B, void___B);
- checkLub(void___C_C, void___B_C, void___B_C);
- checkLub(void___C_C, void___C_C, void___C_C);
- checkLub(void___C_C, void____B, void__);
- checkLub(void___C_C, void____B_C, void__);
- checkLub(void___C_C, void____C_C, void__);
-
- checkLub(void____B, Object_, Object_);
- checkLub(void____B, Function_, Function_);
- checkLub(void____B, dynamic__, dynamic__);
- checkLub(void____B, void__, void__);
- checkLub(void____B, A__, void__);
- checkLub(void____B, B__, void__);
- checkLub(void____B, C__, void__);
- checkLub(void____B, void__A_B, Function_);
- checkLub(void____B, void__A_C, Function_);
- checkLub(void____B, void__B_A, Function_);
- checkLub(void____B, void__B_C, Function_);
- checkLub(void____B, void___B, void__);
- checkLub(void____B, void___B_C, void__);
- checkLub(void____B, void___C_C, void__);
- checkLub(void____B, void____B, void____B);
- checkLub(void____B, void____B_C, void____B);
- checkLub(void____B, void____C_C, void____B);
-
- checkLub(void____B_C, Object_, Object_);
- checkLub(void____B_C, Function_, Function_);
- checkLub(void____B_C, dynamic__, dynamic__);
- checkLub(void____B_C, void__, void__);
- checkLub(void____B_C, A__, void__);
- checkLub(void____B_C, B__, void__);
- checkLub(void____B_C, C__, void__);
- checkLub(void____B_C, void__A_B, Function_);
- checkLub(void____B_C, void__A_C, Function_);
- checkLub(void____B_C, void__B_A, Function_);
- checkLub(void____B_C, void__B_C, Function_);
- checkLub(void____B_C, void___B, void__);
- checkLub(void____B_C, void___B_C, void__);
- checkLub(void____B_C, void___C_C, void__);
- checkLub(void____B_C, void____B, void____B);
- checkLub(void____B_C, void____B_C, void____B_C);
- checkLub(void____B_C, void____C_C, void____B_C);
-
- checkLub(void____C_C, Object_, Object_);
- checkLub(void____C_C, Function_, Function_);
- checkLub(void____C_C, dynamic__, dynamic__);
- checkLub(void____C_C, void__, void__);
- checkLub(void____C_C, A__, void__);
- checkLub(void____C_C, B__, void__);
- checkLub(void____C_C, C__, void__);
- checkLub(void____C_C, void__A_B, Function_);
- checkLub(void____C_C, void__A_C, Function_);
- checkLub(void____C_C, void__B_A, Function_);
- checkLub(void____C_C, void__B_C, Function_);
- checkLub(void____C_C, void___B, void__);
- checkLub(void____C_C, void___B_C, void__);
- checkLub(void____C_C, void___C_C, void__);
- checkLub(void____C_C, void____B, void____B);
- checkLub(void____C_C, void____B_C, void____B_C);
- checkLub(void____C_C, void____C_C, void____C_C);
- }));
-}
-
-void testTypeVariable() {
- asyncTest(() => TypeEnvironment.create(r"""
- class A {}
- class B {}
- class C extends B {}
- class I<S extends A,
- T extends B,
- U extends C,
- V extends T,
- W extends V,
- X extends T> {}
- """).then((env) {
-
- // A B
- // | / \
- // S T C
- // / \ \
- // V X U
- // /
- // W
-
- DartType Object_ = env['Object'];
- DartType A = env['A'];
- DartType B = env['B'];
- DartType C = env['C'];
- ClassElement I = env.getElement('I');
- DartType S = I.typeVariables[0];
- DartType T = I.typeVariables[1];
- DartType U = I.typeVariables[2];
- DartType V = I.typeVariables[3];
- DartType W = I.typeVariables[4];
- DartType X = I.typeVariables[5];
-
- checkLub(DartType a, DartType b, DartType expectedLub) {
- DartType lub = env.computeLeastUpperBound(a, b);
- Expect.equals(expectedLub, lub,
- 'Unexpected lub($a,$b) = $lub, expected $expectedLub');
- }
-
- checkLub(Object_, Object_, Object_);
- checkLub(Object_, A, Object_);
- checkLub(Object_, B, Object_);
- checkLub(Object_, C, Object_);
- checkLub(Object_, S, Object_);
- checkLub(Object_, T, Object_);
- checkLub(Object_, U, Object_);
- checkLub(Object_, V, Object_);
- checkLub(Object_, W, Object_);
- checkLub(Object_, X, Object_);
-
- checkLub(A, Object_, Object_);
- checkLub(A, A, A);
- checkLub(A, B, Object_);
- checkLub(A, C, Object_);
- checkLub(A, S, A);
- checkLub(A, T, Object_);
- checkLub(A, U, Object_);
- checkLub(A, V, Object_);
- checkLub(A, W, Object_);
- checkLub(A, X, Object_);
-
- checkLub(B, Object_, Object_);
- checkLub(B, A, Object_);
- checkLub(B, B, B);
- checkLub(B, C, B);
- checkLub(B, S, Object_);
- checkLub(B, T, B);
- checkLub(B, U, B);
- checkLub(B, V, B);
- checkLub(B, W, B);
- checkLub(B, X, B);
-
- checkLub(C, Object_, Object_);
- checkLub(C, A, Object_);
- checkLub(C, B, B);
- checkLub(C, C, C);
- checkLub(C, S, Object_);
- checkLub(C, T, B);
- checkLub(C, U, C);
- checkLub(C, V, B);
- checkLub(C, W, B);
- checkLub(C, X, B);
-
- checkLub(S, Object_, Object_);
- checkLub(S, A, A);
- checkLub(S, B, Object_);
- checkLub(S, C, Object_);
- checkLub(S, S, S);
- checkLub(S, T, Object_);
- checkLub(S, U, Object_);
- checkLub(S, V, Object_);
- checkLub(S, W, Object_);
- checkLub(S, X, Object_);
-
- checkLub(T, Object_, Object_);
- checkLub(T, A, Object_);
- checkLub(T, B, B);
- checkLub(T, C, B);
- checkLub(T, S, Object_);
- checkLub(T, T, T);
- checkLub(T, U, B);
- checkLub(T, V, T);
- checkLub(T, W, T);
- checkLub(T, X, T);
-
- checkLub(U, Object_, Object_);
- checkLub(U, A, Object_);
- checkLub(U, B, B);
- checkLub(U, C, C);
- checkLub(U, S, Object_);
- checkLub(U, T, B);
- checkLub(U, U, U);
- checkLub(U, V, B);
- checkLub(U, W, B);
- checkLub(U, X, B);
-
- checkLub(V, Object_, Object_);
- checkLub(V, A, Object_);
- checkLub(V, B, B);
- checkLub(V, C, B);
- checkLub(V, S, Object_);
- checkLub(V, T, T);
- checkLub(V, U, B);
- checkLub(V, V, V);
- checkLub(V, W, V);
- checkLub(V, X, T);
-
- checkLub(W, Object_, Object_);
- checkLub(W, A, Object_);
- checkLub(W, B, B);
- checkLub(W, C, B);
- checkLub(W, S, Object_);
- checkLub(W, T, T);
- checkLub(W, U, B);
- checkLub(W, V, V);
- checkLub(W, W, W);
- checkLub(W, X, T);
-
- checkLub(X, Object_, Object_);
- checkLub(X, A, Object_);
- checkLub(X, B, B);
- checkLub(X, C, B);
- checkLub(X, S, Object_);
- checkLub(X, T, T);
- checkLub(X, U, B);
- checkLub(X, V, T);
- checkLub(X, W, T);
- checkLub(X, X, X);
- }));
-}
-
-
+// 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 subtype_test;
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'type_test_helper.dart';
+import 'package:compiler/src/dart_types.dart';
+import "package:compiler/src/elements/elements.dart"
+ show Element, ClassElement;
+import 'package:compiler/src/util/util.dart';
+
+void main() {
+ testInterface1();
+ testInterface2();
+ testGeneric();
+ testMixin();
+ testFunction();
+ testTypeVariable();
+}
+
+void testInterface1() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class A {} // A and B have equal depth.
+ class B {}
+ class I implements A, B {}
+ class J implements A, B {}
+ """).then((env) {
+
+ DartType Object_ = env['Object'];
+ DartType A = env['A'];
+ DartType B = env['B'];
+ DartType I = env['I'];
+ DartType J = env['J'];
+
+ checkLub(DartType a, DartType b, DartType expect) {
+ DartType lub = env.computeLeastUpperBound(a, b);
+ Expect.equals(expect, lub,
+ 'Unexpected lub($a,$b) = $lub, expected $expect.');
+ }
+
+ checkLub(Object_, Object_, Object_);
+ checkLub(Object_, A, Object_);
+ checkLub(Object_, B, Object_);
+ checkLub(Object_, I, Object_);
+ checkLub(Object_, J, Object_);
+
+ checkLub(A, Object_, Object_);
+ checkLub(A, A, A);
+ checkLub(A, B, Object_);
+ checkLub(A, I, A);
+ checkLub(A, J, A);
+
+ checkLub(B, Object_, Object_);
+ checkLub(B, A, Object_);
+ checkLub(B, B, B);
+ checkLub(B, I, B);
+ checkLub(B, J, B);
+
+ checkLub(I, Object_, Object_);
+ checkLub(I, A, A);
+ checkLub(I, B, B);
+ checkLub(I, I, I);
+ checkLub(I, J, Object_);
+
+ checkLub(J, Object_, Object_);
+ checkLub(J, A, A);
+ checkLub(J, B, B);
+ checkLub(J, I, Object_);
+ checkLub(J, J, J);
+ }));
+}
+
+void testInterface2() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class A {}
+ class B {}
+ class C extends B {} // This makes C have higher depth than A.
+ class I implements A, C {}
+ class J implements A, C {}
+ """).then((env) {
+
+ DartType Object_ = env['Object'];
+ DartType A = env['A'];
+ DartType B = env['B'];
+ DartType C = env['C'];
+ DartType I = env['I'];
+ DartType J = env['J'];
+
+ checkLub(DartType a, DartType b, DartType expectedLub) {
+ DartType lub = env.computeLeastUpperBound(a, b);
+ Expect.equals(expectedLub, lub,
+ 'Unexpected lub($a,$b) = $lub, expected $expectedLub');
+ }
+
+ checkLub(Object_, Object_, Object_);
+ checkLub(Object_, A, Object_);
+ checkLub(Object_, B, Object_);
+ checkLub(Object_, C, Object_);
+ checkLub(Object_, I, Object_);
+ checkLub(Object_, J, Object_);
+
+ checkLub(A, Object_, Object_);
+ checkLub(A, A, A);
+ checkLub(A, B, Object_);
+ checkLub(A, C, Object_);
+ checkLub(A, I, A);
+ checkLub(A, J, A);
+
+ checkLub(B, Object_, Object_);
+ checkLub(B, A, Object_);
+ checkLub(B, B, B);
+ checkLub(B, C, B);
+ checkLub(B, I, B);
+ checkLub(B, J, B);
+
+ checkLub(C, Object_, Object_);
+ checkLub(C, A, Object_);
+ checkLub(C, B, B);
+ checkLub(C, C, C);
+ checkLub(C, I, C);
+ checkLub(C, J, C);
+
+ checkLub(I, Object_, Object_);
+ checkLub(I, A, A);
+ checkLub(I, B, B);
+ checkLub(I, C, C);
+ checkLub(I, I, I);
+ checkLub(I, J, C);
+
+ checkLub(J, Object_, Object_);
+ checkLub(J, A, A);
+ checkLub(J, B, B);
+ checkLub(J, C, C);
+ checkLub(J, I, C);
+ checkLub(J, J, J);
+ }));
+}
+
+void testGeneric() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class A {}
+ class B {}
+ class C extends B {}
+ class I<T> {}
+ """).then((env) {
+
+ DartType Object_ = env['Object'];
+ DartType A = env['A'];
+ DartType B = env['B'];
+ DartType C = env['C'];
+ ClassElement I = env.getElement('I');
+ DartType I_A = instantiate(I, [A]);
+ DartType I_B = instantiate(I, [B]);
+ DartType I_C = instantiate(I, [C]);
+
+ checkLub(DartType a, DartType b, DartType expectedLub) {
+ DartType lub = env.computeLeastUpperBound(a, b);
+ Expect.equals(expectedLub, lub,
+ 'Unexpected lub($a,$b) = $lub, expected $expectedLub');
+ }
+
+ checkLub(Object_, Object_, Object_);
+ checkLub(Object_, A, Object_);
+ checkLub(Object_, B, Object_);
+ checkLub(Object_, C, Object_);
+ checkLub(Object_, I_A, Object_);
+ checkLub(Object_, I_B, Object_);
+ checkLub(Object_, I_C, Object_);
+
+ checkLub(A, Object_, Object_);
+ checkLub(A, A, A);
+ checkLub(A, B, Object_);
+ checkLub(A, C, Object_);
+ checkLub(A, I_A, Object_);
+ checkLub(A, I_B, Object_);
+ checkLub(A, I_C, Object_);
+
+ checkLub(B, Object_, Object_);
+ checkLub(B, A, Object_);
+ checkLub(B, B, B);
+ checkLub(B, C, B);
+ checkLub(B, I_A, Object_);
+ checkLub(B, I_B, Object_);
+ checkLub(B, I_C, Object_);
+
+ checkLub(C, Object_, Object_);
+ checkLub(C, A, Object_);
+ checkLub(C, B, B);
+ checkLub(C, C, C);
+ checkLub(C, I_A, Object_);
+ checkLub(C, I_B, Object_);
+ checkLub(C, I_C, Object_);
+
+ checkLub(I_A, Object_, Object_);
+ checkLub(I_A, A, Object_);
+ checkLub(I_A, B, Object_);
+ checkLub(I_A, C, Object_);
+ checkLub(I_A, I_A, I_A);
+ checkLub(I_A, I_B, Object_);
+ checkLub(I_A, I_C, Object_);
+
+ checkLub(I_B, Object_, Object_);
+ checkLub(I_B, A, Object_);
+ checkLub(I_B, B, Object_);
+ checkLub(I_B, C, Object_);
+ checkLub(I_B, I_A, Object_);
+ checkLub(I_B, I_B, I_B);
+ checkLub(I_B, I_C, Object_);
+
+ checkLub(I_C, Object_, Object_);
+ checkLub(I_C, A, Object_);
+ checkLub(I_C, B, Object_);
+ checkLub(I_C, C, Object_);
+ checkLub(I_C, I_A, Object_);
+ checkLub(I_C, I_B, Object_);
+ checkLub(I_C, I_C, I_C);
+ }));
+}
+
+void testMixin() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class A {}
+ class B {}
+ class C extends B {}
+ class D extends C {} // This makes D have higher depth than Object+A.
+ class I extends Object with A, B implements A, D {}
+ class I2 extends Object with A, B implements A, D {}
+ class J extends Object with B, A implements A, D {}
+ """).then((env) {
+
+ DartType Object_ = env['Object'];
+ DartType A = env['A'];
+ DartType B = env['B'];
+ DartType C = env['C'];
+ DartType D = env['D'];
+ DartType I = env['I'];
+ DartType I2 = env['I2'];
+ DartType J = env['J'];
+
+ checkLub(DartType a, DartType b, DartType expectedLub) {
+ DartType lub = env.computeLeastUpperBound(a, b);
+ Expect.equals(expectedLub, lub,
+ 'Unexpected lub($a,$b) = $lub, expected $expectedLub');
+ }
+
+ checkLub(Object_, Object_, Object_);
+ checkLub(Object_, A, Object_);
+ checkLub(Object_, B, Object_);
+ checkLub(Object_, C, Object_);
+ checkLub(Object_, D, Object_);
+ checkLub(Object_, I, Object_);
+ checkLub(Object_, I2, Object_);
+ checkLub(Object_, J, Object_);
+
+ checkLub(A, Object_, Object_);
+ checkLub(A, A, A);
+ checkLub(A, B, Object_);
+ checkLub(A, C, Object_);
+ checkLub(A, D, Object_);
+ checkLub(A, I, A);
+ checkLub(A, I2, A);
+ checkLub(A, J, A);
+
+ checkLub(B, Object_, Object_);
+ checkLub(B, A, Object_);
+ checkLub(B, B, B);
+ checkLub(B, C, B);
+ checkLub(B, D, B);
+ checkLub(B, I, B);
+ checkLub(B, I2, B);
+ checkLub(B, J, B);
+
+ checkLub(C, Object_, Object_);
+ checkLub(C, A, Object_);
+ checkLub(C, B, B);
+ checkLub(C, C, C);
+ checkLub(C, D, C);
+ checkLub(C, I, C);
+ checkLub(C, I2, C);
+ checkLub(C, J, C);
+
+ checkLub(D, Object_, Object_);
+ checkLub(D, A, Object_);
+ checkLub(D, B, B);
+ checkLub(D, C, C);
+ checkLub(D, D, D);
+ checkLub(D, I, D);
+ checkLub(D, I2, D);
+ checkLub(D, J, D);
+
+ checkLub(I, Object_, Object_);
+ checkLub(I, A, A);
+ checkLub(I, B, B);
+ checkLub(I, C, C);
+ checkLub(I, D, D);
+ checkLub(I, I, I);
+ checkLub(I, I2, D);
+ checkLub(I, J, D);
+
+ checkLub(I2, Object_, Object_);
+ checkLub(I2, A, A);
+ checkLub(I2, B, B);
+ checkLub(I2, C, C);
+ checkLub(I2, D, D);
+ checkLub(I2, I, D);
+ checkLub(I2, I2, I2);
+ checkLub(I2, J, D);
+
+ checkLub(J, Object_, Object_);
+ checkLub(J, A, A);
+ checkLub(J, B, B);
+ checkLub(J, C, C);
+ checkLub(J, D, D);
+ checkLub(J, I, D);
+ checkLub(J, I2, D);
+ checkLub(J, J, J);
+ }));
+}
+
+void testFunction() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class A {}
+ class B {}
+ class C extends B {}
+
+ typedef dynamic__();
+ typedef void void__();
+ typedef A A__();
+ typedef B B__();
+ typedef C C__();
+
+ typedef void void__A_B(A a, B b);
+ typedef void void__A_C(A a, C b);
+ typedef void void__B_A(B a, A b);
+ typedef void void__B_C(B a, C b);
+
+ typedef void void___B([B a]);
+ typedef void void___B_C([B a, C b]);
+ typedef void void___C_C([C a, C b]);
+
+ typedef void void____B({B a});
+ typedef void void____B_C({B a, C b});
+ typedef void void____C_C({C a, C b});
+ """).then((env) {
+
+ DartType Object_ = env['Object'];
+ DartType Function_ = env['Function'];
+ DartType dynamic__ = env['dynamic__'];
+ DartType void__ = env['void__'];
+ DartType A__ = env['A__'];
+ DartType B__ = env['B__'];
+ DartType C__ = env['C__'];
+ DartType void__A_B = env['void__A_B'];
+ DartType void__A_C = env['void__A_C'];
+ DartType void__B_A = env['void__B_A'];
+ DartType void__B_C = env['void__B_C'];
+ DartType void___B = env['void___B'];
+ DartType void___B_C = env['void___B_C'];
+ DartType void___C_C = env['void___C_C'];
+ DartType void____B = env['void____B'];
+ DartType void____B_C = env['void____B_C'];
+ DartType void____C_C = env['void____C_C'];
+
+ // Types used only for checking results.
+ DartType void_ = env['void'];
+ DartType B = env['B'];
+ DartType C = env['C'];
+ FunctionType Object__ = env.functionType(Object_, []);
+ FunctionType void__Object_Object =
+ env.functionType(void_, [Object_, Object_]);
+ FunctionType void__Object_B =
+ env.functionType(void_, [Object_, B]);
+ FunctionType void__Object_C =
+ env.functionType(void_, [Object_, C]);
+ FunctionType void__B_Object =
+ env.functionType(void_, [B, Object_]);
+
+ checkLub(DartType a, DartType b, DartType expectedLub) {
+ DartType lub = env.computeLeastUpperBound(a, b);
+ if (a != b) {
+ expectedLub = expectedLub.unalias(env.compiler);
+ lub = lub.unalias(env.compiler);
+ }
+ Expect.equals(expectedLub, lub,
+ 'Unexpected lub(${a.unalias(env.compiler)},'
+ '${b.unalias(env.compiler)}) = '
+ '${lub}, expected ${expectedLub}');
+ }
+
+ checkLub(Object_, Object_, Object_);
+ checkLub(Object_, Function_, Object_);
+ checkLub(Object_, dynamic__, Object_);
+ checkLub(Object_, void__, Object_);
+ checkLub(Object_, A__, Object_);
+ checkLub(Object_, B__, Object_);
+ checkLub(Object_, C__, Object_);
+ checkLub(Object_, void__A_B, Object_);
+ checkLub(Object_, void__A_C, Object_);
+ checkLub(Object_, void__B_A, Object_);
+ checkLub(Object_, void__B_C, Object_);
+ checkLub(Object_, void___B, Object_);
+ checkLub(Object_, void___B_C, Object_);
+ checkLub(Object_, void___C_C, Object_);
+ checkLub(Object_, void____B, Object_);
+ checkLub(Object_, void____B_C, Object_);
+ checkLub(Object_, void____C_C, Object_);
+
+ checkLub(Function_, Object_, Object_);
+ checkLub(Function_, Function_, Function_);
+ checkLub(Function_, dynamic__, Function_);
+ checkLub(Function_, void__, Function_);
+ checkLub(Function_, A__, Function_);
+ checkLub(Function_, B__, Function_);
+ checkLub(Function_, C__, Function_);
+ checkLub(Function_, void__A_B, Function_);
+ checkLub(Function_, void__A_C, Function_);
+ checkLub(Function_, void__B_A, Function_);
+ checkLub(Function_, void__B_C, Function_);
+ checkLub(Function_, void___B, Function_);
+ checkLub(Function_, void___B_C, Function_);
+ checkLub(Function_, void___C_C, Function_);
+ checkLub(Function_, void____B, Function_);
+ checkLub(Function_, void____B_C, Function_);
+ checkLub(Function_, void____C_C, Function_);
+
+ checkLub(dynamic__, Object_, Object_);
+ checkLub(dynamic__, Function_, Function_);
+ checkLub(dynamic__, dynamic__, dynamic__);
+ checkLub(dynamic__, void__, dynamic__);
+ checkLub(dynamic__, A__, dynamic__);
+ checkLub(dynamic__, B__, dynamic__);
+ checkLub(dynamic__, C__, dynamic__);
+ checkLub(dynamic__, void__A_B, Function_);
+ checkLub(dynamic__, void__A_C, Function_);
+ checkLub(dynamic__, void__B_A, Function_);
+ checkLub(dynamic__, void__B_C, Function_);
+ checkLub(dynamic__, void___B, dynamic__);
+ checkLub(dynamic__, void___B_C, dynamic__);
+ checkLub(dynamic__, void___C_C, dynamic__);
+ checkLub(dynamic__, void____B, dynamic__);
+ checkLub(dynamic__, void____B_C, dynamic__);
+ checkLub(dynamic__, void____C_C, dynamic__);
+
+ checkLub(void__, Object_, Object_);
+ checkLub(void__, Function_, Function_);
+ checkLub(void__, dynamic__, dynamic__);
+ checkLub(void__, void__, void__);
+ checkLub(void__, A__, void__);
+ checkLub(void__, B__, void__);
+ checkLub(void__, C__, void__);
+ checkLub(void__, void__A_B, Function_);
+ checkLub(void__, void__A_C, Function_);
+ checkLub(void__, void__B_A, Function_);
+ checkLub(void__, void__B_C, Function_);
+ checkLub(void__, void___B, void__);
+ checkLub(void__, void___B_C, void__);
+ checkLub(void__, void___C_C, void__);
+ checkLub(void__, void____B, void__);
+ checkLub(void__, void____B_C, void__);
+ checkLub(void__, void____C_C, void__);
+
+ checkLub(A__, Object_, Object_);
+ checkLub(A__, Function_, Function_);
+ checkLub(A__, dynamic__, dynamic__);
+ checkLub(A__, void__, void__);
+ checkLub(A__, A__, A__);
+ checkLub(A__, B__, Object__);
+ checkLub(A__, C__, Object__);
+ checkLub(A__, void__A_B, Function_);
+ checkLub(A__, void__A_C, Function_);
+ checkLub(A__, void__B_A, Function_);
+ checkLub(A__, void__B_C, Function_);
+ checkLub(A__, void___B, void__);
+ checkLub(A__, void___B_C, void__);
+ checkLub(A__, void___C_C, void__);
+ checkLub(A__, void____B, void__);
+ checkLub(A__, void____B_C, void__);
+ checkLub(A__, void____C_C, void__);
+
+ checkLub(B__, Object_, Object_);
+ checkLub(B__, Function_, Function_);
+ checkLub(B__, dynamic__, dynamic__);
+ checkLub(B__, void__, void__);
+ checkLub(B__, A__, Object__);
+ checkLub(B__, B__, B__);
+ checkLub(B__, C__, B__);
+ checkLub(B__, void__A_B, Function_);
+ checkLub(B__, void__A_C, Function_);
+ checkLub(B__, void__B_A, Function_);
+ checkLub(B__, void__B_C, Function_);
+ checkLub(B__, void___B, void__);
+ checkLub(B__, void___B_C, void__);
+ checkLub(B__, void___C_C, void__);
+ checkLub(B__, void____B, void__);
+ checkLub(B__, void____B_C, void__);
+ checkLub(B__, void____C_C, void__);
+
+ checkLub(C__, Object_, Object_);
+ checkLub(C__, Function_, Function_);
+ checkLub(C__, dynamic__, dynamic__);
+ checkLub(C__, void__, void__);
+ checkLub(C__, A__, Object__);
+ checkLub(C__, B__, B__);
+ checkLub(C__, C__, C__);
+ checkLub(C__, void__A_B, Function_);
+ checkLub(C__, void__A_C, Function_);
+ checkLub(C__, void__B_A, Function_);
+ checkLub(C__, void__B_C, Function_);
+ checkLub(C__, void___B, void__);
+ checkLub(C__, void___B_C, void__);
+ checkLub(C__, void___C_C, void__);
+ checkLub(C__, void____B, void__);
+ checkLub(C__, void____B_C, void__);
+ checkLub(C__, void____C_C, void__);
+
+ checkLub(void__A_B, Object_, Object_);
+ checkLub(void__A_B, Function_, Function_);
+ checkLub(void__A_B, dynamic__, Function_);
+ checkLub(void__A_B, void__, Function_);
+ checkLub(void__A_B, A__, Function_);
+ checkLub(void__A_B, B__, Function_);
+ checkLub(void__A_B, C__, Function_);
+ checkLub(void__A_B, void__A_B, void__A_B);
+ checkLub(void__A_B, void__A_C, void__A_B);
+ checkLub(void__A_B, void__B_A, void__Object_Object);
+ checkLub(void__A_B, void__B_C, void__Object_B);
+ checkLub(void__A_B, void___B, Function_);
+ checkLub(void__A_B, void___B_C, Function_);
+ checkLub(void__A_B, void___C_C, Function_);
+ checkLub(void__A_B, void____B, Function_);
+ checkLub(void__A_B, void____B_C, Function_);
+ checkLub(void__A_B, void____C_C, Function_);
+
+ checkLub(void__A_C, Object_, Object_);
+ checkLub(void__A_C, Function_, Function_);
+ checkLub(void__A_C, dynamic__, Function_);
+ checkLub(void__A_C, void__, Function_);
+ checkLub(void__A_C, A__, Function_);
+ checkLub(void__A_C, B__, Function_);
+ checkLub(void__A_C, C__, Function_);
+ checkLub(void__A_C, void__A_B, void__A_B);
+ checkLub(void__A_C, void__A_C, void__A_C);
+ checkLub(void__A_C, void__B_A, void__Object_Object);
+ checkLub(void__A_C, void__B_C, void__Object_C);
+ checkLub(void__A_C, void___B, Function_);
+ checkLub(void__A_C, void___B_C, Function_);
+ checkLub(void__A_C, void___C_C, Function_);
+ checkLub(void__A_C, void____B, Function_);
+ checkLub(void__A_C, void____B_C, Function_);
+ checkLub(void__A_C, void____C_C, Function_);
+
+ checkLub(void__B_A, Object_, Object_);
+ checkLub(void__B_A, Function_, Function_);
+ checkLub(void__B_A, dynamic__, Function_);
+ checkLub(void__B_A, void__, Function_);
+ checkLub(void__B_A, A__, Function_);
+ checkLub(void__B_A, B__, Function_);
+ checkLub(void__B_A, C__, Function_);
+ checkLub(void__B_A, void__A_B, void__Object_Object);
+ checkLub(void__B_A, void__A_C, void__Object_Object);
+ checkLub(void__B_A, void__B_A, void__B_A);
+ checkLub(void__B_A, void__B_C, void__B_Object);
+ checkLub(void__B_A, void___B, Function_);
+ checkLub(void__B_A, void___B_C, Function_);
+ checkLub(void__B_A, void___C_C, Function_);
+ checkLub(void__B_A, void____B, Function_);
+ checkLub(void__B_A, void____B_C, Function_);
+ checkLub(void__B_A, void____C_C, Function_);
+
+ checkLub(void__B_C, Object_, Object_);
+ checkLub(void__B_C, Function_, Function_);
+ checkLub(void__B_C, dynamic__, Function_);
+ checkLub(void__B_C, void__, Function_);
+ checkLub(void__B_C, A__, Function_);
+ checkLub(void__B_C, B__, Function_);
+ checkLub(void__B_C, C__, Function_);
+ checkLub(void__B_C, void__A_B, void__Object_B);
+ checkLub(void__B_C, void__A_C, void__Object_C);
+ checkLub(void__B_C, void__B_A, void__B_Object);
+ checkLub(void__B_C, void__B_C, void__B_C);
+ checkLub(void__B_C, void___B, Function_);
+ checkLub(void__B_C, void___B_C, Function_);
+ checkLub(void__B_C, void___C_C, Function_);
+ checkLub(void__B_C, void____B, Function_);
+ checkLub(void__B_C, void____B_C, Function_);
+ checkLub(void__B_C, void____C_C, Function_);
+
+ checkLub(void___B, Object_, Object_);
+ checkLub(void___B, Function_, Function_);
+ checkLub(void___B, dynamic__, dynamic__);
+ checkLub(void___B, void__, void__);
+ checkLub(void___B, A__, void__);
+ checkLub(void___B, B__, void__);
+ checkLub(void___B, C__, void__);
+ checkLub(void___B, void__A_B, Function_);
+ checkLub(void___B, void__A_C, Function_);
+ checkLub(void___B, void__B_A, Function_);
+ checkLub(void___B, void__B_C, Function_);
+ checkLub(void___B, void___B, void___B);
+ checkLub(void___B, void___B_C, void___B);
+ checkLub(void___B, void___C_C, void___B);
+ checkLub(void___B, void____B, void__);
+ checkLub(void___B, void____B_C, void__);
+ checkLub(void___B, void____C_C, void__);
+
+ checkLub(void___B_C, Object_, Object_);
+ checkLub(void___B_C, Function_, Function_);
+ checkLub(void___B_C, dynamic__, dynamic__);
+ checkLub(void___B_C, void__, void__);
+ checkLub(void___B_C, A__, void__);
+ checkLub(void___B_C, B__, void__);
+ checkLub(void___B_C, C__, void__);
+ checkLub(void___B_C, void__A_B, Function_);
+ checkLub(void___B_C, void__A_C, Function_);
+ checkLub(void___B_C, void__B_A, Function_);
+ checkLub(void___B_C, void__B_C, Function_);
+ checkLub(void___B_C, void___B, void___B);
+ checkLub(void___B_C, void___B_C, void___B_C);
+ checkLub(void___B_C, void___C_C, void___B_C);
+ checkLub(void___B_C, void____B, void__);
+ checkLub(void___B_C, void____B_C, void__);
+ checkLub(void___B_C, void____C_C, void__);
+
+ checkLub(void___C_C, Object_, Object_);
+ checkLub(void___C_C, Function_, Function_);
+ checkLub(void___C_C, dynamic__, dynamic__);
+ checkLub(void___C_C, void__, void__);
+ checkLub(void___C_C, A__, void__);
+ checkLub(void___C_C, B__, void__);
+ checkLub(void___C_C, C__, void__);
+ checkLub(void___C_C, void__A_B, Function_);
+ checkLub(void___C_C, void__A_C, Function_);
+ checkLub(void___C_C, void__B_A, Function_);
+ checkLub(void___C_C, void__B_C, Function_);
+ checkLub(void___C_C, void___B, void___B);
+ checkLub(void___C_C, void___B_C, void___B_C);
+ checkLub(void___C_C, void___C_C, void___C_C);
+ checkLub(void___C_C, void____B, void__);
+ checkLub(void___C_C, void____B_C, void__);
+ checkLub(void___C_C, void____C_C, void__);
+
+ checkLub(void____B, Object_, Object_);
+ checkLub(void____B, Function_, Function_);
+ checkLub(void____B, dynamic__, dynamic__);
+ checkLub(void____B, void__, void__);
+ checkLub(void____B, A__, void__);
+ checkLub(void____B, B__, void__);
+ checkLub(void____B, C__, void__);
+ checkLub(void____B, void__A_B, Function_);
+ checkLub(void____B, void__A_C, Function_);
+ checkLub(void____B, void__B_A, Function_);
+ checkLub(void____B, void__B_C, Function_);
+ checkLub(void____B, void___B, void__);
+ checkLub(void____B, void___B_C, void__);
+ checkLub(void____B, void___C_C, void__);
+ checkLub(void____B, void____B, void____B);
+ checkLub(void____B, void____B_C, void____B);
+ checkLub(void____B, void____C_C, void____B);
+
+ checkLub(void____B_C, Object_, Object_);
+ checkLub(void____B_C, Function_, Function_);
+ checkLub(void____B_C, dynamic__, dynamic__);
+ checkLub(void____B_C, void__, void__);
+ checkLub(void____B_C, A__, void__);
+ checkLub(void____B_C, B__, void__);
+ checkLub(void____B_C, C__, void__);
+ checkLub(void____B_C, void__A_B, Function_);
+ checkLub(void____B_C, void__A_C, Function_);
+ checkLub(void____B_C, void__B_A, Function_);
+ checkLub(void____B_C, void__B_C, Function_);
+ checkLub(void____B_C, void___B, void__);
+ checkLub(void____B_C, void___B_C, void__);
+ checkLub(void____B_C, void___C_C, void__);
+ checkLub(void____B_C, void____B, void____B);
+ checkLub(void____B_C, void____B_C, void____B_C);
+ checkLub(void____B_C, void____C_C, void____B_C);
+
+ checkLub(void____C_C, Object_, Object_);
+ checkLub(void____C_C, Function_, Function_);
+ checkLub(void____C_C, dynamic__, dynamic__);
+ checkLub(void____C_C, void__, void__);
+ checkLub(void____C_C, A__, void__);
+ checkLub(void____C_C, B__, void__);
+ checkLub(void____C_C, C__, void__);
+ checkLub(void____C_C, void__A_B, Function_);
+ checkLub(void____C_C, void__A_C, Function_);
+ checkLub(void____C_C, void__B_A, Function_);
+ checkLub(void____C_C, void__B_C, Function_);
+ checkLub(void____C_C, void___B, void__);
+ checkLub(void____C_C, void___B_C, void__);
+ checkLub(void____C_C, void___C_C, void__);
+ checkLub(void____C_C, void____B, void____B);
+ checkLub(void____C_C, void____B_C, void____B_C);
+ checkLub(void____C_C, void____C_C, void____C_C);
+ }));
+}
+
+void testTypeVariable() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class A {}
+ class B {}
+ class C extends B {}
+ class I<S extends A,
+ T extends B,
+ U extends C,
+ V extends T,
+ W extends V,
+ X extends T> {}
+ """).then((env) {
+
+ // A B
+ // | / \
+ // S T C
+ // / \ \
+ // V X U
+ // /
+ // W
+
+ DartType Object_ = env['Object'];
+ DartType A = env['A'];
+ DartType B = env['B'];
+ DartType C = env['C'];
+ ClassElement I = env.getElement('I');
+ DartType S = I.typeVariables[0];
+ DartType T = I.typeVariables[1];
+ DartType U = I.typeVariables[2];
+ DartType V = I.typeVariables[3];
+ DartType W = I.typeVariables[4];
+ DartType X = I.typeVariables[5];
+
+ checkLub(DartType a, DartType b, DartType expectedLub) {
+ DartType lub = env.computeLeastUpperBound(a, b);
+ Expect.equals(expectedLub, lub,
+ 'Unexpected lub($a,$b) = $lub, expected $expectedLub');
+ }
+
+ checkLub(Object_, Object_, Object_);
+ checkLub(Object_, A, Object_);
+ checkLub(Object_, B, Object_);
+ checkLub(Object_, C, Object_);
+ checkLub(Object_, S, Object_);
+ checkLub(Object_, T, Object_);
+ checkLub(Object_, U, Object_);
+ checkLub(Object_, V, Object_);
+ checkLub(Object_, W, Object_);
+ checkLub(Object_, X, Object_);
+
+ checkLub(A, Object_, Object_);
+ checkLub(A, A, A);
+ checkLub(A, B, Object_);
+ checkLub(A, C, Object_);
+ checkLub(A, S, A);
+ checkLub(A, T, Object_);
+ checkLub(A, U, Object_);
+ checkLub(A, V, Object_);
+ checkLub(A, W, Object_);
+ checkLub(A, X, Object_);
+
+ checkLub(B, Object_, Object_);
+ checkLub(B, A, Object_);
+ checkLub(B, B, B);
+ checkLub(B, C, B);
+ checkLub(B, S, Object_);
+ checkLub(B, T, B);
+ checkLub(B, U, B);
+ checkLub(B, V, B);
+ checkLub(B, W, B);
+ checkLub(B, X, B);
+
+ checkLub(C, Object_, Object_);
+ checkLub(C, A, Object_);
+ checkLub(C, B, B);
+ checkLub(C, C, C);
+ checkLub(C, S, Object_);
+ checkLub(C, T, B);
+ checkLub(C, U, C);
+ checkLub(C, V, B);
+ checkLub(C, W, B);
+ checkLub(C, X, B);
+
+ checkLub(S, Object_, Object_);
+ checkLub(S, A, A);
+ checkLub(S, B, Object_);
+ checkLub(S, C, Object_);
+ checkLub(S, S, S);
+ checkLub(S, T, Object_);
+ checkLub(S, U, Object_);
+ checkLub(S, V, Object_);
+ checkLub(S, W, Object_);
+ checkLub(S, X, Object_);
+
+ checkLub(T, Object_, Object_);
+ checkLub(T, A, Object_);
+ checkLub(T, B, B);
+ checkLub(T, C, B);
+ checkLub(T, S, Object_);
+ checkLub(T, T, T);
+ checkLub(T, U, B);
+ checkLub(T, V, T);
+ checkLub(T, W, T);
+ checkLub(T, X, T);
+
+ checkLub(U, Object_, Object_);
+ checkLub(U, A, Object_);
+ checkLub(U, B, B);
+ checkLub(U, C, C);
+ checkLub(U, S, Object_);
+ checkLub(U, T, B);
+ checkLub(U, U, U);
+ checkLub(U, V, B);
+ checkLub(U, W, B);
+ checkLub(U, X, B);
+
+ checkLub(V, Object_, Object_);
+ checkLub(V, A, Object_);
+ checkLub(V, B, B);
+ checkLub(V, C, B);
+ checkLub(V, S, Object_);
+ checkLub(V, T, T);
+ checkLub(V, U, B);
+ checkLub(V, V, V);
+ checkLub(V, W, V);
+ checkLub(V, X, T);
+
+ checkLub(W, Object_, Object_);
+ checkLub(W, A, Object_);
+ checkLub(W, B, B);
+ checkLub(W, C, B);
+ checkLub(W, S, Object_);
+ checkLub(W, T, T);
+ checkLub(W, U, B);
+ checkLub(W, V, V);
+ checkLub(W, W, W);
+ checkLub(W, X, T);
+
+ checkLub(X, Object_, Object_);
+ checkLub(X, A, Object_);
+ checkLub(X, B, B);
+ checkLub(X, C, B);
+ checkLub(X, S, Object_);
+ checkLub(X, T, T);
+ checkLub(X, U, B);
+ checkLub(X, V, T);
+ checkLub(X, W, T);
+ checkLub(X, X, X);
+ }));
+}
+
+
diff --git a/tests/compiler/dart2js/library_resolution_test.dart b/tests/compiler/dart2js/library_resolution_test.dart
index 1a44800..c7058471 100644
--- a/tests/compiler/dart2js/library_resolution_test.dart
+++ b/tests/compiler/dart2js/library_resolution_test.dart
@@ -24,7 +24,7 @@
MessageKind,
NullSink;
-import 'package:_internal/libraries.dart' show
+import 'package:sdk_library_metadata/libraries.dart' show
DART2JS_PLATFORM,
LibraryInfo;
diff --git a/tests/compiler/dart2js/line_column_provider_test.dart b/tests/compiler/dart2js/line_column_provider_test.dart
index c1cdded..ae90daf 100644
--- a/tests/compiler/dart2js/line_column_provider_test.dart
+++ b/tests/compiler/dart2js/line_column_provider_test.dart
@@ -1,84 +1,84 @@
-// 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.
-
-// Unittest for the [LineColumnCollector].
-
-import 'package:expect/expect.dart';
-import 'package:compiler/src/io/code_output.dart';
-import 'package:compiler/src/io/line_column_provider.dart';
-
-import 'output_collector.dart';
-
-test(List events, Map<int, List<int>> expectedPositions) {
- BufferedEventSink sink = new BufferedEventSink();
- LineColumnProvider lineColumnProvider = new LineColumnCollector();
- CodeOutput output = new StreamCodeOutput(sink, [lineColumnProvider]);
- for (var event in events) {
- if (event is String) {
- output.add(event);
- } else if (event is CodeBuffer) {
- output.addBuffer(event);
- }
- }
- output.close();
-
- expectedPositions.forEach((int offset, List<int> expectedPosition) {
- if (expectedPosition == null) {
- Expect.throws(() => lineColumnProvider.getLine(offset),
- (e) => true,
- 'Expected out-of-bounds offset: $offset\n'
- 'text:"""${sink.text}"""\n'
- 'lineColumnProvider:$lineColumnProvider');
- } else {
- int line = lineColumnProvider.getLine(offset);
- int column = lineColumnProvider.getColumn(line, offset);
- Expect.equals(expectedPosition[0], line,
- 'Unexpected result: $offset -> $expectedPosition = [$line,$column]\n'
- 'text:"""${sink.text}"""\n'
- 'lineColumnProvider:$lineColumnProvider');
- Expect.equals(expectedPosition[1], column,
- 'Unexpected result: $offset -> $expectedPosition = [$line,$column]\n'
- 'text:"""${sink.text}"""\n'
- 'lineColumnProvider:$lineColumnProvider');
- }
- });
-}
-
-main() {
- test([""], {0: [0, 0], 1: null});
-
- test([" "], {0: [0, 0], 1: [0, 1], 2: null});
-
- test(["\n "], {0: [0, 0], 1: [1, 0], 2: [1, 1], 3: null});
-
- Map positions = {0: [0, 0],
- 1: [0, 1],
- 2: [1, 0],
- 3: [1, 1],
- 4: [2, 0],
- 5: [2, 1],
- 6: null};
-
- test(["a\nb\nc"], positions);
-
- test(["a", "\nb\nc"], positions);
-
- test(["a", "\n", "b\nc"], positions);
-
- CodeBuffer buffer1 = new CodeBuffer();
- buffer1.add("a\nb\nc");
- test([buffer1], positions);
-
- CodeBuffer buffer2 = new CodeBuffer();
- buffer2.add("\nb\nc");
- test(["a", buffer2], positions);
-
- CodeBuffer buffer3 = new CodeBuffer();
- buffer3.add("a");
- test([buffer3, buffer2], positions);
-
- CodeBuffer buffer4 = new CodeBuffer();
- buffer4.addBuffer(buffer3);
- test([buffer4, buffer2], positions);
-}
+// 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.
+
+// Unittest for the [LineColumnCollector].
+
+import 'package:expect/expect.dart';
+import 'package:compiler/src/io/code_output.dart';
+import 'package:compiler/src/io/line_column_provider.dart';
+
+import 'output_collector.dart';
+
+test(List events, Map<int, List<int>> expectedPositions) {
+ BufferedEventSink sink = new BufferedEventSink();
+ LineColumnProvider lineColumnProvider = new LineColumnCollector();
+ CodeOutput output = new StreamCodeOutput(sink, [lineColumnProvider]);
+ for (var event in events) {
+ if (event is String) {
+ output.add(event);
+ } else if (event is CodeBuffer) {
+ output.addBuffer(event);
+ }
+ }
+ output.close();
+
+ expectedPositions.forEach((int offset, List<int> expectedPosition) {
+ if (expectedPosition == null) {
+ Expect.throws(() => lineColumnProvider.getLine(offset),
+ (e) => true,
+ 'Expected out-of-bounds offset: $offset\n'
+ 'text:"""${sink.text}"""\n'
+ 'lineColumnProvider:$lineColumnProvider');
+ } else {
+ int line = lineColumnProvider.getLine(offset);
+ int column = lineColumnProvider.getColumn(line, offset);
+ Expect.equals(expectedPosition[0], line,
+ 'Unexpected result: $offset -> $expectedPosition = [$line,$column]\n'
+ 'text:"""${sink.text}"""\n'
+ 'lineColumnProvider:$lineColumnProvider');
+ Expect.equals(expectedPosition[1], column,
+ 'Unexpected result: $offset -> $expectedPosition = [$line,$column]\n'
+ 'text:"""${sink.text}"""\n'
+ 'lineColumnProvider:$lineColumnProvider');
+ }
+ });
+}
+
+main() {
+ test([""], {0: [0, 0], 1: null});
+
+ test([" "], {0: [0, 0], 1: [0, 1], 2: null});
+
+ test(["\n "], {0: [0, 0], 1: [1, 0], 2: [1, 1], 3: null});
+
+ Map positions = {0: [0, 0],
+ 1: [0, 1],
+ 2: [1, 0],
+ 3: [1, 1],
+ 4: [2, 0],
+ 5: [2, 1],
+ 6: null};
+
+ test(["a\nb\nc"], positions);
+
+ test(["a", "\nb\nc"], positions);
+
+ test(["a", "\n", "b\nc"], positions);
+
+ CodeBuffer buffer1 = new CodeBuffer();
+ buffer1.add("a\nb\nc");
+ test([buffer1], positions);
+
+ CodeBuffer buffer2 = new CodeBuffer();
+ buffer2.add("\nb\nc");
+ test(["a", buffer2], positions);
+
+ CodeBuffer buffer3 = new CodeBuffer();
+ buffer3.add("a");
+ test([buffer3, buffer2], positions);
+
+ CodeBuffer buffer4 = new CodeBuffer();
+ buffer4.addBuffer(buffer3);
+ test([buffer4, buffer2], positions);
+}
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index b9de4fe..7a4a809 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -11,8 +11,11 @@
import 'package:compiler/src/dart2jslib.dart'
show NullSink;
-import 'package:compiler/compiler.dart'
- show Diagnostic, DiagnosticHandler, CompilerOutputProvider;
+import 'package:compiler/compiler.dart' show
+ CompilerOutputProvider,
+ Diagnostic,
+ DiagnosticHandler,
+ PackagesDiscoveryProvider;
import 'dart:async';
@@ -89,15 +92,20 @@
Expando<MemorySourceFileProvider> expando =
new Expando<MemorySourceFileProvider>();
-Compiler compilerFor(Map<String,String> memorySourceFiles,
- {DiagnosticHandler diagnosticHandler,
- CompilerOutputProvider outputProvider,
- List<String> options: const [],
- Compiler cachedCompiler,
- bool showDiagnostics: true,
- Uri packageRoot}) {
+Compiler compilerFor(
+ Map<String, String> memorySourceFiles,
+ {DiagnosticHandler diagnosticHandler,
+ CompilerOutputProvider outputProvider,
+ List<String> options: const [],
+ Compiler cachedCompiler,
+ bool showDiagnostics: true,
+ Uri packageRoot,
+ Uri packageConfig,
+ PackagesDiscoveryProvider packagesDiscoveryProvider}) {
Uri libraryRoot = Uri.base.resolve('sdk/');
- if (packageRoot == null) {
+ if (packageRoot == null &&
+ packageConfig == null &&
+ packagesDiscoveryProvider == null) {
packageRoot = Uri.base.resolveUri(new Uri.file('${Platform.packageRoot}/'));
}
@@ -127,13 +135,17 @@
outputProvider = noOutputProvider;
}
- Compiler compiler = new Compiler(readStringFromUri,
- outputProvider,
- handler,
- libraryRoot,
- packageRoot,
- options,
- {});
+ Compiler compiler = new Compiler(
+ readStringFromUri,
+ outputProvider,
+ handler,
+ libraryRoot,
+ packageRoot,
+ options,
+ {},
+ packageConfig,
+ packagesDiscoveryProvider);
+
if (cachedCompiler != null) {
compiler.coreLibrary =
cachedCompiler.libraryLoader.lookupLibrary(Uri.parse('dart:core'));
diff --git a/tests/compiler/dart2js/mirror_system_helper.dart b/tests/compiler/dart2js/mirror_system_helper.dart
index 497e6a3..7c97ebd 100644
--- a/tests/compiler/dart2js/mirror_system_helper.dart
+++ b/tests/compiler/dart2js/mirror_system_helper.dart
@@ -1,139 +1,139 @@
-// 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 mirror_system_helper;
-
-import 'dart:async';
-import 'package:compiler/src/mirrors/source_mirrors.dart';
-import 'package:compiler/src/mirrors/dart2js_mirrors.dart';
-import 'mock_compiler.dart';
-
-export 'package:compiler/src/mirrors/source_mirrors.dart';
-export 'package:compiler/src/mirrors/mirrors_util.dart';
-
-const String SOURCE = 'source';
-final Uri SOURCE_URI = new Uri(scheme: SOURCE, path: SOURCE);
-
-// TODO(johnniwinther): Move this to a mirrors helper library.
-Future<MirrorSystem> createMirrorSystem(String source) {
- MockCompiler compiler = new MockCompiler.internal(
- analyzeOnly: true,
- analyzeAll: true,
- preserveComments: true);
- compiler.registerSource(SOURCE_URI, source);
- compiler.librariesToAnalyzeWhenRun = <Uri>[SOURCE_URI];
- return compiler.runCompiler(null).then((_) {
- return new Dart2JsMirrorSystem(compiler);
- });
-}
-
-/**
- * Returns [:true:] if [type] is an instance of [:decl:] with type arguments
- * equal to [typeArgument].
- */
-bool isInstance(ClassMirror decl, List<TypeMirror> typeArguments,
- ClassMirror type) {
- if (type.isOriginalDeclaration) return false;
- if (!isSameDeclaration(decl, type)) return false;
- return areEqualsTypes(typeArguments, type.typeArguments);
-}
-
-/**
- * Returns [:true:] if [type] is the same type as [expected]. This method
- * equates a non-generic declaration with its instantiation.
- */
-bool isEqualType(TypeMirror expected, TypeMirror type) {
- if (expected == type) return true;
- if (expected is ClassMirror && type is ClassMirror) {
- if (!isSameDeclaration(expected, type)) return false;
- if (expected.isOriginalDeclaration || expected.typeArguments.isEmpty) {
- return type.isOriginalDeclaration || type.typeArguments.isEmpty;
- }
- return areEqualsTypes(expected.typeArguments, type.typeArguments);
- }
- return true;
-}
-
-/**
- * Returns [:true:] if [types] are equals to [expected] using the equalitry
- * defined by [isEqualType].
- */
-bool areEqualsTypes(List<TypeMirror> expected, List<TypeMirror> types) {
- return checkSameList(expected, types, isEqualType);
-}
-
-/**
- * Returns [:true:] if an instance of [type] with type arguments equal to
- * [typeArguments] is found in [types].
- */
-bool containsType(ClassMirror decl, List<TypeMirror> typeArguments,
- Iterable<TypeMirror> types) {
- return types.any((type) => isInstance(decl, typeArguments, type));
-}
-
-/**
- * Returns the declaration of [type].
- */
-TypeMirror toDeclaration(TypeMirror type) {
- return type is ClassMirror ? type.originalDeclaration : type;
-}
-
-/**
- * Returns [:true:] if [type] is of the same declaration as [expected].
- */
-bool isSameDeclaration(TypeMirror expected, TypeMirror type) {
- return toDeclaration(expected) == toDeclaration(type);
-}
-
-/**
- * Returns [:true:] if a type of the declaration of [expected] is in [types].
- */
-bool containsDeclaration(TypeMirror expected, Iterable<TypeMirror> types) {
- for (var type in types) {
- if (isSameDeclaration(expected, type)) {
- return true;
- }
- }
- return false;
-}
-
-/**
- * Returns [:true:] if declarations of [expected] are the same as those of
- * [types], taking order into account.
- */
-bool isSameDeclarationList(Iterable<TypeMirror> expected,
- Iterable<TypeMirror> types) {
- return checkSameList(expected, types, isSameDeclaration);
-}
-
-/**
- * Returns [:true:] if declarations of [expected] are the same as those of
- * [iterable], not taking order into account.
- */
-bool isSameDeclarationSet(Iterable<TypeMirror> expected,
- Iterable<TypeMirror> types) {
- Set<TypeMirror> expectedSet = expected.map(toDeclaration).toSet();
- Set<TypeMirror> typesSet = types.map(toDeclaration).toSet();
- return expectedSet.length == typesSet.length &&
- expectedSet.containsAll(typesSet);
-}
-
-/**
- * Utility method for checking whether [expected] and [iterable] contains the
- * same elements with respect to the checking function [check], takin order
- * into account.
- */
-bool checkSameList(Iterable<TypeMirror> expected,
- Iterable<TypeMirror> types,
- bool check(TypeMirror a, TypeMirror b)) {
- if (expected.length != types.length) return false;
- Iterator<TypeMirror> expectedIterator = expected.iterator;
- Iterator<TypeMirror> typesIterator = types.iterator;
- while (expectedIterator.moveNext() && typesIterator.moveNext()) {
- if (!check(expectedIterator.current, typesIterator.current)) {
- return false;
- }
- }
- return true;
-}
+// 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 mirror_system_helper;
+
+import 'dart:async';
+import 'package:compiler/src/mirrors/source_mirrors.dart';
+import 'package:compiler/src/mirrors/dart2js_mirrors.dart';
+import 'mock_compiler.dart';
+
+export 'package:compiler/src/mirrors/source_mirrors.dart';
+export 'package:compiler/src/mirrors/mirrors_util.dart';
+
+const String SOURCE = 'source';
+final Uri SOURCE_URI = new Uri(scheme: SOURCE, path: SOURCE);
+
+// TODO(johnniwinther): Move this to a mirrors helper library.
+Future<MirrorSystem> createMirrorSystem(String source) {
+ MockCompiler compiler = new MockCompiler.internal(
+ analyzeOnly: true,
+ analyzeAll: true,
+ preserveComments: true);
+ compiler.registerSource(SOURCE_URI, source);
+ compiler.librariesToAnalyzeWhenRun = <Uri>[SOURCE_URI];
+ return compiler.runCompiler(null).then((_) {
+ return new Dart2JsMirrorSystem(compiler);
+ });
+}
+
+/**
+ * Returns [:true:] if [type] is an instance of [:decl:] with type arguments
+ * equal to [typeArgument].
+ */
+bool isInstance(ClassMirror decl, List<TypeMirror> typeArguments,
+ ClassMirror type) {
+ if (type.isOriginalDeclaration) return false;
+ if (!isSameDeclaration(decl, type)) return false;
+ return areEqualsTypes(typeArguments, type.typeArguments);
+}
+
+/**
+ * Returns [:true:] if [type] is the same type as [expected]. This method
+ * equates a non-generic declaration with its instantiation.
+ */
+bool isEqualType(TypeMirror expected, TypeMirror type) {
+ if (expected == type) return true;
+ if (expected is ClassMirror && type is ClassMirror) {
+ if (!isSameDeclaration(expected, type)) return false;
+ if (expected.isOriginalDeclaration || expected.typeArguments.isEmpty) {
+ return type.isOriginalDeclaration || type.typeArguments.isEmpty;
+ }
+ return areEqualsTypes(expected.typeArguments, type.typeArguments);
+ }
+ return true;
+}
+
+/**
+ * Returns [:true:] if [types] are equals to [expected] using the equalitry
+ * defined by [isEqualType].
+ */
+bool areEqualsTypes(List<TypeMirror> expected, List<TypeMirror> types) {
+ return checkSameList(expected, types, isEqualType);
+}
+
+/**
+ * Returns [:true:] if an instance of [type] with type arguments equal to
+ * [typeArguments] is found in [types].
+ */
+bool containsType(ClassMirror decl, List<TypeMirror> typeArguments,
+ Iterable<TypeMirror> types) {
+ return types.any((type) => isInstance(decl, typeArguments, type));
+}
+
+/**
+ * Returns the declaration of [type].
+ */
+TypeMirror toDeclaration(TypeMirror type) {
+ return type is ClassMirror ? type.originalDeclaration : type;
+}
+
+/**
+ * Returns [:true:] if [type] is of the same declaration as [expected].
+ */
+bool isSameDeclaration(TypeMirror expected, TypeMirror type) {
+ return toDeclaration(expected) == toDeclaration(type);
+}
+
+/**
+ * Returns [:true:] if a type of the declaration of [expected] is in [types].
+ */
+bool containsDeclaration(TypeMirror expected, Iterable<TypeMirror> types) {
+ for (var type in types) {
+ if (isSameDeclaration(expected, type)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Returns [:true:] if declarations of [expected] are the same as those of
+ * [types], taking order into account.
+ */
+bool isSameDeclarationList(Iterable<TypeMirror> expected,
+ Iterable<TypeMirror> types) {
+ return checkSameList(expected, types, isSameDeclaration);
+}
+
+/**
+ * Returns [:true:] if declarations of [expected] are the same as those of
+ * [iterable], not taking order into account.
+ */
+bool isSameDeclarationSet(Iterable<TypeMirror> expected,
+ Iterable<TypeMirror> types) {
+ Set<TypeMirror> expectedSet = expected.map(toDeclaration).toSet();
+ Set<TypeMirror> typesSet = types.map(toDeclaration).toSet();
+ return expectedSet.length == typesSet.length &&
+ expectedSet.containsAll(typesSet);
+}
+
+/**
+ * Utility method for checking whether [expected] and [iterable] contains the
+ * same elements with respect to the checking function [check], takin order
+ * into account.
+ */
+bool checkSameList(Iterable<TypeMirror> expected,
+ Iterable<TypeMirror> types,
+ bool check(TypeMirror a, TypeMirror b)) {
+ if (expected.length != types.length) return false;
+ Iterator<TypeMirror> expectedIterator = expected.iterator;
+ Iterator<TypeMirror> typesIterator = types.iterator;
+ while (expectedIterator.moveNext() && typesIterator.moveNext()) {
+ if (!check(expectedIterator.current, typesIterator.current)) {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart b/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart
index a3f6871..b8b2e56f 100644
--- a/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart
+++ b/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart
@@ -1,42 +1,42 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/class_mirror_type_variables_expect.dart";
-
-class CompileTimeEnv implements Env {
- final MirrorSystem mirrors;
-
- CompileTimeEnv(this.mirrors);
-
- LibraryMirror get core => mirrors.libraries[Uri.parse('dart:core')];
-
- LibraryMirror get test =>
- mirrors.findLibrary(#class_mirror_type_variables_data);
-
-
- ClassMirror getA() => test.declarations[#A];
- ClassMirror getB() => test.declarations[#B];
- ClassMirror getC() => test.declarations[#C];
- ClassMirror getD() => test.declarations[#D];
- ClassMirror getE() => test.declarations[#E];
- ClassMirror getF() => test.declarations[#F];
- ClassMirror getNoTypeParams() => test.declarations[#NoTypeParams];
- ClassMirror getObject() => core.declarations[#Object];
- ClassMirror getString() => core.declarations[#String];
- ClassMirror getHelperOfString() =>
- createInstantiation(test.declarations[#Helper], [getString()]);
-}
-
-main() {
- asyncTest(() => analyze("class_mirror_type_variables_data.dart").
- then((MirrorSystem mirrors) {
- test(new CompileTimeEnv(mirrors));
- }));
-
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/class_mirror_type_variables_expect.dart";
+
+class CompileTimeEnv implements Env {
+ final MirrorSystem mirrors;
+
+ CompileTimeEnv(this.mirrors);
+
+ LibraryMirror get core => mirrors.libraries[Uri.parse('dart:core')];
+
+ LibraryMirror get test =>
+ mirrors.findLibrary(#class_mirror_type_variables_data);
+
+
+ ClassMirror getA() => test.declarations[#A];
+ ClassMirror getB() => test.declarations[#B];
+ ClassMirror getC() => test.declarations[#C];
+ ClassMirror getD() => test.declarations[#D];
+ ClassMirror getE() => test.declarations[#E];
+ ClassMirror getF() => test.declarations[#F];
+ ClassMirror getNoTypeParams() => test.declarations[#NoTypeParams];
+ ClassMirror getObject() => core.declarations[#Object];
+ ClassMirror getString() => core.declarations[#String];
+ ClassMirror getHelperOfString() =>
+ createInstantiation(test.declarations[#Helper], [getString()]);
+}
+
+main() {
+ asyncTest(() => analyze("class_mirror_type_variables_data.dart").
+ then((MirrorSystem mirrors) {
+ test(new CompileTimeEnv(mirrors));
+ }));
+
+}
diff --git a/tests/compiler/dart2js/mirrors/default_value_test.dart b/tests/compiler/dart2js/mirrors/default_value_test.dart
index 53b8721..b4ea3dc 100644
--- a/tests/compiler/dart2js/mirrors/default_value_test.dart
+++ b/tests/compiler/dart2js/mirrors/default_value_test.dart
@@ -1,62 +1,62 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-import "package:expect/expect.dart";
-import "../memory_compiler.dart";
-
-const SOURCE = const {
- 'main.dart': """
-library main;
-
-class Class {
- var a, b, c, d, e, f, g, h;
- Class.optional(this.a, int b, void this.c(),
- [this.d, int this.e, void this.f(),
- this.g = 0, int this.h = 0]);
- Class.named(this.a, int b, void this.c(),
- {this.d, int this.e, void this.f(),
- this.g: 0, int this.h: 0});
- methodOptional(a, int b, void c(),
- [d, int e, void f(),
- g = 0, int h = 0]) {}
- methodNamed(a, int b, void c(),
- {d, int e, void f(),
- g: 0, int h: 0}) {}
-}
-""",
-};
-
-main() {
- asyncTest(() => mirrorSystemFor(SOURCE).then((MirrorSystem mirrors) {
- LibraryMirror dartCore = mirrors.libraries[Uri.parse('memory:main.dart')];
- ClassMirror classMirror = dartCore.declarations[#Class];
- testMethod(classMirror.declarations[#optional]);
- testMethod(classMirror.declarations[#named]);
- testMethod(classMirror.declarations[#methodOptional]);
- testMethod(classMirror.declarations[#methodNamed]);
- }));
-}
-
-testMethod(MethodMirror mirror) {
- Expect.equals(8, mirror.parameters.length);
- for (int i = 0 ; i < 6 ; i++) {
- testParameter(mirror.parameters[i], false);
- }
- for (int i = 6 ; i < 8 ; i++) {
- testParameter(mirror.parameters[i], true);
- }
-}
-
-testParameter(ParameterMirror mirror, bool expectDefaultValue) {
- if (expectDefaultValue) {
- Expect.isTrue(mirror.hasDefaultValue);
- Expect.isNotNull(mirror.defaultValue);
- } else {
- Expect.isFalse(mirror.hasDefaultValue);
- Expect.isNull(mirror.defaultValue);
- }
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "../memory_compiler.dart";
+
+const SOURCE = const {
+ 'main.dart': """
+library main;
+
+class Class {
+ var a, b, c, d, e, f, g, h;
+ Class.optional(this.a, int b, void this.c(),
+ [this.d, int this.e, void this.f(),
+ this.g = 0, int this.h = 0]);
+ Class.named(this.a, int b, void this.c(),
+ {this.d, int this.e, void this.f(),
+ this.g: 0, int this.h: 0});
+ methodOptional(a, int b, void c(),
+ [d, int e, void f(),
+ g = 0, int h = 0]) {}
+ methodNamed(a, int b, void c(),
+ {d, int e, void f(),
+ g: 0, int h: 0}) {}
+}
+""",
+};
+
+main() {
+ asyncTest(() => mirrorSystemFor(SOURCE).then((MirrorSystem mirrors) {
+ LibraryMirror dartCore = mirrors.libraries[Uri.parse('memory:main.dart')];
+ ClassMirror classMirror = dartCore.declarations[#Class];
+ testMethod(classMirror.declarations[#optional]);
+ testMethod(classMirror.declarations[#named]);
+ testMethod(classMirror.declarations[#methodOptional]);
+ testMethod(classMirror.declarations[#methodNamed]);
+ }));
+}
+
+testMethod(MethodMirror mirror) {
+ Expect.equals(8, mirror.parameters.length);
+ for (int i = 0 ; i < 6 ; i++) {
+ testParameter(mirror.parameters[i], false);
+ }
+ for (int i = 6 ; i < 8 ; i++) {
+ testParameter(mirror.parameters[i], true);
+ }
+}
+
+testParameter(ParameterMirror mirror, bool expectDefaultValue) {
+ if (expectDefaultValue) {
+ Expect.isTrue(mirror.hasDefaultValue);
+ Expect.isNotNull(mirror.defaultValue);
+ } else {
+ Expect.isFalse(mirror.hasDefaultValue);
+ Expect.isNull(mirror.defaultValue);
+ }
+}
diff --git a/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart b/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart
index f01441e..ec22898 100644
--- a/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_exports_hidden_test.dart";
-
-main() {
- asyncTest(() => analyze("library_exports_hidden_test.dart").
- then((MirrorSystem mirrors) {
- test(mirrors);
- }));
-}
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_exports_hidden_test.dart";
+
+main() {
+ asyncTest(() => analyze("library_exports_hidden_test.dart").
+ then((MirrorSystem mirrors) {
+ test(mirrors);
+ }));
+}
diff --git a/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart b/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart
index 87f3369..0234524 100644
--- a/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_exports_shown_test.dart";
-
-main() {
- asyncTest(() => analyze("library_exports_shown_test.dart").
- then((MirrorSystem mirrors) {
- test(mirrors);
- }));
-}
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_exports_shown_test.dart";
+
+main() {
+ asyncTest(() => analyze("library_exports_shown_test.dart").
+ then((MirrorSystem mirrors) {
+ test(mirrors);
+ }));
+}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart b/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart
index ad4ba20..d72132d 100644
--- a/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_imports_hidden_test.dart";
-
-main() {
- asyncTest(() => analyze("library_imports_hidden_test.dart").
- then((MirrorSystem mirrors) {
- test(mirrors);
- }));
-}
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_imports_hidden_test.dart";
+
+main() {
+ asyncTest(() => analyze("library_imports_hidden_test.dart").
+ then((MirrorSystem mirrors) {
+ test(mirrors);
+ }));
+}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart b/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart
index 910dde5..45b7dd5 100644
--- a/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_imports_prefixed_show_hide_test.dart";
-
-main() {
- asyncTest(() => analyze("library_imports_prefixed_show_hide_test.dart").
- then((MirrorSystem mirrors) {
- test(mirrors);
- }));
-}
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_imports_prefixed_show_hide_test.dart";
+
+main() {
+ asyncTest(() => analyze("library_imports_prefixed_show_hide_test.dart").
+ then((MirrorSystem mirrors) {
+ test(mirrors);
+ }));
+}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart b/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart
index 5695e98..528247d 100644
--- a/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_imports_prefixed_test.dart";
-
-main() {
- asyncTest(() => analyze("library_imports_prefixed_test.dart").
- then((MirrorSystem mirrors) {
- test(mirrors);
- }));
-}
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_imports_prefixed_test.dart";
+
+main() {
+ asyncTest(() => analyze("library_imports_prefixed_test.dart").
+ then((MirrorSystem mirrors) {
+ test(mirrors);
+ }));
+}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart b/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart
index 3f84ce7..83a77b0 100644
--- a/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_imports_shown_test.dart";
-
-main() {
- asyncTest(() => analyze("library_imports_shown_test.dart").
- then((MirrorSystem mirrors) {
- test(mirrors);
- }));
-}
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_imports_shown_test.dart";
+
+main() {
+ asyncTest(() => analyze("library_imports_shown_test.dart").
+ then((MirrorSystem mirrors) {
+ test(mirrors);
+ }));
+}
diff --git a/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart b/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
index 908c20c..bd41ab2 100644
--- a/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
+++ b/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
@@ -1,141 +1,141 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that everything reachable from a [MirrorSystem] can be accessed.
-
-library test.mirrors.reader;
-
-import "dart:mirrors" hide SourceLocation;
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/mirrors_reader.dart";
-import "package:compiler/src/util/util.dart";
-import "package:compiler/src/mirrors/dart2js_mirrors.dart";
-import "package:compiler/src/mirrors/source_mirrors.dart";
-
-class SourceMirrorsReader extends MirrorsReader {
- final Dart2JsMirrorSystem mirrorSystem;
-
- SourceMirrorsReader(this.mirrorSystem,
- {bool verbose: false, bool includeStackTrace: false})
- : super(verbose: verbose, includeStackTrace: includeStackTrace);
-
- evaluate(f()) {
- try {
- return f();
- } on SpannableAssertionFailure catch (e) {
- mirrorSystem.compiler.reportAssertionFailure(e);
- rethrow;
- }
- }
-
- visitMirror(Mirror mirror) {
- if (mirror is CombinatorMirror) {
- visitCombinatorMirror(mirror);
- } else if (mirror is LibraryDependencyMirror) {
- visitLibraryDependencyMirror(mirror);
- } else if (mirror is CommentInstanceMirror) {
- visitCommentInstanceMirror(mirror);
- } else if (mirror is ListInstanceMirror) {
- visitListInstanceMirror(mirror);
- } else if (mirror is MapInstanceMirror) {
- visitMapInstanceMirror(mirror);
- } else if (mirror is TypeInstanceMirror) {
- visitTypeInstanceMirror(mirror);
- } else {
- super.visitMirror(mirror);
- }
- }
-
- visitDeclarationMirror(DeclarationSourceMirror mirror) {
- super.visitDeclarationMirror(mirror);
- visit(mirror, 'isNameSynthetic', () => mirror.isNameSynthetic);
- }
-
- visitClassMirror(ClassSourceMirror mirror) {
- super.visitClassMirror(mirror);
- visit(mirror, 'isAbstract', () => mirror.isAbstract);
- }
-
- visitLibraryMirror(LibrarySourceMirror mirror) {
- super.visitLibraryMirror(mirror);
- visit(mirror, 'libraryDependencies', () => mirror.libraryDependencies);
- }
-
- visitParameterMirror(ParameterMirror mirror) {
- super.visitParameterMirror(mirror);
- if (mirror is ParameterSourceMirror) {
- visit(mirror, 'isInitializingFormal', () => mirror.isInitializingFormal);
- visit(mirror, 'initializedField', () => mirror.initializedField);
- }
- }
-
- visitTypeMirror(TypeSourceMirror mirror) {
- super.visitTypeMirror(mirror);
- visit(mirror, 'isVoid', () => mirror.isVoid);
- visit(mirror, 'isDynamic', () => mirror.isDynamic);
- }
-
- visitSourceLocation(SourceLocation location) {
- super.visitSourceLocation(location);
- visit(location, 'line', () => location.line);
- visit(location, 'column', () => location.column);
- visit(location, 'offset', () => location.offset);
- visit(location, 'length', () => location.length);
- visit(location, 'text', () => location.text);
- visit(location, 'sourceUri', () => location.sourceUri);
- visit(location, 'sourceText', () => location.sourceText);
- }
-
- visitCombinatorMirror(CombinatorMirror mirror) {
- visit(mirror, 'identifiers', () => mirror.identifiers);
- visit(mirror, 'isShow', () => mirror.isShow);
- visit(mirror, 'isHide', () => mirror.isHide);
- }
-
- visitLibraryDependencyMirror(LibraryDependencyMirror mirror) {
- visit(mirror, 'isImport', () => mirror.isImport);
- visit(mirror, 'isExport', () => mirror.isExport);
- visit(mirror, 'sourceLibrary', () => mirror.sourceLibrary);
- visit(mirror, 'targetLibrary', () => mirror.targetLibrary);
- visit(mirror, 'prefix', () => mirror.prefix);
- visit(mirror, 'combinators', () => mirror.combinators);
- visit(mirror, 'location', () => mirror.location);
- }
-
- visitCommentInstanceMirror(CommentInstanceMirror mirror) {
- visitInstanceMirror(mirror);
- visit(mirror, 'text', () => mirror.text);
- visit(mirror, 'trimmedText', () => mirror.trimmedText);
- visit(mirror, 'isDocComment', () => mirror.isDocComment);
- }
-
- visitListInstanceMirror(ListInstanceMirror mirror) {
- visitInstanceMirror(mirror);
- visit(mirror, 'length', () => mirror.length);
- }
-
- visitMapInstanceMirror(MapInstanceMirror mirror) {
- visitInstanceMirror(mirror);
- visit(mirror, 'keys', () => mirror.keys);
- visit(mirror, 'length', () => mirror.length);
- }
-
- visitTypeInstanceMirror(TypeInstanceMirror mirror) {
- visitInstanceMirror(mirror);
- visit(mirror, 'representedType', () => mirror.representedType);
- }
-}
-
-main(List<String> arguments) {
- asyncTest(() => analyzeUri(Uri.parse('dart:core')).
- then((MirrorSystem mirrors) {
- MirrorsReader reader = new SourceMirrorsReader(mirrors,
- verbose: arguments.contains('-v'),
- includeStackTrace: arguments.contains('-s'));
- reader.checkMirrorSystem(mirrors);
- }));
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that everything reachable from a [MirrorSystem] can be accessed.
+
+library test.mirrors.reader;
+
+import "dart:mirrors" hide SourceLocation;
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/mirrors_reader.dart";
+import "package:compiler/src/util/util.dart";
+import "package:compiler/src/mirrors/dart2js_mirrors.dart";
+import "package:compiler/src/mirrors/source_mirrors.dart";
+
+class SourceMirrorsReader extends MirrorsReader {
+ final Dart2JsMirrorSystem mirrorSystem;
+
+ SourceMirrorsReader(this.mirrorSystem,
+ {bool verbose: false, bool includeStackTrace: false})
+ : super(verbose: verbose, includeStackTrace: includeStackTrace);
+
+ evaluate(f()) {
+ try {
+ return f();
+ } on SpannableAssertionFailure catch (e) {
+ mirrorSystem.compiler.reportAssertionFailure(e);
+ rethrow;
+ }
+ }
+
+ visitMirror(Mirror mirror) {
+ if (mirror is CombinatorMirror) {
+ visitCombinatorMirror(mirror);
+ } else if (mirror is LibraryDependencyMirror) {
+ visitLibraryDependencyMirror(mirror);
+ } else if (mirror is CommentInstanceMirror) {
+ visitCommentInstanceMirror(mirror);
+ } else if (mirror is ListInstanceMirror) {
+ visitListInstanceMirror(mirror);
+ } else if (mirror is MapInstanceMirror) {
+ visitMapInstanceMirror(mirror);
+ } else if (mirror is TypeInstanceMirror) {
+ visitTypeInstanceMirror(mirror);
+ } else {
+ super.visitMirror(mirror);
+ }
+ }
+
+ visitDeclarationMirror(DeclarationSourceMirror mirror) {
+ super.visitDeclarationMirror(mirror);
+ visit(mirror, 'isNameSynthetic', () => mirror.isNameSynthetic);
+ }
+
+ visitClassMirror(ClassSourceMirror mirror) {
+ super.visitClassMirror(mirror);
+ visit(mirror, 'isAbstract', () => mirror.isAbstract);
+ }
+
+ visitLibraryMirror(LibrarySourceMirror mirror) {
+ super.visitLibraryMirror(mirror);
+ visit(mirror, 'libraryDependencies', () => mirror.libraryDependencies);
+ }
+
+ visitParameterMirror(ParameterMirror mirror) {
+ super.visitParameterMirror(mirror);
+ if (mirror is ParameterSourceMirror) {
+ visit(mirror, 'isInitializingFormal', () => mirror.isInitializingFormal);
+ visit(mirror, 'initializedField', () => mirror.initializedField);
+ }
+ }
+
+ visitTypeMirror(TypeSourceMirror mirror) {
+ super.visitTypeMirror(mirror);
+ visit(mirror, 'isVoid', () => mirror.isVoid);
+ visit(mirror, 'isDynamic', () => mirror.isDynamic);
+ }
+
+ visitSourceLocation(SourceLocation location) {
+ super.visitSourceLocation(location);
+ visit(location, 'line', () => location.line);
+ visit(location, 'column', () => location.column);
+ visit(location, 'offset', () => location.offset);
+ visit(location, 'length', () => location.length);
+ visit(location, 'text', () => location.text);
+ visit(location, 'sourceUri', () => location.sourceUri);
+ visit(location, 'sourceText', () => location.sourceText);
+ }
+
+ visitCombinatorMirror(CombinatorMirror mirror) {
+ visit(mirror, 'identifiers', () => mirror.identifiers);
+ visit(mirror, 'isShow', () => mirror.isShow);
+ visit(mirror, 'isHide', () => mirror.isHide);
+ }
+
+ visitLibraryDependencyMirror(LibraryDependencyMirror mirror) {
+ visit(mirror, 'isImport', () => mirror.isImport);
+ visit(mirror, 'isExport', () => mirror.isExport);
+ visit(mirror, 'sourceLibrary', () => mirror.sourceLibrary);
+ visit(mirror, 'targetLibrary', () => mirror.targetLibrary);
+ visit(mirror, 'prefix', () => mirror.prefix);
+ visit(mirror, 'combinators', () => mirror.combinators);
+ visit(mirror, 'location', () => mirror.location);
+ }
+
+ visitCommentInstanceMirror(CommentInstanceMirror mirror) {
+ visitInstanceMirror(mirror);
+ visit(mirror, 'text', () => mirror.text);
+ visit(mirror, 'trimmedText', () => mirror.trimmedText);
+ visit(mirror, 'isDocComment', () => mirror.isDocComment);
+ }
+
+ visitListInstanceMirror(ListInstanceMirror mirror) {
+ visitInstanceMirror(mirror);
+ visit(mirror, 'length', () => mirror.length);
+ }
+
+ visitMapInstanceMirror(MapInstanceMirror mirror) {
+ visitInstanceMirror(mirror);
+ visit(mirror, 'keys', () => mirror.keys);
+ visit(mirror, 'length', () => mirror.length);
+ }
+
+ visitTypeInstanceMirror(TypeInstanceMirror mirror) {
+ visitInstanceMirror(mirror);
+ visit(mirror, 'representedType', () => mirror.representedType);
+ }
+}
+
+main(List<String> arguments) {
+ asyncTest(() => analyzeUri(Uri.parse('dart:core')).
+ then((MirrorSystem mirrors) {
+ MirrorsReader reader = new SourceMirrorsReader(mirrors,
+ verbose: arguments.contains('-v'),
+ includeStackTrace: arguments.contains('-s'));
+ reader.checkMirrorSystem(mirrors);
+ }));
+}
diff --git a/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart b/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
index 1f57a03..0aa116f 100644
--- a/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
+++ b/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
@@ -1,37 +1,37 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-import 'dart:async';
-
-import 'package:compiler/src/mirrors/source_mirrors.dart';
-import 'package:compiler/src/mirrors/analyze.dart' as source_mirrors;
-import 'package:compiler/src/source_file_provider.dart';
-
-TypeMirror createInstantiation(TypeSourceMirror type,
- List<TypeMirror> typeArguments) {
- return type.createInstantiation(typeArguments);
-}
-
-Future<MirrorSystem> analyze(String test) {
- Uri repository = Platform.script.resolve('../../../../');
- Uri testUri = repository.resolve('tests/lib/mirrors/$test');
- return analyzeUri(testUri);
-}
-
-
-Future<MirrorSystem> analyzeUri(Uri testUri) {
- Uri repository = Platform.script.resolve('../../../../');
- Uri libraryRoot = repository.resolve('sdk/');
- Uri packageRoot = Uri.base.resolveUri(
- new Uri.file('${Platform.packageRoot}/'));
- var provider = new CompilerSourceFileProvider();
- var handler = new FormattingDiagnosticHandler(provider);
- return source_mirrors.analyze(
- [testUri],
- libraryRoot,
- packageRoot,
- provider,
- handler);
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:async';
+
+import 'package:compiler/src/mirrors/source_mirrors.dart';
+import 'package:compiler/src/mirrors/analyze.dart' as source_mirrors;
+import 'package:compiler/src/source_file_provider.dart';
+
+TypeMirror createInstantiation(TypeSourceMirror type,
+ List<TypeMirror> typeArguments) {
+ return type.createInstantiation(typeArguments);
+}
+
+Future<MirrorSystem> analyze(String test) {
+ Uri repository = Platform.script.resolve('../../../../');
+ Uri testUri = repository.resolve('tests/lib/mirrors/$test');
+ return analyzeUri(testUri);
+}
+
+
+Future<MirrorSystem> analyzeUri(Uri testUri) {
+ Uri repository = Platform.script.resolve('../../../../');
+ Uri libraryRoot = repository.resolve('sdk/');
+ Uri packageRoot = Uri.base.resolveUri(
+ new Uri.file('${Platform.packageRoot}/'));
+ var provider = new CompilerSourceFileProvider();
+ var handler = new FormattingDiagnosticHandler(provider);
+ return source_mirrors.analyze(
+ [testUri],
+ libraryRoot,
+ packageRoot,
+ provider,
+ handler);
}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirrors/relation_assignable_test.dart b/tests/compiler/dart2js/mirrors/relation_assignable_test.dart
index 3f57a14..eeb6190 100644
--- a/tests/compiler/dart2js/mirrors/relation_assignable_test.dart
+++ b/tests/compiler/dart2js/mirrors/relation_assignable_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/relation_assignable_test.dart";
-
-main() {
- asyncTest(() => analyze("relation_assignable_test.dart").
- then((MirrorSystem mirrors) {
- test(mirrors);
- }));
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/relation_assignable_test.dart";
+
+main() {
+ asyncTest(() => analyze("relation_assignable_test.dart").
+ then((MirrorSystem mirrors) {
+ test(mirrors);
+ }));
+}
diff --git a/tests/compiler/dart2js/mirrors/relation_subclass_test.dart b/tests/compiler/dart2js/mirrors/relation_subclass_test.dart
index eaab608..86503eb 100644
--- a/tests/compiler/dart2js/mirrors/relation_subclass_test.dart
+++ b/tests/compiler/dart2js/mirrors/relation_subclass_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/relation_subclass_test.dart";
-
-main() {
- asyncTest(() => analyze("relation_subclass_test.dart").
- then((MirrorSystem mirrors) {
- test(mirrors);
- }));
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/relation_subclass_test.dart";
+
+main() {
+ asyncTest(() => analyze("relation_subclass_test.dart").
+ then((MirrorSystem mirrors) {
+ test(mirrors);
+ }));
+}
diff --git a/tests/compiler/dart2js/mirrors/relation_subtype_test.dart b/tests/compiler/dart2js/mirrors/relation_subtype_test.dart
index 036af05..2fca90c 100644
--- a/tests/compiler/dart2js/mirrors/relation_subtype_test.dart
+++ b/tests/compiler/dart2js/mirrors/relation_subtype_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/relation_subtype_test.dart";
-
-main() {
- asyncTest(() => analyze("relation_subtype_test.dart").
- then((MirrorSystem mirrors) {
- test(mirrors);
- }));
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/relation_subtype_test.dart";
+
+main() {
+ asyncTest(() => analyze("relation_subtype_test.dart").
+ then((MirrorSystem mirrors) {
+ test(mirrors);
+ }));
+}
diff --git a/tests/compiler/dart2js/mirrors_exports_test.dart b/tests/compiler/dart2js/mirrors_exports_test.dart
index 0f0a127..07b70e7 100644
--- a/tests/compiler/dart2js/mirrors_exports_test.dart
+++ b/tests/compiler/dart2js/mirrors_exports_test.dart
@@ -1,183 +1,183 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'dart:async';
-import 'memory_compiler.dart';
-import 'package:compiler/src/mirrors/source_mirrors.dart';
-
-const SOURCE_FILES = const {
-'main.dart': '''
-import 'a.dart' show A1, A2;
-import 'b.dart' as b hide B1;
-export 'a.dart' show A2 hide A3, A1;
-export 'b.dart' hide B1, B2 show B3;
-import 'dart:core' as core;
-import 'c.dart' deferred as c;
-
-main() {}
-''',
-'a.dart': '''
-class A1 {}
-class A2 {}
-class A3 {}
-''',
-'b.dart': '''
-class B1 {}
-class B2 {}
-class B3 {}
-''',
-'c.dart': '''
-foo() => 499;
-'''
-};
-
-void main() {
- asyncTest(() => mirrorSystemFor(SOURCE_FILES).then((MirrorSystem mirrors) {
- LibrarySourceMirror mainLibrary =
- mirrors.libraries[Uri.parse('memory:main.dart')];
- Expect.isNotNull(mainLibrary);
-
- LibrarySourceMirror aLibrary =
- mirrors.libraries[Uri.parse('memory:a.dart')];
- Expect.isNotNull(aLibrary);
-
- LibrarySourceMirror bLibrary =
- mirrors.libraries[Uri.parse('memory:b.dart')];
- Expect.isNotNull(bLibrary);
-
- LibrarySourceMirror cLibrary =
- mirrors.libraries[Uri.parse('memory:c.dart')];
- Expect.isNotNull(cLibrary);
-
- LibrarySourceMirror coreLibrary =
- mirrors.libraries[Uri.parse('dart:core')];
- Expect.isNotNull(coreLibrary);
-
- var dependencies = mainLibrary.libraryDependencies;
- Expect.isNotNull(dependencies);
- Expect.equals(6, dependencies.length);
-
- // import 'a.dart' show A1, A2;
- var dependency = dependencies[0];
- Expect.isNotNull(dependency);
- Expect.isTrue(dependency.isImport);
- Expect.isFalse(dependency.isExport);
- Expect.equals(mainLibrary, dependency.sourceLibrary);
- Expect.equals(aLibrary, dependency.targetLibrary);
- Expect.isNull(dependency.prefix);
- Expect.isFalse(dependency.isDeferred);
-
- var combinators = dependency.combinators;
- Expect.isNotNull(combinators);
- Expect.equals(1, combinators.length);
-
- var combinator = combinators[0];
- Expect.isNotNull(combinator);
- Expect.isTrue(combinator.isShow);
- Expect.isFalse(combinator.isHide);
- Expect.listEquals(['A1', 'A2'], combinator.identifiers);
-
- // import 'b.dart' as b hide B1;
- dependency = dependencies[1];
- Expect.isNotNull(dependency);
- Expect.isTrue(dependency.isImport);
- Expect.isFalse(dependency.isExport);
- Expect.equals(mainLibrary, dependency.sourceLibrary);
- Expect.equals(bLibrary, dependency.targetLibrary);
- Expect.equals('b', dependency.prefix);
- Expect.isFalse(dependency.isDeferred);
-
- combinators = dependency.combinators;
- Expect.isNotNull(combinators);
- Expect.equals(1, combinators.length);
-
- combinator = combinators[0];
- Expect.isNotNull(combinator);
- Expect.isFalse(combinator.isShow);
- Expect.isTrue(combinator.isHide);
- Expect.listEquals(['B1'], combinator.identifiers);
-
- // export 'a.dart' show A2 hide A3, A1;
- dependency = dependencies[2];
- Expect.isNotNull(dependency);
- Expect.isFalse(dependency.isImport);
- Expect.isTrue(dependency.isExport);
- Expect.equals(mainLibrary, dependency.sourceLibrary);
- Expect.equals(aLibrary, dependency.targetLibrary);
- Expect.isNull(dependency.prefix);
- Expect.isFalse(dependency.isDeferred);
-
- combinators = dependency.combinators;
- Expect.isNotNull(combinators);
- Expect.equals(2, combinators.length);
-
- combinator = combinators[0];
- Expect.isNotNull(combinator);
- Expect.isTrue(combinator.isShow);
- Expect.isFalse(combinator.isHide);
- Expect.listEquals(['A2'], combinator.identifiers);
-
- combinator = combinators[1];
- Expect.isNotNull(combinator);
- Expect.isFalse(combinator.isShow);
- Expect.isTrue(combinator.isHide);
- Expect.listEquals(['A3', 'A1'], combinator.identifiers);
-
- // export 'b.dart' hide B1, B2 show B3;
- dependency = dependencies[3];
- Expect.isNotNull(dependency);
- Expect.isFalse(dependency.isImport);
- Expect.isTrue(dependency.isExport);
- Expect.equals(mainLibrary, dependency.sourceLibrary);
- Expect.equals(bLibrary, dependency.targetLibrary);
- Expect.isNull(dependency.prefix);
- Expect.isFalse(dependency.isDeferred);
-
- combinators = dependency.combinators;
- Expect.isNotNull(combinators);
- Expect.equals(2, combinators.length);
-
- combinator = combinators[0];
- Expect.isNotNull(combinator);
- Expect.isFalse(combinator.isShow);
- Expect.isTrue(combinator.isHide);
- Expect.listEquals(['B1', 'B2'], combinator.identifiers);
-
- combinator = combinators[1];
- Expect.isNotNull(combinator);
- Expect.isTrue(combinator.isShow);
- Expect.isFalse(combinator.isHide);
- Expect.listEquals(['B3'], combinator.identifiers);
-
- // import 'dart:core' as core;
- dependency = dependencies[4];
- Expect.isNotNull(dependency);
- Expect.isTrue(dependency.isImport);
- Expect.isFalse(dependency.isExport);
- Expect.equals(mainLibrary, dependency.sourceLibrary);
- Expect.equals(coreLibrary, dependency.targetLibrary);
- Expect.equals('core', dependency.prefix);
- Expect.isFalse(dependency.isDeferred);
-
- combinators = dependency.combinators;
- Expect.isNotNull(combinators);
- Expect.equals(0, combinators.length);
-
- // import 'c.dart' deferred as c;
- dependency = dependencies[5];
- Expect.isNotNull(dependency);
- Expect.isTrue(dependency.isImport);
- Expect.isFalse(dependency.isExport);
- Expect.equals(mainLibrary, dependency.sourceLibrary);
- Expect.equals(cLibrary, dependency.targetLibrary);
- Expect.equals('c', dependency.prefix);
- Expect.isTrue(dependency.isDeferred);
-
- combinators = dependency.combinators;
- Expect.isNotNull(combinators);
- Expect.equals(0, combinators.length);
- }));
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+import 'memory_compiler.dart';
+import 'package:compiler/src/mirrors/source_mirrors.dart';
+
+const SOURCE_FILES = const {
+'main.dart': '''
+import 'a.dart' show A1, A2;
+import 'b.dart' as b hide B1;
+export 'a.dart' show A2 hide A3, A1;
+export 'b.dart' hide B1, B2 show B3;
+import 'dart:core' as core;
+import 'c.dart' deferred as c;
+
+main() {}
+''',
+'a.dart': '''
+class A1 {}
+class A2 {}
+class A3 {}
+''',
+'b.dart': '''
+class B1 {}
+class B2 {}
+class B3 {}
+''',
+'c.dart': '''
+foo() => 499;
+'''
+};
+
+void main() {
+ asyncTest(() => mirrorSystemFor(SOURCE_FILES).then((MirrorSystem mirrors) {
+ LibrarySourceMirror mainLibrary =
+ mirrors.libraries[Uri.parse('memory:main.dart')];
+ Expect.isNotNull(mainLibrary);
+
+ LibrarySourceMirror aLibrary =
+ mirrors.libraries[Uri.parse('memory:a.dart')];
+ Expect.isNotNull(aLibrary);
+
+ LibrarySourceMirror bLibrary =
+ mirrors.libraries[Uri.parse('memory:b.dart')];
+ Expect.isNotNull(bLibrary);
+
+ LibrarySourceMirror cLibrary =
+ mirrors.libraries[Uri.parse('memory:c.dart')];
+ Expect.isNotNull(cLibrary);
+
+ LibrarySourceMirror coreLibrary =
+ mirrors.libraries[Uri.parse('dart:core')];
+ Expect.isNotNull(coreLibrary);
+
+ var dependencies = mainLibrary.libraryDependencies;
+ Expect.isNotNull(dependencies);
+ Expect.equals(6, dependencies.length);
+
+ // import 'a.dart' show A1, A2;
+ var dependency = dependencies[0];
+ Expect.isNotNull(dependency);
+ Expect.isTrue(dependency.isImport);
+ Expect.isFalse(dependency.isExport);
+ Expect.equals(mainLibrary, dependency.sourceLibrary);
+ Expect.equals(aLibrary, dependency.targetLibrary);
+ Expect.isNull(dependency.prefix);
+ Expect.isFalse(dependency.isDeferred);
+
+ var combinators = dependency.combinators;
+ Expect.isNotNull(combinators);
+ Expect.equals(1, combinators.length);
+
+ var combinator = combinators[0];
+ Expect.isNotNull(combinator);
+ Expect.isTrue(combinator.isShow);
+ Expect.isFalse(combinator.isHide);
+ Expect.listEquals(['A1', 'A2'], combinator.identifiers);
+
+ // import 'b.dart' as b hide B1;
+ dependency = dependencies[1];
+ Expect.isNotNull(dependency);
+ Expect.isTrue(dependency.isImport);
+ Expect.isFalse(dependency.isExport);
+ Expect.equals(mainLibrary, dependency.sourceLibrary);
+ Expect.equals(bLibrary, dependency.targetLibrary);
+ Expect.equals('b', dependency.prefix);
+ Expect.isFalse(dependency.isDeferred);
+
+ combinators = dependency.combinators;
+ Expect.isNotNull(combinators);
+ Expect.equals(1, combinators.length);
+
+ combinator = combinators[0];
+ Expect.isNotNull(combinator);
+ Expect.isFalse(combinator.isShow);
+ Expect.isTrue(combinator.isHide);
+ Expect.listEquals(['B1'], combinator.identifiers);
+
+ // export 'a.dart' show A2 hide A3, A1;
+ dependency = dependencies[2];
+ Expect.isNotNull(dependency);
+ Expect.isFalse(dependency.isImport);
+ Expect.isTrue(dependency.isExport);
+ Expect.equals(mainLibrary, dependency.sourceLibrary);
+ Expect.equals(aLibrary, dependency.targetLibrary);
+ Expect.isNull(dependency.prefix);
+ Expect.isFalse(dependency.isDeferred);
+
+ combinators = dependency.combinators;
+ Expect.isNotNull(combinators);
+ Expect.equals(2, combinators.length);
+
+ combinator = combinators[0];
+ Expect.isNotNull(combinator);
+ Expect.isTrue(combinator.isShow);
+ Expect.isFalse(combinator.isHide);
+ Expect.listEquals(['A2'], combinator.identifiers);
+
+ combinator = combinators[1];
+ Expect.isNotNull(combinator);
+ Expect.isFalse(combinator.isShow);
+ Expect.isTrue(combinator.isHide);
+ Expect.listEquals(['A3', 'A1'], combinator.identifiers);
+
+ // export 'b.dart' hide B1, B2 show B3;
+ dependency = dependencies[3];
+ Expect.isNotNull(dependency);
+ Expect.isFalse(dependency.isImport);
+ Expect.isTrue(dependency.isExport);
+ Expect.equals(mainLibrary, dependency.sourceLibrary);
+ Expect.equals(bLibrary, dependency.targetLibrary);
+ Expect.isNull(dependency.prefix);
+ Expect.isFalse(dependency.isDeferred);
+
+ combinators = dependency.combinators;
+ Expect.isNotNull(combinators);
+ Expect.equals(2, combinators.length);
+
+ combinator = combinators[0];
+ Expect.isNotNull(combinator);
+ Expect.isFalse(combinator.isShow);
+ Expect.isTrue(combinator.isHide);
+ Expect.listEquals(['B1', 'B2'], combinator.identifiers);
+
+ combinator = combinators[1];
+ Expect.isNotNull(combinator);
+ Expect.isTrue(combinator.isShow);
+ Expect.isFalse(combinator.isHide);
+ Expect.listEquals(['B3'], combinator.identifiers);
+
+ // import 'dart:core' as core;
+ dependency = dependencies[4];
+ Expect.isNotNull(dependency);
+ Expect.isTrue(dependency.isImport);
+ Expect.isFalse(dependency.isExport);
+ Expect.equals(mainLibrary, dependency.sourceLibrary);
+ Expect.equals(coreLibrary, dependency.targetLibrary);
+ Expect.equals('core', dependency.prefix);
+ Expect.isFalse(dependency.isDeferred);
+
+ combinators = dependency.combinators;
+ Expect.isNotNull(combinators);
+ Expect.equals(0, combinators.length);
+
+ // import 'c.dart' deferred as c;
+ dependency = dependencies[5];
+ Expect.isNotNull(dependency);
+ Expect.isTrue(dependency.isImport);
+ Expect.isFalse(dependency.isExport);
+ Expect.equals(mainLibrary, dependency.sourceLibrary);
+ Expect.equals(cLibrary, dependency.targetLibrary);
+ Expect.equals('c', dependency.prefix);
+ Expect.isTrue(dependency.isDeferred);
+
+ combinators = dependency.combinators;
+ Expect.isNotNull(combinators);
+ Expect.equals(0, combinators.length);
+ }));
}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirrors_mixin_test.dart b/tests/compiler/dart2js/mirrors_mixin_test.dart
index 0a94a06..d5ab821 100644
--- a/tests/compiler/dart2js/mirrors_mixin_test.dart
+++ b/tests/compiler/dart2js/mirrors_mixin_test.dart
@@ -1,240 +1,240 @@
-// 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 mirrors_mixin_test;
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'mirror_system_helper.dart';
-
-const String CLASS_SOURCE = '''
-class A {}
-
-class S {}
-class M1<T> {}
-class M2 {}
-
-class C extends S with M1<A> {}
-class D extends S with M1, M2 {}
-class E extends S with M2, M1 implements A, M1 {}
-class E2 extends E {}
-
-class F = S with M1<A>;
-abstract class G = S with M1, M2;
-class H = S with M2, M1 implements A, M1;
-class H2 extends H {}
-''';
-
-void main() {
- asyncTest(() => createMirrorSystem(CLASS_SOURCE).then((MirrorSystem mirrors) {
- LibraryMirror library = mirrors.libraries[SOURCE_URI];
-
- checkSimpleClass(var cls) {
- Expect.isNotNull(cls);
- Expect.isTrue(cls is ClassMirror);
- Expect.isFalse(isMixinApplication(cls));
- Expect.isFalse(cls.isNameSynthetic);
- Expect.isFalse(isObject(cls));
- Expect.isTrue(isObject(cls.superclass));
- Expect.equals(0, cls.superinterfaces.length);
-
- Expect.isTrue(isObject(getSuperclass(cls)));
- Expect.isTrue(getAppliedMixins(cls).isEmpty);
- Expect.isTrue(getExplicitInterfaces(cls).isEmpty);
- }
-
- // class A {}
- var A = library.declarations[#A];
- checkSimpleClass(A);
-
- // class S {}
- var S = library.declarations[#S];
- checkSimpleClass(S);
-
- // class M1 {}
- var M1 = library.declarations[#M1];
- checkSimpleClass(M1);
-
- // class M2 {}
- var M2 = library.declarations[#M2];
- checkSimpleClass(M2);
-
- // class C extends S with M1<A> {}
- var C = library.declarations[#C];
- Expect.isNotNull(C);
- Expect.isTrue(C is ClassMirror);
- Expect.isFalse(isMixinApplication(C));
- Expect.isFalse(isObject(C));
- Expect.equals(0, C.superinterfaces.length);
- var C_super = C.superclass;
- Expect.isNotNull(C_super);
- Expect.isTrue(C_super is ClassMirror);
- Expect.isTrue(isMixinApplication(C_super));
- Expect.isTrue(C_super.isNameSynthetic);
- Expect.equals(1, C_super.superinterfaces.length);
- Expect.isTrue(containsType(M1, [A], C_super.superinterfaces));
- Expect.isTrue(isInstance(M1, [A], C_super.mixin));
- Expect.isFalse(isObject(C_super));
- Expect.isTrue(isSameDeclaration(S, C_super.superclass));
-
- Expect.isTrue(isSameDeclaration(S, getSuperclass(C)));
- Expect.isTrue(isSameDeclarationList([M1], getAppliedMixins(C)));
- Expect.isTrue(getExplicitInterfaces(C).isEmpty);
-
- // D extends S with M1, M2 {}
- var D = library.declarations[#D];
- Expect.isNotNull(D);
- Expect.isTrue(D is ClassMirror);
- Expect.isFalse(isMixinApplication(D));
- Expect.isFalse(isObject(D));
- Expect.equals(0, D.superinterfaces.length);
- var D_super = D.superclass;
- Expect.isNotNull(D_super);
- Expect.isTrue(D_super is ClassMirror);
- Expect.isTrue(isMixinApplication(D_super));
- Expect.isTrue(D_super.isNameSynthetic);
- Expect.equals(1, D_super.superinterfaces.length);
- Expect.isTrue(containsDeclaration(M2, D_super.superinterfaces));
- Expect.isTrue(isSameDeclaration(M2, D_super.mixin));
- Expect.isFalse(isObject(D_super));
- Expect.isFalse(isSameDeclaration(S, D_super.superclass));
- var D_super_super = D_super.superclass;
- Expect.isNotNull(D_super_super);
- Expect.isTrue(D_super_super is ClassMirror);
- Expect.isTrue(isMixinApplication(D_super_super));
- Expect.isTrue(D_super_super.isNameSynthetic);
- Expect.equals(1, D_super_super.superinterfaces.length);
- Expect.isTrue(containsDeclaration(M1, D_super_super.superinterfaces));
- Expect.isTrue(isSameDeclaration(M1, D_super_super.mixin));
- Expect.isFalse(isObject(D_super_super));
- Expect.isTrue(isSameDeclaration(S, D_super_super.superclass));
-
- Expect.isTrue(isSameDeclaration(S, getSuperclass(D)));
- Expect.isTrue(isSameDeclarationList([M1, M2], getAppliedMixins(D)));
- Expect.isTrue(getExplicitInterfaces(D).isEmpty);
-
- // class E extends S with M2, M1 implements A, M1 {}
- var E = library.declarations[#E];
- Expect.isNotNull(E);
- Expect.isTrue(E is ClassMirror);
- Expect.isFalse(isMixinApplication(E));
- Expect.isFalse(isObject(E));
- Expect.equals(2, E.superinterfaces.length);
- Expect.isTrue(containsDeclaration(A, E.superinterfaces));
- Expect.isTrue(containsDeclaration(M1, E.superinterfaces));
- var E_super = E.superclass;
- Expect.isNotNull(E_super);
- Expect.isTrue(E_super is ClassMirror);
- Expect.isTrue(isMixinApplication(E_super));
- Expect.isTrue(E_super.isNameSynthetic);
- Expect.equals(1, E_super.superinterfaces.length);
- Expect.isTrue(containsDeclaration(M1, E_super.superinterfaces));
- Expect.isTrue(isSameDeclaration(M1, E_super.mixin));
- Expect.isFalse(isObject(E_super));
- Expect.isFalse(isSameDeclaration(S, E_super.superclass));
- var E_super_super = E_super.superclass;
- Expect.isNotNull(E_super_super);
- Expect.isTrue(E_super_super is ClassMirror);
- Expect.isTrue(isMixinApplication(E_super_super));
- Expect.isTrue(E_super_super.isNameSynthetic);
- Expect.equals(1, E_super_super.superinterfaces.length);
- Expect.isTrue(containsDeclaration(M2, E_super_super.superinterfaces));
- Expect.isTrue(isSameDeclaration(M2, E_super_super.mixin));
- Expect.isFalse(isObject(E_super_super));
- Expect.isTrue(isSameDeclaration(S, E_super_super.superclass));
-
- Expect.isTrue(isSameDeclaration(S, getSuperclass(E)));
- Expect.isTrue(isSameDeclarationList([M2, M1], getAppliedMixins(E)));
- Expect.isTrue(isSameDeclarationSet([A, M1], getExplicitInterfaces(E)));
-
- // class E2 extends E {}
- var E2 = library.declarations[#E2];
- Expect.isTrue(isSameDeclaration(E, getSuperclass(E2)));
- Expect.isTrue(getAppliedMixins(E2).isEmpty);
- Expect.isTrue(getExplicitInterfaces(E2).isEmpty);
-
- // class F = S with M1<A>;
- var F = library.declarations[#F];
- Expect.isNotNull(F);
- Expect.isTrue(F is ClassMirror);
- Expect.isFalse(F.isAbstract);
- Expect.isTrue(isMixinApplication(F));
- Expect.isFalse(F.isNameSynthetic);
- Expect.equals(#F, F.simpleName);
- Expect.isFalse(isObject(F));
- Expect.equals(1, F.superinterfaces.length);
- Expect.isTrue(containsDeclaration(M1, F.superinterfaces));
- Expect.isTrue(isInstance(M1, [A], F.mixin));
- var F_super = F.superclass;
- Expect.isNotNull(F_super);
- Expect.isTrue(F_super is ClassMirror);
- Expect.isFalse(isMixinApplication(F_super));
- Expect.isFalse(isObject(F_super));
- Expect.isTrue(isSameDeclaration(S, F_super));
-
- Expect.isTrue(isSameDeclaration(S, getSuperclass(F)));
- Expect.isTrue(isSameDeclarationList([M1], getAppliedMixins(F)));
- Expect.isTrue(getExplicitInterfaces(F).isEmpty);
-
- // typedef G = abstract S with M1, M2;
- var G = library.declarations[#G];
- Expect.isNotNull(G);
- Expect.isTrue(G is ClassMirror);
- Expect.isTrue(G.isAbstract);
- Expect.isTrue(isMixinApplication(G));
- Expect.isFalse(G.isNameSynthetic);
- Expect.equals(#G, G.simpleName);
- Expect.isFalse(isObject(G));
- Expect.equals(1, G.superinterfaces.length);
- Expect.isTrue(containsDeclaration(M2, G.superinterfaces));
- Expect.isTrue(isSameDeclaration(M2, G.mixin));
- var G_super = G.superclass;
- Expect.isNotNull(G_super);
- Expect.isTrue(G_super is ClassMirror);
- Expect.isTrue(isMixinApplication(G_super));
- Expect.equals(1, G_super.superinterfaces.length);
- Expect.isTrue(containsDeclaration(M1, G_super.superinterfaces));
- Expect.isTrue(isSameDeclaration(M1, G_super.mixin));
- Expect.isFalse(isObject(G_super));
- Expect.isTrue(isSameDeclaration(S, G_super.superclass));
-
- Expect.isTrue(isSameDeclaration(S, getSuperclass(G)));
- Expect.isTrue(isSameDeclarationList([M1, M2], getAppliedMixins(G)));
- Expect.isTrue(getExplicitInterfaces(G).isEmpty);
-
- // typedef H = S with M2, M1 implements A, M1;
- var H = library.declarations[#H];
- Expect.isNotNull(H);
- Expect.isTrue(H is ClassMirror);
- Expect.isFalse(H.isAbstract);
- Expect.isTrue(isMixinApplication(H));
- Expect.isFalse(H.isNameSynthetic);
- Expect.equals(#H, H.simpleName);
- Expect.isFalse(isObject(H));
- Expect.equals(3, H.superinterfaces.length);
- Expect.isTrue(containsDeclaration(A, H.superinterfaces));
- Expect.isTrue(containsDeclaration(M1, H.superinterfaces));
- Expect.isFalse(containsDeclaration(M2, H.superinterfaces));
- Expect.isTrue(isSameDeclaration(M1, H.mixin));
- var H_super = H.superclass;
- Expect.isNotNull(H_super);
- Expect.isTrue(H_super is ClassMirror);
- Expect.isTrue(isMixinApplication(H_super));
- Expect.equals(1, H_super.superinterfaces.length);
- Expect.isTrue(containsDeclaration(M2, H_super.superinterfaces));
- Expect.isTrue(isSameDeclaration(M2, H_super.mixin));
- Expect.isFalse(isObject(H_super));
- Expect.isTrue(isSameDeclaration(S, H_super.superclass));
-
- Expect.isTrue(isSameDeclaration(S, getSuperclass(H)));
- Expect.isTrue(isSameDeclarationList([M2, M1], getAppliedMixins(H)));
- Expect.isTrue(isSameDeclarationSet([A, M1], getExplicitInterfaces(H)));
-
- // class H2 extends H {}
- var H2 = library.declarations[#H2];
- Expect.isTrue(isSameDeclaration(H, getSuperclass(H2)));
- Expect.isTrue(getAppliedMixins(H2).isEmpty);
- Expect.isTrue(getExplicitInterfaces(H2).isEmpty);
- }));
+// 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 mirrors_mixin_test;
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'mirror_system_helper.dart';
+
+const String CLASS_SOURCE = '''
+class A {}
+
+class S {}
+class M1<T> {}
+class M2 {}
+
+class C extends S with M1<A> {}
+class D extends S with M1, M2 {}
+class E extends S with M2, M1 implements A, M1 {}
+class E2 extends E {}
+
+class F = S with M1<A>;
+abstract class G = S with M1, M2;
+class H = S with M2, M1 implements A, M1;
+class H2 extends H {}
+''';
+
+void main() {
+ asyncTest(() => createMirrorSystem(CLASS_SOURCE).then((MirrorSystem mirrors) {
+ LibraryMirror library = mirrors.libraries[SOURCE_URI];
+
+ checkSimpleClass(var cls) {
+ Expect.isNotNull(cls);
+ Expect.isTrue(cls is ClassMirror);
+ Expect.isFalse(isMixinApplication(cls));
+ Expect.isFalse(cls.isNameSynthetic);
+ Expect.isFalse(isObject(cls));
+ Expect.isTrue(isObject(cls.superclass));
+ Expect.equals(0, cls.superinterfaces.length);
+
+ Expect.isTrue(isObject(getSuperclass(cls)));
+ Expect.isTrue(getAppliedMixins(cls).isEmpty);
+ Expect.isTrue(getExplicitInterfaces(cls).isEmpty);
+ }
+
+ // class A {}
+ var A = library.declarations[#A];
+ checkSimpleClass(A);
+
+ // class S {}
+ var S = library.declarations[#S];
+ checkSimpleClass(S);
+
+ // class M1 {}
+ var M1 = library.declarations[#M1];
+ checkSimpleClass(M1);
+
+ // class M2 {}
+ var M2 = library.declarations[#M2];
+ checkSimpleClass(M2);
+
+ // class C extends S with M1<A> {}
+ var C = library.declarations[#C];
+ Expect.isNotNull(C);
+ Expect.isTrue(C is ClassMirror);
+ Expect.isFalse(isMixinApplication(C));
+ Expect.isFalse(isObject(C));
+ Expect.equals(0, C.superinterfaces.length);
+ var C_super = C.superclass;
+ Expect.isNotNull(C_super);
+ Expect.isTrue(C_super is ClassMirror);
+ Expect.isTrue(isMixinApplication(C_super));
+ Expect.isTrue(C_super.isNameSynthetic);
+ Expect.equals(1, C_super.superinterfaces.length);
+ Expect.isTrue(containsType(M1, [A], C_super.superinterfaces));
+ Expect.isTrue(isInstance(M1, [A], C_super.mixin));
+ Expect.isFalse(isObject(C_super));
+ Expect.isTrue(isSameDeclaration(S, C_super.superclass));
+
+ Expect.isTrue(isSameDeclaration(S, getSuperclass(C)));
+ Expect.isTrue(isSameDeclarationList([M1], getAppliedMixins(C)));
+ Expect.isTrue(getExplicitInterfaces(C).isEmpty);
+
+ // D extends S with M1, M2 {}
+ var D = library.declarations[#D];
+ Expect.isNotNull(D);
+ Expect.isTrue(D is ClassMirror);
+ Expect.isFalse(isMixinApplication(D));
+ Expect.isFalse(isObject(D));
+ Expect.equals(0, D.superinterfaces.length);
+ var D_super = D.superclass;
+ Expect.isNotNull(D_super);
+ Expect.isTrue(D_super is ClassMirror);
+ Expect.isTrue(isMixinApplication(D_super));
+ Expect.isTrue(D_super.isNameSynthetic);
+ Expect.equals(1, D_super.superinterfaces.length);
+ Expect.isTrue(containsDeclaration(M2, D_super.superinterfaces));
+ Expect.isTrue(isSameDeclaration(M2, D_super.mixin));
+ Expect.isFalse(isObject(D_super));
+ Expect.isFalse(isSameDeclaration(S, D_super.superclass));
+ var D_super_super = D_super.superclass;
+ Expect.isNotNull(D_super_super);
+ Expect.isTrue(D_super_super is ClassMirror);
+ Expect.isTrue(isMixinApplication(D_super_super));
+ Expect.isTrue(D_super_super.isNameSynthetic);
+ Expect.equals(1, D_super_super.superinterfaces.length);
+ Expect.isTrue(containsDeclaration(M1, D_super_super.superinterfaces));
+ Expect.isTrue(isSameDeclaration(M1, D_super_super.mixin));
+ Expect.isFalse(isObject(D_super_super));
+ Expect.isTrue(isSameDeclaration(S, D_super_super.superclass));
+
+ Expect.isTrue(isSameDeclaration(S, getSuperclass(D)));
+ Expect.isTrue(isSameDeclarationList([M1, M2], getAppliedMixins(D)));
+ Expect.isTrue(getExplicitInterfaces(D).isEmpty);
+
+ // class E extends S with M2, M1 implements A, M1 {}
+ var E = library.declarations[#E];
+ Expect.isNotNull(E);
+ Expect.isTrue(E is ClassMirror);
+ Expect.isFalse(isMixinApplication(E));
+ Expect.isFalse(isObject(E));
+ Expect.equals(2, E.superinterfaces.length);
+ Expect.isTrue(containsDeclaration(A, E.superinterfaces));
+ Expect.isTrue(containsDeclaration(M1, E.superinterfaces));
+ var E_super = E.superclass;
+ Expect.isNotNull(E_super);
+ Expect.isTrue(E_super is ClassMirror);
+ Expect.isTrue(isMixinApplication(E_super));
+ Expect.isTrue(E_super.isNameSynthetic);
+ Expect.equals(1, E_super.superinterfaces.length);
+ Expect.isTrue(containsDeclaration(M1, E_super.superinterfaces));
+ Expect.isTrue(isSameDeclaration(M1, E_super.mixin));
+ Expect.isFalse(isObject(E_super));
+ Expect.isFalse(isSameDeclaration(S, E_super.superclass));
+ var E_super_super = E_super.superclass;
+ Expect.isNotNull(E_super_super);
+ Expect.isTrue(E_super_super is ClassMirror);
+ Expect.isTrue(isMixinApplication(E_super_super));
+ Expect.isTrue(E_super_super.isNameSynthetic);
+ Expect.equals(1, E_super_super.superinterfaces.length);
+ Expect.isTrue(containsDeclaration(M2, E_super_super.superinterfaces));
+ Expect.isTrue(isSameDeclaration(M2, E_super_super.mixin));
+ Expect.isFalse(isObject(E_super_super));
+ Expect.isTrue(isSameDeclaration(S, E_super_super.superclass));
+
+ Expect.isTrue(isSameDeclaration(S, getSuperclass(E)));
+ Expect.isTrue(isSameDeclarationList([M2, M1], getAppliedMixins(E)));
+ Expect.isTrue(isSameDeclarationSet([A, M1], getExplicitInterfaces(E)));
+
+ // class E2 extends E {}
+ var E2 = library.declarations[#E2];
+ Expect.isTrue(isSameDeclaration(E, getSuperclass(E2)));
+ Expect.isTrue(getAppliedMixins(E2).isEmpty);
+ Expect.isTrue(getExplicitInterfaces(E2).isEmpty);
+
+ // class F = S with M1<A>;
+ var F = library.declarations[#F];
+ Expect.isNotNull(F);
+ Expect.isTrue(F is ClassMirror);
+ Expect.isFalse(F.isAbstract);
+ Expect.isTrue(isMixinApplication(F));
+ Expect.isFalse(F.isNameSynthetic);
+ Expect.equals(#F, F.simpleName);
+ Expect.isFalse(isObject(F));
+ Expect.equals(1, F.superinterfaces.length);
+ Expect.isTrue(containsDeclaration(M1, F.superinterfaces));
+ Expect.isTrue(isInstance(M1, [A], F.mixin));
+ var F_super = F.superclass;
+ Expect.isNotNull(F_super);
+ Expect.isTrue(F_super is ClassMirror);
+ Expect.isFalse(isMixinApplication(F_super));
+ Expect.isFalse(isObject(F_super));
+ Expect.isTrue(isSameDeclaration(S, F_super));
+
+ Expect.isTrue(isSameDeclaration(S, getSuperclass(F)));
+ Expect.isTrue(isSameDeclarationList([M1], getAppliedMixins(F)));
+ Expect.isTrue(getExplicitInterfaces(F).isEmpty);
+
+ // typedef G = abstract S with M1, M2;
+ var G = library.declarations[#G];
+ Expect.isNotNull(G);
+ Expect.isTrue(G is ClassMirror);
+ Expect.isTrue(G.isAbstract);
+ Expect.isTrue(isMixinApplication(G));
+ Expect.isFalse(G.isNameSynthetic);
+ Expect.equals(#G, G.simpleName);
+ Expect.isFalse(isObject(G));
+ Expect.equals(1, G.superinterfaces.length);
+ Expect.isTrue(containsDeclaration(M2, G.superinterfaces));
+ Expect.isTrue(isSameDeclaration(M2, G.mixin));
+ var G_super = G.superclass;
+ Expect.isNotNull(G_super);
+ Expect.isTrue(G_super is ClassMirror);
+ Expect.isTrue(isMixinApplication(G_super));
+ Expect.equals(1, G_super.superinterfaces.length);
+ Expect.isTrue(containsDeclaration(M1, G_super.superinterfaces));
+ Expect.isTrue(isSameDeclaration(M1, G_super.mixin));
+ Expect.isFalse(isObject(G_super));
+ Expect.isTrue(isSameDeclaration(S, G_super.superclass));
+
+ Expect.isTrue(isSameDeclaration(S, getSuperclass(G)));
+ Expect.isTrue(isSameDeclarationList([M1, M2], getAppliedMixins(G)));
+ Expect.isTrue(getExplicitInterfaces(G).isEmpty);
+
+ // typedef H = S with M2, M1 implements A, M1;
+ var H = library.declarations[#H];
+ Expect.isNotNull(H);
+ Expect.isTrue(H is ClassMirror);
+ Expect.isFalse(H.isAbstract);
+ Expect.isTrue(isMixinApplication(H));
+ Expect.isFalse(H.isNameSynthetic);
+ Expect.equals(#H, H.simpleName);
+ Expect.isFalse(isObject(H));
+ Expect.equals(3, H.superinterfaces.length);
+ Expect.isTrue(containsDeclaration(A, H.superinterfaces));
+ Expect.isTrue(containsDeclaration(M1, H.superinterfaces));
+ Expect.isFalse(containsDeclaration(M2, H.superinterfaces));
+ Expect.isTrue(isSameDeclaration(M1, H.mixin));
+ var H_super = H.superclass;
+ Expect.isNotNull(H_super);
+ Expect.isTrue(H_super is ClassMirror);
+ Expect.isTrue(isMixinApplication(H_super));
+ Expect.equals(1, H_super.superinterfaces.length);
+ Expect.isTrue(containsDeclaration(M2, H_super.superinterfaces));
+ Expect.isTrue(isSameDeclaration(M2, H_super.mixin));
+ Expect.isFalse(isObject(H_super));
+ Expect.isTrue(isSameDeclaration(S, H_super.superclass));
+
+ Expect.isTrue(isSameDeclaration(S, getSuperclass(H)));
+ Expect.isTrue(isSameDeclarationList([M2, M1], getAppliedMixins(H)));
+ Expect.isTrue(isSameDeclarationSet([A, M1], getExplicitInterfaces(H)));
+
+ // class H2 extends H {}
+ var H2 = library.declarations[#H2];
+ Expect.isTrue(isSameDeclaration(H, getSuperclass(H2)));
+ Expect.isTrue(getAppliedMixins(H2).isEmpty);
+ Expect.isTrue(getExplicitInterfaces(H2).isEmpty);
+ }));
}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mixin_language_test.dart b/tests/compiler/dart2js/mixin_language_test.dart
index f4be3b2..11f708b 100644
--- a/tests/compiler/dart2js/mixin_language_test.dart
+++ b/tests/compiler/dart2js/mixin_language_test.dart
@@ -1,21 +1,21 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that dart2js produces the expected static type warnings for these
-// language tests. This ensures that the analyzer and dart2js agrees on the
-// tests.
-
-import 'warnings_checker.dart';
-
-/// Map from test files to a map of their expected status. If the status map is
-/// `null` no warnings must be missing or unexpected, otherwise the status map
-/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
-/// the warnings of each category.
-const Map<String, dynamic> TESTS = const {
- 'language/typevariable_substitution2_test.dart': null,
-};
-
-void main(List<String> arguments) {
- checkWarnings(TESTS, arguments);
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that dart2js produces the expected static type warnings for these
+// language tests. This ensures that the analyzer and dart2js agrees on the
+// tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+ 'language/typevariable_substitution2_test.dart': null,
+};
+
+void main(List<String> arguments) {
+ checkWarnings(TESTS, arguments);
+}
diff --git a/tests/compiler/dart2js/mixin_typevariable_test.dart b/tests/compiler/dart2js/mixin_typevariable_test.dart
index 0553589..27fe4bb 100644
--- a/tests/compiler/dart2js/mixin_typevariable_test.dart
+++ b/tests/compiler/dart2js/mixin_typevariable_test.dart
@@ -1,158 +1,158 @@
-// 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 mixin_typevariable_test;
-
-import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
-import 'type_test_helper.dart';
-import 'package:compiler/src/dart_types.dart';
-import "package:compiler/src/elements/elements.dart"
- show Element, ClassElement;
-
-void main() {
- testMixinSupertypes();
- testNonTrivialSubstitutions();
-}
-
-void testMixinSupertypes() {
- asyncTest(() => TypeEnvironment.create(r"""
- class S<S_T> {}
- class M1<M1_T> {}
- class M2<M2_T> {}
- class M3<M3_T> {}
-
- class C1<C1_T> extends S<C1_T> with M1<C1_T>, M2<C1_T>, M3<C1_T> {}
- class C2<C2_T> = S<C2_T> with M1<C2_T>, M2<C2_T>, M3<C2_T>;
- """, expectNoWarningsOrErrors: true).then((env) {
-
- ClassElement Object = env.getElement('Object');
- ClassElement S = env.getElement('S');
- ClassElement M1 = env.getElement('M1');
- ClassElement M2 = env.getElement('M2');
- ClassElement M3 = env.getElement('M3');
- ClassElement C1 = env.getElement('C1');
- ClassElement C2 = env.getElement('C2');
-
- ClassElement C1_S_M1_M2_M3 = C1.superclass;
- ClassElement C1_S_M1_M2 = C1_S_M1_M2_M3.superclass;
- ClassElement C1_S_M1 = C1_S_M1_M2.superclass;
-
- ClassElement C2_S_M1_M2 = C2.superclass;
- ClassElement C2_S_M1 = C2_S_M1_M2.superclass;
-
- void testSupertypes(ClassElement element) {
- if (element != Object) {
- Expect.isTrue(element.typeVariables.length == 1);
- Expect.equals(element,
- element.typeVariables.first.element.enclosingElement);
- }
- for (InterfaceType supertype in element.allSupertypesAndSelf.types) {
- if (!supertype.typeArguments.isEmpty) {
- Expect.listEquals(element.typeVariables, supertype.typeArguments,
- "Type argument mismatch on supertype $supertype of $element.");
- } else {
- Expect.equals(Object, supertype.element);
- }
- }
- }
-
- testSupertypes(Object);
- testSupertypes(S);
- testSupertypes(M1);
- testSupertypes(M2);
- testSupertypes(C1_S_M1);
- testSupertypes(C1_S_M1_M2);
- testSupertypes(C1_S_M1_M2_M3);
- testSupertypes(C1);
- testSupertypes(C2_S_M1);
- testSupertypes(C2_S_M1_M2);
- testSupertypes(C2);
- }));
-}
-
-void testNonTrivialSubstitutions() {
- asyncTest(() => TypeEnvironment.create(r"""
- class _ {}
- class A<A_T> {}
- class B<B_T, B_S> {}
-
- class C1<C1_T> extends A with B {}
- class C2<C2_T> = A with B;
-
- class D1<D1_T> extends A<D1_T> with B<D1_T, A<D1_T>> {}
- class D2<D2_T> = A<D2_T> with B<D2_T, A<D2_T>>;
-
- class E1<E1_T> extends A<_> with B<_, A<_>> {}
- class E2<E2_T> = A<_> with B<_, A<_>>;
-
- class F1<F1_T> extends A<_> with B<_, B<F1_T, _>> {}
- class F2<F2_T> = A<_> with B<_, B<F2_T, _>>;
- """, expectNoWarningsOrErrors: true).then((env) {
- DartType _dynamic = env['dynamic'];
- DartType _ = env['_'];
-
- ClassElement Object = env.getElement('Object');
- ClassElement A = env.getElement('A');
- ClassElement B = env.getElement('B');
- ClassElement C1 = env.getElement('C1');
- ClassElement C2 = env.getElement('C2');
- ClassElement D1 = env.getElement('D1');
- ClassElement D2 = env.getElement('D2');
- ClassElement E1 = env.getElement('E1');
- ClassElement E2 = env.getElement('E2');
- ClassElement F1 = env.getElement('F1');
- ClassElement F2 = env.getElement('F2');
-
- ClassElement C1_A_B = C1.superclass;
- ClassElement D1_A_B = D1.superclass;
- ClassElement E1_A_B = E1.superclass;
- ClassElement F1_A_B = F1.superclass;
-
- void testSupertypes(ClassElement element,
- Map<ClassElement, List<DartType>> typeArguments) {
- if (element != Object) {
- Expect.isTrue(element.typeVariables.length == 1);
- Expect.equals(element,
- element.typeVariables.first.element.enclosingElement);
- }
- for (InterfaceType supertype in element.allSupertypesAndSelf.types) {
- if (typeArguments.containsKey(supertype.element)) {
- Expect.listEquals(typeArguments[supertype.element],
- supertype.typeArguments,
- "Type argument mismatch on supertype $supertype of $element.");
- } else if (!supertype.typeArguments.isEmpty) {
- Expect.listEquals(element.typeVariables, supertype.typeArguments,
- "Type argument mismatch on supertype $supertype of $element.");
- } else {
- Expect.equals(Object, supertype.element);
- }
- }
- }
-
- testSupertypes(C1, {A: [_dynamic], B: [_dynamic, _dynamic]});
- testSupertypes(C1.superclass, {A: [_dynamic], B: [_dynamic, _dynamic]});
- testSupertypes(C2, {A: [_dynamic], B: [_dynamic, _dynamic]});
-
- DartType D1_T = D1.typeVariables.first;
- testSupertypes(D1, {A: [D1_T], B: [D1_T, instantiate(A, [D1_T])]});
- DartType D1_superclass_T = D1.superclass.typeVariables.first;
- testSupertypes(D1.superclass,
- {A: [D1_superclass_T],
- B: [D1_superclass_T, instantiate(A, [D1_superclass_T])]});
- DartType D2_T = D2.typeVariables.first;
- testSupertypes(D2, {A: [D2_T], B: [D2_T, instantiate(A, [D2_T])]});
-
- testSupertypes(E1, {A: [_], B: [_, instantiate(A, [_])]});
- testSupertypes(E1.superclass, {A: [_], B: [_, instantiate(A, [_])]});
- testSupertypes(E2, {A: [_], B: [_, instantiate(A, [_])]});
-
- DartType F1_T = F1.typeVariables.first;
- testSupertypes(F1, {A: [_], B: [_, instantiate(B, [F1_T, _])]});
- DartType F1_superclass_T = F1.superclass.typeVariables.first;
- testSupertypes(F1.superclass, {A: [_], B: [_, instantiate(B, [F1_superclass_T, _])]});
- DartType F2_T = F2.typeVariables.first;
- testSupertypes(F2, {A: [_], B: [_, instantiate(B, [F2_T, _])]});
- }));
-}
+// 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 mixin_typevariable_test;
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'type_test_helper.dart';
+import 'package:compiler/src/dart_types.dart';
+import "package:compiler/src/elements/elements.dart"
+ show Element, ClassElement;
+
+void main() {
+ testMixinSupertypes();
+ testNonTrivialSubstitutions();
+}
+
+void testMixinSupertypes() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class S<S_T> {}
+ class M1<M1_T> {}
+ class M2<M2_T> {}
+ class M3<M3_T> {}
+
+ class C1<C1_T> extends S<C1_T> with M1<C1_T>, M2<C1_T>, M3<C1_T> {}
+ class C2<C2_T> = S<C2_T> with M1<C2_T>, M2<C2_T>, M3<C2_T>;
+ """, expectNoWarningsOrErrors: true).then((env) {
+
+ ClassElement Object = env.getElement('Object');
+ ClassElement S = env.getElement('S');
+ ClassElement M1 = env.getElement('M1');
+ ClassElement M2 = env.getElement('M2');
+ ClassElement M3 = env.getElement('M3');
+ ClassElement C1 = env.getElement('C1');
+ ClassElement C2 = env.getElement('C2');
+
+ ClassElement C1_S_M1_M2_M3 = C1.superclass;
+ ClassElement C1_S_M1_M2 = C1_S_M1_M2_M3.superclass;
+ ClassElement C1_S_M1 = C1_S_M1_M2.superclass;
+
+ ClassElement C2_S_M1_M2 = C2.superclass;
+ ClassElement C2_S_M1 = C2_S_M1_M2.superclass;
+
+ void testSupertypes(ClassElement element) {
+ if (element != Object) {
+ Expect.isTrue(element.typeVariables.length == 1);
+ Expect.equals(element,
+ element.typeVariables.first.element.enclosingElement);
+ }
+ for (InterfaceType supertype in element.allSupertypesAndSelf.types) {
+ if (!supertype.typeArguments.isEmpty) {
+ Expect.listEquals(element.typeVariables, supertype.typeArguments,
+ "Type argument mismatch on supertype $supertype of $element.");
+ } else {
+ Expect.equals(Object, supertype.element);
+ }
+ }
+ }
+
+ testSupertypes(Object);
+ testSupertypes(S);
+ testSupertypes(M1);
+ testSupertypes(M2);
+ testSupertypes(C1_S_M1);
+ testSupertypes(C1_S_M1_M2);
+ testSupertypes(C1_S_M1_M2_M3);
+ testSupertypes(C1);
+ testSupertypes(C2_S_M1);
+ testSupertypes(C2_S_M1_M2);
+ testSupertypes(C2);
+ }));
+}
+
+void testNonTrivialSubstitutions() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class _ {}
+ class A<A_T> {}
+ class B<B_T, B_S> {}
+
+ class C1<C1_T> extends A with B {}
+ class C2<C2_T> = A with B;
+
+ class D1<D1_T> extends A<D1_T> with B<D1_T, A<D1_T>> {}
+ class D2<D2_T> = A<D2_T> with B<D2_T, A<D2_T>>;
+
+ class E1<E1_T> extends A<_> with B<_, A<_>> {}
+ class E2<E2_T> = A<_> with B<_, A<_>>;
+
+ class F1<F1_T> extends A<_> with B<_, B<F1_T, _>> {}
+ class F2<F2_T> = A<_> with B<_, B<F2_T, _>>;
+ """, expectNoWarningsOrErrors: true).then((env) {
+ DartType _dynamic = env['dynamic'];
+ DartType _ = env['_'];
+
+ ClassElement Object = env.getElement('Object');
+ ClassElement A = env.getElement('A');
+ ClassElement B = env.getElement('B');
+ ClassElement C1 = env.getElement('C1');
+ ClassElement C2 = env.getElement('C2');
+ ClassElement D1 = env.getElement('D1');
+ ClassElement D2 = env.getElement('D2');
+ ClassElement E1 = env.getElement('E1');
+ ClassElement E2 = env.getElement('E2');
+ ClassElement F1 = env.getElement('F1');
+ ClassElement F2 = env.getElement('F2');
+
+ ClassElement C1_A_B = C1.superclass;
+ ClassElement D1_A_B = D1.superclass;
+ ClassElement E1_A_B = E1.superclass;
+ ClassElement F1_A_B = F1.superclass;
+
+ void testSupertypes(ClassElement element,
+ Map<ClassElement, List<DartType>> typeArguments) {
+ if (element != Object) {
+ Expect.isTrue(element.typeVariables.length == 1);
+ Expect.equals(element,
+ element.typeVariables.first.element.enclosingElement);
+ }
+ for (InterfaceType supertype in element.allSupertypesAndSelf.types) {
+ if (typeArguments.containsKey(supertype.element)) {
+ Expect.listEquals(typeArguments[supertype.element],
+ supertype.typeArguments,
+ "Type argument mismatch on supertype $supertype of $element.");
+ } else if (!supertype.typeArguments.isEmpty) {
+ Expect.listEquals(element.typeVariables, supertype.typeArguments,
+ "Type argument mismatch on supertype $supertype of $element.");
+ } else {
+ Expect.equals(Object, supertype.element);
+ }
+ }
+ }
+
+ testSupertypes(C1, {A: [_dynamic], B: [_dynamic, _dynamic]});
+ testSupertypes(C1.superclass, {A: [_dynamic], B: [_dynamic, _dynamic]});
+ testSupertypes(C2, {A: [_dynamic], B: [_dynamic, _dynamic]});
+
+ DartType D1_T = D1.typeVariables.first;
+ testSupertypes(D1, {A: [D1_T], B: [D1_T, instantiate(A, [D1_T])]});
+ DartType D1_superclass_T = D1.superclass.typeVariables.first;
+ testSupertypes(D1.superclass,
+ {A: [D1_superclass_T],
+ B: [D1_superclass_T, instantiate(A, [D1_superclass_T])]});
+ DartType D2_T = D2.typeVariables.first;
+ testSupertypes(D2, {A: [D2_T], B: [D2_T, instantiate(A, [D2_T])]});
+
+ testSupertypes(E1, {A: [_], B: [_, instantiate(A, [_])]});
+ testSupertypes(E1.superclass, {A: [_], B: [_, instantiate(A, [_])]});
+ testSupertypes(E2, {A: [_], B: [_, instantiate(A, [_])]});
+
+ DartType F1_T = F1.typeVariables.first;
+ testSupertypes(F1, {A: [_], B: [_, instantiate(B, [F1_T, _])]});
+ DartType F1_superclass_T = F1.superclass.typeVariables.first;
+ testSupertypes(F1.superclass, {A: [_], B: [_, instantiate(B, [F1_superclass_T, _])]});
+ DartType F2_T = F2.typeVariables.first;
+ testSupertypes(F2, {A: [_], B: [_, instantiate(B, [F2_T, _])]});
+ }));
+}
diff --git a/tests/compiler/dart2js/override_inheritance_test.dart b/tests/compiler/dart2js/override_inheritance_test.dart
index 1407156..0e24785 100644
--- a/tests/compiler/dart2js/override_inheritance_test.dart
+++ b/tests/compiler/dart2js/override_inheritance_test.dart
@@ -1,1546 +1,1546 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'compiler_helper.dart';
-import 'package:compiler/src/resolution/class_members.dart'
- show MembersCreator;
-
-main() {
- asyncTest(() => Future.wait([
- testRequiredParameters(),
- testPositionalParameters(),
- testNamedParameters(),
- testNotSubtype(),
- testGetterNotSubtype(),
- testSetterNotSubtype(),
- testGenericNotSubtype(),
- testFieldNotSubtype(),
- testMixedOverride(),
- testAbstractMethods(),
- testNoSuchMethod(),
- ]));
-}
-
-Future check(String source, {errors, warnings, hints, infos}) {
- return MockCompiler.create((MockCompiler compiler) {
- compiler.diagnosticHandler = createHandler(compiler, source);
- compiler.parseScript(source);
- var cls = compiler.mainApp.find('Class');
- cls.ensureResolved(compiler);
- MembersCreator.computeAllClassMembers(compiler, cls);
-
- toList(o) => o == null ? [] : o is List ? o : [o];
-
- compareMessageKinds(source, toList(errors), compiler.errors, 'error');
-
- compareMessageKinds(source, toList(warnings), compiler.warnings, 'warning');
-
- if (infos != null) {
- compareMessageKinds(source, toList(infos), compiler.infos, 'info');
- }
-
- if (hints != null) {
- compareMessageKinds(source, toList(hints), compiler.hints, 'hint');
- }
- });
-}
-
-Future testRequiredParameters() {
- return Future.wait([
- check("""
- class A {
- method() => null; // testRequiredParameters:0
- }
- class Class extends A {
- method() => null; // testRequiredParameters:1
- }
- """),
-
- check("""
- class A {
- method(a) => null; // testRequiredParameters:2
- }
- class Class extends A {
- method(b) => null; // testRequiredParameters:3
- }
- """),
-
- check("""
- class A {
- method(a, b, c, d) => null; // testRequiredParameters:3
- }
- class Class extends A {
- method(b, a, d, c) => null; // testRequiredParameters:4
- }
- """),
-
- check("""
- class A {
- method() => null; // testRequiredParameters:5
- }
- class Class extends A {
- method(a) => null; // testRequiredParameters:6
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A {
- method() => null; // testRequiredParameters:7
- }
- class Class implements A {
- method(a) => null; // testRequiredParameters:8
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A {
- method(a, b, c) => null; // testRequiredParameters:9
- }
- class Class extends A {
- method(a, b, c, d) => null; // testRequiredParameters:10
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
- ]);
-}
-
-Future testPositionalParameters() {
- return Future.wait([
- check("""
- class A {
- method([a]) => null; // testPositionalParameters:1
- }
- class Class extends A {
- method([a]) => null; // testPositionalParameters:2
- }
- """),
-
- check("""
- class A {
- method([a, b]) => null; // testPositionalParameters:3
- }
- class Class extends A {
- method([b, a]) => null; // testPositionalParameters:4
- }
- """),
-
- check("""
- class A {
- method([a, b, c]) => null; // testPositionalParameters:5
- }
- class Class extends A {
- method([b, d, a, c]) => null; // testPositionalParameters:6
- }
- """),
-
- check("""
- class A {
- method([a]) => null; // testPositionalParameters:7
- }
- class Class extends A {
- method([a]) => null; // testPositionalParameters:8
- }
- """),
-
- check("""
- class A {
- method(a) => null; // testPositionalParameters:9
- }
- class Class extends A {
- method() => null; // testPositionalParameters:10
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A {
- method(a, [b]) => null; // testPositionalParameters:11
- }
- class Class extends A {
- method(a) => null; // testPositionalParameters:12
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A {
- method(a, [b]) => null; // testPositionalParameters:13
- }
- class Class extends A {
- method([a]) => null; // testPositionalParameters:14
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A {
- method(a, b, [c, d, e]) => null; // testPositionalParameters:15
- }
- class Class extends A {
- method([a, b, c, d]) => null; // testPositionalParameters:16
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
- ]);
-}
-
-Future testNamedParameters() {
- return Future.wait([
- check("""
- class A {
- method({a}) => null; // testNamedParameters:1
- }
- class Class extends A {
- method({a}) => null; // testNamedParameters:2
- }
- """),
-
- check("""
- class A {
- method({a, b}) => null; // testNamedParameters:3
- }
- class Class extends A {
- method({b, a}) => null; // testNamedParameters:4
- }
- """),
-
- check("""
- class A {
- method({a, b, c}) => null; // testNamedParameters:5
- }
- class Class extends A {
- method({b, c, a, d}) => null; // testNamedParameters:6
- }
- """),
-
- check("""
- class A {
- method(d, {a, b, c}) => null; // testNamedParameters:7
- }
- class Class extends A {
- method(e, {b, c, a, d}) => null; // testNamedParameters:8
- }
- """),
-
- check("""
- class A {
- method({a}) => null; // testNamedParameters:9
- }
- class Class extends A {
- method() => null; // testNamedParameters:10
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A {
- method({a, b}) => null; // testNamedParameters:11
- }
- class Class extends A {
- method({b}) => null; // testNamedParameters:12
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A {
- method({a, b, c, d}) => null; // testNamedParameters:13
- }
- class Class extends A {
- method({a, e, d, c}) => null; // testNamedParameters:14
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
- ]);
-}
-
-Future testNotSubtype() {
- return Future.wait([
- check("""
- class A {
- method(int a) => null; // testNotSubtype:1
- }
- class Class extends A {
- method(int a) => null; // testNotSubtype:2
- }
- """),
-
- check("""
- class A {
- method(int a) => null; // testNotSubtype:3
- }
- class Class extends A {
- method(num a) => null; // testNotSubtype:4
- }
- """),
-
- check("""
- class A {
- void method() {} // testNotSubtype:5
- }
- class Class extends A {
- method() => null; // testNotSubtype:6
- }
- """),
-
- check("""
- class A {
- method() => null; // testNotSubtype:7
- }
- class Class extends A {
- void method() {} // testNotSubtype:8
- }
- """),
-
- check("""
- class A {
- void method() {} // testNotSubtype:9
- }
- class Class extends A {
- int method() => null; // testNotSubtype:10
- }
- """),
-
- check("""
- class A {
- int method() => null; // testNotSubtype:11
- }
- class Class extends A {
- void method() {} // testNotSubtype:12
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A {
- method(int a) => null; // testNotSubtype:13
- }
- class B extends A {
- method(num a) => null; // testNotSubtype:14
- }
- class Class extends B {
- method(double a) => null; // testNotSubtype:15
- }
- """),
-
- check("""
- class A {
- method(int a) => null; // testNotSubtype:16
- }
- class B extends A {
- method(a) => null; // testNotSubtype:17
- }
- class Class extends B {
- method(String a) => null; // testNotSubtype:18
- }
- """),
-
- check("""
- class A {
- method(int a) => null; // testNotSubtype:19
- }
- class Class extends A {
- method(String a) => null; // testNotSubtype:20
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
- check("""
- class A {
- method(int a) => null; // testNotSubtype:23
- }
- class B {
- method(num a) => null; // testNotSubtype:24
- }
- abstract class C implements A, B {
- }
- class Class implements C {
- method(double a) => null; // testNotSubtype:25
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A {
- method(num a) => null; // testNotSubtype:29
- }
- class B {
- method(int a) => null; // testNotSubtype:30
- }
- abstract class C implements A, B {
- }
- class Class implements C {
- method(double a) => null; // testNotSubtype:31
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A {
- method(int a) => null; // testNotSubtype:26
- }
- class B {
- method(num a) => null; // testNotSubtype:27
- }
- abstract class C implements A, B {
- }
- class Class implements C {
- method(String a) => null; // testNotSubtype:28
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
- MessageKind.INVALID_OVERRIDE_METHOD],
- infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
- MessageKind.INVALID_OVERRIDDEN_METHOD]),
- ]);
-}
-
-Future testGetterNotSubtype() {
- return Future.wait([
- check("""
- class A {
- get getter => null; // testGetterNotSubtype:1
- }
- class Class extends A {
- get getter => null; // testGetterNotSubtype:2
- }
- """),
-
- check("""
- class A {
- num get getter => null; // testGetterNotSubtype:3
- }
- class Class extends A {
- num get getter => null; // testGetterNotSubtype:4
- }
- """),
-
- check("""
- class A {
- num get getter => null; // testGetterNotSubtype:5
- }
- class Class extends A {
- int get getter => null; // testGetterNotSubtype:6
- }
- """),
-
- check("""
- class A {
- int get getter => null; // testGetterNotSubtype:7
- }
- class Class extends A {
- num get getter => null; // testGetterNotSubtype:8
- }
- """),
-
- check("""
- class A {
- int get getter => null; // testGetterNotSubtype:9
- }
- class Class extends A {
- double get getter => null; // testGetterNotSubtype:10
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,
- infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
-
- check("""
- class A {
- int get getter => null; // testGetterNotSubtype:11
- }
- class B extends A {
- num get getter => null; // testGetterNotSubtype:12
- }
- class Class extends B {
- double get getter => null; // testGetterNotSubtype:13
- }
- """),
-
- check("""
- class A {
- int get getter => null; // testGetterNotSubtype:14
- }
- class B {
- num get getter => null; // testGetterNotSubtype:15
- }
- class Class extends A implements B {
- double get getter => null; // testGetterNotSubtype:16
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,
- infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
-
- check("""
- class A {
- int get getter => null; // testGetterNotSubtype:17
- }
- class B {
- String get getter => null; // testGetterNotSubtype:18
- }
- class Class extends A implements B {
- double get getter => null; // testGetterNotSubtype:19
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,
- MessageKind.INVALID_OVERRIDE_GETTER],
- infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
- MessageKind.INVALID_OVERRIDDEN_GETTER]),
-
- check("""
- class A {
- int get getter => null; // testGetterNotSubtype:20
- }
- class B {
- String get getter => null; // testGetterNotSubtype:21
- }
- class Class implements A, B {
- double get getter => null; // testGetterNotSubtype:22
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,
- MessageKind.INVALID_OVERRIDE_GETTER],
- infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
- MessageKind.INVALID_OVERRIDDEN_GETTER]),
-
- // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
- check("""
- class A {
- int get getter => null; // testGetterNotSubtype:23
- }
- class B {
- num get getter => null; // testGetterNotSubtype:24
- }
- abstract class C implements A, B {
- }
- class Class implements C {
- double get getter => null; // testGetterNotSubtype:25
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,
- infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
-
- check("""
- class A {
- int get getter => null; // testGetterNotSubtype:26
- }
- class B {
- num get getter => null; // testGetterNotSubtype:27
- }
- abstract class C implements A, B {
- }
- class Class implements C {
- String get getter => null; // testGetterNotSubtype:28
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,
- MessageKind.INVALID_OVERRIDE_GETTER],
- infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
- MessageKind.INVALID_OVERRIDDEN_GETTER]),
- ]);
-}
-
-Future testGenericNotSubtype() {
- return Future.wait([
- check("""
- class A<T> {
- method(T t) => null; // testGenericNotSubtype:1
- }
- class Class<S> extends A<S> {
- method(S s) => null; // testGenericNotSubtype:2
- }
- """),
-
- check("""
- class A<T> {
- method(T t) => null; // testGenericNotSubtype:3
- }
- class Class extends A<num> {
- method(int i) => null; // testGenericNotSubtype:4
- }
- """),
-
- check("""
- class A<T> {
- method(T t) => null; // testGenericNotSubtype:5
- }
- class B<S> {
- method(S s) => null; // testGenericNotSubtype:6
- }
- class Class extends A<double> implements B<int> {
- method(num i) => null; // testGenericNotSubtype:7
- }
- """),
-
- check("""
- class A<T> {
- method(T t) => null; // testGenericNotSubtype:8
- }
- class Class<S> extends A<S> {
- method(int i) => null; // testGenericNotSubtype:9
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A<T> {
- method(T t) => null; // testGenericNotSubtype:10
- }
- class B<S> extends A<S> {
-
- }
- class Class<U> extends B<U> {
- method(U u) => null; // testGenericNotSubtype:11
- }
- """),
-
- check("""
- class A<T> {
- method(T t) => null; // testGenericNotSubtype:12
- }
- class B<S> {
- method(S s) => null; // testGenericNotSubtype:13
- }
- class Class<U> extends A<U> implements B<num> {
- method(int i) => null; // testGenericNotSubtype:14
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A<T> {
- method(T t) => null; // testGenericNotSubtype:15
- }
- class B<S> {
- method(S s) => null; // testGenericNotSubtype:16
- }
- class Class extends A<int> implements B<String> {
- method(double d) => null; // testGenericNotSubtype:17
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
- MessageKind.INVALID_OVERRIDE_METHOD],
- infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
- MessageKind.INVALID_OVERRIDDEN_METHOD]),
-
- check("""
- class A<T> {
- method(T t) => null; // testGenericNotSubtype:18
- }
- class B<S> {
- method(S s) => null; // testGenericNotSubtype:19
- }
- class Class implements A<int>, B<String> {
- method(double d) => null; // testGenericNotSubtype:20
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
- MessageKind.INVALID_OVERRIDE_METHOD],
- infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
- MessageKind.INVALID_OVERRIDDEN_METHOD]),
-
- // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
- check("""
- class A<T> {
- method(T t) => null; // testGenericNotSubtype:21
- }
- class B<S> {
- method(S s) => null; // testGenericNotSubtype:22
- }
- abstract class C implements A<int>, B<num> {
- }
- class Class implements C {
- method(double d) => null; // testGenericNotSubtype:23
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
- infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
-
- check("""
- class A<T> {
- method(T t) => null; // testGenericNotSubtype:24
- }
- class B<S> {
- method(S s) => null; // testGenericNotSubtype:25
- }
- abstract class C implements A<int>, B<num> {
- }
- class Class implements C {
- method(String s) => null; // testGenericNotSubtype:26
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
- MessageKind.INVALID_OVERRIDE_METHOD],
- infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
- MessageKind.INVALID_OVERRIDDEN_METHOD]),
- ]);
-}
-
-Future testSetterNotSubtype() {
- return Future.wait([
- check("""
- class A {
- set setter(_) => null; // testSetterNotSubtype:1
- }
- class Class extends A {
- set setter(_) => null; // testSetterNotSubtype:2
- }
- """),
-
- check("""
- class A {
- void set setter(_) {} // testSetterNotSubtype:3
- }
- class Class extends A {
- set setter(_) => null; // testSetterNotSubtype:4
- }
- """),
-
- check("""
- class A {
- set setter(_) => null; // testSetterNotSubtype:5
- }
- class Class extends A {
- void set setter(_) {} // testSetterNotSubtype:6
- }
- """),
-
- check("""
- class A {
- set setter(_) => null; // testSetterNotSubtype:7
- }
- class Class extends A {
- void set setter(_) {} // testSetterNotSubtype:8
- }
- """),
-
- check("""
- class A {
- set setter(num _) => null; // testSetterNotSubtype:9
- }
- class Class extends A {
- set setter(num _) => null; // testSetterNotSubtype:10
- }
- """),
-
- check("""
- class A {
- set setter(num _) => null; // testSetterNotSubtype:11
- }
- class Class extends A {
- set setter(int _) => null; // testSetterNotSubtype:12
- }
- """),
-
- check("""
- class A {
- set setter(int _) => null; // testSetterNotSubtype:13
- }
- class Class extends A {
- set setter(num _) => null; // testSetterNotSubtype:14
- }
- """),
-
- check("""
- class A {
- set setter(int _) => null; // testSetterNotSubtype:15
- }
- class Class extends A {
- set setter(double _) => null; // testSetterNotSubtype:16
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,
- infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
-
- check("""
- class A {
- set setter(int _) => null; // testSetterNotSubtype:17
- }
- class B extends A {
- set setter(num _) => null; // testSetterNotSubtype:18
- }
- class Class extends B {
- set setter(double _) => null; // testSetterNotSubtype:19
- }
- """),
-
- check("""
- class A {
- set setter(int _) => null; // testSetterNotSubtype:20
- }
- class B {
- set setter(num _) => null; // testSetterNotSubtype:21
- }
- class Class extends A implements B {
- set setter(double _) => null; // testSetterNotSubtype:22
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,
- infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
-
- check("""
- class A {
- set setter(int _) => null; // testSetterNotSubtype:23
- }
- class B {
- set setter(String _) => null; // testSetterNotSubtype:24
- }
- class Class extends A implements B {
- set setter(double _) => null; // testSetterNotSubtype:25
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,
- MessageKind.INVALID_OVERRIDE_SETTER],
- infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,
- MessageKind.INVALID_OVERRIDDEN_SETTER]),
-
- check("""
- class A {
- set setter(int _) => null; // testSetterNotSubtype:26
- }
- class B {
- set setter(String _) => null; // testSetterNotSubtype:27
- }
- class Class implements A, B {
- set setter(double _) => null; // testSetterNotSubtype:28
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,
- MessageKind.INVALID_OVERRIDE_SETTER],
- infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,
- MessageKind.INVALID_OVERRIDDEN_SETTER]),
-
- // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
- check("""
- class A {
- set setter(int _) => null; // testSetterNotSubtype:29
- }
- class B {
- set setter(num _) => null; // testSetterNotSubtype:30
- }
- abstract class C implements A, B {
- }
- class Class implements C {
- set setter(double _) => null; // testSetterNotSubtype:31
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,
- infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
-
- check("""
- class A {
- set setter(int _) => null; // testSetterNotSubtype:32
- }
- class B {
- set setter(num _) => null; // testSetterNotSubtype:33
- }
- abstract class C implements A, B {
- }
- class Class implements C {
- set setter(String _) => null; // testSetterNotSubtype:34
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,
- MessageKind.INVALID_OVERRIDE_SETTER],
- infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,
- MessageKind.INVALID_OVERRIDDEN_SETTER]),
- ]);
-}
-
-Future testFieldNotSubtype() {
- return Future.wait([
- check("""
- class A {
- int field; // testFieldNotSubtype:1
- }
- class Class extends A {
- int field; // testFieldNotSubtype:2
- }
- """),
-
- check("""
- class A {
- num field; // testFieldNotSubtype:3
- }
- class Class extends A {
- int field; // testFieldNotSubtype:4
- }
- """),
-
- check("""
- class A {
- int field; // testFieldNotSubtype:5
- }
- class Class extends A {
- num field; // testFieldNotSubtype:6
- }
- """),
-
- check("""
- class A {
- int field; // testFieldNotSubtype:7
- }
- class Class extends A {
- double field; // testFieldNotSubtype:8
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_FIELD,
- infos: MessageKind.INVALID_OVERRIDDEN_FIELD),
-
- check("""
- class A {
- int field; // testFieldNotSubtype:9
- }
- class B extends A {
- num field; // testFieldNotSubtype:10
- }
- class Class extends B {
- double field; // testFieldNotSubtype:11
- }
- """),
-
- check("""
- class A {
- num field; // testFieldNotSubtype:12
- }
- class Class extends A {
- int get field => null; // testFieldNotSubtype:13
- }
- """),
-
- check("""
- class A {
- num field; // testFieldNotSubtype:14
- }
- class Class extends A {
- String get field => null; // testFieldNotSubtype:15
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
- infos: MessageKind.INVALID_OVERRIDDEN_FIELD),
-
- check("""
- class A {
- num get field => null; // testFieldNotSubtype:16
- }
- class Class extends A {
- String field; // testFieldNotSubtype:17
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
- infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
-
- check("""
- class A {
- num field; // testFieldNotSubtype:18
- }
- class Class extends A {
- set field(int _) {} // testFieldNotSubtype:19
- }
- """),
-
- check("""
- class A {
- num field; // testFieldNotSubtype:19
- }
- class Class extends A {
- void set field(int _) {} // testFieldNotSubtype:20
- }
- """),
-
- check("""
- class A {
- set field(int _) {} // testFieldNotSubtype:21
- }
- class Class extends A {
- num field; // testFieldNotSubtype:22
- }
- """),
-
- check("""
- class A {
- void set field(int _) {} // testFieldNotSubtype:23
- }
- class Class extends A {
- num field; // testFieldNotSubtype:24
- }
- """),
-
- check("""
- class A {
- num field; // testFieldNotSubtype:25
- }
- class Class extends A {
- set field(String _) {} // testFieldNotSubtype:26
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,
- infos: MessageKind.INVALID_OVERRIDDEN_FIELD),
-
- check("""
- class A {
- set field(num _) {} // testFieldNotSubtype:27
- }
- class Class extends A {
- String field; // testFieldNotSubtype:28
- }
- """, warnings: MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,
- infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
-
- check("""
- class A {
- int field; // testFieldNotSubtype:29
- }
- class Class implements A {
- String get field => null; // testFieldNotSubtype:30
- void set field(String s) {} // testFieldNotSubtype:31
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
- MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER],
- infos: [MessageKind.INVALID_OVERRIDDEN_FIELD,
- MessageKind.INVALID_OVERRIDDEN_FIELD]),
-
-
- check("""
- class A {
- String get field => null; // testFieldNotSubtype:32
- void set field(String s) {} // testFieldNotSubtype:33
- }
- class Class implements A {
- int field; // testFieldNotSubtype:34
- }
- """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
- MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD],
- infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
- MessageKind.INVALID_OVERRIDDEN_SETTER]),
- ]);
-}
-
-Future testMixedOverride() {
- return Future.wait([
- check("""
- class A {
- var member; // testMixedOverride:1
- }
- class Class extends A {
- member() {} // testMixedOverride:2
- }
- """, errors: MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
- infos: MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT),
-
- check("""
- class A {
- member() {} // testMixedOverride:3
- }
- class Class extends A {
- var member; // testMixedOverride:4
- }
- """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
- infos: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT),
-
- check("""
- class A {
- get member => null; // testMixedOverride:5
- }
- class Class extends A {
- member() {} // testMixedOverride:6
- }
- """, errors: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
- infos: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT),
-
- check("""
- class A {
- member() {} // testMixedOverride:7
- }
- class Class extends A {
- get member => null; // testMixedOverride:8
- }
- """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
- infos: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT),
-
- check("""
- abstract class A {
- var member; // testMixedOverride:9
- }
- abstract class B {
- get member; // testMixedOverride:10
- }
- abstract class Class implements A, B {
- }
- """),
-
- check("""
- abstract class A {
- var member; // testMixedOverride:11
- }
- abstract class B {
- member() {} // testMixedOverride:12
- }
- abstract class Class implements A, B {
- }
- """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
- infos: [MessageKind.INHERITED_METHOD,
- MessageKind.INHERITED_IMPLICIT_GETTER]),
-
- check("""
- abstract class A {
- get member; // testMixedOverride:13
- }
- abstract class B {
- member() {} // testMixedOverride:14
- }
- abstract class Class implements A, B {
- }
- """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
- infos: [MessageKind.INHERITED_METHOD,
- MessageKind.INHERITED_EXPLICIT_GETTER]),
-
- check("""
- abstract class A {
- get member; // testMixedOverride:15
- }
- abstract class B {
- member() {} // testMixedOverride:16
- }
- abstract class C {
- var member; // testMixedOverride:17
- }
- abstract class D {
- member() {} // testMixedOverride:18
- }
- abstract class E {
- get member; // testMixedOverride:19
- }
- abstract class Class implements A, B, C, D, E {
- }
- """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
- infos: [MessageKind.INHERITED_EXPLICIT_GETTER,
- MessageKind.INHERITED_METHOD,
- MessageKind.INHERITED_IMPLICIT_GETTER,
- MessageKind.INHERITED_METHOD,
- MessageKind.INHERITED_EXPLICIT_GETTER]),
-
- check("""
- abstract class A {
- get member; // testMixedOverride:20
- }
- abstract class B {
- member() {} // testMixedOverride:21
- }
- abstract class C implements A, B {
- }
- class Class extends C {
- member() {} // testMixedOverride:22
- }
- """, errors: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
- warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
- infos: [MessageKind.INHERITED_METHOD,
- MessageKind.INHERITED_EXPLICIT_GETTER,
- MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT]),
-
- check("""
- abstract class A {
- get member; // testMixedOverride:23
- }
- abstract class B {
- member() {} // testMixedOverride:24
- }
- abstract class C implements A, B {
- }
- class Class extends C {
- get member => null; // testMixedOverride:25
- }
- """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
- warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
- infos: [MessageKind.INHERITED_METHOD,
- MessageKind.INHERITED_EXPLICIT_GETTER,
- MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT]),
- ]);
-}
-
-Future testAbstractMethods() {
- return Future.wait([
- check("""
- abstract class Class {
- method(); // testAbstractMethod:1
- }
- """),
-
- check("""
- class Class {
- method(); // testAbstractMethod:2
- }
- """, warnings: MessageKind.ABSTRACT_METHOD,
- infos: []),
-
- check("""
- class Class {
- get getter; // testAbstractMethod:3
- }
- """, warnings: MessageKind.ABSTRACT_GETTER,
- infos: []),
-
- check("""
- class Class {
- set setter(_); // testAbstractMethod:4
- }
- """, warnings: MessageKind.ABSTRACT_SETTER,
- infos: []),
-
- check("""
- abstract class A {
- method(); // testAbstractMethod:5
- }
- class Class extends A {
- method() {} // testAbstractMethod:6
- }
- """),
-
- check("""
- abstract class A {
- method(); // testAbstractMethod:7
- }
- class Class extends A {
- method([a]) {} // testAbstractMethod:8
- }
- """),
-
- check("""
- abstract class A {
- method(); // testAbstractMethod:9
- }
- class Class extends A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
- infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
-
- check("""
- abstract class A {
- get getter; // testAbstractMethod:10
- }
- class Class extends A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,
- infos: MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER),
-
- check("""
- abstract class A {
- set setter(_); // testAbstractMethod:11
- }
- class Class extends A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
- infos: MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER),
-
- check("""
- abstract class A {
- method(); // testAbstractMethod:12
- }
- class B {
- method() {} // testAbstractMethod:13
- }
- class Class extends A implements B {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_METHOD,
- infos: [MessageKind.UNIMPLEMENTED_METHOD_CONT,
- MessageKind.UNIMPLEMENTED_METHOD_CONT]),
-
- check("""
- class Class implements Function {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
- infos: []),
-
- check("""
- abstract class A {
- get getter; // testAbstractMethod:14
- }
- class B {
- get getter => 0; // testAbstractMethod:15
- }
- class Class extends A implements B {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_GETTER,
- infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
- MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER]),
-
- check("""
- abstract class A {
- set setter(_); // testAbstractMethod:16
- }
- class B {
- set setter(_) {} // testAbstractMethod:17
- }
- class Class extends A implements B {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_SETTER,
- infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
- MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER]),
-
- check("""
- abstract class A {
- get field; // testAbstractMethod:18
- }
- class B {
- var field; // testAbstractMethod:19
- }
- class Class extends A implements B {
- set field(_) {} // testAbstractMethod:20
- }
- """, warnings: MessageKind.UNIMPLEMENTED_GETTER,
- infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
- MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER]),
-
- check("""
- abstract class A {
- set field(_); // testAbstractMethod:21
- }
- class B {
- var field; // testAbstractMethod:22
- }
- class Class extends A implements B {
- get field => 0; // testAbstractMethod:23
- }
- """, warnings: MessageKind.UNIMPLEMENTED_SETTER,
- infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
- MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
-
- check("""
- class A {
- method() {} // testAbstractMethod:24
- }
- class Class implements A {
- method() {} // testAbstractMethod:25
- }
- """),
-
- check("""
- class A {
- method() {} // testAbstractMethod:26
- }
- class Class implements A {
- method([a]) {} // testAbstractMethod:27
- }
- """),
-
- check("""
- class A {
- method() {} // testAbstractMethod:28
- }
- class Class implements A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
- infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
-
- check("""
- class A {
- method() {} // testAbstractMethod:29
- }
- class B {
- method() {} // testAbstractMethod:30
- }
- class Class extends A implements B {
- }
- """),
-
- check("""
- class A {
- var member; // testAbstractMethod:31
- }
- class Class implements A {
- }
- """, warnings: [MessageKind.UNIMPLEMENTED_GETTER_ONE,
- MessageKind.UNIMPLEMENTED_SETTER_ONE],
- infos: [MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
- MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
-
- check("""
- class A {
- var member; // testAbstractMethod:32
- }
- class B {
- get member => null; // testAbstractMethod:33
- set member(_) {} // testAbstractMethod:34
- }
- class Class implements A, B {
- }
- """, warnings: [MessageKind.UNIMPLEMENTED_GETTER,
- MessageKind.UNIMPLEMENTED_SETTER],
- infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
- MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
- MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
- MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
-
- check("""
- class A {
- var member; // testAbstractMethod:35
- }
- class B {
- var member; // testAbstractMethod:36
- }
- class Class implements A, B {
- }
- """, warnings: [MessageKind.UNIMPLEMENTED_GETTER,
- MessageKind.UNIMPLEMENTED_SETTER],
- infos: [MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
- MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
- MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER,
- MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
-
- check("""
- class A {
- get member => 0; // testAbstractMethod:37
- }
- class Class implements A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,
- infos: MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER),
-
- check("""
- class A {
- set member(_) {} // testAbstractMethod:38
- }
- class Class implements A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
- infos: MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER),
-
- check("""
- class A {
- var member; // testAbstractMethod:39
- }
- class Class implements A {
- get member => 0;
- }
- """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
- infos: MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER),
-
- check("""
- class A {
- var field; // testAbstractMethod:40
- }
- class Class implements A {
- final field = 0; // testAbstractMethod:41
- }
- """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
- infos: MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER),
-
- check("""
- class A {
- var member; // testAbstractMethod:42
- }
- class Class implements A {
- set member(_) {}
- }
- """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,
- infos: MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER),
-
- check("""
- abstract class A {
- method() {} // testAbstractMethod:43
- }
- class Class extends A {
- method();
- }
- """),
- ]);
-}
-
-Future testNoSuchMethod() {
- return Future.wait([
- check("""
- class Class {
- method(); // testNoSuchMethod:1
- }
- """, warnings: MessageKind.ABSTRACT_METHOD,
- infos: []),
-
- check("""
- @proxy
- class Class {
- method(); // testNoSuchMethod:2
- }
- """, warnings: MessageKind.ABSTRACT_METHOD,
- infos: []),
-
- check("""
- class Class {
- noSuchMethod(_) => null;
- method(); // testNoSuchMethod:3
- }
- """),
-
- check("""
- class Class {
- noSuchMethod(_, [__]) => null;
- method(); // testNoSuchMethod:4
- }
- """),
-
- check("""
- class Class {
- noSuchMethod(_);
- method(); // testNoSuchMethod:5
- }
- """),
-
- check("""
- abstract class A {
- method(); // testNoSuchMethod:6
- }
- class Class extends A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
- infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
-
- check("""
- abstract class A {
- method(); // testNoSuchMethod:7
- }
- @proxy
- class Class extends A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
- infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
-
- check("""
- abstract class A {
- method(); // testNoSuchMethod:8
- }
- class Class extends A {
- noSuchMethod(_) => null;
- }
- """),
-
- check("""
- class A {
- method() {} // testNoSuchMethod:9
- }
- class Class implements A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
- infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
-
- check("""
- class A {
- method() {} // testNoSuchMethod:10
- }
- class Class implements A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
- infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
-
- check("""
- class A {
- method() {} // testNoSuchMethod:11
- }
- @proxy
- class Class implements A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
- infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
-
- check("""
- class A {
- method() {} // testNoSuchMethod:12
- }
- class Class implements A {
- noSuchMethod(_) => null;
- }
- """),
-
- check("""
- class A {
- noSuchMethod(_) => null;
- method(); // testNoSuchMethod:13
- }
- class Class extends A {
- }
- """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
- infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
- ]);
-}
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'compiler_helper.dart';
+import 'package:compiler/src/resolution/class_members.dart'
+ show MembersCreator;
+
+main() {
+ asyncTest(() => Future.wait([
+ testRequiredParameters(),
+ testPositionalParameters(),
+ testNamedParameters(),
+ testNotSubtype(),
+ testGetterNotSubtype(),
+ testSetterNotSubtype(),
+ testGenericNotSubtype(),
+ testFieldNotSubtype(),
+ testMixedOverride(),
+ testAbstractMethods(),
+ testNoSuchMethod(),
+ ]));
+}
+
+Future check(String source, {errors, warnings, hints, infos}) {
+ return MockCompiler.create((MockCompiler compiler) {
+ compiler.diagnosticHandler = createHandler(compiler, source);
+ compiler.parseScript(source);
+ var cls = compiler.mainApp.find('Class');
+ cls.ensureResolved(compiler);
+ MembersCreator.computeAllClassMembers(compiler, cls);
+
+ toList(o) => o == null ? [] : o is List ? o : [o];
+
+ compareMessageKinds(source, toList(errors), compiler.errors, 'error');
+
+ compareMessageKinds(source, toList(warnings), compiler.warnings, 'warning');
+
+ if (infos != null) {
+ compareMessageKinds(source, toList(infos), compiler.infos, 'info');
+ }
+
+ if (hints != null) {
+ compareMessageKinds(source, toList(hints), compiler.hints, 'hint');
+ }
+ });
+}
+
+Future testRequiredParameters() {
+ return Future.wait([
+ check("""
+ class A {
+ method() => null; // testRequiredParameters:0
+ }
+ class Class extends A {
+ method() => null; // testRequiredParameters:1
+ }
+ """),
+
+ check("""
+ class A {
+ method(a) => null; // testRequiredParameters:2
+ }
+ class Class extends A {
+ method(b) => null; // testRequiredParameters:3
+ }
+ """),
+
+ check("""
+ class A {
+ method(a, b, c, d) => null; // testRequiredParameters:3
+ }
+ class Class extends A {
+ method(b, a, d, c) => null; // testRequiredParameters:4
+ }
+ """),
+
+ check("""
+ class A {
+ method() => null; // testRequiredParameters:5
+ }
+ class Class extends A {
+ method(a) => null; // testRequiredParameters:6
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A {
+ method() => null; // testRequiredParameters:7
+ }
+ class Class implements A {
+ method(a) => null; // testRequiredParameters:8
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A {
+ method(a, b, c) => null; // testRequiredParameters:9
+ }
+ class Class extends A {
+ method(a, b, c, d) => null; // testRequiredParameters:10
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+ ]);
+}
+
+Future testPositionalParameters() {
+ return Future.wait([
+ check("""
+ class A {
+ method([a]) => null; // testPositionalParameters:1
+ }
+ class Class extends A {
+ method([a]) => null; // testPositionalParameters:2
+ }
+ """),
+
+ check("""
+ class A {
+ method([a, b]) => null; // testPositionalParameters:3
+ }
+ class Class extends A {
+ method([b, a]) => null; // testPositionalParameters:4
+ }
+ """),
+
+ check("""
+ class A {
+ method([a, b, c]) => null; // testPositionalParameters:5
+ }
+ class Class extends A {
+ method([b, d, a, c]) => null; // testPositionalParameters:6
+ }
+ """),
+
+ check("""
+ class A {
+ method([a]) => null; // testPositionalParameters:7
+ }
+ class Class extends A {
+ method([a]) => null; // testPositionalParameters:8
+ }
+ """),
+
+ check("""
+ class A {
+ method(a) => null; // testPositionalParameters:9
+ }
+ class Class extends A {
+ method() => null; // testPositionalParameters:10
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A {
+ method(a, [b]) => null; // testPositionalParameters:11
+ }
+ class Class extends A {
+ method(a) => null; // testPositionalParameters:12
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A {
+ method(a, [b]) => null; // testPositionalParameters:13
+ }
+ class Class extends A {
+ method([a]) => null; // testPositionalParameters:14
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A {
+ method(a, b, [c, d, e]) => null; // testPositionalParameters:15
+ }
+ class Class extends A {
+ method([a, b, c, d]) => null; // testPositionalParameters:16
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+ ]);
+}
+
+Future testNamedParameters() {
+ return Future.wait([
+ check("""
+ class A {
+ method({a}) => null; // testNamedParameters:1
+ }
+ class Class extends A {
+ method({a}) => null; // testNamedParameters:2
+ }
+ """),
+
+ check("""
+ class A {
+ method({a, b}) => null; // testNamedParameters:3
+ }
+ class Class extends A {
+ method({b, a}) => null; // testNamedParameters:4
+ }
+ """),
+
+ check("""
+ class A {
+ method({a, b, c}) => null; // testNamedParameters:5
+ }
+ class Class extends A {
+ method({b, c, a, d}) => null; // testNamedParameters:6
+ }
+ """),
+
+ check("""
+ class A {
+ method(d, {a, b, c}) => null; // testNamedParameters:7
+ }
+ class Class extends A {
+ method(e, {b, c, a, d}) => null; // testNamedParameters:8
+ }
+ """),
+
+ check("""
+ class A {
+ method({a}) => null; // testNamedParameters:9
+ }
+ class Class extends A {
+ method() => null; // testNamedParameters:10
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A {
+ method({a, b}) => null; // testNamedParameters:11
+ }
+ class Class extends A {
+ method({b}) => null; // testNamedParameters:12
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A {
+ method({a, b, c, d}) => null; // testNamedParameters:13
+ }
+ class Class extends A {
+ method({a, e, d, c}) => null; // testNamedParameters:14
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+ ]);
+}
+
+Future testNotSubtype() {
+ return Future.wait([
+ check("""
+ class A {
+ method(int a) => null; // testNotSubtype:1
+ }
+ class Class extends A {
+ method(int a) => null; // testNotSubtype:2
+ }
+ """),
+
+ check("""
+ class A {
+ method(int a) => null; // testNotSubtype:3
+ }
+ class Class extends A {
+ method(num a) => null; // testNotSubtype:4
+ }
+ """),
+
+ check("""
+ class A {
+ void method() {} // testNotSubtype:5
+ }
+ class Class extends A {
+ method() => null; // testNotSubtype:6
+ }
+ """),
+
+ check("""
+ class A {
+ method() => null; // testNotSubtype:7
+ }
+ class Class extends A {
+ void method() {} // testNotSubtype:8
+ }
+ """),
+
+ check("""
+ class A {
+ void method() {} // testNotSubtype:9
+ }
+ class Class extends A {
+ int method() => null; // testNotSubtype:10
+ }
+ """),
+
+ check("""
+ class A {
+ int method() => null; // testNotSubtype:11
+ }
+ class Class extends A {
+ void method() {} // testNotSubtype:12
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A {
+ method(int a) => null; // testNotSubtype:13
+ }
+ class B extends A {
+ method(num a) => null; // testNotSubtype:14
+ }
+ class Class extends B {
+ method(double a) => null; // testNotSubtype:15
+ }
+ """),
+
+ check("""
+ class A {
+ method(int a) => null; // testNotSubtype:16
+ }
+ class B extends A {
+ method(a) => null; // testNotSubtype:17
+ }
+ class Class extends B {
+ method(String a) => null; // testNotSubtype:18
+ }
+ """),
+
+ check("""
+ class A {
+ method(int a) => null; // testNotSubtype:19
+ }
+ class Class extends A {
+ method(String a) => null; // testNotSubtype:20
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
+ check("""
+ class A {
+ method(int a) => null; // testNotSubtype:23
+ }
+ class B {
+ method(num a) => null; // testNotSubtype:24
+ }
+ abstract class C implements A, B {
+ }
+ class Class implements C {
+ method(double a) => null; // testNotSubtype:25
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A {
+ method(num a) => null; // testNotSubtype:29
+ }
+ class B {
+ method(int a) => null; // testNotSubtype:30
+ }
+ abstract class C implements A, B {
+ }
+ class Class implements C {
+ method(double a) => null; // testNotSubtype:31
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A {
+ method(int a) => null; // testNotSubtype:26
+ }
+ class B {
+ method(num a) => null; // testNotSubtype:27
+ }
+ abstract class C implements A, B {
+ }
+ class Class implements C {
+ method(String a) => null; // testNotSubtype:28
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
+ MessageKind.INVALID_OVERRIDE_METHOD],
+ infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
+ MessageKind.INVALID_OVERRIDDEN_METHOD]),
+ ]);
+}
+
+Future testGetterNotSubtype() {
+ return Future.wait([
+ check("""
+ class A {
+ get getter => null; // testGetterNotSubtype:1
+ }
+ class Class extends A {
+ get getter => null; // testGetterNotSubtype:2
+ }
+ """),
+
+ check("""
+ class A {
+ num get getter => null; // testGetterNotSubtype:3
+ }
+ class Class extends A {
+ num get getter => null; // testGetterNotSubtype:4
+ }
+ """),
+
+ check("""
+ class A {
+ num get getter => null; // testGetterNotSubtype:5
+ }
+ class Class extends A {
+ int get getter => null; // testGetterNotSubtype:6
+ }
+ """),
+
+ check("""
+ class A {
+ int get getter => null; // testGetterNotSubtype:7
+ }
+ class Class extends A {
+ num get getter => null; // testGetterNotSubtype:8
+ }
+ """),
+
+ check("""
+ class A {
+ int get getter => null; // testGetterNotSubtype:9
+ }
+ class Class extends A {
+ double get getter => null; // testGetterNotSubtype:10
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,
+ infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
+
+ check("""
+ class A {
+ int get getter => null; // testGetterNotSubtype:11
+ }
+ class B extends A {
+ num get getter => null; // testGetterNotSubtype:12
+ }
+ class Class extends B {
+ double get getter => null; // testGetterNotSubtype:13
+ }
+ """),
+
+ check("""
+ class A {
+ int get getter => null; // testGetterNotSubtype:14
+ }
+ class B {
+ num get getter => null; // testGetterNotSubtype:15
+ }
+ class Class extends A implements B {
+ double get getter => null; // testGetterNotSubtype:16
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,
+ infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
+
+ check("""
+ class A {
+ int get getter => null; // testGetterNotSubtype:17
+ }
+ class B {
+ String get getter => null; // testGetterNotSubtype:18
+ }
+ class Class extends A implements B {
+ double get getter => null; // testGetterNotSubtype:19
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,
+ MessageKind.INVALID_OVERRIDE_GETTER],
+ infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
+ MessageKind.INVALID_OVERRIDDEN_GETTER]),
+
+ check("""
+ class A {
+ int get getter => null; // testGetterNotSubtype:20
+ }
+ class B {
+ String get getter => null; // testGetterNotSubtype:21
+ }
+ class Class implements A, B {
+ double get getter => null; // testGetterNotSubtype:22
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,
+ MessageKind.INVALID_OVERRIDE_GETTER],
+ infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
+ MessageKind.INVALID_OVERRIDDEN_GETTER]),
+
+ // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
+ check("""
+ class A {
+ int get getter => null; // testGetterNotSubtype:23
+ }
+ class B {
+ num get getter => null; // testGetterNotSubtype:24
+ }
+ abstract class C implements A, B {
+ }
+ class Class implements C {
+ double get getter => null; // testGetterNotSubtype:25
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,
+ infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
+
+ check("""
+ class A {
+ int get getter => null; // testGetterNotSubtype:26
+ }
+ class B {
+ num get getter => null; // testGetterNotSubtype:27
+ }
+ abstract class C implements A, B {
+ }
+ class Class implements C {
+ String get getter => null; // testGetterNotSubtype:28
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,
+ MessageKind.INVALID_OVERRIDE_GETTER],
+ infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
+ MessageKind.INVALID_OVERRIDDEN_GETTER]),
+ ]);
+}
+
+Future testGenericNotSubtype() {
+ return Future.wait([
+ check("""
+ class A<T> {
+ method(T t) => null; // testGenericNotSubtype:1
+ }
+ class Class<S> extends A<S> {
+ method(S s) => null; // testGenericNotSubtype:2
+ }
+ """),
+
+ check("""
+ class A<T> {
+ method(T t) => null; // testGenericNotSubtype:3
+ }
+ class Class extends A<num> {
+ method(int i) => null; // testGenericNotSubtype:4
+ }
+ """),
+
+ check("""
+ class A<T> {
+ method(T t) => null; // testGenericNotSubtype:5
+ }
+ class B<S> {
+ method(S s) => null; // testGenericNotSubtype:6
+ }
+ class Class extends A<double> implements B<int> {
+ method(num i) => null; // testGenericNotSubtype:7
+ }
+ """),
+
+ check("""
+ class A<T> {
+ method(T t) => null; // testGenericNotSubtype:8
+ }
+ class Class<S> extends A<S> {
+ method(int i) => null; // testGenericNotSubtype:9
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A<T> {
+ method(T t) => null; // testGenericNotSubtype:10
+ }
+ class B<S> extends A<S> {
+
+ }
+ class Class<U> extends B<U> {
+ method(U u) => null; // testGenericNotSubtype:11
+ }
+ """),
+
+ check("""
+ class A<T> {
+ method(T t) => null; // testGenericNotSubtype:12
+ }
+ class B<S> {
+ method(S s) => null; // testGenericNotSubtype:13
+ }
+ class Class<U> extends A<U> implements B<num> {
+ method(int i) => null; // testGenericNotSubtype:14
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A<T> {
+ method(T t) => null; // testGenericNotSubtype:15
+ }
+ class B<S> {
+ method(S s) => null; // testGenericNotSubtype:16
+ }
+ class Class extends A<int> implements B<String> {
+ method(double d) => null; // testGenericNotSubtype:17
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
+ MessageKind.INVALID_OVERRIDE_METHOD],
+ infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
+ MessageKind.INVALID_OVERRIDDEN_METHOD]),
+
+ check("""
+ class A<T> {
+ method(T t) => null; // testGenericNotSubtype:18
+ }
+ class B<S> {
+ method(S s) => null; // testGenericNotSubtype:19
+ }
+ class Class implements A<int>, B<String> {
+ method(double d) => null; // testGenericNotSubtype:20
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
+ MessageKind.INVALID_OVERRIDE_METHOD],
+ infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
+ MessageKind.INVALID_OVERRIDDEN_METHOD]),
+
+ // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
+ check("""
+ class A<T> {
+ method(T t) => null; // testGenericNotSubtype:21
+ }
+ class B<S> {
+ method(S s) => null; // testGenericNotSubtype:22
+ }
+ abstract class C implements A<int>, B<num> {
+ }
+ class Class implements C {
+ method(double d) => null; // testGenericNotSubtype:23
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+ infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+ check("""
+ class A<T> {
+ method(T t) => null; // testGenericNotSubtype:24
+ }
+ class B<S> {
+ method(S s) => null; // testGenericNotSubtype:25
+ }
+ abstract class C implements A<int>, B<num> {
+ }
+ class Class implements C {
+ method(String s) => null; // testGenericNotSubtype:26
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
+ MessageKind.INVALID_OVERRIDE_METHOD],
+ infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
+ MessageKind.INVALID_OVERRIDDEN_METHOD]),
+ ]);
+}
+
+Future testSetterNotSubtype() {
+ return Future.wait([
+ check("""
+ class A {
+ set setter(_) => null; // testSetterNotSubtype:1
+ }
+ class Class extends A {
+ set setter(_) => null; // testSetterNotSubtype:2
+ }
+ """),
+
+ check("""
+ class A {
+ void set setter(_) {} // testSetterNotSubtype:3
+ }
+ class Class extends A {
+ set setter(_) => null; // testSetterNotSubtype:4
+ }
+ """),
+
+ check("""
+ class A {
+ set setter(_) => null; // testSetterNotSubtype:5
+ }
+ class Class extends A {
+ void set setter(_) {} // testSetterNotSubtype:6
+ }
+ """),
+
+ check("""
+ class A {
+ set setter(_) => null; // testSetterNotSubtype:7
+ }
+ class Class extends A {
+ void set setter(_) {} // testSetterNotSubtype:8
+ }
+ """),
+
+ check("""
+ class A {
+ set setter(num _) => null; // testSetterNotSubtype:9
+ }
+ class Class extends A {
+ set setter(num _) => null; // testSetterNotSubtype:10
+ }
+ """),
+
+ check("""
+ class A {
+ set setter(num _) => null; // testSetterNotSubtype:11
+ }
+ class Class extends A {
+ set setter(int _) => null; // testSetterNotSubtype:12
+ }
+ """),
+
+ check("""
+ class A {
+ set setter(int _) => null; // testSetterNotSubtype:13
+ }
+ class Class extends A {
+ set setter(num _) => null; // testSetterNotSubtype:14
+ }
+ """),
+
+ check("""
+ class A {
+ set setter(int _) => null; // testSetterNotSubtype:15
+ }
+ class Class extends A {
+ set setter(double _) => null; // testSetterNotSubtype:16
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,
+ infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
+
+ check("""
+ class A {
+ set setter(int _) => null; // testSetterNotSubtype:17
+ }
+ class B extends A {
+ set setter(num _) => null; // testSetterNotSubtype:18
+ }
+ class Class extends B {
+ set setter(double _) => null; // testSetterNotSubtype:19
+ }
+ """),
+
+ check("""
+ class A {
+ set setter(int _) => null; // testSetterNotSubtype:20
+ }
+ class B {
+ set setter(num _) => null; // testSetterNotSubtype:21
+ }
+ class Class extends A implements B {
+ set setter(double _) => null; // testSetterNotSubtype:22
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,
+ infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
+
+ check("""
+ class A {
+ set setter(int _) => null; // testSetterNotSubtype:23
+ }
+ class B {
+ set setter(String _) => null; // testSetterNotSubtype:24
+ }
+ class Class extends A implements B {
+ set setter(double _) => null; // testSetterNotSubtype:25
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,
+ MessageKind.INVALID_OVERRIDE_SETTER],
+ infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,
+ MessageKind.INVALID_OVERRIDDEN_SETTER]),
+
+ check("""
+ class A {
+ set setter(int _) => null; // testSetterNotSubtype:26
+ }
+ class B {
+ set setter(String _) => null; // testSetterNotSubtype:27
+ }
+ class Class implements A, B {
+ set setter(double _) => null; // testSetterNotSubtype:28
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,
+ MessageKind.INVALID_OVERRIDE_SETTER],
+ infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,
+ MessageKind.INVALID_OVERRIDDEN_SETTER]),
+
+ // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
+ check("""
+ class A {
+ set setter(int _) => null; // testSetterNotSubtype:29
+ }
+ class B {
+ set setter(num _) => null; // testSetterNotSubtype:30
+ }
+ abstract class C implements A, B {
+ }
+ class Class implements C {
+ set setter(double _) => null; // testSetterNotSubtype:31
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,
+ infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
+
+ check("""
+ class A {
+ set setter(int _) => null; // testSetterNotSubtype:32
+ }
+ class B {
+ set setter(num _) => null; // testSetterNotSubtype:33
+ }
+ abstract class C implements A, B {
+ }
+ class Class implements C {
+ set setter(String _) => null; // testSetterNotSubtype:34
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,
+ MessageKind.INVALID_OVERRIDE_SETTER],
+ infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,
+ MessageKind.INVALID_OVERRIDDEN_SETTER]),
+ ]);
+}
+
+Future testFieldNotSubtype() {
+ return Future.wait([
+ check("""
+ class A {
+ int field; // testFieldNotSubtype:1
+ }
+ class Class extends A {
+ int field; // testFieldNotSubtype:2
+ }
+ """),
+
+ check("""
+ class A {
+ num field; // testFieldNotSubtype:3
+ }
+ class Class extends A {
+ int field; // testFieldNotSubtype:4
+ }
+ """),
+
+ check("""
+ class A {
+ int field; // testFieldNotSubtype:5
+ }
+ class Class extends A {
+ num field; // testFieldNotSubtype:6
+ }
+ """),
+
+ check("""
+ class A {
+ int field; // testFieldNotSubtype:7
+ }
+ class Class extends A {
+ double field; // testFieldNotSubtype:8
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_FIELD,
+ infos: MessageKind.INVALID_OVERRIDDEN_FIELD),
+
+ check("""
+ class A {
+ int field; // testFieldNotSubtype:9
+ }
+ class B extends A {
+ num field; // testFieldNotSubtype:10
+ }
+ class Class extends B {
+ double field; // testFieldNotSubtype:11
+ }
+ """),
+
+ check("""
+ class A {
+ num field; // testFieldNotSubtype:12
+ }
+ class Class extends A {
+ int get field => null; // testFieldNotSubtype:13
+ }
+ """),
+
+ check("""
+ class A {
+ num field; // testFieldNotSubtype:14
+ }
+ class Class extends A {
+ String get field => null; // testFieldNotSubtype:15
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
+ infos: MessageKind.INVALID_OVERRIDDEN_FIELD),
+
+ check("""
+ class A {
+ num get field => null; // testFieldNotSubtype:16
+ }
+ class Class extends A {
+ String field; // testFieldNotSubtype:17
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
+ infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
+
+ check("""
+ class A {
+ num field; // testFieldNotSubtype:18
+ }
+ class Class extends A {
+ set field(int _) {} // testFieldNotSubtype:19
+ }
+ """),
+
+ check("""
+ class A {
+ num field; // testFieldNotSubtype:19
+ }
+ class Class extends A {
+ void set field(int _) {} // testFieldNotSubtype:20
+ }
+ """),
+
+ check("""
+ class A {
+ set field(int _) {} // testFieldNotSubtype:21
+ }
+ class Class extends A {
+ num field; // testFieldNotSubtype:22
+ }
+ """),
+
+ check("""
+ class A {
+ void set field(int _) {} // testFieldNotSubtype:23
+ }
+ class Class extends A {
+ num field; // testFieldNotSubtype:24
+ }
+ """),
+
+ check("""
+ class A {
+ num field; // testFieldNotSubtype:25
+ }
+ class Class extends A {
+ set field(String _) {} // testFieldNotSubtype:26
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,
+ infos: MessageKind.INVALID_OVERRIDDEN_FIELD),
+
+ check("""
+ class A {
+ set field(num _) {} // testFieldNotSubtype:27
+ }
+ class Class extends A {
+ String field; // testFieldNotSubtype:28
+ }
+ """, warnings: MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,
+ infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
+
+ check("""
+ class A {
+ int field; // testFieldNotSubtype:29
+ }
+ class Class implements A {
+ String get field => null; // testFieldNotSubtype:30
+ void set field(String s) {} // testFieldNotSubtype:31
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
+ MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER],
+ infos: [MessageKind.INVALID_OVERRIDDEN_FIELD,
+ MessageKind.INVALID_OVERRIDDEN_FIELD]),
+
+
+ check("""
+ class A {
+ String get field => null; // testFieldNotSubtype:32
+ void set field(String s) {} // testFieldNotSubtype:33
+ }
+ class Class implements A {
+ int field; // testFieldNotSubtype:34
+ }
+ """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
+ MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD],
+ infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
+ MessageKind.INVALID_OVERRIDDEN_SETTER]),
+ ]);
+}
+
+Future testMixedOverride() {
+ return Future.wait([
+ check("""
+ class A {
+ var member; // testMixedOverride:1
+ }
+ class Class extends A {
+ member() {} // testMixedOverride:2
+ }
+ """, errors: MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
+ infos: MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT),
+
+ check("""
+ class A {
+ member() {} // testMixedOverride:3
+ }
+ class Class extends A {
+ var member; // testMixedOverride:4
+ }
+ """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
+ infos: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT),
+
+ check("""
+ class A {
+ get member => null; // testMixedOverride:5
+ }
+ class Class extends A {
+ member() {} // testMixedOverride:6
+ }
+ """, errors: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
+ infos: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT),
+
+ check("""
+ class A {
+ member() {} // testMixedOverride:7
+ }
+ class Class extends A {
+ get member => null; // testMixedOverride:8
+ }
+ """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
+ infos: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT),
+
+ check("""
+ abstract class A {
+ var member; // testMixedOverride:9
+ }
+ abstract class B {
+ get member; // testMixedOverride:10
+ }
+ abstract class Class implements A, B {
+ }
+ """),
+
+ check("""
+ abstract class A {
+ var member; // testMixedOverride:11
+ }
+ abstract class B {
+ member() {} // testMixedOverride:12
+ }
+ abstract class Class implements A, B {
+ }
+ """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
+ infos: [MessageKind.INHERITED_METHOD,
+ MessageKind.INHERITED_IMPLICIT_GETTER]),
+
+ check("""
+ abstract class A {
+ get member; // testMixedOverride:13
+ }
+ abstract class B {
+ member() {} // testMixedOverride:14
+ }
+ abstract class Class implements A, B {
+ }
+ """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
+ infos: [MessageKind.INHERITED_METHOD,
+ MessageKind.INHERITED_EXPLICIT_GETTER]),
+
+ check("""
+ abstract class A {
+ get member; // testMixedOverride:15
+ }
+ abstract class B {
+ member() {} // testMixedOverride:16
+ }
+ abstract class C {
+ var member; // testMixedOverride:17
+ }
+ abstract class D {
+ member() {} // testMixedOverride:18
+ }
+ abstract class E {
+ get member; // testMixedOverride:19
+ }
+ abstract class Class implements A, B, C, D, E {
+ }
+ """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
+ infos: [MessageKind.INHERITED_EXPLICIT_GETTER,
+ MessageKind.INHERITED_METHOD,
+ MessageKind.INHERITED_IMPLICIT_GETTER,
+ MessageKind.INHERITED_METHOD,
+ MessageKind.INHERITED_EXPLICIT_GETTER]),
+
+ check("""
+ abstract class A {
+ get member; // testMixedOverride:20
+ }
+ abstract class B {
+ member() {} // testMixedOverride:21
+ }
+ abstract class C implements A, B {
+ }
+ class Class extends C {
+ member() {} // testMixedOverride:22
+ }
+ """, errors: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
+ warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
+ infos: [MessageKind.INHERITED_METHOD,
+ MessageKind.INHERITED_EXPLICIT_GETTER,
+ MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT]),
+
+ check("""
+ abstract class A {
+ get member; // testMixedOverride:23
+ }
+ abstract class B {
+ member() {} // testMixedOverride:24
+ }
+ abstract class C implements A, B {
+ }
+ class Class extends C {
+ get member => null; // testMixedOverride:25
+ }
+ """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
+ warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
+ infos: [MessageKind.INHERITED_METHOD,
+ MessageKind.INHERITED_EXPLICIT_GETTER,
+ MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT]),
+ ]);
+}
+
+Future testAbstractMethods() {
+ return Future.wait([
+ check("""
+ abstract class Class {
+ method(); // testAbstractMethod:1
+ }
+ """),
+
+ check("""
+ class Class {
+ method(); // testAbstractMethod:2
+ }
+ """, warnings: MessageKind.ABSTRACT_METHOD,
+ infos: []),
+
+ check("""
+ class Class {
+ get getter; // testAbstractMethod:3
+ }
+ """, warnings: MessageKind.ABSTRACT_GETTER,
+ infos: []),
+
+ check("""
+ class Class {
+ set setter(_); // testAbstractMethod:4
+ }
+ """, warnings: MessageKind.ABSTRACT_SETTER,
+ infos: []),
+
+ check("""
+ abstract class A {
+ method(); // testAbstractMethod:5
+ }
+ class Class extends A {
+ method() {} // testAbstractMethod:6
+ }
+ """),
+
+ check("""
+ abstract class A {
+ method(); // testAbstractMethod:7
+ }
+ class Class extends A {
+ method([a]) {} // testAbstractMethod:8
+ }
+ """),
+
+ check("""
+ abstract class A {
+ method(); // testAbstractMethod:9
+ }
+ class Class extends A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+ infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+ check("""
+ abstract class A {
+ get getter; // testAbstractMethod:10
+ }
+ class Class extends A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,
+ infos: MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER),
+
+ check("""
+ abstract class A {
+ set setter(_); // testAbstractMethod:11
+ }
+ class Class extends A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
+ infos: MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER),
+
+ check("""
+ abstract class A {
+ method(); // testAbstractMethod:12
+ }
+ class B {
+ method() {} // testAbstractMethod:13
+ }
+ class Class extends A implements B {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_METHOD,
+ infos: [MessageKind.UNIMPLEMENTED_METHOD_CONT,
+ MessageKind.UNIMPLEMENTED_METHOD_CONT]),
+
+ check("""
+ class Class implements Function {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+ infos: []),
+
+ check("""
+ abstract class A {
+ get getter; // testAbstractMethod:14
+ }
+ class B {
+ get getter => 0; // testAbstractMethod:15
+ }
+ class Class extends A implements B {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_GETTER,
+ infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
+ MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER]),
+
+ check("""
+ abstract class A {
+ set setter(_); // testAbstractMethod:16
+ }
+ class B {
+ set setter(_) {} // testAbstractMethod:17
+ }
+ class Class extends A implements B {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_SETTER,
+ infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
+ MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER]),
+
+ check("""
+ abstract class A {
+ get field; // testAbstractMethod:18
+ }
+ class B {
+ var field; // testAbstractMethod:19
+ }
+ class Class extends A implements B {
+ set field(_) {} // testAbstractMethod:20
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_GETTER,
+ infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
+ MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER]),
+
+ check("""
+ abstract class A {
+ set field(_); // testAbstractMethod:21
+ }
+ class B {
+ var field; // testAbstractMethod:22
+ }
+ class Class extends A implements B {
+ get field => 0; // testAbstractMethod:23
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_SETTER,
+ infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
+ MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
+
+ check("""
+ class A {
+ method() {} // testAbstractMethod:24
+ }
+ class Class implements A {
+ method() {} // testAbstractMethod:25
+ }
+ """),
+
+ check("""
+ class A {
+ method() {} // testAbstractMethod:26
+ }
+ class Class implements A {
+ method([a]) {} // testAbstractMethod:27
+ }
+ """),
+
+ check("""
+ class A {
+ method() {} // testAbstractMethod:28
+ }
+ class Class implements A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+ infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+ check("""
+ class A {
+ method() {} // testAbstractMethod:29
+ }
+ class B {
+ method() {} // testAbstractMethod:30
+ }
+ class Class extends A implements B {
+ }
+ """),
+
+ check("""
+ class A {
+ var member; // testAbstractMethod:31
+ }
+ class Class implements A {
+ }
+ """, warnings: [MessageKind.UNIMPLEMENTED_GETTER_ONE,
+ MessageKind.UNIMPLEMENTED_SETTER_ONE],
+ infos: [MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
+ MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
+
+ check("""
+ class A {
+ var member; // testAbstractMethod:32
+ }
+ class B {
+ get member => null; // testAbstractMethod:33
+ set member(_) {} // testAbstractMethod:34
+ }
+ class Class implements A, B {
+ }
+ """, warnings: [MessageKind.UNIMPLEMENTED_GETTER,
+ MessageKind.UNIMPLEMENTED_SETTER],
+ infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
+ MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
+ MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
+ MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
+
+ check("""
+ class A {
+ var member; // testAbstractMethod:35
+ }
+ class B {
+ var member; // testAbstractMethod:36
+ }
+ class Class implements A, B {
+ }
+ """, warnings: [MessageKind.UNIMPLEMENTED_GETTER,
+ MessageKind.UNIMPLEMENTED_SETTER],
+ infos: [MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
+ MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
+ MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER,
+ MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
+
+ check("""
+ class A {
+ get member => 0; // testAbstractMethod:37
+ }
+ class Class implements A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,
+ infos: MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER),
+
+ check("""
+ class A {
+ set member(_) {} // testAbstractMethod:38
+ }
+ class Class implements A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
+ infos: MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER),
+
+ check("""
+ class A {
+ var member; // testAbstractMethod:39
+ }
+ class Class implements A {
+ get member => 0;
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
+ infos: MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER),
+
+ check("""
+ class A {
+ var field; // testAbstractMethod:40
+ }
+ class Class implements A {
+ final field = 0; // testAbstractMethod:41
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
+ infos: MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER),
+
+ check("""
+ class A {
+ var member; // testAbstractMethod:42
+ }
+ class Class implements A {
+ set member(_) {}
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,
+ infos: MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER),
+
+ check("""
+ abstract class A {
+ method() {} // testAbstractMethod:43
+ }
+ class Class extends A {
+ method();
+ }
+ """),
+ ]);
+}
+
+Future testNoSuchMethod() {
+ return Future.wait([
+ check("""
+ class Class {
+ method(); // testNoSuchMethod:1
+ }
+ """, warnings: MessageKind.ABSTRACT_METHOD,
+ infos: []),
+
+ check("""
+ @proxy
+ class Class {
+ method(); // testNoSuchMethod:2
+ }
+ """, warnings: MessageKind.ABSTRACT_METHOD,
+ infos: []),
+
+ check("""
+ class Class {
+ noSuchMethod(_) => null;
+ method(); // testNoSuchMethod:3
+ }
+ """),
+
+ check("""
+ class Class {
+ noSuchMethod(_, [__]) => null;
+ method(); // testNoSuchMethod:4
+ }
+ """),
+
+ check("""
+ class Class {
+ noSuchMethod(_);
+ method(); // testNoSuchMethod:5
+ }
+ """),
+
+ check("""
+ abstract class A {
+ method(); // testNoSuchMethod:6
+ }
+ class Class extends A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+ infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+ check("""
+ abstract class A {
+ method(); // testNoSuchMethod:7
+ }
+ @proxy
+ class Class extends A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+ infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+ check("""
+ abstract class A {
+ method(); // testNoSuchMethod:8
+ }
+ class Class extends A {
+ noSuchMethod(_) => null;
+ }
+ """),
+
+ check("""
+ class A {
+ method() {} // testNoSuchMethod:9
+ }
+ class Class implements A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+ infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+ check("""
+ class A {
+ method() {} // testNoSuchMethod:10
+ }
+ class Class implements A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+ infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+ check("""
+ class A {
+ method() {} // testNoSuchMethod:11
+ }
+ @proxy
+ class Class implements A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+ infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+ check("""
+ class A {
+ method() {} // testNoSuchMethod:12
+ }
+ class Class implements A {
+ noSuchMethod(_) => null;
+ }
+ """),
+
+ check("""
+ class A {
+ noSuchMethod(_) => null;
+ method(); // testNoSuchMethod:13
+ }
+ class Class extends A {
+ }
+ """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+ infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+ ]);
+}
diff --git a/tests/compiler/dart2js/package_root_test.dart b/tests/compiler/dart2js/package_root_test.dart
index 5a173f5..f1e6ee6 100644
--- a/tests/compiler/dart2js/package_root_test.dart
+++ b/tests/compiler/dart2js/package_root_test.dart
@@ -6,18 +6,17 @@
library dart2js.test.package_root;
-import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
-import 'memory_source_file_helper.dart';
-
-import 'package:compiler/src/dart2jslib.dart'
- show NullSink;
-
-import 'package:compiler/compiler.dart'
- show DiagnosticHandler, Diagnostic;
-
import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/compiler.dart'
+ show DiagnosticHandler, Diagnostic, PackagesDiscoveryProvider;
+import 'package:package_config/packages.dart';
+
+import 'memory_compiler.dart';
+import 'memory_source_file_helper.dart';
+
const MEMORY_SOURCE_FILES = const {
'main.dart': '''
@@ -25,46 +24,66 @@
main() {}
''',
+ 'package.config': '''
+''',
};
-void runCompiler(Uri main) {
- Uri script = currentDirectory.resolveUri(Platform.script);
- Uri libraryRoot = script.resolve('../../../sdk/');
- Uri packageRoot = script.resolve('./packages/');
+final Uri PACKAGE_CONFIG_URI = Uri.parse('memory:package.config');
- var provider = new MemorySourceFileProvider(MEMORY_SOURCE_FILES);
- var handler = new FormattingDiagnosticHandler(provider);
- var errors = [];
-
- void diagnosticHandler(Uri uri, int begin, int end, String message,
- Diagnostic kind) {
- if (kind == Diagnostic.ERROR) {
- errors.add(message);
- }
- handler(uri, begin, end, message, kind);
- }
-
-
- EventSink<String> outputProvider(String name, String extension) {
- if (name != '') throw 'Attempt to output file "$name.$extension"';
- return new NullSink('$name.$extension');
- }
-
- Compiler compiler = new Compiler(provider,
- outputProvider,
- diagnosticHandler,
- libraryRoot,
- packageRoot,
- [],
- {});
+void runCompiler(Uri main,
+ bool checkError(DiagnosticMessage message),
+ {Uri packageRoot,
+ Uri packageConfig,
+ PackagesDiscoveryProvider packagesDiscoveryProvider}) {
+ DiagnosticCollector collector = new DiagnosticCollector();
+ Compiler compiler = compilerFor(
+ MEMORY_SOURCE_FILES,
+ diagnosticHandler: collector,
+ packageRoot: packageRoot,
+ packageConfig: packageConfig,
+ packagesDiscoveryProvider: packagesDiscoveryProvider);
asyncTest(() => compiler.run(main).then((_) {
- Expect.equals(1, errors.length);
- Expect.isTrue(errors[0].contains("Error reading "));
+ Expect.equals(1, collector.errors.length,
+ "Unexpected errors: ${collector.errors}");
+ Expect.isTrue(checkError(collector.errors.first),
+ "Unexpected error: ${collector.errors.first}");
}));
}
void main() {
- runCompiler(Uri.parse('memory:main.dart'));
- runCompiler(Uri.parse('package:foo/foo.dart'));
+ Uri script = currentDirectory.resolveUri(Platform.script);
+ Uri packageRoot = script.resolve('./packages/');
+
+ PackagesDiscoveryProvider noPackagesDiscovery = (Uri uri) {
+ return new Future.value(Packages.noPackages);
+ };
+
+ bool containsErrorReading(DiagnosticMessage message) {
+ return message.message.contains("Error reading ");
+ }
+
+ bool isLibraryNotFound(DiagnosticMessage message) {
+ return message.message.startsWith("Library not found ");
+ }
+
+ runCompiler(Uri.parse('memory:main.dart'),
+ containsErrorReading,
+ packageRoot: packageRoot);
+ runCompiler(Uri.parse('memory:main.dart'),
+ isLibraryNotFound,
+ packageConfig: PACKAGE_CONFIG_URI);
+ runCompiler(Uri.parse('memory:main.dart'),
+ isLibraryNotFound,
+ packagesDiscoveryProvider: noPackagesDiscovery);
+
+ runCompiler(Uri.parse('package:foo/foo.dart'),
+ containsErrorReading,
+ packageRoot: packageRoot);
+ runCompiler(Uri.parse('package:foo/foo.dart'),
+ isLibraryNotFound,
+ packageConfig: PACKAGE_CONFIG_URI);
+ runCompiler(Uri.parse('package:foo/foo.dart'),
+ isLibraryNotFound,
+ packagesDiscoveryProvider: noPackagesDiscovery);
}
diff --git a/tests/compiler/dart2js/proxy_test.dart b/tests/compiler/dart2js/proxy_test.dart
index c558350..b9d8444 100644
--- a/tests/compiler/dart2js/proxy_test.dart
+++ b/tests/compiler/dart2js/proxy_test.dart
@@ -1,22 +1,22 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that dart2js produces the expected static type warnings for proxy
-// language tests. This ensures that the analyzer and dart2js agrees on these
-// tests.
-
-import 'warnings_checker.dart';
-
-/// Map from test files to a map of their expected status. If the status map is
-/// `null` no warnings must be missing or unexpected, otherwise the status map
-/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
-/// the warnings of each category.
-const Map<String, dynamic> TESTS = const {
- 'language/proxy_test.dart': null,
- 'language/proxy2_test.dart': null,
-};
-
-void main() {
- checkWarnings(TESTS);
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that dart2js produces the expected static type warnings for proxy
+// language tests. This ensures that the analyzer and dart2js agrees on these
+// tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+ 'language/proxy_test.dart': null,
+ 'language/proxy2_test.dart': null,
+};
+
+void main() {
+ checkWarnings(TESTS);
+}
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index 5084fe3..c25eb93 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -686,7 +686,7 @@
new ResolverVisitor(compiler, element,
new ResolutionRegistry.internal(compiler,
new CollectingTreeElements(element)));
- new InitializerResolver(visitor).resolveInitializers(element, tree);
+ new InitializerResolver(visitor, element, tree).resolveInitializers();
visitor.visit(tree.body);
Expect.equals(expectedElementCount, map(visitor).length,
"${map(visitor).values} for '$statement' in context of `$script`");
diff --git a/tests/compiler/dart2js/semantic_visitor_test.dart b/tests/compiler/dart2js/semantic_visitor_test.dart
index 69fad43..19c1694 100644
--- a/tests/compiler/dart2js/semantic_visitor_test.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test.dart
@@ -1,706 +1,706 @@
-// 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_test;
-
-import 'dart:async';
-import 'dart:mirrors';
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/constants/expressions.dart';
-import 'package:compiler/src/dart_types.dart';
-import 'package:compiler/src/dart2jslib.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/resolution/resolution.dart';
-import 'package:compiler/src/resolution/semantic_visitor.dart';
-import 'package:compiler/src/resolution/operators.dart';
-import 'package:compiler/src/tree/tree.dart';
-import 'package:compiler/src/util/util.dart';
-import 'memory_compiler.dart';
-
-part 'semantic_visitor_test_send_data.dart';
-part 'semantic_visitor_test_send_visitor.dart';
-part 'semantic_visitor_test_decl_data.dart';
-part 'semantic_visitor_test_decl_visitor.dart';
-
-class Visit {
- final VisitKind method;
- final element;
- final rhs;
- final arguments;
- final receiver;
- final name;
- final expression;
- final left;
- final right;
- final type;
- final operator;
- final index;
- final getter;
- final setter;
- final constant;
- final selector;
- final parameters;
- final body;
- final target;
- final targetType;
- final initializers;
-
- const Visit(this.method,
- {this.element,
- this.rhs,
- this.arguments,
- this.receiver,
- this.name,
- this.expression,
- this.left,
- this.right,
- this.type,
- this.operator,
- this.index,
- this.getter,
- this.setter,
- this.constant,
- this.selector,
- this.parameters,
- this.body,
- this.target,
- this.targetType,
- this.initializers});
-
- int get hashCode => toString().hashCode;
-
- bool operator ==(other) => '$this' == '$other';
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- sb.write('method=$method');
- if (element != null) {
- sb.write(',element=$element');
- }
- if (rhs != null) {
- sb.write(',rhs=$rhs');
- }
- if (arguments != null) {
- sb.write(',arguments=$arguments');
- }
- if (receiver != null) {
- sb.write(',receiver=$receiver');
- }
- if (name != null) {
- sb.write(',name=$name');
- }
- if (expression != null) {
- sb.write(',expression=$expression');
- }
- if (left != null) {
- sb.write(',left=$left');
- }
- if (right != null) {
- sb.write(',right=$right');
- }
- if (type != null) {
- sb.write(',type=$type');
- }
- if (operator != null) {
- sb.write(',operator=$operator');
- }
- if (index != null) {
- sb.write(',index=$index');
- }
- if (getter != null) {
- sb.write(',getter=$getter');
- }
- if (setter != null) {
- sb.write(',setter=$setter');
- }
- if (constant != null) {
- sb.write(',constant=$constant');
- }
- if (selector != null) {
- sb.write(',selector=$selector');
- }
- if (parameters != null) {
- sb.write(',parameters=$parameters');
- }
- if (body != null) {
- sb.write(',body=$body');
- }
- if (target != null) {
- sb.write(',target=$target');
- }
- if (targetType != null) {
- sb.write(',targetType=$targetType');
- }
- if (initializers != null) {
- sb.write(',initializers=$initializers');
- }
- return sb.toString();
- }
-}
-
-class Test {
- final String codeByPrefix;
- final String code;
- final /*Visit | List<Visit>*/ expectedVisits;
- final String cls;
- final String method;
-
- const Test(this.code, this.expectedVisits)
- : cls = null, method = 'm', codeByPrefix = null;
- const Test.clazz(this.code, this.expectedVisits,
- {this.cls: 'C', this.method: 'm'})
- : codeByPrefix = null;
- const Test.prefix(this.codeByPrefix, this.code, this.expectedVisits)
- : cls = null, method = 'm';
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- sb.writeln();
- sb.writeln(code);
- if (codeByPrefix != null) {
- sb.writeln('imported by prefix:');
- sb.writeln(codeByPrefix);
- }
- return sb.toString();
- }
-}
-
-const List<VisitKind> UNTESTABLE_KINDS = const <VisitKind>[
- // A final field shadowing a non-final field is currently not supported in
- // resolution.
- VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
- VisitKind.VISIT_SUPER_FIELD_FIELD_PREFIX,
- VisitKind.VISIT_SUPER_FIELD_FIELD_POSTFIX,
- // Combination of method and setter with the same name is currently not
- // supported by the element model.
- VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
- VisitKind.VISIT_STATIC_METHOD_SETTER_PREFIX,
- VisitKind.VISIT_STATIC_METHOD_SETTER_POSTFIX,
- VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,
- VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,
- VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,
- VisitKind.VISIT_SUPER_METHOD_SETTER_COMPOUND,
- VisitKind.VISIT_SUPER_METHOD_SETTER_PREFIX,
- VisitKind.VISIT_SUPER_METHOD_SETTER_POSTFIX,
- // The constant expressions of assignment to constant type literals cannot be
- // handled the compile constant evaluator.
- VisitKind.VISIT_CLASS_TYPE_LITERAL_SET,
- VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,
- VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,
- // Invalid assignments is currently report through an erroneous element.
- VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,
- VisitKind.VISIT_FINAL_PARAMETER_SET,
- VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET,
- VisitKind.VISIT_LOCAL_FUNCTION_SET,
- VisitKind.VISIT_STATIC_GETTER_SET,
- VisitKind.VISIT_FINAL_STATIC_FIELD_SET,
- VisitKind.VISIT_STATIC_FUNCTION_SET,
- VisitKind.VISIT_FINAL_TOP_LEVEL_FIELD_SET,
- VisitKind.VISIT_TOP_LEVEL_GETTER_SET,
- VisitKind.VISIT_TOP_LEVEL_FUNCTION_SET,
- VisitKind.VISIT_FINAL_SUPER_FIELD_SET,
- VisitKind.VISIT_SUPER_GETTER_SET,
- VisitKind.VISIT_SUPER_METHOD_SET,
- // The only undefined unary, `+`, is currently handled and skipped in the
- // parser.
- VisitKind.ERROR_UNDEFINED_UNARY_EXPRESSION,
- // Constant expression are currently not computed during resolution.
- VisitKind.VISIT_CONSTANT_GET,
- VisitKind.VISIT_CONSTANT_INVOKE,
-];
-
-main(List<String> arguments) {
- Set<VisitKind> kinds = new Set<VisitKind>.from(VisitKind.values);
- asyncTest(() => Future.forEach([
- () {
- return test(
- kinds,
- arguments,
- SEND_TESTS,
- (elements) => new SemanticSendTestVisitor(elements));
- },
- () {
- return test(
- kinds,
- arguments,
- DECL_TESTS,
- (elements) => new SemanticDeclarationTestVisitor(elements));
- },
- () {
- Set<VisitKind> unvisitedKindSet =
- kinds.toSet()..removeAll(UNTESTABLE_KINDS);
- List<VisitKind> unvisitedKindList = unvisitedKindSet.toList();
- unvisitedKindList..sort((a, b) => a.index.compareTo(b.index));
-
- Expect.isTrue(unvisitedKindList.isEmpty,
- "Untested visit kinds:\n ${unvisitedKindList.join(',\n ')},\n");
-
- Set<VisitKind> testedUntestableKinds =
- UNTESTABLE_KINDS.toSet()..removeAll(kinds);
- Expect.isTrue(testedUntestableKinds.isEmpty,
- "Tested untestable visit kinds (remove from UNTESTABLE_KINDS):\n "
- "${testedUntestableKinds.join(',\n ')},\n");
- },
- () {
- ClassMirror mirror1 = reflectType(SemanticSendTestVisitor);
- Set<Symbol> symbols1 = mirror1.declarations.keys.toSet();
- ClassMirror mirror2 = reflectType(SemanticSendVisitor);
- Set<Symbol> symbols2 =
- mirror2.declarations.values
- .where((m) => m is MethodMirror &&
- !m.isConstructor &&
- m.simpleName != #apply)
- .map((m) => m.simpleName).toSet();
- symbols2.removeAll(symbols1);
- Expect.isTrue(symbols2.isEmpty,
- "Untested visit methods:\n ${symbols2.join(',\n ')},\n");
- }
- ], (f) => f()));
-}
-
-Future test(Set<VisitKind> unvisitedKinds,
- List<String> arguments,
- Map<String, List<Test>> TESTS,
- SemanticTestVisitor createVisitor(TreeElements elements)) {
- Map<String, String> sourceFiles = {};
- Map<String, Test> testMap = {};
- StringBuffer mainSource = new StringBuffer();
- int index = 0;
- TESTS.forEach((String group, List<Test> tests) {
- if (arguments.isNotEmpty && !arguments.contains(group)) return;
-
- tests.forEach((Test test) {
- StringBuffer testSource = new StringBuffer();
- if (test.codeByPrefix != null) {
- String prefixFilename = 'pre$index.dart';
- sourceFiles[prefixFilename] = test.codeByPrefix;
- testSource.writeln("import '$prefixFilename' as p;");
- }
-
- String filename = 'lib$index.dart';
- testSource.writeln(test.code);
- sourceFiles[filename] = testSource.toString();
- mainSource.writeln("import '$filename';");
- testMap[filename] = test;
- index++;
- });
- });
- mainSource.writeln("main() {}");
- sourceFiles['main.dart'] = mainSource.toString();
-
- Compiler compiler = compilerFor(sourceFiles,
- options: ['--analyze-all',
- '--analyze-only',
- '--enable-null-aware-operators']);
- return compiler.run(Uri.parse('memory:main.dart')).then((_) {
- testMap.forEach((String filename, Test test) {
- LibraryElement library = compiler.libraryLoader.lookupLibrary(
- Uri.parse('memory:$filename'));
- Element element;
- String cls = test.cls;
- String method = test.method;
- if (cls == null) {
- element = library.find(method);
- } else {
- ClassElement classElement = library.find(cls);
- Expect.isNotNull(classElement,
- "Class '$cls' not found in:\n"
- "${library.compilationUnit.script.text}");
- element = classElement.localLookup(method);
- }
- var expectedVisits = test.expectedVisits;
- if (expectedVisits == null) {
- Expect.isTrue(element.isErroneous,
- "Element '$method' expected to be have parse errors in:\n"
- "${library.compilationUnit.script.text}");
- return;
- } else if (expectedVisits is! List) {
- expectedVisits = [expectedVisits];
- }
- Expect.isFalse(element.isErroneous,
- "Element '$method' is not expected to be have parse errors in:\n"
- "${library.compilationUnit.script.text}");
-
- void testAstElement(AstElement astElement) {
- Expect.isNotNull(astElement, "Element '$method' not found in:\n"
- "${library.compilationUnit.script.text}");
- ResolvedAst resolvedAst = astElement.resolvedAst;
- SemanticTestVisitor visitor = createVisitor(resolvedAst.elements);
- try {
- compiler.withCurrentElement(resolvedAst.element, () {
- //print(resolvedAst.node.toDebugString());
- resolvedAst.node.accept(visitor);
- });
- } catch (e, s) {
- Expect.fail("$e:\n$s\nIn test:\n"
- "${library.compilationUnit.script.text}");
- }
- Expect.listEquals(expectedVisits, visitor.visits,
- "In test:\n"
- "${library.compilationUnit.script.text}\n\n"
- "Expected: $expectedVisits\n"
- "Found: ${visitor.visits}");
- unvisitedKinds.removeAll(visitor.visits.map((visit) => visit.method));
- }
- if (element.isAbstractField) {
- AbstractFieldElement abstractFieldElement = element;
- if (abstractFieldElement.getter != null) {
- testAstElement(abstractFieldElement.getter);
- } else if (abstractFieldElement.setter != null) {
- testAstElement(abstractFieldElement.setter);
- }
- } else {
- testAstElement(element);
- }
- });
- });
-}
-
-abstract class SemanticTestVisitor extends TraversalVisitor {
- List<Visit> visits = <Visit>[];
-
- SemanticTestVisitor(TreeElements elements) : super(elements);
-
- apply(Node node, arg) => node.accept(this);
-
- internalError(Spannable spannable, String message) {
- throw new SpannableAssertionFailure(spannable, message);
- }
-}
-
-enum VisitKind {
- VISIT_PARAMETER_GET,
- VISIT_PARAMETER_SET,
- VISIT_PARAMETER_INVOKE,
- VISIT_PARAMETER_COMPOUND,
- VISIT_PARAMETER_PREFIX,
- VISIT_PARAMETER_POSTFIX,
- VISIT_FINAL_PARAMETER_SET,
- VISIT_FINAL_PARAMETER_COMPOUND,
- VISIT_FINAL_PARAMETER_PREFIX,
- VISIT_FINAL_PARAMETER_POSTFIX,
-
- VISIT_LOCAL_VARIABLE_GET,
- VISIT_LOCAL_VARIABLE_SET,
- VISIT_LOCAL_VARIABLE_INVOKE,
- VISIT_LOCAL_VARIABLE_COMPOUND,
- VISIT_LOCAL_VARIABLE_PREFIX,
- VISIT_LOCAL_VARIABLE_POSTFIX,
- VISIT_LOCAL_VARIABLE_DECL,
- VISIT_LOCAL_CONSTANT_DECL,
- VISIT_FINAL_LOCAL_VARIABLE_SET,
- VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,
- VISIT_FINAL_LOCAL_VARIABLE_PREFIX,
- VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,
-
- VISIT_LOCAL_FUNCTION_GET,
- VISIT_LOCAL_FUNCTION_INVOKE,
- VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,
- VISIT_LOCAL_FUNCTION_DECL,
- VISIT_CLOSURE_DECL,
- VISIT_LOCAL_FUNCTION_SET,
- VISIT_LOCAL_FUNCTION_COMPOUND,
- VISIT_LOCAL_FUNCTION_PREFIX,
- VISIT_LOCAL_FUNCTION_POSTFIX,
-
- VISIT_STATIC_FIELD_GET,
- VISIT_STATIC_FIELD_SET,
- VISIT_STATIC_FIELD_INVOKE,
- VISIT_STATIC_FIELD_COMPOUND,
- VISIT_STATIC_FIELD_PREFIX,
- VISIT_STATIC_FIELD_POSTFIX,
- VISIT_STATIC_FIELD_DECL,
- VISIT_STATIC_CONSTANT_DECL,
-
- VISIT_STATIC_GETTER_GET,
- VISIT_STATIC_GETTER_SET,
- VISIT_STATIC_GETTER_INVOKE,
-
- VISIT_STATIC_SETTER_GET,
- VISIT_STATIC_SETTER_SET,
- VISIT_STATIC_SETTER_INVOKE,
-
- VISIT_STATIC_GETTER_SETTER_COMPOUND,
- VISIT_STATIC_METHOD_SETTER_COMPOUND,
- VISIT_STATIC_GETTER_SETTER_PREFIX,
- VISIT_STATIC_GETTER_SETTER_POSTFIX,
-
- VISIT_STATIC_GETTER_DECL,
- VISIT_STATIC_SETTER_DECL,
-
- VISIT_FINAL_STATIC_FIELD_SET,
- VISIT_STATIC_FINAL_FIELD_COMPOUND,
- VISIT_STATIC_FINAL_FIELD_POSTFIX,
- VISIT_STATIC_FINAL_FIELD_PREFIX,
-
- VISIT_STATIC_FUNCTION_GET,
- VISIT_STATIC_FUNCTION_SET,
- VISIT_STATIC_FUNCTION_INVOKE,
- VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,
- VISIT_STATIC_FUNCTION_DECL,
- VISIT_STATIC_METHOD_SETTER_PREFIX,
- VISIT_STATIC_METHOD_SETTER_POSTFIX,
-
- VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,
- VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,
- VISIT_STATIC_METHOD_COMPOUND,
- VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,
- VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,
- VISIT_STATIC_METHOD_PREFIX,
- VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,
- VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,
- VISIT_STATIC_METHOD_POSTFIX,
-
- VISIT_TOP_LEVEL_FIELD_GET,
- VISIT_TOP_LEVEL_FIELD_SET,
- VISIT_TOP_LEVEL_FIELD_INVOKE,
- VISIT_FINAL_TOP_LEVEL_FIELD_SET,
- VISIT_TOP_LEVEL_FIELD_COMPOUND,
- VISIT_TOP_LEVEL_FIELD_PREFIX,
- VISIT_TOP_LEVEL_FIELD_POSTFIX,
- VISIT_TOP_LEVEL_FIELD_DECL,
- VISIT_TOP_LEVEL_CONSTANT_DECL,
- VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,
- VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,
- VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,
-
- VISIT_TOP_LEVEL_GETTER_GET,
- VISIT_TOP_LEVEL_GETTER_SET,
- VISIT_TOP_LEVEL_GETTER_INVOKE,
- VISIT_TOP_LEVEL_SETTER_GET,
- VISIT_TOP_LEVEL_SETTER_SET,
- VISIT_TOP_LEVEL_SETTER_INVOKE,
- VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,
- VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,
- VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,
- VISIT_TOP_LEVEL_GETTER_DECL,
- VISIT_TOP_LEVEL_SETTER_DECL,
-
- VISIT_TOP_LEVEL_FUNCTION_GET,
- VISIT_TOP_LEVEL_FUNCTION_SET,
- VISIT_TOP_LEVEL_FUNCTION_INVOKE,
- VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,
- VISIT_TOP_LEVEL_FUNCTION_DECL,
- VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,
- VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,
- VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,
-
- VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,
- VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,
- VISIT_TOP_LEVEL_METHOD_COMPOUND,
- VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,
- VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,
- VISIT_TOP_LEVEL_METHOD_PREFIX,
- VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,
- VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,
- VISIT_TOP_LEVEL_METHOD_POSTFIX,
-
- VISIT_DYNAMIC_PROPERTY_GET,
- VISIT_DYNAMIC_PROPERTY_SET,
- VISIT_DYNAMIC_PROPERTY_INVOKE,
- VISIT_DYNAMIC_PROPERTY_COMPOUND,
- VISIT_DYNAMIC_PROPERTY_PREFIX,
- VISIT_DYNAMIC_PROPERTY_POSTFIX,
-
- VISIT_THIS_GET,
- VISIT_THIS_INVOKE,
-
- VISIT_THIS_PROPERTY_GET,
- VISIT_THIS_PROPERTY_SET,
- VISIT_THIS_PROPERTY_INVOKE,
- VISIT_THIS_PROPERTY_COMPOUND,
- VISIT_THIS_PROPERTY_PREFIX,
- VISIT_THIS_PROPERTY_POSTFIX,
-
- VISIT_SUPER_FIELD_GET,
- VISIT_SUPER_FIELD_SET,
- VISIT_FINAL_SUPER_FIELD_SET,
- VISIT_SUPER_FIELD_INVOKE,
- VISIT_SUPER_FIELD_COMPOUND,
- VISIT_SUPER_FIELD_PREFIX,
- VISIT_SUPER_FIELD_POSTFIX,
- VISIT_SUPER_FINAL_FIELD_COMPOUND,
- VISIT_SUPER_FINAL_FIELD_PREFIX,
- VISIT_SUPER_FINAL_FIELD_POSTFIX,
- VISIT_SUPER_FIELD_FIELD_COMPOUND,
- VISIT_SUPER_FIELD_FIELD_PREFIX,
- VISIT_SUPER_FIELD_FIELD_POSTFIX,
-
- VISIT_SUPER_GETTER_GET,
- VISIT_SUPER_GETTER_SET,
- VISIT_SUPER_GETTER_INVOKE,
- VISIT_SUPER_SETTER_GET,
- VISIT_SUPER_SETTER_SET,
- VISIT_SUPER_SETTER_INVOKE,
- VISIT_SUPER_GETTER_SETTER_COMPOUND,
- VISIT_SUPER_GETTER_FIELD_COMPOUND,
- VISIT_SUPER_FIELD_SETTER_COMPOUND,
- VISIT_SUPER_GETTER_SETTER_PREFIX,
- VISIT_SUPER_GETTER_FIELD_PREFIX,
- VISIT_SUPER_FIELD_SETTER_PREFIX,
- VISIT_SUPER_GETTER_SETTER_POSTFIX,
- VISIT_SUPER_GETTER_FIELD_POSTFIX,
- VISIT_SUPER_FIELD_SETTER_POSTFIX,
-
- VISIT_SUPER_METHOD_GET,
- VISIT_SUPER_METHOD_SET,
- VISIT_SUPER_METHOD_INVOKE,
- VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,
- VISIT_SUPER_METHOD_SETTER_COMPOUND,
- VISIT_SUPER_METHOD_SETTER_PREFIX,
- VISIT_SUPER_METHOD_SETTER_POSTFIX,
- VISIT_SUPER_METHOD_COMPOUND,
- VISIT_SUPER_METHOD_PREFIX,
- VISIT_SUPER_METHOD_POSTFIX,
-
- VISIT_UNRESOLVED_GET,
- VISIT_UNRESOLVED_SET,
- VISIT_UNRESOLVED_INVOKE,
- VISIT_UNRESOLVED_SUPER_GET,
- VISIT_UNRESOLVED_SUPER_INVOKE,
-
- VISIT_BINARY,
- VISIT_INDEX,
- VISIT_EQUALS,
- VISIT_NOT_EQUALS,
- VISIT_INDEX_PREFIX,
- VISIT_INDEX_POSTFIX,
-
- VISIT_SUPER_BINARY,
- VISIT_UNRESOLVED_SUPER_BINARY,
- VISIT_SUPER_INDEX,
- VISIT_UNRESOLVED_SUPER_INDEX,
- VISIT_SUPER_EQUALS,
- VISIT_SUPER_NOT_EQUALS,
- VISIT_SUPER_INDEX_PREFIX,
- VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,
- VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,
- VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,
- VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,
- VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,
- VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,
- VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,
- VISIT_SUPER_INDEX_POSTFIX,
- VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,
- VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,
- VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,
- VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,
- VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,
-
- VISIT_UNRESOLVED_SUPER_COMPOUND,
- VISIT_UNRESOLVED_SUPER_PREFIX,
- VISIT_UNRESOLVED_SUPER_POSTFIX,
-
- VISIT_UNARY,
- VISIT_SUPER_UNARY,
- VISIT_UNRESOLVED_SUPER_UNARY,
- VISIT_NOT,
-
- VISIT_EXPRESSION_INVOKE,
-
- VISIT_CLASS_TYPE_LITERAL_GET,
- VISIT_CLASS_TYPE_LITERAL_SET,
- VISIT_CLASS_TYPE_LITERAL_INVOKE,
- VISIT_CLASS_TYPE_LITERAL_COMPOUND,
- VISIT_CLASS_TYPE_LITERAL_PREFIX,
- VISIT_CLASS_TYPE_LITERAL_POSTFIX,
-
- VISIT_TYPEDEF_TYPE_LITERAL_GET,
- VISIT_TYPEDEF_TYPE_LITERAL_SET,
- VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
- VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,
- VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
- VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,
-
- VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,
- VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,
- VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,
- VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,
- VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,
- VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,
-
- VISIT_DYNAMIC_TYPE_LITERAL_GET,
- VISIT_DYNAMIC_TYPE_LITERAL_SET,
- VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
- VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,
- VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
- VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,
-
- VISIT_INDEX_SET,
- VISIT_COMPOUND_INDEX_SET,
- VISIT_SUPER_INDEX_SET,
- VISIT_UNRESOLVED_SUPER_INDEX_SET,
- VISIT_SUPER_COMPOUND_INDEX_SET,
- VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,
- VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,
- VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,
-
- VISIT_ASSERT,
- VISIT_LOGICAL_AND,
- VISIT_LOGICAL_OR,
- VISIT_IS,
- VISIT_IS_NOT,
- VISIT_AS,
-
- VISIT_CONST_CONSTRUCTOR_INVOKE,
- VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
- VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
- VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
- VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
- VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
- VISIT_FACTORY_CONSTRUCTOR_INVOKE,
- VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
- ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,
-
- VISIT_SUPER_CONSTRUCTOR_INVOKE,
- VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
- VISIT_THIS_CONSTRUCTOR_INVOKE,
- VISIT_FIELD_INITIALIZER,
-
- VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
- VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,
- VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
- VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
-
- VISIT_INSTANCE_GETTER_DECL,
- VISIT_INSTANCE_SETTER_DECL,
- VISIT_INSTANCE_METHOD_DECL,
- VISIT_ABSTRACT_GETTER_DECL,
- VISIT_ABSTRACT_SETTER_DECL,
- VISIT_ABSTRACT_METHOD_DECL,
- VISIT_INSTANCE_FIELD_DECL,
-
- VISIT_GENERATIVE_CONSTRUCTOR_DECL,
- VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,
- VISIT_FACTORY_CONSTRUCTOR_DECL,
- VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
-
- VISIT_REQUIRED_PARAMETER_DECL,
- VISIT_OPTIONAL_PARAMETER_DECL,
- VISIT_NAMED_PARAMETER_DECL,
- VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,
- VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,
- VISIT_NAMED_INITIALIZING_FORMAL_DECL,
-
- VISIT_UNRESOLVED_COMPOUND,
- VISIT_UNRESOLVED_PREFIX,
- VISIT_UNRESOLVED_POSTFIX,
-
- VISIT_IF_NULL,
- VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
- VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,
- VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,
- VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,
- VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,
- VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,
-
- ERROR_INVALID_ASSERT,
- ERROR_UNDEFINED_UNARY_EXPRESSION,
- ERROR_UNDEFINED_BINARY_EXPRESSION,
-
- VISIT_CONSTANT_GET,
- VISIT_CONSTANT_INVOKE,
-}
+// 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_test;
+
+import 'dart:async';
+import 'dart:mirrors';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/constants/expressions.dart';
+import 'package:compiler/src/dart_types.dart';
+import 'package:compiler/src/dart2jslib.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/resolution/resolution.dart';
+import 'package:compiler/src/resolution/semantic_visitor.dart';
+import 'package:compiler/src/resolution/operators.dart';
+import 'package:compiler/src/tree/tree.dart';
+import 'package:compiler/src/util/util.dart';
+import 'memory_compiler.dart';
+
+part 'semantic_visitor_test_send_data.dart';
+part 'semantic_visitor_test_send_visitor.dart';
+part 'semantic_visitor_test_decl_data.dart';
+part 'semantic_visitor_test_decl_visitor.dart';
+
+class Visit {
+ final VisitKind method;
+ final element;
+ final rhs;
+ final arguments;
+ final receiver;
+ final name;
+ final expression;
+ final left;
+ final right;
+ final type;
+ final operator;
+ final index;
+ final getter;
+ final setter;
+ final constant;
+ final selector;
+ final parameters;
+ final body;
+ final target;
+ final targetType;
+ final initializers;
+
+ const Visit(this.method,
+ {this.element,
+ this.rhs,
+ this.arguments,
+ this.receiver,
+ this.name,
+ this.expression,
+ this.left,
+ this.right,
+ this.type,
+ this.operator,
+ this.index,
+ this.getter,
+ this.setter,
+ this.constant,
+ this.selector,
+ this.parameters,
+ this.body,
+ this.target,
+ this.targetType,
+ this.initializers});
+
+ int get hashCode => toString().hashCode;
+
+ bool operator ==(other) => '$this' == '$other';
+
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.write('method=$method');
+ if (element != null) {
+ sb.write(',element=$element');
+ }
+ if (rhs != null) {
+ sb.write(',rhs=$rhs');
+ }
+ if (arguments != null) {
+ sb.write(',arguments=$arguments');
+ }
+ if (receiver != null) {
+ sb.write(',receiver=$receiver');
+ }
+ if (name != null) {
+ sb.write(',name=$name');
+ }
+ if (expression != null) {
+ sb.write(',expression=$expression');
+ }
+ if (left != null) {
+ sb.write(',left=$left');
+ }
+ if (right != null) {
+ sb.write(',right=$right');
+ }
+ if (type != null) {
+ sb.write(',type=$type');
+ }
+ if (operator != null) {
+ sb.write(',operator=$operator');
+ }
+ if (index != null) {
+ sb.write(',index=$index');
+ }
+ if (getter != null) {
+ sb.write(',getter=$getter');
+ }
+ if (setter != null) {
+ sb.write(',setter=$setter');
+ }
+ if (constant != null) {
+ sb.write(',constant=$constant');
+ }
+ if (selector != null) {
+ sb.write(',selector=$selector');
+ }
+ if (parameters != null) {
+ sb.write(',parameters=$parameters');
+ }
+ if (body != null) {
+ sb.write(',body=$body');
+ }
+ if (target != null) {
+ sb.write(',target=$target');
+ }
+ if (targetType != null) {
+ sb.write(',targetType=$targetType');
+ }
+ if (initializers != null) {
+ sb.write(',initializers=$initializers');
+ }
+ return sb.toString();
+ }
+}
+
+class Test {
+ final String codeByPrefix;
+ final String code;
+ final /*Visit | List<Visit>*/ expectedVisits;
+ final String cls;
+ final String method;
+
+ const Test(this.code, this.expectedVisits)
+ : cls = null, method = 'm', codeByPrefix = null;
+ const Test.clazz(this.code, this.expectedVisits,
+ {this.cls: 'C', this.method: 'm'})
+ : codeByPrefix = null;
+ const Test.prefix(this.codeByPrefix, this.code, this.expectedVisits)
+ : cls = null, method = 'm';
+
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.writeln();
+ sb.writeln(code);
+ if (codeByPrefix != null) {
+ sb.writeln('imported by prefix:');
+ sb.writeln(codeByPrefix);
+ }
+ return sb.toString();
+ }
+}
+
+const List<VisitKind> UNTESTABLE_KINDS = const <VisitKind>[
+ // A final field shadowing a non-final field is currently not supported in
+ // resolution.
+ VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
+ VisitKind.VISIT_SUPER_FIELD_FIELD_PREFIX,
+ VisitKind.VISIT_SUPER_FIELD_FIELD_POSTFIX,
+ // Combination of method and setter with the same name is currently not
+ // supported by the element model.
+ VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+ VisitKind.VISIT_STATIC_METHOD_SETTER_PREFIX,
+ VisitKind.VISIT_STATIC_METHOD_SETTER_POSTFIX,
+ VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,
+ VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,
+ VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,
+ VisitKind.VISIT_SUPER_METHOD_SETTER_COMPOUND,
+ VisitKind.VISIT_SUPER_METHOD_SETTER_PREFIX,
+ VisitKind.VISIT_SUPER_METHOD_SETTER_POSTFIX,
+ // The constant expressions of assignment to constant type literals cannot be
+ // handled the compile constant evaluator.
+ VisitKind.VISIT_CLASS_TYPE_LITERAL_SET,
+ VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,
+ VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,
+ // Invalid assignments is currently report through an erroneous element.
+ VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,
+ VisitKind.VISIT_FINAL_PARAMETER_SET,
+ VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET,
+ VisitKind.VISIT_LOCAL_FUNCTION_SET,
+ VisitKind.VISIT_STATIC_GETTER_SET,
+ VisitKind.VISIT_FINAL_STATIC_FIELD_SET,
+ VisitKind.VISIT_STATIC_FUNCTION_SET,
+ VisitKind.VISIT_FINAL_TOP_LEVEL_FIELD_SET,
+ VisitKind.VISIT_TOP_LEVEL_GETTER_SET,
+ VisitKind.VISIT_TOP_LEVEL_FUNCTION_SET,
+ VisitKind.VISIT_FINAL_SUPER_FIELD_SET,
+ VisitKind.VISIT_SUPER_GETTER_SET,
+ VisitKind.VISIT_SUPER_METHOD_SET,
+ // The only undefined unary, `+`, is currently handled and skipped in the
+ // parser.
+ VisitKind.ERROR_UNDEFINED_UNARY_EXPRESSION,
+ // Constant expression are currently not computed during resolution.
+ VisitKind.VISIT_CONSTANT_GET,
+ VisitKind.VISIT_CONSTANT_INVOKE,
+];
+
+main(List<String> arguments) {
+ Set<VisitKind> kinds = new Set<VisitKind>.from(VisitKind.values);
+ asyncTest(() => Future.forEach([
+ () {
+ return test(
+ kinds,
+ arguments,
+ SEND_TESTS,
+ (elements) => new SemanticSendTestVisitor(elements));
+ },
+ () {
+ return test(
+ kinds,
+ arguments,
+ DECL_TESTS,
+ (elements) => new SemanticDeclarationTestVisitor(elements));
+ },
+ () {
+ Set<VisitKind> unvisitedKindSet =
+ kinds.toSet()..removeAll(UNTESTABLE_KINDS);
+ List<VisitKind> unvisitedKindList = unvisitedKindSet.toList();
+ unvisitedKindList..sort((a, b) => a.index.compareTo(b.index));
+
+ Expect.isTrue(unvisitedKindList.isEmpty,
+ "Untested visit kinds:\n ${unvisitedKindList.join(',\n ')},\n");
+
+ Set<VisitKind> testedUntestableKinds =
+ UNTESTABLE_KINDS.toSet()..removeAll(kinds);
+ Expect.isTrue(testedUntestableKinds.isEmpty,
+ "Tested untestable visit kinds (remove from UNTESTABLE_KINDS):\n "
+ "${testedUntestableKinds.join(',\n ')},\n");
+ },
+ () {
+ ClassMirror mirror1 = reflectType(SemanticSendTestVisitor);
+ Set<Symbol> symbols1 = mirror1.declarations.keys.toSet();
+ ClassMirror mirror2 = reflectType(SemanticSendVisitor);
+ Set<Symbol> symbols2 =
+ mirror2.declarations.values
+ .where((m) => m is MethodMirror &&
+ !m.isConstructor &&
+ m.simpleName != #apply)
+ .map((m) => m.simpleName).toSet();
+ symbols2.removeAll(symbols1);
+ Expect.isTrue(symbols2.isEmpty,
+ "Untested visit methods:\n ${symbols2.join(',\n ')},\n");
+ }
+ ], (f) => f()));
+}
+
+Future test(Set<VisitKind> unvisitedKinds,
+ List<String> arguments,
+ Map<String, List<Test>> TESTS,
+ SemanticTestVisitor createVisitor(TreeElements elements)) {
+ Map<String, String> sourceFiles = {};
+ Map<String, Test> testMap = {};
+ StringBuffer mainSource = new StringBuffer();
+ int index = 0;
+ TESTS.forEach((String group, List<Test> tests) {
+ if (arguments.isNotEmpty && !arguments.contains(group)) return;
+
+ tests.forEach((Test test) {
+ StringBuffer testSource = new StringBuffer();
+ if (test.codeByPrefix != null) {
+ String prefixFilename = 'pre$index.dart';
+ sourceFiles[prefixFilename] = test.codeByPrefix;
+ testSource.writeln("import '$prefixFilename' as p;");
+ }
+
+ String filename = 'lib$index.dart';
+ testSource.writeln(test.code);
+ sourceFiles[filename] = testSource.toString();
+ mainSource.writeln("import '$filename';");
+ testMap[filename] = test;
+ index++;
+ });
+ });
+ mainSource.writeln("main() {}");
+ sourceFiles['main.dart'] = mainSource.toString();
+
+ Compiler compiler = compilerFor(sourceFiles,
+ options: ['--analyze-all',
+ '--analyze-only',
+ '--enable-null-aware-operators']);
+ return compiler.run(Uri.parse('memory:main.dart')).then((_) {
+ testMap.forEach((String filename, Test test) {
+ LibraryElement library = compiler.libraryLoader.lookupLibrary(
+ Uri.parse('memory:$filename'));
+ Element element;
+ String cls = test.cls;
+ String method = test.method;
+ if (cls == null) {
+ element = library.find(method);
+ } else {
+ ClassElement classElement = library.find(cls);
+ Expect.isNotNull(classElement,
+ "Class '$cls' not found in:\n"
+ "${library.compilationUnit.script.text}");
+ element = classElement.localLookup(method);
+ }
+ var expectedVisits = test.expectedVisits;
+ if (expectedVisits == null) {
+ Expect.isTrue(element.isErroneous,
+ "Element '$method' expected to be have parse errors in:\n"
+ "${library.compilationUnit.script.text}");
+ return;
+ } else if (expectedVisits is! List) {
+ expectedVisits = [expectedVisits];
+ }
+ Expect.isFalse(element.isErroneous,
+ "Element '$method' is not expected to be have parse errors in:\n"
+ "${library.compilationUnit.script.text}");
+
+ void testAstElement(AstElement astElement) {
+ Expect.isNotNull(astElement, "Element '$method' not found in:\n"
+ "${library.compilationUnit.script.text}");
+ ResolvedAst resolvedAst = astElement.resolvedAst;
+ SemanticTestVisitor visitor = createVisitor(resolvedAst.elements);
+ try {
+ compiler.withCurrentElement(resolvedAst.element, () {
+ //print(resolvedAst.node.toDebugString());
+ resolvedAst.node.accept(visitor);
+ });
+ } catch (e, s) {
+ Expect.fail("$e:\n$s\nIn test:\n"
+ "${library.compilationUnit.script.text}");
+ }
+ Expect.listEquals(expectedVisits, visitor.visits,
+ "In test:\n"
+ "${library.compilationUnit.script.text}\n\n"
+ "Expected: $expectedVisits\n"
+ "Found: ${visitor.visits}");
+ unvisitedKinds.removeAll(visitor.visits.map((visit) => visit.method));
+ }
+ if (element.isAbstractField) {
+ AbstractFieldElement abstractFieldElement = element;
+ if (abstractFieldElement.getter != null) {
+ testAstElement(abstractFieldElement.getter);
+ } else if (abstractFieldElement.setter != null) {
+ testAstElement(abstractFieldElement.setter);
+ }
+ } else {
+ testAstElement(element);
+ }
+ });
+ });
+}
+
+abstract class SemanticTestVisitor extends TraversalVisitor {
+ List<Visit> visits = <Visit>[];
+
+ SemanticTestVisitor(TreeElements elements) : super(elements);
+
+ apply(Node node, arg) => node.accept(this);
+
+ internalError(Spannable spannable, String message) {
+ throw new SpannableAssertionFailure(spannable, message);
+ }
+}
+
+enum VisitKind {
+ VISIT_PARAMETER_GET,
+ VISIT_PARAMETER_SET,
+ VISIT_PARAMETER_INVOKE,
+ VISIT_PARAMETER_COMPOUND,
+ VISIT_PARAMETER_PREFIX,
+ VISIT_PARAMETER_POSTFIX,
+ VISIT_FINAL_PARAMETER_SET,
+ VISIT_FINAL_PARAMETER_COMPOUND,
+ VISIT_FINAL_PARAMETER_PREFIX,
+ VISIT_FINAL_PARAMETER_POSTFIX,
+
+ VISIT_LOCAL_VARIABLE_GET,
+ VISIT_LOCAL_VARIABLE_SET,
+ VISIT_LOCAL_VARIABLE_INVOKE,
+ VISIT_LOCAL_VARIABLE_COMPOUND,
+ VISIT_LOCAL_VARIABLE_PREFIX,
+ VISIT_LOCAL_VARIABLE_POSTFIX,
+ VISIT_LOCAL_VARIABLE_DECL,
+ VISIT_LOCAL_CONSTANT_DECL,
+ VISIT_FINAL_LOCAL_VARIABLE_SET,
+ VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,
+ VISIT_FINAL_LOCAL_VARIABLE_PREFIX,
+ VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,
+
+ VISIT_LOCAL_FUNCTION_GET,
+ VISIT_LOCAL_FUNCTION_INVOKE,
+ VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,
+ VISIT_LOCAL_FUNCTION_DECL,
+ VISIT_CLOSURE_DECL,
+ VISIT_LOCAL_FUNCTION_SET,
+ VISIT_LOCAL_FUNCTION_COMPOUND,
+ VISIT_LOCAL_FUNCTION_PREFIX,
+ VISIT_LOCAL_FUNCTION_POSTFIX,
+
+ VISIT_STATIC_FIELD_GET,
+ VISIT_STATIC_FIELD_SET,
+ VISIT_STATIC_FIELD_INVOKE,
+ VISIT_STATIC_FIELD_COMPOUND,
+ VISIT_STATIC_FIELD_PREFIX,
+ VISIT_STATIC_FIELD_POSTFIX,
+ VISIT_STATIC_FIELD_DECL,
+ VISIT_STATIC_CONSTANT_DECL,
+
+ VISIT_STATIC_GETTER_GET,
+ VISIT_STATIC_GETTER_SET,
+ VISIT_STATIC_GETTER_INVOKE,
+
+ VISIT_STATIC_SETTER_GET,
+ VISIT_STATIC_SETTER_SET,
+ VISIT_STATIC_SETTER_INVOKE,
+
+ VISIT_STATIC_GETTER_SETTER_COMPOUND,
+ VISIT_STATIC_METHOD_SETTER_COMPOUND,
+ VISIT_STATIC_GETTER_SETTER_PREFIX,
+ VISIT_STATIC_GETTER_SETTER_POSTFIX,
+
+ VISIT_STATIC_GETTER_DECL,
+ VISIT_STATIC_SETTER_DECL,
+
+ VISIT_FINAL_STATIC_FIELD_SET,
+ VISIT_STATIC_FINAL_FIELD_COMPOUND,
+ VISIT_STATIC_FINAL_FIELD_POSTFIX,
+ VISIT_STATIC_FINAL_FIELD_PREFIX,
+
+ VISIT_STATIC_FUNCTION_GET,
+ VISIT_STATIC_FUNCTION_SET,
+ VISIT_STATIC_FUNCTION_INVOKE,
+ VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,
+ VISIT_STATIC_FUNCTION_DECL,
+ VISIT_STATIC_METHOD_SETTER_PREFIX,
+ VISIT_STATIC_METHOD_SETTER_POSTFIX,
+
+ VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,
+ VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,
+ VISIT_STATIC_METHOD_COMPOUND,
+ VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,
+ VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,
+ VISIT_STATIC_METHOD_PREFIX,
+ VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,
+ VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,
+ VISIT_STATIC_METHOD_POSTFIX,
+
+ VISIT_TOP_LEVEL_FIELD_GET,
+ VISIT_TOP_LEVEL_FIELD_SET,
+ VISIT_TOP_LEVEL_FIELD_INVOKE,
+ VISIT_FINAL_TOP_LEVEL_FIELD_SET,
+ VISIT_TOP_LEVEL_FIELD_COMPOUND,
+ VISIT_TOP_LEVEL_FIELD_PREFIX,
+ VISIT_TOP_LEVEL_FIELD_POSTFIX,
+ VISIT_TOP_LEVEL_FIELD_DECL,
+ VISIT_TOP_LEVEL_CONSTANT_DECL,
+ VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,
+ VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,
+ VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,
+
+ VISIT_TOP_LEVEL_GETTER_GET,
+ VISIT_TOP_LEVEL_GETTER_SET,
+ VISIT_TOP_LEVEL_GETTER_INVOKE,
+ VISIT_TOP_LEVEL_SETTER_GET,
+ VISIT_TOP_LEVEL_SETTER_SET,
+ VISIT_TOP_LEVEL_SETTER_INVOKE,
+ VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,
+ VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,
+ VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,
+ VISIT_TOP_LEVEL_GETTER_DECL,
+ VISIT_TOP_LEVEL_SETTER_DECL,
+
+ VISIT_TOP_LEVEL_FUNCTION_GET,
+ VISIT_TOP_LEVEL_FUNCTION_SET,
+ VISIT_TOP_LEVEL_FUNCTION_INVOKE,
+ VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,
+ VISIT_TOP_LEVEL_FUNCTION_DECL,
+ VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,
+ VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,
+ VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,
+
+ VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,
+ VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,
+ VISIT_TOP_LEVEL_METHOD_COMPOUND,
+ VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,
+ VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,
+ VISIT_TOP_LEVEL_METHOD_PREFIX,
+ VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,
+ VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,
+ VISIT_TOP_LEVEL_METHOD_POSTFIX,
+
+ VISIT_DYNAMIC_PROPERTY_GET,
+ VISIT_DYNAMIC_PROPERTY_SET,
+ VISIT_DYNAMIC_PROPERTY_INVOKE,
+ VISIT_DYNAMIC_PROPERTY_COMPOUND,
+ VISIT_DYNAMIC_PROPERTY_PREFIX,
+ VISIT_DYNAMIC_PROPERTY_POSTFIX,
+
+ VISIT_THIS_GET,
+ VISIT_THIS_INVOKE,
+
+ VISIT_THIS_PROPERTY_GET,
+ VISIT_THIS_PROPERTY_SET,
+ VISIT_THIS_PROPERTY_INVOKE,
+ VISIT_THIS_PROPERTY_COMPOUND,
+ VISIT_THIS_PROPERTY_PREFIX,
+ VISIT_THIS_PROPERTY_POSTFIX,
+
+ VISIT_SUPER_FIELD_GET,
+ VISIT_SUPER_FIELD_SET,
+ VISIT_FINAL_SUPER_FIELD_SET,
+ VISIT_SUPER_FIELD_INVOKE,
+ VISIT_SUPER_FIELD_COMPOUND,
+ VISIT_SUPER_FIELD_PREFIX,
+ VISIT_SUPER_FIELD_POSTFIX,
+ VISIT_SUPER_FINAL_FIELD_COMPOUND,
+ VISIT_SUPER_FINAL_FIELD_PREFIX,
+ VISIT_SUPER_FINAL_FIELD_POSTFIX,
+ VISIT_SUPER_FIELD_FIELD_COMPOUND,
+ VISIT_SUPER_FIELD_FIELD_PREFIX,
+ VISIT_SUPER_FIELD_FIELD_POSTFIX,
+
+ VISIT_SUPER_GETTER_GET,
+ VISIT_SUPER_GETTER_SET,
+ VISIT_SUPER_GETTER_INVOKE,
+ VISIT_SUPER_SETTER_GET,
+ VISIT_SUPER_SETTER_SET,
+ VISIT_SUPER_SETTER_INVOKE,
+ VISIT_SUPER_GETTER_SETTER_COMPOUND,
+ VISIT_SUPER_GETTER_FIELD_COMPOUND,
+ VISIT_SUPER_FIELD_SETTER_COMPOUND,
+ VISIT_SUPER_GETTER_SETTER_PREFIX,
+ VISIT_SUPER_GETTER_FIELD_PREFIX,
+ VISIT_SUPER_FIELD_SETTER_PREFIX,
+ VISIT_SUPER_GETTER_SETTER_POSTFIX,
+ VISIT_SUPER_GETTER_FIELD_POSTFIX,
+ VISIT_SUPER_FIELD_SETTER_POSTFIX,
+
+ VISIT_SUPER_METHOD_GET,
+ VISIT_SUPER_METHOD_SET,
+ VISIT_SUPER_METHOD_INVOKE,
+ VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,
+ VISIT_SUPER_METHOD_SETTER_COMPOUND,
+ VISIT_SUPER_METHOD_SETTER_PREFIX,
+ VISIT_SUPER_METHOD_SETTER_POSTFIX,
+ VISIT_SUPER_METHOD_COMPOUND,
+ VISIT_SUPER_METHOD_PREFIX,
+ VISIT_SUPER_METHOD_POSTFIX,
+
+ VISIT_UNRESOLVED_GET,
+ VISIT_UNRESOLVED_SET,
+ VISIT_UNRESOLVED_INVOKE,
+ VISIT_UNRESOLVED_SUPER_GET,
+ VISIT_UNRESOLVED_SUPER_INVOKE,
+
+ VISIT_BINARY,
+ VISIT_INDEX,
+ VISIT_EQUALS,
+ VISIT_NOT_EQUALS,
+ VISIT_INDEX_PREFIX,
+ VISIT_INDEX_POSTFIX,
+
+ VISIT_SUPER_BINARY,
+ VISIT_UNRESOLVED_SUPER_BINARY,
+ VISIT_SUPER_INDEX,
+ VISIT_UNRESOLVED_SUPER_INDEX,
+ VISIT_SUPER_EQUALS,
+ VISIT_SUPER_NOT_EQUALS,
+ VISIT_SUPER_INDEX_PREFIX,
+ VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,
+ VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,
+ VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,
+ VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,
+ VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,
+ VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,
+ VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,
+ VISIT_SUPER_INDEX_POSTFIX,
+ VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,
+ VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,
+ VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,
+ VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,
+ VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,
+
+ VISIT_UNRESOLVED_SUPER_COMPOUND,
+ VISIT_UNRESOLVED_SUPER_PREFIX,
+ VISIT_UNRESOLVED_SUPER_POSTFIX,
+
+ VISIT_UNARY,
+ VISIT_SUPER_UNARY,
+ VISIT_UNRESOLVED_SUPER_UNARY,
+ VISIT_NOT,
+
+ VISIT_EXPRESSION_INVOKE,
+
+ VISIT_CLASS_TYPE_LITERAL_GET,
+ VISIT_CLASS_TYPE_LITERAL_SET,
+ VISIT_CLASS_TYPE_LITERAL_INVOKE,
+ VISIT_CLASS_TYPE_LITERAL_COMPOUND,
+ VISIT_CLASS_TYPE_LITERAL_PREFIX,
+ VISIT_CLASS_TYPE_LITERAL_POSTFIX,
+
+ VISIT_TYPEDEF_TYPE_LITERAL_GET,
+ VISIT_TYPEDEF_TYPE_LITERAL_SET,
+ VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
+ VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,
+ VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
+ VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,
+
+ VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,
+ VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,
+ VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,
+ VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,
+ VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,
+ VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,
+
+ VISIT_DYNAMIC_TYPE_LITERAL_GET,
+ VISIT_DYNAMIC_TYPE_LITERAL_SET,
+ VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
+ VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,
+ VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
+ VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,
+
+ VISIT_INDEX_SET,
+ VISIT_COMPOUND_INDEX_SET,
+ VISIT_SUPER_INDEX_SET,
+ VISIT_UNRESOLVED_SUPER_INDEX_SET,
+ VISIT_SUPER_COMPOUND_INDEX_SET,
+ VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,
+ VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,
+ VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,
+
+ VISIT_ASSERT,
+ VISIT_LOGICAL_AND,
+ VISIT_LOGICAL_OR,
+ VISIT_IS,
+ VISIT_IS_NOT,
+ VISIT_AS,
+
+ VISIT_CONST_CONSTRUCTOR_INVOKE,
+ VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+ VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+ VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+ VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+ VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
+ VISIT_FACTORY_CONSTRUCTOR_INVOKE,
+ VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
+ ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,
+
+ VISIT_SUPER_CONSTRUCTOR_INVOKE,
+ VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+ VISIT_THIS_CONSTRUCTOR_INVOKE,
+ VISIT_FIELD_INITIALIZER,
+
+ VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
+ VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,
+ VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
+ VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+
+ VISIT_INSTANCE_GETTER_DECL,
+ VISIT_INSTANCE_SETTER_DECL,
+ VISIT_INSTANCE_METHOD_DECL,
+ VISIT_ABSTRACT_GETTER_DECL,
+ VISIT_ABSTRACT_SETTER_DECL,
+ VISIT_ABSTRACT_METHOD_DECL,
+ VISIT_INSTANCE_FIELD_DECL,
+
+ VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+ VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,
+ VISIT_FACTORY_CONSTRUCTOR_DECL,
+ VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+
+ VISIT_REQUIRED_PARAMETER_DECL,
+ VISIT_OPTIONAL_PARAMETER_DECL,
+ VISIT_NAMED_PARAMETER_DECL,
+ VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,
+ VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,
+ VISIT_NAMED_INITIALIZING_FORMAL_DECL,
+
+ VISIT_UNRESOLVED_COMPOUND,
+ VISIT_UNRESOLVED_PREFIX,
+ VISIT_UNRESOLVED_POSTFIX,
+
+ VISIT_IF_NULL,
+ VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
+ VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,
+ VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,
+ VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,
+ VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,
+ VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,
+
+ ERROR_INVALID_ASSERT,
+ ERROR_UNDEFINED_UNARY_EXPRESSION,
+ ERROR_UNDEFINED_BINARY_EXPRESSION,
+
+ VISIT_CONSTANT_GET,
+ VISIT_CONSTANT_INVOKE,
+}
diff --git a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart b/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
index ab22664..f31b688 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
@@ -1,870 +1,870 @@
-// 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_test;
-
-const Map<String, List<Test>> DECL_TESTS = const {
- 'Function declarations': const [
- const Test(
- '''
- m(a, b) {}
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '(a,b)',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#b)',
- index: 1),
- ]),
- const Test(
- '''
- m(a, [b]) {}
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '(a,[b])',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
- element: 'parameter(m#b)',
- index: 1,
- constant: 'null'),
- ]),
- const Test(
- '''
- m(a, [b = null]) {}
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '(a,[b=null])',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
- element: 'parameter(m#b)',
- constant: 'null',
- index: 1),
- ]),
- const Test(
- '''
- m(a, [b = 42]) {}
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '(a,[b=42])',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
- element: 'parameter(m#b)',
- constant: 42,
- index: 1),
- ]),
- const Test(
- '''
- m(a, {b}) {}
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '(a,{b})',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
- element: 'parameter(m#b)',
- constant: 'null'),
- ]),
- const Test(
- '''
- m(a, {b: null}) {}
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '(a,{b: null})',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
- element: 'parameter(m#b)',
- constant: 'null'),
- ]),
- const Test(
- '''
- m(a, {b:42}) {}
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '(a,{b: 42})',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
- element: 'parameter(m#b)',
- constant: 42),
- ]),
- const Test(
- '''
- get m => null;
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_DECL,
- element: 'getter(m)',
- body: '=>null;'),
- ]),
- const Test(
- '''
- set m(a) {}
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_DECL,
- element: 'setter(m)',
- parameters: '(a)',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- ]),
- const Test.clazz(
- '''
- class C {
- static m(a, b) {}
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_STATIC_FUNCTION_DECL,
- element: 'function(C#m)',
- parameters: '(a,b)',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#b)',
- index: 1),
- ]),
- const Test.clazz(
- '''
- class C {
- static get m => null;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_STATIC_GETTER_DECL,
- element: 'getter(C#m)',
- body: '=>null;'),
- ]),
- const Test.clazz(
- '''
- class C {
- static set m(a) {}
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_STATIC_SETTER_DECL,
- element: 'setter(C#m)',
- parameters: '(a)',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- ]),
- const Test.clazz(
- '''
- class C {
- m(a, b) {}
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_INSTANCE_METHOD_DECL,
- element: 'function(C#m)',
- parameters: '(a,b)',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#b)',
- index: 1),
- ]),
- const Test.clazz(
- '''
- class C {
- get m => null;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_INSTANCE_GETTER_DECL,
- element: 'getter(C#m)',
- body: '=>null;'),
- ]),
- const Test.clazz(
- '''
- class C {
- set m(a) {}
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_INSTANCE_SETTER_DECL,
- element: 'setter(C#m)',
- parameters: '(a)',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- ]),
- const Test.clazz(
- '''
- abstract class C {
- m(a, b);
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_ABSTRACT_METHOD_DECL,
- element: 'function(C#m)',
- parameters: '(a,b)'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#b)',
- index: 1),
- ]),
- const Test.clazz(
- '''
- abstract class C {
- get m;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_ABSTRACT_GETTER_DECL,
- element: 'getter(C#m)'),
- ]),
- const Test.clazz(
- '''
- abstract class C {
- set m(a);
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_ABSTRACT_SETTER_DECL,
- element: 'setter(C#m)',
- parameters: '(a)'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- ]),
- const Test(
- '''
- m(a, b) {}
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '(a,b)',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(m#b)',
- index: 1),
- ]),
- const Test(
- '''
- m() {
- local(a, b) {}
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '()',
- body: '{local(a,b){}}'),
- const Visit(VisitKind.VISIT_LOCAL_FUNCTION_DECL,
- element: 'function(m#local)',
- parameters: '(a,b)',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(local#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(local#b)',
- index: 1),
- ]),
- const Test(
- '''
- m() => (a, b) {};
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '()',
- body: '=>(a,b){};'),
- const Visit(VisitKind.VISIT_CLOSURE_DECL,
- element: 'function(m#)',
- parameters: '(a,b)',
- body: '{}'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- ]),
- ],
- 'Constructor declarations': const [
- const Test.clazz(
- '''
- class C {
- C(a, b);
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
- element: 'generative_constructor(C#)',
- parameters: '(a,b)',
- body: ';'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Object#)',
- type: 'Object'),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- var b;
- C(a, this.b);
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
- element: 'generative_constructor(C#)',
- parameters: '(a,this.b)',
- body: ';'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,
- element: 'initializing_formal(#b)',
- index: 1),
- const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Object#)',
- type: 'Object'),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- var b;
- C(a, [this.b = 42]);
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
- element: 'generative_constructor(C#)',
- parameters: '(a,[this.b=42])',
- body: ';'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,
- element: 'initializing_formal(#b)',
- constant: 42,
- index: 1),
- const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Object#)',
- type: 'Object'),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- var b;
- C(a, {this.b: 42});
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
- element: 'generative_constructor(C#)',
- parameters: '(a,{this.b: 42})',
- body: ';'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_NAMED_INITIALIZING_FORMAL_DECL,
- element: 'initializing_formal(#b)',
- constant: 42),
- const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Object#)',
- type: 'Object'),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- C(a, b) : super();
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
- element: 'generative_constructor(C#)',
- parameters: '(a,b)',
- body: ';'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- const Visit(VisitKind.VISIT_SUPER_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Object#)',
- type: 'Object',
- arguments: '()',
- selector: 'CallStructure(arity=0)'),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- var field;
- C(a, b) : this.field = a;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
- element: 'generative_constructor(C#)',
- parameters: '(a,b)',
- body: ';'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- const Visit(VisitKind.VISIT_FIELD_INITIALIZER,
- element: 'field(C#field)',
- rhs: 'a'),
- const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Object#)',
- type: 'Object'),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- var field1;
- var field2;
- C(a, b) : this.field1 = a, this.field2 = b;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
- element: 'generative_constructor(C#)',
- parameters: '(a,b)',
- body: ';'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- const Visit(VisitKind.VISIT_FIELD_INITIALIZER,
- element: 'field(C#field1)',
- rhs: 'a'),
- const Visit(VisitKind.VISIT_FIELD_INITIALIZER,
- element: 'field(C#field2)',
- rhs: 'b'),
- const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Object#)',
- type: 'Object'),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- C(a, b) : this._(a, b);
- C._(a, b);
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,
- element: 'generative_constructor(C#)',
- parameters: '(a,b)',
- initializers: ':this._(a,b)'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- const Visit(VisitKind.VISIT_THIS_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(C#_)',
- arguments: '(a,b)',
- selector: 'CallStructure(arity=2)'),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- factory C(a, b) => null;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_DECL,
- element: 'function(C#)',
- parameters: '(a,b)',
- body: '=>null;'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- factory C(a, b) = C._;
- C._(a, b);
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
- element: 'function(C#)',
- parameters: '(a,b)',
- target: 'generative_constructor(C#_)',
- type: 'C'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- factory C(a, b) = D;
- }
- class D<T> {
- D(a, b);
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
- element: 'function(C#)',
- parameters: '(a,b)',
- target: 'generative_constructor(D#)',
- type: 'D'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- factory C(a, b) = D<int>;
- }
- class D<T> {
- D(a, b);
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
- element: 'function(C#)',
- parameters: '(a,b)',
- target: 'generative_constructor(D#)',
- type: 'D<int>'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- ],
- method: ''),
- const Test.clazz(
- '''
- class C {
- factory C(a, b) = D<int>;
- }
- class D<T> {
- factory D(a, b) = E<D<T>>;
- }
- class E<S> {
- E(a, b);
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
- element: 'function(C#)',
- parameters: '(a,b)',
- target: 'function(D#)',
- type: 'D<int>'),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#a)',
- index: 0),
- const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: 'parameter(#b)',
- index: 1),
- ],
- method: ''),
- ],
- "Field declarations": const [
- const Test.clazz(
- '''
- class C {
- var m;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
- element: 'field(C#m)'),
- ]),
- const Test.clazz(
- '''
- class C {
- var m, n;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
- element: 'field(C#m)'),
- ]),
- const Test.clazz(
- '''
- class C {
- var m = 42;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
- element: 'field(C#m)',
- rhs: 42),
- ]),
- const Test(
- '''
- m() {
- var local;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '()',
- body: '{var local;}'),
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
- element: 'variable(m#local)'),
- ]),
- const Test(
- '''
- m() {
- var local = 42;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '()',
- body: '{var local=42;}'),
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
- element: 'variable(m#local)',
- rhs: 42),
- ]),
- const Test(
- '''
- m() {
- const local = 42;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '()',
- body: '{const local=42;}'),
- const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
- element: 'variable(m#local)',
- constant: 42),
- ]),
- const Test(
- '''
- m() {
- var local1, local2;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '()',
- body: '{var local1,local2;}'),
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
- element: 'variable(m#local1)'),
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
- element: 'variable(m#local2)'),
- ]),
- const Test(
- '''
- m() {
- var local1 = 42, local2 = true;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '()',
- body: '{var local1=42,local2=true;}'),
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
- element: 'variable(m#local1)',
- rhs: 42),
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
- element: 'variable(m#local2)',
- rhs: true),
- ]),
- const Test(
- '''
- m() {
- const local1 = 42, local2 = true;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: 'function(m)',
- parameters: '()',
- body: '{const local1=42,local2=true;}'),
- const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
- element: 'variable(m#local1)',
- constant: 42),
- const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
- element: 'variable(m#local2)',
- constant: true),
- ]),
- const Test.clazz(
- '''
- class C {
- static var m;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
- element: 'field(C#m)'),
- ]),
- const Test.clazz(
- '''
- class C {
- static var m, n;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
- element: 'field(C#m)'),
- ]),
- const Test.clazz(
- '''
- class C {
- static var k, l, m, n;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
- element: 'field(C#m)'),
- ]),
- const Test.clazz(
- '''
- class C {
- static var m = 42;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
- element: 'field(C#m)',
- rhs: 42),
- ]),
- const Test.clazz(
- '''
- class C {
- static var m = 42, n = true;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
- element: 'field(C#m)',
- rhs: 42),
- ]),
- const Test.clazz(
- '''
- class C {
- static const m = 42;
- }
- ''',
- const [
- const Visit(VisitKind.VISIT_STATIC_CONSTANT_DECL,
- element: 'field(C#m)',
- constant: 42),
- ]),
- const Test(
- '''
- var m;
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
- element: 'field(m)'),
- ]),
- const Test(
- '''
- var m, n;
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
- element: 'field(m)'),
- ]),
- const Test(
- '''
- var m = 42;
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
- element: 'field(m)',
- rhs: 42),
- ]),
- const Test(
- '''
- const m = 42;
- ''',
- const [
- const Visit(VisitKind.VISIT_TOP_LEVEL_CONSTANT_DECL,
- element: 'field(m)',
- constant: 42),
- ]),
- ],
-};
+// 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_test;
+
+const Map<String, List<Test>> DECL_TESTS = const {
+ 'Function declarations': const [
+ const Test(
+ '''
+ m(a, b) {}
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '(a,b)',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ index: 1),
+ ]),
+ const Test(
+ '''
+ m(a, [b]) {}
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '(a,[b])',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ index: 1,
+ constant: 'null'),
+ ]),
+ const Test(
+ '''
+ m(a, [b = null]) {}
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '(a,[b=null])',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ constant: 'null',
+ index: 1),
+ ]),
+ const Test(
+ '''
+ m(a, [b = 42]) {}
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '(a,[b=42])',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ constant: 42,
+ index: 1),
+ ]),
+ const Test(
+ '''
+ m(a, {b}) {}
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '(a,{b})',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ constant: 'null'),
+ ]),
+ const Test(
+ '''
+ m(a, {b: null}) {}
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '(a,{b: null})',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ constant: 'null'),
+ ]),
+ const Test(
+ '''
+ m(a, {b:42}) {}
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '(a,{b: 42})',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ constant: 42),
+ ]),
+ const Test(
+ '''
+ get m => null;
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_DECL,
+ element: 'getter(m)',
+ body: '=>null;'),
+ ]),
+ const Test(
+ '''
+ set m(a) {}
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_DECL,
+ element: 'setter(m)',
+ parameters: '(a)',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ static m(a, b) {}
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_STATIC_FUNCTION_DECL,
+ element: 'function(C#m)',
+ parameters: '(a,b)',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ index: 1),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ static get m => null;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_STATIC_GETTER_DECL,
+ element: 'getter(C#m)',
+ body: '=>null;'),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ static set m(a) {}
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_STATIC_SETTER_DECL,
+ element: 'setter(C#m)',
+ parameters: '(a)',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ m(a, b) {}
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_INSTANCE_METHOD_DECL,
+ element: 'function(C#m)',
+ parameters: '(a,b)',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ index: 1),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ get m => null;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_INSTANCE_GETTER_DECL,
+ element: 'getter(C#m)',
+ body: '=>null;'),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ set m(a) {}
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_INSTANCE_SETTER_DECL,
+ element: 'setter(C#m)',
+ parameters: '(a)',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ ]),
+ const Test.clazz(
+ '''
+ abstract class C {
+ m(a, b);
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_ABSTRACT_METHOD_DECL,
+ element: 'function(C#m)',
+ parameters: '(a,b)'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ index: 1),
+ ]),
+ const Test.clazz(
+ '''
+ abstract class C {
+ get m;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_ABSTRACT_GETTER_DECL,
+ element: 'getter(C#m)'),
+ ]),
+ const Test.clazz(
+ '''
+ abstract class C {
+ set m(a);
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_ABSTRACT_SETTER_DECL,
+ element: 'setter(C#m)',
+ parameters: '(a)'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ ]),
+ const Test(
+ '''
+ m(a, b) {}
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '(a,b)',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(m#b)',
+ index: 1),
+ ]),
+ const Test(
+ '''
+ m() {
+ local(a, b) {}
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '()',
+ body: '{local(a,b){}}'),
+ const Visit(VisitKind.VISIT_LOCAL_FUNCTION_DECL,
+ element: 'function(m#local)',
+ parameters: '(a,b)',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(local#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(local#b)',
+ index: 1),
+ ]),
+ const Test(
+ '''
+ m() => (a, b) {};
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '()',
+ body: '=>(a,b){};'),
+ const Visit(VisitKind.VISIT_CLOSURE_DECL,
+ element: 'function(m#)',
+ parameters: '(a,b)',
+ body: '{}'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ ]),
+ ],
+ 'Constructor declarations': const [
+ const Test.clazz(
+ '''
+ class C {
+ C(a, b);
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+ element: 'generative_constructor(C#)',
+ parameters: '(a,b)',
+ body: ';'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Object#)',
+ type: 'Object'),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ var b;
+ C(a, this.b);
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+ element: 'generative_constructor(C#)',
+ parameters: '(a,this.b)',
+ body: ';'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,
+ element: 'initializing_formal(#b)',
+ index: 1),
+ const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Object#)',
+ type: 'Object'),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ var b;
+ C(a, [this.b = 42]);
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+ element: 'generative_constructor(C#)',
+ parameters: '(a,[this.b=42])',
+ body: ';'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,
+ element: 'initializing_formal(#b)',
+ constant: 42,
+ index: 1),
+ const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Object#)',
+ type: 'Object'),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ var b;
+ C(a, {this.b: 42});
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+ element: 'generative_constructor(C#)',
+ parameters: '(a,{this.b: 42})',
+ body: ';'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_NAMED_INITIALIZING_FORMAL_DECL,
+ element: 'initializing_formal(#b)',
+ constant: 42),
+ const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Object#)',
+ type: 'Object'),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ C(a, b) : super();
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+ element: 'generative_constructor(C#)',
+ parameters: '(a,b)',
+ body: ';'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ const Visit(VisitKind.VISIT_SUPER_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Object#)',
+ type: 'Object',
+ arguments: '()',
+ selector: 'CallStructure(arity=0)'),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ var field;
+ C(a, b) : this.field = a;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+ element: 'generative_constructor(C#)',
+ parameters: '(a,b)',
+ body: ';'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ const Visit(VisitKind.VISIT_FIELD_INITIALIZER,
+ element: 'field(C#field)',
+ rhs: 'a'),
+ const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Object#)',
+ type: 'Object'),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ var field1;
+ var field2;
+ C(a, b) : this.field1 = a, this.field2 = b;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+ element: 'generative_constructor(C#)',
+ parameters: '(a,b)',
+ body: ';'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ const Visit(VisitKind.VISIT_FIELD_INITIALIZER,
+ element: 'field(C#field1)',
+ rhs: 'a'),
+ const Visit(VisitKind.VISIT_FIELD_INITIALIZER,
+ element: 'field(C#field2)',
+ rhs: 'b'),
+ const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Object#)',
+ type: 'Object'),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ C(a, b) : this._(a, b);
+ C._(a, b);
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,
+ element: 'generative_constructor(C#)',
+ parameters: '(a,b)',
+ initializers: ':this._(a,b)'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ const Visit(VisitKind.VISIT_THIS_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(C#_)',
+ arguments: '(a,b)',
+ selector: 'CallStructure(arity=2)'),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ factory C(a, b) => null;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_DECL,
+ element: 'function(C#)',
+ parameters: '(a,b)',
+ body: '=>null;'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ factory C(a, b) = C._;
+ C._(a, b);
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+ element: 'function(C#)',
+ parameters: '(a,b)',
+ target: 'generative_constructor(C#_)',
+ type: 'C'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ factory C(a, b) = D;
+ }
+ class D<T> {
+ D(a, b);
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+ element: 'function(C#)',
+ parameters: '(a,b)',
+ target: 'generative_constructor(D#)',
+ type: 'D'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ factory C(a, b) = D<int>;
+ }
+ class D<T> {
+ D(a, b);
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+ element: 'function(C#)',
+ parameters: '(a,b)',
+ target: 'generative_constructor(D#)',
+ type: 'D<int>'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ ],
+ method: ''),
+ const Test.clazz(
+ '''
+ class C {
+ factory C(a, b) = D<int>;
+ }
+ class D<T> {
+ factory D(a, b) = E<D<T>>;
+ }
+ class E<S> {
+ E(a, b);
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+ element: 'function(C#)',
+ parameters: '(a,b)',
+ target: 'function(D#)',
+ type: 'D<int>'),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#a)',
+ index: 0),
+ const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: 'parameter(#b)',
+ index: 1),
+ ],
+ method: ''),
+ ],
+ "Field declarations": const [
+ const Test.clazz(
+ '''
+ class C {
+ var m;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
+ element: 'field(C#m)'),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ var m, n;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
+ element: 'field(C#m)'),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ var m = 42;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
+ element: 'field(C#m)',
+ rhs: 42),
+ ]),
+ const Test(
+ '''
+ m() {
+ var local;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '()',
+ body: '{var local;}'),
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+ element: 'variable(m#local)'),
+ ]),
+ const Test(
+ '''
+ m() {
+ var local = 42;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '()',
+ body: '{var local=42;}'),
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+ element: 'variable(m#local)',
+ rhs: 42),
+ ]),
+ const Test(
+ '''
+ m() {
+ const local = 42;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '()',
+ body: '{const local=42;}'),
+ const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
+ element: 'variable(m#local)',
+ constant: 42),
+ ]),
+ const Test(
+ '''
+ m() {
+ var local1, local2;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '()',
+ body: '{var local1,local2;}'),
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+ element: 'variable(m#local1)'),
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+ element: 'variable(m#local2)'),
+ ]),
+ const Test(
+ '''
+ m() {
+ var local1 = 42, local2 = true;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '()',
+ body: '{var local1=42,local2=true;}'),
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+ element: 'variable(m#local1)',
+ rhs: 42),
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+ element: 'variable(m#local2)',
+ rhs: true),
+ ]),
+ const Test(
+ '''
+ m() {
+ const local1 = 42, local2 = true;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: 'function(m)',
+ parameters: '()',
+ body: '{const local1=42,local2=true;}'),
+ const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
+ element: 'variable(m#local1)',
+ constant: 42),
+ const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
+ element: 'variable(m#local2)',
+ constant: true),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ static var m;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+ element: 'field(C#m)'),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ static var m, n;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+ element: 'field(C#m)'),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ static var k, l, m, n;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+ element: 'field(C#m)'),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ static var m = 42;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+ element: 'field(C#m)',
+ rhs: 42),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ static var m = 42, n = true;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+ element: 'field(C#m)',
+ rhs: 42),
+ ]),
+ const Test.clazz(
+ '''
+ class C {
+ static const m = 42;
+ }
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_STATIC_CONSTANT_DECL,
+ element: 'field(C#m)',
+ constant: 42),
+ ]),
+ const Test(
+ '''
+ var m;
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
+ element: 'field(m)'),
+ ]),
+ const Test(
+ '''
+ var m, n;
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
+ element: 'field(m)'),
+ ]),
+ const Test(
+ '''
+ var m = 42;
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
+ element: 'field(m)',
+ rhs: 42),
+ ]),
+ const Test(
+ '''
+ const m = 42;
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_TOP_LEVEL_CONSTANT_DECL,
+ element: 'field(m)',
+ constant: 42),
+ ]),
+ ],
+};
diff --git a/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart b/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart
index 253f1f3..5382a29 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart
@@ -1,483 +1,483 @@
-// 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_test;
-
-class SemanticDeclarationTestVisitor extends SemanticTestVisitor {
-
- SemanticDeclarationTestVisitor(TreeElements elements) : super(elements);
-
- @override
- errorUnresolvedSuperConstructorInvoke(
- Send node,
- Element element,
- NodeList arguments,
- Selector selector,
- arg) {
- // TODO: implement errorUnresolvedSuperConstructorInvoke
- }
-
- @override
- errorUnresolvedThisConstructorInvoke(
- Send node,
- Element element,
- NodeList arguments,
- Selector selector,
- arg) {
- // TODO: implement errorUnresolvedThisConstructorInvoke
- }
-
- @override
- visitAbstractMethodDeclaration(
- FunctionExpression node,
- MethodElement method,
- NodeList parameters,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_ABSTRACT_METHOD_DECL,
- element: method, parameters: parameters));
- applyParameters(parameters, arg);
- }
-
- @override
- visitClosureDeclaration(
- FunctionExpression node,
- LocalFunctionElement function,
- NodeList parameters,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CLOSURE_DECL,
- element: function, parameters: parameters, body: body));
- applyParameters(parameters, arg);
- apply(body, arg);
- }
-
- @override
- visitFactoryConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_DECL,
- element: constructor, parameters: parameters, body: body));
- applyParameters(parameters, arg);
- apply(body, arg);
- }
-
- @override
- visitFieldInitializer(
- SendSet node,
- FieldElement field,
- Node initializer,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FIELD_INITIALIZER,
- element: field, rhs: initializer));
- apply(initializer, arg);
- }
-
- @override
- visitGenerativeConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- NodeList initializers,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
- element: constructor, parameters: parameters, body: body));
- applyParameters(parameters, arg);
- applyInitializers(node, arg);
- apply(body, arg);
- }
-
- @override
- visitInstanceMethodDeclaration(
- FunctionExpression node,
- MethodElement method,
- NodeList parameters,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_INSTANCE_METHOD_DECL,
- element: method, parameters: parameters, body: body));
- applyParameters(parameters, arg);
- apply(body, arg);
- }
-
- @override
- visitLocalFunctionDeclaration(
- FunctionExpression node,
- LocalFunctionElement function,
- NodeList parameters,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_DECL,
- element: function, parameters: parameters, body: body));
- applyParameters(parameters, arg);
- apply(body, arg);
- }
-
- @override
- visitRedirectingFactoryConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- InterfaceType redirectionType,
- ConstructorElement redirectionTarget,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
- element: constructor,
- parameters: parameters,
- target: redirectionTarget,
- type: redirectionType));
- applyParameters(parameters, arg);
- }
-
- @override
- visitRedirectingGenerativeConstructorDeclaration(
- FunctionExpression node,
- ConstructorElement constructor,
- NodeList parameters,
- NodeList initializers,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,
- element: constructor,
- parameters: parameters,
- initializers: initializers));
- applyParameters(parameters, arg);
- applyInitializers(node, arg);
- }
-
- @override
- visitStaticFunctionDeclaration(
- FunctionExpression node,
- MethodElement function,
- NodeList parameters,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_DECL,
- element: function, parameters: parameters, body: body));
- applyParameters(parameters, arg);
- apply(body, arg);
- }
-
- @override
- visitSuperConstructorInvoke(
- Send node,
- ConstructorElement superConstructor,
- InterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_CONSTRUCTOR_INVOKE,
- element: superConstructor, type: type,
- arguments: arguments, selector: callStructure));
- super.visitSuperConstructorInvoke(
- node, superConstructor, type, arguments, callStructure, arg);
- }
-
- @override
- visitImplicitSuperConstructorInvoke(
- FunctionExpression node,
- ConstructorElement superConstructor,
- InterfaceType type,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
- element: superConstructor, type: type));
- super.visitImplicitSuperConstructorInvoke(
- node, superConstructor, type, arg);
- }
-
- @override
- visitThisConstructorInvoke(
- Send node,
- ConstructorElement thisConstructor,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_THIS_CONSTRUCTOR_INVOKE,
- element: thisConstructor,
- arguments: arguments, selector: callStructure));
- super.visitThisConstructorInvoke(
- node, thisConstructor, arguments, callStructure, arg);
- }
-
- @override
- visitTopLevelFunctionDeclaration(
- FunctionExpression node,
- MethodElement function,
- NodeList parameters,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
- element: function, parameters: parameters, body: body));
- applyParameters(parameters, arg);
- apply(body, arg);
- }
-
- @override
- errorUnresolvedFieldInitializer(
- SendSet node,
- Element element,
- Node initializer,
- arg) {
- // TODO: implement errorUnresolvedFieldInitializer
- }
-
- @override
- visitOptionalParameterDeclaration(
- VariableDefinitions node,
- Node definition,
- ParameterElement parameter,
- ConstantExpression defaultValue,
- int index,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
- element: parameter,
- constant: defaultValue != null ? defaultValue.getText() : null,
- index: index));
- }
-
- @override
- visitParameterDeclaration(
- VariableDefinitions node,
- Node definition,
- ParameterElement parameter,
- int index,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
- element: parameter, index: index));
- }
-
- @override
- visitInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement initializingFormal,
- int index,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,
- element: initializingFormal, index: index));
- }
-
- @override
- visitLocalVariableDeclaration(
- VariableDefinitions node,
- Node definition,
- LocalVariableElement variable,
- Node initializer,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
- element: variable, rhs: initializer));
- if (initializer != null) {
- apply(initializer, arg);
- }
- }
-
- @override
- visitLocalConstantDeclaration(
- VariableDefinitions node,
- Node definition,
- LocalVariableElement variable,
- ConstantExpression constant,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
- element: variable, constant: constant.getText()));
- }
-
- @override
- visitNamedInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement initializingFormal,
- ConstantExpression defaultValue,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_NAMED_INITIALIZING_FORMAL_DECL,
- element: initializingFormal,
- constant: defaultValue != null ? defaultValue.getText() : null));
- }
-
- @override
- visitNamedParameterDeclaration(
- VariableDefinitions node,
- Node definition,
- ParameterElement parameter,
- ConstantExpression defaultValue,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
- element: parameter,
- constant: defaultValue != null ? defaultValue.getText() : null));
- }
-
- @override
- visitOptionalInitializingFormalDeclaration(
- VariableDefinitions node,
- Node definition,
- InitializingFormalElement initializingFormal,
- ConstantExpression defaultValue,
- int index,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,
- element: initializingFormal,
- constant: defaultValue != null ? defaultValue.getText() : null,
- index: index));
- }
-
- @override
- visitInstanceFieldDeclaration(
- VariableDefinitions node,
- Node definition,
- FieldElement field,
- Node initializer,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
- element: field, rhs: initializer));
- if (initializer != null) {
- apply(initializer, arg);
- }
- }
-
- @override
- visitStaticConstantDeclaration(
- VariableDefinitions node,
- Node definition,
- FieldElement field,
- ConstantExpression constant,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_CONSTANT_DECL,
- element: field, constant: constant.getText()));
- }
-
- @override
- visitStaticFieldDeclaration(
- VariableDefinitions node,
- Node definition,
- FieldElement field,
- Node initializer,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
- element: field, rhs: initializer));
- if (initializer != null) {
- apply(initializer, arg);
- }
- }
-
- @override
- visitTopLevelConstantDeclaration(
- VariableDefinitions node,
- Node definition,
- FieldElement field,
- ConstantExpression constant,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_CONSTANT_DECL,
- element: field, constant: constant.getText()));
- }
-
- @override
- visitTopLevelFieldDeclaration(
- VariableDefinitions node,
- Node definition,
- FieldElement field,
- Node initializer,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
- element: field, rhs: initializer));
- if (initializer != null) {
- apply(initializer, arg);
- }
- }
-
- @override
- visitAbstractGetterDeclaration(
- FunctionExpression node,
- MethodElement getter,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_ABSTRACT_GETTER_DECL,
- element: getter));
- }
-
- @override
- visitAbstractSetterDeclaration(
- FunctionExpression node,
- MethodElement setter,
- NodeList parameters,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_ABSTRACT_SETTER_DECL,
- element: setter, parameters: parameters));
- applyParameters(parameters, arg);
- }
-
- @override
- visitInstanceGetterDeclaration(
- FunctionExpression node,
- MethodElement getter,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_INSTANCE_GETTER_DECL,
- element: getter, body: body));
- apply(body, arg);
- }
-
- @override
- visitInstanceSetterDeclaration(
- FunctionExpression node,
- MethodElement setter,
- NodeList parameters,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_INSTANCE_SETTER_DECL,
- element: setter, parameters: parameters, body: body));
- applyParameters(parameters, arg);
- apply(body, arg);
- }
-
- @override
- visitTopLevelGetterDeclaration(
- FunctionExpression node,
- MethodElement getter,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_DECL,
- element: getter, body: body));
- apply(body, arg);
- }
-
- @override
- visitTopLevelSetterDeclaration(
- FunctionExpression node,
- MethodElement setter,
- NodeList parameters,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_DECL,
- element: setter, parameters: parameters, body: body));
- applyParameters(parameters, arg);
- apply(body, arg);
- }
-
- @override
- visitStaticGetterDeclaration(
- FunctionExpression node,
- MethodElement getter,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_DECL,
- element: getter, body: body));
- apply(body, arg);
- }
-
- @override
- visitStaticSetterDeclaration(
- FunctionExpression node,
- MethodElement setter,
- NodeList parameters,
- Node body,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_DECL,
- element: setter, parameters: parameters, body: body));
- applyParameters(parameters, arg);
- apply(body, arg);
- }
-}
+// 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_test;
+
+class SemanticDeclarationTestVisitor extends SemanticTestVisitor {
+
+ SemanticDeclarationTestVisitor(TreeElements elements) : super(elements);
+
+ @override
+ errorUnresolvedSuperConstructorInvoke(
+ Send node,
+ Element element,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ // TODO: implement errorUnresolvedSuperConstructorInvoke
+ }
+
+ @override
+ errorUnresolvedThisConstructorInvoke(
+ Send node,
+ Element element,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ // TODO: implement errorUnresolvedThisConstructorInvoke
+ }
+
+ @override
+ visitAbstractMethodDeclaration(
+ FunctionExpression node,
+ MethodElement method,
+ NodeList parameters,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_ABSTRACT_METHOD_DECL,
+ element: method, parameters: parameters));
+ applyParameters(parameters, arg);
+ }
+
+ @override
+ visitClosureDeclaration(
+ FunctionExpression node,
+ LocalFunctionElement function,
+ NodeList parameters,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CLOSURE_DECL,
+ element: function, parameters: parameters, body: body));
+ applyParameters(parameters, arg);
+ apply(body, arg);
+ }
+
+ @override
+ visitFactoryConstructorDeclaration(
+ FunctionExpression node,
+ ConstructorElement constructor,
+ NodeList parameters,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_DECL,
+ element: constructor, parameters: parameters, body: body));
+ applyParameters(parameters, arg);
+ apply(body, arg);
+ }
+
+ @override
+ visitFieldInitializer(
+ SendSet node,
+ FieldElement field,
+ Node initializer,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FIELD_INITIALIZER,
+ element: field, rhs: initializer));
+ apply(initializer, arg);
+ }
+
+ @override
+ visitGenerativeConstructorDeclaration(
+ FunctionExpression node,
+ ConstructorElement constructor,
+ NodeList parameters,
+ NodeList initializers,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+ element: constructor, parameters: parameters, body: body));
+ applyParameters(parameters, arg);
+ applyInitializers(node, arg);
+ apply(body, arg);
+ }
+
+ @override
+ visitInstanceMethodDeclaration(
+ FunctionExpression node,
+ MethodElement method,
+ NodeList parameters,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_INSTANCE_METHOD_DECL,
+ element: method, parameters: parameters, body: body));
+ applyParameters(parameters, arg);
+ apply(body, arg);
+ }
+
+ @override
+ visitLocalFunctionDeclaration(
+ FunctionExpression node,
+ LocalFunctionElement function,
+ NodeList parameters,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_DECL,
+ element: function, parameters: parameters, body: body));
+ applyParameters(parameters, arg);
+ apply(body, arg);
+ }
+
+ @override
+ visitRedirectingFactoryConstructorDeclaration(
+ FunctionExpression node,
+ ConstructorElement constructor,
+ NodeList parameters,
+ InterfaceType redirectionType,
+ ConstructorElement redirectionTarget,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+ element: constructor,
+ parameters: parameters,
+ target: redirectionTarget,
+ type: redirectionType));
+ applyParameters(parameters, arg);
+ }
+
+ @override
+ visitRedirectingGenerativeConstructorDeclaration(
+ FunctionExpression node,
+ ConstructorElement constructor,
+ NodeList parameters,
+ NodeList initializers,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,
+ element: constructor,
+ parameters: parameters,
+ initializers: initializers));
+ applyParameters(parameters, arg);
+ applyInitializers(node, arg);
+ }
+
+ @override
+ visitStaticFunctionDeclaration(
+ FunctionExpression node,
+ MethodElement function,
+ NodeList parameters,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_DECL,
+ element: function, parameters: parameters, body: body));
+ applyParameters(parameters, arg);
+ apply(body, arg);
+ }
+
+ @override
+ visitSuperConstructorInvoke(
+ Send node,
+ ConstructorElement superConstructor,
+ InterfaceType type,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_CONSTRUCTOR_INVOKE,
+ element: superConstructor, type: type,
+ arguments: arguments, selector: callStructure));
+ super.visitSuperConstructorInvoke(
+ node, superConstructor, type, arguments, callStructure, arg);
+ }
+
+ @override
+ visitImplicitSuperConstructorInvoke(
+ FunctionExpression node,
+ ConstructorElement superConstructor,
+ InterfaceType type,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+ element: superConstructor, type: type));
+ super.visitImplicitSuperConstructorInvoke(
+ node, superConstructor, type, arg);
+ }
+
+ @override
+ visitThisConstructorInvoke(
+ Send node,
+ ConstructorElement thisConstructor,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_THIS_CONSTRUCTOR_INVOKE,
+ element: thisConstructor,
+ arguments: arguments, selector: callStructure));
+ super.visitThisConstructorInvoke(
+ node, thisConstructor, arguments, callStructure, arg);
+ }
+
+ @override
+ visitTopLevelFunctionDeclaration(
+ FunctionExpression node,
+ MethodElement function,
+ NodeList parameters,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+ element: function, parameters: parameters, body: body));
+ applyParameters(parameters, arg);
+ apply(body, arg);
+ }
+
+ @override
+ errorUnresolvedFieldInitializer(
+ SendSet node,
+ Element element,
+ Node initializer,
+ arg) {
+ // TODO: implement errorUnresolvedFieldInitializer
+ }
+
+ @override
+ visitOptionalParameterDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ ParameterElement parameter,
+ ConstantExpression defaultValue,
+ int index,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
+ element: parameter,
+ constant: defaultValue != null ? defaultValue.getText() : null,
+ index: index));
+ }
+
+ @override
+ visitParameterDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ ParameterElement parameter,
+ int index,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+ element: parameter, index: index));
+ }
+
+ @override
+ visitInitializingFormalDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ InitializingFormalElement initializingFormal,
+ int index,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,
+ element: initializingFormal, index: index));
+ }
+
+ @override
+ visitLocalVariableDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ LocalVariableElement variable,
+ Node initializer,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+ element: variable, rhs: initializer));
+ if (initializer != null) {
+ apply(initializer, arg);
+ }
+ }
+
+ @override
+ visitLocalConstantDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ LocalVariableElement variable,
+ ConstantExpression constant,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
+ element: variable, constant: constant.getText()));
+ }
+
+ @override
+ visitNamedInitializingFormalDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ InitializingFormalElement initializingFormal,
+ ConstantExpression defaultValue,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_NAMED_INITIALIZING_FORMAL_DECL,
+ element: initializingFormal,
+ constant: defaultValue != null ? defaultValue.getText() : null));
+ }
+
+ @override
+ visitNamedParameterDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ ParameterElement parameter,
+ ConstantExpression defaultValue,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
+ element: parameter,
+ constant: defaultValue != null ? defaultValue.getText() : null));
+ }
+
+ @override
+ visitOptionalInitializingFormalDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ InitializingFormalElement initializingFormal,
+ ConstantExpression defaultValue,
+ int index,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,
+ element: initializingFormal,
+ constant: defaultValue != null ? defaultValue.getText() : null,
+ index: index));
+ }
+
+ @override
+ visitInstanceFieldDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ FieldElement field,
+ Node initializer,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
+ element: field, rhs: initializer));
+ if (initializer != null) {
+ apply(initializer, arg);
+ }
+ }
+
+ @override
+ visitStaticConstantDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ FieldElement field,
+ ConstantExpression constant,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_CONSTANT_DECL,
+ element: field, constant: constant.getText()));
+ }
+
+ @override
+ visitStaticFieldDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ FieldElement field,
+ Node initializer,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+ element: field, rhs: initializer));
+ if (initializer != null) {
+ apply(initializer, arg);
+ }
+ }
+
+ @override
+ visitTopLevelConstantDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ FieldElement field,
+ ConstantExpression constant,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_CONSTANT_DECL,
+ element: field, constant: constant.getText()));
+ }
+
+ @override
+ visitTopLevelFieldDeclaration(
+ VariableDefinitions node,
+ Node definition,
+ FieldElement field,
+ Node initializer,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
+ element: field, rhs: initializer));
+ if (initializer != null) {
+ apply(initializer, arg);
+ }
+ }
+
+ @override
+ visitAbstractGetterDeclaration(
+ FunctionExpression node,
+ MethodElement getter,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_ABSTRACT_GETTER_DECL,
+ element: getter));
+ }
+
+ @override
+ visitAbstractSetterDeclaration(
+ FunctionExpression node,
+ MethodElement setter,
+ NodeList parameters,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_ABSTRACT_SETTER_DECL,
+ element: setter, parameters: parameters));
+ applyParameters(parameters, arg);
+ }
+
+ @override
+ visitInstanceGetterDeclaration(
+ FunctionExpression node,
+ MethodElement getter,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_INSTANCE_GETTER_DECL,
+ element: getter, body: body));
+ apply(body, arg);
+ }
+
+ @override
+ visitInstanceSetterDeclaration(
+ FunctionExpression node,
+ MethodElement setter,
+ NodeList parameters,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_INSTANCE_SETTER_DECL,
+ element: setter, parameters: parameters, body: body));
+ applyParameters(parameters, arg);
+ apply(body, arg);
+ }
+
+ @override
+ visitTopLevelGetterDeclaration(
+ FunctionExpression node,
+ MethodElement getter,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_DECL,
+ element: getter, body: body));
+ apply(body, arg);
+ }
+
+ @override
+ visitTopLevelSetterDeclaration(
+ FunctionExpression node,
+ MethodElement setter,
+ NodeList parameters,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_DECL,
+ element: setter, parameters: parameters, body: body));
+ applyParameters(parameters, arg);
+ apply(body, arg);
+ }
+
+ @override
+ visitStaticGetterDeclaration(
+ FunctionExpression node,
+ MethodElement getter,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_DECL,
+ element: getter, body: body));
+ apply(body, arg);
+ }
+
+ @override
+ visitStaticSetterDeclaration(
+ FunctionExpression node,
+ MethodElement setter,
+ NodeList parameters,
+ Node body,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_DECL,
+ element: setter, parameters: parameters, body: body));
+ applyParameters(parameters, arg);
+ apply(body, arg);
+ }
+}
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
index ebad789..514aa2a 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
@@ -1,3567 +1,3567 @@
-// 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_test;
-
-const Map<String, List<Test>> SEND_TESTS = const {
- 'Parameters': const [
- // Parameters
- const Test('m(o) => o;',
- const Visit(VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#o)')),
- const Test('m(o) { o = 42; }',
- const Visit(VisitKind.VISIT_PARAMETER_SET,
- element: 'parameter(m#o)',
- rhs:'42')),
- const Test('m(o) { o(null, 42); }',
- const Visit(VisitKind.VISIT_PARAMETER_INVOKE,
- element: 'parameter(m#o)',
- arguments: '(null,42)',
- selector: 'CallStructure(arity=2)')),
- // TODO(johnniwinther): Expect [VISIT_FINAL_PARAMETER_SET] instead.
- const Test('m(final o) { o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs:'42')),
- ],
- 'Local variables': const [
- // Local variables
- const Test('m() { var o; return o; }',
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_GET,
- element: 'variable(m#o)')),
- const Test('m() { var o; o = 42; }',
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET,
- element: 'variable(m#o)',
- rhs:'42')),
- const Test('m() { var o; o(null, 42); }',
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_INVOKE,
- element: 'variable(m#o)',
- arguments: '(null,42)',
- selector: 'CallStructure(arity=2)')),
- // TODO(johnniwinther): Expect [VISIT_FINAL_LOCAL_VARIABLE_SET] instead.
- const Test('m() { final o = 0; o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs:'42')),
- // TODO(johnniwinther): Expect [VISIT_FINAL_LOCAL_VARIABLE_SET] instead.
- const Test('m() { const o = 0; o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs:'42')),
- ],
- 'Local functions': const [
- // Local functions
- const Test('m() { o(a, b) {}; return o; }',
- const Visit(VisitKind.VISIT_LOCAL_FUNCTION_GET,
- element: 'function(m#o)')),
- const Test('m() { o(a, b) {}; o(null, 42); }',
- const Visit(VisitKind.VISIT_LOCAL_FUNCTION_INVOKE,
- element: 'function(m#o)',
- arguments: '(null,42)',
- selector: 'CallStructure(arity=2)')),
- const Test('m() { o(a) {}; o(null, 42); }',
- const Visit(VisitKind.VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,
- element: 'function(m#o)',
- arguments: '(null,42)',
- selector: 'CallStructure(arity=2)')),
- // TODO(johnniwinther): Expect [VISIT_LOCAL_FUNCTION_SET] instead.
- const Test('m() { o(a, b) {}; o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- ],
- 'Static fields': const [
- // Static fields
- const Test(
- '''
- class C { static var o; }
- m() => C.o;
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
- element: 'field(C#o)')),
- const Test.clazz(
- '''
- class C {
- static var o;
- m() => o;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
- element: 'field(C#o)')),
- const Test.clazz(
- '''
- class C {
- static var o;
- m() => C.o;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
- element: 'field(C#o)')),
- const Test.prefix(
- '''
- class C {
- static var o;
- }
- ''',
- 'm() => p.C.o;',
- const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
- element: 'field(C#o)')),
- const Test(
- '''
- class C {
- var o;
- }
- m() => C.o;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_GET,
- name: 'o')),
- const Test(
- '''
- class C {
- C.o();
- }
- m() => C.o;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_GET,
- name: 'o')),
- const Test(
- '''
- class C {}
- m() => C.this;
- ''',
- null),
- const Test(
- '''
- class C { static var o; }
- m() { C.o = 42; }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
- element: 'field(C#o)',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static var o;
- m() { o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
- element: 'field(C#o)',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static var o;
- m() { C.o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
- element: 'field(C#o)',
- rhs: '42')),
- const Test.prefix(
- '''
- class C {
- static var o;
- }
- ''',
- 'm() { p.C.o = 42; }',
- const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
- element: 'field(C#o)',
- rhs: '42')),
- const Test(
- '''
- class C { static var o; }
- m() { C.o(null, 42); }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
- element: 'field(C#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class C {
- static var o;
- m() { o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
- element: 'field(C#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class C {
- static var o;
- m() { C.o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
- element: 'field(C#o)',
- arguments: '(null,42)')),
- const Test.prefix(
- '''
- class C {
- static var o;
- }
- ''',
- 'm() { p.C.o(null, 42); }',
- const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
- element: 'field(C#o)',
- arguments: '(null,42)')),
- const Test(
- '''
- class C {}
- m() => C.this(null, 42);
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
- name: 'this', arguments: '(null,42)')),
- // TODO(johnniwinther): Expect [VISIT_FINAL_STATIC_FIELD_SET] instead.
- const Test(
- '''
- class C { static final o = 0; }
- m() { C.o = 42; }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static final o = 0;
- m() { o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static final o = 0;
- m() { C.o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.prefix(
- '''
- class C {
- static final o = 0;
- }
- ''',
- 'm() { p.C.o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test(
- '''
- class C { static const o = 0; }
- m() { C.o = 42; }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static const o = 0;
- m() { o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static const o = 0;
- m() { C.o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.prefix(
- '''
- class C {
- static const o = 0;
- }
- ''',
- 'm() { p.C.o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- ],
- 'Static properties': const [
- // Static properties
- const Test(
- '''
- class C {
- static get o => null;
- }
- m() => C.o;
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
- element: 'getter(C#o)')),
- const Test.clazz(
- '''
- class C {
- static get o => null;
- m() => o;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
- element: 'getter(C#o)')),
- const Test.clazz(
- '''
- class C {
- static get o => null;
- m() => C.o;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
- element: 'getter(C#o)')),
- const Test.prefix(
- '''
- class C {
- static get o => null;
- }
- ''',
- 'm() => p.C.o;',
- const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
- element: 'getter(C#o)')),
- // TODO(johnniwinther): Expected [VISIT_STATIC_GETTER_SET] instead.
- const Test(
- '''
- class C { static get o => 42; }
- m() { C.o = 42; }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static get o => 42;
- m() { o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static get o => 42;
- m() { C.o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.prefix(
- '''
- class C {
- static get o => 42;
- }
- ''',
- 'm() { p.C.o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test(
- '''
- class C {
- static set o(_) {}
- }
- m() => C.o;
- ''',
- const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
- element: 'setter(C#o)')),
- const Test.clazz(
- '''
- class C {
- static set o(_) {}
- m() => o;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
- element: 'setter(C#o)')),
-
- const Test.clazz(
- '''
- class C {
- static set o(_) {}
- m() => C.o;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
- element: 'setter(C#o)')),
- const Test.prefix(
- '''
- class C {
- static set o(_) {}
- }
- ''',
- 'm() => p.C.o;',
- const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
- element: 'setter(C#o)')),
- const Test(
- '''
- class C { static set o(_) {} }
- m() { C.o = 42; }
- ''',
- const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
- element: 'setter(C#o)',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static set o(_) {}
- m() { o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
- element: 'setter(C#o)',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static set o(_) {}
- m() { C.o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
- element: 'setter(C#o)',
- rhs: '42')),
- const Test.prefix(
- '''
- class C {
- static set o(_) {}
- }
- ''',
- 'm() { p.C.o = 42; }',
- const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
- element: 'setter(C#o)',
- rhs: '42')),
- const Test(
- '''
- class C { static get o => null; }
- m() => C.o(null, 42);
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
- element: 'getter(C#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class C {
- static get o => null;
- m() { o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
- element: 'getter(C#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class C {
- static get o => null;
- m() { C.o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
- element: 'getter(C#o)',
- arguments: '(null,42)')),
- const Test.prefix(
- '''
- class C {
- static get o => null;
- }
- ''',
- 'm() { p.C.o(null, 42); }',
- const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
- element: 'getter(C#o)',
- arguments: '(null,42)')),
- const Test(
- '''
- class C { static set o(_) {} }
- m() => C.o(null, 42);
- ''',
- const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
- element: 'setter(C#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class C {
- static set o(_) {}
- m() { o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
- element: 'setter(C#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class C {
- static set o(_) {}
- m() { C.o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
- element: 'setter(C#o)',
- arguments: '(null,42)')),
- const Test.prefix(
- '''
- class C {
- static set o(_) {}
- }
- ''',
- 'm() { p.C.o(null, 42); }',
- const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
- element: 'setter(C#o)',
- arguments: '(null,42)')),
- ],
- 'Static functions': const [
- // Static functions
- const Test(
- '''
- class C { static o(a, b) {} }
- m() => C.o;
- ''',
- const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
- element: 'function(C#o)')),
- const Test.clazz(
- '''
- class C {
- static o(a, b) {}
- m() => o;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
- element: 'function(C#o)')),
- const Test.clazz(
- '''
- class C {
- static o(a, b) {}
- m() => C.o;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
- element: 'function(C#o)')),
- const Test.prefix(
- '''
- class C { static o(a, b) {} }
- ''',
- '''
- m() => p.C.o;
- ''',
- const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
- element: 'function(C#o)')),
- // TODO(johnniwinther): Expect [VISIT_STATIC_FUNCTION_SET] instead.
- const Test(
- '''
- class C { static o(a, b) {} }
- m() { C.o = 42; }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static o(a, b) {}
- m() { o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static o(a, b) {}
- m() { C.o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.prefix(
- '''
- class C { static o(a, b) {} }
- ''',
- '''
- m() { p.C.o = 42; }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test(
- '''
- class C { static o(a, b) {} }
- m() => C.o(null, 42);
- ''',
- const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
- element: 'function(C#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class C {
- static o(a, b) {}
- m() { o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
- element: 'function(C#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class C {
- static o(a, b) {}
- m() { C.o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
- element: 'function(C#o)',
- arguments: '(null,42)')),
- const Test.prefix(
- '''
- class C {
- static o(a, b) {}
- }
- ''',
- 'm() { p.C.o(null, 42); }',
- const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
- element: 'function(C#o)',
- arguments: '(null,42)')),
- const Test(
- '''
- class C { static o(a, b) {} }
- m() => C.o(null);
- ''',
- const Visit(VisitKind.VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,
- element: 'function(C#o)',
- arguments: '(null)')),
- ],
- 'Top level fields': const [
- // Top level fields
- const Test(
- '''
- var o;
- m() => o;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET,
- element: 'field(o)')),
- const Test.prefix(
- '''
- var o;
- ''',
- 'm() => p.o;',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET,
- element: 'field(o)')),
- const Test(
- '''
- var o;
- m() { o = 42; }
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
- element: 'field(o)',
- rhs: '42')),
- const Test.prefix(
- '''
- var o;
- ''',
- 'm() { p.o = 42; }',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
- element: 'field(o)',
- rhs: '42')),
- // TODO(johnniwinther): Expect [VISIT_FINAL_TOP_LEVEL_FIELD_SET] instead.
- const Test(
- '''
- final o = 0;
- m() { o = 42; }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.prefix(
- '''
- final o = 0;
- ''',
- 'm() { p.o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test(
- '''
- const o = 0;
- m() { o = 42; }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.prefix(
- '''
- const o = 0;
- ''',
- 'm() { p.o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test(
- '''
- var o;
- m() { o(null, 42); }
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
- element: 'field(o)',
- arguments: '(null,42)')),
- const Test.prefix(
- '''
- var o;
- ''',
- 'm() { p.o(null, 42); }',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
- element: 'field(o)',
- arguments: '(null,42)')),
- const Test(
- '''
- m() => o;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_GET,
- name: 'o')),
- ],
- 'Top level properties': const [
- // Top level properties
- const Test(
- '''
- get o => null;
- m() => o;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,
- element: 'getter(o)')),
- const Test.prefix(
- '''
- get o => null;
- ''',
- '''
- m() => p.o;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,
- element: 'getter(o)')),
- // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_SETTER_GET] instead.
- const Test(
- '''
- set o(_) {}
- m() => o;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_GET,
- element: 'setter(o)')),
- const Test.prefix(
- '''
- set o(_) {}
- ''',
- '''
- m() => p.o;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_GET,
- name: 'o')),
- // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_GETTER_SET] instead.
- const Test(
- '''
- get o => null;
- m() { o = 42; }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.prefix(
- '''
- get o => null;
- ''',
- 'm() { p.o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test(
- '''
- set o(_) {}
- m() { o = 42; }
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,
- element: 'setter(o)',
- rhs: '42')),
- const Test.prefix(
- '''
- set o(_) {}
- ''',
- 'm() { p.o = 42; }',
- const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,
- element: 'setter(o)',
- rhs: '42')),
- const Test(
- '''
- get o => null;
- m() => o(null, 42);
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,
- element: 'getter(o)',
- arguments: '(null,42)')),
- const Test.prefix(
- '''
- get o => null;
- ''',
- 'm() { p.o(null, 42); }',
- const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,
- element: 'getter(o)',
- arguments: '(null,42)')),
- // TODO(johnniwinther): Expected [VISIT_TOP_LEVEL_SETTER_INVOKE] instead.
- const Test(
- '''
- set o(_) {}
- m() => o(null, 42);
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_INVOKE,
- element: 'setter(o)',
- arguments: '(null,42)')),
- const Test.prefix(
- '''
- set o(_) {}
- ''',
- 'm() { p.o(null, 42); }',
- const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
- name: 'o',
- arguments: '(null,42)')),
- ],
- 'Top level functions': const [
- // Top level functions
- const Test(
- '''
- o(a, b) {}
- m() => o;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_GET,
- element: 'function(o)')),
- const Test(
- '''
- o(a, b) {}
- m() => o(null, 42);
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,
- element: 'function(o)',
- arguments: '(null,42)')),
- const Test(
- '''
- o(a, b) {}
- m() => o(null);
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,
- element: 'function(o)',
- arguments: '(null)')),
- const Test.prefix(
- '''
- o(a, b) {}
- ''',
- 'm() { p.o(null, 42); }',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,
- element: 'function(o)',
- arguments: '(null,42)')),
- const Test(
- '''
- m() => o(null, 42);
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
- name: 'o',
- arguments: '(null,42)')),
- // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_FUNCTION_SET] instead.
- const Test(
- '''
- o(a, b) {}
- m() { o = 42; }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.prefix(
- '''
- o(a, b) {}
- ''',
- 'm() { p.o = 42; }',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- ],
- 'Dynamic properties': const [
- // Dynamic properties
- const Test('m(o) => o.foo;',
- const [
- const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
- receiver: 'o',
- name: 'foo'),
- const Visit(VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#o)'),
- ]),
- const Test('m(o) { o.foo = 42; }',
- const [
- const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,
- receiver: 'o',
- name: 'foo',
- rhs: '42'),
- const Visit(VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#o)'),
- ]),
- const Test('m(o) { o.foo(null, 42); }',
- const [
- const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,
- receiver: 'o',
- name: 'foo',
- arguments: '(null,42)'),
- const Visit(VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#o)'),
- ]),
- ],
- 'This access': const [
- // This access
- const Test.clazz(
- '''
- class C {
- m() => this;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_GET)),
- const Test.clazz(
- '''
- class C {
- call(a, b) {}
- m() { this(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_INVOKE,
- arguments: '(null,42)')),
- ],
- 'This properties': const [
- // This properties
- const Test.clazz(
- '''
- class C {
- var foo;
- m() => foo;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
- name: 'foo')),
- const Test.clazz(
- '''
- class C {
- var foo;
- m() => this.foo;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
- name: 'foo')),
- const Test.clazz(
- '''
- class C {
- get foo => null;
- m() => foo;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
- name: 'foo')),
- const Test.clazz(
- '''
- class C {
- get foo => null;
- m() => this.foo;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
- name: 'foo')),
- const Test.clazz(
- '''
- class C {
- var foo;
- m() { foo = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
- name: 'foo',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- var foo;
- m() { this.foo = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
- name: 'foo',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- set foo(_) {}
- m() { foo = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
- name: 'foo',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- set foo(_) {}
- m() { this.foo = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
- name: 'foo',
- rhs: '42')),
- const Test.clazz(
- '''
- class C {
- var foo;
- m() { foo(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,
- name: 'foo',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class C {
- var foo;
- m() { this.foo(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,
- name: 'foo',
- arguments: '(null,42)')),
- ],
- 'Super fields': const [
- // Super fields
- const Test.clazz(
- '''
- class B {
- var o;
- }
- class C extends B {
- m() => super.o;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_GET,
- element: 'field(B#o)')),
- const Test.clazz(
- '''
- class B {
- var o;
- }
- class C extends B {
- m() { super.o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_SET,
- element: 'field(B#o)',
- rhs: '42')),
- // TODO(johnniwinther): Expect [VISIT_FINAL_SUPER_FIELD_SET] instead.
- const Test.clazz(
- '''
- class B {
- final o = 0;
- }
- class C extends B {
- m() { super.o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.clazz(
- '''
- class B {
- var o;
- }
- class C extends B {
- m() { super.o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_INVOKE,
- element: 'field(B#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => super.o;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GET)),
- ],
- 'Super properties': const [
- // Super properties
- const Test.clazz(
- '''
- class B {
- get o => null;
- }
- class C extends B {
- m() => super.o;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_GET,
- element: 'getter(B#o)')),
- const Test.clazz(
- '''
- class B {
- set o(_) {}
- }
- class C extends B {
- m() => super.o;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_SETTER_GET,
- element: 'setter(B#o)')),
- // TODO(johnniwinther): Expect [VISIT_SUPER_GETTER_SET] instead.
- const Test.clazz(
- '''
- class B {
- get o => 0;
- }
- class C extends B {
- m() { super.o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: 'o',
- rhs: '42')),
- const Test.clazz(
- '''
- class B {
- set o(_) {}
- }
- class C extends B {
- m() { super.o = 42; }
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_SETTER_SET,
- element: 'setter(B#o)',
- rhs: '42')),
- const Test.clazz(
- '''
- class B {
- get o => null;
- }
- class C extends B {
- m() { super.o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,
- element: 'getter(B#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class B {
- set o(_) {}
- }
- class C extends B {
- m() { super.o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_SETTER_INVOKE,
- element: 'setter(B#o)',
- arguments: '(null,42)')),
- ],
- 'Super methods': const [
- // Super methods
- const Test.clazz(
- '''
- class B {
- o(a, b) {}
- }
- class C extends B {
- m() => super.o;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_METHOD_GET,
- element: 'function(B#o)')),
- const Test.clazz(
- '''
- class B {
- o(a, b) {}
- }
- class C extends B {
- m() { super.o(null, 42); }
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_METHOD_INVOKE,
- element: 'function(B#o)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class B {
- o(a, b) {}
- }
- class C extends B {
- m() { super.o(null); }
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,
- element: 'function(B#o)',
- arguments: '(null)')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => super.o(null, 42);
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INVOKE,
- arguments: '(null,42)')),
- ],
- 'Expression invoke': const [
- // Expression invoke
- const Test('m() => (a, b){}(null, 42);',
- const Visit(VisitKind.VISIT_EXPRESSION_INVOKE,
- receiver: '(a,b){}',
- arguments: '(null,42)')),
- ],
- 'Class type literals': const [
- // Class type literals
- const Test(
- '''
- class C {}
- m() => C;
- ''',
- const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
- constant: 'C')),
- const Test(
- '''
- class C {}
- m() => C(null, 42);
- ''',
- const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
- constant: 'C',
- arguments: '(null,42)')),
- const Test(
- '''
- class C {}
- m() => C += 42;
- ''',
- const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,
- constant: 'C',
- operator: '+=',
- rhs: '42')),
- const Test(
- '''
- class C {}
- m() => ++C;
- ''',
- const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,
- constant: 'C',
- operator: '++')),
- const Test(
- '''
- class C {}
- m() => C--;
- ''',
- const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,
- constant: 'C',
- operator: '--')),
- const Test(
- '''
- class C {}
- m() => (C).hashCode;
- ''',
- const [
- const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
- receiver: '(C)', name: 'hashCode'),
- const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
- constant: 'C'),
- ]),
- ],
- 'Typedef type literals': const [
- // Typedef type literals
- const Test(
- '''
- typedef F();
- m() => F;
- ''',
- const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_GET,
- constant: 'F')),
- const Test(
- '''
- typedef F();
- m() => F(null, 42);
- ''',
- const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
- constant: 'F',
- arguments: '(null,42)')),
- const Test(
- '''
- typedef F();
- m() => F += 42;
- ''',
- const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,
- constant: 'F',
- operator: '+=',
- rhs: '42')),
- const Test(
- '''
- typedef F();
- m() => ++F;
- ''',
- const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
- constant: 'F',
- operator: '++')),
- const Test(
- '''
- typedef F();
- m() => F--;
- ''',
- const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,
- constant: 'F',
- operator: '--')),
- ],
- 'Type variable type literals': const [
- // Type variable type literals
- const Test.clazz(
- '''
- class C<T> {
- m() => T;
- }
- ''',
- const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,
- element: 'type_variable(C#T)')),
- const Test.clazz(
- '''
- class C<T> {
- m() => T(null, 42);
- }
- ''',
- const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,
- element: 'type_variable(C#T)',
- arguments: '(null,42)')),
- const Test.clazz(
- '''
- class C<T> {
- m() => T += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,
- element: 'type_variable(C#T)',
- operator: '+=',
- rhs: '42')),
- const Test.clazz(
- '''
- class C<T> {
- m() => ++T;
- }
- ''',
- const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,
- element: 'type_variable(C#T)',
- operator: '++')),
- const Test.clazz(
- '''
- class C<T> {
- m() => T--;
- }
- ''',
- const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,
- element: 'type_variable(C#T)',
- operator: '--')),
-
- ],
- 'Dynamic type literals': const [
- // Dynamic type literals
- const Test(
- '''
- m() => dynamic;
- ''',
- const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,
- constant: 'dynamic')),
- // TODO(johnniwinther): Update these to expect the constant to be `dynamic`
- // instead of `Type`. Currently the compile time constant evaluator cannot
- // detect `dynamic` as a constant subexpression.
- const Test(
- '''
- m() { dynamic(null, 42); }
- ''',
- const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
- constant: 'Type',
- arguments: '(null,42)')),
- const Test(
- '''
- m() => dynamic += 42;
- ''',
- const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,
- constant: 'Type',
- operator: '+=',
- rhs: '42')),
- const Test(
- '''
- m() => ++dynamic;
- ''',
- const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
- constant: 'Type',
- operator: '++')),
- const Test(
- '''
- m() => dynamic--;
- ''',
- const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,
- constant: 'Type',
- operator: '--')),
- ],
- 'Assert': const [
- // Assert
- const Test(
- '''
- m() { assert(false); }
- ''',
- const Visit(VisitKind.VISIT_ASSERT, expression: 'false')),
- const Test(
- '''
- m() { assert(); }
- ''',
- const Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: '()')),
- const Test(
- '''
- m() { assert(42, true); }
- ''',
- const Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: '(42,true)')),
- ],
- 'Logical and': const [
- // Logical and
- const Test(
- '''
- m() => true && false;
- ''',
- const Visit(VisitKind.VISIT_LOGICAL_AND, left: 'true', right: 'false')),
- ],
- 'Logical or': const [
- // Logical or
- const Test(
- '''
- m() => true || false;
- ''',
- const Visit(VisitKind.VISIT_LOGICAL_OR, left: 'true', right: 'false')),
- ],
- 'Is test': const [
- // Is test
- const Test(
- '''
- class C {}
- m() => 0 is C;
- ''',
- const Visit(VisitKind.VISIT_IS, expression: '0', type: 'C')),
- ],
- 'Is not test': const [
- // Is not test
- const Test(
- '''
- class C {}
- m() => 0 is! C;
- ''',
- const Visit(VisitKind.VISIT_IS_NOT, expression: '0', type: 'C')),
- ],
- 'As test': const [
- // As test
- const Test(
- '''
- class C {}
- m() => 0 as C;
- ''',
- const Visit(VisitKind.VISIT_AS, expression: '0', type: 'C')),
- ],
- 'Binary operators': const [
- // Binary operators
- const Test(
- '''
- m() => 2 + 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '+', right: '3')),
- const Test(
- '''
- m() => 2 - 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '-', right: '3')),
- const Test(
- '''
- m() => 2 * 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '*', right: '3')),
- const Test(
- '''
- m() => 2 / 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '/', right: '3')),
- const Test(
- '''
- m() => 2 ~/ 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '~/', right: '3')),
- const Test(
- '''
- m() => 2 % 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '%', right: '3')),
- const Test(
- '''
- m() => 2 << 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '<<', right: '3')),
- const Test(
- '''
- m() => 2 >> 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '>>', right: '3')),
- const Test(
- '''
- m() => 2 <= 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '<=', right: '3')),
- const Test(
- '''
- m() => 2 < 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '<', right: '3')),
- const Test(
- '''
- m() => 2 >= 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '>=', right: '3')),
- const Test(
- '''
- m() => 2 > 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '>', right: '3')),
- const Test(
- '''
- m() => 2 & 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '&', right: '3')),
- const Test(
- '''
- m() => 2 | 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '|', right: '3')),
- const Test(
- '''
- m() => 2 ^ 3;
- ''',
- const Visit(VisitKind.VISIT_BINARY,
- left: '2', operator: '^', right: '3')),
- const Test.clazz(
- '''
- class B {
- operator +(_) => null;
- }
- class C extends B {
- m() => super + 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_BINARY,
- element: 'function(B#+)',
- operator: '+',
- right: '42')),
- const Test.clazz(
- '''
- class B {}
- class C extends B {
- m() => super + 42;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_BINARY,
- operator: '+',
- right: '42')),
- const Test(
- '''
- m() => 2 === 3;
- ''',
- const Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,
- left: '2', operator: '===', right: '3')),
- const Test(
- '''
- m() => 2 !== 3;
- ''',
- const Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,
- left: '2', operator: '!==', right: '3')),
- ],
- 'Index': const [
- // Index
- const Test(
- '''
- m() => 2[3];
- ''',
- const Visit(VisitKind.VISIT_INDEX,
- receiver: '2', index: '3')),
- const Test(
- '''
- m() => --2[3];
- ''',
- const Visit(VisitKind.VISIT_INDEX_PREFIX,
- receiver: '2', index: '3', operator: '--')),
- const Test(
- '''
- m() => 2[3]++;
- ''',
- const Visit(VisitKind.VISIT_INDEX_POSTFIX,
- receiver: '2', index: '3', operator: '++')),
- const Test.clazz(
- '''
- class B {
- operator [](_) => null;
- }
- class C extends B {
- m() => super[42];
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_INDEX,
- element: 'function(B#[])',
- index: '42')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => super[42];
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX,
- index: '42')),
- const Test.clazz(
- '''
- class B {
- operator [](_) => null;
- operator []=(a, b) {}
- }
- class C extends B {
- m() => ++super[42];
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_INDEX_PREFIX,
- getter: 'function(B#[])',
- setter: 'function(B#[]=)',
- index: '42',
- operator: '++')),
- const Test.clazz(
- '''
- class B {
- operator []=(a, b) {}
- }
- class C extends B {
- m() => ++super[42];
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,
- setter: 'function(B#[]=)',
- index: '42',
- operator: '++')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => ++super[42];
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,
- index: '42',
- operator: '++')),
- const Test.clazz(
- '''
- class B {
- operator [](_) => null;
- }
- class C extends B {
- m() => ++super[42];
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,
- getter: 'function(B#[])',
- index: '42',
- operator: '++')),
- const Test.clazz(
- '''
- class B {
- operator [](_) => null;
- operator []=(a, b) {}
- }
- class C extends B {
- m() => super[42]--;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_INDEX_POSTFIX,
- getter: 'function(B#[])',
- setter: 'function(B#[]=)',
- index: '42',
- operator: '--')),
- const Test.clazz(
- '''
- class B {
- operator []=(a, b) {}
- }
- class C extends B {
- m() => super[42]--;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,
- setter: 'function(B#[]=)',
- index: '42',
- operator: '--')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => super[42]--;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,
- index: '42',
- operator: '--')),
- const Test.clazz(
- '''
- class B {
- operator [](_) => null;
- }
- class C extends B {
- m() => super[42]--;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,
- getter: 'function(B#[])',
- index: '42',
- operator: '--')),
- ],
- 'Equals': const [
- // Equals
- const Test(
- '''
- m() => 2 == 3;
- ''',
- const Visit(VisitKind.VISIT_EQUALS,
- left: '2', right: '3')),
- const Test.clazz(
- '''
- class B {
- operator ==(_) => null;
- }
- class C extends B {
- m() => super == 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_EQUALS,
- element: 'function(B#==)',
- right: '42')),
- ],
- 'Not equals': const [
- // Not equals
- const Test(
- '''
- m() => 2 != 3;
- ''',
- const Visit(VisitKind.VISIT_NOT_EQUALS,
- left: '2', right: '3')),
- const Test.clazz(
- '''
- class B {
- operator ==(_) => null;
- }
- class C extends B {
- m() => super != 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,
- element: 'function(B#==)',
- right: '42')),
- ],
- 'Unary expression': const [
- // Unary expression
- const Test(
- '''
- m() => -false;
- ''',
- const Visit(VisitKind.VISIT_UNARY,
- expression: 'false', operator: '-')),
- const Test(
- '''
- m() => ~false;
- ''',
- const Visit(VisitKind.VISIT_UNARY,
- expression: 'false', operator: '~')),
- const Test.clazz(
- '''
- class B {
- operator -() => null;
- }
- class C extends B {
- m() => -super;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_UNARY,
- element: 'function(B#unary-)', operator: '-')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => -super;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_UNARY,
- operator: '-')),
- const Test.clazz(
- '''
- class B {
- operator ~() => null;
- }
- class C extends B {
- m() => ~super;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_UNARY,
- element: 'function(B#~)', operator: '~')),
- const Test(
- '''
- m() => !0;
- ''',
- const Visit(VisitKind.VISIT_NOT, expression: '0')),
- const Test(
- '''
- m() => +false;
- ''',
- // TODO(johnniwinther): Should this be an
- // ERROR_UNDEFINED_UNARY_EXPRESSION? Currently the parser just skips
- // the `+`.
- const []),
- ],
- 'Index set': const [
- // Index set
- const Test(
- '''
- m() => 0[1] = 2;
- ''',
- const Visit(VisitKind.VISIT_INDEX_SET,
- receiver: '0', index: '1', rhs: '2')),
- const Test.clazz(
- '''
- class B {
- operator []=(a, b) {}
- }
- class C extends B {
- m() => super[1] = 2;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_INDEX_SET,
- element: 'function(B#[]=)', index: '1', rhs: '2')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => super[1] = 2;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_SET,
- index: '1', rhs: '2')),
- ],
- 'Compound assignment': const [
- // Compound assignment
- const Test(
- '''
- m(a) => a.b += 42;
- ''',
- const [
- const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_COMPOUND,
- receiver: 'a', operator: '+=', rhs: '42',
- getter: 'Selector(getter, b, arity=0)',
- setter: 'Selector(setter, b, arity=1)'),
- const Visit(VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#a)')
- ]),
- const Test(
- '''
- m(a) => a += 42;
- ''',
- const Visit(VisitKind.VISIT_PARAMETER_COMPOUND,
- element: 'parameter(m#a)', operator: '+=', rhs: '42')),
- const Test(
- '''
- m(final a) => a += 42;
- ''',
- const Visit(VisitKind.VISIT_FINAL_PARAMETER_COMPOUND,
- element: 'parameter(m#a)', operator: '+=', rhs: '42')),
- const Test(
- '''
- m() {
- var a;
- a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_COMPOUND,
- element: 'variable(m#a)', operator: '+=', rhs: '42')),
- const Test(
- '''
- m() {
- final a = 0;
- a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,
- element: 'variable(m#a)', operator: '+=', rhs: '42')),
- const Test(
- '''
- m() {
- a() {}
- a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_LOCAL_FUNCTION_COMPOUND,
- element: 'function(m#a)', operator: '+=', rhs: '42')),
- const Test(
- '''
- var a;
- m() => a += 42;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_COMPOUND,
- element: 'field(a)', operator: '+=', rhs: '42')),
- const Test(
- '''
- get a => 0;
- set a(_) {}
- m() => a += 42;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,
- getter: 'getter(a)', setter: 'setter(a)',
- operator: '+=', rhs: '42')),
- const Test(
- '''
- class C {
- static var a;
- }
- m() => C.a += 42;
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
- element: 'field(C#a)', operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static var a;
- m() => C.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
- element: 'field(C#a)', operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static var a;
- m() => a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
- element: 'field(C#a)', operator: '+=', rhs: '42')),
- const Test.prefix(
- '''
- class C {
- static var a;
- }
- ''',
- '''
- m() => p.C.a += 42;
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
- element: 'field(C#a)', operator: '+=', rhs: '42')),
- const Test(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- }
- m() => C.a += 42;
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- m() => C.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- m() => a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '+=', rhs: '42')),
- const Test.prefix(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- }
- ''',
- '''
- m() => p.C.a += 42;
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '+=', rhs: '42')),
- // TODO(johnniwinther): Enable these when dart2js supports method and setter
- // with the same name.
- /*const Test(
- '''
- class C {
- static a() {}
- static set a(_) {}
- }
- m() => C.a += 42;
- ''',
- const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
- getter: 'function(C#a)', setter: 'setter(C#a)',
- operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static a() {}
- static set a(_) {}
- m() => C.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
- getter: 'function(C#a)', setter: 'setter(C#a)',
- operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class C {
- static a() {}
- static set a(_) {}
- m() => a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
- getter: 'function(C#a)', setter: 'setter(C#a)',
- operator: '+=', rhs: '42')),
- const Test.prefix(
- '''
- class C {
- static a() {}
- static set a(_) {}
- }
- ''',
- '''
- m() => p.C.a += 42;
- ''',
- const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
- getter: 'function(C#a)', setter: 'setter(C#a)',
- operator: '+=', rhs: '42')),*/
- const Test.clazz(
- '''
- class C {
- var a;
- m() => a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,
- operator: '+=', rhs: '42',
- getter: 'Selector(getter, a, arity=0)',
- setter: 'Selector(setter, a, arity=1)')),
- const Test.clazz(
- '''
- class C {
- var a = 0;
- m() => this.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,
- operator: '+=', rhs: '42',
- getter: 'Selector(getter, a, arity=0)',
- setter: 'Selector(setter, a, arity=1)')),
- const Test.clazz(
- '''
- class B {
- var a = 0;
- }
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_COMPOUND,
- element: 'field(B#a)', operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class B {
- final a = 0;
- }
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,
- element: 'field(B#a)', operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class B {
- get a => 0;
- set a (_) {}
- }
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,
- getter: 'getter(B#a)', setter: 'setter(B#a)',
- operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class A {
- get a => 0;
- }
- class B extends A {
- set a (_) {}
- }
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,
- getter: 'getter(A#a)', setter: 'setter(B#a)',
- operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class A {
- var a;
- }
- class B extends A {
- get a => 0;
- }
-
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_COMPOUND,
- getter: 'getter(B#a)', setter: 'field(A#a)',
- operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class A {
- var a;
- }
- class B extends A {
- set a(_) {}
- }
-
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_COMPOUND,
- getter: 'field(A#a)', setter: 'setter(B#a)',
- operator: '+=', rhs: '42')),
- // TODO(johnniwinther): Enable this when dart2js supports shadow setters.
- /*const Test.clazz(
- '''
- class A {
- var a;
- }
- class B extends A {
- final a = 0;
- }
-
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
- getter: 'field(B#a)', setter: 'field(A#a)',
- operator: '+=', rhs: '42')),*/
- const Test.clazz(
- '''
- class B {
- a() {}
- }
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_METHOD_COMPOUND,
- element: 'function(B#a)',
- operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND,
- operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class B {
- set a(_) {}
- }
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,
- setter: 'setter(B#a)', operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class B {
- get a => 42;
- }
- class C extends B {
- m() => super.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,
- getter: 'getter(B#a)', operator: '+=', rhs: '42')),
-
- const Test.clazz(
- '''
- class C {
- static set a(var value) { }
- m() => a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,
- setter: 'setter(C#a)', operator: '+=', rhs: '42')),
-
- const Test.clazz(
- '''
- class C {
- static get a => 42;
- m() => C.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,
- getter: 'getter(C#a)', operator: '+=', rhs: '42')),
-
- const Test.clazz(
- '''
- class C {
- static final a = 42;
- m() => C.a += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_COMPOUND,
- element: 'field(C#a)', operator: '+=', rhs: '42')),
-
- const Test(
- '''
- class C {
- static a(var value) { }
- }
- m() => C.a += 42;
- ''',
- const Visit(VisitKind.VISIT_STATIC_METHOD_COMPOUND,
- element: 'function(C#a)', operator: '+=', rhs: '42')),
-
- const Test(
- '''
- set a(var value) { }
- m() => a += 42;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,
- setter: 'setter(a)', operator: '+=', rhs: '42')),
-
- const Test(
- '''
- get a => 42;
- m() => a += 42;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,
- getter: 'getter(a)', operator: '+=', rhs: '42')),
-
- const Test(
- '''
- a(var value) { }
- m() => a += 42;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_COMPOUND,
- element: 'function(a)', operator: '+=', rhs: '42')),
-
- const Test(
- '''
- final a = 42;
- m() => a += 42;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,
- element: 'field(a)', operator: '+=', rhs: '42')),
-
- const Test(
- '''
- m() => unresolved += 42;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_COMPOUND,
- operator: '+=', rhs: '42')),
- ],
- 'Compound index assignment': const [
- // Compound index assignment
- const Test(
- '''
- m() => 0[1] += 42;
- ''',
- const Visit(VisitKind.VISIT_COMPOUND_INDEX_SET,
- receiver: '0', index: '1', operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class B {
- operator [](_) {}
- operator []=(a, b) {}
- }
- class C extends B {
- m() => super[1] += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_COMPOUND_INDEX_SET,
- getter: 'function(B#[])', setter: 'function(B#[]=)',
- index: '1', operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class B {
- operator []=(a, b) {}
- }
- class C extends B {
- m() => super[1] += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,
- setter: 'function(B#[]=)',
- index: '1', operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => super[1] += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,
- index: '1', operator: '+=', rhs: '42')),
- const Test.clazz(
- '''
- class B {
- operator [](_) {}
- }
- class C extends B {
- m() => super[1] += 42;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,
- getter: 'function(B#[])',
- index: '1', operator: '+=', rhs: '42')),
- ],
- 'Prefix expression': const [
- // Prefix expression
- const Test(
- '''
- m(a) => --a.b;
- ''',
- const [
- const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_PREFIX,
- receiver: 'a', operator: '--',
- getter: 'Selector(getter, b, arity=0)',
- setter: 'Selector(setter, b, arity=1)'),
- const Visit(VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#a)')
- ]),
- const Test(
- '''
- m(a) => ++a;
- ''',
- const Visit(VisitKind.VISIT_PARAMETER_PREFIX,
- element: 'parameter(m#a)', operator: '++')),
- const Test(
- '''
- m(final a) => ++a;
- ''',
- const Visit(VisitKind.VISIT_FINAL_PARAMETER_PREFIX,
- element: 'parameter(m#a)', operator: '++')),
- const Test(
- '''
- m() {
- var a;
- --a;
- }
- ''',
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_PREFIX,
- element: 'variable(m#a)', operator: '--')),
- const Test(
- '''
- m() {
- final a = 42;
- --a;
- }
- ''',
- const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_PREFIX,
- element: 'variable(m#a)', operator: '--')),
- const Test(
- '''
- m() {
- a() {}
- --a;
- }
- ''',
- const Visit(VisitKind.VISIT_LOCAL_FUNCTION_PREFIX,
- element: 'function(m#a)', operator: '--')),
- const Test(
- '''
- var a;
- m() => ++a;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_PREFIX,
- element: 'field(a)', operator: '++')),
- const Test(
- '''
- get a => 0;
- set a(_) {}
- m() => --a;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,
- getter: 'getter(a)', setter: 'setter(a)',
- operator: '--')),
- const Test(
- '''
- class C {
- static var a;
- }
- m() => ++C.a;
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
- element: 'field(C#a)', operator: '++')),
- const Test.clazz(
- '''
- class C {
- static var a;
- m() => ++C.a;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
- element: 'field(C#a)', operator: '++')),
- const Test.clazz(
- '''
- class C {
- static var a;
- m() => --a;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
- element: 'field(C#a)', operator: '--')),
- const Test.prefix(
- '''
- class C {
- static var a;
- }
- ''',
- '''
- m() => --p.C.a;
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
- element: 'field(C#a)', operator: '--')),
- const Test(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- }
- m() => ++C.a;
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '++')),
- const Test.clazz(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- m() => --C.a;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '--')),
- const Test.clazz(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- m() => --a;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '--')),
- const Test.prefix(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- }
- ''',
- '''
- m() => ++p.C.a;
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '++')),
- const Test.clazz(
- '''
- class C {
- var a;
- m() => --a;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,
- operator: '--',
- getter: 'Selector(getter, a, arity=0)',
- setter: 'Selector(setter, a, arity=1)')),
- const Test.clazz(
- '''
- class C {
- var a = 0;
- m() => ++this.a;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,
- operator: '++',
- getter: 'Selector(getter, a, arity=0)',
- setter: 'Selector(setter, a, arity=1)')),
- const Test.clazz(
- '''
- class B {
- var a = 0;
- }
- class C extends B {
- m() => --super.a;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_PREFIX,
- element: 'field(B#a)', operator: '--')),
- const Test.clazz(
- '''
- class B {
- final a = 0;
- }
- class C extends B {
- m() => --super.a;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_PREFIX,
- element: 'field(B#a)', operator: '--')),
- const Test.clazz(
- '''
- class B {
- get a => 0;
- set a (_) {}
- }
- class C extends B {
- m() => --super.a;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,
- getter: 'getter(B#a)', setter: 'setter(B#a)',
- operator: '--')),
- const Test.clazz(
- '''
- class A {
- get a => 0;
- }
- class B extends A {
- set a (_) {}
- }
- class C extends B {
- m() => ++super.a;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,
- getter: 'getter(A#a)', setter: 'setter(B#a)',
- operator: '++')),
- const Test.clazz(
- '''
- class A {
- var a;
- }
- class B extends A {
- get a => 0;
- }
-
- class C extends B {
- m() => --super.a;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_PREFIX,
- getter: 'getter(B#a)', setter: 'field(A#a)',
- operator: '--')),
- const Test.clazz(
- '''
- class A {
- var a;
- }
- class B extends A {
- set a(_) {}
- }
-
- class C extends B {
- m() => ++super.a;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,
- getter: 'field(A#a)', setter: 'setter(B#a)',
- operator: '++')),
- const Test.clazz(
- '''
- class B {
- a() {}
- }
- class C extends B {
- m() => ++super.a;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_METHOD_PREFIX,
- element: 'function(B#a)',
- operator: '++')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => ++super.a;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_PREFIX,
- operator: '++')),
- const Test.clazz(
- '''
- class B {
- set a(_) {}
- }
- class C extends B {
- m() => ++super.a;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,
- setter: 'setter(B#a)', operator: '++')),
- const Test.clazz(
- '''
- class B {
- get a => 42;
- }
- class C extends B {
- m() => ++super.a;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,
- getter: 'getter(B#a)', operator: '++')),
-
- const Test.clazz(
- '''
- class C {
- static set a(var value) { }
- m() => ++a;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,
- setter: 'setter(C#a)', operator: '++')),
-
- const Test.clazz(
- '''
- class C {
- static get a => 42;
- m() => ++C.a;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,
- getter: 'getter(C#a)', operator: '++')),
-
- const Test.clazz(
- '''
- class C {
- static final a = 42;
- m() => ++C.a;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_PREFIX,
- element: 'field(C#a)', operator: '++')),
-
- const Test(
- '''
- class C {
- static a(var value) { }
- }
- m() => ++C.a;
- ''',
- const Visit(VisitKind.VISIT_STATIC_METHOD_PREFIX,
- element: 'function(C#a)', operator: '++')),
-
- const Test(
- '''
- set a(var value) { }
- m() => ++a;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,
- setter: 'setter(a)', operator: '++')),
-
- const Test(
- '''
- get a => 42;
- m() => ++a;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,
- getter: 'getter(a)', operator: '++')),
-
- const Test(
- '''
- a(var value) { }
- m() => ++a;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_PREFIX,
- element: 'function(a)', operator: '++')),
-
- const Test(
- '''
- final a = 42;
- m() => ++a;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,
- element: 'field(a)', operator: '++')),
-
- const Test(
- '''
- m() => ++unresolved;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_PREFIX,
- operator: '++')),
- ],
- 'Postfix expression': const [
- // Postfix expression
- const Test(
- '''
- m(a) => a.b--;
- ''',
- const [
- const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_POSTFIX,
- receiver: 'a', operator: '--',
- getter: 'Selector(getter, b, arity=0)',
- setter: 'Selector(setter, b, arity=1)'),
- const Visit(VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#a)')
- ]),
- const Test(
- '''
- m(a) => a++;
- ''',
- const Visit(VisitKind.VISIT_PARAMETER_POSTFIX,
- element: 'parameter(m#a)', operator: '++')),
- const Test(
- '''
- m(final a) => a++;
- ''',
- const Visit(VisitKind.VISIT_FINAL_PARAMETER_POSTFIX,
- element: 'parameter(m#a)', operator: '++')),
- const Test(
- '''
- m() {
- var a;
- a--;
- }
- ''',
- const Visit(VisitKind.VISIT_LOCAL_VARIABLE_POSTFIX,
- element: 'variable(m#a)', operator: '--')),
- const Test(
- '''
- m() {
- final a = 42;
- a--;
- }
- ''',
- const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,
- element: 'variable(m#a)', operator: '--')),
- const Test(
- '''
- m() {
- a() {}
- a--;
- }
- ''',
- const Visit(VisitKind.VISIT_LOCAL_FUNCTION_POSTFIX,
- element: 'function(m#a)', operator: '--')),
- const Test(
- '''
- var a;
- m() => a++;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_POSTFIX,
- element: 'field(a)', operator: '++')),
- const Test(
- '''
- get a => 0;
- set a(_) {}
- m() => a--;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,
- getter: 'getter(a)', setter: 'setter(a)',
- operator: '--')),
- const Test(
- '''
- class C {
- static var a;
- }
- m() => C.a++;
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
- element: 'field(C#a)', operator: '++')),
- const Test.clazz(
- '''
- class C {
- static var a;
- m() => C.a++;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
- element: 'field(C#a)', operator: '++')),
- const Test.clazz(
- '''
- class C {
- static var a;
- m() => a--;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
- element: 'field(C#a)', operator: '--')),
- const Test.prefix(
- '''
- class C {
- static var a;
- }
- ''',
- '''
- m() => p.C.a--;
- ''',
- const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
- element: 'field(C#a)', operator: '--')),
- const Test(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- }
- m() => C.a++;
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '++')),
- const Test.clazz(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- m() => C.a--;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '--')),
- const Test.clazz(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- m() => a--;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '--')),
- const Test.prefix(
- '''
- class C {
- static get a => 0;
- static set a(_) {}
- }
- ''',
- '''
- m() => p.C.a++;
- ''',
- const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
- getter: 'getter(C#a)', setter: 'setter(C#a)',
- operator: '++')),
- const Test.clazz(
- '''
- class C {
- var a;
- m() => a--;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,
- operator: '--',
- getter: 'Selector(getter, a, arity=0)',
- setter: 'Selector(setter, a, arity=1)')),
- const Test.clazz(
- '''
- class C {
- var a = 0;
- m() => this.a++;
- }
- ''',
- const Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,
- operator: '++',
- getter: 'Selector(getter, a, arity=0)',
- setter: 'Selector(setter, a, arity=1)')),
- const Test.clazz(
- '''
- class B {
- var a = 0;
- }
- class C extends B {
- m() => super.a--;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_POSTFIX,
- element: 'field(B#a)', operator: '--')),
- const Test.clazz(
- '''
- class B {
- final a = 0;
- }
- class C extends B {
- m() => super.a--;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_POSTFIX,
- element: 'field(B#a)', operator: '--')),
- const Test.clazz(
- '''
- class B {
- get a => 0;
- set a (_) {}
- }
- class C extends B {
- m() => super.a--;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,
- getter: 'getter(B#a)', setter: 'setter(B#a)',
- operator: '--')),
- const Test.clazz(
- '''
- class A {
- get a => 0;
- }
- class B extends A {
- set a (_) {}
- }
- class C extends B {
- m() => super.a++;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,
- getter: 'getter(A#a)', setter: 'setter(B#a)',
- operator: '++')),
- const Test.clazz(
- '''
- class A {
- var a;
- }
- class B extends A {
- get a => 0;
- }
-
- class C extends B {
- m() => super.a--;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_POSTFIX,
- getter: 'getter(B#a)', setter: 'field(A#a)',
- operator: '--')),
- const Test.clazz(
- '''
- class A {
- var a;
- }
- class B extends A {
- set a(_) {}
- }
-
- class C extends B {
- m() => super.a++;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,
- getter: 'field(A#a)', setter: 'setter(B#a)',
- operator: '++')),
- const Test.clazz(
- '''
- class B {
- a() {}
- }
- class C extends B {
- m() => super.a++;
- }
- ''',
- const Visit(VisitKind.VISIT_SUPER_METHOD_POSTFIX,
- element: 'function(B#a)',
- operator: '++')),
- const Test.clazz(
- '''
- class B {
- }
- class C extends B {
- m() => super.a++;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_POSTFIX,
- operator: '++')),
- const Test.clazz(
- '''
- class B {
- set a(_) {}
- }
- class C extends B {
- m() => super.a++;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,
- setter: 'setter(B#a)', operator: '++')),
- const Test.clazz(
- '''
- class B {
- get a => 42;
- }
- class C extends B {
- m() => super.a++;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,
- getter: 'getter(B#a)', operator: '++')),
-
- const Test.clazz(
- '''
- class C {
- static set a(var value) { }
- m() => a++;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,
- setter: 'setter(C#a)', operator: '++')),
-
- const Test.clazz(
- '''
- class C {
- static get a => 42;
- m() => C.a++;
- }
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,
- getter: 'getter(C#a)', operator: '++')),
-
- const Test.clazz(
- '''
- class C {
- static final a = 42;
- m() => C.a++;
- }
- ''',
- const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_POSTFIX,
- element: 'field(C#a)', operator: '++')),
-
- const Test(
- '''
- class C {
- static a(var value) { }
- }
- m() => C.a++;
- ''',
- const Visit(VisitKind.VISIT_STATIC_METHOD_POSTFIX,
- element: 'function(C#a)', operator: '++')),
-
- const Test(
- '''
- set a(var value) { }
- m() => a++;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,
- setter: 'setter(a)', operator: '++')),
-
- const Test(
- '''
- get a => 42;
- m() => a++;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,
- getter: 'getter(a)', operator: '++')),
-
- const Test(
- '''
- a(var value) { }
- m() => a++;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_POSTFIX,
- element: 'function(a)', operator: '++')),
-
- const Test(
- '''
- final a = 42;
- m() => a++;
- ''',
- const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,
- element: 'field(a)', operator: '++')),
-
- const Test(
- '''
- m() => unresolved++;
- ''',
- const Visit(VisitKind.VISIT_UNRESOLVED_POSTFIX,
- operator: '++')),
- ],
- 'Constructor invocations': const [
- const Test(
- '''
- class Class {
- const Class(a, b);
- }
- m() => const Class(true, 42);
- ''',
- const Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,
- constant: 'const Class(true, 42)')),
- const Test(
- '''
- m() => const bool.fromEnvironment('foo');
- ''',
- const Visit(VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
- constant:
- 'const bool.fromEnvironment("foo")')),
- const Test(
- '''
- m() => const bool.fromEnvironment('foo', defaultValue: true);
- ''',
- const Visit(VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
- constant: 'const bool.fromEnvironment("foo", defaultValue: true)')),
- const Test(
- '''
- m() => const int.fromEnvironment('foo');
- ''',
- const Visit(VisitKind.VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
- constant: 'const int.fromEnvironment("foo")')),
- const Test(
- '''
- m() => const String.fromEnvironment('foo');
- ''',
- const Visit(VisitKind.VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
- constant:
- 'const String.fromEnvironment("foo")')),
- const Test(
- '''
- class Class {
- Class(a, b);
- }
- m() => const Class(true, 42);
- ''',
- const Visit(VisitKind.ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {}
- m() => new Class();
- ''',
- const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Class#)',
- arguments: '()',
- type: 'Class',
- selector: 'CallStructure(arity=0)')),
- const Test(
- '''
- class Class {
- Class(a, b);
- }
- m() => new Class(true, 42);
- ''',
- const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {
- Class.named(a, b);
- }
- m() => new Class.named(true, 42);
- ''',
- const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Class#named)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {}
- m() => new Class(true, 42);
- ''',
- const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
- element: 'generative_constructor(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {
- Class(a, b) : this._(a, b);
- Class._(a, b);
- }
- m() => new Class(true, 42);
- ''',
- const Visit(VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {
- Class() : this._(true, 42);
- Class._(a, b);
- }
- m() => new Class(true, 42);
- ''',
- const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
- element: 'generative_constructor(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {
- factory Class(a, b) => new Class._(a, b);
- Class._(a, b);
- }
- m() => new Class(true, 42);
- ''',
- const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,
- element: 'function(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {
- factory Class() => new Class._(true, 42);
- Class._(a, b);
- }
- m() => new Class(true, 42);
- ''',
- const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
- element: 'function(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class<T> {
- factory Class(a, b) = Class<int>.a;
- factory Class.a(a, b) = Class<Class<T>>.b;
- Class.b(a, b);
- }
- m() => new Class<double>(true, 42);
- ''',
- const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- element: 'function(Class#)',
- arguments: '(true,42)',
- type: 'Class<double>',
- target: 'generative_constructor(Class#b)',
- targetType: 'Class<Class<int>>',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class<T> {
- factory Class(a) = Class<int>.a;
- factory Class.a(a, [b]) = Class<Class<T>>.b;
- Class.b(a, [b]);
- }
- m() => new Class<double>(true, 42);
- ''',
- const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- element: 'function(Class#)',
- arguments: '(true,42)',
- type: 'Class<double>',
- target: 'generative_constructor(Class#b)',
- targetType: 'Class<Class<int>>',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {
- factory Class() = Class._;
- Class._();
- }
- m() => new Class(true, 42);
- ''',
- const Visit(
- VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- element: 'function(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class<T> {
- factory Class(a, b) = Class<int>.a;
- factory Class.a(a, b) = Class<Class<T>>.b;
- Class.b(a);
- }
- m() => new Class<double>(true, 42);
- ''',
- const Visit(
- VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- element: 'function(Class#)',
- arguments: '(true,42)',
- type: 'Class<double>',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {
- Class(a, b);
- }
- m() => new Class.unresolved(true, 42);
- ''',
- const Visit(
- VisitKind.VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,
- arguments: '(true,42)')),
- const Test(
- '''
- m() => new Unresolved(true, 42);
- ''',
- const Visit(
- VisitKind.VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
- arguments: '(true,42)')),
- const Test(
- '''
- abstract class AbstractClass {}
- m() => new AbstractClass();
- ''',
- const Visit(
- VisitKind.VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
- element: 'generative_constructor(AbstractClass#)',
- type: 'AbstractClass',
- arguments: '()',
- selector: 'CallStructure(arity=0)')),
- const Test(
- '''
- class Class {
- factory Class(a, b) = Unresolved;
- }
- m() => new Class(true, 42);
- ''',
- const Visit(
- VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- element: 'function(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {
- factory Class(a, b) = Class.named;
- }
- m() => new Class(true, 42);
- ''',
- const Visit(
- VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- element: 'function(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- class Class {
- factory Class(a, b) = Class.named;
- factory Class.named(a, b) = Class.unresolved;
- }
- m() => new Class(true, 42);
- ''',
- const Visit(
- VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- element: 'function(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- const Test(
- '''
- abstract class AbstractClass {
- AbstractClass(a, b);
- }
- class Class {
- factory Class(a, b) = AbstractClass;
- }
- m() => new Class(true, 42);
- ''',
- const Visit(
- VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- element: 'function(Class#)',
- arguments: '(true,42)',
- type: 'Class',
- selector: 'CallStructure(arity=2)')),
- ],
- 'If not null expressions': const [
- const Test(
- '''
- m(a) => a?.b;
- ''',
- const [
- const Visit(
- VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
- receiver: 'a',
- name: 'b'),
- const Visit(
- VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#a)'),
- ]),
- const Test(
- '''
- class C {
- static var b;
- }
- m(a) => C?.b;
- ''',
- const [
- const Visit(
- VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
- receiver: 'C',
- name: 'b'),
- const Visit(
- VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
- constant: 'C'),
- ]),
- const Test(
- '''
- m(a) => a?.b = 42;
- ''',
- const [
- const Visit(
- VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,
- receiver: 'a',
- name: 'b',
- rhs: '42'),
- const Visit(
- VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#a)'),
- ]),
- const Test(
- '''
- m(a) => a?.b(42, true);
- ''',
- const [
- const Visit(
- VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,
- receiver: 'a',
- arguments: '(42,true)',
- selector: 'Selector(call, b, arity=2)'),
- const Visit(
- VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#a)'),
- ]),
- const Test(
- '''
- m(a) => ++a?.b;
- ''',
- const [
- const Visit(
- VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,
- receiver: 'a',
- getter: 'Selector(getter, b, arity=0)',
- setter: 'Selector(setter, b, arity=1)',
- operator: '++'),
- const Visit(
- VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#a)'),
- ]),
- const Test(
- '''
- m(a) => a?.b--;
- ''',
- const [
- const Visit(
- VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,
- receiver: 'a',
- getter: 'Selector(getter, b, arity=0)',
- setter: 'Selector(setter, b, arity=1)',
- operator: '--'),
- const Visit(
- VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#a)'),
- ]),
- const Test(
- '''
- m(a) => a?.b *= 42;
- ''',
- const [
- const Visit(
- VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,
- receiver: 'a',
- getter: 'Selector(getter, b, arity=0)',
- setter: 'Selector(setter, b, arity=1)',
- operator: '*=',
- rhs: '42'),
- const Visit(
- VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#a)'),
- ]),
- const Test(
- '''
- m(a, b) => a ?? b;
- ''',
- const [
- const Visit(VisitKind.VISIT_IF_NULL,
- left: 'a', right: 'b'),
- const Visit(
- VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#a)'),
- const Visit(
- VisitKind.VISIT_PARAMETER_GET,
- element: 'parameter(m#b)'),
- ]),
- const Test(
- '''
- m(a) => a ??= 42;
- ''',
- const Visit(
- VisitKind.VISIT_PARAMETER_COMPOUND,
- element: 'parameter(m#a)',
- operator: '??=',
- rhs: '42')),
- ],
-};
+// 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_test;
+
+const Map<String, List<Test>> SEND_TESTS = const {
+ 'Parameters': const [
+ // Parameters
+ const Test('m(o) => o;',
+ const Visit(VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#o)')),
+ const Test('m(o) { o = 42; }',
+ const Visit(VisitKind.VISIT_PARAMETER_SET,
+ element: 'parameter(m#o)',
+ rhs:'42')),
+ const Test('m(o) { o(null, 42); }',
+ const Visit(VisitKind.VISIT_PARAMETER_INVOKE,
+ element: 'parameter(m#o)',
+ arguments: '(null,42)',
+ selector: 'CallStructure(arity=2)')),
+ // TODO(johnniwinther): Expect [VISIT_FINAL_PARAMETER_SET] instead.
+ const Test('m(final o) { o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs:'42')),
+ ],
+ 'Local variables': const [
+ // Local variables
+ const Test('m() { var o; return o; }',
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_GET,
+ element: 'variable(m#o)')),
+ const Test('m() { var o; o = 42; }',
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET,
+ element: 'variable(m#o)',
+ rhs:'42')),
+ const Test('m() { var o; o(null, 42); }',
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_INVOKE,
+ element: 'variable(m#o)',
+ arguments: '(null,42)',
+ selector: 'CallStructure(arity=2)')),
+ // TODO(johnniwinther): Expect [VISIT_FINAL_LOCAL_VARIABLE_SET] instead.
+ const Test('m() { final o = 0; o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs:'42')),
+ // TODO(johnniwinther): Expect [VISIT_FINAL_LOCAL_VARIABLE_SET] instead.
+ const Test('m() { const o = 0; o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs:'42')),
+ ],
+ 'Local functions': const [
+ // Local functions
+ const Test('m() { o(a, b) {}; return o; }',
+ const Visit(VisitKind.VISIT_LOCAL_FUNCTION_GET,
+ element: 'function(m#o)')),
+ const Test('m() { o(a, b) {}; o(null, 42); }',
+ const Visit(VisitKind.VISIT_LOCAL_FUNCTION_INVOKE,
+ element: 'function(m#o)',
+ arguments: '(null,42)',
+ selector: 'CallStructure(arity=2)')),
+ const Test('m() { o(a) {}; o(null, 42); }',
+ const Visit(VisitKind.VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,
+ element: 'function(m#o)',
+ arguments: '(null,42)',
+ selector: 'CallStructure(arity=2)')),
+ // TODO(johnniwinther): Expect [VISIT_LOCAL_FUNCTION_SET] instead.
+ const Test('m() { o(a, b) {}; o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ ],
+ 'Static fields': const [
+ // Static fields
+ const Test(
+ '''
+ class C { static var o; }
+ m() => C.o;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
+ element: 'field(C#o)')),
+ const Test.clazz(
+ '''
+ class C {
+ static var o;
+ m() => o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
+ element: 'field(C#o)')),
+ const Test.clazz(
+ '''
+ class C {
+ static var o;
+ m() => C.o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
+ element: 'field(C#o)')),
+ const Test.prefix(
+ '''
+ class C {
+ static var o;
+ }
+ ''',
+ 'm() => p.C.o;',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
+ element: 'field(C#o)')),
+ const Test(
+ '''
+ class C {
+ var o;
+ }
+ m() => C.o;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_GET,
+ name: 'o')),
+ const Test(
+ '''
+ class C {
+ C.o();
+ }
+ m() => C.o;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_GET,
+ name: 'o')),
+ const Test(
+ '''
+ class C {}
+ m() => C.this;
+ ''',
+ null),
+ const Test(
+ '''
+ class C { static var o; }
+ m() { C.o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
+ element: 'field(C#o)',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static var o;
+ m() { o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
+ element: 'field(C#o)',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static var o;
+ m() { C.o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
+ element: 'field(C#o)',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ class C {
+ static var o;
+ }
+ ''',
+ 'm() { p.C.o = 42; }',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
+ element: 'field(C#o)',
+ rhs: '42')),
+ const Test(
+ '''
+ class C { static var o; }
+ m() { C.o(null, 42); }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
+ element: 'field(C#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class C {
+ static var o;
+ m() { o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
+ element: 'field(C#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class C {
+ static var o;
+ m() { C.o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
+ element: 'field(C#o)',
+ arguments: '(null,42)')),
+ const Test.prefix(
+ '''
+ class C {
+ static var o;
+ }
+ ''',
+ 'm() { p.C.o(null, 42); }',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
+ element: 'field(C#o)',
+ arguments: '(null,42)')),
+ const Test(
+ '''
+ class C {}
+ m() => C.this(null, 42);
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
+ name: 'this', arguments: '(null,42)')),
+ // TODO(johnniwinther): Expect [VISIT_FINAL_STATIC_FIELD_SET] instead.
+ const Test(
+ '''
+ class C { static final o = 0; }
+ m() { C.o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static final o = 0;
+ m() { o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static final o = 0;
+ m() { C.o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ class C {
+ static final o = 0;
+ }
+ ''',
+ 'm() { p.C.o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test(
+ '''
+ class C { static const o = 0; }
+ m() { C.o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static const o = 0;
+ m() { o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static const o = 0;
+ m() { C.o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ class C {
+ static const o = 0;
+ }
+ ''',
+ 'm() { p.C.o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ ],
+ 'Static properties': const [
+ // Static properties
+ const Test(
+ '''
+ class C {
+ static get o => null;
+ }
+ m() => C.o;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
+ element: 'getter(C#o)')),
+ const Test.clazz(
+ '''
+ class C {
+ static get o => null;
+ m() => o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
+ element: 'getter(C#o)')),
+ const Test.clazz(
+ '''
+ class C {
+ static get o => null;
+ m() => C.o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
+ element: 'getter(C#o)')),
+ const Test.prefix(
+ '''
+ class C {
+ static get o => null;
+ }
+ ''',
+ 'm() => p.C.o;',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
+ element: 'getter(C#o)')),
+ // TODO(johnniwinther): Expected [VISIT_STATIC_GETTER_SET] instead.
+ const Test(
+ '''
+ class C { static get o => 42; }
+ m() { C.o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static get o => 42;
+ m() { o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static get o => 42;
+ m() { C.o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ class C {
+ static get o => 42;
+ }
+ ''',
+ 'm() { p.C.o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test(
+ '''
+ class C {
+ static set o(_) {}
+ }
+ m() => C.o;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
+ element: 'setter(C#o)')),
+ const Test.clazz(
+ '''
+ class C {
+ static set o(_) {}
+ m() => o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
+ element: 'setter(C#o)')),
+
+ const Test.clazz(
+ '''
+ class C {
+ static set o(_) {}
+ m() => C.o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
+ element: 'setter(C#o)')),
+ const Test.prefix(
+ '''
+ class C {
+ static set o(_) {}
+ }
+ ''',
+ 'm() => p.C.o;',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
+ element: 'setter(C#o)')),
+ const Test(
+ '''
+ class C { static set o(_) {} }
+ m() { C.o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
+ element: 'setter(C#o)',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static set o(_) {}
+ m() { o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
+ element: 'setter(C#o)',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static set o(_) {}
+ m() { C.o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
+ element: 'setter(C#o)',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ class C {
+ static set o(_) {}
+ }
+ ''',
+ 'm() { p.C.o = 42; }',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
+ element: 'setter(C#o)',
+ rhs: '42')),
+ const Test(
+ '''
+ class C { static get o => null; }
+ m() => C.o(null, 42);
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
+ element: 'getter(C#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class C {
+ static get o => null;
+ m() { o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
+ element: 'getter(C#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class C {
+ static get o => null;
+ m() { C.o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
+ element: 'getter(C#o)',
+ arguments: '(null,42)')),
+ const Test.prefix(
+ '''
+ class C {
+ static get o => null;
+ }
+ ''',
+ 'm() { p.C.o(null, 42); }',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
+ element: 'getter(C#o)',
+ arguments: '(null,42)')),
+ const Test(
+ '''
+ class C { static set o(_) {} }
+ m() => C.o(null, 42);
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
+ element: 'setter(C#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class C {
+ static set o(_) {}
+ m() { o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
+ element: 'setter(C#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class C {
+ static set o(_) {}
+ m() { C.o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
+ element: 'setter(C#o)',
+ arguments: '(null,42)')),
+ const Test.prefix(
+ '''
+ class C {
+ static set o(_) {}
+ }
+ ''',
+ 'm() { p.C.o(null, 42); }',
+ const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
+ element: 'setter(C#o)',
+ arguments: '(null,42)')),
+ ],
+ 'Static functions': const [
+ // Static functions
+ const Test(
+ '''
+ class C { static o(a, b) {} }
+ m() => C.o;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
+ element: 'function(C#o)')),
+ const Test.clazz(
+ '''
+ class C {
+ static o(a, b) {}
+ m() => o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
+ element: 'function(C#o)')),
+ const Test.clazz(
+ '''
+ class C {
+ static o(a, b) {}
+ m() => C.o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
+ element: 'function(C#o)')),
+ const Test.prefix(
+ '''
+ class C { static o(a, b) {} }
+ ''',
+ '''
+ m() => p.C.o;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
+ element: 'function(C#o)')),
+ // TODO(johnniwinther): Expect [VISIT_STATIC_FUNCTION_SET] instead.
+ const Test(
+ '''
+ class C { static o(a, b) {} }
+ m() { C.o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static o(a, b) {}
+ m() { o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static o(a, b) {}
+ m() { C.o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ class C { static o(a, b) {} }
+ ''',
+ '''
+ m() { p.C.o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test(
+ '''
+ class C { static o(a, b) {} }
+ m() => C.o(null, 42);
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
+ element: 'function(C#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class C {
+ static o(a, b) {}
+ m() { o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
+ element: 'function(C#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class C {
+ static o(a, b) {}
+ m() { C.o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
+ element: 'function(C#o)',
+ arguments: '(null,42)')),
+ const Test.prefix(
+ '''
+ class C {
+ static o(a, b) {}
+ }
+ ''',
+ 'm() { p.C.o(null, 42); }',
+ const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
+ element: 'function(C#o)',
+ arguments: '(null,42)')),
+ const Test(
+ '''
+ class C { static o(a, b) {} }
+ m() => C.o(null);
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,
+ element: 'function(C#o)',
+ arguments: '(null)')),
+ ],
+ 'Top level fields': const [
+ // Top level fields
+ const Test(
+ '''
+ var o;
+ m() => o;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET,
+ element: 'field(o)')),
+ const Test.prefix(
+ '''
+ var o;
+ ''',
+ 'm() => p.o;',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET,
+ element: 'field(o)')),
+ const Test(
+ '''
+ var o;
+ m() { o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
+ element: 'field(o)',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ var o;
+ ''',
+ 'm() { p.o = 42; }',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
+ element: 'field(o)',
+ rhs: '42')),
+ // TODO(johnniwinther): Expect [VISIT_FINAL_TOP_LEVEL_FIELD_SET] instead.
+ const Test(
+ '''
+ final o = 0;
+ m() { o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ final o = 0;
+ ''',
+ 'm() { p.o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test(
+ '''
+ const o = 0;
+ m() { o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ const o = 0;
+ ''',
+ 'm() { p.o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test(
+ '''
+ var o;
+ m() { o(null, 42); }
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
+ element: 'field(o)',
+ arguments: '(null,42)')),
+ const Test.prefix(
+ '''
+ var o;
+ ''',
+ 'm() { p.o(null, 42); }',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
+ element: 'field(o)',
+ arguments: '(null,42)')),
+ const Test(
+ '''
+ m() => o;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_GET,
+ name: 'o')),
+ ],
+ 'Top level properties': const [
+ // Top level properties
+ const Test(
+ '''
+ get o => null;
+ m() => o;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,
+ element: 'getter(o)')),
+ const Test.prefix(
+ '''
+ get o => null;
+ ''',
+ '''
+ m() => p.o;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,
+ element: 'getter(o)')),
+ // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_SETTER_GET] instead.
+ const Test(
+ '''
+ set o(_) {}
+ m() => o;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_GET,
+ element: 'setter(o)')),
+ const Test.prefix(
+ '''
+ set o(_) {}
+ ''',
+ '''
+ m() => p.o;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_GET,
+ name: 'o')),
+ // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_GETTER_SET] instead.
+ const Test(
+ '''
+ get o => null;
+ m() { o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ get o => null;
+ ''',
+ 'm() { p.o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test(
+ '''
+ set o(_) {}
+ m() { o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,
+ element: 'setter(o)',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ set o(_) {}
+ ''',
+ 'm() { p.o = 42; }',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,
+ element: 'setter(o)',
+ rhs: '42')),
+ const Test(
+ '''
+ get o => null;
+ m() => o(null, 42);
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,
+ element: 'getter(o)',
+ arguments: '(null,42)')),
+ const Test.prefix(
+ '''
+ get o => null;
+ ''',
+ 'm() { p.o(null, 42); }',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,
+ element: 'getter(o)',
+ arguments: '(null,42)')),
+ // TODO(johnniwinther): Expected [VISIT_TOP_LEVEL_SETTER_INVOKE] instead.
+ const Test(
+ '''
+ set o(_) {}
+ m() => o(null, 42);
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_INVOKE,
+ element: 'setter(o)',
+ arguments: '(null,42)')),
+ const Test.prefix(
+ '''
+ set o(_) {}
+ ''',
+ 'm() { p.o(null, 42); }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
+ name: 'o',
+ arguments: '(null,42)')),
+ ],
+ 'Top level functions': const [
+ // Top level functions
+ const Test(
+ '''
+ o(a, b) {}
+ m() => o;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_GET,
+ element: 'function(o)')),
+ const Test(
+ '''
+ o(a, b) {}
+ m() => o(null, 42);
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,
+ element: 'function(o)',
+ arguments: '(null,42)')),
+ const Test(
+ '''
+ o(a, b) {}
+ m() => o(null);
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,
+ element: 'function(o)',
+ arguments: '(null)')),
+ const Test.prefix(
+ '''
+ o(a, b) {}
+ ''',
+ 'm() { p.o(null, 42); }',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,
+ element: 'function(o)',
+ arguments: '(null,42)')),
+ const Test(
+ '''
+ m() => o(null, 42);
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
+ name: 'o',
+ arguments: '(null,42)')),
+ // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_FUNCTION_SET] instead.
+ const Test(
+ '''
+ o(a, b) {}
+ m() { o = 42; }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.prefix(
+ '''
+ o(a, b) {}
+ ''',
+ 'm() { p.o = 42; }',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ ],
+ 'Dynamic properties': const [
+ // Dynamic properties
+ const Test('m(o) => o.foo;',
+ const [
+ const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
+ receiver: 'o',
+ name: 'foo'),
+ const Visit(VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#o)'),
+ ]),
+ const Test('m(o) { o.foo = 42; }',
+ const [
+ const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,
+ receiver: 'o',
+ name: 'foo',
+ rhs: '42'),
+ const Visit(VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#o)'),
+ ]),
+ const Test('m(o) { o.foo(null, 42); }',
+ const [
+ const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,
+ receiver: 'o',
+ name: 'foo',
+ arguments: '(null,42)'),
+ const Visit(VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#o)'),
+ ]),
+ ],
+ 'This access': const [
+ // This access
+ const Test.clazz(
+ '''
+ class C {
+ m() => this;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_GET)),
+ const Test.clazz(
+ '''
+ class C {
+ call(a, b) {}
+ m() { this(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_INVOKE,
+ arguments: '(null,42)')),
+ ],
+ 'This properties': const [
+ // This properties
+ const Test.clazz(
+ '''
+ class C {
+ var foo;
+ m() => foo;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
+ name: 'foo')),
+ const Test.clazz(
+ '''
+ class C {
+ var foo;
+ m() => this.foo;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
+ name: 'foo')),
+ const Test.clazz(
+ '''
+ class C {
+ get foo => null;
+ m() => foo;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
+ name: 'foo')),
+ const Test.clazz(
+ '''
+ class C {
+ get foo => null;
+ m() => this.foo;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
+ name: 'foo')),
+ const Test.clazz(
+ '''
+ class C {
+ var foo;
+ m() { foo = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
+ name: 'foo',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ var foo;
+ m() { this.foo = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
+ name: 'foo',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ set foo(_) {}
+ m() { foo = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
+ name: 'foo',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ set foo(_) {}
+ m() { this.foo = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
+ name: 'foo',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ var foo;
+ m() { foo(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,
+ name: 'foo',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class C {
+ var foo;
+ m() { this.foo(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,
+ name: 'foo',
+ arguments: '(null,42)')),
+ ],
+ 'Super fields': const [
+ // Super fields
+ const Test.clazz(
+ '''
+ class B {
+ var o;
+ }
+ class C extends B {
+ m() => super.o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FIELD_GET,
+ element: 'field(B#o)')),
+ const Test.clazz(
+ '''
+ class B {
+ var o;
+ }
+ class C extends B {
+ m() { super.o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FIELD_SET,
+ element: 'field(B#o)',
+ rhs: '42')),
+ // TODO(johnniwinther): Expect [VISIT_FINAL_SUPER_FIELD_SET] instead.
+ const Test.clazz(
+ '''
+ class B {
+ final o = 0;
+ }
+ class C extends B {
+ m() { super.o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ var o;
+ }
+ class C extends B {
+ m() { super.o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FIELD_INVOKE,
+ element: 'field(B#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => super.o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GET)),
+ ],
+ 'Super properties': const [
+ // Super properties
+ const Test.clazz(
+ '''
+ class B {
+ get o => null;
+ }
+ class C extends B {
+ m() => super.o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_GET,
+ element: 'getter(B#o)')),
+ const Test.clazz(
+ '''
+ class B {
+ set o(_) {}
+ }
+ class C extends B {
+ m() => super.o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_SETTER_GET,
+ element: 'setter(B#o)')),
+ // TODO(johnniwinther): Expect [VISIT_SUPER_GETTER_SET] instead.
+ const Test.clazz(
+ '''
+ class B {
+ get o => 0;
+ }
+ class C extends B {
+ m() { super.o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: 'o',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ set o(_) {}
+ }
+ class C extends B {
+ m() { super.o = 42; }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_SETTER_SET,
+ element: 'setter(B#o)',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ get o => null;
+ }
+ class C extends B {
+ m() { super.o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,
+ element: 'getter(B#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class B {
+ set o(_) {}
+ }
+ class C extends B {
+ m() { super.o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_SETTER_INVOKE,
+ element: 'setter(B#o)',
+ arguments: '(null,42)')),
+ ],
+ 'Super methods': const [
+ // Super methods
+ const Test.clazz(
+ '''
+ class B {
+ o(a, b) {}
+ }
+ class C extends B {
+ m() => super.o;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_METHOD_GET,
+ element: 'function(B#o)')),
+ const Test.clazz(
+ '''
+ class B {
+ o(a, b) {}
+ }
+ class C extends B {
+ m() { super.o(null, 42); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_METHOD_INVOKE,
+ element: 'function(B#o)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class B {
+ o(a, b) {}
+ }
+ class C extends B {
+ m() { super.o(null); }
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,
+ element: 'function(B#o)',
+ arguments: '(null)')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => super.o(null, 42);
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INVOKE,
+ arguments: '(null,42)')),
+ ],
+ 'Expression invoke': const [
+ // Expression invoke
+ const Test('m() => (a, b){}(null, 42);',
+ const Visit(VisitKind.VISIT_EXPRESSION_INVOKE,
+ receiver: '(a,b){}',
+ arguments: '(null,42)')),
+ ],
+ 'Class type literals': const [
+ // Class type literals
+ const Test(
+ '''
+ class C {}
+ m() => C;
+ ''',
+ const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
+ constant: 'C')),
+ const Test(
+ '''
+ class C {}
+ m() => C(null, 42);
+ ''',
+ const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
+ constant: 'C',
+ arguments: '(null,42)')),
+ const Test(
+ '''
+ class C {}
+ m() => C += 42;
+ ''',
+ const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,
+ constant: 'C',
+ operator: '+=',
+ rhs: '42')),
+ const Test(
+ '''
+ class C {}
+ m() => ++C;
+ ''',
+ const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,
+ constant: 'C',
+ operator: '++')),
+ const Test(
+ '''
+ class C {}
+ m() => C--;
+ ''',
+ const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,
+ constant: 'C',
+ operator: '--')),
+ const Test(
+ '''
+ class C {}
+ m() => (C).hashCode;
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
+ receiver: '(C)', name: 'hashCode'),
+ const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
+ constant: 'C'),
+ ]),
+ ],
+ 'Typedef type literals': const [
+ // Typedef type literals
+ const Test(
+ '''
+ typedef F();
+ m() => F;
+ ''',
+ const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_GET,
+ constant: 'F')),
+ const Test(
+ '''
+ typedef F();
+ m() => F(null, 42);
+ ''',
+ const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
+ constant: 'F',
+ arguments: '(null,42)')),
+ const Test(
+ '''
+ typedef F();
+ m() => F += 42;
+ ''',
+ const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,
+ constant: 'F',
+ operator: '+=',
+ rhs: '42')),
+ const Test(
+ '''
+ typedef F();
+ m() => ++F;
+ ''',
+ const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
+ constant: 'F',
+ operator: '++')),
+ const Test(
+ '''
+ typedef F();
+ m() => F--;
+ ''',
+ const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,
+ constant: 'F',
+ operator: '--')),
+ ],
+ 'Type variable type literals': const [
+ // Type variable type literals
+ const Test.clazz(
+ '''
+ class C<T> {
+ m() => T;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,
+ element: 'type_variable(C#T)')),
+ const Test.clazz(
+ '''
+ class C<T> {
+ m() => T(null, 42);
+ }
+ ''',
+ const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,
+ element: 'type_variable(C#T)',
+ arguments: '(null,42)')),
+ const Test.clazz(
+ '''
+ class C<T> {
+ m() => T += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,
+ element: 'type_variable(C#T)',
+ operator: '+=',
+ rhs: '42')),
+ const Test.clazz(
+ '''
+ class C<T> {
+ m() => ++T;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,
+ element: 'type_variable(C#T)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class C<T> {
+ m() => T--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,
+ element: 'type_variable(C#T)',
+ operator: '--')),
+
+ ],
+ 'Dynamic type literals': const [
+ // Dynamic type literals
+ const Test(
+ '''
+ m() => dynamic;
+ ''',
+ const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,
+ constant: 'dynamic')),
+ // TODO(johnniwinther): Update these to expect the constant to be `dynamic`
+ // instead of `Type`. Currently the compile time constant evaluator cannot
+ // detect `dynamic` as a constant subexpression.
+ const Test(
+ '''
+ m() { dynamic(null, 42); }
+ ''',
+ const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
+ constant: 'Type',
+ arguments: '(null,42)')),
+ const Test(
+ '''
+ m() => dynamic += 42;
+ ''',
+ const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,
+ constant: 'Type',
+ operator: '+=',
+ rhs: '42')),
+ const Test(
+ '''
+ m() => ++dynamic;
+ ''',
+ const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
+ constant: 'Type',
+ operator: '++')),
+ const Test(
+ '''
+ m() => dynamic--;
+ ''',
+ const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,
+ constant: 'Type',
+ operator: '--')),
+ ],
+ 'Assert': const [
+ // Assert
+ const Test(
+ '''
+ m() { assert(false); }
+ ''',
+ const Visit(VisitKind.VISIT_ASSERT, expression: 'false')),
+ const Test(
+ '''
+ m() { assert(); }
+ ''',
+ const Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: '()')),
+ const Test(
+ '''
+ m() { assert(42, true); }
+ ''',
+ const Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: '(42,true)')),
+ ],
+ 'Logical and': const [
+ // Logical and
+ const Test(
+ '''
+ m() => true && false;
+ ''',
+ const Visit(VisitKind.VISIT_LOGICAL_AND, left: 'true', right: 'false')),
+ ],
+ 'Logical or': const [
+ // Logical or
+ const Test(
+ '''
+ m() => true || false;
+ ''',
+ const Visit(VisitKind.VISIT_LOGICAL_OR, left: 'true', right: 'false')),
+ ],
+ 'Is test': const [
+ // Is test
+ const Test(
+ '''
+ class C {}
+ m() => 0 is C;
+ ''',
+ const Visit(VisitKind.VISIT_IS, expression: '0', type: 'C')),
+ ],
+ 'Is not test': const [
+ // Is not test
+ const Test(
+ '''
+ class C {}
+ m() => 0 is! C;
+ ''',
+ const Visit(VisitKind.VISIT_IS_NOT, expression: '0', type: 'C')),
+ ],
+ 'As test': const [
+ // As test
+ const Test(
+ '''
+ class C {}
+ m() => 0 as C;
+ ''',
+ const Visit(VisitKind.VISIT_AS, expression: '0', type: 'C')),
+ ],
+ 'Binary operators': const [
+ // Binary operators
+ const Test(
+ '''
+ m() => 2 + 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '+', right: '3')),
+ const Test(
+ '''
+ m() => 2 - 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '-', right: '3')),
+ const Test(
+ '''
+ m() => 2 * 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '*', right: '3')),
+ const Test(
+ '''
+ m() => 2 / 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '/', right: '3')),
+ const Test(
+ '''
+ m() => 2 ~/ 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '~/', right: '3')),
+ const Test(
+ '''
+ m() => 2 % 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '%', right: '3')),
+ const Test(
+ '''
+ m() => 2 << 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '<<', right: '3')),
+ const Test(
+ '''
+ m() => 2 >> 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '>>', right: '3')),
+ const Test(
+ '''
+ m() => 2 <= 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '<=', right: '3')),
+ const Test(
+ '''
+ m() => 2 < 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '<', right: '3')),
+ const Test(
+ '''
+ m() => 2 >= 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '>=', right: '3')),
+ const Test(
+ '''
+ m() => 2 > 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '>', right: '3')),
+ const Test(
+ '''
+ m() => 2 & 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '&', right: '3')),
+ const Test(
+ '''
+ m() => 2 | 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '|', right: '3')),
+ const Test(
+ '''
+ m() => 2 ^ 3;
+ ''',
+ const Visit(VisitKind.VISIT_BINARY,
+ left: '2', operator: '^', right: '3')),
+ const Test.clazz(
+ '''
+ class B {
+ operator +(_) => null;
+ }
+ class C extends B {
+ m() => super + 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_BINARY,
+ element: 'function(B#+)',
+ operator: '+',
+ right: '42')),
+ const Test.clazz(
+ '''
+ class B {}
+ class C extends B {
+ m() => super + 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_BINARY,
+ operator: '+',
+ right: '42')),
+ const Test(
+ '''
+ m() => 2 === 3;
+ ''',
+ const Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,
+ left: '2', operator: '===', right: '3')),
+ const Test(
+ '''
+ m() => 2 !== 3;
+ ''',
+ const Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,
+ left: '2', operator: '!==', right: '3')),
+ ],
+ 'Index': const [
+ // Index
+ const Test(
+ '''
+ m() => 2[3];
+ ''',
+ const Visit(VisitKind.VISIT_INDEX,
+ receiver: '2', index: '3')),
+ const Test(
+ '''
+ m() => --2[3];
+ ''',
+ const Visit(VisitKind.VISIT_INDEX_PREFIX,
+ receiver: '2', index: '3', operator: '--')),
+ const Test(
+ '''
+ m() => 2[3]++;
+ ''',
+ const Visit(VisitKind.VISIT_INDEX_POSTFIX,
+ receiver: '2', index: '3', operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ operator [](_) => null;
+ }
+ class C extends B {
+ m() => super[42];
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_INDEX,
+ element: 'function(B#[])',
+ index: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => super[42];
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX,
+ index: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ operator [](_) => null;
+ operator []=(a, b) {}
+ }
+ class C extends B {
+ m() => ++super[42];
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_INDEX_PREFIX,
+ getter: 'function(B#[])',
+ setter: 'function(B#[]=)',
+ index: '42',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ operator []=(a, b) {}
+ }
+ class C extends B {
+ m() => ++super[42];
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,
+ setter: 'function(B#[]=)',
+ index: '42',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => ++super[42];
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,
+ index: '42',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ operator [](_) => null;
+ }
+ class C extends B {
+ m() => ++super[42];
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,
+ getter: 'function(B#[])',
+ index: '42',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ operator [](_) => null;
+ operator []=(a, b) {}
+ }
+ class C extends B {
+ m() => super[42]--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_INDEX_POSTFIX,
+ getter: 'function(B#[])',
+ setter: 'function(B#[]=)',
+ index: '42',
+ operator: '--')),
+ const Test.clazz(
+ '''
+ class B {
+ operator []=(a, b) {}
+ }
+ class C extends B {
+ m() => super[42]--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,
+ setter: 'function(B#[]=)',
+ index: '42',
+ operator: '--')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => super[42]--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,
+ index: '42',
+ operator: '--')),
+ const Test.clazz(
+ '''
+ class B {
+ operator [](_) => null;
+ }
+ class C extends B {
+ m() => super[42]--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,
+ getter: 'function(B#[])',
+ index: '42',
+ operator: '--')),
+ ],
+ 'Equals': const [
+ // Equals
+ const Test(
+ '''
+ m() => 2 == 3;
+ ''',
+ const Visit(VisitKind.VISIT_EQUALS,
+ left: '2', right: '3')),
+ const Test.clazz(
+ '''
+ class B {
+ operator ==(_) => null;
+ }
+ class C extends B {
+ m() => super == 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_EQUALS,
+ element: 'function(B#==)',
+ right: '42')),
+ ],
+ 'Not equals': const [
+ // Not equals
+ const Test(
+ '''
+ m() => 2 != 3;
+ ''',
+ const Visit(VisitKind.VISIT_NOT_EQUALS,
+ left: '2', right: '3')),
+ const Test.clazz(
+ '''
+ class B {
+ operator ==(_) => null;
+ }
+ class C extends B {
+ m() => super != 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,
+ element: 'function(B#==)',
+ right: '42')),
+ ],
+ 'Unary expression': const [
+ // Unary expression
+ const Test(
+ '''
+ m() => -false;
+ ''',
+ const Visit(VisitKind.VISIT_UNARY,
+ expression: 'false', operator: '-')),
+ const Test(
+ '''
+ m() => ~false;
+ ''',
+ const Visit(VisitKind.VISIT_UNARY,
+ expression: 'false', operator: '~')),
+ const Test.clazz(
+ '''
+ class B {
+ operator -() => null;
+ }
+ class C extends B {
+ m() => -super;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_UNARY,
+ element: 'function(B#unary-)', operator: '-')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => -super;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_UNARY,
+ operator: '-')),
+ const Test.clazz(
+ '''
+ class B {
+ operator ~() => null;
+ }
+ class C extends B {
+ m() => ~super;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_UNARY,
+ element: 'function(B#~)', operator: '~')),
+ const Test(
+ '''
+ m() => !0;
+ ''',
+ const Visit(VisitKind.VISIT_NOT, expression: '0')),
+ const Test(
+ '''
+ m() => +false;
+ ''',
+ // TODO(johnniwinther): Should this be an
+ // ERROR_UNDEFINED_UNARY_EXPRESSION? Currently the parser just skips
+ // the `+`.
+ const []),
+ ],
+ 'Index set': const [
+ // Index set
+ const Test(
+ '''
+ m() => 0[1] = 2;
+ ''',
+ const Visit(VisitKind.VISIT_INDEX_SET,
+ receiver: '0', index: '1', rhs: '2')),
+ const Test.clazz(
+ '''
+ class B {
+ operator []=(a, b) {}
+ }
+ class C extends B {
+ m() => super[1] = 2;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_INDEX_SET,
+ element: 'function(B#[]=)', index: '1', rhs: '2')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => super[1] = 2;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_SET,
+ index: '1', rhs: '2')),
+ ],
+ 'Compound assignment': const [
+ // Compound assignment
+ const Test(
+ '''
+ m(a) => a.b += 42;
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_COMPOUND,
+ receiver: 'a', operator: '+=', rhs: '42',
+ getter: 'Selector(getter, b, arity=0)',
+ setter: 'Selector(setter, b, arity=1)'),
+ const Visit(VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#a)')
+ ]),
+ const Test(
+ '''
+ m(a) => a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_PARAMETER_COMPOUND,
+ element: 'parameter(m#a)', operator: '+=', rhs: '42')),
+ const Test(
+ '''
+ m(final a) => a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_FINAL_PARAMETER_COMPOUND,
+ element: 'parameter(m#a)', operator: '+=', rhs: '42')),
+ const Test(
+ '''
+ m() {
+ var a;
+ a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_COMPOUND,
+ element: 'variable(m#a)', operator: '+=', rhs: '42')),
+ const Test(
+ '''
+ m() {
+ final a = 0;
+ a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,
+ element: 'variable(m#a)', operator: '+=', rhs: '42')),
+ const Test(
+ '''
+ m() {
+ a() {}
+ a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_LOCAL_FUNCTION_COMPOUND,
+ element: 'function(m#a)', operator: '+=', rhs: '42')),
+ const Test(
+ '''
+ var a;
+ m() => a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_COMPOUND,
+ element: 'field(a)', operator: '+=', rhs: '42')),
+ const Test(
+ '''
+ get a => 0;
+ set a(_) {}
+ m() => a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,
+ getter: 'getter(a)', setter: 'setter(a)',
+ operator: '+=', rhs: '42')),
+ const Test(
+ '''
+ class C {
+ static var a;
+ }
+ m() => C.a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
+ element: 'field(C#a)', operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static var a;
+ m() => C.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
+ element: 'field(C#a)', operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static var a;
+ m() => a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
+ element: 'field(C#a)', operator: '+=', rhs: '42')),
+ const Test.prefix(
+ '''
+ class C {
+ static var a;
+ }
+ ''',
+ '''
+ m() => p.C.a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
+ element: 'field(C#a)', operator: '+=', rhs: '42')),
+ const Test(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ }
+ m() => C.a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ m() => C.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ m() => a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '+=', rhs: '42')),
+ const Test.prefix(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ }
+ ''',
+ '''
+ m() => p.C.a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '+=', rhs: '42')),
+ // TODO(johnniwinther): Enable these when dart2js supports method and setter
+ // with the same name.
+ /*const Test(
+ '''
+ class C {
+ static a() {}
+ static set a(_) {}
+ }
+ m() => C.a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+ getter: 'function(C#a)', setter: 'setter(C#a)',
+ operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static a() {}
+ static set a(_) {}
+ m() => C.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+ getter: 'function(C#a)', setter: 'setter(C#a)',
+ operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class C {
+ static a() {}
+ static set a(_) {}
+ m() => a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+ getter: 'function(C#a)', setter: 'setter(C#a)',
+ operator: '+=', rhs: '42')),
+ const Test.prefix(
+ '''
+ class C {
+ static a() {}
+ static set a(_) {}
+ }
+ ''',
+ '''
+ m() => p.C.a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+ getter: 'function(C#a)', setter: 'setter(C#a)',
+ operator: '+=', rhs: '42')),*/
+ const Test.clazz(
+ '''
+ class C {
+ var a;
+ m() => a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,
+ operator: '+=', rhs: '42',
+ getter: 'Selector(getter, a, arity=0)',
+ setter: 'Selector(setter, a, arity=1)')),
+ const Test.clazz(
+ '''
+ class C {
+ var a = 0;
+ m() => this.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,
+ operator: '+=', rhs: '42',
+ getter: 'Selector(getter, a, arity=0)',
+ setter: 'Selector(setter, a, arity=1)')),
+ const Test.clazz(
+ '''
+ class B {
+ var a = 0;
+ }
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FIELD_COMPOUND,
+ element: 'field(B#a)', operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ final a = 0;
+ }
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,
+ element: 'field(B#a)', operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ get a => 0;
+ set a (_) {}
+ }
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,
+ getter: 'getter(B#a)', setter: 'setter(B#a)',
+ operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class A {
+ get a => 0;
+ }
+ class B extends A {
+ set a (_) {}
+ }
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,
+ getter: 'getter(A#a)', setter: 'setter(B#a)',
+ operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class A {
+ var a;
+ }
+ class B extends A {
+ get a => 0;
+ }
+
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_COMPOUND,
+ getter: 'getter(B#a)', setter: 'field(A#a)',
+ operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class A {
+ var a;
+ }
+ class B extends A {
+ set a(_) {}
+ }
+
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_COMPOUND,
+ getter: 'field(A#a)', setter: 'setter(B#a)',
+ operator: '+=', rhs: '42')),
+ // TODO(johnniwinther): Enable this when dart2js supports shadow setters.
+ /*const Test.clazz(
+ '''
+ class A {
+ var a;
+ }
+ class B extends A {
+ final a = 0;
+ }
+
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
+ getter: 'field(B#a)', setter: 'field(A#a)',
+ operator: '+=', rhs: '42')),*/
+ const Test.clazz(
+ '''
+ class B {
+ a() {}
+ }
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_METHOD_COMPOUND,
+ element: 'function(B#a)',
+ operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND,
+ operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ set a(_) {}
+ }
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,
+ setter: 'setter(B#a)', operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ get a => 42;
+ }
+ class C extends B {
+ m() => super.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,
+ getter: 'getter(B#a)', operator: '+=', rhs: '42')),
+
+ const Test.clazz(
+ '''
+ class C {
+ static set a(var value) { }
+ m() => a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,
+ setter: 'setter(C#a)', operator: '+=', rhs: '42')),
+
+ const Test.clazz(
+ '''
+ class C {
+ static get a => 42;
+ m() => C.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,
+ getter: 'getter(C#a)', operator: '+=', rhs: '42')),
+
+ const Test.clazz(
+ '''
+ class C {
+ static final a = 42;
+ m() => C.a += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_COMPOUND,
+ element: 'field(C#a)', operator: '+=', rhs: '42')),
+
+ const Test(
+ '''
+ class C {
+ static a(var value) { }
+ }
+ m() => C.a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_METHOD_COMPOUND,
+ element: 'function(C#a)', operator: '+=', rhs: '42')),
+
+ const Test(
+ '''
+ set a(var value) { }
+ m() => a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,
+ setter: 'setter(a)', operator: '+=', rhs: '42')),
+
+ const Test(
+ '''
+ get a => 42;
+ m() => a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,
+ getter: 'getter(a)', operator: '+=', rhs: '42')),
+
+ const Test(
+ '''
+ a(var value) { }
+ m() => a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_COMPOUND,
+ element: 'function(a)', operator: '+=', rhs: '42')),
+
+ const Test(
+ '''
+ final a = 42;
+ m() => a += 42;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,
+ element: 'field(a)', operator: '+=', rhs: '42')),
+
+ const Test(
+ '''
+ m() => unresolved += 42;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_COMPOUND,
+ operator: '+=', rhs: '42')),
+ ],
+ 'Compound index assignment': const [
+ // Compound index assignment
+ const Test(
+ '''
+ m() => 0[1] += 42;
+ ''',
+ const Visit(VisitKind.VISIT_COMPOUND_INDEX_SET,
+ receiver: '0', index: '1', operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ operator [](_) {}
+ operator []=(a, b) {}
+ }
+ class C extends B {
+ m() => super[1] += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_COMPOUND_INDEX_SET,
+ getter: 'function(B#[])', setter: 'function(B#[]=)',
+ index: '1', operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ operator []=(a, b) {}
+ }
+ class C extends B {
+ m() => super[1] += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,
+ setter: 'function(B#[]=)',
+ index: '1', operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => super[1] += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,
+ index: '1', operator: '+=', rhs: '42')),
+ const Test.clazz(
+ '''
+ class B {
+ operator [](_) {}
+ }
+ class C extends B {
+ m() => super[1] += 42;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,
+ getter: 'function(B#[])',
+ index: '1', operator: '+=', rhs: '42')),
+ ],
+ 'Prefix expression': const [
+ // Prefix expression
+ const Test(
+ '''
+ m(a) => --a.b;
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_PREFIX,
+ receiver: 'a', operator: '--',
+ getter: 'Selector(getter, b, arity=0)',
+ setter: 'Selector(setter, b, arity=1)'),
+ const Visit(VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#a)')
+ ]),
+ const Test(
+ '''
+ m(a) => ++a;
+ ''',
+ const Visit(VisitKind.VISIT_PARAMETER_PREFIX,
+ element: 'parameter(m#a)', operator: '++')),
+ const Test(
+ '''
+ m(final a) => ++a;
+ ''',
+ const Visit(VisitKind.VISIT_FINAL_PARAMETER_PREFIX,
+ element: 'parameter(m#a)', operator: '++')),
+ const Test(
+ '''
+ m() {
+ var a;
+ --a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_PREFIX,
+ element: 'variable(m#a)', operator: '--')),
+ const Test(
+ '''
+ m() {
+ final a = 42;
+ --a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_PREFIX,
+ element: 'variable(m#a)', operator: '--')),
+ const Test(
+ '''
+ m() {
+ a() {}
+ --a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_LOCAL_FUNCTION_PREFIX,
+ element: 'function(m#a)', operator: '--')),
+ const Test(
+ '''
+ var a;
+ m() => ++a;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_PREFIX,
+ element: 'field(a)', operator: '++')),
+ const Test(
+ '''
+ get a => 0;
+ set a(_) {}
+ m() => --a;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,
+ getter: 'getter(a)', setter: 'setter(a)',
+ operator: '--')),
+ const Test(
+ '''
+ class C {
+ static var a;
+ }
+ m() => ++C.a;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
+ element: 'field(C#a)', operator: '++')),
+ const Test.clazz(
+ '''
+ class C {
+ static var a;
+ m() => ++C.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
+ element: 'field(C#a)', operator: '++')),
+ const Test.clazz(
+ '''
+ class C {
+ static var a;
+ m() => --a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
+ element: 'field(C#a)', operator: '--')),
+ const Test.prefix(
+ '''
+ class C {
+ static var a;
+ }
+ ''',
+ '''
+ m() => --p.C.a;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
+ element: 'field(C#a)', operator: '--')),
+ const Test(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ }
+ m() => ++C.a;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ m() => --C.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '--')),
+ const Test.clazz(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ m() => --a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '--')),
+ const Test.prefix(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ }
+ ''',
+ '''
+ m() => ++p.C.a;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class C {
+ var a;
+ m() => --a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,
+ operator: '--',
+ getter: 'Selector(getter, a, arity=0)',
+ setter: 'Selector(setter, a, arity=1)')),
+ const Test.clazz(
+ '''
+ class C {
+ var a = 0;
+ m() => ++this.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,
+ operator: '++',
+ getter: 'Selector(getter, a, arity=0)',
+ setter: 'Selector(setter, a, arity=1)')),
+ const Test.clazz(
+ '''
+ class B {
+ var a = 0;
+ }
+ class C extends B {
+ m() => --super.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FIELD_PREFIX,
+ element: 'field(B#a)', operator: '--')),
+ const Test.clazz(
+ '''
+ class B {
+ final a = 0;
+ }
+ class C extends B {
+ m() => --super.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_PREFIX,
+ element: 'field(B#a)', operator: '--')),
+ const Test.clazz(
+ '''
+ class B {
+ get a => 0;
+ set a (_) {}
+ }
+ class C extends B {
+ m() => --super.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,
+ getter: 'getter(B#a)', setter: 'setter(B#a)',
+ operator: '--')),
+ const Test.clazz(
+ '''
+ class A {
+ get a => 0;
+ }
+ class B extends A {
+ set a (_) {}
+ }
+ class C extends B {
+ m() => ++super.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,
+ getter: 'getter(A#a)', setter: 'setter(B#a)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class A {
+ var a;
+ }
+ class B extends A {
+ get a => 0;
+ }
+
+ class C extends B {
+ m() => --super.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_PREFIX,
+ getter: 'getter(B#a)', setter: 'field(A#a)',
+ operator: '--')),
+ const Test.clazz(
+ '''
+ class A {
+ var a;
+ }
+ class B extends A {
+ set a(_) {}
+ }
+
+ class C extends B {
+ m() => ++super.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,
+ getter: 'field(A#a)', setter: 'setter(B#a)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ a() {}
+ }
+ class C extends B {
+ m() => ++super.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_METHOD_PREFIX,
+ element: 'function(B#a)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => ++super.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_PREFIX,
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ set a(_) {}
+ }
+ class C extends B {
+ m() => ++super.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,
+ setter: 'setter(B#a)', operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ get a => 42;
+ }
+ class C extends B {
+ m() => ++super.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,
+ getter: 'getter(B#a)', operator: '++')),
+
+ const Test.clazz(
+ '''
+ class C {
+ static set a(var value) { }
+ m() => ++a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,
+ setter: 'setter(C#a)', operator: '++')),
+
+ const Test.clazz(
+ '''
+ class C {
+ static get a => 42;
+ m() => ++C.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,
+ getter: 'getter(C#a)', operator: '++')),
+
+ const Test.clazz(
+ '''
+ class C {
+ static final a = 42;
+ m() => ++C.a;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_PREFIX,
+ element: 'field(C#a)', operator: '++')),
+
+ const Test(
+ '''
+ class C {
+ static a(var value) { }
+ }
+ m() => ++C.a;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_METHOD_PREFIX,
+ element: 'function(C#a)', operator: '++')),
+
+ const Test(
+ '''
+ set a(var value) { }
+ m() => ++a;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,
+ setter: 'setter(a)', operator: '++')),
+
+ const Test(
+ '''
+ get a => 42;
+ m() => ++a;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,
+ getter: 'getter(a)', operator: '++')),
+
+ const Test(
+ '''
+ a(var value) { }
+ m() => ++a;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_PREFIX,
+ element: 'function(a)', operator: '++')),
+
+ const Test(
+ '''
+ final a = 42;
+ m() => ++a;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,
+ element: 'field(a)', operator: '++')),
+
+ const Test(
+ '''
+ m() => ++unresolved;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_PREFIX,
+ operator: '++')),
+ ],
+ 'Postfix expression': const [
+ // Postfix expression
+ const Test(
+ '''
+ m(a) => a.b--;
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_POSTFIX,
+ receiver: 'a', operator: '--',
+ getter: 'Selector(getter, b, arity=0)',
+ setter: 'Selector(setter, b, arity=1)'),
+ const Visit(VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#a)')
+ ]),
+ const Test(
+ '''
+ m(a) => a++;
+ ''',
+ const Visit(VisitKind.VISIT_PARAMETER_POSTFIX,
+ element: 'parameter(m#a)', operator: '++')),
+ const Test(
+ '''
+ m(final a) => a++;
+ ''',
+ const Visit(VisitKind.VISIT_FINAL_PARAMETER_POSTFIX,
+ element: 'parameter(m#a)', operator: '++')),
+ const Test(
+ '''
+ m() {
+ var a;
+ a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_LOCAL_VARIABLE_POSTFIX,
+ element: 'variable(m#a)', operator: '--')),
+ const Test(
+ '''
+ m() {
+ final a = 42;
+ a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,
+ element: 'variable(m#a)', operator: '--')),
+ const Test(
+ '''
+ m() {
+ a() {}
+ a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_LOCAL_FUNCTION_POSTFIX,
+ element: 'function(m#a)', operator: '--')),
+ const Test(
+ '''
+ var a;
+ m() => a++;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_POSTFIX,
+ element: 'field(a)', operator: '++')),
+ const Test(
+ '''
+ get a => 0;
+ set a(_) {}
+ m() => a--;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,
+ getter: 'getter(a)', setter: 'setter(a)',
+ operator: '--')),
+ const Test(
+ '''
+ class C {
+ static var a;
+ }
+ m() => C.a++;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
+ element: 'field(C#a)', operator: '++')),
+ const Test.clazz(
+ '''
+ class C {
+ static var a;
+ m() => C.a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
+ element: 'field(C#a)', operator: '++')),
+ const Test.clazz(
+ '''
+ class C {
+ static var a;
+ m() => a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
+ element: 'field(C#a)', operator: '--')),
+ const Test.prefix(
+ '''
+ class C {
+ static var a;
+ }
+ ''',
+ '''
+ m() => p.C.a--;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
+ element: 'field(C#a)', operator: '--')),
+ const Test(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ }
+ m() => C.a++;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ m() => C.a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '--')),
+ const Test.clazz(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ m() => a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '--')),
+ const Test.prefix(
+ '''
+ class C {
+ static get a => 0;
+ static set a(_) {}
+ }
+ ''',
+ '''
+ m() => p.C.a++;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
+ getter: 'getter(C#a)', setter: 'setter(C#a)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class C {
+ var a;
+ m() => a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,
+ operator: '--',
+ getter: 'Selector(getter, a, arity=0)',
+ setter: 'Selector(setter, a, arity=1)')),
+ const Test.clazz(
+ '''
+ class C {
+ var a = 0;
+ m() => this.a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,
+ operator: '++',
+ getter: 'Selector(getter, a, arity=0)',
+ setter: 'Selector(setter, a, arity=1)')),
+ const Test.clazz(
+ '''
+ class B {
+ var a = 0;
+ }
+ class C extends B {
+ m() => super.a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FIELD_POSTFIX,
+ element: 'field(B#a)', operator: '--')),
+ const Test.clazz(
+ '''
+ class B {
+ final a = 0;
+ }
+ class C extends B {
+ m() => super.a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_POSTFIX,
+ element: 'field(B#a)', operator: '--')),
+ const Test.clazz(
+ '''
+ class B {
+ get a => 0;
+ set a (_) {}
+ }
+ class C extends B {
+ m() => super.a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,
+ getter: 'getter(B#a)', setter: 'setter(B#a)',
+ operator: '--')),
+ const Test.clazz(
+ '''
+ class A {
+ get a => 0;
+ }
+ class B extends A {
+ set a (_) {}
+ }
+ class C extends B {
+ m() => super.a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,
+ getter: 'getter(A#a)', setter: 'setter(B#a)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class A {
+ var a;
+ }
+ class B extends A {
+ get a => 0;
+ }
+
+ class C extends B {
+ m() => super.a--;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_POSTFIX,
+ getter: 'getter(B#a)', setter: 'field(A#a)',
+ operator: '--')),
+ const Test.clazz(
+ '''
+ class A {
+ var a;
+ }
+ class B extends A {
+ set a(_) {}
+ }
+
+ class C extends B {
+ m() => super.a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,
+ getter: 'field(A#a)', setter: 'setter(B#a)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ a() {}
+ }
+ class C extends B {
+ m() => super.a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_SUPER_METHOD_POSTFIX,
+ element: 'function(B#a)',
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ }
+ class C extends B {
+ m() => super.a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_POSTFIX,
+ operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ set a(_) {}
+ }
+ class C extends B {
+ m() => super.a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,
+ setter: 'setter(B#a)', operator: '++')),
+ const Test.clazz(
+ '''
+ class B {
+ get a => 42;
+ }
+ class C extends B {
+ m() => super.a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,
+ getter: 'getter(B#a)', operator: '++')),
+
+ const Test.clazz(
+ '''
+ class C {
+ static set a(var value) { }
+ m() => a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,
+ setter: 'setter(C#a)', operator: '++')),
+
+ const Test.clazz(
+ '''
+ class C {
+ static get a => 42;
+ m() => C.a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,
+ getter: 'getter(C#a)', operator: '++')),
+
+ const Test.clazz(
+ '''
+ class C {
+ static final a = 42;
+ m() => C.a++;
+ }
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_POSTFIX,
+ element: 'field(C#a)', operator: '++')),
+
+ const Test(
+ '''
+ class C {
+ static a(var value) { }
+ }
+ m() => C.a++;
+ ''',
+ const Visit(VisitKind.VISIT_STATIC_METHOD_POSTFIX,
+ element: 'function(C#a)', operator: '++')),
+
+ const Test(
+ '''
+ set a(var value) { }
+ m() => a++;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,
+ setter: 'setter(a)', operator: '++')),
+
+ const Test(
+ '''
+ get a => 42;
+ m() => a++;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,
+ getter: 'getter(a)', operator: '++')),
+
+ const Test(
+ '''
+ a(var value) { }
+ m() => a++;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_POSTFIX,
+ element: 'function(a)', operator: '++')),
+
+ const Test(
+ '''
+ final a = 42;
+ m() => a++;
+ ''',
+ const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,
+ element: 'field(a)', operator: '++')),
+
+ const Test(
+ '''
+ m() => unresolved++;
+ ''',
+ const Visit(VisitKind.VISIT_UNRESOLVED_POSTFIX,
+ operator: '++')),
+ ],
+ 'Constructor invocations': const [
+ const Test(
+ '''
+ class Class {
+ const Class(a, b);
+ }
+ m() => const Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,
+ constant: 'const Class(true, 42)')),
+ const Test(
+ '''
+ m() => const bool.fromEnvironment('foo');
+ ''',
+ const Visit(VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+ constant:
+ 'const bool.fromEnvironment("foo")')),
+ const Test(
+ '''
+ m() => const bool.fromEnvironment('foo', defaultValue: true);
+ ''',
+ const Visit(VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+ constant: 'const bool.fromEnvironment("foo", defaultValue: true)')),
+ const Test(
+ '''
+ m() => const int.fromEnvironment('foo');
+ ''',
+ const Visit(VisitKind.VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+ constant: 'const int.fromEnvironment("foo")')),
+ const Test(
+ '''
+ m() => const String.fromEnvironment('foo');
+ ''',
+ const Visit(VisitKind.VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+ constant:
+ 'const String.fromEnvironment("foo")')),
+ const Test(
+ '''
+ class Class {
+ Class(a, b);
+ }
+ m() => const Class(true, 42);
+ ''',
+ const Visit(VisitKind.ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {}
+ m() => new Class();
+ ''',
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Class#)',
+ arguments: '()',
+ type: 'Class',
+ selector: 'CallStructure(arity=0)')),
+ const Test(
+ '''
+ class Class {
+ Class(a, b);
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {
+ Class.named(a, b);
+ }
+ m() => new Class.named(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Class#named)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {}
+ m() => new Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
+ element: 'generative_constructor(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {
+ Class(a, b) : this._(a, b);
+ Class._(a, b);
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {
+ Class() : this._(true, 42);
+ Class._(a, b);
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
+ element: 'generative_constructor(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {
+ factory Class(a, b) => new Class._(a, b);
+ Class._(a, b);
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {
+ factory Class() => new Class._(true, 42);
+ Class._(a, b);
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class<T> {
+ factory Class(a, b) = Class<int>.a;
+ factory Class.a(a, b) = Class<Class<T>>.b;
+ Class.b(a, b);
+ }
+ m() => new Class<double>(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class<double>',
+ target: 'generative_constructor(Class#b)',
+ targetType: 'Class<Class<int>>',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class<T> {
+ factory Class(a) = Class<int>.a;
+ factory Class.a(a, [b]) = Class<Class<T>>.b;
+ Class.b(a, [b]);
+ }
+ m() => new Class<double>(true, 42);
+ ''',
+ const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class<double>',
+ target: 'generative_constructor(Class#b)',
+ targetType: 'Class<Class<int>>',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {
+ factory Class() = Class._;
+ Class._();
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(
+ VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class<T> {
+ factory Class(a, b) = Class<int>.a;
+ factory Class.a(a, b) = Class<Class<T>>.b;
+ Class.b(a);
+ }
+ m() => new Class<double>(true, 42);
+ ''',
+ const Visit(
+ VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class<double>',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {
+ Class(a, b);
+ }
+ m() => new Class.unresolved(true, 42);
+ ''',
+ const Visit(
+ VisitKind.VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,
+ arguments: '(true,42)')),
+ const Test(
+ '''
+ m() => new Unresolved(true, 42);
+ ''',
+ const Visit(
+ VisitKind.VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
+ arguments: '(true,42)')),
+ const Test(
+ '''
+ abstract class AbstractClass {}
+ m() => new AbstractClass();
+ ''',
+ const Visit(
+ VisitKind.VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
+ element: 'generative_constructor(AbstractClass#)',
+ type: 'AbstractClass',
+ arguments: '()',
+ selector: 'CallStructure(arity=0)')),
+ const Test(
+ '''
+ class Class {
+ factory Class(a, b) = Unresolved;
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(
+ VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {
+ factory Class(a, b) = Class.named;
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(
+ VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ class Class {
+ factory Class(a, b) = Class.named;
+ factory Class.named(a, b) = Class.unresolved;
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(
+ VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ const Test(
+ '''
+ abstract class AbstractClass {
+ AbstractClass(a, b);
+ }
+ class Class {
+ factory Class(a, b) = AbstractClass;
+ }
+ m() => new Class(true, 42);
+ ''',
+ const Visit(
+ VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: 'function(Class#)',
+ arguments: '(true,42)',
+ type: 'Class',
+ selector: 'CallStructure(arity=2)')),
+ ],
+ 'If not null expressions': const [
+ const Test(
+ '''
+ m(a) => a?.b;
+ ''',
+ const [
+ const Visit(
+ VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
+ receiver: 'a',
+ name: 'b'),
+ const Visit(
+ VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#a)'),
+ ]),
+ const Test(
+ '''
+ class C {
+ static var b;
+ }
+ m(a) => C?.b;
+ ''',
+ const [
+ const Visit(
+ VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
+ receiver: 'C',
+ name: 'b'),
+ const Visit(
+ VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
+ constant: 'C'),
+ ]),
+ const Test(
+ '''
+ m(a) => a?.b = 42;
+ ''',
+ const [
+ const Visit(
+ VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,
+ receiver: 'a',
+ name: 'b',
+ rhs: '42'),
+ const Visit(
+ VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#a)'),
+ ]),
+ const Test(
+ '''
+ m(a) => a?.b(42, true);
+ ''',
+ const [
+ const Visit(
+ VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,
+ receiver: 'a',
+ arguments: '(42,true)',
+ selector: 'Selector(call, b, arity=2)'),
+ const Visit(
+ VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#a)'),
+ ]),
+ const Test(
+ '''
+ m(a) => ++a?.b;
+ ''',
+ const [
+ const Visit(
+ VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,
+ receiver: 'a',
+ getter: 'Selector(getter, b, arity=0)',
+ setter: 'Selector(setter, b, arity=1)',
+ operator: '++'),
+ const Visit(
+ VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#a)'),
+ ]),
+ const Test(
+ '''
+ m(a) => a?.b--;
+ ''',
+ const [
+ const Visit(
+ VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,
+ receiver: 'a',
+ getter: 'Selector(getter, b, arity=0)',
+ setter: 'Selector(setter, b, arity=1)',
+ operator: '--'),
+ const Visit(
+ VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#a)'),
+ ]),
+ const Test(
+ '''
+ m(a) => a?.b *= 42;
+ ''',
+ const [
+ const Visit(
+ VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,
+ receiver: 'a',
+ getter: 'Selector(getter, b, arity=0)',
+ setter: 'Selector(setter, b, arity=1)',
+ operator: '*=',
+ rhs: '42'),
+ const Visit(
+ VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#a)'),
+ ]),
+ const Test(
+ '''
+ m(a, b) => a ?? b;
+ ''',
+ const [
+ const Visit(VisitKind.VISIT_IF_NULL,
+ left: 'a', right: 'b'),
+ const Visit(
+ VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#a)'),
+ const Visit(
+ VisitKind.VISIT_PARAMETER_GET,
+ element: 'parameter(m#b)'),
+ ]),
+ const Test(
+ '''
+ m(a) => a ??= 42;
+ ''',
+ const Visit(
+ VisitKind.VISIT_PARAMETER_COMPOUND,
+ element: 'parameter(m#a)',
+ operator: '??=',
+ rhs: '42')),
+ ],
+};
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart b/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
index 511b1f7..a602e2e 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
@@ -1,2943 +1,2943 @@
-// 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_test;
-
-class SemanticSendTestVisitor extends SemanticTestVisitor {
-
- SemanticSendTestVisitor(TreeElements elements) : super(elements);
-
- @override
- visitAs(
- Send node,
- Node expression,
- DartType type,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_AS,
- expression: expression, type: type));
- apply(expression, arg);
- }
-
- @override
- visitAssert(
- Send node,
- Node expression,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_ASSERT, expression: expression));
- super.visitAssert(node, expression, arg);
- }
-
- @override
- errorInvalidAssert(
- Send node,
- NodeList arguments,
- arg) {
- visits.add(new Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: arguments));
- super.errorInvalidAssert(node, arguments, arg);
- }
-
- @override
- visitBinary(
- Send node,
- Node left,
- BinaryOperator operator,
- Node right,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_BINARY,
- left: left, operator: operator, right: right));
- super.visitBinary(node, left, operator, right, arg);
- }
-
- @override
- errorUndefinedBinaryExpression(
- Send node,
- Node left,
- Operator operator,
- Node right,
- arg) {
- visits.add(new Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,
- left: left, operator: operator, right: right));
- super.errorUndefinedBinaryExpression(node, left, operator, right, arg);
- }
-
- @override
- visitIndex(
- Send node,
- Node receiver,
- Node index,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_INDEX,
- receiver: receiver, index: index));
- apply(receiver, arg);
- apply(index, arg);
- }
-
- @override
- visitClassTypeLiteralGet(
- Send node,
- ConstantExpression constant,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
- constant: constant.getText()));
- }
-
- @override
- visitClassTypeLiteralInvoke(
- Send node,
- ConstantExpression constant,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
- constant: constant.getText(), arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitClassTypeLiteralSet(
- SendSet node,
- ConstantExpression constant,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
- constant: constant.getText(), rhs: rhs));
- super.visitClassTypeLiteralSet(node, constant, rhs, arg);
- }
-
- @override
- visitNotEquals(
- Send node,
- Node left,
- Node right,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_NOT_EQUALS,
- left: left, right: right));
- apply(left, arg);
- apply(right, arg);
- }
-
- @override
- visitDynamicPropertyPrefix(
- Send node,
- Node receiver,
- IncDecOperator operator,
- Selector getterSelector,
- Selector setterSelector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_PREFIX,
- receiver: receiver, operator: operator,
- getter: getterSelector, setter: setterSelector));
- apply(receiver, arg);
- }
-
- @override
- visitDynamicPropertyPostfix(
- Send node,
- Node receiver,
- IncDecOperator operator,
- Selector getterSelector,
- Selector setterSelector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_POSTFIX,
- receiver: receiver, operator: operator,
- getter: getterSelector, setter: setterSelector));
- apply(receiver, arg);
- }
-
- @override
- visitDynamicPropertyGet(
- Send node,
- Node receiver,
- Selector selector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
- receiver: receiver, name: selector.name));
- apply(receiver, arg);
- }
-
- @override
- visitDynamicPropertyInvoke(
- Send node,
- Node receiver,
- NodeList arguments,
- Selector selector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,
- receiver: receiver, name: selector.name, arguments: arguments));
- apply(receiver, arg);
- apply(arguments, arg);
- }
-
- @override
- visitDynamicPropertySet(
- SendSet node,
- Node receiver,
- Selector selector,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,
- receiver: receiver, name: selector.name, rhs: rhs));
- super.visitDynamicPropertySet(node, receiver, selector, rhs, arg);
- }
-
- @override
- visitDynamicTypeLiteralGet(
- Send node,
- ConstantExpression constant,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,
- constant: constant.getText()));
- }
-
- @override
- visitDynamicTypeLiteralInvoke(
- Send node,
- ConstantExpression constant,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
- constant: constant.getText(), arguments: arguments));
- }
-
- @override
- visitDynamicTypeLiteralSet(
- Send node,
- ConstantExpression constant,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,
- rhs: rhs));
- super.visitDynamicTypeLiteralSet(node, constant, rhs, arg);
- }
-
- @override
- visitExpressionInvoke(
- Send node,
- Node expression,
- NodeList arguments,
- Selector selector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_EXPRESSION_INVOKE,
- receiver: expression, arguments: arguments));
- }
-
- @override
- visitIs(
- Send node,
- Node expression,
- DartType type,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_IS,
- expression: expression, type: type));
- apply(expression, arg);
- }
-
- @override
- visitIsNot(
- Send node,
- Node expression,
- DartType type,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_IS_NOT,
- expression: expression, type: type));
- apply(expression, arg);
- }
-
- @override
- visitLogicalAnd(
- Send node,
- Node left,
- Node right,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOGICAL_AND,
- left: left, right: right));
- apply(left, arg);
- apply(right, arg);
- }
-
- @override
- visitLogicalOr(
- Send node,
- Node left,
- Node right,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOGICAL_OR,
- left: left, right: right));
- apply(left, arg);
- apply(right, arg);
- }
-
- @override
- visitLocalFunctionGet(
- Send node,
- LocalFunctionElement function,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_GET,
- element: function));
- }
-
- @override
- visitLocalFunctionSet(
- SendSet node,
- LocalFunctionElement function,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_SET,
- element: function, rhs: rhs));
- super.visitLocalFunctionSet(node, function, rhs, arg);
- }
-
- @override
- visitLocalFunctionInvoke(
- Send node,
- LocalFunctionElement function,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_INVOKE,
- element: function, arguments: arguments, selector: callStructure));
- super.visitLocalFunctionInvoke(
- node, function, arguments, callStructure, arg);
- }
-
- @override
- visitLocalFunctionIncompatibleInvoke(
- Send node,
- LocalFunctionElement function,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,
- element: function, arguments: arguments, selector: callStructure));
- super.visitLocalFunctionInvoke(
- node, function, arguments, callStructure, arg);
- }
-
- @override
- visitLocalVariableGet(
- Send node,
- LocalVariableElement variable,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_GET,
- element: variable));
- }
-
- @override
- visitLocalVariableInvoke(
- Send node,
- LocalVariableElement variable,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_INVOKE,
- element: variable, arguments: arguments, selector: callStructure));
- apply(arguments, arg);
- }
-
- @override
- visitLocalVariableSet(
- SendSet node,
- LocalVariableElement variable,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET,
- element: variable, rhs: rhs));
- super.visitLocalVariableSet(node, variable, rhs, arg);
- }
-
- @override
- visitFinalLocalVariableSet(
- SendSet node,
- LocalVariableElement variable,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET,
- element: variable, rhs: rhs));
- super.visitFinalLocalVariableSet(node, variable, rhs, arg);
- }
-
- @override
- visitParameterGet(
- Send node,
- ParameterElement parameter,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_PARAMETER_GET, element: parameter));
- }
-
- @override
- visitParameterInvoke(
- Send node,
- ParameterElement parameter,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_PARAMETER_INVOKE,
- element: parameter, arguments: arguments, selector: callStructure));
- apply(arguments, arg);
- }
-
- @override
- visitParameterSet(
- SendSet node,
- ParameterElement parameter,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_PARAMETER_SET,
- element: parameter, rhs: rhs));
- super.visitParameterSet(node, parameter, rhs, arg);
- }
-
- @override
- visitFinalParameterSet(
- SendSet node,
- ParameterElement parameter,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_SET,
- element: parameter, rhs: rhs));
- super.visitFinalParameterSet(node, parameter, rhs, arg);
- }
-
- @override
- visitStaticFieldGet(
- Send node,
- FieldElement field,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_GET, element: field));
- }
-
- @override
- visitStaticFieldInvoke(
- Send node,
- FieldElement field,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
- element: field, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitStaticFieldSet(
- SendSet node,
- FieldElement field,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_SET,
- element: field, rhs: rhs));
- super.visitStaticFieldSet(node, field, rhs, arg);
- }
-
- @override
- visitFinalStaticFieldSet(
- SendSet node,
- FieldElement field,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_STATIC_FIELD_SET,
- element: field, rhs: rhs));
- super.visitFinalStaticFieldSet(node, field, rhs, arg);
- }
-
- @override
- visitStaticFunctionGet(
- Send node,
- MethodElement function,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
- element: function));
- }
-
- @override
- visitStaticFunctionSet(
- SendSet node,
- MethodElement function,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_SET,
- element: function, rhs: rhs));
- super.visitStaticFunctionSet(node, function, rhs, arg);
- }
-
- @override
- visitStaticFunctionInvoke(
- Send node,
- MethodElement function,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
- element: function, arguments: arguments));
- super.visitStaticFunctionInvoke(
- node, function, arguments, callStructure, arg);
- }
-
- @override
- visitStaticFunctionIncompatibleInvoke(
- Send node,
- MethodElement function,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,
- element: function, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitStaticGetterGet(
- Send node,
- FunctionElement getter,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_GET,
- element: getter));
- super.visitStaticGetterGet(node, getter, arg);
- }
-
- @override
- visitStaticGetterSet(
- SendSet node,
- MethodElement getter,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SET,
- element: getter, rhs: rhs));
- super.visitStaticGetterSet(node, getter, rhs, arg);
- }
-
- @override
- visitStaticGetterInvoke(
- Send node,
- FunctionElement getter,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
- element: getter, arguments: arguments));
- super.visitStaticGetterInvoke(node, getter, arguments, callStructure, arg);
- }
-
- @override
- visitStaticSetterInvoke(
- Send node,
- FunctionElement setter,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
- element: setter, arguments: arguments));
- super.visitStaticSetterInvoke(node, setter, arguments, callStructure, arg);
- }
-
- @override
- visitStaticSetterGet(
- Send node,
- FunctionElement getter,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_GET,
- element: getter));
- super.visitStaticSetterGet(node, getter, arg);
- }
-
- @override
- visitStaticSetterSet(
- SendSet node,
- FunctionElement setter,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_SET,
- element: setter, rhs: rhs));
- super.visitStaticSetterSet(node, setter, rhs, arg);
- }
-
- @override
- visitSuperBinary(
- Send node,
- FunctionElement function,
- BinaryOperator operator,
- Node argument,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_BINARY,
- element: function, operator: operator, right: argument));
- apply(argument, arg);
- }
-
- @override
- visitUnresolvedSuperBinary(
- Send node,
- Element element,
- BinaryOperator operator,
- Node argument,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_BINARY,
- operator: operator, right: argument));
- apply(argument, arg);
- }
-
- @override
- visitSuperIndex(
- Send node,
- FunctionElement function,
- Node index,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX,
- element: function, index: index));
- apply(index, arg);
- }
-
- @override
- visitUnresolvedSuperIndex(
- Send node,
- Element element,
- Node index,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX,
- index: index));
- apply(index, arg);
- }
-
- @override
- visitSuperNotEquals(
- Send node,
- FunctionElement function,
- Node argument,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,
- element: function, right: argument));
- apply(argument, arg);
- }
-
- @override
- visitThisGet(Identifier node, arg) {
- visits.add(new Visit(VisitKind.VISIT_THIS_GET));
- }
-
- @override
- visitThisInvoke(
- Send node,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_THIS_INVOKE, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitThisPropertyGet(
- Send node,
- Selector selector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
- name: selector.name));
- }
-
- @override
- visitThisPropertyInvoke(
- Send node,
- NodeList arguments,
- Selector selector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,
- name: selector.name, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitThisPropertySet(
- SendSet node,
- Selector selector,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
- name: selector.name, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitTopLevelFieldGet(
- Send node,
- FieldElement field,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET, element: field));
- }
-
- @override
- visitTopLevelFieldInvoke(
- Send node,
- FieldElement field,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
- element: field, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitTopLevelFieldSet(
- SendSet node,
- FieldElement field,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
- element: field, rhs: rhs));
- super.visitTopLevelFieldSet(node, field, rhs, arg);
- }
-
- @override
- visitFinalTopLevelFieldSet(
- SendSet node,
- FieldElement field,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_TOP_LEVEL_FIELD_SET,
- element: field, rhs: rhs));
- super.visitFinalTopLevelFieldSet(node, field, rhs, arg);
- }
-
- @override
- visitTopLevelFunctionGet(
- Send node,
- MethodElement function,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_GET,
- element: function));
- }
-
- @override
- visitTopLevelFunctionSet(
- SendSet node,
- MethodElement function,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_SET,
- element: function, rhs: rhs));
- super.visitTopLevelFunctionSet(node, function, rhs, arg);
- }
-
- @override
- visitTopLevelFunctionInvoke(
- Send node,
- MethodElement function,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,
- element: function, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitTopLevelFunctionIncompatibleInvoke(
- Send node,
- MethodElement function,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,
- element: function, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitTopLevelGetterGet(
- Send node,
- FunctionElement getter,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,
- element: getter));
- super.visitTopLevelGetterGet(node, getter, arg);
- }
-
- @override
- visitTopLevelSetterGet(
- Send node,
- FunctionElement setter,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_GET,
- element: setter));
- super.visitTopLevelSetterGet(node, setter, arg);
- }
-
- @override
- visitTopLevelGetterInvoke(
- Send node,
- FunctionElement getter,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,
- element: getter, arguments: arguments));
- super.visitTopLevelGetterInvoke(
- node, getter, arguments, callStructure, arg);
- }
-
- @override
- visitTopLevelSetterInvoke(
- Send node,
- FunctionElement setter,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_INVOKE,
- element: setter, arguments: arguments));
- super.visitTopLevelSetterInvoke(
- node, setter, arguments, callStructure, arg);
- }
-
- @override
- visitTopLevelGetterSet(
- SendSet node,
- FunctionElement getter,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SET,
- element: getter, rhs: rhs));
- super.visitTopLevelGetterSet(node, getter, rhs, arg);
- }
-
- @override
- visitTopLevelSetterSet(
- SendSet node,
- FunctionElement setter,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,
- element: setter, rhs: rhs));
- super.visitTopLevelSetterSet(node, setter, rhs, arg);
- }
-
- @override
- visitTypeVariableTypeLiteralGet(
- Send node,
- TypeVariableElement element,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,
- element: element));
- }
-
- @override
- visitTypeVariableTypeLiteralInvoke(
- Send node,
- TypeVariableElement element,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,
- element: element, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitTypeVariableTypeLiteralSet(
- SendSet node,
- TypeVariableElement element,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,
- element: element, rhs: rhs));
- super.visitTypeVariableTypeLiteralSet(node, element, rhs, arg);
- }
-
- @override
- visitTypedefTypeLiteralGet(
- Send node,
- ConstantExpression constant,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_GET,
- constant: constant.getText()));
- }
-
- @override
- visitTypedefTypeLiteralInvoke(
- Send node,
- ConstantExpression constant,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
- constant: constant.getText(), arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitTypedefTypeLiteralSet(
- SendSet node,
- ConstantExpression constant,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,
- constant: constant.getText(), rhs: rhs));
- super.visitTypedefTypeLiteralSet(node, constant, rhs, arg);
- }
-
- @override
- visitUnary(
- Send node,
- UnaryOperator operator,
- Node expression,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNARY,
- expression: expression, operator: operator));
- super.visitUnary(node, operator, expression, arg);
- }
-
- @override
- errorUndefinedUnaryExpression(
- Send node,
- Operator operator,
- Node expression,
- arg) {
- visits.add(new Visit(VisitKind.ERROR_UNDEFINED_UNARY_EXPRESSION,
- expression: expression, operator: operator));
- super.errorUndefinedUnaryExpression(node, operator, expression, arg);
- }
-
- @override
- visitNot(
- Send node,
- Node expression,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_NOT, expression: expression));
- apply(expression, arg);
- }
-
- @override
- visitSuperFieldGet(
- Send node,
- FieldElement field,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_GET, element: field));
- }
-
- @override
- visitUnresolvedSuperGet(
- Send node,
- Element element,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GET));
- }
-
- @override
- visitSuperFieldInvoke(
- Send node,
- FieldElement field,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_INVOKE,
- element: field, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitUnresolvedSuperInvoke(
- Send node,
- Element element,
- NodeList arguments,
- Selector selector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INVOKE,
- arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitSuperFieldSet(
- SendSet node,
- FieldElement field,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SET,
- element: field, rhs: rhs));
- super.visitSuperFieldSet(node, field, rhs, arg);
- }
-
- @override
- visitFinalSuperFieldSet(
- SendSet node,
- FieldElement field,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_SUPER_FIELD_SET,
- element: field, rhs: rhs));
- super.visitFinalSuperFieldSet(node, field, rhs, arg);
- }
-
- @override
- visitSuperMethodGet(
- Send node,
- MethodElement method,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_GET, element: method));
- }
-
- @override
- visitSuperMethodSet(
- SendSet node,
- MethodElement method,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SET,
- element: method, rhs: rhs));
- super.visitSuperMethodSet(node, method, rhs, arg);
- }
-
- @override
- visitSuperMethodInvoke(
- Send node,
- MethodElement method,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_INVOKE,
- element: method, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitSuperMethodIncompatibleInvoke(
- Send node,
- MethodElement method,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,
- element: method, arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitSuperGetterGet(
- Send node,
- FunctionElement getter,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_GET, element: getter));
- super.visitSuperGetterGet(node, getter, arg);
- }
-
- @override
- visitSuperSetterGet(
- Send node,
- FunctionElement setter,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_GET, element: setter));
- super.visitSuperSetterGet(node, setter, arg);
- }
-
- @override
- visitSuperGetterInvoke(
- Send node,
- FunctionElement getter,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,
- element: getter, arguments: arguments));
- super.visitSuperGetterInvoke(node, getter, arguments, callStructure, arg);
- }
-
- @override
- visitSuperSetterInvoke(
- Send node,
- FunctionElement setter,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_INVOKE,
- element: setter, arguments: arguments));
- super.visitSuperSetterInvoke(node, setter, arguments, callStructure, arg);
- }
-
- @override
- visitSuperGetterSet(
- SendSet node,
- FunctionElement getter,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SET,
- element: getter, rhs: rhs));
- super.visitSuperGetterSet(node, getter, rhs, arg);
- }
-
- @override
- visitSuperSetterSet(
- SendSet node,
- FunctionElement setter,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_SET,
- element: setter, rhs: rhs));
- super.visitSuperSetterSet(node, setter, rhs, arg);
- }
-
- @override
- visitSuperUnary(
- Send node,
- UnaryOperator operator,
- FunctionElement function,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_UNARY,
- element: function, operator: operator));
- }
-
- @override
- visitUnresolvedSuperUnary(
- Send node,
- UnaryOperator operator,
- Element element,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_UNARY,
- operator: operator));
- }
-
- @override
- visitEquals(
- Send node,
- Node left,
- Node right,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_EQUALS, left: left, right: right));
- apply(left, arg);
- apply(right, arg);
- }
-
- @override
- visitSuperEquals(
- Send node,
- FunctionElement function,
- Node argument,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_EQUALS,
- element: function, right: argument));
- apply(argument, arg);
- }
-
- @override
- visitIndexSet(
- Send node,
- Node receiver,
- Node index,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_INDEX_SET,
- receiver: receiver, index: index, rhs: rhs));
- apply(receiver, arg);
- apply(index, arg);
- apply(rhs, arg);
- }
-
- @override
- visitSuperIndexSet(
- Send node,
- FunctionElement function,
- Node index,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_SET,
- element: function, index: index, rhs: rhs));
- apply(index, arg);
- apply(rhs, arg);
- }
-
- @override
- visitDynamicPropertyCompound(
- Send node,
- Node receiver,
- AssignmentOperator operator,
- Node rhs,
- Selector getterSelector,
- Selector setterSelector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_COMPOUND,
- receiver: receiver, operator: operator, rhs: rhs,
- getter: getterSelector, setter: setterSelector));
- apply(receiver, arg);
- apply(rhs, arg);
- }
-
- @override
- visitFinalLocalVariableCompound(
- Send node,
- LocalVariableElement variable,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,
- element: variable, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitFinalLocalVariablePrefix(
- Send node,
- LocalVariableElement variable,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_PREFIX,
- element: variable, operator: operator));
- }
-
- @override
- visitFinalLocalVariablePostfix(
- Send node,
- LocalVariableElement variable,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,
- element: variable, operator: operator));
- }
-
- @override
- visitFinalParameterCompound(
- Send node,
- ParameterElement parameter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_COMPOUND,
- element: parameter, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitFinalParameterPrefix(
- Send node,
- ParameterElement parameter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_PREFIX,
- element: parameter, operator: operator));
- }
-
- @override
- visitFinalParameterPostfix(
- Send node,
- ParameterElement parameter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_POSTFIX,
- element: parameter, operator: operator));
- }
-
- @override
- visitFinalStaticFieldCompound(
- Send node,
- FieldElement field,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_COMPOUND,
- element: field, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitFinalStaticFieldPostfix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_POSTFIX,
- element: field, operator: operator));
- }
-
- @override
- visitFinalStaticFieldPrefix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_PREFIX,
- element: field, operator: operator));
- }
-
- @override
- visitFinalSuperFieldCompound(
- Send node,
- FieldElement field,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,
- element: field, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitFinalTopLevelFieldCompound(
- Send node,
- FieldElement field,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,
- element: field, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitFinalTopLevelFieldPostfix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,
- element: field, operator: operator));
- }
-
- @override
- visitFinalTopLevelFieldPrefix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,
- element: field, operator: operator));
- }
-
- @override
- visitLocalFunctionCompound(
- Send node,
- LocalFunctionElement function,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_COMPOUND,
- element: function, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitLocalVariableCompound(
- Send node,
- LocalVariableElement variable,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_COMPOUND,
- element: variable, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitParameterCompound(
- Send node,
- ParameterElement parameter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_PARAMETER_COMPOUND,
- element: parameter, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitStaticFieldCompound(
- Send node,
- FieldElement field,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
- element: field, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitStaticGetterSetterCompound(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
- operator: operator, rhs: rhs,
- getter: getter, setter: setter));
- apply(rhs, arg);
- }
-
- @override
- visitSuperFieldCompound(
- Send node,
- FieldElement field,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_COMPOUND,
- element: field, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitSuperGetterSetterCompound(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,
- operator: operator, rhs: rhs,
- getter: getter, setter: setter));
- apply(rhs, arg);
- }
-
- @override
- visitThisPropertyCompound(
- Send node,
- AssignmentOperator operator,
- Node rhs,
- Selector getterSelector,
- Selector setterSelector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,
- operator: operator, rhs: rhs,
- getter: getterSelector, setter: setterSelector));
- apply(rhs, arg);
- }
-
- @override
- visitTopLevelFieldCompound(
- Send node,
- FieldElement field,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_COMPOUND,
- element: field, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitTopLevelGetterSetterCompound(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,
- operator: operator, rhs: rhs,
- getter: getter, setter: setter));
- apply(rhs, arg);
- }
-
- @override
- visitStaticMethodSetterCompound(
- Send node,
- FunctionElement method,
- FunctionElement setter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
- operator: operator, rhs: rhs,
- getter: method, setter: setter));
- apply(rhs, arg);
- }
-
- @override
- visitSuperFieldSetterCompound(
- Send node,
- FieldElement field,
- FunctionElement setter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_COMPOUND,
- operator: operator, rhs: rhs,
- getter: field, setter: setter));
- apply(rhs, arg);
- }
-
- @override
- visitSuperGetterFieldCompound(
- Send node,
- FunctionElement getter,
- FieldElement field,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_COMPOUND,
- operator: operator, rhs: rhs,
- getter: getter, setter: field));
- apply(rhs, arg);
- }
-
- @override
- visitSuperMethodSetterCompound(
- Send node,
- FunctionElement method,
- FunctionElement setter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_COMPOUND,
- getter: method, setter: setter, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitSuperMethodCompound(
- Send node,
- FunctionElement method,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_COMPOUND,
- element: method, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitSuperMethodPrefix(
- Send node,
- FunctionElement method,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_PREFIX,
- element: method, operator: operator));
- }
-
- @override
- visitSuperMethodPostfix(
- Send node,
- FunctionElement method,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_POSTFIX,
- element: method, operator: operator));
- }
-
- @override
- visitUnresolvedSuperCompound(
- Send node,
- Element element,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND,
- operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedSuperPrefix(
- Send node,
- Element element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_PREFIX,
- operator: operator));
- }
-
- @override
- visitUnresolvedSuperPostfix(
- Send node,
- Element element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_POSTFIX,
- operator: operator));
- }
-
- @override
- visitTopLevelMethodSetterCompound(
- Send node,
- FunctionElement method,
- FunctionElement setter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,
- getter: method, setter: setter, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitCompoundIndexSet(
- Send node,
- Node receiver,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_COMPOUND_INDEX_SET,
- receiver: receiver, index: index, rhs: rhs, operator: operator));
- apply(receiver, arg);
- apply(index, arg);
- apply(rhs, arg);
- }
-
- @override
- visitSuperCompoundIndexSet(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_COMPOUND_INDEX_SET,
- getter: getter, setter: setter,
- index: index, rhs: rhs, operator: operator));
- apply(index, arg);
- apply(rhs, arg);
- }
-
- @override
- visitClassTypeLiteralCompound(
- Send node,
- ConstantExpression constant,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,
- constant: constant.getText(), operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitDynamicTypeLiteralCompound(
- Send node,
- ConstantExpression constant,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,
- constant: constant.getText(), operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitTypeVariableTypeLiteralCompound(
- Send node,
- TypeVariableElement element,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,
- element: element, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitTypedefTypeLiteralCompound(
- Send node,
- ConstantExpression constant,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,
- constant: constant.getText(), operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitLocalFunctionPrefix(
- Send node,
- LocalFunctionElement function,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_PREFIX,
- element: function, operator: operator));
- }
-
- @override
- visitClassTypeLiteralPrefix(
- Send node,
- ConstantExpression constant,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,
- constant: constant.getText(), operator: operator));
- }
-
- @override
- visitDynamicTypeLiteralPrefix(
- Send node,
- ConstantExpression constant,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
- constant: constant.getText(), operator: operator));
- }
-
- @override
- visitLocalVariablePrefix(
- Send node,
- LocalVariableElement variable,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_PREFIX,
- element: variable, operator: operator));
- }
-
- @override
- visitParameterPrefix(
- Send node,
- ParameterElement parameter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_PARAMETER_PREFIX,
- element: parameter, operator: operator));
- }
-
- @override
- visitStaticFieldPrefix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
- element: field, operator: operator));
- }
-
- @override
- visitStaticGetterSetterPrefix(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
- getter: getter, setter: setter, operator: operator));
- }
-
- @override
- visitStaticMethodSetterPrefix(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_PREFIX,
- getter: getter, setter: setter, operator: operator));
- }
-
- @override
- visitSuperFieldFieldCompound(
- Send node,
- FieldElement readField,
- FieldElement writtenField,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
- getter: readField, setter: writtenField, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitSuperFieldFieldPrefix(
- Send node,
- FieldElement readField,
- FieldElement writtenField,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_PREFIX,
- getter: readField, setter: writtenField, operator: operator));
- }
-
- @override
- visitSuperFieldPrefix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_PREFIX,
- element: field, operator: operator));
- }
-
- @override
- visitFinalSuperFieldPrefix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_PREFIX,
- element: field, operator: operator));
- }
-
- @override
- visitSuperFieldSetterPrefix(
- Send node,
- FieldElement field,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,
- getter: field, setter: setter, operator: operator));
- }
-
- @override
- visitSuperGetterFieldPrefix(
- Send node,
- FunctionElement getter,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_PREFIX,
- getter: getter, setter: field, operator: operator));
- }
-
- @override
- visitSuperGetterSetterPrefix(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,
- getter: getter, setter: setter, operator: operator));
- }
-
- @override
- visitSuperMethodSetterPrefix(
- Send node,
- FunctionElement method,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_PREFIX,
- getter: method, setter: setter, operator: operator));
- }
-
- @override
- visitThisPropertyPrefix(
- Send node,
- IncDecOperator operator,
- Selector getterSelector,
- Selector setterSelector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,
- operator: operator,
- getter: getterSelector, setter: setterSelector));
- }
-
- @override
- visitTopLevelFieldPrefix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_PREFIX,
- element: field, operator: operator));
- }
-
- @override
- visitTopLevelGetterSetterPrefix(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,
- getter: getter, setter: setter, operator: operator));
- }
-
- @override
- visitTopLevelMethodSetterPrefix(
- Send node,
- FunctionElement method,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,
- getter: method, setter: setter, operator: operator));
- }
-
- @override
- visitTypeVariableTypeLiteralPrefix(
- Send node,
- TypeVariableElement element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,
- element: element, operator: operator));
- }
-
- @override
- visitTypedefTypeLiteralPrefix(
- Send node,
- ConstantExpression constant,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
- constant: constant.getText(), operator: operator));
- }
-
- @override
- visitLocalFunctionPostfix(
- Send node,
- LocalFunctionElement function,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_POSTFIX,
- element: function, operator: operator));
- }
-
- @override
- visitClassTypeLiteralPostfix(
- Send node,
- ConstantExpression constant,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,
- constant: constant.getText(), operator: operator));
- }
-
- @override
- visitDynamicTypeLiteralPostfix(
- Send node,
- ConstantExpression constant,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,
- constant: constant.getText(), operator: operator));
- }
-
- @override
- visitLocalVariablePostfix(
- Send node,
- LocalVariableElement variable,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_POSTFIX,
- element: variable, operator: operator));
- }
-
- @override
- visitParameterPostfix(
- Send node,
- ParameterElement parameter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_PARAMETER_POSTFIX,
- element: parameter, operator: operator));
- }
-
- @override
- visitStaticFieldPostfix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
- element: field, operator: operator));
- }
-
- @override
- visitStaticGetterSetterPostfix(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
- getter: getter, setter: setter, operator: operator));
- }
-
- @override
- visitStaticMethodSetterPostfix(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_POSTFIX,
- getter: getter, setter: setter, operator: operator));
- }
-
- @override
- visitSuperFieldFieldPostfix(
- Send node,
- FieldElement readField,
- FieldElement writtenField,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_POSTFIX,
- getter: readField, setter: writtenField, operator: operator));
- }
-
- @override
- visitSuperFieldPostfix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_POSTFIX,
- element: field, operator: operator));
- }
-
- @override
- visitFinalSuperFieldPostfix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_POSTFIX,
- element: field, operator: operator));
- }
-
- @override
- visitSuperFieldSetterPostfix(
- Send node,
- FieldElement field,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,
- getter: field, setter: setter, operator: operator));
- }
-
- @override
- visitSuperGetterFieldPostfix(
- Send node,
- FunctionElement getter,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_POSTFIX,
- getter: getter, setter: field, operator: operator));
- }
-
- @override
- visitSuperGetterSetterPostfix(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,
- getter: getter, setter: setter, operator: operator));
- }
-
- @override
- visitSuperMethodSetterPostfix(
- Send node,
- FunctionElement method,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_POSTFIX,
- getter: method, setter: setter, operator: operator));
- }
-
- @override
- visitThisPropertyPostfix(
- Send node,
- IncDecOperator operator,
- Selector getterSelector,
- Selector setterSelector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,
- operator: operator,
- getter: getterSelector, setter: setterSelector));
- }
-
- @override
- visitTopLevelFieldPostfix(
- Send node,
- FieldElement field,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_POSTFIX,
- element: field, operator: operator));
- }
-
- @override
- visitTopLevelGetterSetterPostfix(
- Send node,
- FunctionElement getter,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,
- getter: getter, setter: setter, operator: operator));
- }
-
- @override
- visitTopLevelMethodSetterPostfix(
- Send node,
- FunctionElement method,
- FunctionElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,
- getter: method, setter: setter, operator: operator));
- }
-
- @override
- visitTypeVariableTypeLiteralPostfix(
- Send node,
- TypeVariableElement element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,
- element: element, operator: operator));
- }
-
- @override
- visitTypedefTypeLiteralPostfix(
- Send node,
- ConstantExpression constant,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,
- constant: constant.getText(), operator: operator));
- }
-
- @override
- visitUnresolvedCompound(
- Send node,
- ErroneousElement element,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_COMPOUND,
- operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedGet(
- Send node,
- Element element,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_GET, name: element.name));
- }
-
- @override
- visitUnresolvedSet(
- Send node,
- Element element,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SET,
- name: element.name, rhs: rhs));
- super.visitUnresolvedSet(node, element, rhs, arg);
- }
-
- @override
- visitUnresolvedInvoke(
- Send node,
- Element element,
- NodeList arguments,
- Selector selector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
- name: element.name, arguments: arguments));
- super.visitUnresolvedInvoke(node, element, arguments, selector, arg);
- }
-
- @override
- visitUnresolvedPostfix(
- Send node,
- ErroneousElement element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_UNRESOLVED_POSTFIX, operator: operator));
- }
-
- @override
- visitUnresolvedPrefix(
- Send node,
- ErroneousElement element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_UNRESOLVED_PREFIX, operator: operator));
- }
-
- @override
- visitUnresolvedSuperCompoundIndexSet(
- Send node,
- Element element,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,
- index: index, operator: operator, rhs: rhs));
- apply(index, arg);
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedSuperGetterCompoundIndexSet(
- Send node,
- Element element,
- MethodElement setter,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,
- setter: setter, index: index, operator: operator, rhs: rhs));
- apply(index, arg);
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedSuperSetterCompoundIndexSet(
- Send node,
- MethodElement getter,
- Element element,
- Node index,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,
- getter: getter, index: index, operator: operator, rhs: rhs));
- apply(index, arg);
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedSuperIndexSet(
- Send node,
- ErroneousElement element,
- Node index,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_SET,
- index: index, rhs: rhs));
- apply(index, arg);
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedSuperIndexPostfix(
- Send node,
- Element element,
- Node index,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,
- index: index, operator: operator));
- apply(index, arg);
- }
-
- @override
- visitUnresolvedSuperGetterIndexPostfix(
- Send node,
- Element element,
- MethodElement setter,
- Node index,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,
- setter: setter, index: index, operator: operator));
- apply(index, arg);
- }
-
- @override
- visitUnresolvedSuperSetterIndexPostfix(
- Send node,
- MethodElement getter,
- Element element,
- Node index,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,
- getter: getter, index: index, operator: operator));
- apply(index, arg);
- }
-
- @override
- visitUnresolvedSuperIndexPrefix(
- Send node,
- Element element,
- Node index,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,
- index: index, operator: operator));
- apply(index, arg);
- }
-
- @override
- visitUnresolvedSuperGetterIndexPrefix(
- Send node,
- Element element,
- MethodElement setter,
- Node index,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,
- setter: setter, index: index, operator: operator));
- apply(index, arg);
- }
-
- @override
- visitUnresolvedSuperSetterIndexPrefix(
- Send node,
- MethodElement getter,
- Element element,
- Node index,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,
- getter: getter, index: index, operator: operator));
- apply(index, arg);
- }
-
- @override
- visitIndexPostfix(
- Send node,
- Node receiver,
- Node index,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_INDEX_POSTFIX,
- receiver: receiver, index: index, operator: operator));
- apply(receiver, arg);
- apply(index, arg);
- }
-
- @override
- visitIndexPrefix(
- Send node,
- Node receiver,
- Node index,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_INDEX_PREFIX,
- receiver: receiver, index: index, operator: operator));
- apply(receiver, arg);
- apply(index, arg);
- }
-
- @override
- visitSuperIndexPostfix(
- Send node,
- FunctionElement indexFunction,
- FunctionElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_POSTFIX,
- getter: indexFunction, setter: indexSetFunction,
- index: index, operator: operator));
- apply(index, arg);
- }
-
- @override
- visitSuperIndexPrefix(
- Send node,
- FunctionElement indexFunction,
- FunctionElement indexSetFunction,
- Node index,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_PREFIX,
- getter: indexFunction, setter: indexSetFunction,
- index: index, operator: operator));
- apply(index, arg);
- }
-
- @override
- visitUnresolvedClassConstructorInvoke(
- NewExpression node,
- Element constructor,
- DartType type,
- NodeList arguments,
- Selector selector,
- arg) {
- // TODO(johnniwinther): Test [type] when it is not `dynamic`.
- visits.add(new Visit(
- VisitKind.VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
- arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitUnresolvedConstructorInvoke(
- NewExpression node,
- Element constructor,
- DartType type,
- NodeList arguments,
- Selector selector,
- arg) {
- // TODO(johnniwinther): Test [type] when it is not `dynamic`.
- visits.add(new Visit(
- VisitKind.VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,
- arguments: arguments));
- apply(arguments, arg);
- }
-
- @override
- visitConstConstructorInvoke(
- NewExpression node,
- ConstructedConstantExpression constant,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,
- constant: constant.getText()));
- super.visitConstConstructorInvoke(node, constant, arg);
- }
-
- @override
- visitBoolFromEnvironmentConstructorInvoke(
- NewExpression node,
- BoolFromEnvironmentConstantExpression constant,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
- constant: constant.getText()));
- super.visitBoolFromEnvironmentConstructorInvoke(node, constant, arg);
- }
-
- @override
- visitIntFromEnvironmentConstructorInvoke(
- NewExpression node,
- IntFromEnvironmentConstantExpression constant,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
- constant: constant.getText()));
- super.visitIntFromEnvironmentConstructorInvoke(node, constant, arg);
- }
-
- @override
- visitStringFromEnvironmentConstructorInvoke(
- NewExpression node,
- StringFromEnvironmentConstantExpression constant,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
- constant: constant.getText()));
- super.visitStringFromEnvironmentConstructorInvoke(node, constant, arg);
- }
-
- @override
- errorNonConstantConstructorInvoke(
- NewExpression node,
- Element element,
- DartType type,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,
- element: element, type: type,
- arguments: arguments, selector: callStructure));
- super.errorNonConstantConstructorInvoke(
- node, element, type, arguments, callStructure, arg);
- }
-
- @override
- visitConstructorIncompatibleInvoke(
- NewExpression node,
- ConstructorElement constructor,
- InterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
- element: constructor, type: type,
- arguments: arguments, selector: callStructure));
- super.visitConstructorIncompatibleInvoke(
- node, constructor, type, arguments, callStructure, arg);
- }
-
- @override
- visitFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- InterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,
- element: constructor,
- type: type,
- arguments: arguments,
- selector: callStructure));
- apply(arguments, arg);
- }
-
- @override
- visitGenerativeConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- InterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
- element: constructor,
- type: type,
- arguments: arguments,
- selector: callStructure));
- apply(arguments, arg);
- }
-
- @override
- visitRedirectingFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- InterfaceType type,
- ConstructorElement effectiveTarget,
- InterfaceType effectiveTargetType,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- element: constructor,
- type: type,
- target: effectiveTarget,
- targetType: effectiveTargetType,
- arguments: arguments,
- selector: callStructure));
- apply(arguments, arg);
- }
-
- @override
- visitRedirectingGenerativeConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- InterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
- element: constructor,
- type: type,
- arguments: arguments,
- selector: callStructure));
- apply(arguments, arg);
- }
-
- @override
- visitAbstractClassConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- InterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
- element: constructor,
- type: type,
- arguments: arguments,
- selector: callStructure));
- apply(arguments, arg);
- }
-
- @override
- visitUnresolvedRedirectingFactoryConstructorInvoke(
- NewExpression node,
- ConstructorElement constructor,
- InterfaceType type,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(
- VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
- element: constructor,
- type: type,
- arguments: arguments,
- selector: callStructure));
- apply(arguments, arg);
- }
-
- @override
- visitUnresolvedStaticGetterCompound(
- Send node,
- Element element,
- MethodElement setter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,
- setter: setter, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedTopLevelGetterCompound(
- Send node,
- Element element,
- MethodElement setter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,
- setter: setter, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedStaticSetterCompound(
- Send node,
- MethodElement getter,
- Element element,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,
- getter: getter, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedTopLevelSetterCompound(
- Send node,
- MethodElement getter,
- Element element,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,
- getter: getter, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitStaticMethodCompound(
- Send node,
- MethodElement method,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_COMPOUND,
- element: method, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitTopLevelMethodCompound(
- Send node,
- MethodElement method,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_COMPOUND,
- element: method, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedStaticGetterPrefix(
- Send node,
- Element element,
- MethodElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,
- setter: setter, operator: operator));
- }
-
- @override
- visitUnresolvedTopLevelGetterPrefix(
- Send node,
- Element element,
- MethodElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,
- setter: setter, operator: operator));
- }
-
- @override
- visitUnresolvedStaticSetterPrefix(
- Send node,
- MethodElement getter,
- Element element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,
- getter: getter, operator: operator));
- }
-
- @override
- visitUnresolvedTopLevelSetterPrefix(
- Send node,
- MethodElement getter,
- Element element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,
- getter: getter, operator: operator));
- }
-
- @override
- visitStaticMethodPrefix(
- Send node,
- MethodElement method,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_PREFIX,
- element: method, operator: operator));
- }
-
- @override
- visitTopLevelMethodPrefix(
- Send node,
- MethodElement method,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_PREFIX,
- element: method, operator: operator));
- }
-
- @override
- visitUnresolvedStaticGetterPostfix(
- Send node,
- Element element,
- MethodElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,
- setter: setter, operator: operator));
- }
-
- @override
- visitUnresolvedTopLevelGetterPostfix(
- Send node,
- Element element,
- MethodElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,
- setter: setter, operator: operator));
- }
-
- @override
- visitUnresolvedStaticSetterPostfix(
- Send node,
- MethodElement getter,
- Element element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,
- getter: getter, operator: operator));
- }
-
- @override
- visitUnresolvedTopLevelSetterPostfix(
- Send node,
- MethodElement getter,
- Element element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,
- getter: getter, operator: operator));
- }
-
- @override
- visitStaticMethodPostfix(
- Send node,
- MethodElement method,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_POSTFIX,
- element: method, operator: operator));
- }
-
- @override
- visitTopLevelMethodPostfix(
- Send node,
- MethodElement method,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_POSTFIX,
- element: method, operator: operator));
- }
-
- @override
- visitUnresolvedSuperGetterCompound(
- Send node, Element element,
- MethodElement setter,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,
- setter: setter, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedSuperGetterPostfix(
- Send node,
- Element element,
- MethodElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,
- setter: setter, operator: operator));
- }
-
- @override
- visitUnresolvedSuperGetterPrefix(
- Send node,
- Element element,
- MethodElement setter,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,
- setter: setter, operator: operator));
- }
-
- @override
- visitUnresolvedSuperSetterCompound(
- Send node, MethodElement getter,
- Element element,
- AssignmentOperator operator,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,
- getter: getter, operator: operator, rhs: rhs));
- apply(rhs, arg);
- }
-
- @override
- visitUnresolvedSuperSetterPostfix(
- Send node,
- MethodElement getter,
- Element element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,
- getter: getter, operator: operator));
- }
-
- @override
- visitUnresolvedSuperSetterPrefix(
- Send node,
- MethodElement getter,
- Element element,
- IncDecOperator operator,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,
- getter: getter, operator: operator));
- }
-
- @override
- visitIfNotNullDynamicPropertyGet(
- Send node,
- Node receiver,
- Selector selector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
- receiver: receiver, name: selector.name));
- super.visitIfNotNullDynamicPropertyGet(node, receiver, selector, arg);
- }
-
- @override
- visitIfNotNullDynamicPropertySet(
- Send node,
- Node receiver,
- Selector selector,
- Node rhs,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,
- receiver: receiver, name: selector.name, rhs: rhs));
- super.visitIfNotNullDynamicPropertySet(node, receiver, selector, rhs, arg);
- }
-
- @override
- visitIfNotNullDynamicPropertyInvoke(
- Send node,
- Node receiver,
- NodeList arguments,
- Selector selector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,
- receiver: receiver, selector: selector, arguments: arguments));
- super.visitIfNotNullDynamicPropertyInvoke(
- node, receiver, arguments, selector, arg);
- }
-
- @override
- visitIfNotNullDynamicPropertyPrefix(
- Send node,
- Node receiver,
- IncDecOperator operator,
- Selector getterSelector,
- Selector setterSelector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,
- receiver: receiver, operator: operator,
- getter: getterSelector, setter: setterSelector));
- super.visitIfNotNullDynamicPropertyPrefix(
- node, receiver, operator, getterSelector, setterSelector, arg);
- }
-
- @override
- visitIfNotNullDynamicPropertyPostfix(
- Send node,
- Node receiver,
- IncDecOperator operator,
- Selector getterSelector,
- Selector setterSelector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,
- receiver: receiver, operator: operator,
- getter: getterSelector, setter: setterSelector));
- super.visitIfNotNullDynamicPropertyPostfix(
- node, receiver, operator, getterSelector, setterSelector, arg);
- }
-
- @override
- visitIfNotNullDynamicPropertyCompound(
- Send node,
- Node receiver,
- AssignmentOperator operator,
- Node rhs,
- Selector getterSelector,
- Selector setterSelector,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,
- receiver: receiver, operator: operator, rhs: rhs,
- getter: getterSelector, setter: setterSelector));
- super.visitIfNotNullDynamicPropertyCompound(
- node, receiver, operator, rhs, getterSelector, setterSelector, arg);
- }
-
- @override
- visitIfNull(
- Send node,
- Node left,
- Node right,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_IF_NULL, left: left, right: right));
- super.visitIfNull(node, left, right, arg);
- }
-
- @override
- visitConstantGet(
- Send node,
- ConstantExpression constant,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CONSTANT_GET,
- constant: constant.getText()));
- super.visitConstantGet(node, constant, arg);
- }
-
- @override
- visitConstantInvoke(
- Send node,
- ConstantExpression constant,
- NodeList arguments,
- CallStructure callStructure,
- arg) {
- visits.add(new Visit(VisitKind.VISIT_CONSTANT_INVOKE,
- constant: constant.getText()));
- super.visitConstantInvoke(node, constant, arguments, callStructure, arg);
- }
-}
+// 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_test;
+
+class SemanticSendTestVisitor extends SemanticTestVisitor {
+
+ SemanticSendTestVisitor(TreeElements elements) : super(elements);
+
+ @override
+ visitAs(
+ Send node,
+ Node expression,
+ DartType type,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_AS,
+ expression: expression, type: type));
+ apply(expression, arg);
+ }
+
+ @override
+ visitAssert(
+ Send node,
+ Node expression,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_ASSERT, expression: expression));
+ super.visitAssert(node, expression, arg);
+ }
+
+ @override
+ errorInvalidAssert(
+ Send node,
+ NodeList arguments,
+ arg) {
+ visits.add(new Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: arguments));
+ super.errorInvalidAssert(node, arguments, arg);
+ }
+
+ @override
+ visitBinary(
+ Send node,
+ Node left,
+ BinaryOperator operator,
+ Node right,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_BINARY,
+ left: left, operator: operator, right: right));
+ super.visitBinary(node, left, operator, right, arg);
+ }
+
+ @override
+ errorUndefinedBinaryExpression(
+ Send node,
+ Node left,
+ Operator operator,
+ Node right,
+ arg) {
+ visits.add(new Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,
+ left: left, operator: operator, right: right));
+ super.errorUndefinedBinaryExpression(node, left, operator, right, arg);
+ }
+
+ @override
+ visitIndex(
+ Send node,
+ Node receiver,
+ Node index,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_INDEX,
+ receiver: receiver, index: index));
+ apply(receiver, arg);
+ apply(index, arg);
+ }
+
+ @override
+ visitClassTypeLiteralGet(
+ Send node,
+ ConstantExpression constant,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
+ constant: constant.getText()));
+ }
+
+ @override
+ visitClassTypeLiteralInvoke(
+ Send node,
+ ConstantExpression constant,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
+ constant: constant.getText(), arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitClassTypeLiteralSet(
+ SendSet node,
+ ConstantExpression constant,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
+ constant: constant.getText(), rhs: rhs));
+ super.visitClassTypeLiteralSet(node, constant, rhs, arg);
+ }
+
+ @override
+ visitNotEquals(
+ Send node,
+ Node left,
+ Node right,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_NOT_EQUALS,
+ left: left, right: right));
+ apply(left, arg);
+ apply(right, arg);
+ }
+
+ @override
+ visitDynamicPropertyPrefix(
+ Send node,
+ Node receiver,
+ IncDecOperator operator,
+ Selector getterSelector,
+ Selector setterSelector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_PREFIX,
+ receiver: receiver, operator: operator,
+ getter: getterSelector, setter: setterSelector));
+ apply(receiver, arg);
+ }
+
+ @override
+ visitDynamicPropertyPostfix(
+ Send node,
+ Node receiver,
+ IncDecOperator operator,
+ Selector getterSelector,
+ Selector setterSelector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_POSTFIX,
+ receiver: receiver, operator: operator,
+ getter: getterSelector, setter: setterSelector));
+ apply(receiver, arg);
+ }
+
+ @override
+ visitDynamicPropertyGet(
+ Send node,
+ Node receiver,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
+ receiver: receiver, name: selector.name));
+ apply(receiver, arg);
+ }
+
+ @override
+ visitDynamicPropertyInvoke(
+ Send node,
+ Node receiver,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,
+ receiver: receiver, name: selector.name, arguments: arguments));
+ apply(receiver, arg);
+ apply(arguments, arg);
+ }
+
+ @override
+ visitDynamicPropertySet(
+ SendSet node,
+ Node receiver,
+ Selector selector,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,
+ receiver: receiver, name: selector.name, rhs: rhs));
+ super.visitDynamicPropertySet(node, receiver, selector, rhs, arg);
+ }
+
+ @override
+ visitDynamicTypeLiteralGet(
+ Send node,
+ ConstantExpression constant,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,
+ constant: constant.getText()));
+ }
+
+ @override
+ visitDynamicTypeLiteralInvoke(
+ Send node,
+ ConstantExpression constant,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
+ constant: constant.getText(), arguments: arguments));
+ }
+
+ @override
+ visitDynamicTypeLiteralSet(
+ Send node,
+ ConstantExpression constant,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,
+ rhs: rhs));
+ super.visitDynamicTypeLiteralSet(node, constant, rhs, arg);
+ }
+
+ @override
+ visitExpressionInvoke(
+ Send node,
+ Node expression,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_EXPRESSION_INVOKE,
+ receiver: expression, arguments: arguments));
+ }
+
+ @override
+ visitIs(
+ Send node,
+ Node expression,
+ DartType type,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_IS,
+ expression: expression, type: type));
+ apply(expression, arg);
+ }
+
+ @override
+ visitIsNot(
+ Send node,
+ Node expression,
+ DartType type,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_IS_NOT,
+ expression: expression, type: type));
+ apply(expression, arg);
+ }
+
+ @override
+ visitLogicalAnd(
+ Send node,
+ Node left,
+ Node right,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOGICAL_AND,
+ left: left, right: right));
+ apply(left, arg);
+ apply(right, arg);
+ }
+
+ @override
+ visitLogicalOr(
+ Send node,
+ Node left,
+ Node right,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOGICAL_OR,
+ left: left, right: right));
+ apply(left, arg);
+ apply(right, arg);
+ }
+
+ @override
+ visitLocalFunctionGet(
+ Send node,
+ LocalFunctionElement function,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_GET,
+ element: function));
+ }
+
+ @override
+ visitLocalFunctionSet(
+ SendSet node,
+ LocalFunctionElement function,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_SET,
+ element: function, rhs: rhs));
+ super.visitLocalFunctionSet(node, function, rhs, arg);
+ }
+
+ @override
+ visitLocalFunctionInvoke(
+ Send node,
+ LocalFunctionElement function,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_INVOKE,
+ element: function, arguments: arguments, selector: callStructure));
+ super.visitLocalFunctionInvoke(
+ node, function, arguments, callStructure, arg);
+ }
+
+ @override
+ visitLocalFunctionIncompatibleInvoke(
+ Send node,
+ LocalFunctionElement function,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,
+ element: function, arguments: arguments, selector: callStructure));
+ super.visitLocalFunctionInvoke(
+ node, function, arguments, callStructure, arg);
+ }
+
+ @override
+ visitLocalVariableGet(
+ Send node,
+ LocalVariableElement variable,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_GET,
+ element: variable));
+ }
+
+ @override
+ visitLocalVariableInvoke(
+ Send node,
+ LocalVariableElement variable,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_INVOKE,
+ element: variable, arguments: arguments, selector: callStructure));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitLocalVariableSet(
+ SendSet node,
+ LocalVariableElement variable,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET,
+ element: variable, rhs: rhs));
+ super.visitLocalVariableSet(node, variable, rhs, arg);
+ }
+
+ @override
+ visitFinalLocalVariableSet(
+ SendSet node,
+ LocalVariableElement variable,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET,
+ element: variable, rhs: rhs));
+ super.visitFinalLocalVariableSet(node, variable, rhs, arg);
+ }
+
+ @override
+ visitParameterGet(
+ Send node,
+ ParameterElement parameter,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_PARAMETER_GET, element: parameter));
+ }
+
+ @override
+ visitParameterInvoke(
+ Send node,
+ ParameterElement parameter,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_PARAMETER_INVOKE,
+ element: parameter, arguments: arguments, selector: callStructure));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitParameterSet(
+ SendSet node,
+ ParameterElement parameter,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_PARAMETER_SET,
+ element: parameter, rhs: rhs));
+ super.visitParameterSet(node, parameter, rhs, arg);
+ }
+
+ @override
+ visitFinalParameterSet(
+ SendSet node,
+ ParameterElement parameter,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_SET,
+ element: parameter, rhs: rhs));
+ super.visitFinalParameterSet(node, parameter, rhs, arg);
+ }
+
+ @override
+ visitStaticFieldGet(
+ Send node,
+ FieldElement field,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_GET, element: field));
+ }
+
+ @override
+ visitStaticFieldInvoke(
+ Send node,
+ FieldElement field,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
+ element: field, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitStaticFieldSet(
+ SendSet node,
+ FieldElement field,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_SET,
+ element: field, rhs: rhs));
+ super.visitStaticFieldSet(node, field, rhs, arg);
+ }
+
+ @override
+ visitFinalStaticFieldSet(
+ SendSet node,
+ FieldElement field,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_STATIC_FIELD_SET,
+ element: field, rhs: rhs));
+ super.visitFinalStaticFieldSet(node, field, rhs, arg);
+ }
+
+ @override
+ visitStaticFunctionGet(
+ Send node,
+ MethodElement function,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
+ element: function));
+ }
+
+ @override
+ visitStaticFunctionSet(
+ SendSet node,
+ MethodElement function,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_SET,
+ element: function, rhs: rhs));
+ super.visitStaticFunctionSet(node, function, rhs, arg);
+ }
+
+ @override
+ visitStaticFunctionInvoke(
+ Send node,
+ MethodElement function,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
+ element: function, arguments: arguments));
+ super.visitStaticFunctionInvoke(
+ node, function, arguments, callStructure, arg);
+ }
+
+ @override
+ visitStaticFunctionIncompatibleInvoke(
+ Send node,
+ MethodElement function,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,
+ element: function, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitStaticGetterGet(
+ Send node,
+ FunctionElement getter,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_GET,
+ element: getter));
+ super.visitStaticGetterGet(node, getter, arg);
+ }
+
+ @override
+ visitStaticGetterSet(
+ SendSet node,
+ MethodElement getter,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SET,
+ element: getter, rhs: rhs));
+ super.visitStaticGetterSet(node, getter, rhs, arg);
+ }
+
+ @override
+ visitStaticGetterInvoke(
+ Send node,
+ FunctionElement getter,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
+ element: getter, arguments: arguments));
+ super.visitStaticGetterInvoke(node, getter, arguments, callStructure, arg);
+ }
+
+ @override
+ visitStaticSetterInvoke(
+ Send node,
+ FunctionElement setter,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
+ element: setter, arguments: arguments));
+ super.visitStaticSetterInvoke(node, setter, arguments, callStructure, arg);
+ }
+
+ @override
+ visitStaticSetterGet(
+ Send node,
+ FunctionElement getter,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_GET,
+ element: getter));
+ super.visitStaticSetterGet(node, getter, arg);
+ }
+
+ @override
+ visitStaticSetterSet(
+ SendSet node,
+ FunctionElement setter,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_SET,
+ element: setter, rhs: rhs));
+ super.visitStaticSetterSet(node, setter, rhs, arg);
+ }
+
+ @override
+ visitSuperBinary(
+ Send node,
+ FunctionElement function,
+ BinaryOperator operator,
+ Node argument,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_BINARY,
+ element: function, operator: operator, right: argument));
+ apply(argument, arg);
+ }
+
+ @override
+ visitUnresolvedSuperBinary(
+ Send node,
+ Element element,
+ BinaryOperator operator,
+ Node argument,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_BINARY,
+ operator: operator, right: argument));
+ apply(argument, arg);
+ }
+
+ @override
+ visitSuperIndex(
+ Send node,
+ FunctionElement function,
+ Node index,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX,
+ element: function, index: index));
+ apply(index, arg);
+ }
+
+ @override
+ visitUnresolvedSuperIndex(
+ Send node,
+ Element element,
+ Node index,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX,
+ index: index));
+ apply(index, arg);
+ }
+
+ @override
+ visitSuperNotEquals(
+ Send node,
+ FunctionElement function,
+ Node argument,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,
+ element: function, right: argument));
+ apply(argument, arg);
+ }
+
+ @override
+ visitThisGet(Identifier node, arg) {
+ visits.add(new Visit(VisitKind.VISIT_THIS_GET));
+ }
+
+ @override
+ visitThisInvoke(
+ Send node,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_THIS_INVOKE, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitThisPropertyGet(
+ Send node,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
+ name: selector.name));
+ }
+
+ @override
+ visitThisPropertyInvoke(
+ Send node,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,
+ name: selector.name, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitThisPropertySet(
+ SendSet node,
+ Selector selector,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
+ name: selector.name, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitTopLevelFieldGet(
+ Send node,
+ FieldElement field,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET, element: field));
+ }
+
+ @override
+ visitTopLevelFieldInvoke(
+ Send node,
+ FieldElement field,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
+ element: field, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitTopLevelFieldSet(
+ SendSet node,
+ FieldElement field,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
+ element: field, rhs: rhs));
+ super.visitTopLevelFieldSet(node, field, rhs, arg);
+ }
+
+ @override
+ visitFinalTopLevelFieldSet(
+ SendSet node,
+ FieldElement field,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_TOP_LEVEL_FIELD_SET,
+ element: field, rhs: rhs));
+ super.visitFinalTopLevelFieldSet(node, field, rhs, arg);
+ }
+
+ @override
+ visitTopLevelFunctionGet(
+ Send node,
+ MethodElement function,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_GET,
+ element: function));
+ }
+
+ @override
+ visitTopLevelFunctionSet(
+ SendSet node,
+ MethodElement function,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_SET,
+ element: function, rhs: rhs));
+ super.visitTopLevelFunctionSet(node, function, rhs, arg);
+ }
+
+ @override
+ visitTopLevelFunctionInvoke(
+ Send node,
+ MethodElement function,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,
+ element: function, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitTopLevelFunctionIncompatibleInvoke(
+ Send node,
+ MethodElement function,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,
+ element: function, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitTopLevelGetterGet(
+ Send node,
+ FunctionElement getter,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,
+ element: getter));
+ super.visitTopLevelGetterGet(node, getter, arg);
+ }
+
+ @override
+ visitTopLevelSetterGet(
+ Send node,
+ FunctionElement setter,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_GET,
+ element: setter));
+ super.visitTopLevelSetterGet(node, setter, arg);
+ }
+
+ @override
+ visitTopLevelGetterInvoke(
+ Send node,
+ FunctionElement getter,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,
+ element: getter, arguments: arguments));
+ super.visitTopLevelGetterInvoke(
+ node, getter, arguments, callStructure, arg);
+ }
+
+ @override
+ visitTopLevelSetterInvoke(
+ Send node,
+ FunctionElement setter,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_INVOKE,
+ element: setter, arguments: arguments));
+ super.visitTopLevelSetterInvoke(
+ node, setter, arguments, callStructure, arg);
+ }
+
+ @override
+ visitTopLevelGetterSet(
+ SendSet node,
+ FunctionElement getter,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SET,
+ element: getter, rhs: rhs));
+ super.visitTopLevelGetterSet(node, getter, rhs, arg);
+ }
+
+ @override
+ visitTopLevelSetterSet(
+ SendSet node,
+ FunctionElement setter,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,
+ element: setter, rhs: rhs));
+ super.visitTopLevelSetterSet(node, setter, rhs, arg);
+ }
+
+ @override
+ visitTypeVariableTypeLiteralGet(
+ Send node,
+ TypeVariableElement element,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,
+ element: element));
+ }
+
+ @override
+ visitTypeVariableTypeLiteralInvoke(
+ Send node,
+ TypeVariableElement element,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,
+ element: element, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitTypeVariableTypeLiteralSet(
+ SendSet node,
+ TypeVariableElement element,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,
+ element: element, rhs: rhs));
+ super.visitTypeVariableTypeLiteralSet(node, element, rhs, arg);
+ }
+
+ @override
+ visitTypedefTypeLiteralGet(
+ Send node,
+ ConstantExpression constant,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_GET,
+ constant: constant.getText()));
+ }
+
+ @override
+ visitTypedefTypeLiteralInvoke(
+ Send node,
+ ConstantExpression constant,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
+ constant: constant.getText(), arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitTypedefTypeLiteralSet(
+ SendSet node,
+ ConstantExpression constant,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,
+ constant: constant.getText(), rhs: rhs));
+ super.visitTypedefTypeLiteralSet(node, constant, rhs, arg);
+ }
+
+ @override
+ visitUnary(
+ Send node,
+ UnaryOperator operator,
+ Node expression,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNARY,
+ expression: expression, operator: operator));
+ super.visitUnary(node, operator, expression, arg);
+ }
+
+ @override
+ errorUndefinedUnaryExpression(
+ Send node,
+ Operator operator,
+ Node expression,
+ arg) {
+ visits.add(new Visit(VisitKind.ERROR_UNDEFINED_UNARY_EXPRESSION,
+ expression: expression, operator: operator));
+ super.errorUndefinedUnaryExpression(node, operator, expression, arg);
+ }
+
+ @override
+ visitNot(
+ Send node,
+ Node expression,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_NOT, expression: expression));
+ apply(expression, arg);
+ }
+
+ @override
+ visitSuperFieldGet(
+ Send node,
+ FieldElement field,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_GET, element: field));
+ }
+
+ @override
+ visitUnresolvedSuperGet(
+ Send node,
+ Element element,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GET));
+ }
+
+ @override
+ visitSuperFieldInvoke(
+ Send node,
+ FieldElement field,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_INVOKE,
+ element: field, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitUnresolvedSuperInvoke(
+ Send node,
+ Element element,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INVOKE,
+ arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitSuperFieldSet(
+ SendSet node,
+ FieldElement field,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SET,
+ element: field, rhs: rhs));
+ super.visitSuperFieldSet(node, field, rhs, arg);
+ }
+
+ @override
+ visitFinalSuperFieldSet(
+ SendSet node,
+ FieldElement field,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_SUPER_FIELD_SET,
+ element: field, rhs: rhs));
+ super.visitFinalSuperFieldSet(node, field, rhs, arg);
+ }
+
+ @override
+ visitSuperMethodGet(
+ Send node,
+ MethodElement method,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_GET, element: method));
+ }
+
+ @override
+ visitSuperMethodSet(
+ SendSet node,
+ MethodElement method,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SET,
+ element: method, rhs: rhs));
+ super.visitSuperMethodSet(node, method, rhs, arg);
+ }
+
+ @override
+ visitSuperMethodInvoke(
+ Send node,
+ MethodElement method,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_INVOKE,
+ element: method, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitSuperMethodIncompatibleInvoke(
+ Send node,
+ MethodElement method,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,
+ element: method, arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitSuperGetterGet(
+ Send node,
+ FunctionElement getter,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_GET, element: getter));
+ super.visitSuperGetterGet(node, getter, arg);
+ }
+
+ @override
+ visitSuperSetterGet(
+ Send node,
+ FunctionElement setter,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_GET, element: setter));
+ super.visitSuperSetterGet(node, setter, arg);
+ }
+
+ @override
+ visitSuperGetterInvoke(
+ Send node,
+ FunctionElement getter,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,
+ element: getter, arguments: arguments));
+ super.visitSuperGetterInvoke(node, getter, arguments, callStructure, arg);
+ }
+
+ @override
+ visitSuperSetterInvoke(
+ Send node,
+ FunctionElement setter,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_INVOKE,
+ element: setter, arguments: arguments));
+ super.visitSuperSetterInvoke(node, setter, arguments, callStructure, arg);
+ }
+
+ @override
+ visitSuperGetterSet(
+ SendSet node,
+ FunctionElement getter,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SET,
+ element: getter, rhs: rhs));
+ super.visitSuperGetterSet(node, getter, rhs, arg);
+ }
+
+ @override
+ visitSuperSetterSet(
+ SendSet node,
+ FunctionElement setter,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_SET,
+ element: setter, rhs: rhs));
+ super.visitSuperSetterSet(node, setter, rhs, arg);
+ }
+
+ @override
+ visitSuperUnary(
+ Send node,
+ UnaryOperator operator,
+ FunctionElement function,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_UNARY,
+ element: function, operator: operator));
+ }
+
+ @override
+ visitUnresolvedSuperUnary(
+ Send node,
+ UnaryOperator operator,
+ Element element,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_UNARY,
+ operator: operator));
+ }
+
+ @override
+ visitEquals(
+ Send node,
+ Node left,
+ Node right,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_EQUALS, left: left, right: right));
+ apply(left, arg);
+ apply(right, arg);
+ }
+
+ @override
+ visitSuperEquals(
+ Send node,
+ FunctionElement function,
+ Node argument,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_EQUALS,
+ element: function, right: argument));
+ apply(argument, arg);
+ }
+
+ @override
+ visitIndexSet(
+ Send node,
+ Node receiver,
+ Node index,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_INDEX_SET,
+ receiver: receiver, index: index, rhs: rhs));
+ apply(receiver, arg);
+ apply(index, arg);
+ apply(rhs, arg);
+ }
+
+ @override
+ visitSuperIndexSet(
+ Send node,
+ FunctionElement function,
+ Node index,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_SET,
+ element: function, index: index, rhs: rhs));
+ apply(index, arg);
+ apply(rhs, arg);
+ }
+
+ @override
+ visitDynamicPropertyCompound(
+ Send node,
+ Node receiver,
+ AssignmentOperator operator,
+ Node rhs,
+ Selector getterSelector,
+ Selector setterSelector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_COMPOUND,
+ receiver: receiver, operator: operator, rhs: rhs,
+ getter: getterSelector, setter: setterSelector));
+ apply(receiver, arg);
+ apply(rhs, arg);
+ }
+
+ @override
+ visitFinalLocalVariableCompound(
+ Send node,
+ LocalVariableElement variable,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,
+ element: variable, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitFinalLocalVariablePrefix(
+ Send node,
+ LocalVariableElement variable,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_PREFIX,
+ element: variable, operator: operator));
+ }
+
+ @override
+ visitFinalLocalVariablePostfix(
+ Send node,
+ LocalVariableElement variable,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,
+ element: variable, operator: operator));
+ }
+
+ @override
+ visitFinalParameterCompound(
+ Send node,
+ ParameterElement parameter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_COMPOUND,
+ element: parameter, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitFinalParameterPrefix(
+ Send node,
+ ParameterElement parameter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_PREFIX,
+ element: parameter, operator: operator));
+ }
+
+ @override
+ visitFinalParameterPostfix(
+ Send node,
+ ParameterElement parameter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_POSTFIX,
+ element: parameter, operator: operator));
+ }
+
+ @override
+ visitFinalStaticFieldCompound(
+ Send node,
+ FieldElement field,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_COMPOUND,
+ element: field, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitFinalStaticFieldPostfix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_POSTFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitFinalStaticFieldPrefix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_PREFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitFinalSuperFieldCompound(
+ Send node,
+ FieldElement field,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,
+ element: field, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitFinalTopLevelFieldCompound(
+ Send node,
+ FieldElement field,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,
+ element: field, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitFinalTopLevelFieldPostfix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitFinalTopLevelFieldPrefix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitLocalFunctionCompound(
+ Send node,
+ LocalFunctionElement function,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_COMPOUND,
+ element: function, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitLocalVariableCompound(
+ Send node,
+ LocalVariableElement variable,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_COMPOUND,
+ element: variable, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitParameterCompound(
+ Send node,
+ ParameterElement parameter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_PARAMETER_COMPOUND,
+ element: parameter, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitStaticFieldCompound(
+ Send node,
+ FieldElement field,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
+ element: field, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitStaticGetterSetterCompound(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
+ operator: operator, rhs: rhs,
+ getter: getter, setter: setter));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitSuperFieldCompound(
+ Send node,
+ FieldElement field,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_COMPOUND,
+ element: field, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitSuperGetterSetterCompound(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,
+ operator: operator, rhs: rhs,
+ getter: getter, setter: setter));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitThisPropertyCompound(
+ Send node,
+ AssignmentOperator operator,
+ Node rhs,
+ Selector getterSelector,
+ Selector setterSelector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,
+ operator: operator, rhs: rhs,
+ getter: getterSelector, setter: setterSelector));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitTopLevelFieldCompound(
+ Send node,
+ FieldElement field,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_COMPOUND,
+ element: field, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitTopLevelGetterSetterCompound(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,
+ operator: operator, rhs: rhs,
+ getter: getter, setter: setter));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitStaticMethodSetterCompound(
+ Send node,
+ FunctionElement method,
+ FunctionElement setter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+ operator: operator, rhs: rhs,
+ getter: method, setter: setter));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitSuperFieldSetterCompound(
+ Send node,
+ FieldElement field,
+ FunctionElement setter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_COMPOUND,
+ operator: operator, rhs: rhs,
+ getter: field, setter: setter));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitSuperGetterFieldCompound(
+ Send node,
+ FunctionElement getter,
+ FieldElement field,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_COMPOUND,
+ operator: operator, rhs: rhs,
+ getter: getter, setter: field));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitSuperMethodSetterCompound(
+ Send node,
+ FunctionElement method,
+ FunctionElement setter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_COMPOUND,
+ getter: method, setter: setter, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitSuperMethodCompound(
+ Send node,
+ FunctionElement method,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_COMPOUND,
+ element: method, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitSuperMethodPrefix(
+ Send node,
+ FunctionElement method,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_PREFIX,
+ element: method, operator: operator));
+ }
+
+ @override
+ visitSuperMethodPostfix(
+ Send node,
+ FunctionElement method,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_POSTFIX,
+ element: method, operator: operator));
+ }
+
+ @override
+ visitUnresolvedSuperCompound(
+ Send node,
+ Element element,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND,
+ operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedSuperPrefix(
+ Send node,
+ Element element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_PREFIX,
+ operator: operator));
+ }
+
+ @override
+ visitUnresolvedSuperPostfix(
+ Send node,
+ Element element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_POSTFIX,
+ operator: operator));
+ }
+
+ @override
+ visitTopLevelMethodSetterCompound(
+ Send node,
+ FunctionElement method,
+ FunctionElement setter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,
+ getter: method, setter: setter, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitCompoundIndexSet(
+ Send node,
+ Node receiver,
+ Node index,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_COMPOUND_INDEX_SET,
+ receiver: receiver, index: index, rhs: rhs, operator: operator));
+ apply(receiver, arg);
+ apply(index, arg);
+ apply(rhs, arg);
+ }
+
+ @override
+ visitSuperCompoundIndexSet(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ Node index,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_COMPOUND_INDEX_SET,
+ getter: getter, setter: setter,
+ index: index, rhs: rhs, operator: operator));
+ apply(index, arg);
+ apply(rhs, arg);
+ }
+
+ @override
+ visitClassTypeLiteralCompound(
+ Send node,
+ ConstantExpression constant,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,
+ constant: constant.getText(), operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitDynamicTypeLiteralCompound(
+ Send node,
+ ConstantExpression constant,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,
+ constant: constant.getText(), operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitTypeVariableTypeLiteralCompound(
+ Send node,
+ TypeVariableElement element,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,
+ element: element, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitTypedefTypeLiteralCompound(
+ Send node,
+ ConstantExpression constant,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,
+ constant: constant.getText(), operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitLocalFunctionPrefix(
+ Send node,
+ LocalFunctionElement function,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_PREFIX,
+ element: function, operator: operator));
+ }
+
+ @override
+ visitClassTypeLiteralPrefix(
+ Send node,
+ ConstantExpression constant,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,
+ constant: constant.getText(), operator: operator));
+ }
+
+ @override
+ visitDynamicTypeLiteralPrefix(
+ Send node,
+ ConstantExpression constant,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
+ constant: constant.getText(), operator: operator));
+ }
+
+ @override
+ visitLocalVariablePrefix(
+ Send node,
+ LocalVariableElement variable,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_PREFIX,
+ element: variable, operator: operator));
+ }
+
+ @override
+ visitParameterPrefix(
+ Send node,
+ ParameterElement parameter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_PARAMETER_PREFIX,
+ element: parameter, operator: operator));
+ }
+
+ @override
+ visitStaticFieldPrefix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitStaticGetterSetterPrefix(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
+ getter: getter, setter: setter, operator: operator));
+ }
+
+ @override
+ visitStaticMethodSetterPrefix(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_PREFIX,
+ getter: getter, setter: setter, operator: operator));
+ }
+
+ @override
+ visitSuperFieldFieldCompound(
+ Send node,
+ FieldElement readField,
+ FieldElement writtenField,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
+ getter: readField, setter: writtenField, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitSuperFieldFieldPrefix(
+ Send node,
+ FieldElement readField,
+ FieldElement writtenField,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_PREFIX,
+ getter: readField, setter: writtenField, operator: operator));
+ }
+
+ @override
+ visitSuperFieldPrefix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_PREFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitFinalSuperFieldPrefix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_PREFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitSuperFieldSetterPrefix(
+ Send node,
+ FieldElement field,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,
+ getter: field, setter: setter, operator: operator));
+ }
+
+ @override
+ visitSuperGetterFieldPrefix(
+ Send node,
+ FunctionElement getter,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_PREFIX,
+ getter: getter, setter: field, operator: operator));
+ }
+
+ @override
+ visitSuperGetterSetterPrefix(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,
+ getter: getter, setter: setter, operator: operator));
+ }
+
+ @override
+ visitSuperMethodSetterPrefix(
+ Send node,
+ FunctionElement method,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_PREFIX,
+ getter: method, setter: setter, operator: operator));
+ }
+
+ @override
+ visitThisPropertyPrefix(
+ Send node,
+ IncDecOperator operator,
+ Selector getterSelector,
+ Selector setterSelector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,
+ operator: operator,
+ getter: getterSelector, setter: setterSelector));
+ }
+
+ @override
+ visitTopLevelFieldPrefix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_PREFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitTopLevelGetterSetterPrefix(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,
+ getter: getter, setter: setter, operator: operator));
+ }
+
+ @override
+ visitTopLevelMethodSetterPrefix(
+ Send node,
+ FunctionElement method,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,
+ getter: method, setter: setter, operator: operator));
+ }
+
+ @override
+ visitTypeVariableTypeLiteralPrefix(
+ Send node,
+ TypeVariableElement element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,
+ element: element, operator: operator));
+ }
+
+ @override
+ visitTypedefTypeLiteralPrefix(
+ Send node,
+ ConstantExpression constant,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
+ constant: constant.getText(), operator: operator));
+ }
+
+ @override
+ visitLocalFunctionPostfix(
+ Send node,
+ LocalFunctionElement function,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_POSTFIX,
+ element: function, operator: operator));
+ }
+
+ @override
+ visitClassTypeLiteralPostfix(
+ Send node,
+ ConstantExpression constant,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,
+ constant: constant.getText(), operator: operator));
+ }
+
+ @override
+ visitDynamicTypeLiteralPostfix(
+ Send node,
+ ConstantExpression constant,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,
+ constant: constant.getText(), operator: operator));
+ }
+
+ @override
+ visitLocalVariablePostfix(
+ Send node,
+ LocalVariableElement variable,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_POSTFIX,
+ element: variable, operator: operator));
+ }
+
+ @override
+ visitParameterPostfix(
+ Send node,
+ ParameterElement parameter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_PARAMETER_POSTFIX,
+ element: parameter, operator: operator));
+ }
+
+ @override
+ visitStaticFieldPostfix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitStaticGetterSetterPostfix(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
+ getter: getter, setter: setter, operator: operator));
+ }
+
+ @override
+ visitStaticMethodSetterPostfix(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_POSTFIX,
+ getter: getter, setter: setter, operator: operator));
+ }
+
+ @override
+ visitSuperFieldFieldPostfix(
+ Send node,
+ FieldElement readField,
+ FieldElement writtenField,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_POSTFIX,
+ getter: readField, setter: writtenField, operator: operator));
+ }
+
+ @override
+ visitSuperFieldPostfix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_POSTFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitFinalSuperFieldPostfix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_POSTFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitSuperFieldSetterPostfix(
+ Send node,
+ FieldElement field,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,
+ getter: field, setter: setter, operator: operator));
+ }
+
+ @override
+ visitSuperGetterFieldPostfix(
+ Send node,
+ FunctionElement getter,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_POSTFIX,
+ getter: getter, setter: field, operator: operator));
+ }
+
+ @override
+ visitSuperGetterSetterPostfix(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,
+ getter: getter, setter: setter, operator: operator));
+ }
+
+ @override
+ visitSuperMethodSetterPostfix(
+ Send node,
+ FunctionElement method,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_POSTFIX,
+ getter: method, setter: setter, operator: operator));
+ }
+
+ @override
+ visitThisPropertyPostfix(
+ Send node,
+ IncDecOperator operator,
+ Selector getterSelector,
+ Selector setterSelector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,
+ operator: operator,
+ getter: getterSelector, setter: setterSelector));
+ }
+
+ @override
+ visitTopLevelFieldPostfix(
+ Send node,
+ FieldElement field,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_POSTFIX,
+ element: field, operator: operator));
+ }
+
+ @override
+ visitTopLevelGetterSetterPostfix(
+ Send node,
+ FunctionElement getter,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,
+ getter: getter, setter: setter, operator: operator));
+ }
+
+ @override
+ visitTopLevelMethodSetterPostfix(
+ Send node,
+ FunctionElement method,
+ FunctionElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,
+ getter: method, setter: setter, operator: operator));
+ }
+
+ @override
+ visitTypeVariableTypeLiteralPostfix(
+ Send node,
+ TypeVariableElement element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,
+ element: element, operator: operator));
+ }
+
+ @override
+ visitTypedefTypeLiteralPostfix(
+ Send node,
+ ConstantExpression constant,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,
+ constant: constant.getText(), operator: operator));
+ }
+
+ @override
+ visitUnresolvedCompound(
+ Send node,
+ ErroneousElement element,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_COMPOUND,
+ operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedGet(
+ Send node,
+ Element element,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_GET, name: element.name));
+ }
+
+ @override
+ visitUnresolvedSet(
+ Send node,
+ Element element,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SET,
+ name: element.name, rhs: rhs));
+ super.visitUnresolvedSet(node, element, rhs, arg);
+ }
+
+ @override
+ visitUnresolvedInvoke(
+ Send node,
+ Element element,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
+ name: element.name, arguments: arguments));
+ super.visitUnresolvedInvoke(node, element, arguments, selector, arg);
+ }
+
+ @override
+ visitUnresolvedPostfix(
+ Send node,
+ ErroneousElement element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_UNRESOLVED_POSTFIX, operator: operator));
+ }
+
+ @override
+ visitUnresolvedPrefix(
+ Send node,
+ ErroneousElement element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_UNRESOLVED_PREFIX, operator: operator));
+ }
+
+ @override
+ visitUnresolvedSuperCompoundIndexSet(
+ Send node,
+ Element element,
+ Node index,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,
+ index: index, operator: operator, rhs: rhs));
+ apply(index, arg);
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedSuperGetterCompoundIndexSet(
+ Send node,
+ Element element,
+ MethodElement setter,
+ Node index,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,
+ setter: setter, index: index, operator: operator, rhs: rhs));
+ apply(index, arg);
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedSuperSetterCompoundIndexSet(
+ Send node,
+ MethodElement getter,
+ Element element,
+ Node index,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,
+ getter: getter, index: index, operator: operator, rhs: rhs));
+ apply(index, arg);
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedSuperIndexSet(
+ Send node,
+ ErroneousElement element,
+ Node index,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_SET,
+ index: index, rhs: rhs));
+ apply(index, arg);
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedSuperIndexPostfix(
+ Send node,
+ Element element,
+ Node index,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,
+ index: index, operator: operator));
+ apply(index, arg);
+ }
+
+ @override
+ visitUnresolvedSuperGetterIndexPostfix(
+ Send node,
+ Element element,
+ MethodElement setter,
+ Node index,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,
+ setter: setter, index: index, operator: operator));
+ apply(index, arg);
+ }
+
+ @override
+ visitUnresolvedSuperSetterIndexPostfix(
+ Send node,
+ MethodElement getter,
+ Element element,
+ Node index,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,
+ getter: getter, index: index, operator: operator));
+ apply(index, arg);
+ }
+
+ @override
+ visitUnresolvedSuperIndexPrefix(
+ Send node,
+ Element element,
+ Node index,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,
+ index: index, operator: operator));
+ apply(index, arg);
+ }
+
+ @override
+ visitUnresolvedSuperGetterIndexPrefix(
+ Send node,
+ Element element,
+ MethodElement setter,
+ Node index,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,
+ setter: setter, index: index, operator: operator));
+ apply(index, arg);
+ }
+
+ @override
+ visitUnresolvedSuperSetterIndexPrefix(
+ Send node,
+ MethodElement getter,
+ Element element,
+ Node index,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,
+ getter: getter, index: index, operator: operator));
+ apply(index, arg);
+ }
+
+ @override
+ visitIndexPostfix(
+ Send node,
+ Node receiver,
+ Node index,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_INDEX_POSTFIX,
+ receiver: receiver, index: index, operator: operator));
+ apply(receiver, arg);
+ apply(index, arg);
+ }
+
+ @override
+ visitIndexPrefix(
+ Send node,
+ Node receiver,
+ Node index,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_INDEX_PREFIX,
+ receiver: receiver, index: index, operator: operator));
+ apply(receiver, arg);
+ apply(index, arg);
+ }
+
+ @override
+ visitSuperIndexPostfix(
+ Send node,
+ FunctionElement indexFunction,
+ FunctionElement indexSetFunction,
+ Node index,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_POSTFIX,
+ getter: indexFunction, setter: indexSetFunction,
+ index: index, operator: operator));
+ apply(index, arg);
+ }
+
+ @override
+ visitSuperIndexPrefix(
+ Send node,
+ FunctionElement indexFunction,
+ FunctionElement indexSetFunction,
+ Node index,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_PREFIX,
+ getter: indexFunction, setter: indexSetFunction,
+ index: index, operator: operator));
+ apply(index, arg);
+ }
+
+ @override
+ visitUnresolvedClassConstructorInvoke(
+ NewExpression node,
+ Element constructor,
+ DartType type,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ // TODO(johnniwinther): Test [type] when it is not `dynamic`.
+ visits.add(new Visit(
+ VisitKind.VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
+ arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitUnresolvedConstructorInvoke(
+ NewExpression node,
+ Element constructor,
+ DartType type,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ // TODO(johnniwinther): Test [type] when it is not `dynamic`.
+ visits.add(new Visit(
+ VisitKind.VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,
+ arguments: arguments));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitConstConstructorInvoke(
+ NewExpression node,
+ ConstructedConstantExpression constant,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,
+ constant: constant.getText()));
+ super.visitConstConstructorInvoke(node, constant, arg);
+ }
+
+ @override
+ visitBoolFromEnvironmentConstructorInvoke(
+ NewExpression node,
+ BoolFromEnvironmentConstantExpression constant,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+ constant: constant.getText()));
+ super.visitBoolFromEnvironmentConstructorInvoke(node, constant, arg);
+ }
+
+ @override
+ visitIntFromEnvironmentConstructorInvoke(
+ NewExpression node,
+ IntFromEnvironmentConstantExpression constant,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+ constant: constant.getText()));
+ super.visitIntFromEnvironmentConstructorInvoke(node, constant, arg);
+ }
+
+ @override
+ visitStringFromEnvironmentConstructorInvoke(
+ NewExpression node,
+ StringFromEnvironmentConstantExpression constant,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+ constant: constant.getText()));
+ super.visitStringFromEnvironmentConstructorInvoke(node, constant, arg);
+ }
+
+ @override
+ errorNonConstantConstructorInvoke(
+ NewExpression node,
+ Element element,
+ DartType type,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,
+ element: element, type: type,
+ arguments: arguments, selector: callStructure));
+ super.errorNonConstantConstructorInvoke(
+ node, element, type, arguments, callStructure, arg);
+ }
+
+ @override
+ visitConstructorIncompatibleInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
+ element: constructor, type: type,
+ arguments: arguments, selector: callStructure));
+ super.visitConstructorIncompatibleInvoke(
+ node, constructor, type, arguments, callStructure, arg);
+ }
+
+ @override
+ visitFactoryConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ arguments: arguments,
+ selector: callStructure));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitGenerativeConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ arguments: arguments,
+ selector: callStructure));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitRedirectingFactoryConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ ConstructorElement effectiveTarget,
+ InterfaceType effectiveTargetType,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ target: effectiveTarget,
+ targetType: effectiveTargetType,
+ arguments: arguments,
+ selector: callStructure));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitRedirectingGenerativeConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ arguments: arguments,
+ selector: callStructure));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitAbstractClassConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ arguments: arguments,
+ selector: callStructure));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitUnresolvedRedirectingFactoryConstructorInvoke(
+ NewExpression node,
+ ConstructorElement constructor,
+ InterfaceType type,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(
+ VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+ element: constructor,
+ type: type,
+ arguments: arguments,
+ selector: callStructure));
+ apply(arguments, arg);
+ }
+
+ @override
+ visitUnresolvedStaticGetterCompound(
+ Send node,
+ Element element,
+ MethodElement setter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,
+ setter: setter, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedTopLevelGetterCompound(
+ Send node,
+ Element element,
+ MethodElement setter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,
+ setter: setter, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedStaticSetterCompound(
+ Send node,
+ MethodElement getter,
+ Element element,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,
+ getter: getter, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedTopLevelSetterCompound(
+ Send node,
+ MethodElement getter,
+ Element element,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,
+ getter: getter, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitStaticMethodCompound(
+ Send node,
+ MethodElement method,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_COMPOUND,
+ element: method, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitTopLevelMethodCompound(
+ Send node,
+ MethodElement method,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_COMPOUND,
+ element: method, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedStaticGetterPrefix(
+ Send node,
+ Element element,
+ MethodElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,
+ setter: setter, operator: operator));
+ }
+
+ @override
+ visitUnresolvedTopLevelGetterPrefix(
+ Send node,
+ Element element,
+ MethodElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,
+ setter: setter, operator: operator));
+ }
+
+ @override
+ visitUnresolvedStaticSetterPrefix(
+ Send node,
+ MethodElement getter,
+ Element element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,
+ getter: getter, operator: operator));
+ }
+
+ @override
+ visitUnresolvedTopLevelSetterPrefix(
+ Send node,
+ MethodElement getter,
+ Element element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,
+ getter: getter, operator: operator));
+ }
+
+ @override
+ visitStaticMethodPrefix(
+ Send node,
+ MethodElement method,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_PREFIX,
+ element: method, operator: operator));
+ }
+
+ @override
+ visitTopLevelMethodPrefix(
+ Send node,
+ MethodElement method,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_PREFIX,
+ element: method, operator: operator));
+ }
+
+ @override
+ visitUnresolvedStaticGetterPostfix(
+ Send node,
+ Element element,
+ MethodElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,
+ setter: setter, operator: operator));
+ }
+
+ @override
+ visitUnresolvedTopLevelGetterPostfix(
+ Send node,
+ Element element,
+ MethodElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,
+ setter: setter, operator: operator));
+ }
+
+ @override
+ visitUnresolvedStaticSetterPostfix(
+ Send node,
+ MethodElement getter,
+ Element element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,
+ getter: getter, operator: operator));
+ }
+
+ @override
+ visitUnresolvedTopLevelSetterPostfix(
+ Send node,
+ MethodElement getter,
+ Element element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,
+ getter: getter, operator: operator));
+ }
+
+ @override
+ visitStaticMethodPostfix(
+ Send node,
+ MethodElement method,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_POSTFIX,
+ element: method, operator: operator));
+ }
+
+ @override
+ visitTopLevelMethodPostfix(
+ Send node,
+ MethodElement method,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_POSTFIX,
+ element: method, operator: operator));
+ }
+
+ @override
+ visitUnresolvedSuperGetterCompound(
+ Send node, Element element,
+ MethodElement setter,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,
+ setter: setter, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedSuperGetterPostfix(
+ Send node,
+ Element element,
+ MethodElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,
+ setter: setter, operator: operator));
+ }
+
+ @override
+ visitUnresolvedSuperGetterPrefix(
+ Send node,
+ Element element,
+ MethodElement setter,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,
+ setter: setter, operator: operator));
+ }
+
+ @override
+ visitUnresolvedSuperSetterCompound(
+ Send node, MethodElement getter,
+ Element element,
+ AssignmentOperator operator,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,
+ getter: getter, operator: operator, rhs: rhs));
+ apply(rhs, arg);
+ }
+
+ @override
+ visitUnresolvedSuperSetterPostfix(
+ Send node,
+ MethodElement getter,
+ Element element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,
+ getter: getter, operator: operator));
+ }
+
+ @override
+ visitUnresolvedSuperSetterPrefix(
+ Send node,
+ MethodElement getter,
+ Element element,
+ IncDecOperator operator,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,
+ getter: getter, operator: operator));
+ }
+
+ @override
+ visitIfNotNullDynamicPropertyGet(
+ Send node,
+ Node receiver,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
+ receiver: receiver, name: selector.name));
+ super.visitIfNotNullDynamicPropertyGet(node, receiver, selector, arg);
+ }
+
+ @override
+ visitIfNotNullDynamicPropertySet(
+ Send node,
+ Node receiver,
+ Selector selector,
+ Node rhs,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,
+ receiver: receiver, name: selector.name, rhs: rhs));
+ super.visitIfNotNullDynamicPropertySet(node, receiver, selector, rhs, arg);
+ }
+
+ @override
+ visitIfNotNullDynamicPropertyInvoke(
+ Send node,
+ Node receiver,
+ NodeList arguments,
+ Selector selector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,
+ receiver: receiver, selector: selector, arguments: arguments));
+ super.visitIfNotNullDynamicPropertyInvoke(
+ node, receiver, arguments, selector, arg);
+ }
+
+ @override
+ visitIfNotNullDynamicPropertyPrefix(
+ Send node,
+ Node receiver,
+ IncDecOperator operator,
+ Selector getterSelector,
+ Selector setterSelector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,
+ receiver: receiver, operator: operator,
+ getter: getterSelector, setter: setterSelector));
+ super.visitIfNotNullDynamicPropertyPrefix(
+ node, receiver, operator, getterSelector, setterSelector, arg);
+ }
+
+ @override
+ visitIfNotNullDynamicPropertyPostfix(
+ Send node,
+ Node receiver,
+ IncDecOperator operator,
+ Selector getterSelector,
+ Selector setterSelector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,
+ receiver: receiver, operator: operator,
+ getter: getterSelector, setter: setterSelector));
+ super.visitIfNotNullDynamicPropertyPostfix(
+ node, receiver, operator, getterSelector, setterSelector, arg);
+ }
+
+ @override
+ visitIfNotNullDynamicPropertyCompound(
+ Send node,
+ Node receiver,
+ AssignmentOperator operator,
+ Node rhs,
+ Selector getterSelector,
+ Selector setterSelector,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,
+ receiver: receiver, operator: operator, rhs: rhs,
+ getter: getterSelector, setter: setterSelector));
+ super.visitIfNotNullDynamicPropertyCompound(
+ node, receiver, operator, rhs, getterSelector, setterSelector, arg);
+ }
+
+ @override
+ visitIfNull(
+ Send node,
+ Node left,
+ Node right,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_IF_NULL, left: left, right: right));
+ super.visitIfNull(node, left, right, arg);
+ }
+
+ @override
+ visitConstantGet(
+ Send node,
+ ConstantExpression constant,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CONSTANT_GET,
+ constant: constant.getText()));
+ super.visitConstantGet(node, constant, arg);
+ }
+
+ @override
+ visitConstantInvoke(
+ Send node,
+ ConstantExpression constant,
+ NodeList arguments,
+ CallStructure callStructure,
+ arg) {
+ visits.add(new Visit(VisitKind.VISIT_CONSTANT_INVOKE,
+ constant: constant.getText()));
+ super.visitConstantInvoke(node, constant, arguments, callStructure, arg);
+ }
+}
diff --git a/tests/compiler/dart2js/show_package_warnings_test.dart b/tests/compiler/dart2js/show_package_warnings_test.dart
index eb9a441..de518f9 100644
--- a/tests/compiler/dart2js/show_package_warnings_test.dart
+++ b/tests/compiler/dart2js/show_package_warnings_test.dart
@@ -69,14 +69,26 @@
'Unexpected errors: ${collector.errors}');
Expect.equals(warnings, collector.warnings.length,
'Unexpected warnings: ${collector.warnings}');
+ checkUriSchemes(collector.warnings);
Expect.equals(hints, collector.hints.length,
'Unexpected hints: ${collector.hints}');
+ checkUriSchemes(collector.hints);
Expect.equals(infos, collector.infos.length,
'Unexpected infos: ${collector.infos}');
+ checkUriSchemes(collector.infos);
print('==================================================================');
}));
}
+void checkUriSchemes(Iterable<DiagnosticMessage> messages) {
+ for (DiagnosticMessage message in messages) {
+ if (message.uri != null) {
+ Expect.notEquals('package', message.uri.scheme,
+ "Unexpected package uri `${message.uri}` in message: $message");
+ }
+ }
+}
+
void main() {
test([Uri.parse('memory:main.dart')],
showPackageWarnings: true,
diff --git a/tests/compiler/dart2js/top_level_closure_tree_shake_test.dart b/tests/compiler/dart2js/top_level_closure_tree_shake_test.dart
new file mode 100644
index 0000000..6c3ae37
--- /dev/null
+++ b/tests/compiler/dart2js/top_level_closure_tree_shake_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'compiler_helper.dart';
+
+const String TEST_ONE = r"""
+main() {
+ var f = use;
+ if (false) {
+ // This statement and the use of 'foo' should be optimized away, causing
+ // 'foo' to be absent from the final code.
+ f(foo);
+ }
+ f(bar);
+}
+
+foo() => 'Tarantula!';
+bar() => 'Coelacanth!';
+
+use(x) {
+ print(x());
+}
+""";
+
+
+main() {
+ asyncTest(() => Future.wait([
+ compileAll(TEST_ONE).then((String generated) {
+ Expect.isFalse(generated.contains('Tarantula!'),
+ "failed to remove 'foo'");
+ Expect.isTrue(generated.contains('Coelacanth!'));
+ }),
+ ]));
+}
diff --git a/tests/compiler/dart2js/type_order_test.dart b/tests/compiler/dart2js/type_order_test.dart
index a3337f3..e4faa01 100644
--- a/tests/compiler/dart2js/type_order_test.dart
+++ b/tests/compiler/dart2js/type_order_test.dart
@@ -1,72 +1,72 @@
-// 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 subtype_test;
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'type_test_helper.dart';
-import 'package:compiler/src/dart_types.dart';
-import "package:compiler/src/elements/elements.dart"
- show Element, ClassElement, TypedefElement;
-
-void main() {
- asyncTest(() => TypeEnvironment.create(r"""
- class A<AT, AS> {}
- typedef BS B<BT, BS>(BT t);
- class C<CT, CS> extends A<CS, CT> {}
- class X {}
- class Y {}
- class Z {}
- """).then((env) {
-
- List types = [];
- DartType add(DartType type) {
- types.add(type);
- return type;
- }
-
- DartType dynamic_ = add(env['dynamic']);
- DartType void_ = add(env['void']);
-
- ClassElement A = env.getElement('A');
- TypedefElement B = env.getElement('B');
- ClassElement C = env.getElement('C');
- DartType X = add(env['X']);
- DartType Y = add(env['Y']);
- DartType Z = add(env['Z']);
-
- InterfaceType A_this = add(A.thisType);
- InterfaceType A_raw = add(A.rawType);
- TypeVariableType AT = add(A_this.typeArguments[0]);
- TypeVariableType AS = add(A_this.typeArguments[1]);
- InterfaceType A_X_Y = add(instantiate(A, [X, Y]));
- InterfaceType A_Y_X = add(instantiate(A, [Y, X]));
-
- TypedefType B_this = add(B.computeType(env.compiler));
- TypedefType B_raw = add(B.rawType);
- TypeVariableType BT = add(B_this.typeArguments[0]);
- TypeVariableType BS = add(B_this.typeArguments[1]);
- FunctionType B_this_alias = add(B.alias);
- TypedefType B_X_Y = add(instantiate(B, [X, Y]));
- FunctionType B_X_Y_alias = add(B_X_Y.unalias(env.compiler));
- TypedefType B_Y_X = add(instantiate(B, [Y, X]));
- FunctionType B_Y_X_alias = add(B_Y_X.unalias(env.compiler));
-
- InterfaceType C_this = add(C.thisType);
- InterfaceType C_raw = add(C.rawType);
- TypeVariableType CT = add(C_this.typeArguments[0]);
- TypeVariableType CS = add(C_this.typeArguments[1]);
-
- Expect.listEquals(
- [void_, dynamic_,
- A_raw, A_this, A_X_Y, A_Y_X, AT, AS,
- B_raw, B_this, B_X_Y, B_Y_X, BT, BS,
- C_raw, C_this, CT, CS,
- X, Y, Z,
- B_this_alias, B_Y_X_alias, B_X_Y_alias,
- ],
- Types.sorted(types));
- }));
+// 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 subtype_test;
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'type_test_helper.dart';
+import 'package:compiler/src/dart_types.dart';
+import "package:compiler/src/elements/elements.dart"
+ show Element, ClassElement, TypedefElement;
+
+void main() {
+ asyncTest(() => TypeEnvironment.create(r"""
+ class A<AT, AS> {}
+ typedef BS B<BT, BS>(BT t);
+ class C<CT, CS> extends A<CS, CT> {}
+ class X {}
+ class Y {}
+ class Z {}
+ """).then((env) {
+
+ List types = [];
+ DartType add(DartType type) {
+ types.add(type);
+ return type;
+ }
+
+ DartType dynamic_ = add(env['dynamic']);
+ DartType void_ = add(env['void']);
+
+ ClassElement A = env.getElement('A');
+ TypedefElement B = env.getElement('B');
+ ClassElement C = env.getElement('C');
+ DartType X = add(env['X']);
+ DartType Y = add(env['Y']);
+ DartType Z = add(env['Z']);
+
+ InterfaceType A_this = add(A.thisType);
+ InterfaceType A_raw = add(A.rawType);
+ TypeVariableType AT = add(A_this.typeArguments[0]);
+ TypeVariableType AS = add(A_this.typeArguments[1]);
+ InterfaceType A_X_Y = add(instantiate(A, [X, Y]));
+ InterfaceType A_Y_X = add(instantiate(A, [Y, X]));
+
+ TypedefType B_this = add(B.computeType(env.compiler));
+ TypedefType B_raw = add(B.rawType);
+ TypeVariableType BT = add(B_this.typeArguments[0]);
+ TypeVariableType BS = add(B_this.typeArguments[1]);
+ FunctionType B_this_alias = add(B.alias);
+ TypedefType B_X_Y = add(instantiate(B, [X, Y]));
+ FunctionType B_X_Y_alias = add(B_X_Y.unalias(env.compiler));
+ TypedefType B_Y_X = add(instantiate(B, [Y, X]));
+ FunctionType B_Y_X_alias = add(B_Y_X.unalias(env.compiler));
+
+ InterfaceType C_this = add(C.thisType);
+ InterfaceType C_raw = add(C.rawType);
+ TypeVariableType CT = add(C_this.typeArguments[0]);
+ TypeVariableType CS = add(C_this.typeArguments[1]);
+
+ Expect.listEquals(
+ [void_, dynamic_,
+ A_raw, A_this, A_X_Y, A_Y_X, AT, AS,
+ B_raw, B_this, B_X_Y, B_Y_X, BT, BS,
+ C_raw, C_this, CT, CS,
+ X, Y, Z,
+ B_this_alias, B_Y_X_alias, B_X_Y_alias,
+ ],
+ Types.sorted(types));
+ }));
}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/type_promotion_test.dart b/tests/compiler/dart2js/type_promotion_test.dart
index 8739394..b391cf9 100644
--- a/tests/compiler/dart2js/type_promotion_test.dart
+++ b/tests/compiler/dart2js/type_promotion_test.dart
@@ -1,29 +1,29 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that dart2js produces the expected static type warnings for type
-// promotion language tests. This ensures that the analyzer and dart2js agrees
-// on these tests.
-
-import 'warnings_checker.dart';
-
-/// Map from test files to a map of their expected status. If the status map is
-/// `null` no warnings must be missing or unexpected, otherwise the status map
-/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
-/// the warnings of each category.
-const Map<String, dynamic> TESTS = const {
- 'language/type_promotion_assign_test.dart': null,
- 'language/type_promotion_closure_test.dart': null,
- 'language/type_promotion_functions_test.dart':
- const {'missing': const [62, 63, 64]}, // Issue 14933.
- 'language/type_promotion_local_test.dart': null,
- 'language/type_promotion_logical_and_test.dart': null,
- 'language/type_promotion_more_specific_test.dart': null,
- 'language/type_promotion_multiple_test.dart': null,
- 'language/type_promotion_parameter_test.dart': null,
-};
-
-void main() {
- checkWarnings(TESTS);
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that dart2js produces the expected static type warnings for type
+// promotion language tests. This ensures that the analyzer and dart2js agrees
+// on these tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+ 'language/type_promotion_assign_test.dart': null,
+ 'language/type_promotion_closure_test.dart': null,
+ 'language/type_promotion_functions_test.dart':
+ const {'missing': const [62, 63, 64]}, // Issue 14933.
+ 'language/type_promotion_local_test.dart': null,
+ 'language/type_promotion_logical_and_test.dart': null,
+ 'language/type_promotion_more_specific_test.dart': null,
+ 'language/type_promotion_multiple_test.dart': null,
+ 'language/type_promotion_parameter_test.dart': null,
+};
+
+void main() {
+ checkWarnings(TESTS);
+}
diff --git a/tests/compiler/dart2js/warnings_checker.dart b/tests/compiler/dart2js/warnings_checker.dart
index e1dba07..daaa32d 100644
--- a/tests/compiler/dart2js/warnings_checker.dart
+++ b/tests/compiler/dart2js/warnings_checker.dart
@@ -1,83 +1,83 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that dart2js produces the expected static type warnings to ensures that
-// the analyzer and dart2js agrees on the tests.
-
-import 'dart:async';
-import 'dart:io';
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'memory_compiler.dart';
-import 'package:compiler/src/filenames.dart';
-import 'package:compiler/src/io/source_file.dart';
-import 'package:compiler/src/source_file_provider.dart';
-import 'package:compiler/src/util/uri_extras.dart';
-import 'dart:convert';
-
-void checkWarnings(Map<String, dynamic> tests, [List<String> arguments]) {
- bool isWindows = Platform.isWindows;
- Uri script = currentDirectory.resolveUri(Platform.script);
- bool warningsMismatch = false;
- bool verbose = arguments != null && arguments.contains('-v');
- asyncTest(() => Future.forEach(tests.keys, (String test) {
- Uri uri = script.resolve('../../$test');
- String source = UTF8.decode(readAll(uriPathToNative(uri.path)));
- SourceFile file = new StringSourceFile(
- uri, relativize(currentDirectory, uri, isWindows), source);
- Map<int,String> expectedWarnings = {};
- int lineNo = 0;
- for (String line in source.split('\n')) {
- if (line.contains('///') &&
- (line.contains('static type warning') ||
- line.contains('static warning'))) {
- expectedWarnings[lineNo] = line;
- }
- lineNo++;
- }
- Set<int> unseenWarnings = new Set<int>.from(expectedWarnings.keys);
- DiagnosticCollector collector = new DiagnosticCollector();
- var compiler = compilerFor(const {},
- diagnosticHandler: collector,
- options: ['--analyze-only'],
- showDiagnostics: verbose);
- return compiler.run(uri).then((_) {
- Map<String, List<int>> statusMap = tests[test];
- // Line numbers with known unexpected warnings.
- List<int> unexpectedStatus = [];
- if (statusMap != null && statusMap.containsKey('unexpected')) {
- unexpectedStatus = statusMap['unexpected'];
- }
- // Line numbers with known missing warnings.
- List<int> missingStatus = [];
- if (statusMap != null && statusMap.containsKey('missing')) {
- missingStatus = statusMap['missing'];
- }
- for (DiagnosticMessage message in collector.warnings) {
- Expect.equals(uri, message.uri);
- int lineNo = file.getLine(message.begin);
- if (expectedWarnings.containsKey(lineNo)) {
- unseenWarnings.remove(lineNo);
- } else if (!unexpectedStatus.contains(lineNo+1)) {
- warningsMismatch = true;
- print(file.getLocationMessage(
- 'Unexpected warning: ${message.message}',
- message.begin, message.end));
- }
- }
- if (!unseenWarnings.isEmpty) {
- for (int lineNo in unseenWarnings) {
- if (!missingStatus.contains(lineNo+1)) {
- warningsMismatch = true;
- String line = expectedWarnings[lineNo];
- print('$uri [${lineNo+1}]: Missing static type warning.');
- print(line);
- }
- }
- }
- });
- }).then((_) {
- Expect.isFalse(warningsMismatch);
- }));
-}
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that dart2js produces the expected static type warnings to ensures that
+// the analyzer and dart2js agrees on the tests.
+
+import 'dart:async';
+import 'dart:io';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'memory_compiler.dart';
+import 'package:compiler/src/filenames.dart';
+import 'package:compiler/src/io/source_file.dart';
+import 'package:compiler/src/source_file_provider.dart';
+import 'package:compiler/src/util/uri_extras.dart';
+import 'dart:convert';
+
+void checkWarnings(Map<String, dynamic> tests, [List<String> arguments]) {
+ bool isWindows = Platform.isWindows;
+ Uri script = currentDirectory.resolveUri(Platform.script);
+ bool warningsMismatch = false;
+ bool verbose = arguments != null && arguments.contains('-v');
+ asyncTest(() => Future.forEach(tests.keys, (String test) {
+ Uri uri = script.resolve('../../$test');
+ String source = UTF8.decode(readAll(uriPathToNative(uri.path)));
+ SourceFile file = new StringSourceFile(
+ uri, relativize(currentDirectory, uri, isWindows), source);
+ Map<int,String> expectedWarnings = {};
+ int lineNo = 0;
+ for (String line in source.split('\n')) {
+ if (line.contains('///') &&
+ (line.contains('static type warning') ||
+ line.contains('static warning'))) {
+ expectedWarnings[lineNo] = line;
+ }
+ lineNo++;
+ }
+ Set<int> unseenWarnings = new Set<int>.from(expectedWarnings.keys);
+ DiagnosticCollector collector = new DiagnosticCollector();
+ var compiler = compilerFor(const {},
+ diagnosticHandler: collector,
+ options: ['--analyze-only'],
+ showDiagnostics: verbose);
+ return compiler.run(uri).then((_) {
+ Map<String, List<int>> statusMap = tests[test];
+ // Line numbers with known unexpected warnings.
+ List<int> unexpectedStatus = [];
+ if (statusMap != null && statusMap.containsKey('unexpected')) {
+ unexpectedStatus = statusMap['unexpected'];
+ }
+ // Line numbers with known missing warnings.
+ List<int> missingStatus = [];
+ if (statusMap != null && statusMap.containsKey('missing')) {
+ missingStatus = statusMap['missing'];
+ }
+ for (DiagnosticMessage message in collector.warnings) {
+ Expect.equals(uri, message.uri);
+ int lineNo = file.getLine(message.begin);
+ if (expectedWarnings.containsKey(lineNo)) {
+ unseenWarnings.remove(lineNo);
+ } else if (!unexpectedStatus.contains(lineNo+1)) {
+ warningsMismatch = true;
+ print(file.getLocationMessage(
+ 'Unexpected warning: ${message.message}',
+ message.begin, message.end));
+ }
+ }
+ if (!unseenWarnings.isEmpty) {
+ for (int lineNo in unseenWarnings) {
+ if (!missingStatus.contains(lineNo+1)) {
+ warningsMismatch = true;
+ String line = expectedWarnings[lineNo];
+ print('$uri [${lineNo+1}]: Missing static type warning.');
+ print(line);
+ }
+ }
+ }
+ });
+ }).then((_) {
+ Expect.isFalse(warningsMismatch);
+ }));
+}
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 2399b15..c398750 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -67,48 +67,28 @@
11673_test: RuntimeError # Cannot read property 'prototype' of undefined
12320_test: RuntimeError # Cannot read property 'prototype' of undefined
16407_test: Pass # Please triage this failure.
-17645_test: RuntimeError # Please triage this failure.
-19191_test: RuntimeError # Please triage this failure.
-21166_test: RuntimeError # Please triage this failure.
-21579_test: RuntimeError # Please triage this failure.
-21666_test: Crash # Internal Error: No default constructor available.
22487_test: RuntimeError # Cannot read property 'prototype' of undefined
22868_test: Crash # (main()async{var clo... cannot handle async/sync*/async* functions
22895_test: Crash # (main()async{var clo... cannot handle async/sync*/async* functions
23404_test: RuntimeError # Cannot read property 'prototype' of undefined
-23432_test: RuntimeError # Please triage this failure.
+23432_test : RuntimeError #
LayoutTests_fast_mediastream_getusermedia_t01_test/none: RuntimeError # Cannot read property 'prototype' of undefined
async_stacktrace_test/asyncStar: Crash # (runTests()async{awa... cannot handle async/sync*/async* functions
async_stacktrace_test/none: Crash # (runTests()async{awa... cannot handle async/sync*/async* functions
-bounds_check_test/none: RuntimeError # Please triage this failure.
closure5_test: RuntimeError # Cannot read property 'prototype' of undefined
-closure_capture4_test: RuntimeError # Please triage this failure.
closure_capture5_test: Crash # (i=0): For-loop variable captured in loop header
-closure_type_reflection2_test: Crash # Internal Error: No default constructor available.
-closure_type_reflection_test: Crash # Internal Error: No default constructor available.
-compound_operator_index_test: RuntimeError # Please triage this failure.
conditional_send_test: RuntimeError # receiver.get$_collection$_nums is not a function
-conflict_index_test: RuntimeError # Please triage this failure.
deferred/deferred_class_test: RuntimeError # receiver.get$_collection$_nums is not a function
deferred/deferred_constant2_test: RuntimeError # receiver.get$_collection$_nums is not a function
deferred/deferred_constant3_test: RuntimeError # receiver.get$_collection$_nums is not a function
deferred/deferred_constant4_test: RuntimeError # receiver.get$_collection$_nums is not a function
deferred/deferred_function_test: RuntimeError # receiver.get$_collection$_nums is not a function
deferred/deferred_mirrors1_test: RuntimeError # receiver.get$_collection$_nums is not a function
-deferred/deferred_mirrors2_test: Crash # Internal Error: No default constructor available.
+deferred/deferred_mirrors2_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
deferred/deferred_overlapping_test: RuntimeError # receiver.get$_collection$_nums is not a function
-deferred_fail_and_retry_test: Crash # Internal Error: No default constructor available.
-deferred_fail_and_retry_worker_test: Crash # Internal Error: No default constructor available.
for_test: RuntimeError # Please triage this failure.
if_null_test: RuntimeError # receiver.get$_collection$_nums is not a function
-index_test: RuntimeError # Please triage this failure.
-int_index_test/none: RuntimeError # Please triage this failure.
-invalid_length_negative_test: Fail # Please triage this failure.
-is_check_instanceof_test: RuntimeError # Please triage this failure.
-list_factory_test: RuntimeError # Please triage this failure.
-mirror_invalid_field_access2_test: RuntimeError # Please triage this failure.
mirror_invalid_field_access3_test: Crash # Internal Error: No default constructor available.
-mirror_invalid_field_access4_test: RuntimeError # Please triage this failure.
mirror_invalid_field_access_test: Crash # Internal Error: No default constructor available.
mirror_invalid_invoke3_test: Crash # Internal Error: No default constructor available.
mirror_invalid_invoke_test: Crash # Internal Error: No default constructor available.
@@ -117,14 +97,12 @@
mirror_type_inference_field2_test: Crash # Internal Error: No default constructor available.
mirror_type_inference_field_test: Crash # Internal Error: No default constructor available.
mirror_type_inference_function_test: Crash # Internal Error: No default constructor available.
-mirrors_declarations_filtering_test: Crash # Internal Error: No default constructor available.
-mirrors_used_native_test: RuntimeError # Please triage this failure.
-mirrors_used_warning2_test: RuntimeError # receiver.get$_nums is not a function
-mirrors_used_warning_test/minif: RuntimeError # receiver.get$_nums is not a function
-mirrors_used_warning_test/none: RuntimeError # receiver.get$_nums is not a function
-no_such_method_mirrors_test: RuntimeError # Please triage this failure.
+mirrors_used_warning2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+mirrors_used_warning_test/minif : RuntimeError # TypeError: receiver.get$_nums is not a function
+mirrors_used_warning_test/none : RuntimeError # TypeError: receiver.get$_nums is not a function
reflect_native_types_test: Crash # Internal Error: No default constructor available.
runtime_type_test: RuntimeError # Cannot read property 'prototype' of undefined
-string_interpolation_opt1_test: RuntimeError # Please triage this failure.
switch_test/none: Crash # (switch (val){foo:ba... continue to a labeled switch case
timer_test: RuntimeError # receiver.get$_collection$_nums is not a function
+no_such_method_test : Crash # Internal Error: No default constructor available.
+mirrors_used_closure_test : Crash # Internal Error: No default constructor available.
diff --git a/tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart b/tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart
index 03d4725..60702c4 100644
--- a/tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart
+++ b/tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// Note: This test relies on LF line endings in the source file.
+
import "package:expect/expect.dart";
main() {
diff --git a/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart b/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart
index 14ff9a5..461bcfe 100644
--- a/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart
+++ b/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart
Binary files differ
diff --git a/tests/compiler/dart2js_extra/string_interpolation_test.dart b/tests/compiler/dart2js_extra/string_interpolation_test.dart
index 7552214..b8350e1 100644
--- a/tests/compiler/dart2js_extra/string_interpolation_test.dart
+++ b/tests/compiler/dart2js_extra/string_interpolation_test.dart
Binary files differ
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index 9798091..bb3bb85 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -23,17 +23,14 @@
[ $compiler == dart2js && $cps_ir ]
compute_this_script_test: RuntimeError # receiver.get$_collection$_nums is not a function
event_loop_test: RuntimeError # receiver.get$_collection$_nums is not a function
-inference_of_helper_methods_test: RuntimeError # Please triage this failure.
internal_library_test: RuntimeError # receiver.get$_collection$_nums is not a function
mirror_intercepted_field_test: Crash # Internal Error: No default constructor available.
native_closure_identity_frog_test: RuntimeError # invoke is not a function
-native_exception2_test: RuntimeError # Please triage this failure.
native_exception_test: RuntimeError # J.getInterceptor(...).toString$0 is not a function
native_method_inlining_test: RuntimeError # Please triage this failure.
native_mirror_test: Crash # Internal Error: No default constructor available.
native_mixin_field_test: RuntimeError # Please triage this failure.
-native_mixin_with_plain_test: RuntimeError # Please triage this failure.
-native_no_such_method_exception3_frog_test: RuntimeError # Please triage this failure.
+native_no_such_method_exception3_frog_test : RuntimeError #
native_wrapping_function3_frog_test: RuntimeError # invoke is not a function
native_wrapping_function_frog_test: RuntimeError # invoke is not a function
optimization_hints_test: RuntimeError # Please triage this failure.
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index b9428c1..693a690 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -36,6 +36,9 @@
int_parse_radix_test/02: Fail # No bigints.
double_parse_test/01: Pass, Fail # JS implementations disagree on U+0085 being whitespace.
integer_to_radix_string_test: RuntimeError # issue 22045
+int_modulo_arith_test/bignum: RuntimeError # No bigints.
+int_modulo_arith_test/modPow: RuntimeError # No bigints.
+
# With the exception of 'void', const Symbol() should not accept reserved
# words.
@@ -210,133 +213,47 @@
big_integer_parsed_mul_div_vm_test: Pass, Slow
[ $compiler == dart2js && $cps_ir ]
-apply2_test: RuntimeError # Please triage this failure.
-apply3_test: RuntimeError # Please triage this failure.
-apply4_test: RuntimeError # Please triage this failure.
-apply_test: RuntimeError # Please triage this failure.
-collection_from_test: RuntimeError # Please triage this failure.
-collection_length_test: RuntimeError # Please triage this failure.
-collection_removes_test: RuntimeError # Please triage this failure.
-collection_test: RuntimeError # Please triage this failure.
-collection_to_string_test: RuntimeError # Please triage this failure.
-core_runtime_types_test: RuntimeError # Please triage this failure.
date_time2_test: RuntimeError # Cannot read property 'prototype' of undefined
date_time3_test: RuntimeError # Cannot read property 'prototype' of undefined
date_time4_test: RuntimeError # Cannot read property 'prototype' of undefined
date_time7_test: RuntimeError # Cannot read property 'prototype' of undefined
date_time_parse_test: RuntimeError # Cannot read property 'prototype' of undefined
error_stack_trace1_test: Pass # H.unwrapException(...).get$stackTrace is not a function
-for_in_test: RuntimeError # Please triage this failure.
-hash_set_test/none: RuntimeError # Please triage this failure.
hashcode_test: RuntimeError # Please triage this failure.
-indexed_list_access_test: RuntimeError # Please triage this failure.
int_parse_radix_test/01: Crash # Invalid argument(s)
int_parse_radix_test/02: Crash # Invalid argument(s)
-int_parse_radix_test/none: Crash # Invalid argument(s)
-iterable_contains_test: RuntimeError # Please triage this failure.
iterable_empty_test: RuntimeError # Please triage this failure.
-iterable_fold_test: RuntimeError # Please triage this failure.
-iterable_join_test: RuntimeError # Please triage this failure.
-iterable_mapping_test: RuntimeError # Please triage this failure.
-iterable_reduce_test: RuntimeError # Please triage this failure.
iterable_return_type_test/none: RuntimeError # Please triage this failure.
-iterable_skip_test: RuntimeError # Please triage this failure.
-iterable_test: RuntimeError # Please triage this failure.
iterable_to_list_test: RuntimeError # Please triage this failure.
iterable_to_set_test: RuntimeError # Please triage this failure.
-iterable_tostring_test: RuntimeError # Please triage this failure.
-json_map_test: Crash # Internal Error: No default constructor available.
-linked_hash_map_test: RuntimeError # Please triage this failure.
-list_as_map_test: RuntimeError # Please triage this failure.
-list_contains_argument_order_test: RuntimeError # Please triage this failure.
-list_fill_range_test: RuntimeError # Please triage this failure.
-list_for_each_test: RuntimeError # Please triage this failure.
-list_get_range_test: RuntimeError # Please triage this failure.
-list_growable_test: RuntimeError # Please triage this failure.
-list_index_of2_test: RuntimeError # Please triage this failure.
-list_index_of_test: RuntimeError # Please triage this failure.
-list_insert_all_test: RuntimeError # Please triage this failure.
-list_insert_test: RuntimeError # Please triage this failure.
-list_iterators_test: RuntimeError # Please triage this failure.
-list_literal_is_growable_test: RuntimeError # Please triage this failure.
-list_literal_test: RuntimeError # Please triage this failure.
-list_map_test: RuntimeError # Please triage this failure.
-list_remove_range_test: RuntimeError # Please triage this failure.
-list_removeat_test: RuntimeError # Please triage this failure.
-list_replace_range_test: RuntimeError # Please triage this failure.
-list_reversed_test: RuntimeError # Please triage this failure.
-list_set_all_test: RuntimeError # Please triage this failure.
-list_set_range_test: RuntimeError # Please triage this failure.
-list_sort_test: RuntimeError # Please triage this failure.
list_test/01: RuntimeError # this.get$length is not a function
list_test/none: RuntimeError # this.get$length is not a function
-list_to_string2_test: RuntimeError # Please triage this failure.
-list_unmodifiable_test: RuntimeError # Please triage this failure.
main_test: RuntimeError # receiver.get$_collection$_nums is not a function
-map_test: Crash # Internal Error: No default constructor available.
map_values2_test: RuntimeError # Please triage this failure.
map_values3_test: RuntimeError # Please triage this failure.
map_values4_test: RuntimeError # Please triage this failure.
null_test: RuntimeError # Cannot read property 'prototype' of undefined
-queue_first_test: RuntimeError # Please triage this failure.
-queue_iterator_test: RuntimeError # Please triage this failure.
-queue_last_test: RuntimeError # Please triage this failure.
-queue_single_test: RuntimeError # Please triage this failure.
-queue_test: RuntimeError # Please triage this failure.
-range_error_test: RuntimeError # Please triage this failure.
reg_exp_first_match_test: RuntimeError # Cannot read property 'prototype' of undefined
reg_exp_group_test: RuntimeError # Cannot read property 'prototype' of undefined
-reg_exp_groups_test: RuntimeError # Please triage this failure.
reg_exp_string_match_test: RuntimeError # Cannot read property 'prototype' of undefined
regexp/capture-3_test: RuntimeError # Cannot read property 'prototype' of undefined
-regexp/capture_test: RuntimeError # Please triage this failure.
regexp/extended-characters-match_test: RuntimeError # Cannot read property 'prototype' of undefined
-regexp/global_test: RuntimeError # Please triage this failure.
-regexp/many-brackets_test: RuntimeError # Please triage this failure.
regexp/non-bmp_test: RuntimeError # Cannot read property 'prototype' of undefined
-regexp/non-capturing-groups_test: RuntimeError # Please triage this failure.
regexp/pcre_test: Crash # Stack Overflow
-regexp/regexp_test: RuntimeError # Please triage this failure.
regexp/regress-regexp-construct-result_test: RuntimeError # Cannot read property 'prototype' of undefined
regexp/results-cache_test: RuntimeError # Cannot read property 'prototype' of undefined
-regexp/stack-overflow2_test: RuntimeError # Please triage this failure.
regexp/stack-overflow_test: RuntimeError # Cannot read property 'prototype' of undefined
regexp/unicode-handling_test: RuntimeError # Cannot read property 'prototype' of undefined
-regress_11099_test: RuntimeError # Please triage this failure.
-set_test: RuntimeError # Please triage this failure.
-set_to_string_test: RuntimeError # Please triage this failure.
shuffle_test: RuntimeError # Please triage this failure.
-sort_test: RuntimeError # Please triage this failure.
-splay_tree_test: RuntimeError # Please triage this failure.
stacktrace_fromstring_test: RuntimeError # receiver.get$_collection$_nums is not a function
stopwatch2_test: RuntimeError # Cannot read property 'prototype' of undefined
stopwatch_test: RuntimeError # Cannot read property 'prototype' of undefined
-string_codeunits_test: RuntimeError # Please triage this failure.
-string_from_list_test: RuntimeError # Please triage this failure.
string_fromcharcodes_test: RuntimeError # Please triage this failure.
-string_pattern_test: RuntimeError # Please triage this failure.
string_replace_all_test: RuntimeError # Cannot read property 'prototype' of undefined
-string_replace_test: RuntimeError # Please triage this failure.
-string_runes_test: RuntimeError # Please triage this failure.
-string_source_test: RuntimeError # Please triage this failure.
-string_split_test: RuntimeError # Please triage this failure.
-string_test: RuntimeError # Please triage this failure.
-string_to_lower_case_test: RuntimeError # Please triage this failure.
-strings_test: RuntimeError # Please triage this failure.
-symbol_operator_test/03: RuntimeError # Please triage this failure.
+symbol_operator_test/03 : RuntimeError #
symbol_reserved_word_test/03: Pass # Please triage this failure.
symbol_reserved_word_test/06: RuntimeError # Please triage this failure.
symbol_reserved_word_test/09: RuntimeError # Please triage this failure.
symbol_reserved_word_test/12: RuntimeError # Please triage this failure.
symbol_test/none: Crash # The null object does not have a getter '_element'.
-uri_base_test: Crash # Invalid argument(s)
-uri_file_test: Crash # Invalid argument(s)
-uri_http_test: Crash # Invalid argument(s)
-uri_ipv4_test: RuntimeError # Please triage this failure.
-uri_ipv6_test: Crash # Invalid argument(s)
-uri_normalize_path_test: RuntimeError # Please triage this failure.
-uri_parse_test: Crash # Invalid argument(s)
-uri_path_test: Crash # Invalid argument(s)
-uri_query_test: Crash # Internal Error: No default constructor available.
-uri_scheme_test: Crash # Invalid argument(s)
uri_test: Crash # Invalid argument(s)
diff --git a/tests/corelib/int_modulo_arith_test.dart b/tests/corelib/int_modulo_arith_test.dart
new file mode 100644
index 0000000..87d253d
--- /dev/null
+++ b/tests/corelib/int_modulo_arith_test.dart
@@ -0,0 +1,207 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "dart:math" show pow;
+
+var smallNumber = 1234567890; // is 31-bit integer.
+var mediumNumber = 1234567890123456; // is 53-bit integer
+var bigNumber = 590295810358705600000; // is > 64-bit integer, exact as double.
+
+testModPow() {
+ test(x, e, m, expectedResult) {
+ // Check that expected result is correct, using an unoptimized version.
+ assert(() {
+ if (1 is double) return true; // Don't have bignums.
+ slowModPow(x, e, m) {
+ var r = 1;
+ while (e > 0) {
+ if (e.isOdd) r = (r * x) % m;
+ e >>= 1;
+ x = (x * x) % m;
+ }
+ return r;
+ }
+ return slowModPow(x, e, m) == expectedResult;
+ });
+ var result = x.modPow(e, m);
+ Expect.equals(expectedResult, result, "$x.modPow($e, $m)");
+ }
+
+ test(10, 20, 1, 0);
+ test(1234567890, 1000000001, 19, 11);
+ test(1234567890, 19, 1000000001, 122998977);
+ test(19, 1234567890, 1000000001, 619059596);
+ test(19, 1000000001, 1234567890, 84910879);
+ test(1000000001, 19, 1234567890, 872984351);
+ test(1000000001, 1234567890, 19, 0);
+ test(12345678901234567890, 10000000000000000001, 19, 2);
+ test(12345678901234567890, 19, 10000000000000000001, 3239137215315834625);
+ test(19, 12345678901234567890, 10000000000000000001, 4544207837373941034);
+ test(19, 10000000000000000001, 12345678901234567890, 11135411705397624859);
+ test(10000000000000000001, 19, 12345678901234567890, 2034013733189773841);
+ test(10000000000000000001, 12345678901234567890, 19, 1);
+ test(12345678901234567890, 19, 10000000000000000001, 3239137215315834625);
+ test(12345678901234567890, 10000000000000000001, 19, 2);
+ test(123456789012345678901234567890,
+ 123456789012345678901234567891,
+ 123456789012345678901234567899,
+ 116401406051033429924651549616);
+ test(123456789012345678901234567890,
+ 123456789012345678901234567899,
+ 123456789012345678901234567891,
+ 123456789012345678901234567890);
+ test(123456789012345678901234567899,
+ 123456789012345678901234567890,
+ 123456789012345678901234567891,
+ 35088523091000351053091545070);
+ test(123456789012345678901234567899,
+ 123456789012345678901234567891,
+ 123456789012345678901234567890,
+ 18310047270234132455316941949);
+ test(123456789012345678901234567891,
+ 123456789012345678901234567899,
+ 123456789012345678901234567890,
+ 1);
+ test(123456789012345678901234567891,
+ 123456789012345678901234567890,
+ 123456789012345678901234567899,
+ 40128068573873018143207285483);
+
+}
+
+testModInverse() {
+ test(x, m, expectedResult) {
+ //print("$x op $m == $expectedResult");
+ // Check that expectedResult is an inverse.
+ assert(expectedResult < m);
+ // The 1 % m handles the m = 1 special case.
+ // This test may overflow if we don't have bignums, so only run on VM.
+ assert(1 is double || (((x % m) * expectedResult) - 1) % m == 0);
+
+ var result = x.modInverse(m);
+ Expect.equals(expectedResult, result, "$x modinv $m");
+
+ if (x > m) {
+ x = x % m;
+ var result = x.modInverse(m);
+ Expect.equals(expectedResult, result, "$x modinv $m");
+ }
+ }
+
+ testThrows(x, m) {
+ // Throws if not co-prime, which is a symmetric property.
+ Expect.throws(() => x.modInverse(m), null, "$x modinv $m");
+ Expect.throws(() => m.modInverse(x), null, "$m modinv $x");
+ }
+
+ test(1, 1, 0);
+
+ testThrows(0, 1000000001);
+ testThrows(2, 4);
+ testThrows(99, 9);
+ testThrows(19, 1000000001);
+ testThrows(123456789012345678901234567890, 123456789012345678901234567899);
+
+ // Co-prime numbers
+ test(1234567890, 19, 11);
+ test(1234567890, 1000000001, 189108911);
+ test(19, 1234567890, 519818059);
+ test(1000000001, 1234567890, 1001100101);
+
+ test(12345, 12346, 12345);
+ test(12345, 12346, 12345);
+
+ test(smallNumber, 137, 42);
+ test(137, smallNumber, 856087223);
+ test(mediumNumber, 137, 77);
+ test(137, mediumNumber, 540686667207353);
+ test(bigNumber, 137, 128); /// bignum: ok
+ // Bigger numbers as modulo is tested in big_integer_arith_vm_test.dart.
+ // Big doubles are not co-prime, so there is nothing to test for dart2js.
+}
+
+testGcd() {
+ // Call testFunc with all combinations and orders of plus/minus
+ // value and other.
+ callCombos(value, other, testFunc) {
+ testFunc(value, other);
+ testFunc(value, -other);
+ testFunc(-value, other);
+ testFunc(-value, -other);
+ if (value == other) return;
+ testFunc(other, value);
+ testFunc(other, -value);
+ testFunc(-other, value);
+ testFunc(-other, -value);
+ }
+
+ // Test that gcd of value and other (non-negative) is expectedResult.
+ // Tests all combinations of positive and negative values and order of
+ // operands, so use positive values and order is not important.
+ test(value, other, [expectedResult]) {
+ assert(value % expectedResult == 0); // Check for bug in test.
+ assert(other % expectedResult == 0);
+ callCombos(value, other, (a, b) {
+ var result = a.gcd(b);
+ /// Check that the result is a divisor.
+ Expect.equals(0, a % result, "$result | $a");
+ Expect.equals(0, b % result, "$result | $b");
+ // Check for bug in test. If assert fails, the expected value is too low,
+ // and the gcd call has found a greater common divisor.
+ assert(result >= expectedResult);
+ Expect.equals(expectedResult, result, "$a.gcd($b)");
+ });
+ }
+
+ // Test that gcd of value and other (non-negative) throws.
+ testThrows(value, other) {
+ callCombos(value, other, (a, b) {
+ Expect.throws(() => a.gcd(b), null, "$a.gcd($b)");
+ });
+ }
+
+ // Throws if either operand is zero, and if both operands are zero.
+ testThrows(0, 1000);
+ testThrows(0, 0);
+
+ // Format:
+ // test(value1, value2, expectedResult);
+ test(1, 1, 1); // both are 1
+ test(1, 2, 1); // one is 1
+ test(3, 5, 1); // coprime.
+ test(37, 37, 37); // Same larger prime.
+
+ test(9999, 7272, 909); // Larger numbers
+
+ // Multiplying both operands by a number multiplies result by same number.
+ test(693, 609, 21);
+ test(693 << 5, 609 << 5, 21 << 5);
+ test(693 * 937, 609 * 937, 21 * 937);
+ test(693 * pow(2, 32), 609 * pow(2, 32), 21 * pow(2, 32));
+ test(693 * pow(2, 52), 609 * pow(2, 52), 21 * pow(2, 52));
+ test(693 * pow(2, 53), 609 * pow(2, 53), 21 * pow(2, 53)); // Regression.
+ test(693 * pow(2, 99), 609 * pow(2, 99), 21 * pow(2, 99));
+
+ test(1234567890, 19, 1);
+ test(1234567890, 1000000001, 1);
+ test(19, 1000000001, 19);
+
+ test(0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF);
+ test(0x3FFFFFFF, 0x40000000, 1);
+
+ test(pow(2, 54), pow(2, 53), pow(2, 53));
+
+ test((pow(2, 52) - 1) * pow(2, 14),
+ (pow(2, 26) - 1) * pow(2, 22),
+ (pow(2, 26) - 1) * pow(2, 14));
+}
+
+main() {
+ testModPow(); /// modPow: ok
+ testModInverse();
+ testGcd();
+}
+
diff --git a/tests/html/html.status b/tests/html/html.status
index 8814b56..1dd6339 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -6,6 +6,9 @@
dromaeo_smoke_test: Skip # Issue 14521, 8257
cross_frame_test: Skip # Test reloads itself. Issue 18558
+js_array_test: Skip # Issue 23676, 23677
+js_typed_interop_test: Skip # Issue 23676, 23677
+
[ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
custom/attribute_changed_callback_test/unsupported_on_polyfill: Fail # Issue 18931 (Disabled for Chrome 35 roll)
form_data_test/functional: Skip # Issue 19726
@@ -414,150 +417,3 @@
window_nosuchmethod_test: StaticWarning
[ $compiler == dart2js && $cps_ir ]
-async_spawnuri_test: Crash # Invalid argument(s)
-async_test: Crash # Invalid argument(s)
-audiobuffersourcenode_test: Crash # Invalid argument(s)
-audiocontext_test: Crash # Invalid argument(s)
-audioelement_test: Crash # Invalid argument(s)
-b_element_test: Crash # Invalid argument(s)
-blob_constructor_test: Crash # Invalid argument(s)
-cache_test: Crash # Invalid argument(s)
-callbacks_test: Crash # Invalid argument(s)
-canvas_pixel_array_type_alias_test: Crash # Invalid argument(s)
-canvas_test: Crash # Invalid argument(s)
-canvasrenderingcontext2d_test: Crash # Invalid argument(s)
-cdata_test: Crash # Invalid argument(s)
-client_rect_test: Crash # Invalid argument(s)
-cross_domain_iframe_test: Crash # Invalid argument(s)
-crypto_test: Crash # Invalid argument(s)
-css_rule_list_test: Crash # Invalid argument(s)
-css_test: Crash # Invalid argument(s)
-cssstyledeclaration_test: Crash # Invalid argument(s)
-custom/attribute_changed_callback_test: Crash # Invalid argument(s)
-custom/constructor_calls_created_synchronously_test: Crash # Invalid argument(s)
-custom/created_callback_test: Crash # Invalid argument(s)
-custom/document_register_basic_test: Crash # Invalid argument(s)
-custom/document_register_type_extensions_test: Crash # Invalid argument(s)
-custom/element_upgrade_test: Crash # Invalid argument(s)
-custom/entered_left_view_test: Crash # Invalid argument(s)
-custom/js_custom_test: Crash # Invalid argument(s)
-custom/mirrors_test: Crash # Invalid argument(s)
-custom/regress_194523002_test: Crash # Internal Error: No default constructor available.
-custom_element_method_clash_test: Crash # Invalid argument(s)
-custom_element_name_clash_test: Crash # Invalid argument(s)
-custom_elements_23127_test: Crash # Invalid argument(s)
-custom_elements_test: Crash # Invalid argument(s)
-custom_tags_test: Crash # Invalid argument(s)
-dart_object_local_storage_test: Crash # Invalid argument(s)
-datalistelement_test: Crash # Invalid argument(s)
-document_test: Crash # Invalid argument(s)
-documentfragment_test: Crash # Invalid argument(s)
-dom_constructors_test: Crash # Invalid argument(s)
-domparser_test: Crash # Invalid argument(s)
-element_add_test: Crash # Invalid argument(s)
-element_animate_test: Crash # Invalid argument(s)
-element_classes_svg_test: Crash # Invalid argument(s)
-element_classes_test: Crash # Invalid argument(s)
-element_constructor_1_test: Crash # Invalid argument(s)
-element_dimensions_test: Crash # Invalid argument(s)
-element_offset_test: Crash # Invalid argument(s)
-element_test: Crash # Invalid argument(s)
-element_types_constructors1_test: Crash # Invalid argument(s)
-element_types_constructors2_test: Crash # Invalid argument(s)
-element_types_constructors3_test: Crash # Invalid argument(s)
-element_types_constructors4_test: Crash # Invalid argument(s)
-element_types_constructors5_test: Crash # Invalid argument(s)
-element_types_constructors6_test: Crash # Invalid argument(s)
-element_types_test: Crash # Invalid argument(s)
-event_customevent_test: Crash # Invalid argument(s)
-event_test: Crash # Invalid argument(s)
-events_test: Crash # Invalid argument(s)
-exceptions_test: Crash # Invalid argument(s)
-fileapi_test: Crash # Invalid argument(s)
-filereader_test: Crash # Invalid argument(s)
-fontface_loaded_test: Crash # Invalid argument(s)
-fontface_test: Crash # Invalid argument(s)
-form_data_test: Crash # Invalid argument(s)
-form_element_test: Crash # Invalid argument(s)
-geolocation_test: Crash # Invalid argument(s)
-hidden_dom_1_test: Crash # Invalid argument(s)
-hidden_dom_2_test: Crash # Invalid argument(s)
-history_test: Crash # Invalid argument(s)
-htmlcollection_test: Crash # Invalid argument(s)
-htmlelement_test: Crash # Invalid argument(s)
-htmloptionscollection_test: Crash # Invalid argument(s)
-indexeddb_1_test: Crash # Invalid argument(s)
-indexeddb_2_test: Crash # Invalid argument(s)
-indexeddb_3_test: Crash # Invalid argument(s)
-indexeddb_4_test: Crash # Invalid argument(s)
-indexeddb_5_test: Crash # Invalid argument(s)
-input_element_test: Crash # Invalid argument(s)
-instance_of_test: Crash # Invalid argument(s)
-isolates_test: Crash # Invalid argument(s)
-js_interop_1_test: Crash # Invalid argument(s)
-js_test: Crash # Invalid argument(s)
-keyboard_event_test: Crash # Invalid argument(s)
-localstorage_test: Crash # Invalid argument(s)
-location_test: Crash # Invalid argument(s)
-media_stream_test: Crash # Invalid argument(s)
-mediasource_test: Crash # Invalid argument(s)
-messageevent_test: Crash # Invalid argument(s)
-mouse_event_test: Crash # Invalid argument(s)
-mutationobserver_test: Crash # Invalid argument(s)
-native_gc_test: Crash # Invalid argument(s)
-navigator_test: Crash # Invalid argument(s)
-node_test: Crash # Invalid argument(s)
-node_validator_important_if_you_suppress_make_the_bug_critical_test: Crash # Invalid argument(s)
-non_instantiated_is_test: Crash # Invalid argument(s)
-notification_test: Crash # Invalid argument(s)
-performance_api_test: Crash # Invalid argument(s)
-postmessage_structured_test: Crash # Invalid argument(s)
-query_test: Crash # Invalid argument(s)
-queryall_test: Crash # Invalid argument(s)
-range_test: Crash # Invalid argument(s)
-request_animation_frame_test: Crash # Invalid argument(s)
-rtc_test: Crash # Invalid argument(s)
-selectelement_test: Crash # Invalid argument(s)
-serialized_script_value_test: Crash # Invalid argument(s)
-shadow_dom_test: Crash # Invalid argument(s)
-shadowroot_test: Crash # Invalid argument(s)
-speechrecognition_test: Crash # Invalid argument(s)
-storage_quota_test/missingenumcheck: Crash # Invalid argument(s)
-storage_quota_test/none: Crash # Invalid argument(s)
-storage_test: Crash # Invalid argument(s)
-streams_test: Crash # Invalid argument(s)
-svg_test: Crash # Invalid argument(s)
-svgelement_test: Crash # Invalid argument(s)
-table_test: Crash # Invalid argument(s)
-text_event_test: Crash # Invalid argument(s)
-touchevent_test: Crash # Invalid argument(s)
-track_element_constructor_test: Crash # Invalid argument(s)
-transferables_test: Crash # Invalid argument(s)
-transition_event_test: Crash # Invalid argument(s)
-trusted_html_tree_sanitizer_test: Crash # Invalid argument(s)
-typed_arrays_1_test: Crash # Invalid argument(s)
-typed_arrays_2_test: Crash # Invalid argument(s)
-typed_arrays_3_test: Crash # Invalid argument(s)
-typed_arrays_4_test: Crash # Invalid argument(s)
-typed_arrays_5_test: Crash # Invalid argument(s)
-typed_arrays_arraybuffer_test: Crash # Invalid argument(s)
-typed_arrays_dataview_test: Crash # Invalid argument(s)
-typed_arrays_range_checks_test: Crash # Invalid argument(s)
-typed_arrays_simd_test: Crash # Invalid argument(s)
-typing_test: Crash # Invalid argument(s)
-unknownelement_test: Crash # Invalid argument(s)
-uri_test: Crash # Invalid argument(s)
-url_test: Crash # Invalid argument(s)
-webgl_1_test: Crash # Invalid argument(s)
-websocket_test: Crash # Invalid argument(s)
-websql_test: Crash # Invalid argument(s)
-wheelevent_test: Crash # Invalid argument(s)
-window_eq_test: Crash # Invalid argument(s)
-window_mangling_test: Crash # Invalid argument(s)
-window_nosuchmethod_test: Crash # Invalid argument(s)
-window_test: Crash # Invalid argument(s)
-worker_api_test: Crash # Invalid argument(s)
-worker_test: Crash # Invalid argument(s)
-xhr_cross_origin_test: Crash # Invalid argument(s)
-xhr_test: Crash # Invalid argument(s)
-xsltprocessor_test: Crash # Invalid argument(s)
diff --git a/tests/html/js_array_test.dart b/tests/html/js_array_test.dart
new file mode 100644
index 0000000..4ede8ed
--- /dev/null
+++ b/tests/html/js_array_test.dart
@@ -0,0 +1,594 @@
+// 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 jsArrayTest;
+
+import 'dart:html';
+import 'dart:js';
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+
+_injectJs() {
+ document.body.append(new ScriptElement()
+ ..type = 'text/javascript'
+ ..innerHtml = r"""
+function callJsMethod(jsObj, jsMethodName, args) {
+ return jsObj[jsMethodName].apply(jsObj, args);
+}
+
+function jsEnumerateIndices(obj) {
+ var ret = [];
+ for(var i in obj) {
+ ret.push(i);
+ }
+ return ret;
+}
+
+function setValue(obj, index, value) {
+ return obj[index] = value;
+}
+
+function getValue(obj, index) {
+ return obj[index];
+}
+
+function checkIsArray(obj) {
+ return Array.isArray(obj);
+}
+
+function concatValues(obj) {
+ return obj.concat("a", "b", ["c", "d"], 42, {foo: 10});
+}
+
+function concatOntoArray(obj) {
+ return [1,2,3].concat(obj, "foo");
+}
+
+function repeatedConcatOntoArray(obj) {
+ return [1,2,3].concat(obj, obj);
+}
+
+function everyGreaterThanZero(obj) {
+ return obj.every(function(currentValue, index, array) {
+ return currentValue > 0;
+ });
+}
+
+function everyGreaterThanZeroCheckThisArg(obj) {
+ var j = 0;
+ return obj.every(function(currentValue, index, array) {
+ if (j != index) {
+ throw "Unxpected index";
+ }
+ j++;
+ if (array !== obj) {
+ throw "Array argument doesn't match obj";
+ }
+ return currentValue > 0;
+ });
+}
+
+function filterGreater42(obj) {
+ return obj.filter(function(currentValue, index, array) {
+ return currentValue > 42;
+ });
+}
+
+function forEachCollectResult(array, callback) {
+ var result = [];
+ array.forEach(function(currentValue) {
+ result.push(currentValue * 2);
+ });
+ return result;
+}
+
+function someEqual42(array, callback) {
+ return array.some(function(currentValue) {
+ return currentValue == 42;
+ });
+}
+
+function sortNumbersBackwards(array) {
+ return array.sort(function(a, b) {
+ return b - a;
+ });
+}
+
+function spliceDummyItems(array) {
+ return array.splice(1, 2, "quick" ,"brown", "fox");
+}
+
+function spliceTestStringArgs(array) {
+ return array.splice("1.2", "2.01", "quick" ,"brown", "fox");
+}
+
+function splicePastEnd(array) {
+ return array.splice(1, 5332, "quick" ,"brown", "fox");
+}
+
+function callJsToString(array) {
+ return array.toString();
+}
+
+function mapAddIndexToEachElement(array) {
+ return array.map(function(currentValue, index) {
+ return currentValue + index;
+ });
+}
+
+function reduceSumDoubledElements(array) {
+ return array.reduce(function(previousValue, currentValue) {
+ return previousValue + currentValue*2;
+ },
+ 0);
+}
+
+// TODO(jacobr): add a test that distinguishes reduce from reduceRight.
+function reduceRightSumDoubledElements(array) {
+ return array.reduceRight(function(previousValue, currentValue) {
+ return previousValue + currentValue*2;
+ },
+ 0);
+}
+
+function identical(o1, o2) {
+ return o1 === o2;
+}
+
+function getOwnPropertyDescriptorJson(array, property) {
+ return JSON.stringify(Object.getOwnPropertyDescriptor(array, property));
+}
+
+function setLength(array, len) {
+ return array.length = len;
+}
+
+function jsonStringify(o) {
+ return JSON.stringify(o);
+}
+
+// Calling a method from Dart List on an arbitrary target object.
+function callListMethodOnTarget(dartArray, target, methodName, args) {
+ return dartArray[methodName].apply(target, args);
+}
+
+""");
+}
+
+class Foo {}
+
+callJsMethod(List array, String methodName, List args) =>
+ context.callMethod("callJsMethod", [array, methodName, args]);
+
+callIndexOf(List array, value) => callJsMethod(array, "indexOf", [value]);
+callLastIndexOf(List array, value) =>
+ callJsMethod(array, "lastIndexOf", [value]);
+
+callPop(List array) => callJsMethod(array, "pop", []);
+callPush(List array, element) => callJsMethod(array, "push", [element]);
+callShift(List array) => callJsMethod(array, "shift", []);
+callReverse(List array) => callJsMethod(array, "reverse", []);
+callSetLength(List array, length) =>
+ context.callMethod("setLength", [array, length]);
+
+callListMethodOnObject(JsObject object, String methodName, List args) => context
+ .callMethod("callListMethodOnTarget", [[], object, methodName, args]);
+
+jsonStringify(JsObject object) => context.callMethod("jsonStringify", [object]);
+
+main() {
+ _injectJs();
+ useHtmlConfiguration();
+
+ group('indexOf', () {
+ var div = new DivElement();
+ var list = [3, 42, "foo", 42, div];
+ test('found', () {
+ expect(callIndexOf(list, 3), equals(0));
+ expect(callIndexOf(list, 42), equals(1));
+ expect(callIndexOf(list, "foo"), equals(2));
+ expect(callIndexOf(list, div), equals(4));
+ });
+
+ test('missing', () {
+ expect(callIndexOf(list, 31), equals(-1));
+ expect(callIndexOf(list, "42"), equals(-1));
+ expect(callIndexOf(list, null), equals(-1));
+ });
+ });
+
+ group('set length', () {
+ test('larger', () {
+ var list = ["a", "b", "c", "d"];
+ expect(callSetLength(list, 10), equals(10));
+ expect(list.length, equals(10));
+ expect(list.last, equals(null));
+ expect(list[3], equals("d"));
+ });
+
+ test('smaller', () {
+ var list = ["a", "b", "c", "d"];
+ expect(callSetLength(list, 2), equals(2));
+ expect(list.first, equals("a"));
+ expect(list.last, equals("b"));
+ expect(list.length, equals(2));
+ expect(callSetLength(list, 0), equals(0));
+ expect(list.length, equals(0));
+ expect(callSetLength(list, 2), equals(2));
+ expect(list.first, equals(null));
+ });
+
+ test('invalid', () {
+ var list = ["a", "b", "c", "d"];
+ expect(() => callSetLength(list, 2.3), throws);
+ expect(list.length, equals(4));
+ expect(() => callSetLength(list, -1), throws);
+ expect(list.length, equals(4));
+ // Make sure we are coercing to a JS number.
+ expect(callSetLength(list, "2"), equals("2"));
+ expect(list.length, equals(2));
+ });
+ });
+
+ group('join', () {
+ var list = [3, 42, "foo"];
+ var listWithDartClasses = [3, new Foo(), 42, "foo", new Object()];
+ test('default', () {
+ expect(callJsMethod(list, "join", []), equals("3,42,foo"));
+ expect(callJsMethod(listWithDartClasses, "join", []),
+ equals("3,Instance of 'Foo',42,foo,Instance of 'Object'"));
+ });
+
+ test('custom separator', () {
+ expect(callJsMethod(list, "join", ["##"]), equals("3##42##foo"));
+ });
+ });
+
+ group('lastIndexOf', () {
+ var list = [3, 42, "foo", 42];
+ test('found', () {
+ expect(callLastIndexOf(list, 3), equals(0));
+ expect(callLastIndexOf(list, 42), equals(3));
+ expect(callLastIndexOf(list, "foo"), equals(2));
+ });
+
+ test('missing', () {
+ expect(callLastIndexOf(list, 31), equals(-1));
+ expect(callLastIndexOf(list, "42"), equals(-1));
+ expect(callLastIndexOf(list, null), equals(-1));
+ });
+ });
+
+ group('pop', () {
+ test('all', () {
+ var foo = new Foo();
+ var div = new DivElement();
+ var list = [3, 42, "foo", foo, div];
+ expect(callPop(list), equals(div));
+ expect(list.length, equals(4));
+ expect(callPop(list), equals(foo));
+ expect(list.length, equals(3));
+ expect(callPop(list), equals("foo"));
+ expect(list.length, equals(2));
+ expect(callPop(list), equals(42));
+ expect(list.length, equals(1));
+ expect(callPop(list), equals(3));
+ expect(list.length, equals(0));
+ expect(callPop(list), equals(null));
+ expect(list.length, equals(0));
+ });
+ });
+
+ group('push', () {
+ test('strings', () {
+ var list = [];
+ var div = new DivElement();
+ expect(callPush(list, "foo"), equals(1));
+ expect(callPush(list, "bar"), equals(2));
+ // Calling push with 0 elements should do nothing.
+ expect(callJsMethod(list, "push", []), equals(2));
+ expect(callPush(list, "baz"), equals(3));
+ expect(callPush(list, div), equals(4));
+ expect(callJsMethod(list, "push", ["a", "b"]), equals(6));
+ expect(list, equals(["foo", "bar", "baz", div, "a", "b"]));
+ });
+ });
+
+ group('shift', () {
+ test('all', () {
+ var foo = new Foo();
+ var div = new DivElement();
+ var list = [3, 42, "foo", foo, div];
+ expect(callShift(list), equals(3));
+ expect(list.length, equals(4));
+ expect(callShift(list), equals(42));
+ expect(list.length, equals(3));
+ expect(callShift(list), equals("foo"));
+ expect(list.length, equals(2));
+ expect(callShift(list), equals(foo));
+ expect(list.length, equals(1));
+ expect(callShift(list), equals(div));
+ expect(list.length, equals(0));
+ expect(callShift(list), equals(null));
+ expect(list.length, equals(0));
+ });
+ });
+
+ group('reverse', () {
+ test('simple', () {
+ var foo = new Foo();
+ var div = new DivElement();
+ var list = [div, 42, foo];
+ callReverse(list);
+ expect(list, equals([foo, 42, div]));
+ list = [3, 42];
+ callReverse(list);
+ expect(list, equals([42, 3]));
+ });
+ });
+
+ group('slice', () {
+ test('copy', () {
+ var foo = new Foo();
+ var div = new DivElement();
+ var list = [3, 42, "foo", foo, div];
+ var copy = callJsMethod(list, "slice", []);
+ expect(identical(list, copy), isFalse);
+ expect(copy.length, equals(list.length));
+ for (var i = 0; i < list.length; i++) {
+ expect(list[i], equals(copy[i]));
+ }
+ expect(identical(list[3], copy[3]), isTrue);
+ expect(identical(list[4], copy[4]), isTrue);
+
+ copy.add("dummy");
+ expect(list.length + 1, equals(copy.length));
+ });
+
+ test('specify start', () {
+ var list = [3, 42, "foo"];
+ var copy = callJsMethod(list, "slice", [1]);
+ expect(copy.first, equals(42));
+ });
+
+ test('specify start and end', () {
+ var list = [3, 42, 92, "foo"];
+ var copy = callJsMethod(list, "slice", [1, 3]);
+ expect(copy.first, equals(42));
+ expect(copy.last, equals(92));
+ });
+
+ test('from end', () {
+ var list = [3, 42, 92, "foo"];
+ expect(callJsMethod(list, "slice", [-2]), equals([92, "foo"]));
+
+ // Past the end of the front of the array.
+ expect(callJsMethod(list, "slice", [-2, 3]), equals([92]));
+
+ // Past the end of the front of the array.
+ expect(callJsMethod(list, "slice", [-10, 2]), equals([3, 42]));
+ });
+ });
+
+ group("js snippet tests", () {
+ test("enumerate indices", () {
+ var list = ["a", "b", "c", "d"];
+ var indices = context.callMethod('jsEnumerateIndices', [list]);
+ expect(indices.length, equals(4));
+ for (int i = 0; i < 4; i++) {
+ expect(indices[i], equals('$i'));
+ }
+ });
+
+ test("set element", () {
+ var list = ["a", "b", "c", "d"];
+ context.callMethod('setValue', [list, 0, 42]);
+ expect(list[0], equals(42));
+ context.callMethod('setValue', [list, 1, 84]);
+ expect(list[1], equals(84));
+ context.callMethod(
+ 'setValue', [list, 6, 100]); // Off the end of the list.
+ expect(list.length, equals(7));
+ expect(list[4], equals(null));
+ expect(list[6], equals(100));
+
+ // These tests have to be commented out because we don't persist
+ // JS proxies for Dart objects like we could/should.
+ // context.callMethod('setValue', [list, -1, "foo"]); // Not a valid array index
+ // expect(context.callMethod('getValue', [list, -1]), equals("foo"));
+ // expect(context.callMethod('getValue', [list, "-1"]), equals("foo"));
+ });
+
+ test("get element", () {
+ var list = ["a", "b", "c", "d"];
+ expect(context.callMethod('getValue', [list, 0]), equals("a"));
+ expect(context.callMethod('getValue', [list, 1]), equals("b"));
+ expect(context.callMethod('getValue', [list, 6]), equals(null));
+ expect(context.callMethod('getValue', [list, -1]), equals(null));
+
+ expect(context.callMethod('getValue', [list, "0"]), equals("a"));
+ expect(context.callMethod('getValue', [list, "1"]), equals("b"));
+ });
+
+ test("is array", () {
+ var list = ["a", "b"];
+ expect(context.callMethod("checkIsArray", [list]), isTrue);
+ });
+
+ test("property descriptors", () {
+ // This test matters to make behavior consistent with JS native arrays
+ // and to make devtools integration work well.
+ var list = ["a", "b"];
+ expect(context.callMethod("getOwnPropertyDescriptorJson", [list, 0]),
+ equals('{"value":"a",'
+ '"writable":true,'
+ '"enumerable":true,'
+ '"configurable":true}'));
+
+ expect(
+ context.callMethod("getOwnPropertyDescriptorJson", [list, "length"]),
+ equals('{"value":2,'
+ '"writable":true,'
+ '"enumerable":false,'
+ '"configurable":false}'));
+ });
+
+ test("concat js arrays", () {
+ var list = ["1", "2"];
+ // Tests that calling the concat method from JS will flatten out JS arrays
+ // We concat the array with "a", "b", ["c", "d"], 42, {foo: 10}
+ // which should generate ["1", "2", "a", "b", ["c", "d"], 42, {foo: 10}]
+ var ret = context.callMethod("concatValues", [list]);
+ expect(list.length, equals(2));
+ expect(ret.length, equals(8));
+ expect(ret[0], equals("1"));
+ expect(ret[3], equals("b"));
+ expect(ret[5], equals("d"));
+ expect(ret[6], equals(42));
+ expect(ret[7]['foo'], equals(10));
+ });
+
+ test("concat onto arrays", () {
+ // This test only passes if we have monkey patched the core Array object
+ // prototype to handle Dart Lists.
+ var list = ["a", "b"];
+ var ret = context.callMethod("concatOntoArray", [list]);
+ expect(list.length, equals(2));
+ expect(ret, equals([1, 2, 3, "a", "b", "foo"]));
+ });
+
+ test("dart arrays on dart arrays", () {
+ // This test only passes if we have monkey patched the core Array object
+ // prototype to handle Dart Lists.
+ var list = ["a", "b"];
+ var ret = callJsMethod(list, "concat", [["c", "d"], "e", ["f", "g"]]);
+ expect(list.length, equals(2));
+ expect(ret, equals(["a", "b", "c", "d", "e", "f", "g"]));
+ });
+
+ test("every greater than zero", () {
+ expect(context.callMethod("everyGreaterThanZero", [[1, 5]]), isTrue);
+ expect(context.callMethod("everyGreaterThanZeroCheckThisArg", [[1, 5]]),
+ isTrue);
+ expect(context.callMethod("everyGreaterThanZero", [[1, 0]]), isFalse);
+ expect(context.callMethod("everyGreaterThanZero", [[]]), isTrue);
+ });
+
+ test("filter greater than 42", () {
+ expect(context.callMethod("filterGreater42", [[1, 5]]), equals([]));
+ expect(context.callMethod("filterGreater42", [[43, 5, 49]]),
+ equals([43, 49]));
+ expect(context.callMethod("filterGreater42", [["43", "5", "49"]]),
+ equals(["43", "49"]));
+ });
+
+ test("for each collect result", () {
+ expect(context.callMethod("forEachCollectResult", [[1, 5, 7]]),
+ equals([2, 10, 14]));
+ });
+
+ test("some", () {
+ expect(context.callMethod("someEqual42", [[1, 5, 9]]), isFalse);
+ expect(context.callMethod("someEqual42", [[1, 42, 9]]), isTrue);
+ });
+
+ test("sort backwards", () {
+ var arr = [1, 5, 9];
+ var ret = context.callMethod("sortNumbersBackwards", [arr]);
+ expect(identical(arr, ret), isTrue);
+ expect(ret, equals([9, 5, 1]));
+ });
+
+ test("splice dummy items", () {
+ var list = [1, 2, 3, 4];
+ var removed = context.callMethod("spliceDummyItems", [list]);
+ expect(removed.length, equals(2));
+ expect(removed[0], equals(2));
+ expect(removed[1], equals(3));
+ expect(list.first, equals(1));
+ expect(list[1], equals("quick"));
+ expect(list[2], equals("brown"));
+ expect(list[3], equals("fox"));
+ expect(list.last, equals(4));
+ });
+
+ test("splice string args", () {
+ var list = [1, 2, 3, 4];
+ var removed = context.callMethod("spliceTestStringArgs", [list]);
+ expect(removed.length, equals(2));
+ expect(removed[0], equals(2));
+ expect(removed[1], equals(3));
+ expect(list.first, equals(1));
+ expect(list[1], equals("quick"));
+ expect(list[2], equals("brown"));
+ expect(list[3], equals("fox"));
+ expect(list.last, equals(4));
+ });
+
+ test("splice pastEndOfArray", () {
+ var list = [1, 2, 3, 4];
+ var removed = context.callMethod("splicePastEnd", [list]);
+ expect(removed.length, equals(3));
+ expect(list.first, equals(1));
+ expect(list.length, equals(4));
+ expect(list[1], equals("quick"));
+ expect(list[2], equals("brown"));
+ expect(list[3], equals("fox"));
+ });
+
+ test("splice both bounds past end of array", () {
+ var list = [1];
+ var removed = context.callMethod("splicePastEnd", [list]);
+ expect(removed.length, equals(0));
+ expect(list.first, equals(1));
+ expect(list.length, equals(4));
+ expect(list[1], equals("quick"));
+ expect(list[2], equals("brown"));
+ expect(list[3], equals("fox"));
+ });
+
+ test("call List method on JavaScript object", () {
+ var jsObject = new JsObject.jsify({});
+ callListMethodOnObject(jsObject, 'push', ["a"]);
+ callListMethodOnObject(jsObject, 'push', ["b"]);
+ callListMethodOnObject(jsObject, 'push', ["c", "d"]);
+ callListMethodOnObject(jsObject, 'push', []);
+
+ expect(jsonStringify(jsObject),
+ equals('{"0":"a","1":"b","2":"c","3":"d","length":4}'));
+
+ expect(callListMethodOnObject(jsObject, 'pop', []), equals("d"));
+ expect(callListMethodOnObject(jsObject, 'join', ["#"]), equals("a#b#c"));
+
+ var jsArray = new JsObject.jsify([]);
+ callListMethodOnObject(jsArray, 'push', ["a"]);
+ callListMethodOnObject(jsArray, 'push', ["b"]);
+ callListMethodOnObject(jsArray, 'push', ["c", "d"]);
+ callListMethodOnObject(jsArray, 'push', []);
+
+ expect(jsonStringify(jsArray), equals('["a","b","c","d"]'));
+ });
+ });
+
+ // This test group is disabled until we figure out an efficient way to
+ // distinguish between "array" Dart List types and non-array Dart list types.
+ /*
+ group('Non-array Lists', () {
+ test('opaque proxy', () {
+ // Dartium could easily support making LinkedList and all other classes
+ // implementing List behave like a JavaScript array but that would
+ // be challenging to implement in dart2js until browsers support ES6.
+ var list = ["a", "b", "c", "d"];
+ var listView = new UnmodifiableListView(list.getRange(1,3));
+ expect(listView is List, isTrue);
+ expect(listView.length, equals(2));
+ expect(context.callMethod("checkIsArray", [listView]), isFalse);
+ expect(context.callMethod("checkIsArray", [listView.toList()]), isTrue);
+ expect(context.callMethod("getOwnPropertyDescriptorJson",
+ [listView, "length"]), equals("null"));
+ });
+ });
+ */
+}
diff --git a/tests/html/js_typed_interop_test.dart b/tests/html/js_typed_interop_test.dart
new file mode 100644
index 0000000..c8c0260
--- /dev/null
+++ b/tests/html/js_typed_interop_test.dart
@@ -0,0 +1,139 @@
+// 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 jsArrayTest;
+
+import 'dart:html';
+import 'dart:js';
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+
+_injectJs() {
+ document.body.append(new ScriptElement()
+ ..type = 'text/javascript'
+ ..innerHtml = r"""
+ var foo = {
+ x: 3,
+ z: 40, // Not specified in typed Dart API so should fail in checked mode.
+ multiplyByX: function(arg) { return arg * this.x; },
+ // This function can be torn off without having to bind this.
+ multiplyBy2: function(arg) { return arg * 2; }
+ };
+
+ var foob = {
+ x: 8,
+ y: "why",
+ multiplyByX: function(arg) { return arg * this.x; }
+ };
+
+ var bar = {
+ x: "foo",
+ multiplyByX: true
+ };
+
+ var selection = ["a", "b", "c", foo, bar];
+ selection.doubleLength = function() { return this.length * 2; };
+""");
+}
+
+abstract class Foo {
+ int get x;
+ set x(int v);
+ num multiplyByX(num y);
+ num multiplyBy2(num y);
+}
+
+abstract class Foob extends Foo {
+ final String y;
+}
+
+abstract class Bar {
+ String get x;
+ bool get multiplyByX;
+}
+
+class Baz {}
+
+// This class shows the pattern used by APIs such as jQuery that add methods
+// to Arrays.
+abstract class Selection implements List {
+ num doubleLength();
+}
+
+Foo get foo => context['foo'];
+Foob get foob => context['foob'];
+Bar get bar => context['bar'];
+Selection get selection => context['selection'];
+
+main() {
+ // Call experimental API to register Dart interfaces implemented by
+ // JavaScript classes.
+ registerJsInterfaces([Foo, Foob, Bar, Selection]);
+
+ _injectJs();
+
+ useHtmlConfiguration();
+
+ group('property', () {
+ test('get', () {
+ expect(foo.x, equals(3));
+ expect(foob.x, equals(8));
+ expect(foob.y, equals("why"));
+
+ // Exists in JS but not in API.
+ expect(() => foo.z, throws);
+ expect(bar.multiplyByX, isTrue);
+ });
+ test('set', () {
+ foo.x = 42;
+ expect(foo.x, equals(42));
+ // Property tagged as read only in typed API.
+ expect(() => foob.y = "bla", throws);
+ expect(() => foo.unknownName = 42, throws);
+ });
+ });
+
+ group('method', () {
+ test('call', () {
+ foo.x = 100;
+ expect(foo.multiplyByX(4), equals(400));
+ foob.x = 10;
+ expect(foob.multiplyByX(4), equals(40));
+ });
+
+ test('tearoff', () {
+ foo.x = 10;
+ // TODO(jacobr): should we automatically bind "this" for tearoffs of JS
+ // objects?
+ JsFunction multiplyBy2 = foo.multiplyBy2;
+ expect(multiplyBy2(5), equals(10));
+ });
+ });
+
+ group('type check', () {
+ test('js interfaces', () {
+ expect(foo is JsObject, isTrue);
+ // Cross-casts are allowed.
+ expect(foo is Bar, isTrue);
+ expect(selection is JsArray, isTrue);
+
+ // We do know at runtime whether something is a JsArray or not.
+ expect(foo is JsArray, isFalse);
+ });
+
+ test('dart interfaces', () {
+ expect(foo is Function, isFalse);
+ expect(selection is List, isTrue);
+ });
+ });
+
+ group("registration", () {
+ test('repeated fails', () {
+ // The experimental registerJsInterfaces API has already been called so
+ // it cannot be called a second time.
+ expect(() => registerJsInterfaces([Baz]), throws);
+ });
+ });
+}
diff --git a/tests/html/svgelement_test.dart b/tests/html/svgelement_test.dart
index 2b573ca..5527dcd 100644
--- a/tests/html/svgelement_test.dart
+++ b/tests/html/svgelement_test.dart
@@ -40,11 +40,11 @@
}
group('additionalConstructors', () {
test('valid', () {
- final svgContent = """
-<svg version="1.1">
- <circle></circle>
- <path></path>
-</svg>""";
+ final svgContent =
+ "<svg version=\"1.1\">\n"
+ " <circle></circle>\n"
+ " <path></path>\n"
+ "</svg>";
final el = new svg.SvgElement.svg(svgContent);
expect(el, isSvgSvgElement);
expect(el.innerHtml, anyOf("<circle></circle><path></path>", '<circle '
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 58a420a..e6b89b8 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -129,55 +129,54 @@
bool_from_environment_default_value_test: RuntimeError # receiver.get$_collection$_nums is not a function
capability_test: RuntimeError # receiver.get$_collection$_nums is not a function
compile_time_error_test/none: RuntimeError # receiver.get$_collection$_nums is not a function
-count_test: Crash # Invalid argument(s)
-cross_isolate_message_test: Crash # Invalid argument(s)
-deferred_in_isolate2_test: Crash # Invalid argument(s)
+count_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+cross_isolate_message_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+deferred_in_isolate2_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
deferred_in_isolate_test: RuntimeError # receiver.get$_collection$_nums is not a function
function_send_test: RuntimeError # receiver.get$_nums is not a function
handle_error2_test: RuntimeError # receiver.get$_collection$_nums is not a function
handle_error3_test: RuntimeError # receiver.get$_collection$_nums is not a function
handle_error_test: RuntimeError # receiver.get$_collection$_nums is not a function
-illegal_msg_function_test: Crash # Invalid argument(s)
-illegal_msg_mirror_test: Crash # Invalid argument(s)
+illegal_msg_function_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+illegal_msg_mirror_test : RuntimeError # TypeError: receiver.get$_nums is not a function
int_from_environment_default_value_test: RuntimeError # receiver.get$_collection$_nums is not a function
-isolate_complex_messages_test: Crash # Invalid argument(s)
+isolate_complex_messages_test : RuntimeError # TypeError: receiver.get$_nums is not a function
isolate_current_test: RuntimeError # receiver.get$_nums is not a function
isolate_import_test/none: RuntimeError # receiver.get$_collection$_nums is not a function
issue_22778_test: RuntimeError # receiver.get$_collection$_nums is not a function
kill2_test: RuntimeError # receiver.get$_collection$_nums is not a function
kill_self_test: RuntimeError # receiver.get$_collection$_nums is not a function
kill_test: RuntimeError # receiver.get$_collection$_nums is not a function
-mandel_isolate_test: Crash # Invalid argument(s)
-message2_test: Crash # Invalid argument(s)
+mandel_isolate_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
+message2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
message3_test/byteBuffer: RuntimeError # receiver.get$_collection$_nums is not a function
message3_test/constInstance: Crash # Invalid argument(s)
message3_test/fun: RuntimeError # receiver.get$_collection$_nums is not a function
message3_test/int32x4: RuntimeError # receiver.get$_collection$_nums is not a function
message3_test/none: RuntimeError # receiver.get$_collection$_nums is not a function
message_enum_test: RuntimeError # receiver.get$_collection$_nums is not a function
-message_test: Crash # Invalid argument(s)
-mint_maker_test: Crash # Invalid argument(s)
-nested_spawn2_test: Crash # Invalid argument(s)
-nested_spawn_test: Crash # Invalid argument(s)
+message_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+mint_maker_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+nested_spawn2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+nested_spawn_test : RuntimeError # TypeError: receiver.get$_nums is not a function
object_leak_test: RuntimeError # receiver.get$_collection$_nums is not a function
ondone_test: RuntimeError # receiver.get$_nums is not a function
pause_test: RuntimeError # receiver.get$_nums is not a function
ping_pause_test: RuntimeError # receiver.get$_collection$_nums is not a function
ping_test: RuntimeError # receiver.get$_collection$_nums is not a function
port_test: RuntimeError # receiver.get$_collection$_nums is not a function
-raw_port_test: Crash # Invalid argument(s)
-request_reply_test: Crash # Invalid argument(s)
+raw_port_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+request_reply_test : RuntimeError # TypeError: receiver.get$_nums is not a function
simple_message_test/none: RuntimeError # receiver.get$_collection$_nums is not a function
-spawn_function_custom_class_test: Crash # Invalid argument(s)
-spawn_function_test: Crash # Invalid argument(s)
-spawn_uri_missing_from_isolate_test: Crash # Invalid argument(s)
-spawn_uri_missing_test: Crash # Invalid argument(s)
-spawn_uri_multi_test/01: Crash # Invalid argument(s)
+spawn_function_custom_class_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+spawn_function_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+spawn_uri_missing_from_isolate_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
+spawn_uri_missing_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
spawn_uri_multi_test/none: Crash # Invalid argument(s)
-stacktrace_message_test: Crash # Invalid argument(s)
+stacktrace_message_test : RuntimeError # TypeError: receiver.get$_nums is not a function
start_paused_test: RuntimeError # receiver.get$_nums is not a function
-static_function_test: Crash # Invalid argument(s)
+static_function_test : RuntimeError # TypeError: receiver.get$_nums is not a function
string_from_environment_default_value_test: RuntimeError # receiver.get$_collection$_nums is not a function
-timer_isolate_test: Crash # Invalid argument(s)
+timer_isolate_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
typed_message_test: RuntimeError # receiver.get$_nums is not a function
-unresolved_ports_test: Crash # Invalid argument(s)
+unresolved_ports_test : RuntimeError # TypeError: receiver.get$_nums is not a function
diff --git a/tests/language/async_await_syntax_test.dart b/tests/language/async_await_syntax_test.dart
index 2b28e47..aa73ff3 100644
--- a/tests/language/async_await_syntax_test.dart
+++ b/tests/language/async_await_syntax_test.dart
@@ -13,6 +13,7 @@
a01a() async => null; /// a01a: ok
a01b() async* => null; /// a01b: compile-time error
a01c() sync* => null; /// a01c: compile-time error
+a01d() async => yield 5; /// a01d: compile-time error
a02a() async {} /// a02a: ok
a03a() async* {} /// a03a: ok
a03b() async * {} /// a03b: ok
@@ -40,6 +41,12 @@
var await = (a) {}; /// a05f: continued
await(0); /// a05f: continued
} /// a05f: continued
+a05g() async { /// a05g: continued
+ yield 5; /// a05g: compile-time error
+} /// a05g: continued
+a05h() async { /// a05h: continued
+ yield* st; /// a05h: compile-time error
+} /// a05h: continued
a06a() async { await for (var o in st) {} } /// a06a: ok
a06b() sync* { await for (var o in st) {} } /// a06b: compile-time error
a07a() sync* { yield 0; } /// a07a: ok
@@ -116,6 +123,7 @@
b08a() sync* { yield* []; } /// b08a: ok
b09a() async* { yield 0; } /// b09a: ok
b10a() async* { yield* []; } /// b10a: static type warning
+ b10b() async { yield 0; } /// b10b: compile-time error
get sync sync {} /// b11a: compile-time error
get sync sync* {} /// b11b: ok
@@ -160,6 +168,8 @@
c08a() sync* { yield* []; } c08a(); /// c08a: ok
c09a() async* { yield 0; } c09a(); /// c09a: ok
c10a() async* { yield* []; } c10a(); /// c10a: static type warning
+ c11a() async { yield -5; } c11a(); /// c11a: compile-time error
+ c11b() async { yield* st; } c11b(); /// c11b: compile-time error
}
method2() {
@@ -197,6 +207,7 @@
a01a(); /// a01a: continued
a01b(); /// a01b: continued
a01c(); /// a01c: continued
+ a01d(); /// a01d: continued
a02a(); /// a02a: continued
a03a(); /// a03a: continued
a03b(); /// a03b: continued
@@ -209,6 +220,8 @@
a05d(); /// a05d: continued
a05e(); /// a05e: continued
a05f(); /// a05f: continued
+ a05g(); /// a05g: continued
+ a05h(); /// a05h: continued
a06a(); /// a06a: continued
a06b(); /// a06b: continued
a07a(); /// a07a: continued
@@ -259,6 +272,7 @@
c.b08a(); /// b08a: continued
c.b09a(); /// b09a: continued
c.b10a(); /// b10a: continued
+ c.b10b(); /// b10b: continued
a = c.sync; /// b11a: continued
a = c.sync; /// b11b: continued
a = c.async; /// b11c: continued
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 7209ad5..7b73b20 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -150,7 +150,11 @@
mixin_mixin_bound2_test: RuntimeError # Issue 12605
[ $compiler == dart2js ]
-malformed_test/none: Fail # Expect failure in lib/_internal/compiler/js_lib/preambles/d8.js
+async_await_syntax_test/a05h: Fail # 23716
+async_await_syntax_test/c11a: Fail # 23716
+async_await_syntax_test/c11b: Fail # 23716
+
+malformed_test/none: Fail # Expect failure in lib/_internal/js_runtime/lib/preambles/d8.js
type_variable_conflict2_test/01: RuntimeError # Issue 19725
@@ -245,10 +249,6 @@
generic_field_mixin5_test: Crash # Issue 18651
[ $compiler == dart2js && $cps_ir ]
-abstract_object_method_test: RuntimeError # Please triage this failure.
-assert_assignable_type_test: RuntimeError # Please triage this failure.
-assign_op_test: RuntimeError # Please triage this failure.
-assignable_expression_test/none: RuntimeError # Please triage this failure.
async_and_or_test: Crash # (test()async{await test1();await test2();}): cannot handle async/sync*/async* functions
async_await_catch_regression_test: Crash # (test()async{var exc... cannot handle async/sync*/async* functions
async_await_syntax_test/a01a: Crash # (a01a()async=>null;): cannot handle async/sync*/async* functions
@@ -358,19 +358,11 @@
await_regression_test: Crash # (main()async{testNes... cannot handle async/sync*/async* functions
await_test: Crash # (others()async{var a... cannot handle async/sync*/async* functions
bind_test: RuntimeError # Cannot read property 'prototype' of undefined
-bound_closure_primitives_test: RuntimeError # Please triage this failure.
-call_with_no_such_method_test: RuntimeError # Please triage this failure.
canonical_const3_test: RuntimeError # Cannot read property 'prototype' of undefined
-cascade2_test: RuntimeError # Please triage this failure.
-cascade_2_test: RuntimeError # Please triage this failure.
cascade_test/none: RuntimeError # Cannot read property 'prototype' of undefined
-cast_test/04: RuntimeError # Please triage this failure.
-cast_test/05: RuntimeError # Please triage this failure.
-cast_test/none: RuntimeError # Please triage this failure.
cha_deopt1_test: RuntimeError # receiver.get$_collection$_nums is not a function
cha_deopt2_test: RuntimeError # receiver.get$_collection$_nums is not a function
cha_deopt3_test: RuntimeError # receiver.get$_collection$_nums is not a function
-char_escape_test: RuntimeError # Please triage this failure.
closure7_test: RuntimeError # Cannot read property 'prototype' of undefined
closure8_test: RuntimeError # Cannot read property 'prototype' of undefined
closure_cycles_test: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -378,15 +370,8 @@
closure_shared_state_test: RuntimeError # Cannot read property 'prototype' of undefined
closure_type_variables_test: Crash # Invalid argument(s)
closures_initializer2_test: RuntimeError # Cannot read property 'prototype' of undefined
-compile_time_constant_a_test: RuntimeError # Please triage this failure.
-compile_time_constant_b_test: RuntimeError # Please triage this failure.
-compound_assignment_operator_test: RuntimeError # Please triage this failure.
const_evaluation_test/01: Crash # Internal Error: No default constructor available.
-const_list_test: RuntimeError # Please triage this failure.
-const_map_test: RuntimeError # Please triage this failure.
-const_nested_test: Crash # Invalid argument(s)
constructor12_test: RuntimeError # Please triage this failure.
-constructor_with_mixin_test: Crash # Internal Error: No default constructor available.
crash_6725_test/01: Crash # The null object does not have a getter '_element'.
custom_await_stack_trace_test: Crash # (main()async{try {va... cannot handle async/sync*/async* functions
cyclic_type_test/00: RuntimeError # Cannot read property 'prototype' of undefined
@@ -423,7 +408,7 @@
deferred_load_inval_code_test: RuntimeError # receiver.get$_collection$_nums is not a function
deferred_load_library_wrong_args_test/none: RuntimeError # receiver.get$_collection$_nums is not a function
deferred_mixin_test: RuntimeError # receiver.get$_collection$_nums is not a function
-deferred_no_such_method_test: RuntimeError # receiver.get$_collection$_nums is not a function
+deferred_no_such_method_test : RuntimeError # TypeError: receiver.get$_nums is not a function
deferred_not_loaded_check_test: RuntimeError # Please triage this failure.
deferred_only_constant_test: RuntimeError # receiver.get$_collection$_nums is not a function
deferred_optimized_test: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -432,20 +417,9 @@
deferred_shadow_load_library_test: RuntimeError # receiver.get$_collection$_nums is not a function
deferred_shared_and_unshared_classes_test: RuntimeError # receiver.get$_collection$_nums is not a function
deferred_static_seperate_test: RuntimeError # receiver.get$_collection$_nums is not a function
-deopt_no_feedback_test: RuntimeError # Please triage this failure.
-enum_duplicate_test/01: RuntimeError # Please triage this failure.
-enum_duplicate_test/02: RuntimeError # Please triage this failure.
-enum_duplicate_test/none: RuntimeError # Please triage this failure.
enum_mirror_test: Crash # Internal Error: No default constructor available.
-enum_private_test/01: RuntimeError # Please triage this failure.
-enum_private_test/02: RuntimeError # Please triage this failure.
-enum_private_test/none: RuntimeError # Please triage this failure.
-execute_finally7_test: RuntimeError # Cannot read property 'call$0' of null
f_bounded_equality_test: RuntimeError # Cannot read property 'prototype' of undefined
-fannkuch_test: RuntimeError # Please triage this failure.
-field_increment_bailout_test: RuntimeError # Please triage this failure.
-final_super_field_set_test/01: RuntimeError # Please triage this failure.
-fixed_length_test: RuntimeError # Please triage this failure.
+final_super_field_set_test/01 : RuntimeError #
fixed_type_variable_test/02: RuntimeError # Cannot read property 'prototype' of undefined
fixed_type_variable_test/04: RuntimeError # Cannot read property 'prototype' of undefined
fixed_type_variable_test/06: RuntimeError # Cannot read property 'prototype' of undefined
@@ -480,53 +454,14 @@
function_subtype_simple1_test: RuntimeError # Cannot read property 'prototype' of undefined
function_subtype_simple2_test: RuntimeError # Cannot read property 'prototype' of undefined
function_subtype_top_level0_test: RuntimeError # Cannot read property 'prototype' of undefined
-function_syntax_test/none: RuntimeError # Please triage this failure.
-function_test: RuntimeError # Please triage this failure.
function_type_alias6_test/none: RuntimeError # Cannot read property 'prototype' of undefined
-gc_test: RuntimeError # Please triage this failure.
-generic_constructor_mixin2_test: Crash # Internal Error: No default constructor available.
-generic_constructor_mixin3_test: Crash # Internal Error: No default constructor available.
-generic_constructor_mixin_test: Crash # Internal Error: No default constructor available.
generic_creation_test: RuntimeError # Cannot read property 'prototype' of undefined
generic_field_mixin3_test: RuntimeError # Please triage this failure.
-getter_setter_interceptor_test: RuntimeError # Please triage this failure.
-getter_setter_order_test: RuntimeError # Please triage this failure.
-gvn_interceptor_test: RuntimeError # Please triage this failure.
identical_closure_test: RuntimeError # Cannot read property 'prototype' of undefined
-if_null_assignment_behavior_test/01: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/02: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/04: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/05: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/06: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/07: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/08: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/09: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/10: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/12: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/16: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/17: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/18: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/19: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/20: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/21: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/22: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/23: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/24: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/25: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/26: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/27: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/28: RuntimeError # Please triage this failure.
if_null_assignment_static_test/01: RuntimeError # Issue 23669
if_null_assignment_static_test/03: RuntimeError # Issue 23669
if_null_assignment_static_test/04: RuntimeError # Issue 23669
if_null_assignment_static_test/05: RuntimeError # Issue 23669
-if_null_assignment_static_test/29: RuntimeError # Issue 23669
-if_null_assignment_static_test/30: RuntimeError # Please triage this failure.
-if_null_assignment_static_test/31: RuntimeError # Issue 23669
-if_null_assignment_static_test/32: RuntimeError # Issue 23669
-if_null_assignment_static_test/33: RuntimeError # Issue 23669
-if_null_assignment_static_test/34: RuntimeError # Please triage this failure.
-if_null_assignment_static_test/35: RuntimeError # Please triage this failure.
if_null_assignment_static_test/36: RuntimeError # Issue 23669
if_null_assignment_static_test/38: RuntimeError # Issue 23669
if_null_assignment_static_test/39: RuntimeError # Issue 23669
@@ -534,31 +469,17 @@
implicit_closure1_test: RuntimeError # Cannot read property 'prototype' of undefined
implicit_closure2_test: RuntimeError # Cannot read property 'prototype' of undefined
implicit_closure_test: RuntimeError # Cannot read property 'prototype' of undefined
-incr_op_test: RuntimeError # Please triage this failure.
-index_test: RuntimeError # Please triage this failure.
-inference_mixin_field_test: Crash # Internal Error: No default constructor available.
infinite_switch_label_test: Crash # (switch (target){l0:... continue to a labeled switch case
inlined_conditional_test: RuntimeError # Cannot read property 'prototype' of undefined
instance_creation_in_function_annotation_test: Crash # Internal Error: No default constructor available.
instanceof4_test/01: RuntimeError # Please triage this failure.
-interceptor7_test: RuntimeError # Please triage this failure.
-invocation_mirror_invoke_on2_test: RuntimeError # Please triage this failure.
-invocation_mirror_invoke_on_test: RuntimeError # Please triage this failure.
+invocation_mirror_invoke_on_test : RuntimeError #
invocation_mirror_test: Crash # (super[37]=42): visitUnresolvedSuperIndexSet
is_function_test: RuntimeError # Cannot read property 'prototype' of undefined
-issue12288_test: RuntimeError # Please triage this failure.
issue13179_test: RuntimeError # Cannot read property 'prototype' of undefined
-issue7513_test: RuntimeError # Please triage this failure.
issue_1751477_test: RuntimeError # receiver.get$_collection$_nums is not a function
large_class_declaration_test: Crash # Stack Overflow
-list_literal3_test: RuntimeError # Please triage this failure.
list_test: RuntimeError # Please triage this failure.
-list_tracer_closure_test: RuntimeError # Please triage this failure.
-list_tracer_in_list_test: RuntimeError # Please triage this failure.
-list_tracer_in_map_test: RuntimeError # Please triage this failure.
-list_tracer_return_from_tearoff_closure_test: RuntimeError # Please triage this failure.
-local_function_test: RuntimeError # Please triage this failure.
-logical_expression_test: RuntimeError # Please triage this failure.
main_test/01: RuntimeError # receiver.get$_collection$_nums is not a function
main_test/02: RuntimeError # receiver.get$_collection$_nums is not a function
main_test/04: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -571,65 +492,33 @@
main_test/43: RuntimeError # receiver.get$_collection$_nums is not a function
main_test/44: RuntimeError # receiver.get$_collection$_nums is not a function
main_test/45: RuntimeError # receiver.get$_collection$_nums is not a function
-many_calls_test: RuntimeError # Please triage this failure.
-many_named_arguments_test: RuntimeError # Please triage this failure.
-many_overridden_no_such_method_test: RuntimeError # Please triage this failure.
-mega_load_test: RuntimeError # Please triage this failure.
+many_overridden_no_such_method_test : RuntimeError #
method_binding_test: RuntimeError # Cannot read property 'prototype' of undefined
methods_as_constants2_test: RuntimeError # Cannot read property 'prototype' of undefined
-minify_closure_variable_collision_test: RuntimeError # Please triage this failure.
mint_compares_test: RuntimeError # Cannot read property 'prototype' of undefined
-mixin_bound_test: Crash # Internal Error: No default constructor available.
-mixin_forwarding_constructor1_test: Crash # Internal Error: No default constructor available.
-mixin_forwarding_constructor3_test: Crash # Internal Error: No default constructor available.
-mixin_prefix_test: Crash # Internal Error: No default constructor available.
-mixin_super_constructor2_test: Crash # Internal Error: No default constructor available.
-mixin_super_constructor_default_test: Crash # Internal Error: No default constructor available.
-mixin_super_constructor_multiple_test: Crash # Internal Error: No default constructor available.
mixin_super_constructor_named_test/01: Crash # Internal Error: No default constructor available.
-mixin_super_constructor_named_test/none: Crash # Internal Error: No default constructor available.
mixin_super_constructor_positionals_test/01: Crash # Internal Error: No default constructor available.
-mixin_super_constructor_positionals_test/none: Crash # Internal Error: No default constructor available.
-mixin_super_constructor_test: Crash # Internal Error: No default constructor available.
-mixin_type_parameter2_test: Crash # Internal Error: No default constructor available.
-mixin_type_parameter3_test: Crash # Internal Error: No default constructor available.
mixin_type_parameters_mixin_extends_test: Crash # The null object does not have a getter '_element'.
mixin_type_parameters_mixin_test: Crash # The null object does not have a getter '_element'.
mixin_type_parameters_super_extends_test: Crash # The null object does not have a getter '_element'.
mixin_type_parameters_super_test: Crash # The null object does not have a getter '_element'.
-mixin_typedef_constructor_test: Crash # Internal Error: No default constructor available.
named_parameters_with_conversions_test: RuntimeError # Cannot read property 'prototype' of undefined
-named_parameters_with_dollars_test: RuntimeError # Please triage this failure.
-nested_if_test: RuntimeError # Please triage this failure.
nested_switch_label_test: Crash # (switch (target){out... continue to a labeled switch case
-no_such_method_dispatcher_test: RuntimeError # Please triage this failure.
-no_such_method_empty_selector_test: RuntimeError # Please triage this failure.
-no_such_method_test: RuntimeError # Please triage this failure.
+no_such_method_test : RuntimeError #
null_test/none: Crash # Internal Error: No default constructor available.
null_to_string2_test: RuntimeError # Cannot read property 'prototype' of undefined
null_to_string_test: RuntimeError # Cannot read property 'prototype' of undefined
-operator_index_evaluation_order_test: RuntimeError # Please triage this failure.
-optimize_redundant_array_load_test: RuntimeError # Please triage this failure.
-optimized_lists_test: RuntimeError # Please triage this failure.
-osr_test: RuntimeError # Please triage this failure.
-overridden_no_such_method_test: RuntimeError # Please triage this failure.
+overridden_no_such_method_test : RuntimeError #
override_method_with_field_test/02: RuntimeError # Cannot read property 'prototype' of undefined
override_method_with_field_test/none: RuntimeError # Cannot read property 'prototype' of undefined
-param2_test: RuntimeError # Please triage this failure.
prefix14_test: RuntimeError # Cannot read property 'prototype' of undefined
prefix15_test: RuntimeError # Cannot read property 'prototype' of undefined
prefix21_test: RuntimeError # Cannot read property 'prototype' of undefined
-pure_function2_test: RuntimeError # Please triage this failure.
-pure_function_test: RuntimeError # Please triage this failure.
range_analysis_test: RuntimeError # Cannot read property 'prototype' of undefined
recursive_calls_test: RuntimeError # Cannot read property 'prototype' of undefined
reg_ex2_test: RuntimeError # Cannot read property 'prototype' of undefined
reg_exp2_test: RuntimeError # Cannot read property 'prototype' of undefined
-reg_exp_test: RuntimeError # Please triage this failure.
-regress_11800_test: RuntimeError # Please triage this failure.
-regress_18435_test: Crash # Invalid argument(s)
regress_18535_test: Crash # Internal Error: No default constructor available.
-regress_21016_test: RuntimeError # Please triage this failure.
regress_22438_test: Crash # (main()async{var err... cannot handle async/sync*/async* functions
regress_22443_test: RuntimeError # receiver.get$_collection$_nums is not a function
regress_22445_test: Crash # (main()async{var err... cannot handle async/sync*/async* functions
@@ -647,24 +536,17 @@
static_implicit_closure_test: RuntimeError # Cannot read property 'prototype' of undefined
string_interpolation_test/01: RuntimeError # Cannot read property 'prototype' of undefined
string_interpolation_test/none: RuntimeError # Cannot read property 'prototype' of undefined
-string_join_test: RuntimeError # Please triage this failure.
-string_test: RuntimeError # Please triage this failure.
super_bound_closure_test/01: RuntimeError # Cannot read property 'call' of undefined
super_bound_closure_test/none: RuntimeError # Cannot read property 'call' of undefined
-super_call4_test: RuntimeError # Please triage this failure.
+super_call4_test : RuntimeError #
super_getter_setter_test: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
super_implicit_closure_test: RuntimeError # Cannot read property 'prototype' of undefined
super_operator_index2_test: RuntimeError # this.get$map is not a function
-super_operator_index3_test: RuntimeError # Please triage this failure.
-super_operator_index4_test: RuntimeError # Please triage this failure.
super_operator_index5_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
-super_operator_index6_test: RuntimeError # Please triage this failure.
super_operator_index7_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
super_operator_index8_test: Crash # (super[f()]=g()): visitUnresolvedSuperIndexSet
super_operator_index_test/03: Crash # (super[4]=42): visitUnresolvedSuperIndexSet
super_operator_index_test/05: Crash # (super[4]=42): visitUnresolvedSuperIndexSet
-super_operator_index_test/06: Crash # The null object does not have a getter 'isParameter'.
-super_operator_test: RuntimeError # Please triage this failure.
switch_label2_test: Crash # (switch (target){cas... continue to a labeled switch case
switch_label_test: Crash # (switch (animal){cas... continue to a labeled switch case
switch_try_catch_test: Crash # (switch (0){_0:case ... continue to a labeled switch case
@@ -708,8 +590,9 @@
type_promotion_functions_test/none: RuntimeError # Cannot read property 'prototype' of undefined
type_variable_closure2_test: RuntimeError # Please triage this failure.
type_variable_closure_test: Crash # Invalid argument(s)
-type_variable_conflict2_test/07: RuntimeError # Please triage this failure.
typedef_is_test: RuntimeError # Cannot read property 'prototype' of undefined
-typevariable_substitution2_test/01: Crash # Internal Error: No default constructor available.
-typevariable_substitution2_test/02: Crash # Internal Error: No default constructor available.
-typevariable_substitution2_test/none: Crash # Internal Error: No default constructor available.
+invocation_mirror2_test : Crash # Internal Error: No default constructor available.
+type_variable_conflict2_test/01 : Crash # Internal Error: No default constructor available.
+async_await_syntax_test/a05h : Crash # bailout: (a05h()async{yield*st;}): cannot handle async/sync*/async* functions
+async_await_syntax_test/c11a : Crash # bailout: (c11a()async{yield-5;}): cannot handle async/sync*/async* functions
+async_await_syntax_test/c11b : Crash # bailout: (c11b()async{yield*st;}): cannot handle async/sync*/async* functions
diff --git a/tests/language/multiline_strings_test.dart b/tests/language/multiline_strings_test.dart
index d7f8f3e..8795014 100644
--- a/tests/language/multiline_strings_test.dart
+++ b/tests/language/multiline_strings_test.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// Note: This test relies on LF line endings in the source file.
+
import "package:expect/expect.dart";
main() {
diff --git a/tests/language/raw_string_test.dart b/tests/language/raw_string_test.dart
index ee5365b..b577747 100644
--- a/tests/language/raw_string_test.dart
+++ b/tests/language/raw_string_test.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// Note: This test relies on LF line endings in the source file.
+
import "package:expect/expect.dart";
class RawStringTest {
diff --git a/tests/lib/convert/json_pretty_test.dart b/tests/lib/convert/json_pretty_test.dart
index a0c3bc6..6238052 100644
--- a/tests/lib/convert/json_pretty_test.dart
+++ b/tests/lib/convert/json_pretty_test.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// Note: This test relies on LF line endings in the source file.
+
library json_pretty_test;
import 'dart:convert';
diff --git a/tests/lib/convert/utf84_test.dart b/tests/lib/convert/utf84_test.dart
index 37f0e2c..ddd1dc9 100755
--- a/tests/lib/convert/utf84_test.dart
+++ b/tests/lib/convert/utf84_test.dart
@@ -87,9 +87,8 @@
0xbd, 0xb6, 0x20, 0xce, 0xbe, 0xce, 0xad, 0xcf,
0x86, 0xcf, 0x89, 0xcf, 0x84, 0xce, 0xbf];
-const String testKatakanaPhrase = """
-イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム
-ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン""";
+const String testKatakanaPhrase = "イロハニホヘト チリヌルヲ ワカヨタレソ "
+ "ツネナラム ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
const List<int> testKatakanaUtf8 = const<int>[
0xe3, 0x82, 0xa4, 0xe3, 0x83, 0xad, 0xe3, 0x83,
@@ -101,7 +100,7 @@
0x82, 0xbf, 0xe3, 0x83, 0xac, 0xe3, 0x82, 0xbd,
0x20, 0xe3, 0x83, 0x84, 0xe3, 0x83, 0x8d, 0xe3,
0x83, 0x8a, 0xe3, 0x83, 0xa9, 0xe3, 0x83, 0xa0,
- 0x0a, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xb0, 0xe3,
+ 0x20, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xb0, 0xe3,
0x83, 0x8e, 0xe3, 0x82, 0xaa, 0xe3, 0x82, 0xaf,
0xe3, 0x83, 0xa4, 0xe3, 0x83, 0x9e, 0x20, 0xe3,
0x82, 0xb1, 0xe3, 0x83, 0x95, 0xe3, 0x82, 0xb3,
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 184c01d..015e3bd 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -354,13 +354,13 @@
async/catch_errors7_test: RuntimeError # receiver.get$_nums is not a function
async/catch_errors8_test: RuntimeError # receiver.get$_nums is not a function
async/catch_errors_test: RuntimeError # receiver.get$_nums is not a function
-async/first_regression_test: Crash # Invalid argument(s)
+async/first_regression_test : RuntimeError # TypeError: receiver.get$_nums is not a function
async/future_constructor_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/future_delayed_error_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/future_microtask_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/future_test/01: Crash # (()async=>new Future.value(value)): cannot handle async/sync*/async* functions
async/future_test/none: RuntimeError # receiver.get$_nums is not a function
-async/future_timeout_test: Crash # Invalid argument(s)
+async/future_timeout_test : RuntimeError # TypeError: receiver.get$_nums is not a function
async/future_value_chain2_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/future_value_chain3_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/future_value_chain4_test: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -373,7 +373,7 @@
async/intercept_schedule_microtask4_test: RuntimeError # receiver.get$_nums is not a function
async/intercept_schedule_microtask5_test: RuntimeError # receiver.get$_nums is not a function
async/intercept_schedule_microtask6_test: RuntimeError # receiver.get$_nums is not a function
-async/multiple_timer_test: Crash # Invalid argument(s)
+async/multiple_timer_test : RuntimeError # TypeError: receiver.get$_nums is not a function
async/print_test/none: RuntimeError # receiver.get$_nums is not a function
async/run_zoned1_test: RuntimeError # receiver.get$_nums is not a function
async/run_zoned4_test: RuntimeError # receiver.get$_nums is not a function
@@ -382,10 +382,10 @@
async/run_zoned7_test: RuntimeError # receiver.get$_nums is not a function
async/run_zoned8_test: RuntimeError # receiver.get$_nums is not a function
async/run_zoned9_test/none: RuntimeError # receiver.get$_nums is not a function
-async/schedule_microtask2_test: Crash # Invalid argument(s)
-async/schedule_microtask3_test: Crash # Invalid argument(s)
-async/schedule_microtask5_test: Crash # Invalid argument(s)
-async/schedule_microtask_test: Crash # Invalid argument(s)
+async/schedule_microtask2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/schedule_microtask3_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/schedule_microtask5_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/schedule_microtask_test : RuntimeError # TypeError: receiver.get$_nums is not a function
async/slow_consumer2_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/slow_consumer3_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/slow_consumer_test: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -414,41 +414,41 @@
async/stack_trace23_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/stack_trace24_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/stack_trace25_test: RuntimeError # receiver.get$_collection$_nums is not a function
-async/stream_controller_async_test: Crash # Invalid argument(s)
+async/stream_controller_async_test : RuntimeError # TypeError: receiver.get$_nums is not a function
async/stream_controller_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/stream_empty_test: Crash # (Future runTest()asy... cannot handle async/sync*/async* functions
async/stream_event_transformed_test: RuntimeError # receiver.get$_nums is not a function
-async/stream_first_where_test: Crash # Invalid argument(s)
-async/stream_from_iterable_test: Crash # Invalid argument(s)
+async/stream_first_where_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_from_iterable_test : RuntimeError # TypeError: receiver.get$_nums is not a function
async/stream_iterator_double_cancel_test: RuntimeError # receiver.get$_collection$_nums is not a function
-async/stream_iterator_test: Crash # Invalid argument(s)
-async/stream_join_test: Crash # Invalid argument(s)
-async/stream_last_where_test: Crash # Invalid argument(s)
+async/stream_iterator_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_join_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_last_where_test : RuntimeError # TypeError: receiver.get$_nums is not a function
async/stream_listen_zone_test: RuntimeError # receiver.get$_nums is not a function
-async/stream_periodic2_test: Crash # Invalid argument(s)
-async/stream_periodic3_test: Crash # Invalid argument(s)
-async/stream_periodic4_test: Crash # Invalid argument(s)
-async/stream_periodic5_test: Crash # Invalid argument(s)
-async/stream_periodic_test: Crash # Invalid argument(s)
-async/stream_single_test: Crash # Invalid argument(s)
-async/stream_single_to_multi_subscriber_test: Crash # Invalid argument(s)
-async/stream_state_nonzero_timer_test: Crash # Invalid argument(s)
-async/stream_state_test: Crash # Invalid argument(s)
-async/stream_subscription_as_future_test: Crash # Invalid argument(s)
-async/stream_subscription_cancel_test: Crash # Invalid argument(s)
-async/stream_timeout_test: Crash # Invalid argument(s)
-async/stream_transform_test: Crash # Invalid argument(s)
-async/stream_transformation_broadcast_test: Crash # Invalid argument(s)
+async/stream_periodic2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_periodic3_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_periodic4_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_periodic5_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_periodic_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_single_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_single_to_multi_subscriber_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_state_nonzero_timer_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_state_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_subscription_as_future_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_subscription_cancel_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_timeout_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_transform_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_transformation_broadcast_test : RuntimeError # TypeError: receiver.get$_nums is not a function
async/stream_transformer_from_handlers_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/stream_transformer_test: RuntimeError # receiver.get$_collection$_nums is not a function
async/stream_zones_test: RuntimeError # receiver.get$_nums is not a function
-async/timer_cancel1_test: Crash # Invalid argument(s)
-async/timer_cancel2_test: Crash # Invalid argument(s)
-async/timer_cancel_test: Crash # Invalid argument(s)
-async/timer_isActive_test: Crash # Invalid argument(s)
+async/timer_cancel1_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/timer_cancel2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/timer_cancel_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/timer_isActive_test : RuntimeError # TypeError: receiver.get$_nums is not a function
async/timer_regress22626_test: RuntimeError # receiver.get$_collection$_nums is not a function
-async/timer_repeat_test: Crash # Invalid argument(s)
-async/timer_test: Crash # Invalid argument(s)
+async/timer_repeat_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/timer_test : RuntimeError # TypeError: receiver.get$_nums is not a function
async/zone_bind_callback_test: RuntimeError # receiver.get$_nums is not a function
async/zone_bind_callback_unary_test: RuntimeError # receiver.get$_nums is not a function
async/zone_bind_test: RuntimeError # receiver.get$_nums is not a function
@@ -469,47 +469,22 @@
async/zone_run_unary_test: RuntimeError # receiver.get$_nums is not a function
async/zone_value_test: RuntimeError # receiver.get$_collection$_nums is not a function
convert/ascii_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion1_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion2_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_json_decode1_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_json_encode1_test: Crash # Internal Error: No default constructor available.
-convert/chunked_conversion_utf82_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf83_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf84_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf85_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf86_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf87_test: RuntimeError # Please triage this failure.
convert/chunked_conversion_utf88_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf89_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf8_test: RuntimeError # Please triage this failure.
convert/codec1_test: RuntimeError # Cannot read property 'prototype' of undefined
-convert/codec2_test: Crash # Internal Error: No default constructor available.
convert/encoding_test: RuntimeError # receiver.get$_collection$_nums is not a function
convert/html_escape_test: RuntimeError # receiver.get$_collection$_nums is not a function
-convert/json_chunk_test: RuntimeError # Please triage this failure.
-convert/json_lib_test: Crash # Invalid argument(s)
-convert/json_pretty_test: Crash # Internal Error: No default constructor available.
-convert/json_test: Crash # Internal Error: No default constructor available.
-convert/json_toEncodable_reviver_test: Crash # Internal Error: No default constructor available.
-convert/json_utf8_chunk_test: RuntimeError # Please triage this failure.
-convert/json_util_test: Crash # Internal Error: No default constructor available.
+convert/json_lib_test : RuntimeError # TypeError: receiver.get$_nums is not a function
convert/latin1_test: RuntimeError # Please triage this failure.
-convert/line_splitter_test: Crash # Invalid argument(s)
+convert/line_splitter_test : RuntimeError # TypeError: receiver.get$_nums is not a function
convert/streamed_conversion_json_decode1_test: RuntimeError # receiver.get$_collection$_nums is not a function
-convert/streamed_conversion_json_encode1_test: Crash # Internal Error: No default constructor available.
+convert/streamed_conversion_json_encode1_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
convert/streamed_conversion_json_utf8_decode_test: RuntimeError # receiver.get$_collection$_nums is not a function
-convert/streamed_conversion_json_utf8_encode_test: Crash # Internal Error: No default constructor available.
+convert/streamed_conversion_json_utf8_encode_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
convert/streamed_conversion_utf8_decode_test: RuntimeError # receiver.get$_collection$_nums is not a function
convert/streamed_conversion_utf8_encode_test: RuntimeError # receiver.get$_collection$_nums is not a function
-convert/utf82_test: RuntimeError # Please triage this failure.
-convert/utf84_test: RuntimeError # Please triage this failure.
-convert/utf8_encode_test: RuntimeError # Please triage this failure.
-convert/utf8_test: RuntimeError # Please triage this failure.
-js/datetime_roundtrip_test: Crash # Internal Error: No default constructor available.
-js/null_test: Crash # Invalid argument(s)
math/pi_test: RuntimeError # receiver.get$_collection$_nums is not a function
-math/point_test: Crash # Invalid argument(s)
-math/rectangle_test: Crash # Invalid argument(s)
+math/point_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+math/rectangle_test : RuntimeError # TypeError: receiver.get$_nums is not a function
mirrors/abstract_class_test/00: Crash # Internal Error: No default constructor available.
mirrors/abstract_class_test/none: Crash # Internal Error: No default constructor available.
mirrors/abstract_test: Crash # Internal Error: No default constructor available.
@@ -532,10 +507,10 @@
mirrors/declarations_type_test: Crash # Internal Error: No default constructor available.
mirrors/deferred_mirrors_metadata_test: Crash # Internal Error: No default constructor available.
mirrors/deferred_mirrors_metatarget_test: Crash # Internal Error: No default constructor available.
-mirrors/deferred_mirrors_update_test: Crash # Internal Error: No default constructor available.
+mirrors/deferred_mirrors_update_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
mirrors/deferred_type_test: Crash # Internal Error: No default constructor available.
-mirrors/delegate_call_through_getter_test: RuntimeError # Please triage this failure.
-mirrors/delegate_test: RuntimeError # Please triage this failure.
+mirrors/delegate_call_through_getter_test : RuntimeError #
+mirrors/delegate_test : RuntimeError #
mirrors/disable_tree_shaking_test: Crash # Internal Error: No default constructor available.
mirrors/empty_test: Crash # Internal Error: No default constructor available.
mirrors/enum_test: Crash # Internal Error: No default constructor available.
@@ -571,7 +546,6 @@
mirrors/generics_substitution_test: Crash # Internal Error: No default constructor available.
mirrors/generics_test/01: Crash # Internal Error: No default constructor available.
mirrors/generics_test/none: Crash # Internal Error: No default constructor available.
-mirrors/get_field_cache_test: RuntimeError # Please triage this failure.
mirrors/get_field_static_test/00: Crash # Internal Error: No default constructor available.
mirrors/get_field_static_test/none: Crash # Internal Error: No default constructor available.
mirrors/globalized_closures2_test/00: Crash # Internal Error: No default constructor available.
@@ -581,7 +555,6 @@
mirrors/hierarchy_invariants_test: Crash # Internal Error: No default constructor available.
mirrors/immutable_collections_test: Crash # Internal Error: No default constructor available.
mirrors/inherit_field_test: Crash # Internal Error: No default constructor available.
-mirrors/inherited_metadata_test: Crash # Internal Error: No default constructor available.
mirrors/initializing_formals_test/01: Crash # Internal Error: No default constructor available.
mirrors/initializing_formals_test/none: Crash # Internal Error: No default constructor available.
mirrors/instance_members_easier_test: Crash # Internal Error: No default constructor available.
@@ -593,7 +566,6 @@
mirrors/intercepted_class_test: Crash # Internal Error: No default constructor available.
mirrors/intercepted_object_test: Crash # Internal Error: No default constructor available.
mirrors/intercepted_superclass_test: Crash # Internal Error: No default constructor available.
-mirrors/invocation_cache_test: RuntimeError # Please triage this failure.
mirrors/invocation_fuzz_test/emptyarray: Crash # Internal Error: No default constructor available.
mirrors/invocation_fuzz_test/false: Crash # Internal Error: No default constructor available.
mirrors/invocation_fuzz_test/none: Crash # Internal Error: No default constructor available.
@@ -647,7 +619,6 @@
mirrors/metadata_allowed_values_test/14: Crash # Internal Error: No default constructor available.
mirrors/metadata_allowed_values_test/none: Crash # Internal Error: No default constructor available.
mirrors/metadata_class_mirror_test: Crash # Internal Error: No default constructor available.
-mirrors/metadata_const_map_test: Crash # Internal Error: No default constructor available.
mirrors/metadata_constructed_constant_test: Crash # Internal Error: No default constructor available.
mirrors/metadata_constructor_arguments_test/none: Crash # Internal Error: No default constructor available.
mirrors/metadata_nested_constructor_call_test/none: Crash # Internal Error: No default constructor available.
@@ -665,8 +636,6 @@
mirrors/mirrors_reader_test: Crash # Internal Error: No default constructor available.
mirrors/mirrors_resolve_fields_test: Crash # Internal Error: No default constructor available.
mirrors/mirrors_test: Crash # Internal Error: No default constructor available.
-mirrors/mirrors_used_typedef_declaration_test/01: Crash # Internal Error: No default constructor available.
-mirrors/mirrors_used_typedef_declaration_test/none: Crash # Internal Error: No default constructor available.
mirrors/mixin_application_test: Crash # Internal Error: No default constructor available.
mirrors/mixin_members_test: Crash # Internal Error: No default constructor available.
mirrors/mixin_test: Crash # Internal Error: No default constructor available.
@@ -677,11 +646,9 @@
mirrors/null2_test: Crash # Internal Error: No default constructor available.
mirrors/null_test: Crash # Invalid argument(s)
mirrors/operator_test: Crash # Internal Error: No default constructor available.
-mirrors/parameter_annotation_mirror_test: Crash # Internal Error: No default constructor available.
mirrors/parameter_is_const_test/none: Crash # Internal Error: No default constructor available.
mirrors/parameter_metadata_test: Crash # Internal Error: No default constructor available.
mirrors/parameter_of_mixin_app_constructor_test: Crash # Internal Error: No default constructor available.
-mirrors/parameter_test/01: Crash # Internal Error: No default constructor available.
mirrors/parameter_test/none: Crash # Internal Error: No default constructor available.
mirrors/private_symbol_mangling_test: Crash # Internal Error: No default constructor available.
mirrors/private_types_test: Crash # Internal Error: No default constructor available.
@@ -719,8 +686,6 @@
mirrors/relation_subtype_test: Crash # Internal Error: No default constructor available.
mirrors/removed_api_test: Crash # Internal Error: No default constructor available.
mirrors/repeated_private_anon_mixin_app_test: Crash # Internal Error: No default constructor available.
-mirrors/return_type_test: Crash # Internal Error: No default constructor available.
-mirrors/runtime_type_test: Crash # Internal Error: No default constructor available.
mirrors/set_field_with_final_inheritance_test: Crash # Internal Error: No default constructor available.
mirrors/set_field_with_final_test: Crash # Internal Error: No default constructor available.
mirrors/spawn_function_root_library_test: Crash # Internal Error: No default constructor available.
@@ -736,22 +701,15 @@
mirrors/to_string_test: Crash # Internal Error: No default constructor available.
mirrors/top_level_accessors_test: Crash # Internal Error: No default constructor available.
mirrors/type_argument_is_type_variable_test: Crash # Internal Error: No default constructor available.
-mirrors/type_mirror_for_type_test: Crash # Internal Error: No default constructor available.
mirrors/type_variable_is_static_test: Crash # Internal Error: No default constructor available.
mirrors/type_variable_owner_test/01: Crash # Internal Error: No default constructor available.
mirrors/type_variable_owner_test/none: Crash # Internal Error: No default constructor available.
mirrors/typearguments_mirror_test: Crash # Internal Error: No default constructor available.
-mirrors/typedef_deferred_library_test: Crash # Internal Error: No default constructor available.
-mirrors/typedef_in_signature_test: Crash # Internal Error: No default constructor available.
-mirrors/typedef_library_test: Crash # Internal Error: No default constructor available.
+mirrors/typedef_deferred_library_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
mirrors/typedef_metadata_test: Crash # Internal Error: No default constructor available.
mirrors/typedef_reflected_type_test/01: Crash # Internal Error: No default constructor available.
mirrors/typedef_reflected_type_test/none: Crash # Internal Error: No default constructor available.
mirrors/typedef_test: Crash # Internal Error: No default constructor available.
mirrors/unnamed_library_test: Crash # Internal Error: No default constructor available.
-mirrors/unused_mirrors_used_test: RuntimeError # Please triage this failure.
mirrors/variable_is_const_test/none: Crash # Internal Error: No default constructor available.
-typed_data/int32x4_test: RuntimeError # Please triage this failure.
-typed_data/typed_data_from_list_test: RuntimeError # Please triage this failure.
typed_data/typed_data_list_test: RuntimeError # Please triage this failure.
-typed_data/typed_list_iterable_test: RuntimeError # Please triage this failure.
diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart b/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart
index 851c04c..45533d4 100755
--- a/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart
Binary files differ
diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart b/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart
index bcf3e64..d93615c 100755
--- a/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart
@@ -2,8 +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.
-// This file is marked executable so source control will preserve the type of
-// line ending.
+// Note: This test relies on CRLF line endings in the source file.
library line_endings.crlf;
diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart b/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart
index 71a34c8..b805a75 100755
--- a/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart
@@ -2,8 +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.
-// This file is marked executable so source control will preserve the type of
-// line ending.
+// Note: This test relies on LF line endings in the source file.
library line_endings.lf;
diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_test.dart b/tests/lib/mirrors/method_mirror_source_line_ending_test.dart
index e052cc1..c059397 100644
--- a/tests/lib/mirrors/method_mirror_source_line_ending_test.dart
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_test.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// Note: These tests rely on specific line endings in the source files.
+
import "dart:mirrors";
import "package:expect/expect.dart";
diff --git a/tests/lib/mirrors/method_mirror_source_other.dart b/tests/lib/mirrors/method_mirror_source_other.dart
index 29adf5b..37151b6 100644
--- a/tests/lib/mirrors/method_mirror_source_other.dart
+++ b/tests/lib/mirrors/method_mirror_source_other.dart
@@ -3,4 +3,6 @@
}
// This function must be on the first line.
-class SomethingInOther {}
\ No newline at end of file
+class SomethingInOther {}
+
+// Note: This test relies on LF line endings in the source file.
diff --git a/tests/lib/mirrors/method_mirror_source_test.dart b/tests/lib/mirrors/method_mirror_source_test.dart
index 9b09452..cea4dc1 100644
--- a/tests/lib/mirrors/method_mirror_source_test.dart
+++ b/tests/lib/mirrors/method_mirror_source_test.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// Note: This test relies on LF line endings in the source file.
+
import "dart:mirrors";
import "package:expect/expect.dart";
import "method_mirror_source_other.dart";
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 7036123..9edc6cc 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -170,120 +170,16 @@
io/http_client_stays_alive_test: Skip # Timeout.
[ $compiler == dart2js && $cps_ir ]
-array_bounds_check_generalization_test: RuntimeError # Please triage this failure.
-coverage_test: Crash # Invalid argument(s)
-io/addlatexhash_test: Crash # Invalid argument(s)
-io/create_recursive_test: Crash # Invalid argument(s)
-io/directory_list_pause_test: Crash # Invalid argument(s)
-io/directory_uri_test: Crash # Invalid argument(s)
-io/file_lock_test: Crash # Invalid argument(s)
-io/file_stat_test: Crash # Invalid argument(s)
io/file_test: Crash # Invalid argument(s)
-io/file_typed_data_test: Crash # Invalid argument(s)
-io/file_uri_test: Crash # Invalid argument(s)
io/file_write_only_test: Crash # (main()async{asyncSt... cannot handle async/sync*/async* functions
-io/http_10_test: Crash # Internal Error: No default constructor available.
-io/http_advanced_test: Crash # Internal Error: No default constructor available.
-io/http_auth_digest_test: Crash # Invalid argument(s)
-io/http_auth_test: Crash # Invalid argument(s)
-io/http_basic_test: Crash # Internal Error: No default constructor available.
io/http_bind_test: Crash # (testBindShared(Stri... cannot handle async/sync*/async* functions
-io/http_client_connect_test: Crash # Internal Error: No default constructor available.
-io/http_client_exception_test: Crash # Internal Error: No default constructor available.
-io/http_client_request_test: Crash # Internal Error: No default constructor available.
-io/http_client_stays_alive_test: Crash # Internal Error: No default constructor available.
-io/http_close_test: Crash # Internal Error: No default constructor available.
-io/http_compression_test: Crash # Internal Error: No default constructor available.
-io/http_connection_close_test: Crash # Invalid argument(s)
-io/http_connection_header_test: Crash # Internal Error: No default constructor available.
-io/http_connection_info_test: Crash # Internal Error: No default constructor available.
-io/http_content_length_test: Crash # Internal Error: No default constructor available.
-io/http_cookie_date_test: Crash # Invalid argument(s)
-io/http_cookie_test: Crash # Internal Error: No default constructor available.
-io/http_cross_process_test: Crash # Internal Error: No default constructor available.
-io/http_date_test: Crash # Invalid argument(s)
-io/http_detach_socket_test: Crash # Internal Error: No default constructor available.
-io/http_head_test: Crash # Internal Error: No default constructor available.
-io/http_headers_state_test: Crash # Internal Error: No default constructor available.
-io/http_headers_test: Crash # Internal Error: No default constructor available.
-io/http_ipv6_test: Crash # Invalid argument(s)
-io/http_keep_alive_test: Crash # Internal Error: No default constructor available.
-io/http_no_reason_phrase_test: Crash # Invalid argument(s)
-io/http_outgoing_size_test: Crash # Internal Error: No default constructor available.
-io/http_parser_test: Crash # Invalid argument(s)
-io/http_proxy_configuration_test: Crash # Internal Error: No default constructor available.
-io/http_proxy_test: Crash # Invalid argument(s)
-io/http_read_test: Crash # Internal Error: No default constructor available.
-io/http_redirect_test: Crash # Invalid argument(s)
-io/http_request_pipeling_test: Crash # Internal Error: No default constructor available.
-io/http_requested_uri_test: Crash # Internal Error: No default constructor available.
-io/http_response_deadline_test: Crash # Internal Error: No default constructor available.
-io/http_reuse_server_port_test: Crash # Internal Error: No default constructor available.
-io/http_server_close_response_after_error_test: Crash # Internal Error: No default constructor available.
-io/http_server_early_client_close2_test: Crash # Internal Error: No default constructor available.
-io/http_server_early_client_close_test: Crash # Internal Error: No default constructor available.
-io/http_server_idle_timeout_test: Crash # Internal Error: No default constructor available.
-io/http_server_response_test: Crash # Internal Error: No default constructor available.
-io/http_server_test: Crash # Internal Error: No default constructor available.
-io/http_session_test: Crash # Internal Error: No default constructor available.
-io/http_shutdown_test: Crash # Internal Error: No default constructor available.
-io/http_stream_close_test: Crash # Invalid argument(s)
+io/http_parser_test : RuntimeError # TypeError: receiver.get$_nums is not a function
io/https_bad_certificate_test: Crash # (main()async{var cli... cannot handle async/sync*/async* functions
-io/https_client_certificate_test: Crash # Invalid argument(s)
-io/https_client_exception_test: Crash # Invalid argument(s)
-io/https_server_test: Crash # Internal Error: No default constructor available.
-io/https_unauthorized_test: Crash # Internal Error: No default constructor available.
io/issue_22636_test: Crash # (test()async{server=... cannot handle async/sync*/async* functions
io/issue_22637_test: Crash # (test()async{server=... cannot handle async/sync*/async* functions
-io/link_async_test: Crash # Invalid argument(s)
-io/link_test: Crash # Invalid argument(s)
-io/link_uri_test: Crash # Invalid argument(s)
io/observatory_test: Crash # Invalid argument(s)
-io/parent_test: Crash # Invalid argument(s)
-io/platform_resolved_executable_test/00: Crash # Internal Error: No default constructor available.
-io/platform_resolved_executable_test/01: Crash # Invalid argument(s)
-io/platform_resolved_executable_test/02: Crash # Invalid argument(s)
-io/platform_resolved_executable_test/03: Crash # Internal Error: No default constructor available.
-io/platform_resolved_executable_test/04: Crash # Invalid argument(s)
-io/platform_resolved_executable_test/05: Crash # Invalid argument(s)
-io/platform_resolved_executable_test/06: Crash # Internal Error: No default constructor available.
-io/platform_resolved_executable_test/none: Crash # Internal Error: No default constructor available.
-io/platform_test: Crash # Internal Error: No default constructor available.
-io/process_environment_test: Crash # Internal Error: No default constructor available.
-io/process_path_environment_test: Crash # Internal Error: No default constructor available.
-io/raw_secure_server_closing_test: Crash # Invalid argument(s)
-io/raw_secure_server_socket_test: Crash # Invalid argument(s)
-io/raw_secure_socket_pause_test: Crash # Internal Error: No default constructor available.
-io/raw_secure_socket_test: Crash # Internal Error: No default constructor available.
-io/raw_socket_test: Crash # Invalid argument(s)
-io/raw_socket_typed_data_test: Crash # Invalid argument(s)
-io/regress_8828_test: Crash # Internal Error: No default constructor available.
-io/regress_9194_test: Crash # Internal Error: No default constructor available.
-io/resolve_symbolic_links_test: Crash # Invalid argument(s)
-io/secure_builtin_roots_test: Crash # Invalid argument(s)
-io/secure_server_closing_test: Crash # Invalid argument(s)
-io/secure_server_socket_test: Crash # Invalid argument(s)
-io/secure_socket_test: Crash # Internal Error: No default constructor available.
-io/skipping_dart2js_compilations_test: Crash # Invalid argument(s)
io/socket_bind_test: Crash # (testListenCloseList... cannot handle async/sync*/async* functions
-io/socket_exception_test: Crash # Invalid argument(s)
io/socket_source_address_test: Crash # (Future testConnect(... cannot handle async/sync*/async* functions
-io/socket_upgrade_to_secure_test: Crash # Invalid argument(s)
-io/stdin_sync_test: Crash # Internal Error: No default constructor available.
-io/test_extension_fail_test: Crash # Invalid argument(s)
-io/test_extension_test: Crash # Invalid argument(s)
-io/test_runner_test: Crash # Internal Error: No default constructor available.
-io/uri_platform_test: Crash # Invalid argument(s)
-io/web_socket_error_test: Crash # Internal Error: No default constructor available.
-io/web_socket_ping_test: Crash # Internal Error: No default constructor available.
-io/web_socket_pipe_test: Crash # Internal Error: No default constructor available.
-io/web_socket_protocol_test: Crash # Internal Error: No default constructor available.
-io/web_socket_test: Crash # Internal Error: No default constructor available.
-io/web_socket_typed_data_test: Crash # Internal Error: No default constructor available.
-io/windows_environment_test: Crash # Invalid argument(s)
priority_queue_stress_test: RuntimeError # receiver.get$_collection$_nums is not a function
slowpath_safepoints_test: RuntimeError # Cannot read property 'prototype' of undefined
-status_expression_test: RuntimeError # Please triage this failure.
typed_array_test: RuntimeError # receiver.get$_collection$_nums is not a function
-verbose_gc_to_bmu_test: Crash # Invalid argument(s)
-verified_mem_test: RuntimeError # Please triage this failure.
diff --git a/tests/try/poi/serialize_test.dart b/tests/try/poi/serialize_test.dart
index 8cc192d..87f4d7b 100644
--- a/tests/try/poi/serialize_test.dart
+++ b/tests/try/poi/serialize_test.dart
@@ -532,6 +532,10 @@
"kind": "class"
},
{
+ "name": "Resource",
+ "kind": "class"
+ },
+ {
"name": "Set",
"kind": "class"
},
diff --git a/tools/VERSION b/tools/VERSION
index d214ff1..11b57f2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 1
MINOR 12
PATCH 0
-PRERELEASE 0
+PRERELEASE 1
PRERELEASE_PATCH 0
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 3a2b541..fefd0c6 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -204,7 +204,8 @@
for library in [join('_blink', 'dartium'),
join('_chrome', 'dart2js'), join('_chrome', 'dartium'),
- join('_internal', 'compiler'),
+ join('_internal', 'js_runtime'),
+ join('_internal', 'sdk_library_metadata'),
'async', 'collection', 'convert', 'core', 'developer',
'internal', 'io', 'isolate',
join('html', 'dart2js'), join('html', 'dartium'),
@@ -219,10 +220,6 @@
ignore=ignore_patterns('*.svn', 'doc', '*.py', '*.gypi', '*.sh',
'.gitignore'))
- # Copy lib/_internal/libraries.dart.
- copyfile(join(HOME, 'sdk', 'lib', '_internal', 'libraries.dart'),
- join(LIB, '_internal', 'libraries.dart'))
-
# Create and copy tools.
UTIL = join(SDK_tmp, 'util')
os.makedirs(UTIL)
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 191a94c..f3d4784 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -13,7 +13,7 @@
"dartium_chromium_commit": "62a7524d4f71c9e0858d24b0aa1bbff3a2d09bff",
"chromium_base_revision": "297060",
"dartium_webkit_branch": "/blink/branches/dart/dartium",
- "dartium_webkit_revision": "197293",
+ "dartium_webkit_revision": "198020",
"args_tag": "@0.13.0",
"barback_rev" : "@29ee90dbcf77cfd64632fa2797a4c8a4f29a4b51",
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index 0934721..1d55826 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -146,9 +146,9 @@
'_DOMWindowCrossFrame': () => _DOMWindowCrossFrame,
// FIXME: Move these to better locations.
'DateTime': () => DateTime,
- 'JsObject': () => js.JsObject,
- 'JsFunction': () => js.JsFunction,
- 'JsArray': () => js.JsArray,
+ 'JsObject': () => js.JsObjectImpl,
+ 'JsFunction': () => js.JsFunctionImpl,
+ 'JsArray': () => js.JsArrayImpl,
$!TYPE_MAP
};
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index e2b0d18..fc1d536 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -279,7 +279,8 @@
Uri sdk = useSdk ?
nativeDirectoryToUri(buildDir).resolve('dart-sdk/') :
nativeDirectoryToUri(TestUtils.dartDir.toNativePath()).resolve('sdk/');
- Uri preambleDir = sdk.resolve('lib/_internal/compiler/js_lib/preambles/');
+ Uri preambleDir = sdk.resolve(
+ 'lib/_internal/js_runtime/lib/preambles/');
return runtimeConfiguration.dart2jsPreambles(preambleDir)
..add(artifact.filename);
}
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 3c3116a..f09f283 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -1897,7 +1897,7 @@
// NOTE: We exclude tests and patch files for now.
return filename.endsWith(".dart") &&
!filename.endsWith("_test.dart") &&
- !filename.contains("_internal/compiler/js_lib");
+ !filename.contains("_internal/js_runtime/lib");
}
bool get listRecursively => true;
diff --git a/utils/analysis_server/analysis_server.gyp b/utils/analysis_server/analysis_server.gyp
index 99e059b..1708ad7 100644
--- a/utils/analysis_server/analysis_server.gyp
+++ b/utils/analysis_server/analysis_server.gyp
@@ -17,7 +17,7 @@
'action_name': 'generate_analysis_server_snapshot',
'inputs': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
- '../../sdk/lib/_internal/libraries.dart',
+ '../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
'<(SHARED_INTERMEDIATE_DIR)/packages.stamp',
'<(SHARED_INTERMEDIATE_DIR)/pkg_files.stamp',
],
diff --git a/utils/apidoc/apidoc.dart b/utils/apidoc/apidoc.dart
index 1dcc495..db74d32 100644
--- a/utils/apidoc/apidoc.dart
+++ b/utils/apidoc/apidoc.dart
@@ -20,12 +20,11 @@
import 'html_diff.dart';
-// TODO(rnystrom): Use "package:" URL (#4968).
-import '../../pkg/compiler/lib/src/mirrors/source_mirrors.dart';
-import '../../pkg/compiler/lib/src/mirrors/mirrors_util.dart';
-import '../../pkg/compiler/lib/src/filenames.dart';
-import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart';
-import '../../sdk/lib/_internal/libraries.dart';
+import 'package:compiler/src/mirrors/source_mirrors.dart';
+import 'package:compiler/src/mirrors/mirrors_util.dart';
+import 'package:compiler/src/filenames.dart';
+import 'package:dartdoc/dartdoc.dart';
+import 'package:sdk_library_metadata/libraries.dart';
import 'package:path/path.dart' as path;
HtmlDiff _diff;
diff --git a/utils/compiler/compiler.gyp b/utils/compiler/compiler.gyp
index 61c4548..37d2074 100644
--- a/utils/compiler/compiler.gyp
+++ b/utils/compiler/compiler.gyp
@@ -20,7 +20,7 @@
'action_name': 'generate_snapshots',
'inputs': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
- '../../sdk/lib/_internal/libraries.dart',
+ '../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
'<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../runtime/lib", "../../sdk/lib/_internal/dartdoc"])',
'create_snapshot.dart',
'<(SHARED_INTERMEDIATE_DIR)/dart2js_files.stamp',
diff --git a/utils/dartfmt/dartfmt.gyp b/utils/dartfmt/dartfmt.gyp
index 2615f85..62b8906 100644
--- a/utils/dartfmt/dartfmt.gyp
+++ b/utils/dartfmt/dartfmt.gyp
@@ -16,7 +16,7 @@
'action_name': 'generate_dartfmt_snapshot',
'inputs': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
- '../../sdk/lib/_internal/libraries.dart',
+ '../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
'<(SHARED_INTERMEDIATE_DIR)/packages.stamp',
'<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../third_party/pkg_tested/dart_style"])',
],
diff --git a/utils/pub/pub.gyp b/utils/pub/pub.gyp
index 81dcec7..146a505 100644
--- a/utils/pub/pub.gyp
+++ b/utils/pub/pub.gyp
@@ -18,7 +18,7 @@
'action_name': 'generate_pub_snapshot',
'inputs': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
- '../../sdk/lib/_internal/libraries.dart',
+ '../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
'<(SHARED_INTERMEDIATE_DIR)/dart2js_files.stamp',
'<(SHARED_INTERMEDIATE_DIR)/pkg_files.stamp',
'<(SHARED_INTERMEDIATE_DIR)/packages.stamp',