Version 2.0.0-dev.49.0
Merge commit '17d7f23e71d588656612d1dfdee4c90d16ddc594' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 931d854..de609346 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,24 +1,13 @@
-## 2.0.0-dev.48.0
-
-### Language
-
-#### Strong Mode
-
-### Core library changes
-
-### Dart VM
+## 2.0.0-dev.49.0
### Tool Changes
#### Pub
-#### Other Tools
+* Fix another bug where the version solver could crash when resolving a conflict
+ involving pre-release constraints ([`pub_semver` issue 20][]).
-## 2.0.0-dev.49.0
-
-## 2.0.0-dev.47.0
-
-### Tool Changes
+[`pub_semver` issue 20]: https://github.com/dart-lang/pub_semver/issues/20
## 2.0.0-dev.48.0
diff --git a/DEPS b/DEPS
index 82394f1..4ba2514 100644
--- a/DEPS
+++ b/DEPS
@@ -96,10 +96,9 @@
"http_throttle_tag" : "@1.0.1",
"idl_parser_rev": "@5fb1ebf49d235b5a70c9f49047e83b0654031eb7",
"intl_tag": "@0.15.2",
- "isolate_tag": "@1.1.0",
"jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "@2.0.6",
- "linter_tag": "@0.1.47",
+ "linter_tag": "@0.1.48",
"logging_tag": "@0.11.3+1",
"markdown_tag": "@1.1.1",
"matcher_tag": "@0.12.1+4",
@@ -116,7 +115,7 @@
"pool_tag": "@1.3.4",
"protobuf_tag": "@0.7.1",
"pub_rev": "@4947e0b3cb3ec77e4e8fe0d3141ce4dc60f43256",
- "pub_semver_tag": "@1.3.6",
+ "pub_semver_tag": "@1.3.7",
"quiver_tag": "@5aaa3f58c48608af5b027444d561270b53f15dbf",
"resource_rev":"@af5a5bf65511943398146cf146e466e5f0b95cb9",
"root_certificates_rev": "@16ef64be64c7dfdff2b9f4b910726e635ccc519e",
@@ -251,8 +250,6 @@
Var("http_throttle_tag"),
Var("dart_root") + "/third_party/pkg/intl":
Var("dart_git") + "intl.git" + Var("intl_tag"),
- Var("dart_root") + "/third_party/pkg/isolate":
- Var("dart_git") + "isolate.git" + Var("isolate_tag"),
Var("dart_root") + "/third_party/pkg/json_rpc_2":
Var("dart_git") + "json_rpc_2.git" + Var("json_rpc_2_tag"),
Var("dart_root") + "/third_party/pkg/linter":
diff --git a/docs/language/informal/subtyping.md b/docs/language/informal/subtyping.md
index 121a657..20aa5aa 100644
--- a/docs/language/informal/subtyping.md
+++ b/docs/language/informal/subtyping.md
@@ -1,4 +1,4 @@
-# Dart 2.0 static and runtime subtyping
+# Dart 2.0 Static and Runtime Subtyping
leafp@google.com
@@ -7,6 +7,7 @@
This is intended to define the core of the Dart 2.0 static and runtime subtyping
relation.
+
## Types
The syntactic set of types used in this draft are a slight simplification of
@@ -14,12 +15,15 @@
The meta-variables `X`, `Y`, and `Z` range over type variables.
-The meta-variables `T`, `S`, and `U` range over types.
+The meta-variables `T`, `S`, `U`, and `V` range over types.
The meta-variable `C` ranges over classes.
The meta-variable `B` ranges over types used as bounds for type variables.
+As a general rule, indices up to `k` are used for type parameters and type
+arguments, `n` for required value parameters, and `m` for all value parameters.
+
The set of types under consideration are as follows:
- Type variables `X`
@@ -31,10 +35,10 @@
- `Function`
- `Future<T>`
- `FutureOr<T>`
-- Interface types `C`, `C<T0, ..., Tn>`
+- Interface types `C`, `C<T0, ..., Tk>`
- Function types
- - `U Function<X0 extends B0, ...., Xl extends Bl>(T0 x0, ...., Tn xn, [Tn+1 xn+1, ..., Tm xm])`
- - `U Function<X0 extends B0, ...., Xl extends Bl>(T0 x0, ...., Tn xn, {Tn+1 xn+1, ..., Tm xm})`
+ - `U Function<X0 extends B0, ...., Xk extends Bk>(T0 x0, ...., Tn xn, [Tn+1 xn+1, ..., Tm xm])`
+ - `U Function<X0 extends B0, ...., Xk extends Bk>(T0 x0, ...., Tn xn, {Tn+1 xn+1, ..., Tm xm})`
We leave the set of interface types unspecified, but assume a class hierarchy
which provides a mapping from interfaces types `T` to the set of direct
@@ -46,7 +50,7 @@
The types `Object`, `dynamic` and `void` are all referred to as *top* types, and
are considered equivalent as types (including when they appear as sub-components
of other types). They exist as distinct names only to support distinct errors
-and warnings (or absense thereof).
+and warnings (or absence thereof).
The type `X & T` represents the result of a type promotion operation on a
variable. In certain circumstances (defined elsewhere) a variable `x` of type
@@ -56,16 +60,18 @@
type variables only occur statically (never at runtime).
Given the current promotion semantics the following properties are also true:
- - If `X` has bound `B` then for any type `X & T`, `T <: B` will be true
+ - If `X` has bound `B` then for any type `X & T`, `T <: B` will be true.
- Promoted type variable types will only appear as top level types: that is,
they can never appear as sub-components of other types, in bounds, or as
part of other promoted type variables.
+
## Notation
-We use `S[T0/Y0, ..., Tl/Yl]` for the result of performing a simultaneous
-capture-avoiding substitution of types `T0, ..., Tl` for the type variables `Y0,
-..., Yl` in the type `S`.
+We use `S[T0/Y0, ..., Tk/Yk]` for the result of performing a simultaneous
+capture-avoiding substitution of types `T0, ..., Tk` for the type variables
+`Y0, ..., Yk` in the type `S`.
+
## Type equality
@@ -75,7 +81,8 @@
TODO: make these rules explicit.
-## Algorithmic (Syntax Directed) Subtyping
+
+## Algorithmic subtyping
By convention the following rules are intended to be applied in top down order,
with exactly one rule syntactically applying. That is, rules are written in the
@@ -91,9 +98,15 @@
a rule (but not the syntactic criteria for any rule preceeding it), then the
subtyping query holds iff the listed additional conditions hold.
+This makes the rules algorithmic, because they correspond in an obvious manner
+to an algorithm with an acceptable time complexity, and it makes them syntax
+directed because the overall structure of the algorithm corresponds to specific
+syntactic shapes. We will use the word _algorithmic_ to refer to this property.
+
The runtime subtyping rules can be derived by eliminating all clauses dealing
with promoted type variables.
+
### Rules
We say that a type `T0` is a subtype of a type `T1` (written `T0 <: T1`) when:
@@ -140,26 +153,30 @@
- **Function Type/Function**: `T0` is a function type and `T1` is `Function`
-- **Interface Compositionality**: `T0` is an interface type `C0<S0, ..., Sn>`
- and `T1` is `C0<U0, ..., Un>`
+- **Interface Compositionality**: `T0` is an interface type `C0<S0, ..., Sk>`
+ and `T1` is `C0<U0, ..., Uk>`
- and each `Si <: Ui`
- **Super-Interface**: `T0` is an interface type with super-interfaces `S0,...Sn`
- and `Si <: T1` for some `i`
-- **Positional Function Types**: `T0` is `U0 Function<X0 extends B00, ..., Xk extends B0k>(T0 x0, ..., Tn xn, [Tn+1 xn+1, ..., Tm xm])`
- - and `T1` is `U1 Function<Y0 extends B10, ..., Yk extends B1k>(S0 y0, ..., Sp yp, [Sp+1 yp+1, ..., Sq yq])`
+- **Positional Function Types**: `T0` is
+ `U0 Function<X0 extends B00, ..., Xk extends B0k>(V0 x0, ..., Vn xn, [Vn+1 xn+1, ..., Vm xm])`
+ - and `T1` is
+ `U1 Function<Y0 extends B10, ..., Yk extends B1k>(S0 y0, ..., Sp yp, [Sp+1 yp+1, ..., Sq yq])`
- and `p >= n`
- and `m >= q`
- - and `Si[Z0/Y0, ..., Zk/Yk] <: Ti[Z0/X0, ..., Zk/Xk]` for `i` in `0...q`
+ - and `Si[Z0/Y0, ..., Zk/Yk] <: Vi[Z0/X0, ..., Zk/Xk]` for `i` in `0...q`
- and `U0[Z0/X0, ..., Zk/Xk] <: U1[Z0/Y0, ..., Zk/Yk]`
- and `B0i[Z0/X0, ..., Zk/Xk] === B1i[Z0/Y0, ..., Zk/Yk]` for `i` in `0...k`
- where the `Zi` are fresh type variables with bounds `B0i[Z0/X0, ..., Zk/Xk]`
-- **Named Function Types**: `T0` is `U0 Function<X0 extends B00, ..., Xk extends B0k>(T0 x0, ..., Tn xn, {Tn+1 xn+1, ..., Tm xm})`
- - and `T1` is `U1 Function<Y0 extends B10, ..., Yk extends B1k>(S0 y0, ..., Sn yn, {Sn+1 yn+1, ..., Sq yq})`
+- **Named Function Types**: `T0` is
+ `U0 Function<X0 extends B00, ..., Xk extends B0k>(V0 x0, ..., Vn xn, {Vn+1 xn+1, ..., Vm xm})`
+ - and `T1` is
+ `U1 Function<Y0 extends B10, ..., Yk extends B1k>(S0 y0, ..., Sn yn, {Sn+1 yn+1, ..., Sq yq})`
- and `{yn+1, ... , yq}` subsetof `{xn+1, ... , xm}`
- - and `Si[Z0/Y0, ..., Zk/Yk] <: Ti[Z0/X0, ..., Zk/Xk]` for `i` in `0...n`
+ - and `Si[Z0/Y0, ..., Zk/Yk] <: Vi[Z0/X0, ..., Zk/Xk]` for `i` in `0...n`
- and `Si[Z0/Y0, ..., Zk/Yk] <: Tj[Z0/X0, ..., Zk/Xk]` for `i` in `n+1...q`, `yj = xi`
- and `U0[Z0/X0, ..., Zk/Xk] <: U1[Z0/Y0, ..., Zk/Yk]`
- and `B0i[Z0/X0, ..., Zk/Xk] === B1i[Z0/Y0, ..., Zk/Yk]` for `i` in `0...k`
@@ -169,14 +186,18 @@
that the choice of common variable names avoid capture. It is valid to choose
the `Xi` or the `Yi` for `Zi` so long as capture is avoided*
-## Derivation of syntax directed rules
-This section sketches out the derivation of the syntax directed rules from the
-interpretation of `FutureOr` and promoted type bounds as intersection types.
+## Derivation of algorithmic rules
-### Non syntax directed rules
+This section sketches out the derivation of the algorithmic rules from the
+interpretation of `FutureOr` as a union type, and promoted type bounds as
+intersection types, based on standard rules for such types that do not satisfy
+the requirements for being algorithmic.
-The non syntax directed rules that we derive from first principles of union and
+
+### Non-algorithmic rules
+
+The non-algorithmic rules that we derive from first principles of union and
intersection types are as follows:
Left union introduction:
@@ -191,16 +212,17 @@
Right intersection introduction:
- `S <: X & T` if `S <: X` and `S <: T`
-The only remaining non-syntax directed rule is the variable bounds rule:
+The only remaining non-algorithmic rule is the variable bounds rule:
Variable bounds:
- `X <: T` if `X extends B` and `B <: T`
-All other rules are syntax directed.
+All other rules are algorithmic.
-Note: I believe that bounds can be treated simply as uses of intersections,
+Note: We believe that bounds can be treated simply as uses of intersections,
which could simplify this presentation.
+
### Preliminaries
**Lemma 1**: If there is any derivation of `FutureOr<S> <: T`, then there is a
@@ -250,7 +272,6 @@
- so by left union introduction, we have a derivation of `FutureOr<S> <: X & T0`
- QED
-
Note: The reverse is not true. Counter-example:
Given arbitrary `B <: A`, suppose we wish to show that `(X extends FutureOr<B>)
@@ -279,7 +300,6 @@
right union introduction rule. But applying the variable bounds rule doesn't
work.
-
**Lemma 2**: If there is any derivation of `S <: X & T`, then there is
derivation ending in a use of right intersection introduction.
@@ -326,29 +346,30 @@
- so by right intersection introduction, we have a derivation of `FutureOr<S0> <: X & T`
- QED
-
**Conjecture 1**: `FutureOr<A> <: FutureOr<B>` is derivable iff `A <: B` is
derivable.
-pf: Showing that `A <: B => FutureOr<A> <: FutureOr<B>` is easy, it's not
-immediately clear to me how to tackle the opposite direction.
-
+Showing that `A <: B => FutureOr<A> <: FutureOr<B>` is easy, but it is not
+immediately clear how to tackle the opposite direction.
**Lemma 3**: Transitivity of subtyping is admissible. Given derivations of `A <: B`
and `B <: C`, there is a derivation of `A <: C`.
-proof sketch: The proof should go through by induction on sizes of derivations,
+Proof sketch: The proof should go through by induction on sizes of derivations,
cases on pairs of rules used. For any pair of rules used, we can construct a
new derivation of the desired result using only smaller derivations.
**Observation 1**: Given `X` with bound `S`, we have the property that for all
instances of `X & T`, `T <: S` will be true, and hence `S <: M => T <: M`.
-### Syntax directed rules
+
+### Algorithmic rules
Consider `T0 <: T1`.
+
#### Union on the left
+
By lemma 1, if `T0` is of the form `FutureOr<S0>` and there is any derivation of
`T0 <: T1`, then there is a derivation ending with a use of left union
introduction so we have the rule:
@@ -357,6 +378,7 @@
- and `Future<S0> <: T1`
- and `S0 <: T1`
+
#### Identical type variables
If `T0` and `T1` are both the same unpromoted type variable, then subtyping
@@ -375,10 +397,12 @@
is `X0 & S1`
- and `T0 <: S1`.
-*Note that neither of the previous rules are required to make the rules syntax
-directed: they are merely useful special cases of the next rule.*
+*Note that neither of the previous rules are required to make the rules
+algorithmic: they are merely useful special cases of the next rule.*
+
#### Intersection on the right
+
By lemma 2, if `T1` is of the `X1 & S1` and there is any derivation of `T0 <:
T1`, then there is a derivation ending with a use of right intersection
introduction, hence the rule:
@@ -387,7 +411,9 @@
- and `T0 <: X1`
- and `T0 <: S1`
+
#### Union on the right
+
Suppose `T1` is `FutureOr<S1>`. The rules above have eliminated the possibility
that `T0` is of the form `FutureOr<S0`. The only rules that could possibly
apply then are right union introduction, left intersection introduction, or the
@@ -418,7 +444,9 @@
- or `T0` is `X0` and `X0` has bound `S0` and `S0 <: T1`
- or `T0` is `X0 & S0` and `S0 <: T1`
+
#### Intersection on the left
+
Suppose `T0` is `X0 & S0`. We've eliminated the possibility that `T1` is
`FutureOr<S1>`, the possibility that `T1` is `X1 & S1`, and the possibility that
`T1` is any variant of `X0`. The only remaining rule that applies is left
@@ -430,7 +458,9 @@
`T0` is a promoted type variable `X0 & S0`
- and `S0 <: T1`
+
#### Type variable on the left
+
Suppose `T0` is `X0`. We've eliminated the possibility that `T1` is
`FutureOr<S1>`, the possibility that `T1` is `X1 & S1`, and the possibility that
`T1` is any variant of `X0`. The only rule that applies is the variable bounds
@@ -439,8 +469,5 @@
`T0` is a type variable `X0` with bound `B0`
- and `B0 <: T1`
-This eliminates all of the non-syntax directed rules: the remainder are strictly
-syntax directed.
-
-
-## Testing
+This eliminates all of the non-algorithmic rules: the remainder are strictly
+algorithmic.
diff --git a/pkg/analysis_server/benchmark/benchmarks.dart b/pkg/analysis_server/benchmark/benchmarks.dart
index 62e0b44..274571d 100644
--- a/pkg/analysis_server/benchmark/benchmarks.dart
+++ b/pkg/analysis_server/benchmark/benchmarks.dart
@@ -14,11 +14,13 @@
import 'package:path/path.dart' as path;
import 'perf/benchmarks_impl.dart';
+import 'perf/flutter_analyze_benchmark.dart';
Future main(List<String> args) async {
final List<Benchmark> benchmarks = [
new ColdAnalysisBenchmark(),
- new AnalysisBenchmark()
+ new AnalysisBenchmark(),
+ new FlutterAnalyzeBenchmark(),
];
CommandRunner runner = new CommandRunner(
@@ -110,6 +112,11 @@
actualIterations = math.min(benchmark.maxIterations, repeatCount);
}
+ if (benchmark.needsSetup) {
+ print('Setting up $benchmarkId...');
+ await benchmark.oneTimeSetup();
+ }
+
try {
BenchMarkResult result;
Stopwatch time = new Stopwatch()..start();
@@ -129,6 +136,8 @@
print('Finished in ${time.elapsed.inSeconds} seconds.\n');
Map m = {'benchmark': benchmarkId, 'result': result.toJson()};
print(json.encode(m));
+
+ await benchmark.oneTimeCleanup();
} catch (error, st) {
print('$benchmarkId threw exception: $error');
print(st);
@@ -147,6 +156,12 @@
Benchmark(this.id, this.description, {this.enabled: true, this.kind: 'cpu'});
+ bool get needsSetup => false;
+
+ Future oneTimeSetup() => new Future.value();
+
+ Future oneTimeCleanup() => new Future.value();
+
Future<BenchMarkResult> run({
bool quick: false,
bool useCFE: false,
diff --git a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
index 7f54193..0058fdf 100644
--- a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
@@ -109,7 +109,7 @@
static bool isFormat(String line) {
List<String> fields = _parseFields(line);
if (fields.length < 2) return false;
- int timeStamp = int.parse(fields[0], onError: (_) => -1);
+ int timeStamp = int.tryParse(fields[0]) ?? -1;
String opCode = fields[1];
return timeStamp > 0 && opCode == 'Ver';
}
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index a84e913..a04fb4a 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -174,10 +174,12 @@
String portText = args[DIAGNOSTIC_PORT_OPTION];
if (portText != null) {
- perfArgs.diagnosticPort = int.parse(portText, onError: (s) {
- print('invalid $DIAGNOSTIC_PORT_OPTION: $s');
+ if (int.tryParse(portText) == null) {
+ print('invalid $DIAGNOSTIC_PORT_OPTION: $portText');
showHelp = true;
- });
+ } else {
+ perfArgs.diagnosticPort = int.tryParse(portText);
+ }
}
if (args[VERY_VERBOSE_CMDLINE_OPTION] || rawArgs.contains('-vv')) {
diff --git a/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart b/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart
deleted file mode 100644
index fb60e43..0000000
--- a/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:args/args.dart';
-import 'package:test/test.dart';
-
-import 'performance_tests.dart';
-
-/**
- * Pass in the directory of the source to be analyzed as option `--source`,
- * optionally specify a priority file with `--priority` and the specific
- * test to run with `--metric`. If no test is specified, the default is
- * `analysis`.
- */
-main(List<String> arguments) {
- ArgParser parser = _createArgParser();
- var args = parser.parse(arguments);
- if (args[SOURCE_OPTION] == null) {
- print('path to source directory must be specified');
- exit(1);
- }
- source = args[SOURCE_OPTION];
- priorityFile = args[PRIORITY_FILE_OPTION];
- List names = args[METRIC_NAME_OPTION] as List;
- for (var name in names) {
- metricNames.add(name as String);
- }
-
- var test;
-
- if (metricNames.isEmpty) {
- test = new AnalysisTimingTest();
- } else {
- test = new SubscriptionTimingTest();
- }
-
- Future.wait(<Future>[test.test_timing()]);
-}
-
-const DEFAULT_METRIC = 'analysis';
-const METRIC_NAME_OPTION = 'metric';
-const PRIORITY_FILE_OPTION = 'priority';
-const SOURCE_OPTION = 'source';
-
-final metricNames = <String>[];
-String priorityFile;
-String source;
-
-ArgParser _createArgParser() => new ArgParser()
- ..addMultiOption(METRIC_NAME_OPTION,
- help: 'metric name (defaults to `analysis`)')
- ..addOption(SOURCE_OPTION, help: 'full path to source directory for analysis')
- ..addOption(PRIORITY_FILE_OPTION,
- help: '(optional) full path to a priority file');
-
-/**
- * AnalysisTimingTest measures the time taken by the analysis server to fully analyze
- * the given directory. Measurement is started after setting the analysis root, and
- * analysis is considered complete on receiving the `"isAnalyzing": false` message
- * from the analysis server.
- */
-class AnalysisTimingTest extends AbstractTimingTest {
- Future test_timing() async {
- // Set root after subscribing to avoid empty notifications.
- await init(source);
-
- setAnalysisRoot();
- stopwatch.start();
- await analysisFinished;
- print('analysis completed in ${stopwatch.elapsed}');
-
- await shutdown();
- }
-}
-
-class Metric {
- List<Duration> timings = <Duration>[];
- Stream eventStream;
- AnalysisService service;
- String name;
- Metric(this.name, this.service, this.eventStream);
- String toString() => '$name: $service, ${eventStream.runtimeType}, $timings';
-}
-
-/**
- * SubscriptionTimingTest measures the time taken by the analysis server to return
- * information for navigation, semantic highlighting, outline, get occurrences,
- * overrides, folding and implemented. These timings are wrt to the specified priority file
- * - the file that is currently opened and has focus in the editor. Measure the time from
- * when the client subscribes for the notifications till there is a response from the server.
- * Does not wait for analysis to be complete before subscribing for notifications.
- */
-class SubscriptionTimingTest extends AbstractTimingTest {
- List<Metric> _metrics;
-
- List<Metric> get metrics => _metrics ??= metricNames.map(getMetric).toList();
-
- Metric getMetric(String name) {
- switch (name) {
- case 'folding':
- return new Metric(name, AnalysisService.FOLDING, onAnalysisFolding);
- case 'highlighting':
- return new Metric(
- name, AnalysisService.HIGHLIGHTS, onAnalysisHighlights);
- case 'implemented':
- return new Metric(
- name, AnalysisService.IMPLEMENTED, onAnalysisImplemented);
- case 'navigation':
- return new Metric(
- name, AnalysisService.NAVIGATION, onAnalysisNavigation);
- case 'outline':
- return new Metric(name, AnalysisService.OUTLINE, onAnalysisOutline);
- case 'occurences':
- return new Metric(
- name, AnalysisService.OCCURRENCES, onAnalysisOccurrences);
- case 'overrides':
- return new Metric(name, AnalysisService.OVERRIDES, onAnalysisOverrides);
- }
- print('no metric found for $name');
- exit(1);
- return null; // Won't get here.
- }
-
- Future test_timing() async {
-// debugStdio();
-
- expect(metrics, isNotEmpty);
- expect(priorityFile, isNotNull,
- reason: 'A priority file must be specified for '
- '${metrics.first.name} testing.');
-
- await init(source);
- stopwatch.start();
-
- metrics.forEach((Metric m) => m.eventStream.listen((_) {
- m.timings.add(
- new Duration(milliseconds: stopwatch.elapsed.inMilliseconds));
- }));
-
- var subscriptions = <AnalysisService, List<String>>{};
- metrics.forEach((Metric m) => subscriptions[m.service] = [priorityFile]);
-
- sendAnalysisSetSubscriptions(subscriptions);
-
- // Set root after subscribing to avoid empty notifications.
- setAnalysisRoot();
-
- sendAnalysisSetPriorityFiles([priorityFile]);
-
- await analysisFinished;
- print('analysis completed in ${stopwatch.elapsed}');
- metrics.forEach((Metric m) => print('${m.name} timings: ${m.timings}'));
-
- await shutdown();
- }
-}
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_angular.dart b/pkg/analysis_server/benchmark/perf/benchmark_angular.dart
deleted file mode 100644
index c93138d..0000000
--- a/pkg/analysis_server/benchmark/perf/benchmark_angular.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'benchmark_scenario.dart';
-import 'memory_tests.dart';
-
-main(List<String> args) async {
- int length = args.length;
- if (length < 1) {
- print(
- 'Usage: dart benchmark_local.dart path_to_np8080 (an example ngdart project)'
- ' [benchmark_id]');
- return;
- }
- paths = new PathHolder(projectPath: args[0]);
- String id = args.length >= 2 ? args[1] : null;
- if (id == null) {
- for (String id in benchmarks.keys) {
- BenchmarkFunction benchmark = benchmarks[id];
- await benchmark(id);
- }
- } else {
- BenchmarkFunction benchmark = benchmarks[id];
- if (benchmark != null) {
- benchmark(id);
- }
- }
-}
-
-const Map<String, BenchmarkFunction> benchmarks =
- const <String, BenchmarkFunction>{
- 'ng-initialAnalysis': run_ng_initialAnalysis,
- 'ng-change-dart': run_ng_change_dart,
- 'ng-change-html': run_ng_change_html,
- 'ng-memory-initialAnalysis': run_ng_memory_initialAnalysis,
-};
-
-PathHolder paths;
-
-Future run_ng_change_dart(String id) async {
- String description = r'''
-1. Open 'packages/np8080'.
-2. Add an @Output to the class
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
- roots: [paths.packageNp8080],
- file: paths.editorDart,
- fileChange: new FileChange(
- afterStr: 'showPreview = false;',
- insertStr: '@Output() EventEmitter<int> myEventEmitter;'),
- numOfRepeats: 10);
- printBenchmarkResults(id, description, times);
-}
-
-Future run_ng_change_html(String id) async {
- String description = r'''
-1. Open 'packages/np8080'.
-2. Change the contents of a mustache
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
- roots: [paths.packageNp8080],
- file: paths.editorHtml,
- fileChange: new FileChange(
- afterStr: 'note.lastModified', afterStrBack: 4, insertStr: 'NewName'),
- numOfRepeats: 4);
- printBenchmarkResults(id, description, times);
-}
-
-Future run_ng_initialAnalysis(String id) async {
- String description = r'''
-1. Start server, set 'package/np8080' analysis roots.
-2. Measure the time to finish initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
- List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
- roots: [paths.packageNp8080], numOfRepeats: 5);
- printBenchmarkResults(id, description, times);
-}
-
-Future run_ng_memory_initialAnalysis(String id) async {
- String description = r'''
-1. Start server, set 'package/np8080' as the analysis root.
-2. Measure the memory usage after finishing initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
- List<int> sizes = await AnalysisServerMemoryUsageTest
- .start_waitInitialAnalysis_shutdown(
- roots: <String>[paths.packageNp8080], numOfRepeats: 3);
- printMemoryResults(id, description, sizes);
-}
-
-typedef BenchmarkFunction(String id);
-
-class PathHolder {
- String editorHtml;
- String editorDart;
- String packageNp8080;
-
- PathHolder({String projectPath}) {
- editorHtml = '$projectPath/lib/editor/editor_component.html';
- editorDart = '$projectPath/lib/editor/editor_component.dart';
- packageNp8080 = projectPath;
- }
-}
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart b/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart
deleted file mode 100644
index 2e47a2b..0000000
--- a/pkg/analysis_server/benchmark/perf/benchmark_flutter.dart
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-
-import 'benchmark_scenario.dart';
-import 'memory_tests.dart';
-
-main(List<String> args) async {
- int length = args.length;
- if (length < 1) {
- print('Usage: dart benchmark_local.dart path_to_flutter_checkout'
- ' [benchmark_id]');
- return;
- }
- paths = new PathHolder(flutterPath: args[0]);
- String id = args.length >= 2 ? args[1] : null;
- if (id == null) {
- for (String id in benchmarks.keys) {
- BenchmarkFunction benchmark = benchmarks[id];
- await benchmark(id);
- }
- } else {
- BenchmarkFunction benchmark = benchmarks[id];
- if (benchmark != null) {
- benchmark(id);
- }
- }
-}
-
-const Map<String, BenchmarkFunction> benchmarks =
- const <String, BenchmarkFunction>{
- 'flutter-initialAnalysis-1': run_flutter_initialAnalysis_1,
- 'flutter-initialAnalysis-2': run_flutter_initialAnalysis_2,
- 'flutter-change-1': run_flutter_change_1,
- 'flutter-change-2': run_flutter_change_2,
- 'flutter-completion-1': run_flutter_completion_1,
- 'flutter-completion-2': run_flutter_completion_2,
- 'flutter-refactoring-1': run_flutter_refactoring_1,
- 'flutter-memory-initialAnalysis-1': run_flutter_memory_initialAnalysis_1,
- 'flutter-memory-initialAnalysis-2': run_flutter_memory_initialAnalysis_2,
-};
-
-PathHolder paths;
-
-Future run_flutter_change_1(String id) async {
- String description = r'''
-1. Open 'packages/flutter'.
-2. Change a method body in lib/src/painting/colors.dart
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
- roots: [paths.packageFlutter],
- file: '${paths.packageFlutter}/lib/src/painting/colors.dart',
- fileChange: new FileChange(
- afterStr: 'final double h = hue % 360;', insertStr: 'print(12345);'),
- numOfRepeats: 10);
- printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_change_2(String id) async {
- String description = r'''
-1. Open 'packages/flutter'.
-2. Change the name of a public method in lib/src/painting/colors.dart
-3. Measure the time to finish analysis.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario().waitAnalyze_change_analyze(
- roots: [paths.packageFlutter],
- file: '${paths.packageFlutter}/lib/src/painting/colors.dart',
- fileChange: new FileChange(
- afterStr: 'withValue(dou', afterStrBack: 4, insertStr: 'NewName'),
- numOfRepeats: 5);
- printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_completion_1(String id) async {
- String description = r'''
-1. Open 'packages/flutter'.
-2. Change a method body in packages/flutter/lib/src/material/button.dart
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- String completionMarker = 'print(12345);';
- List<int> times = await new BenchmarkScenario()
- .waitAnalyze_change_getCompletion(
- roots: [paths.packageFlutter],
- file: '${paths.packageFlutter}/lib/src/material/button.dart',
- fileChange: new FileChange(
- afterStr: 'Widget build(BuildContext context) {',
- insertStr: completionMarker),
- completeAfterStr: completionMarker,
- numOfRepeats: 10);
- printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_completion_2(String id) async {
- String description = r'''
-1. Open 'packages/flutter'.
-2. Change the name of a public method in lib/src/rendering/layer.dart
-3. Request code completion in this method and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario()
- .waitAnalyze_change_getCompletion(
- roots: [paths.packageFlutter],
- file: '${paths.packageFlutter}/lib/src/rendering/layer.dart',
- fileChange: new FileChange(
- replaceWhat: 'void removeAllChildren() {',
- replaceWith: 'void removeAllChildren2() {print(12345);parent.'),
- completeAfterStr: 'print(12345);parent.',
- numOfRepeats: 5);
- printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_initialAnalysis_1(String id) async {
- String description = r'''
-1. Start server, set 'hello_world' analysis root.
-2. Measure the time to finish initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
- List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
- roots: [paths.exampleHelloWorld], numOfRepeats: 5);
- printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_initialAnalysis_2(String id) async {
- String description = r'''
-1. Start server, set 'hello_world' and 'flutter_gallery' analysis roots.
-2. Measure the time to finish initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
- List<int> times = await BenchmarkScenario.start_waitInitialAnalysis_shutdown(
- roots: [paths.exampleHelloWorld, paths.exampleGallery], numOfRepeats: 5);
- printBenchmarkResults(id, description, times);
-}
-
-Future run_flutter_memory_initialAnalysis_1(String id) async {
- String description = r'''
-1. Start server, set 'packages/flutter' as the analysis root.
-2. Measure the memory usage after finishing initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
- List<int> sizes = await AnalysisServerMemoryUsageTest
- .start_waitInitialAnalysis_shutdown(
- roots: <String>[paths.packageFlutter], numOfRepeats: 3);
- printMemoryResults(id, description, sizes);
-}
-
-Future run_flutter_memory_initialAnalysis_2(String id) async {
- String description = r'''
-1. Start server, set 'packages/flutter' and 'packages/flutter_markdown' analysis roots.
-2. Measure the memory usage after finishing initial analysis.
-3. Shutdown the server.
-4. Go to (1).
-''';
- List<int> sizes = await AnalysisServerMemoryUsageTest
- .start_waitInitialAnalysis_shutdown(
- roots: <String>[paths.packageFlutter, paths.packageMarkdown],
- numOfRepeats: 3);
- printMemoryResults(id, description, sizes);
-}
-
-Future run_flutter_refactoring_1(String id) async {
- String description = r'''
-1. Open 'packages/flutter'.
-2. Change the name of a public method in lib/src/rendering/layer.dart
-3. Request rename refactoring for `getSourcesWithFullName` and measure time to get results.
-4. Rollback changes to the file and wait for analysis.
-5. Go to (2).
-''';
- List<int> times = await new BenchmarkScenario()
- .waitAnalyze_change_getRefactoring(
- roots: [paths.packageFlutter],
- file: '${paths.packageFlutter}/lib/src/rendering/layer.dart',
- fileChange: new FileChange(
- replaceWhat: 'void removeAllChildren() {',
- replaceWith: 'void removeAllChildren2() {'),
- refactoringAtStr: 'addToScene(ui.SceneBuilder builder',
- refactoringKind: RefactoringKind.RENAME,
- refactoringOptions: new RenameOptions('addToScene2'),
- numOfRepeats: 5);
- printBenchmarkResults(id, description, times);
-}
-
-typedef BenchmarkFunction(String id);
-
-class PathHolder {
- String exampleHelloWorld;
- String exampleGallery;
- String exampleStocks;
- String packageFlutter;
- String packageMarkdown;
- String packageSprites;
-
- PathHolder({String flutterPath}) {
- exampleHelloWorld = '$flutterPath/examples/hello_world';
- exampleGallery = '$flutterPath/examples/flutter_gallery';
- exampleStocks = '$flutterPath/examples/stocks';
- packageFlutter = '$flutterPath/packages/flutter';
- packageMarkdown = '$flutterPath/packages/flutter_markdown';
- packageSprites = '$flutterPath/packages/flutter_sprites';
- }
-}
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart b/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart
deleted file mode 100644
index 930bc0e..0000000
--- a/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-import 'dart:math';
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-
-import '../../test/integration/support/integration_tests.dart';
-import 'performance_tests.dart';
-
-void printBenchmarkResults(String id, String description, List<int> times) {
- int minTime = times.fold(1 << 20, min);
- String now = new DateTime.now().toUtc().toIso8601String();
- print('$now ========== $id');
- print('times: $times');
- print('min_time: $minTime');
- print(description.trim());
- print('--------------------');
- print('');
- print('');
-}
-
-class BenchmarkScenario extends AbstractTimingTest {
- /**
- * Init.
- * - Start Analysis Server.
- * - Set the analysis [roots].
- * - Wait for analysis to complete.
- * - Make [file] the priority file.
- *
- * Measurement.
- * - Change the [file] according to the [fileChange].
- * - Record the time to finish analysis.
- *
- * Repeat.
- * - Undo changes to the [file].
- * - Repeat measurement [numOfRepeats] times.
- */
- Future<List<int>> waitAnalyze_change_analyze(
- {List<String> roots,
- String file,
- FileChange fileChange,
- int numOfRepeats}) async {
- outOfTestExpect(roots, isNotNull, reason: 'roots');
- outOfTestExpect(file, isNotNull, reason: 'file');
- outOfTestExpect(fileChange, isNotNull, reason: 'fileChange');
- outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
- // Initialize Analysis Server.
- await super.setUp();
- await subscribeToStatusNotifications();
- // Set roots and analyze.
- await sendAnalysisSetAnalysisRoots(roots, []);
- await analysisFinished;
- // Make the file priority.
- await sendAnalysisSetPriorityFiles([file]);
- // Repeat.
- List<int> times = <int>[];
- for (int i = 0; i < numOfRepeats; i++) {
- // Update and wait for analysis.
- Stopwatch stopwatch = new Stopwatch()..start();
- await _applyFileChange(file, fileChange);
- await analysisFinished;
- times.add(stopwatch.elapsed.inMilliseconds);
- // Remove the overlay and analyze.
- await sendAnalysisUpdateContent({file: new RemoveContentOverlay()});
- await analysisFinished;
- }
- // Done.
- await shutdown();
- return times;
- }
-
- /**
- * Init.
- * 1. Start Analysis Server.
- * 2. Set the analysis [roots].
- * 3. Wait for analysis to complete.
- * 4. Make [file] the priority file.
- *
- * Measurement.
- * 5. Change the [file] according to the [fileChange].
- * 6. Request [completeAfterStr] in the updated file content.
- * 7. Record the time to get completion results.
- * 8. Undo changes to the [file] and analyze.
- * 9. Go to (5).
- */
- Future<List<int>> waitAnalyze_change_getCompletion(
- {List<String> roots,
- String file,
- FileChange fileChange,
- String completeAfterStr,
- int numOfRepeats}) async {
- outOfTestExpect(roots, isNotNull, reason: 'roots');
- outOfTestExpect(file, isNotNull, reason: 'file');
- outOfTestExpect(fileChange, isNotNull, reason: 'fileChange');
- outOfTestExpect(completeAfterStr, isNotNull, reason: 'completeAfterStr');
- outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
- // Initialize Analysis Server.
- await super.setUp();
- await subscribeToStatusNotifications();
- // Set roots and analyze.
- await sendAnalysisSetAnalysisRoots(roots, []);
- await analysisFinished;
- // Make the file priority.
- await sendAnalysisSetPriorityFiles([file]);
- // Repeat.
- List<int> times = <int>[];
- for (int i = 0; i < numOfRepeats; i++) {
- String updatedContent = await _applyFileChange(file, fileChange);
- // Measure completion time.
- int completionOffset =
- _indexOfEnd(file, updatedContent, completeAfterStr);
- Duration completionDuration =
- await _measureCompletionTime(file, completionOffset);
- times.add(completionDuration.inMilliseconds);
- // Remove the overlay and analyze.
- await sendAnalysisUpdateContent({file: new RemoveContentOverlay()});
- await analysisFinished;
- }
- // Done.
- await shutdown();
- return times;
- }
-
- /**
- * Init.
- * 1. Start Analysis Server.
- * 2. Set the analysis [roots].
- * 3. Wait for analysis to complete.
- * 4. Make [file] the priority file.
- *
- * Measurement.
- * 5. Change the [file] according to the [fileChange].
- * 6. Request [refactoringAtStr] in the updated file content.
- * 7. Record the time to get refactoring.
- * 8. Undo changes to the [file] and analyze.
- * 9. Go to (5).
- */
- Future<List<int>> waitAnalyze_change_getRefactoring(
- {List<String> roots,
- String file,
- FileChange fileChange,
- String refactoringAtStr,
- RefactoringKind refactoringKind,
- RefactoringOptions refactoringOptions,
- int numOfRepeats}) async {
- outOfTestExpect(roots, isNotNull, reason: 'roots');
- outOfTestExpect(file, isNotNull, reason: 'file');
- outOfTestExpect(fileChange, isNotNull, reason: 'fileChange');
- outOfTestExpect(refactoringAtStr, isNotNull, reason: 'refactoringAtStr');
- outOfTestExpect(refactoringKind, isNotNull, reason: 'refactoringKind');
- outOfTestExpect(refactoringOptions, isNotNull,
- reason: 'refactoringOptions');
- outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
- // Initialize Analysis Server.
- await super.setUp();
- await subscribeToStatusNotifications();
- // Set roots and analyze.
- await sendAnalysisSetAnalysisRoots(roots, []);
- await analysisFinished;
- // Make the file priority.
- await sendAnalysisSetPriorityFiles([file]);
- // Repeat.
- List<int> times = <int>[];
- for (int i = 0; i < numOfRepeats; i++) {
- String updatedContent = await _applyFileChange(file, fileChange);
- // Measure time to get refactoring.
- int refactoringOffset = _indexOf(file, updatedContent, refactoringAtStr);
- Duration refactoringDuration = await _measureRefactoringTime(
- file, refactoringOffset, refactoringKind, refactoringOptions);
- times.add(refactoringDuration.inMilliseconds);
- // Remove the overlay and analyze.
- await sendAnalysisUpdateContent({file: new RemoveContentOverlay()});
- await analysisFinished;
- }
- // Done.
- await shutdown();
- return times;
- }
-
- /**
- * Compute updated content of the [file] as described by [desc], add overlay
- * for the [file], and return the updated content.
- */
- Future<String> _applyFileChange(String file, FileChange desc) async {
- String originalContent = _getFileContent(file);
- String updatedContent;
- if (desc.afterStr != null) {
- int offset = _indexOfEnd(file, originalContent, desc.afterStr);
- offset -= desc.afterStrBack;
- updatedContent = originalContent.substring(0, offset) +
- desc.insertStr +
- originalContent.substring(offset);
- } else if (desc.replaceWhat != null) {
- int offset = _indexOf(file, originalContent, desc.replaceWhat);
- updatedContent = originalContent.substring(0, offset) +
- desc.replaceWith +
- originalContent.substring(offset + desc.replaceWhat.length);
- }
- await sendAnalysisUpdateContent(
- {file: new AddContentOverlay(updatedContent)});
- return updatedContent;
- }
-
- Future<Duration> _measureCompletionTime(String file, int offset) async {
- Stopwatch stopwatch = new Stopwatch();
- stopwatch.start();
- Completer<Duration> completer = new Completer<Duration>();
- var completionSubscription = onCompletionResults.listen((_) {
- completer.complete(stopwatch.elapsed);
- });
- try {
- await sendCompletionGetSuggestions(file, offset);
- return await completer.future;
- } finally {
- completionSubscription.cancel();
- }
- }
-
- Future<Duration> _measureRefactoringTime(
- String file,
- int offset,
- RefactoringKind refactoringKind,
- RefactoringOptions refactoringOptions) async {
- Stopwatch stopwatch = new Stopwatch();
- stopwatch.start();
- await sendEditGetRefactoring(refactoringKind, file, offset, 0, false,
- options: refactoringOptions);
- return stopwatch.elapsed;
- }
-
- /**
- * 1. Start Analysis Server.
- * 2. Set the analysis [roots].
- * 3. Wait for analysis to complete.
- * 4. Record the time to finish analysis.
- * 5. Shutdown.
- * 6. Go to (1).
- */
- static Future<List<int>> start_waitInitialAnalysis_shutdown(
- {List<String> roots, int numOfRepeats}) async {
- outOfTestExpect(roots, isNotNull, reason: 'roots');
- outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
- // Repeat.
- List<int> times = <int>[];
- for (int i = 0; i < numOfRepeats; i++) {
- BenchmarkScenario instance = new BenchmarkScenario();
- // Initialize Analysis Server.
- await instance.setUp();
- await instance.subscribeToStatusNotifications();
- // Set roots and analyze.
- Stopwatch stopwatch = new Stopwatch()..start();
- await instance.sendAnalysisSetAnalysisRoots(roots, []);
- await instance.analysisFinished;
- times.add(stopwatch.elapsed.inMilliseconds);
- // Stop the server.
- await instance.shutdown();
- }
- return times;
- }
-
- static String _getFileContent(String path) {
- File file = new File(path);
- outOfTestExpect(file.existsSync(), isTrue,
- reason: 'File $path does not exist.');
- return file.readAsStringSync();
- }
-
- /**
- * Return the index of [what] in [where] in the [file], fail if not found.
- */
- static int _indexOf(String file, String where, String what) {
- int index = where.indexOf(what);
- outOfTestExpect(index, isNot(-1), reason: 'Cannot find |$what| in $file.');
- return index;
- }
-
- /**
- * Return the end index if [what] in [where] in the [file], fail if not found.
- */
- static int _indexOfEnd(String file, String where, String what) {
- return _indexOf(file, where, what) + what.length;
- }
-}
-
-class FileChange {
- final String afterStr;
- final int afterStrBack;
- final String insertStr;
- final String replaceWhat;
- final String replaceWith;
-
- FileChange(
- {this.afterStr,
- this.afterStrBack: 0,
- this.insertStr,
- this.replaceWhat,
- this.replaceWith}) {
- if (afterStr != null) {
- outOfTestExpect(insertStr, isNotNull, reason: 'insertStr');
- } else if (replaceWhat != null) {
- outOfTestExpect(replaceWith, isNotNull, reason: 'replaceWith');
- }
- }
-}
diff --git a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart b/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
deleted file mode 100644
index 0a12041..0000000
--- a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:test/test.dart';
-
-import 'performance_tests.dart';
-
-const COMPLETION_OFFSET = 'offset';
-const PRIORITY_FILE_OPTION = 'priority';
-const SOURCE_OPTION = 'source';
-
-/**
- * Pass in the directory of the source to be analyzed as option `--source`,
- * specify a priority file with `--priority` and an offset for completions
- * with a `--offset`.
- */
-main(List<String> arguments) async {
- ArgParser parser = _createArgParser();
- var args = parser.parse(arguments);
- if (args[SOURCE_OPTION] == null) {
- print('path to source directory must be specified');
- exit(1);
- }
-
- int offset = int.parse(args[COMPLETION_OFFSET]);
- String priorityFile = args[PRIORITY_FILE_OPTION];
- String source = args[SOURCE_OPTION];
-
- CompletionTimingTest test =
- new CompletionTimingTest(offset, priorityFile, source);
- await test.test_timing();
-}
-
-ArgParser _createArgParser() => new ArgParser()
- ..addOption(SOURCE_OPTION, help: 'full path to source directory for analysis')
- ..addOption(PRIORITY_FILE_OPTION, help: 'full path to a priority file')
- ..addOption(COMPLETION_OFFSET, help: 'offset in file for code completions');
-
-/**
- * CompletionTimingTest measures the time taken for the analysis server to respond with
- * completion suggestions for a given file and offset. The time measured starts when
- * the analysis root is set and is done when the completion suggestions are received
- * from the server. The test does not wait for analysis to be complete before asking for
- * completions.
- */
-class CompletionTimingTest extends AbstractTimingTest {
- final int offset;
- final String priorityFile;
- final String source;
-
- List<Duration> timings = <Duration>[];
-
- CompletionTimingTest(this.offset, this.priorityFile, this.source);
-
- Future test_timing() async {
-// debugStdio();
-
- expect(priorityFile, isNotNull,
- reason: 'A priority file must be specified for completion testing.');
- expect(offset, isNotNull,
- reason: 'An offset must be specified for completion testing.');
-
- await init(source);
- stopwatch.start();
-
- onCompletionResults.listen((_) {
- timings.add(new Duration(milliseconds: stopwatch.elapsed.inMilliseconds));
- });
-
- setAnalysisRoot();
- sendAnalysisSetPriorityFiles([priorityFile]);
- sendCompletionGetSuggestions(priorityFile, offset);
-
- await analysisFinished;
-
- print('analysis completed in ${stopwatch.elapsed}');
- print('completion received at : $timings');
- await shutdown();
- }
-}
diff --git a/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart b/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
new file mode 100644
index 0000000..620c032
--- /dev/null
+++ b/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+
+import '../benchmarks.dart';
+
+/// benchmarks:
+/// - analysis-flutter-analyze
+class FlutterAnalyzeBenchmark extends Benchmark {
+ FlutterAnalyzeBenchmark()
+ : super(
+ 'analysis-flutter-analyze',
+ "Clone the flutter/flutter repo and run "
+ "'flutter analyze --flutter-repo' with the current Dart VM and "
+ "analysis server.",
+ kind: 'cpu',
+ );
+
+ bool get needsSetup => true;
+
+ Directory flutterDir;
+
+ Future oneTimeSetup() async {
+ flutterDir = Directory.systemTemp.createTempSync('flutter');
+
+ // git clone https://github.com/flutter/flutter $flutterDir
+ await _runProcess('git', [
+ 'clone',
+ 'https://github.com/flutter/flutter',
+ path.canonicalize(flutterDir.path)
+ ]);
+
+ String flutterTool = path.join(flutterDir.path, 'bin', 'flutter');
+
+ // flutter --version
+ await _runProcess(flutterTool, ['--version'], cwd: flutterDir.path);
+
+ // flutter precache
+ await _runProcess(flutterTool, ['precache'], cwd: flutterDir.path);
+
+ // flutter update-packages
+ await _runProcess(flutterTool, ['update-packages'], cwd: flutterDir.path);
+ }
+
+ Future oneTimeCleanup() {
+ try {
+ flutterDir.deleteSync(recursive: true);
+ } on FileSystemException catch (e) {
+ print(e);
+ }
+
+ return new Future.value();
+ }
+
+ int get maxIterations => 3;
+
+ @override
+ Future<BenchMarkResult> run({
+ bool quick: false,
+ bool useCFE: false,
+ bool verbose: false,
+ }) async {
+ if (!quick) {
+ deleteServerCache();
+ }
+
+ final Stopwatch stopwatch = new Stopwatch()..start();
+
+ await _runProcess(
+ Platform.resolvedExecutable,
+ [
+ 'packages/flutter_tools/bin/flutter_tools.dart',
+ 'analyze',
+ '--flutter-repo',
+ ],
+ cwd: flutterDir.path,
+ failOnError: false,
+ );
+
+ stopwatch.stop();
+
+ return new BenchMarkResult('micros', stopwatch.elapsedMicroseconds);
+ }
+}
+
+Future<int> _runProcess(
+ String command,
+ List<String> args, {
+ String cwd,
+ bool failOnError = true,
+}) async {
+ print('\n$command ${args.join(' ')}');
+
+ Process process = await Process.start(command, args, workingDirectory: cwd);
+
+ process.stdout
+ .transform(utf8.decoder)
+ .transform(new LineSplitter())
+ .listen((line) {
+ print(' $line');
+ });
+ process.stderr
+ .transform(utf8.decoder)
+ .transform(new LineSplitter())
+ .listen((line) => print(' $line'));
+
+ int exitCode = await process.exitCode;
+ if (exitCode != 0 && failOnError) {
+ throw '$command exited with $exitCode';
+ }
+
+ return exitCode;
+}
diff --git a/pkg/analysis_server/benchmark/perf/performance_tests.dart b/pkg/analysis_server/benchmark/perf/performance_tests.dart
deleted file mode 100644
index 540678c..0000000
--- a/pkg/analysis_server/benchmark/perf/performance_tests.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:test/test.dart';
-
-import '../../test/integration/support/integration_tests.dart';
-
-/**
- * Base class for analysis server performance tests.
- */
-abstract class AbstractAnalysisServerPerformanceTest
- extends AbstractAnalysisServerIntegrationTest {
- /**
- * Stopwatch for timing results;
- */
- Stopwatch stopwatch = new Stopwatch();
-
- /**
- * Send the server an 'analysis.setAnalysisRoots' command directing it to
- * analyze [sourceDirectory].
- */
- Future setAnalysisRoot() =>
- sendAnalysisSetAnalysisRoots([sourceDirectory.path], []);
-
- /**
- * The server is automatically started before every test.
- */
- @override
- Future setUp() {
- onAnalysisErrors.listen((AnalysisErrorsParams params) {
- currentAnalysisErrors[params.file] = params.errors;
- });
- onServerError.listen((ServerErrorParams params) {
- // A server error should never happen during an integration test.
- fail('${params.message}\n${params.stackTrace}');
- });
- Completer serverConnected = new Completer();
- onServerConnected.listen((_) {
- outOfTestExpect(serverConnected.isCompleted, isFalse);
- serverConnected.complete();
- });
- return startServer(checked: false).then((_) {
- server.listenToOutput(dispatchNotification);
- server.exitCode.then((_) {
- skipShutdown = true;
- });
- return serverConnected.future;
- });
- }
-
- /**
- * After every test, the server is stopped.
- */
- Future shutdown() async => await shutdownIfNeeded();
-
- /**
- * Enable [ServerService.STATUS] notifications so that [analysisFinished]
- * can be used.
- */
- Future subscribeToStatusNotifications() async {
- await sendServerSetSubscriptions([ServerService.STATUS]);
- }
-}
-
-class AbstractTimingTest extends AbstractAnalysisServerPerformanceTest {
- Future init(String source) async {
- await super.setUp();
- sourceDirectory = new Directory(source);
- return subscribeToStatusNotifications();
- }
-}
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index e050dc0..23bda67 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
- 1.20.0
+ 1.20.1
</h1>
<p>
This document contains a specification of the API provided by the
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 703297c..9b4578e 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -43,7 +43,6 @@
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analysis_server/src/utilities/null_string_sink.dart';
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/exception/exception.dart';
@@ -51,8 +50,8 @@
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
@@ -64,6 +63,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
import 'package:analyzer/src/util/glob.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
@@ -108,7 +108,7 @@
* The version of the analysis server. The value should be replaced
* automatically during the build.
*/
- static final String VERSION = '1.20.0';
+ static final String VERSION = '1.20.1';
/**
* The options of this server instance.
diff --git a/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart b/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
index 15fe295..d1fe2d4 100644
--- a/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
@@ -5,6 +5,7 @@
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/source.dart';
/**
@@ -53,6 +54,8 @@
_DartUnitClosingLabelsComputerVisitor(this.computer);
+ ClosingLabel get _currentLabel => labelStack.isEmpty ? null : labelStack.last;
+
@override
Object visitInstanceCreationExpression(InstanceCreationExpression node) {
ClosingLabel label;
@@ -117,9 +120,9 @@
checkLinesUsing = checkLinesUsing ?? node;
- final LineInfo_Location start =
+ final CharacterLocation start =
computer._lineInfo.getLocation(checkLinesUsing.offset);
- final LineInfo_Location end =
+ final CharacterLocation end =
computer._lineInfo.getLocation(checkLinesUsing.end - 1);
final ClosingLabel closingLabel =
@@ -141,13 +144,11 @@
return closingLabel;
}
- void _pushLabel(ClosingLabel label) {
- labelStack.add(label);
- }
-
- ClosingLabel get _currentLabel => labelStack.isEmpty ? null : labelStack.last;
-
void _popLabel() {
labelStack.removeLast();
}
+
+ void _pushLabel(ClosingLabel label) {
+ labelStack.add(label);
+ }
}
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 0508fa7..3516bbe 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart' as engine;
import 'package:analyzer/dart/element/type.dart' as engine;
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -106,7 +107,7 @@
}
Location _getLocationOffsetLength(int offset, int length) {
- LineInfo_Location lineLocation = lineInfo.getLocation(offset);
+ CharacterLocation lineLocation = lineInfo.getLocation(offset);
int startLine = lineLocation.lineNumber;
int startColumn = lineLocation.columnNumber;
return new Location(file, offset, length, startLine, startColumn);
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 84d9d18..a1ad9b6 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -8,18 +8,14 @@
import 'dart:core';
import 'package:analysis_server/src/plugin/notification_manager.dart';
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
-import 'package:analyzer/source/package_map_provider.dart';
import 'package:analyzer/source/package_map_resolver.dart';
-import 'package:analyzer/source/path_filter.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
-import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
@@ -30,6 +26,10 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/pubspec/pubspec_validator.dart';
+import 'package:analyzer/src/source/package_map_provider.dart';
+import 'package:analyzer/src/source/path_filter.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
+import 'package:analyzer/src/source/sdk_ext.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/util/absolute_path.dart';
import 'package:analyzer/src/util/glob.dart';
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 64878c1..22b7f36 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -561,6 +561,18 @@
int length = params.length;
// add refactoring kinds
List<RefactoringKind> kinds = <RefactoringKind>[];
+ // Try EXTRACT_WIDGETS.
+ {
+ var unit = await server.getResolvedCompilationUnit(file);
+ var analysisSession = server.getAnalysisDriver(file)?.currentSession;
+ if (unit != null && analysisSession != null) {
+ var refactoring = new ExtractWidgetRefactoring(
+ searchEngine, analysisSession, unit, offset);
+ if (refactoring.isAvailable()) {
+ kinds.add(RefactoringKind.EXTRACT_WIDGET);
+ }
+ }
+ }
// try EXTRACT_*
if (length != 0) {
kinds.add(RefactoringKind.EXTRACT_LOCAL_VARIABLE);
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
index 36980eb..4686b23 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
@@ -8,10 +8,10 @@
import 'dart:io' show Platform, Process, ProcessResult;
import 'package:analysis_server/src/plugin/notification_manager.dart';
-import 'package:analyzer/context/context_root.dart' as analyzer;
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/context/context_root.dart' as analyzer;
import 'package:analyzer/src/generated/bazel.dart';
import 'package:analyzer/src/generated/gn.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -303,6 +303,11 @@
<PluginInfo, Map<String, List<int>>>{};
/**
+ * The console environment key used by the pub tool.
+ */
+ static const String _pubEnvironmentKey = 'PUB_ENVIRONMENT';
+
+ /**
* The resource provider used to access the file system.
*/
final ResourceProvider resourceProvider;
@@ -834,11 +839,6 @@
}
/**
- * The console environment key used by the pub tool.
- */
- static const String _pubEnvironmentKey = 'PUB_ENVIRONMENT';
-
- /**
* Returns the environment value that should be used when running pub.
*
* Includes any existing environment value, if one exists.
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
index 8de5ea2..5d050de 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
@@ -4,8 +4,8 @@
import 'package:analysis_server/src/plugin/plugin_locator.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/util/absolute_path.dart';
import 'package:front_end/src/base/source.dart';
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index a84b950..ca18225 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -14,6 +14,7 @@
import 'package:analyzer/error/error.dart' as engine;
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/ast/utilities.dart' as engine;
import 'package:analyzer/src/error/codes.dart' as engine;
import 'package:analyzer/src/generated/engine.dart' as engine;
@@ -107,7 +108,7 @@
int startLine = -1;
int startColumn = -1;
if (lineInfo != null) {
- engine.LineInfo_Location lineLocation = lineInfo.getLocation(offset);
+ CharacterLocation lineLocation = lineInfo.getLocation(offset);
if (lineLocation != null) {
startLine = lineLocation.lineNumber;
startColumn = lineLocation.columnNumber;
@@ -272,8 +273,7 @@
try {
engine.LineInfo lineInfo = unitElement.lineInfo;
if (lineInfo != null) {
- engine.LineInfo_Location offsetLocation =
- lineInfo.getLocation(range.offset);
+ CharacterLocation offsetLocation = lineInfo.getLocation(range.offset);
startLine = offsetLocation.lineNumber;
startColumn = offsetLocation.columnNumber;
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index f0d5a9e..351c240 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -36,7 +36,7 @@
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index f7d3540..3cdcf21 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -16,7 +16,6 @@
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/utilities/flutter.dart' as flutter;
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
@@ -26,6 +25,7 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
index 6a0010c..76d0115 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
@@ -145,6 +145,11 @@
}
@override
+ bool isAvailable() {
+ return !_checkSelection().hasFatalError;
+ }
+
+ @override
bool requiresPreview() => false;
/// Checks if [offset] is a widget creation expression that can be extracted.
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index 3fe03a8..96243dd 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -250,6 +250,12 @@
* level of checking.
*/
RefactoringStatus checkName();
+
+ /**
+ * Return `true` if refactoring is available, possibly without checking all
+ * initial conditions.
+ */
+ bool isAvailable();
}
/**
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index 4676e02..d138f3e 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -10,8 +10,8 @@
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
/**
* Instances of the class [SocketServer] implement the common parts of
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 51249a4..b3050c4 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -20,11 +20,10 @@
import 'package:analysis_server/src/status/element_writer.dart';
import 'package:analysis_server/src/status/pages.dart';
import 'package:analysis_server/src/utilities/profiling.dart';
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/source/package_map_resolver.dart';
-import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/context/source.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
@@ -36,6 +35,7 @@
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/source/sdk_ext.dart';
import 'package:path/path.dart' as pathPackage;
final String kCustomCss = '''
@@ -1200,6 +1200,52 @@
}
}
+class ServiceProtocol {
+ final WebSocket socket;
+
+ int _id = 0;
+ Map<String, Completer> _completers = {};
+
+ ServiceProtocol._(this.socket) {
+ socket.listen(_handleMessage);
+ }
+
+ Future<Map> call(String method, [Map args]) {
+ String id = '${++_id}';
+ Completer completer = new Completer();
+ _completers[id] = completer;
+ Map m = {'id': id, 'method': method};
+ if (args != null) m['params'] = args;
+ String message = jsonEncode(m);
+ socket.add(message);
+ return completer.future;
+ }
+
+ Future dispose() => socket.close();
+
+ void _handleMessage(dynamic message) {
+ if (message is! String) {
+ return;
+ }
+
+ try {
+ dynamic json = jsonDecode(message);
+ if (json.containsKey('id')) {
+ dynamic id = json['id'];
+ _completers[id]?.complete(json['result']);
+ _completers.remove(id);
+ }
+ } catch (e) {
+ // ignore
+ }
+ }
+
+ static Future<ServiceProtocol> connect(Uri uri) async {
+ WebSocket socket = await WebSocket.connect(uri.toString());
+ return new ServiceProtocol._(socket);
+ }
+}
+
class StatusPage extends DiagnosticPageWithNav {
StatusPage(DiagnosticsSite site)
: super(site, 'status', 'Status',
@@ -1280,49 +1326,3 @@
});
}
}
-
-class ServiceProtocol {
- final WebSocket socket;
-
- int _id = 0;
- Map<String, Completer> _completers = {};
-
- static Future<ServiceProtocol> connect(Uri uri) async {
- WebSocket socket = await WebSocket.connect(uri.toString());
- return new ServiceProtocol._(socket);
- }
-
- ServiceProtocol._(this.socket) {
- socket.listen(_handleMessage);
- }
-
- Future<Map> call(String method, [Map args]) {
- String id = '${++_id}';
- Completer completer = new Completer();
- _completers[id] = completer;
- Map m = {'id': id, 'method': method};
- if (args != null) m['params'] = args;
- String message = jsonEncode(m);
- socket.add(message);
- return completer.future;
- }
-
- void _handleMessage(dynamic message) {
- if (message is! String) {
- return;
- }
-
- try {
- dynamic json = jsonDecode(message);
- if (json.containsKey('id')) {
- dynamic id = json['id'];
- _completers[id]?.complete(json['result']);
- _completers.remove(id);
- }
- } catch (e) {
- // ignore
- }
- }
-
- Future dispose() => socket.close();
-}
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 0e1ae08..43c8630 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -10,7 +10,6 @@
args: '>=0.13.0 <2.0.0'
dart_style: '^1.0.6'
intl: ^0.15.0
- isolate: '>=0.2.2 <2.0.0'
linter: ^0.1.16
logging: any
package_config: '>=0.1.5 <2.0.0'
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 19f1ac7..8e99e48 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -4,13 +4,13 @@
import 'dart:async';
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 95bce6d..6b36df9 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -12,9 +12,9 @@
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analyzer/context/context_root.dart' as analyzer;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/context/context_root.dart' as analyzer;
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
diff --git a/pkg/analysis_server/test/benchmarks_test.dart b/pkg/analysis_server/test/benchmarks_test.dart
index 6fa9319..5dd51fb 100644
--- a/pkg/analysis_server/test/benchmarks_test.dart
+++ b/pkg/analysis_server/test/benchmarks_test.dart
@@ -27,6 +27,10 @@
});
for (String benchmarkId in benchmarks) {
+ if (benchmarkId == 'analysis-flutter-analyze') {
+ continue;
+ }
+
test(benchmarkId, () {
ProcessResult r = Process.runSync(
Platform.resolvedExecutable,
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index db983e5..431bf6a 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -7,12 +7,12 @@
import 'package:analysis_server/src/context_manager.dart';
import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/utilities/null_string_sink.dart';
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/error/codes.dart';
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index 29f95af..ed61e22 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -13,6 +13,7 @@
import '../analysis_abstract.dart';
import '../mocks.dart';
+import '../src/utilities/flutter_util.dart' as flutter;
main() {
defineReflectiveSuite(() {
@@ -789,6 +790,15 @@
class GetAvailableRefactoringsTest extends AbstractAnalysisTest {
List<RefactoringKind> kinds;
+ void addFlutterPackage() {
+ var libFolder = flutter.configureFlutterPackage(resourceProvider);
+ packageMapProvider.packageMap['flutter'] = [libFolder];
+ // Create .packages in the project.
+ newFile(join(projectPath, '.packages'), content: '''
+flutter:${libFolder.toUri()}
+''');
+ }
+
/**
* Tests that there is refactoring of the given [kind] is available at the
* [search] offset.
@@ -866,6 +876,23 @@
expect(kinds, contains(RefactoringKind.EXTRACT_METHOD));
}
+ Future test_extractWidget() async {
+ addFlutterPackage();
+ addTestFile('''
+import 'package:flutter/material.dart';
+
+class MyWidget extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return new Text('AAA');
+ }
+}
+''');
+ await waitForTasksFinished();
+ await getRefactoringsForString('new Text');
+ expect(kinds, contains(RefactoringKind.EXTRACT_WIDGET));
+ }
+
Future test_rename_hasElement_class() {
return assertHasRenameRefactoring('''
class Test {}
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 53ebe1f..6a26f97 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -11,9 +11,9 @@
import 'package:analysis_server/src/channel/channel.dart';
import 'package:analyzer/file_system/file_system.dart' as resource;
import 'package:analyzer/file_system/memory_file_system.dart' as resource;
-import 'package:analyzer/source/package_map_provider.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_provider.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
import 'package:front_end/src/base/timestamped_data.dart';
import 'package:test/test.dart';
diff --git a/pkg/analysis_server/test/services/linter/linter_test.dart b/pkg/analysis_server/test/services/linter/linter_test.dart
index c88c48a..19272d8 100644
--- a/pkg/analysis_server/test/services/linter/linter_test.dart
+++ b/pkg/analysis_server/test/services/linter/linter_test.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/lint/options_rule_validator.dart';
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index 8c0088f..b03c081 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -7,10 +7,10 @@
import 'package:analysis_server/src/plugin/notification_manager.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/channel/channel.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
index 2707c57..8b7669b 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -8,10 +8,10 @@
import 'package:analysis_server/src/plugin/plugin_locator.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/plugin/plugin_watcher.dart';
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
@@ -135,7 +135,7 @@
fsState = new FileSystemState(
new PerformanceLog(null),
new MemoryByteStore(),
- null,
+ new FileContentOverlay(),
resourceProvider,
sourceFactory,
new AnalysisOptionsImpl(),
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 50954cd..62c933f 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
- <version>1.20.0</version>
+ <version>1.20.1</version>
</h1>
<p>
This document contains a specification of the API provided by the
diff --git a/pkg/analyzer/lib/dart/ast/resolution_base_classes.dart b/pkg/analyzer/lib/dart/ast/resolution_base_classes.dart
deleted file mode 100644
index 54ca0d8..0000000
--- a/pkg/analyzer/lib/dart/ast/resolution_base_classes.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Abstract base class for a resolved element maintained in an AST data
- * structure.
- *
- * This abstract type decouples the AST representation from depending on the
- * element model.
- */
-abstract class ResolutionTarget {}
-
-/**
- * Abstract base class for a resolved type maintained in AST data structure.
- *
- * This abstract type decouples the AST representation from depending on the
- * type model.
- */
-abstract class ResolutionType {}
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 12a88e8..5b2237b 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -34,10 +34,7 @@
* statements declares a local variable then the local variable will be
* represented by an element.
*/
-library analyzer.dart.element.element;
-
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/resolution_base_classes.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
@@ -45,8 +42,8 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/api/model.dart' show AnalysisTarget;
import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/model.dart' show AnalysisTarget;
/**
* An element that represents a class.
@@ -564,7 +561,7 @@
*
* Clients may not extend, implement or mix-in this class.
*/
-abstract class Element implements AnalysisTarget, ResolutionTarget {
+abstract class Element implements AnalysisTarget {
/**
* A comparator that can be used to sort elements by their name offset.
* Elements with a smaller offset will be sorted to be before elements with a
@@ -848,8 +845,7 @@
*
* Clients may not extend, implement or mix-in this class.
*/
-abstract class ElementAnnotation
- implements ConstantEvaluationTarget, ResolutionTarget {
+abstract class ElementAnnotation implements ConstantEvaluationTarget {
/**
* An empty list of annotations.
*/
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 69d76ad..64c8606 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -20,9 +20,6 @@
* parameters. But if we declare a variable as `Pair<String, int> pair;` the
* references to `String` and `int` are type arguments.
*/
-library analyzer.dart.element.type;
-
-import 'package:analyzer/dart/ast/resolution_base_classes.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart' show InterfaceTypeImpl;
import 'package:analyzer/src/generated/type_system.dart' show TypeSystem;
@@ -32,7 +29,7 @@
*
* Clients may not extend, implement or mix-in this class.
*/
-abstract class DartType implements ResolutionType {
+abstract class DartType {
/**
* An empty list of types.
*/
@@ -127,6 +124,16 @@
*/
bool isAssignableTo(DartType type);
+ /// Indicates whether `this` represents a type that is equivalent to `dest`.
+ ///
+ /// This is different from `operator==`. Consider for example:
+ ///
+ /// typedef void F<T>(); // T not used!
+ ///
+ /// `operator==` would consider F<int> and F<bool> to be different types;
+ /// `isEquivalentTo` considers them to be equivalent.
+ bool isEquivalentTo(DartType dest);
+
/**
* Return `true` if this type is more specific than the given [type].
*/
@@ -172,16 +179,6 @@
*/
DartType substitute2(
List<DartType> argumentTypes, List<DartType> parameterTypes);
-
- /// Indicates whether `this` represents a type that is equivalent to `dest`.
- ///
- /// This is different from `operator==`. Consider for example:
- ///
- /// typedef void F<T>(); // T not used!
- ///
- /// `operator==` would consider F<int> and F<bool> to be different types;
- /// `isEquivalentTo` considers them to be equivalent.
- bool isEquivalentTo(DartType dest);
}
/**
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 1d0416c..beb7369 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -678,7 +678,6 @@
StrongModeCode.TOP_LEVEL_INSTANCE_GETTER,
StrongModeCode.TOP_LEVEL_INSTANCE_METHOD,
StrongModeCode.TOP_LEVEL_UNSUPPORTED,
- StrongModeCode.USES_DYNAMIC_AS_BOTTOM,
TodoCode.TODO,
];
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 07493b9..4c05644 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -197,28 +197,6 @@
}
}
- _MemoryFile renameFileSync(_MemoryFile file, String newPath) {
- String path = file.path;
- if (newPath == path) {
- return file;
- }
- _MemoryResource existingNewResource = _pathToResource[newPath];
- if (existingNewResource is _MemoryFolder) {
- throw new FileSystemException(
- path, 'Could not be renamed: $newPath is a folder.');
- }
- _MemoryFile newFile = _newFile(newPath);
- _pathToResource.remove(path);
- _pathToBytes[newPath] = _pathToBytes.remove(path);
- _pathToTimestamp[newPath] = _pathToTimestamp.remove(path);
- if (existingNewResource != null) {
- _notifyWatchers(newPath, ChangeType.REMOVE);
- }
- _notifyWatchers(path, ChangeType.REMOVE);
- _notifyWatchers(newPath, ChangeType.ADD);
- return newFile;
- }
-
File updateFile(String path, String content, [int stamp]) {
path = pathContext.normalize(path);
newFolder(pathContext.dirname(path));
@@ -286,6 +264,28 @@
});
}
+ _MemoryFile _renameFileSync(_MemoryFile file, String newPath) {
+ String path = file.path;
+ if (newPath == path) {
+ return file;
+ }
+ _MemoryResource existingNewResource = _pathToResource[newPath];
+ if (existingNewResource is _MemoryFolder) {
+ throw new FileSystemException(
+ path, 'Could not be renamed: $newPath is a folder.');
+ }
+ _MemoryFile newFile = _newFile(newPath);
+ _pathToResource.remove(path);
+ _pathToBytes[newPath] = _pathToBytes.remove(path);
+ _pathToTimestamp[newPath] = _pathToTimestamp.remove(path);
+ if (existingNewResource != null) {
+ _notifyWatchers(newPath, ChangeType.REMOVE);
+ }
+ _notifyWatchers(path, ChangeType.REMOVE);
+ _notifyWatchers(newPath, ChangeType.ADD);
+ return newFile;
+ }
+
void _setFileContent(_MemoryFile file, List<int> bytes) {
String path = file.path;
_pathToResource[path] = file;
@@ -444,7 +444,7 @@
@override
File renameSync(String newPath) {
- return _provider.renameFileSync(this, newPath);
+ return _provider._renameFileSync(this, newPath);
}
@override
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 1812123..a5d2a99 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -12,7 +12,6 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/source/source_resource.dart';
import 'package:analyzer/src/util/absolute_path.dart';
-import 'package:isolate/isolate_runner.dart';
import 'package:path/path.dart';
import 'package:watcher/watcher.dart';
@@ -40,9 +39,9 @@
}
/**
-* The name of the directory containing plugin specific subfolders used to
-* store data across sessions.
-*/
+ * The name of the directory containing plugin specific subfolders used to
+ * store data across sessions.
+ */
const String _SERVER_DIR = ".dartServer";
/**
@@ -72,8 +71,6 @@
*/
final String _stateLocation;
- static Future<IsolateRunner> pathsToTimesIsolate = IsolateRunner.spawn();
-
@override
final AbsolutePathContext absolutePathContext =
new AbsolutePathContext(io.Platform.isWindows);
@@ -103,8 +100,7 @@
@override
Future<List<int>> getModificationTimes(List<Source> sources) async {
List<String> paths = sources.map((source) => source.fullName).toList();
- IsolateRunner runner = await pathsToTimesIsolate;
- return runner.run(_pathsToTimes, paths);
+ return _pathsToTimes(paths);
}
@override
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index 27d0c1a..38bf416 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -2,12 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.instrumentation.instrumentation;
-
import 'dart:async';
import 'dart:convert';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
/**
* A container with analysis performance constants.
diff --git a/pkg/analyzer/lib/source/analysis_options_provider.dart b/pkg/analyzer/lib/source/analysis_options_provider.dart
index 550f3e3..939f634 100644
--- a/pkg/analyzer/lib/source/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/source/analysis_options_provider.dart
@@ -2,142 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:core';
+@deprecated
+library analyzer.src.analysis_options.analysis_options_provider;
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/source/source_resource.dart';
-import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/util/yaml.dart';
-import 'package:source_span/source_span.dart';
-import 'package:yaml/yaml.dart';
-
-/// Provide the options found in the analysis options file.
-class AnalysisOptionsProvider {
- /// The source factory used to resolve include declarations
- /// in analysis options files or `null` if include is not supported.
- SourceFactory sourceFactory;
-
- AnalysisOptionsProvider([this.sourceFactory]);
-
- /// Provide the options found in either
- /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_FILE] or
- /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE].
- /// Recursively merge options referenced by an include directive
- /// and remove the include directive from the resulting options map.
- /// Return an empty options map if the file does not exist.
- YamlMap getOptions(Folder root, {bool crawlUp: false}) {
- File optionsFile = getOptionsFile(root, crawlUp: crawlUp);
- if (optionsFile == null) {
- return new YamlMap();
- }
- return getOptionsFromFile(optionsFile);
- }
-
- /// Return the analysis options file from which options should be read, or
- /// `null` if there is no analysis options file for code in the given [root].
- ///
- /// The given [root] directory will be searched first. If no file is found and
- /// if [crawlUp] is `true`, then enclosing directories will be searched.
- File getOptionsFile(Folder root, {bool crawlUp: false}) {
- Resource resource = null;
- for (Folder folder = root; folder != null; folder = folder.parent) {
- resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
- if (resource.exists) {
- break;
- }
- resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- if (resource.exists || !crawlUp) {
- break;
- }
- }
- if (resource is File && resource.exists) {
- return resource;
- }
- return null;
- }
-
- /// Provide the options found in [file].
- /// Recursively merge options referenced by an include directive
- /// and remove the include directive from the resulting options map.
- /// Return an empty options map if the file does not exist.
- YamlMap getOptionsFromFile(File file) {
- return getOptionsFromSource(new FileSource(file));
- }
-
- /// Provide the options found in [source].
- /// Recursively merge options referenced by an include directive
- /// and remove the include directive from the resulting options map.
- /// Return an empty options map if the file does not exist.
- YamlMap getOptionsFromSource(Source source) {
- YamlMap options = getOptionsFromString(_readAnalysisOptions(source));
- YamlNode node = getValue(options, AnalyzerOptions.include);
- if (sourceFactory != null && node is YamlScalar) {
- var path = node.value;
- if (path is String) {
- Source parent = sourceFactory.resolveUri(source, path);
- options = merge(getOptionsFromSource(parent), options);
- }
- }
- return options;
- }
-
- /// Provide the options found in [optionsSource].
- /// An include directive, if present, will be left as-is,
- /// and the referenced options will NOT be merged into the result.
- /// Return an empty options map if the source is null.
- YamlMap getOptionsFromString(String optionsSource) {
- if (optionsSource == null) {
- return new YamlMap();
- }
- try {
- YamlNode doc = loadYamlNode(optionsSource);
- if (doc is YamlMap) {
- return doc;
- }
- return new YamlMap();
- } on YamlException catch (e) {
- throw new OptionsFormatException(e.message, e.span);
- } catch (e) {
- throw new OptionsFormatException('Unable to parse YAML document.');
- }
- }
-
- /// Merge the given options contents where the values in [defaults] may be
- /// overridden by [overrides].
- ///
- /// Some notes about merge semantics:
- ///
- /// * lists are merged (without duplicates).
- /// * lists of scalar values can be promoted to simple maps when merged with
- /// maps of strings to booleans (e.g., ['opt1', 'opt2'] becomes
- /// {'opt1': true, 'opt2': true}.
- /// * maps are merged recursively.
- /// * if map values cannot be merged, the overriding value is taken.
- ///
- YamlMap merge(YamlMap defaults, YamlMap overrides) =>
- new Merger().mergeMap(defaults, overrides);
-
- /// Read the contents of [source] as a string.
- /// Returns null if source is null or does not exist.
- String _readAnalysisOptions(Source source) {
- try {
- return source.contents.data;
- } catch (e) {
- // Source can't be read.
- return null;
- }
- }
-}
-
-/// Thrown on options format exceptions.
-class OptionsFormatException implements Exception {
- final String message;
- final SourceSpan span;
- OptionsFormatException(this.message, [this.span]);
-
- @override
- String toString() =>
- 'OptionsFormatException: ${message?.toString()}, ${span?.toString()}';
-}
+export 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
diff --git a/pkg/analyzer/lib/source/custom_resolver.dart b/pkg/analyzer/lib/source/custom_resolver.dart
index f5bbf46..8dfe9f9 100644
--- a/pkg/analyzer/lib/source/custom_resolver.dart
+++ b/pkg/analyzer/lib/source/custom_resolver.dart
@@ -2,29 +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.
+@deprecated
library analyzer.source.custom_resolver;
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-class CustomUriResolver extends UriResolver {
- final ResourceProvider resourceProvider;
- final Map<String, String> _urlMappings;
-
- CustomUriResolver(this.resourceProvider, this._urlMappings);
-
- @override
- Source resolveAbsolute(Uri uri, [Uri actualUri]) {
- String mapping = _urlMappings[uri.toString()];
- if (mapping == null) {
- return null;
- }
- Uri fileUri = new Uri.file(mapping);
- if (!fileUri.isAbsolute) {
- return null;
- }
- return resourceProvider
- .getFile(resourceProvider.pathContext.fromUri(fileUri))
- .createSource(actualUri ?? uri);
- }
-}
+export 'package:analyzer/src/source/custom_resolver.dart';
diff --git a/pkg/analyzer/lib/source/line_info.dart b/pkg/analyzer/lib/source/line_info.dart
new file mode 100644
index 0000000..38ac611
--- /dev/null
+++ b/pkg/analyzer/lib/source/line_info.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+/**
+ * The location of a character represented as a line and column pair.
+ */
+// ignore: deprecated_member_use
+class CharacterLocation extends LineInfo_Location {
+ // TODO(brianwilkerson) Replace the body of this class with the body of
+ // LineInfo_Location and remove LineInfo_Location.
+ /**
+ * Initialize a newly created location to represent the location of the
+ * character at the given [lineNumber] and [columnNumber].
+ */
+ CharacterLocation(int lineNumber, int columnNumber)
+ : super(lineNumber, columnNumber);
+}
+
+/**
+ * Information about line and column information within a source file.
+ */
+class LineInfo {
+ /**
+ * A list containing the offsets of the first character of each line in the
+ * source code.
+ */
+ final List<int> lineStarts;
+
+ /**
+ * The zero-based [lineStarts] index resulting from the last call to
+ * [getLocation].
+ */
+ int _previousLine = 0;
+
+ /**
+ * Initialize a newly created set of line information to represent the data
+ * encoded in the given list of [lineStarts].
+ */
+ LineInfo(this.lineStarts) {
+ if (lineStarts == null) {
+ throw new ArgumentError("lineStarts must be non-null");
+ } else if (lineStarts.length < 1) {
+ throw new ArgumentError("lineStarts must be non-empty");
+ }
+ }
+
+ /**
+ * Initialize a newly created set of line information corresponding to the
+ * given file [content].
+ */
+ factory LineInfo.fromContent(String content) =>
+ new LineInfo(StringUtilities.computeLineStarts(content));
+
+ /**
+ * The number of lines.
+ */
+ int get lineCount => lineStarts.length;
+
+ /**
+ * Return the location information for the character at the given [offset].
+ */
+ CharacterLocation getLocation(int offset) {
+ var min = 0;
+ var max = lineStarts.length - 1;
+
+ // Subsequent calls to [getLocation] are often for offsets near each other.
+ // To take advantage of that, we cache the index of the line start we found
+ // when this was last called. If the current offset is on that line or
+ // later, we'll skip those early indices completely when searching.
+ if (offset >= lineStarts[_previousLine]) {
+ min = _previousLine;
+
+ // Before kicking off a full binary search, do a quick check here to see
+ // if the new offset is on that exact line.
+ if (min == lineStarts.length - 1 || offset < lineStarts[min + 1]) {
+ return new CharacterLocation(min + 1, offset - lineStarts[min] + 1);
+ }
+ }
+
+ // Binary search to fine the line containing this offset.
+ while (min < max) {
+ var midpoint = (max - min + 1) ~/ 2 + min;
+
+ if (lineStarts[midpoint] > offset) {
+ max = midpoint - 1;
+ } else {
+ min = midpoint;
+ }
+ }
+
+ _previousLine = min;
+
+ return new CharacterLocation(min + 1, offset - lineStarts[min] + 1);
+ }
+
+ /**
+ * Return the offset of the first character on the line with the given
+ * [lineNumber].
+ */
+ int getOffsetOfLine(int lineNumber) {
+ if (lineNumber < 0 || lineNumber >= lineCount) {
+ throw new ArgumentError(
+ 'Invalid line number: $lineNumber; must be between 0 and ${lineCount - 1}');
+ }
+ return lineStarts[lineNumber];
+ }
+
+ /**
+ * Return the offset of the first character on the line following the line
+ * containing the given [offset].
+ */
+ int getOffsetOfLineAfter(int offset) {
+ return getOffsetOfLine(getLocation(offset).lineNumber + 1);
+ }
+}
diff --git a/pkg/analyzer/lib/source/package_map_provider.dart b/pkg/analyzer/lib/source/package_map_provider.dart
index b2eb8b6..f3c2119 100644
--- a/pkg/analyzer/lib/source/package_map_provider.dart
+++ b/pkg/analyzer/lib/source/package_map_provider.dart
@@ -2,43 +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.
+@deprecated
library analyzer.source.package_map_provider;
-import 'package:analyzer/file_system/file_system.dart';
-
-/**
- * Data structure output by PackageMapProvider. This contains both the package
- * map and dependency information.
- */
-class PackageMapInfo {
- /**
- * The package map itself. This is a map from package name to a list of
- * the folders containing source code for the package.
- *
- * `null` if an error occurred.
- */
- Map<String, List<Folder>> packageMap;
-
- /**
- * Dependency information. This is a set of the paths which were consulted
- * in order to generate the package map. If any of these files is
- * modified, the package map will need to be regenerated.
- */
- Set<String> dependencies;
-
- PackageMapInfo(this.packageMap, this.dependencies);
-}
-
-/**
- * A PackageMapProvider is an entity capable of determining the mapping from
- * package name to source directory for a given folder.
- */
-abstract class PackageMapProvider {
- /**
- * Compute a package map for the given folder, if possible.
- *
- * If a package map can't be computed (e.g. because an error occurred), a
- * [PackageMapInfo] will still be returned, but its packageMap will be null.
- */
- PackageMapInfo computePackageMap(Folder folder);
-}
+export 'package:analyzer/src/source/package_map_provider.dart';
diff --git a/pkg/analyzer/lib/source/path_filter.dart b/pkg/analyzer/lib/source/path_filter.dart
index c207014..ba5454e 100644
--- a/pkg/analyzer/lib/source/path_filter.dart
+++ b/pkg/analyzer/lib/source/path_filter.dart
@@ -2,76 +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.
+@deprecated
library analyzer.source.path_filter;
-import 'package:analyzer/src/util/glob.dart';
-import 'package:path/path.dart' as path;
-
-/// Filter paths against a set of [_ignorePatterns] relative to a [root]
-/// directory. Paths outside of [root] are also ignored.
-class PathFilter {
- /// The path context to use when manipulating paths.
- final path.Context pathContext;
-
- /// Path that all ignore patterns are relative to.
- final String root;
-
- /// List of ignore patterns that paths are tested against.
- final List<Glob> _ignorePatterns = new List<Glob>();
-
- /// Construct a new path filter rooted at [root] with [ignorePatterns].
- /// If [pathContext] is not specified, then the system path context is used.
- PathFilter(this.root, List<String> ignorePatterns, [path.Context pathContext])
- : this.pathContext = pathContext ?? path.context {
- setIgnorePatterns(ignorePatterns);
- }
-
- /// Returns true if [path] should be ignored. A path is ignored if it is not
- /// contained in [root] or matches one of the ignore patterns.
- /// [path] is absolute or relative to [root].
- bool ignored(String path) {
- path = _canonicalize(path);
- return !_contained(path) || _match(path);
- }
-
- /// Set the ignore patterns.
- void setIgnorePatterns(List<String> ignorePatterns) {
- _ignorePatterns.clear();
- if (ignorePatterns != null) {
- for (var ignorePattern in ignorePatterns) {
- _ignorePatterns.add(new Glob(pathContext.separator, ignorePattern));
- }
- }
- }
-
- @override
- String toString() {
- StringBuffer sb = new StringBuffer();
- for (Glob pattern in _ignorePatterns) {
- sb.write('$pattern ');
- }
- sb.writeln('');
- return sb.toString();
- }
-
- /// Returns the absolute path of [path], relative to [root].
- String _canonicalize(String path) =>
- pathContext.normalize(pathContext.join(root, path));
-
- /// Returns true when [path] is contained inside [root].
- bool _contained(String path) => path.startsWith(root);
-
- /// Returns true if [path] matches any ignore patterns.
- bool _match(String path) {
- path = _relative(path);
- for (Glob glob in _ignorePatterns) {
- if (glob.matches(path)) {
- return true;
- }
- }
- return false;
- }
-
- /// Returns the relative portion of [path] from [root].
- String _relative(String path) => pathContext.relative(path, from: root);
-}
+export 'package:analyzer/src/source/path_filter.dart';
diff --git a/pkg/analyzer/lib/source/pub_package_map_provider.dart b/pkg/analyzer/lib/source/pub_package_map_provider.dart
index 26436d9..feb2221 100644
--- a/pkg/analyzer/lib/source/pub_package_map_provider.dart
+++ b/pkg/analyzer/lib/source/pub_package_map_provider.dart
@@ -2,183 +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.
+@deprecated
library analyzer.source.pub_package_map_provider;
-import 'dart:collection';
-import 'dart:convert';
-import 'dart:core';
-import 'dart:io' as io;
-
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_provider.dart';
-import 'package:analyzer/src/dart/sdk/sdk.dart';
-import 'package:analyzer/src/generated/engine.dart';
-
-/**
- * The function used to run pub list.
- */
-typedef io.ProcessResult RunPubList(Folder folder);
-
-/**
- * Implementation of PackageMapProvider that operates by executing pub.
- */
-class PubPackageMapProvider implements PackageMapProvider {
- static const String PUB_LIST_COMMAND = 'list-package-dirs';
-
- /**
- * The name of the 'pubspec.lock' file, which we assume is the dependency
- * in the event that [PUB_LIST_COMMAND] fails.
- */
- static const String PUBSPEC_LOCK_NAME = 'pubspec.lock';
-
- /**
- * [ResourceProvider] that is used to create the [Folder]s that populate the
- * package map.
- */
- final ResourceProvider resourceProvider;
-
- /**
- * Sdk that we use to find the pub executable.
- */
- final FolderBasedDartSdk sdk;
-
- /**
- * The function used to run pub list.
- */
- RunPubList _runPubList;
-
- /**
- * Construct a new instance.
- * A [RunPubList] implementation may be injected for testing
- */
- PubPackageMapProvider(this.resourceProvider, this.sdk, [this._runPubList]) {
- if (_runPubList == null) {
- _runPubList = _runPubListDefault;
- }
- }
-
- @override
- PackageMapInfo computePackageMap(Folder folder) {
- // If the pubspec.lock file does not exist, no need to run anything.
- {
- String lockPath = getPubspecLockPath(folder);
- if (!resourceProvider.getFile(lockPath).exists) {
- return computePackageMapError(folder);
- }
- }
- // TODO(paulberry) make this asynchronous so that we can (a) do other
- // analysis while it's in progress, and (b) time out if it takes too long
- // to respond.
- io.ProcessResult result;
- try {
- result = _runPubList(folder);
- } on io.ProcessException catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logInformation(
- "Error running pub $PUB_LIST_COMMAND\n$exception\n$stackTrace");
- }
- if (result == null || result.exitCode != 0) {
- String exitCode =
- result != null ? 'exit code ${result.exitCode}' : 'null';
- AnalysisEngine.instance.logger
- .logInformation("pub $PUB_LIST_COMMAND failed: $exitCode");
- return computePackageMapError(folder);
- }
- try {
- PackageMapInfo packageMap =
- parsePackageMap(json.decode(result.stdout), folder);
- return packageMap;
- } catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logError(
- "Malformed output from pub $PUB_LIST_COMMAND\n$exception\n$stackTrace");
- }
-
- return computePackageMapError(folder);
- }
-
- /**
- * Create a PackageMapInfo object representing an error condition.
- */
- PackageMapInfo computePackageMapError(Folder folder) {
- // Even if an error occurs, we still need to know the dependencies, so that
- // we'll know when to try running "pub list-package-dirs" again.
- // Unfortunately, "pub list-package-dirs" doesn't tell us dependencies when
- // an error occurs, so just assume there is one dependency, "pubspec.lock".
- String lockPath = getPubspecLockPath(folder);
- List<String> dependencies = <String>[lockPath];
- return new PackageMapInfo(null, dependencies.toSet());
- }
-
- /**
- * Return the path to the `pubspec.lock` file in the given [folder].
- */
- String getPubspecLockPath(Folder folder) =>
- resourceProvider.pathContext.join(folder.path, PUBSPEC_LOCK_NAME);
-
- /**
- * Decode the JSON output from pub into a package map. Paths in the
- * output are considered relative to [folder].
- */
- PackageMapInfo parsePackageMap(Map obj, Folder folder) {
- // The output of pub looks like this:
- // {
- // "packages": {
- // "foo": "path/to/foo",
- // "bar": ["path/to/bar1", "path/to/bar2"],
- // "myapp": "path/to/myapp", // self link is included
- // },
- // "input_files": [
- // "path/to/myapp/pubspec.lock"
- // ]
- // }
- Map<String, List<Folder>> packageMap = new HashMap<String, List<Folder>>();
- Map packages = obj['packages'];
- processPaths(String packageName, List paths) {
- List<Folder> folders = <Folder>[];
- for (var path in paths) {
- if (path is String) {
- Resource resource = folder.getChildAssumingFolder(path);
- if (resource is Folder) {
- folders.add(resource);
- }
- }
- }
- if (folders.isNotEmpty) {
- packageMap[packageName] = folders;
- }
- }
-
- packages.forEach((key, value) {
- if (value is String) {
- processPaths(key, [value]);
- } else if (value is List) {
- processPaths(key, value);
- }
- });
- Set<String> dependencies = new Set<String>();
- List inputFiles = obj['input_files'];
- if (inputFiles != null) {
- for (var path in inputFiles) {
- if (path is String) {
- dependencies.add(folder.canonicalizePath(path));
- }
- }
- }
- return new PackageMapInfo(packageMap, dependencies);
- }
-
- /**
- * Run pub list to determine the packages and input files.
- */
- io.ProcessResult _runPubListDefault(Folder folder) {
- String executablePath = sdk.pubExecutable.path;
- List<String> arguments = [PUB_LIST_COMMAND];
- String workingDirectory = folder.path;
- int subprocessId = AnalysisEngine.instance.instrumentationService
- .logSubprocessStart(executablePath, arguments, workingDirectory);
- io.ProcessResult result = io.Process
- .runSync(executablePath, arguments, workingDirectory: workingDirectory);
- AnalysisEngine.instance.instrumentationService.logSubprocessResult(
- subprocessId, result.exitCode, result.stdout, result.stderr);
- return result;
- }
-}
+export 'package:analyzer/src/source/pub_package_map_provider.dart';
diff --git a/pkg/analyzer/lib/source/sdk_ext.dart b/pkg/analyzer/lib/source/sdk_ext.dart
index a1ea2b3..7f5557b 100644
--- a/pkg/analyzer/lib/source/sdk_ext.dart
+++ b/pkg/analyzer/lib/source/sdk_ext.dart
@@ -2,206 +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.
+@deprecated
library analyzer.source.sdk_ext;
-import 'dart:convert';
-import 'dart:core';
-
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_provider.dart'
- show PackageMapProvider;
-import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
-import 'package:path/path.dart' as pathos;
-
-/// Given a packageMap (see [PackageMapProvider]), check in each package's lib
-/// directory for the existence of a `_sdkext` file. This file must contain a
-/// JSON encoded map. Each key in the map is a `dart:` library name. Each value
-/// is a path (relative to the directory containing `_sdkext`) to a dart script
-/// for the given library. For example:
-/// {
-/// "dart:sky": "../sdk_ext/dart_sky.dart"
-/// }
-///
-/// If a key doesn't begin with `dart:` it is ignored.
-class SdkExtUriResolver extends UriResolver {
- static const String SDK_EXT_NAME = '_sdkext';
- static const String DART_COLON_PREFIX = 'dart:';
-
- final Map<String, String> _urlMappings = <String, String>{};
-
- /**
- * The absolute paths of the extension files that contributed to the
- * [_urlMappings].
- */
- final List<String> extensionFilePaths = <String>[];
-
- /// Construct a [SdkExtUriResolver] from a package map
- /// (see [PackageMapProvider]).
- SdkExtUriResolver(Map<String, List<Folder>> packageMap) {
- if (packageMap == null) {
- return;
- }
- packageMap.forEach(_processPackage);
- }
-
- /// Number of sdk extensions.
- int get length => _urlMappings.length;
-
- /**
- * Return a table mapping the names of extensions to the paths where those
- * extensions can be found.
- */
- Map<String, String> get urlMappings =>
- new Map<String, String>.from(_urlMappings);
-
- /// Return the path mapping for [libName] or null if there is none.
- String operator [](String libName) => _urlMappings[libName];
-
- /// Programmatically add a new SDK extension given a JSON description
- /// ([sdkExtJSON]) and a lib directory ([libDir]).
- void addSdkExt(String sdkExtJSON, Folder libDir) {
- _processSdkExt(sdkExtJSON, libDir);
- }
-
- @override
- Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
- String libraryName = _libraryName(importUri);
- String partPath = _partPath(importUri);
- // Lookup library name in mappings.
- String mapping = _urlMappings[libraryName];
- if (mapping == null) {
- // Not found.
- return null;
- }
- // This mapping points to the main entry file of the sdk extension.
- Uri libraryEntry = new Uri.file(mapping);
- if (!libraryEntry.isAbsolute) {
- // We expect an absolute path.
- return null;
- }
-
- if (partPath != null) {
- return _resolvePart(libraryEntry, partPath, importUri);
- } else {
- return _resolveEntry(libraryEntry, importUri);
- }
- }
-
- @override
- Uri restoreAbsolute(Source source) {
- String extensionName = _findExtensionNameFor(source.fullName);
- if (extensionName != null) {
- return Uri.parse(extensionName);
- }
- // TODO(johnmccutchan): Handle restoring parts.
- return null;
- }
-
- /// Return the extension name for [fullName] or `null`.
- String _findExtensionNameFor(String fullName) {
- var result;
- _urlMappings.forEach((extensionName, pathMapping) {
- if (pathMapping == fullName) {
- result = extensionName;
- }
- });
- return result;
- }
-
- /// Return the library name of [importUri].
- String _libraryName(Uri importUri) {
- var uri = importUri.toString();
- int index = uri.indexOf('/');
- if (index >= 0) {
- return uri.substring(0, index);
- }
- return uri;
- }
-
- /// Return the part path of [importUri].
- String _partPath(Uri importUri) {
- var uri = importUri.toString();
- int index = uri.indexOf('/');
- if (index >= 0) {
- return uri.substring(index + 1);
- }
- return null;
- }
-
- /// Given a package [name] and a list of folders ([libDirs]),
- /// add any found sdk extensions.
- void _processPackage(String name, List<Folder> libDirs) {
- for (var libDir in libDirs) {
- var sdkExt = _readDotSdkExt(libDir);
- if (sdkExt != null) {
- _processSdkExt(sdkExt, libDir);
- }
- }
- }
-
- /// Given the JSON for an SDK extension ([sdkExtJSON]) and a folder
- /// ([libDir]), setup the uri mapping.
- void _processSdkExt(String sdkExtJSON, Folder libDir) {
- var sdkExt;
- try {
- sdkExt = json.decode(sdkExtJSON);
- } catch (e) {
- return;
- }
- if ((sdkExt == null) || (sdkExt is! Map)) {
- return;
- }
- bool contributed = false;
- sdkExt.forEach((k, v) {
- if (_processSdkExtension(k, v, libDir)) {
- contributed = true;
- }
- });
- if (contributed) {
- extensionFilePaths.add(libDir.getChild(SDK_EXT_NAME).path);
- }
- }
-
- /// Install the mapping from [name] to [libDir]/[file].
- bool _processSdkExtension(String name, String file, Folder libDir) {
- if (!name.startsWith(DART_COLON_PREFIX)) {
- // SDK extensions must begin with 'dart:'.
- return false;
- }
- var key = name;
- var value = libDir.canonicalizePath(file);
- _urlMappings[key] = value;
- return true;
- }
-
- /// Read the contents of [libDir]/[SDK_EXT_NAME] as a string.
- /// Returns null if the file doesn't exist.
- String _readDotSdkExt(Folder libDir) {
- File file = libDir.getChild(SDK_EXT_NAME);
- try {
- return file.readAsStringSync();
- } on FileSystemException {
- // File can't be read.
- return null;
- }
- }
-
- /// Resolve an import of an sdk extension.
- Source _resolveEntry(Uri libraryEntry, Uri importUri) {
- // Library entry.
- JavaFile javaFile = new JavaFile.fromUri(libraryEntry);
- return new FileBasedSource(javaFile, importUri);
- }
-
- /// Resolve a 'part' statement inside an sdk extension.
- Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) {
- // Library part.
- var directory = pathos.dirname(libraryEntry.path);
- var partUri = new Uri.file(pathos.join(directory, partPath));
- assert(partUri.isAbsolute);
- JavaFile javaFile = new JavaFile.fromUri(partUri);
- return new FileBasedSource(javaFile, importUri);
- }
-}
+export 'package:analyzer/src/source/sdk_ext.dart';
diff --git a/pkg/analyzer/lib/source/source_range.dart b/pkg/analyzer/lib/source/source_range.dart
new file mode 100644
index 0000000..338ad7a
--- /dev/null
+++ b/pkg/analyzer/lib/source/source_range.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:math" as math;
+
+/**
+ * A source range defines a range of characters within source code.
+ */
+class SourceRange {
+ /**
+ * An empty source range (a range with offset `0` and length `0`).
+ */
+ static const SourceRange EMPTY = const SourceRange(0, 0);
+
+ /**
+ * The 0-based index of the first character of the source range.
+ */
+ final int offset;
+
+ /**
+ * The number of characters in the source range.
+ */
+ final int length;
+
+ /**
+ * Initialize a newly created source range using the given [offset] and
+ * [length].
+ */
+ const SourceRange(this.offset, this.length);
+
+ /**
+ * Return the 0-based index of the character immediately after this source
+ * range.
+ */
+ int get end => offset + length;
+
+ @override
+ int get hashCode => 31 * offset + length;
+
+ @override
+ bool operator ==(Object other) {
+ return other is SourceRange &&
+ other.offset == offset &&
+ other.length == length;
+ }
+
+ /**
+ * Return `true` if [x] is in the interval `[offset, offset + length)`.
+ */
+ bool contains(int x) => offset <= x && x < offset + length;
+
+ /**
+ * Return `true` if [x] is in the interval `(offset, offset + length)`.
+ */
+ bool containsExclusive(int x) => offset < x && x < offset + length;
+
+ /**
+ * Return `true` if the [otherRange] covers this source range.
+ */
+ bool coveredBy(SourceRange otherRange) => otherRange.covers(this);
+
+ /**
+ * Return `true` if this source range covers the [otherRange].
+ */
+ bool covers(SourceRange otherRange) =>
+ offset <= otherRange.offset && otherRange.end <= end;
+
+ /**
+ * Return `true` if this source range ends inside the [otherRange].
+ */
+ bool endsIn(SourceRange otherRange) {
+ int thisEnd = end;
+ return otherRange.contains(thisEnd);
+ }
+
+ /**
+ * Return a source range covering [delta] characters before the start of this
+ * source range and [delta] characters after the end of this source range.
+ */
+ SourceRange getExpanded(int delta) =>
+ new SourceRange(offset - delta, delta + length + delta);
+
+ /**
+ * Return a source range with the same offset as this source range but whose
+ * length is [delta] characters longer than this source range.
+ */
+ SourceRange getMoveEnd(int delta) => new SourceRange(offset, length + delta);
+
+ /**
+ * Return a source range with the same length as this source range but whose
+ * offset is [delta] characters after the offset of this source range.
+ */
+ SourceRange getTranslated(int delta) =>
+ new SourceRange(offset + delta, length);
+
+ /**
+ * Return the minimal source range that covers both this and the [otherRange].
+ */
+ SourceRange getUnion(SourceRange otherRange) {
+ int newOffset = math.min(offset, otherRange.offset);
+ int newEnd =
+ math.max(offset + length, otherRange.offset + otherRange.length);
+ return new SourceRange(newOffset, newEnd - newOffset);
+ }
+
+ /**
+ * Return `true` if this source range intersects the [otherRange].
+ */
+ bool intersects(SourceRange otherRange) {
+ if (otherRange == null) {
+ return false;
+ }
+ if (end <= otherRange.offset) {
+ return false;
+ }
+ if (offset >= otherRange.end) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Return `true` if this source range starts in the [otherRange].
+ */
+ bool startsIn(SourceRange otherRange) => otherRange.contains(offset);
+
+ @override
+ String toString() => '[offset=$offset, length=$length]';
+}
diff --git a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
new file mode 100644
index 0000000..550f3e3
--- /dev/null
+++ b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:core';
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/source_resource.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer/src/util/yaml.dart';
+import 'package:source_span/source_span.dart';
+import 'package:yaml/yaml.dart';
+
+/// Provide the options found in the analysis options file.
+class AnalysisOptionsProvider {
+ /// The source factory used to resolve include declarations
+ /// in analysis options files or `null` if include is not supported.
+ SourceFactory sourceFactory;
+
+ AnalysisOptionsProvider([this.sourceFactory]);
+
+ /// Provide the options found in either
+ /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_FILE] or
+ /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE].
+ /// Recursively merge options referenced by an include directive
+ /// and remove the include directive from the resulting options map.
+ /// Return an empty options map if the file does not exist.
+ YamlMap getOptions(Folder root, {bool crawlUp: false}) {
+ File optionsFile = getOptionsFile(root, crawlUp: crawlUp);
+ if (optionsFile == null) {
+ return new YamlMap();
+ }
+ return getOptionsFromFile(optionsFile);
+ }
+
+ /// Return the analysis options file from which options should be read, or
+ /// `null` if there is no analysis options file for code in the given [root].
+ ///
+ /// The given [root] directory will be searched first. If no file is found and
+ /// if [crawlUp] is `true`, then enclosing directories will be searched.
+ File getOptionsFile(Folder root, {bool crawlUp: false}) {
+ Resource resource = null;
+ for (Folder folder = root; folder != null; folder = folder.parent) {
+ resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
+ if (resource.exists) {
+ break;
+ }
+ resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ if (resource.exists || !crawlUp) {
+ break;
+ }
+ }
+ if (resource is File && resource.exists) {
+ return resource;
+ }
+ return null;
+ }
+
+ /// Provide the options found in [file].
+ /// Recursively merge options referenced by an include directive
+ /// and remove the include directive from the resulting options map.
+ /// Return an empty options map if the file does not exist.
+ YamlMap getOptionsFromFile(File file) {
+ return getOptionsFromSource(new FileSource(file));
+ }
+
+ /// Provide the options found in [source].
+ /// Recursively merge options referenced by an include directive
+ /// and remove the include directive from the resulting options map.
+ /// Return an empty options map if the file does not exist.
+ YamlMap getOptionsFromSource(Source source) {
+ YamlMap options = getOptionsFromString(_readAnalysisOptions(source));
+ YamlNode node = getValue(options, AnalyzerOptions.include);
+ if (sourceFactory != null && node is YamlScalar) {
+ var path = node.value;
+ if (path is String) {
+ Source parent = sourceFactory.resolveUri(source, path);
+ options = merge(getOptionsFromSource(parent), options);
+ }
+ }
+ return options;
+ }
+
+ /// Provide the options found in [optionsSource].
+ /// An include directive, if present, will be left as-is,
+ /// and the referenced options will NOT be merged into the result.
+ /// Return an empty options map if the source is null.
+ YamlMap getOptionsFromString(String optionsSource) {
+ if (optionsSource == null) {
+ return new YamlMap();
+ }
+ try {
+ YamlNode doc = loadYamlNode(optionsSource);
+ if (doc is YamlMap) {
+ return doc;
+ }
+ return new YamlMap();
+ } on YamlException catch (e) {
+ throw new OptionsFormatException(e.message, e.span);
+ } catch (e) {
+ throw new OptionsFormatException('Unable to parse YAML document.');
+ }
+ }
+
+ /// Merge the given options contents where the values in [defaults] may be
+ /// overridden by [overrides].
+ ///
+ /// Some notes about merge semantics:
+ ///
+ /// * lists are merged (without duplicates).
+ /// * lists of scalar values can be promoted to simple maps when merged with
+ /// maps of strings to booleans (e.g., ['opt1', 'opt2'] becomes
+ /// {'opt1': true, 'opt2': true}.
+ /// * maps are merged recursively.
+ /// * if map values cannot be merged, the overriding value is taken.
+ ///
+ YamlMap merge(YamlMap defaults, YamlMap overrides) =>
+ new Merger().mergeMap(defaults, overrides);
+
+ /// Read the contents of [source] as a string.
+ /// Returns null if source is null or does not exist.
+ String _readAnalysisOptions(Source source) {
+ try {
+ return source.contents.data;
+ } catch (e) {
+ // Source can't be read.
+ return null;
+ }
+ }
+}
+
+/// Thrown on options format exceptions.
+class OptionsFormatException implements Exception {
+ final String message;
+ final SourceSpan span;
+ OptionsFormatException(this.message, [this.span]);
+
+ @override
+ String toString() =>
+ 'OptionsFormatException: ${message?.toString()}, ${span?.toString()}';
+}
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 29d84ce..2aee1c4 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -5,18 +5,18 @@
import 'dart:collection';
import 'dart:core';
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/command_line/arguments.dart'
show
applyAnalysisOptionFlags,
bazelAnalysisOptionsPath,
flutterAnalysisOptionsPath;
import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart'
show AnalysisDriver, AnalysisDriverScheduler;
import 'package:analyzer/src/dart/analysis/file_state.dart';
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 1a86195..40a2d9e 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.context.cache;
-
import 'dart:async';
import 'dart:collection';
@@ -12,8 +10,8 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/model.dart';
-import 'package:analyzer/task/model.dart';
/**
* The cache results visiting function type.
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 200ed96..a70c50e5 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.context.context;
-
import 'dart:async';
import 'dart:collection';
@@ -12,7 +10,6 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/plugin/task.dart';
import 'package:analyzer/src/cancelable_future.dart';
import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
import 'package:analyzer/src/context/cache.dart';
@@ -23,14 +20,15 @@
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/plugin/task.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/html.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/dart_work_manager.dart';
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/html.dart';
-import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart' show Document;
/**
diff --git a/pkg/analyzer/lib/context/context_root.dart b/pkg/analyzer/lib/src/context/context_root.dart
similarity index 100%
rename from pkg/analyzer/lib/context/context_root.dart
rename to pkg/analyzer/lib/src/context/context_root.dart
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
index ff0ecb0..628d28c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analyzer/context/context_root.dart' as old;
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/context_builder.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
@@ -11,6 +10,7 @@
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/context/builder.dart' as old
show ContextBuilder, ContextBuilderOptions;
+import 'package:analyzer/src/context/context_root.dart' as old;
import 'package:analyzer/src/dart/analysis/driver.dart'
show AnalysisDriver, AnalysisDriverScheduler;
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 83147d0..e53835f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -4,7 +4,6 @@
import 'dart:collection';
-import 'package:analyzer/context/context_root.dart' as old;
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/context_locator.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
@@ -13,6 +12,7 @@
show PhysicalResourceProvider;
import 'package:analyzer/src/context/builder.dart'
show ContextBuilder, ContextBuilderOptions;
+import 'package:analyzer/src/context/context_root.dart' as old;
import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart'
show AnalysisDriver, AnalysisDriverScheduler;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index da83c22..91c19a8 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -6,7 +6,6 @@
import 'dart:collection';
import 'dart:typed_data';
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/results.dart' as results;
import 'package:analyzer/dart/analysis/session.dart';
@@ -17,6 +16,7 @@
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/file_tracker.dart';
import 'package:analyzer/src/dart/analysis/frontend_resolution.dart';
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index c6032e3..b82ab39 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -82,6 +82,11 @@
* should be called.
*/
class FileState {
+ /**
+ * The next value for [_exportDeclarationsId].
+ */
+ static int _exportDeclarationsNextId = 0;
+
final FileSystemState _fsState;
/**
@@ -116,11 +121,12 @@
String _content;
String _contentHash;
LineInfo _lineInfo;
- Set<String> _definedTopLevelNames;
Set<String> _definedClassMemberNames;
+ Set<String> _definedTopLevelNames;
Set<String> _referencedNames;
Set<String> _subtypedNames;
String _unlinkedKey;
+ AnalysisDriverUnlinkedUnit _driverUnlinkedUnit;
UnlinkedUnit _unlinked;
List<int> _apiSignature;
@@ -135,6 +141,7 @@
Map<String, TopLevelDeclaration> _topLevelDeclarations;
Map<String, TopLevelDeclaration> _exportedTopLevelDeclarations;
+ int _exportDeclarationsId = 0;
/**
* The flag that shows whether the file has an error or warning that
@@ -172,12 +179,18 @@
/**
* The class member names defined by the file.
*/
- Set<String> get definedClassMemberNames => _definedClassMemberNames;
+ Set<String> get definedClassMemberNames {
+ return _definedClassMemberNames ??=
+ _driverUnlinkedUnit.definedClassMemberNames.toSet();
+ }
/**
* The top-level names defined by the file.
*/
- Set<String> get definedTopLevelNames => _definedTopLevelNames;
+ Set<String> get definedTopLevelNames {
+ return _definedTopLevelNames ??=
+ _driverUnlinkedUnit.definedTopLevelNames.toSet();
+ }
/**
* Return the set of all directly referenced files - imported, exported or
@@ -200,44 +213,8 @@
* keys to the map are names of declarations.
*/
Map<String, TopLevelDeclaration> get exportedTopLevelDeclarations {
- if (_exportedTopLevelDeclarations == null) {
- _exportedTopLevelDeclarations = <String, TopLevelDeclaration>{};
-
- Set<FileState> seenLibraries = new Set<FileState>();
-
- /**
- * Compute [TopLevelDeclaration]s exported from the [library].
- */
- Map<String, TopLevelDeclaration> computeExported(FileState library) {
- var declarations = <String, TopLevelDeclaration>{};
- if (seenLibraries.add(library)) {
- // Append the exported declarations.
- for (int i = 0; i < library._exportedFiles.length; i++) {
- Map<String, TopLevelDeclaration> exported =
- computeExported(library._exportedFiles[i]);
- for (TopLevelDeclaration t in exported.values) {
- if (library._exportFilters[i].accepts(t.name)) {
- declarations[t.name] = t;
- }
- }
- }
-
- // Append the library declarations.
- declarations.addAll(library.topLevelDeclarations);
- for (FileState part in library.partedFiles) {
- declarations.addAll(part.topLevelDeclarations);
- }
-
- // We're done with this library.
- seenLibraries.remove(library);
- }
-
- return declarations;
- }
-
- _exportedTopLevelDeclarations = computeExported(this);
- }
- return _exportedTopLevelDeclarations;
+ _exportDeclarationsNextId = 1;
+ return _computeExportedDeclarations().declarations;
}
@override
@@ -281,13 +258,17 @@
/**
* The external names referenced by the file.
*/
- Set<String> get referencedNames => _referencedNames;
+ Set<String> get referencedNames {
+ return _referencedNames ??= _driverUnlinkedUnit.referencedNames.toSet();
+ }
/**
* The names which are used in `extends`, `with` or `implements` clauses in
* the file. Import prefixes and type arguments are not included.
*/
- Set<String> get subtypedNames => _subtypedNames;
+ Set<String> get subtypedNames {
+ return _subtypedNames ??= _driverUnlinkedUnit.subtypedNames.toSet();
+ }
@visibleForTesting
FileStateTestView get test => new FileStateTestView(this);
@@ -415,24 +396,20 @@
* Read the file content and ensure that all of the file properties are
* consistent with the read content, including API signature.
*
+ * If [allowCached] is `true`, don't read the content of the file if it
+ * is already cached (in another [FileSystemState], because otherwise we
+ * would not create this new instance of [FileState] and refresh it).
+ *
* Return `true` if the API signature changed since the last refresh.
*/
- bool refresh() {
- // Read the content.
- try {
- _content = _fsState._contentOverlay[path];
- _content ??= _fsState._resourceProvider.getFile(path).readAsStringSync();
- _exists = true;
- } catch (_) {
- _content = '';
- _exists = false;
- }
-
- // Compute the content hash.
- List<int> contentBytes = utf8.encode(_content);
+ bool refresh({bool allowCached: false}) {
+ List<int> contentBytes;
{
- List<int> hashBytes = md5.convert(contentBytes).bytes;
- _contentHash = hex.encode(hashBytes);
+ var rawFileState = _fsState._fileContentCache.get(path, allowCached);
+ _content = rawFileState.content;
+ _exists = rawFileState.exists;
+ contentBytes = rawFileState.contentBytes;
+ _contentHash = rawFileState.contentHash;
}
// Prepare the unlinked bundle key.
@@ -469,14 +446,15 @@
}
// Read the unlinked bundle.
- var driverUnlinkedUnit = new AnalysisDriverUnlinkedUnit.fromBuffer(bytes);
- _definedTopLevelNames = driverUnlinkedUnit.definedTopLevelNames.toSet();
- _definedClassMemberNames =
- driverUnlinkedUnit.definedClassMemberNames.toSet();
- _referencedNames = driverUnlinkedUnit.referencedNames.toSet();
- _subtypedNames = driverUnlinkedUnit.subtypedNames.toSet();
- _unlinked = driverUnlinkedUnit.unit;
+ _driverUnlinkedUnit = new AnalysisDriverUnlinkedUnit.fromBuffer(bytes);
+ _unlinked = _driverUnlinkedUnit.unit;
_lineInfo = new LineInfo(_unlinked.lineStarts);
+
+ // Invalidate unlinked information.
+ _definedTopLevelNames = null;
+ _definedClassMemberNames = null;
+ _referencedNames = null;
+ _subtypedNames = null;
_topLevelDeclarations = null;
// Prepare API signature.
@@ -558,6 +536,70 @@
@override
String toString() => path;
+ /**
+ * Compute the full or partial map of exported declarations for this library.
+ */
+ _ExportedDeclarations _computeExportedDeclarations() {
+ // If we know exported declarations, return them.
+ if (_exportedTopLevelDeclarations != null) {
+ return new _ExportedDeclarations(0, _exportedTopLevelDeclarations);
+ }
+
+ // If we are already computing exported declarations for this library,
+ // report that we found a cycle.
+ if (_exportDeclarationsId != 0) {
+ return new _ExportedDeclarations(_exportDeclarationsId, null);
+ }
+
+ var declarations = <String, TopLevelDeclaration>{};
+
+ // Give each library a unique identifier.
+ _exportDeclarationsId = _exportDeclarationsNextId++;
+
+ // Append the exported declarations.
+ int firstCycleId = 0;
+ for (int i = 0; i < _exportedFiles.length; i++) {
+ var exported = _exportedFiles[i]._computeExportedDeclarations();
+ if (exported.declarations != null) {
+ for (TopLevelDeclaration t in exported.declarations.values) {
+ if (_exportFilters[i].accepts(t.name)) {
+ declarations[t.name] = t;
+ }
+ }
+ }
+ if (exported.firstCycleId > 0) {
+ if (firstCycleId == 0 || firstCycleId > exported.firstCycleId) {
+ firstCycleId = exported.firstCycleId;
+ }
+ }
+ }
+
+ // If this library is the first component of the cycle, then we are at
+ // the beginning of this cycle, and combination of partial export
+ // namespaces of other exported libraries and declarations of this library
+ // is the full export namespace of this library.
+ if (firstCycleId != 0 && firstCycleId == _exportDeclarationsId) {
+ firstCycleId = 0;
+ }
+
+ // We're done with this library, successfully or not.
+ _exportDeclarationsId = 0;
+
+ // Append the library declarations.
+ declarations.addAll(topLevelDeclarations);
+ for (FileState part in partedFiles) {
+ declarations.addAll(part.topLevelDeclarations);
+ }
+
+ // Record the declarations only if it is the full result.
+ if (firstCycleId == 0) {
+ _exportedTopLevelDeclarations = declarations;
+ }
+
+ // Return the full or partial result.
+ return new _ExportedDeclarations(firstCycleId, declarations);
+ }
+
CompilationUnit _createEmptyCompilationUnit() {
var token = new Token.eof(0);
return astFactory.compilationUnit(token, null, [], [], token)
@@ -708,6 +750,12 @@
*/
FileState _unresolvedFile;
+ /**
+ * The cache of content of files, possibly shared with other file system
+ * states with the same resource provider and the content overlay.
+ */
+ _FileContentCache _fileContentCache;
+
FileSystemStateTestView _testView;
FileSystemState(
@@ -720,6 +768,8 @@
this._salt,
{this.externalSummaries,
this.parseExceptionHandler}) {
+ _fileContentCache =
+ _FileContentCache.getInstance(_resourceProvider, _contentOverlay);
_testView = new FileSystemStateTestView(this);
}
@@ -770,7 +820,7 @@
_uriToFile[uri] = file;
_addFileWithPath(path, file);
_pathToCanonicalFile[path] = file;
- file.refresh();
+ file.refresh(allowCached: true);
}
return file;
}
@@ -810,7 +860,7 @@
file = new FileState._(this, path, uri, fileUri, source);
_uriToFile[uri] = file;
_addFileWithPath(path, file);
- file.refresh();
+ file.refresh(allowCached: true);
}
return file;
}
@@ -851,9 +901,18 @@
}
/**
+ * The file with the given [path] might have changed, so ensure that it is
+ * read the next time it is refreshed.
+ */
+ void markFileForReading(String path) {
+ _fileContentCache.remove(path);
+ }
+
+ /**
* Remove the file with the given [path].
*/
void removeFile(String path) {
+ markFileForReading(path);
_uriToFile.clear();
knownFilePaths.clear();
_pathToFiles.clear();
@@ -889,4 +948,107 @@
.where((f) => f._transitiveSignature == null)
.toSet();
}
+
+ Set<FileState> get librariesWithComputedExportedDeclarations {
+ return state._uriToFile.values
+ .where((f) => !f.isPart && f._exportedTopLevelDeclarations != null)
+ .toSet();
+ }
+}
+
+/**
+ * The result of computing exported top-level declarations.
+ * It can be full (when [firstCycleId] is zero), or partial (when a cycle)
+ */
+class _ExportedDeclarations {
+ final int firstCycleId;
+ final Map<String, TopLevelDeclaration> declarations;
+
+ _ExportedDeclarations(this.firstCycleId, this.declarations);
+}
+
+/**
+ * Information about the content of a file.
+ */
+class _FileContent {
+ final String path;
+ final bool exists;
+ final String content;
+ final List<int> contentBytes;
+ final String contentHash;
+
+ _FileContent(this.path, this.exists, this.content, this.contentBytes,
+ this.contentHash);
+}
+
+/**
+ * The cache of information about content of files.
+ */
+class _FileContentCache {
+ /**
+ * Weak map of cache instances.
+ *
+ * Outer key is a [FileContentOverlay].
+ * Inner key is a [ResourceProvider].
+ */
+ static final _instances = new Expando<Expando<_FileContentCache>>();
+
+ final ResourceProvider _resourceProvider;
+ final FileContentOverlay _contentOverlay;
+ final Map<String, _FileContent> _pathToFile = {};
+
+ _FileContentCache(this._resourceProvider, this._contentOverlay);
+
+ /**
+ * Return the content of the file with the given [path].
+ *
+ * If [allowCached] is `true`, and the file is in the cache, return the
+ * cached data. Otherwise read the file, compute and cache the data.
+ */
+ _FileContent get(String path, bool allowCached) {
+ var file = allowCached ? _pathToFile[path] : null;
+ if (file == null) {
+ String content;
+ bool exists;
+ try {
+ content = _contentOverlay[path];
+ content ??= _resourceProvider.getFile(path).readAsStringSync();
+ exists = true;
+ } catch (_) {
+ content = '';
+ exists = false;
+ }
+
+ List<int> contentBytes = utf8.encode(content);
+
+ List<int> contentHashBytes = md5.convert(contentBytes).bytes;
+ String contentHash = hex.encode(contentHashBytes);
+
+ file = new _FileContent(path, exists, content, contentBytes, contentHash);
+ _pathToFile[path] = file;
+ }
+ return file;
+ }
+
+ /**
+ * Remove the file with the given [path] from the cache.
+ */
+ void remove(String path) {
+ _pathToFile.remove(path);
+ }
+
+ static _FileContentCache getInstance(
+ ResourceProvider resourceProvider, FileContentOverlay contentOverlay) {
+ var providerToInstance = _instances[contentOverlay];
+ if (providerToInstance == null) {
+ providerToInstance = new Expando<_FileContentCache>();
+ _instances[contentOverlay] = providerToInstance;
+ }
+ var instance = providerToInstance[resourceProvider];
+ if (instance == null) {
+ instance = new _FileContentCache(resourceProvider, contentOverlay);
+ providerToInstance[resourceProvider] = instance;
+ }
+ return instance;
+ }
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart b/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
index 5cfb130..6c08079 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
@@ -144,6 +144,7 @@
* Adds the given [path] to the set of "added files".
*/
void addFile(String path) {
+ _fsState.markFileForReading(path);
addedFiles.add(path);
_pendingFiles.add(path);
_changeHook();
@@ -166,6 +167,7 @@
if (addedFiles.contains(path)) {
_pendingChangedFiles.add(path);
}
+ _fsState.markFileForReading(path);
_changeHook();
}
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 3156fe9..56eb475 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -1667,6 +1667,7 @@
_isEqualNodeLists(node.metadata, other.metadata) &&
isEqualTokens(node.keyword, other.keyword) &&
isEqualNodes(node.uri, other.uri) &&
+ _isEqualNodeLists(node.configurations, other.configurations) &&
isEqualTokens(node.deferredKeyword, other.deferredKeyword) &&
isEqualTokens(node.asKeyword, other.asKeyword) &&
isEqualNodes(node.prefix, other.prefix) &&
diff --git a/pkg/analyzer/lib/src/dart/sdk/patch.dart b/pkg/analyzer/lib/src/dart/sdk/patch.dart
index 8057686..657fde0 100644
--- a/pkg/analyzer/lib/src/dart/sdk/patch.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/patch.dart
@@ -2,12 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.dart.sdk.patch;
-
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/parser.dart';
@@ -95,7 +94,7 @@
}
String _getLocationDesc3(CompilationUnit unit, int offset) {
- LineInfo_Location location = unit.lineInfo.getLocation(offset);
+ CharacterLocation location = unit.lineInfo.getLocation(offset);
return 'the line ${location.lineNumber}';
}
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 9e84278..63cfad3 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -3735,7 +3735,8 @@
static const StaticWarningCode IMPORT_DUPLICATED_LIBRARY_NAMED =
const StaticWarningCode('IMPORT_DUPLICATED_LIBRARY_NAMED',
"The imported libraries '{0}' and '{1}' can't have the same name '{2}'.",
- correction: "Try adding a hide clause to one of the imports.");
+ correction: "Try adding a hide clause to one of the imports.",
+ isStrongModeError: false);
/**
* 14.1 Imports: It is a static warning if the specified URI of a deferred
@@ -5027,19 +5028,6 @@
"The type of '{0}' can't be inferred because {1} expressions aren't supported.",
correction: "Try adding an explicit type for '{0}'.");
- /**
- * This warning is generated when a function type is assigned to a function
- * typed location, and the assignment will be invalid after fuzzy arrows
- * (the treatment of dynamic as bottom in certain locations) is removed.
- *
- */
- static const StrongModeCode USES_DYNAMIC_AS_BOTTOM = const StrongModeCode(
- ErrorType.STATIC_TYPE_WARNING,
- 'USES_DYNAMIC_AS_BOTTOM',
- "A function of type '{0}' can't be assigned to a location of type '{1}'.",
- correction: "Try changing the parameter types of the function or of the "
- " receiving location.");
-
@override
final ErrorType type;
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 742643d..997767c 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -874,8 +874,17 @@
Expression condition = pop();
switch (kind) {
case Assert.Expression:
- throw new UnimplementedError(
- 'assert expressions are not yet supported');
+ // The parser has already reported an error indicating that assert
+ // cannot be used in an expression. Insert a placeholder.
+ List<Expression> arguments = <Expression>[condition];
+ if (message != null) {
+ arguments.add(message);
+ }
+ push(ast.functionExpressionInvocation(
+ ast.simpleIdentifier(assertKeyword),
+ null,
+ ast.argumentList(
+ leftParenthesis, arguments, leftParenthesis?.endGroup)));
break;
case Assert.Initializer:
push(ast.assertInitializer(assertKeyword, leftParenthesis, condition,
@@ -1097,6 +1106,15 @@
}
}
+ @override
+ void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+ Token varFinalOrConst) {
+ push(new _Modifiers()
+ ..covariantKeyword = covariantToken
+ ..finalConstOrVarKeyword = varFinalOrConst);
+ }
+
+ @override
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
assert(optionalOrNull('this', thisKeyword));
@@ -1460,23 +1478,6 @@
push(ast.postfixExpression(expression, operator));
}
- void handleModifier(Token token) {
- assert(token.isModifier);
- debugEvent("Modifier");
-
- push(token);
- }
-
- void handleModifiers(int count) {
- debugEvent("Modifiers");
-
- if (count == 0) {
- push(NullValue.Modifiers);
- } else {
- push(new _Modifiers(popTypedList(count)));
- }
- }
-
void beginTopLevelMethod(Token lastConsumed, Token externalToken) {
push(new _Modifiers()..externalKeyword = externalToken);
}
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index ad983e9..45b1794 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.generated.engine;
-
import 'dart:async';
import 'dart:collection';
import 'dart:typed_data';
@@ -27,14 +25,14 @@
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/plugin/engine_plugin.dart';
import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/general.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/src/task/manager.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/task/yaml.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/model.dart';
import 'package:front_end/src/base/api_signature.dart';
import 'package:front_end/src/base/timestamped_data.dart';
import 'package:front_end/src/fasta/scanner/token.dart';
diff --git a/pkg/analyzer/lib/src/generated/gn.dart b/pkg/analyzer/lib/src/generated/gn.dart
index b55f96b..51440cb 100644
--- a/pkg/analyzer/lib/src/generated/gn.dart
+++ b/pkg/analyzer/lib/src/generated/gn.dart
@@ -234,8 +234,9 @@
File config = provider.getFile(pathContext.join(root, '.config'));
if (config.exists) {
String content = config.readAsStringSync();
- Match match = new RegExp(r'^FUCHSIA_BUILD_DIR="(.+)"$', multiLine: true)
- .firstMatch(content);
+ Match match =
+ new RegExp(r'^FUCHSIA_BUILD_DIR=["\x27](.+)["\x27]$', multiLine: true)
+ .firstMatch(content);
if (match != null) {
String path = match.group(1);
if (pathContext.isRelative(path)) {
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index de9c88f..d693693 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -2,15 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.generated.source;
-
import 'dart:collection';
-import "dart:math" as math;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/source.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
@@ -19,6 +15,8 @@
import 'package:package_config/packages.dart';
import 'package:path/path.dart' as pathos;
+export 'package:analyzer/source/line_info.dart' show LineInfo;
+export 'package:analyzer/source/source_range.dart';
export 'package:front_end/src/base/source.dart' show Source;
export 'package:front_end/src/base/uri_kind.dart' show UriKind;
@@ -199,107 +197,10 @@
}
/**
- * Information about line and column information within a source file.
- */
-class LineInfo {
- /**
- * A list containing the offsets of the first character of each line in the
- * source code.
- */
- final List<int> lineStarts;
-
- /**
- * The zero-based [lineStarts] index resulting from the last call to
- * [getLocation].
- */
- int _previousLine = 0;
-
- /**
- * Initialize a newly created set of line information to represent the data
- * encoded in the given list of [lineStarts].
- */
- LineInfo(this.lineStarts) {
- if (lineStarts == null) {
- throw new ArgumentError("lineStarts must be non-null");
- } else if (lineStarts.length < 1) {
- throw new ArgumentError("lineStarts must be non-empty");
- }
- }
-
- /**
- * Initialize a newly created set of line information corresponding to the
- * given file [content].
- */
- factory LineInfo.fromContent(String content) =>
- new LineInfo(StringUtilities.computeLineStarts(content));
-
- /**
- * The number of lines.
- */
- int get lineCount => lineStarts.length;
-
- /**
- * Return the location information for the character at the given [offset].
- */
- LineInfo_Location getLocation(int offset) {
- var min = 0;
- var max = lineStarts.length - 1;
-
- // Subsequent calls to [getLocation] are often for offsets near each other.
- // To take advantage of that, we cache the index of the line start we found
- // when this was last called. If the current offset is on that line or
- // later, we'll skip those early indices completely when searching.
- if (offset >= lineStarts[_previousLine]) {
- min = _previousLine;
-
- // Before kicking off a full binary search, do a quick check here to see
- // if the new offset is on that exact line.
- if (min == lineStarts.length - 1 || offset < lineStarts[min + 1]) {
- return new LineInfo_Location(min + 1, offset - lineStarts[min] + 1);
- }
- }
-
- // Binary search to fine the line containing this offset.
- while (min < max) {
- var midpoint = (max - min + 1) ~/ 2 + min;
-
- if (lineStarts[midpoint] > offset) {
- max = midpoint - 1;
- } else {
- min = midpoint;
- }
- }
-
- _previousLine = min;
-
- return new LineInfo_Location(min + 1, offset - lineStarts[min] + 1);
- }
-
- /**
- * Return the offset of the first character on the line with the given
- * [lineNumber].
- */
- int getOffsetOfLine(int lineNumber) {
- if (lineNumber < 0 || lineNumber >= lineCount) {
- throw new ArgumentError(
- 'Invalid line number: $lineNumber; must be between 0 and ${lineCount - 1}');
- }
- return lineStarts[lineNumber];
- }
-
- /**
- * Return the offset of the first character on the line following the line
- * containing the given [offset].
- */
- int getOffsetOfLineAfter(int offset) {
- return getOffsetOfLine(getLocation(offset).lineNumber + 1);
- }
-}
-
-/**
* Instances of the class `Location` represent the location of a character as a line and
* column pair.
*/
+@deprecated
class LineInfo_Location {
/**
* The one-based index of the line containing the character.
@@ -312,11 +213,8 @@
final int columnNumber;
/**
- * Initialize a newly created location to represent the location of the character at the given
- * line and column position.
- *
- * @param lineNumber the one-based index of the line containing the character
- * @param columnNumber the one-based index of the column containing the character
+ * Initialize a newly created location to represent the location of the
+ * character at the given [lineNumber] and [columnNumber].
*/
LineInfo_Location(this.lineNumber, this.columnNumber);
@@ -607,131 +505,6 @@
}
/**
- * A source range defines an [Element]'s source coordinates relative to its [Source].
- */
-class SourceRange {
- /**
- * An empty [SourceRange] with offset `0` and length `0`.
- */
- static SourceRange EMPTY = new SourceRange(0, 0);
-
- /**
- * The 0-based index of the first character of the source code for this element, relative to the
- * source buffer in which this element is contained.
- */
- final int offset;
-
- /**
- * The number of characters of the source code for this element, relative to the source buffer in
- * which this element is contained.
- */
- final int length;
-
- /**
- * Initialize a newly created source range using the given offset and the given length.
- *
- * @param offset the given offset
- * @param length the given length
- */
- SourceRange(this.offset, this.length);
-
- /**
- * @return the 0-based index of the after-last character of the source code for this element,
- * relative to the source buffer in which this element is contained.
- */
- int get end => offset + length;
-
- @override
- int get hashCode => 31 * offset + length;
-
- @override
- bool operator ==(Object other) {
- return other is SourceRange &&
- other.offset == offset &&
- other.length == length;
- }
-
- /**
- * @return `true` if <code>x</code> is in [offset, offset + length) interval.
- */
- bool contains(int x) => offset <= x && x < offset + length;
-
- /**
- * @return `true` if <code>x</code> is in (offset, offset + length) interval.
- */
- bool containsExclusive(int x) => offset < x && x < offset + length;
-
- /**
- * @return `true` if <code>otherRange</code> covers this [SourceRange].
- */
- bool coveredBy(SourceRange otherRange) => otherRange.covers(this);
-
- /**
- * @return `true` if this [SourceRange] covers <code>otherRange</code>.
- */
- bool covers(SourceRange otherRange) =>
- offset <= otherRange.offset && otherRange.end <= end;
-
- /**
- * @return `true` if this [SourceRange] ends in <code>otherRange</code>.
- */
- bool endsIn(SourceRange otherRange) {
- int thisEnd = end;
- return otherRange.contains(thisEnd);
- }
-
- /**
- * @return the expanded instance of [SourceRange], which has the same center.
- */
- SourceRange getExpanded(int delta) =>
- new SourceRange(offset - delta, delta + length + delta);
-
- /**
- * @return the instance of [SourceRange] with end moved on "delta".
- */
- SourceRange getMoveEnd(int delta) => new SourceRange(offset, length + delta);
-
- /**
- * @return the expanded translated of [SourceRange], with moved start and the same length.
- */
- SourceRange getTranslated(int delta) =>
- new SourceRange(offset + delta, length);
-
- /**
- * @return the minimal [SourceRange] that cover this and the given [SourceRange]s.
- */
- SourceRange getUnion(SourceRange other) {
- int newOffset = math.min(offset, other.offset);
- int newEnd = math.max(offset + length, other.offset + other.length);
- return new SourceRange(newOffset, newEnd - newOffset);
- }
-
- /**
- * @return `true` if this [SourceRange] intersects with given.
- */
- bool intersects(SourceRange other) {
- if (other == null) {
- return false;
- }
- if (end <= other.offset) {
- return false;
- }
- if (offset >= other.end) {
- return false;
- }
- return true;
- }
-
- /**
- * Return `true` if this [SourceRange] starts in the [otherRange].
- */
- bool startsIn(SourceRange otherRange) => otherRange.contains(offset);
-
- @override
- String toString() => '[offset=$offset, length=$length]';
-}
-
-/**
* The abstract class `UriResolver` defines the behavior of objects that are used to resolve
* URI's for a source factory. Subclasses of this class are expected to resolve a single scheme of
* absolute URI.
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 06b9b36..16ad79b 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -103,12 +103,6 @@
return ft.parameters.any((p) => predicate(p.type));
}
- FunctionType functionTypeToConcreteType(FunctionType t) =>
- _replaceDynamicParameters(t, typeProvider.objectType);
-
- FunctionType functionTypeToFuzzyType(FunctionType t) =>
- _replaceDynamicParameters(t, typeProvider.nullType);
-
/// Given a type t, if t is an interface type with a call method
/// defined, return the function type for the call method, otherwise
/// return null.
@@ -445,12 +439,6 @@
}
}
- // A fuzzy arrow subtype
- if (toType is FunctionType &&
- isSubtypeOf(fromType, functionTypeToFuzzyType(toType))) {
- return true;
- }
-
if (isDeclarationCast) {
if (!declarationCasts) {
return false;
@@ -487,14 +475,6 @@
return true;
}
- // A reverse fuzzy arrow subtype. We want to disallow this soon, but
- // we have to let this pass for now because of
- // https://github.com/dart-lang/sdk/issues/32114
- if (fromType is FunctionType &&
- isSubtypeOf(toType, functionTypeToFuzzyType(fromType))) {
- return true;
- }
-
return false;
}
@@ -804,9 +784,6 @@
}
/// Check that [f1] is a subtype of [f2].
- ///
- /// This will always assume function types use fuzzy arrows, in other words
- /// that dynamic parameters of f1 and f2 are treated as bottom.
bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2) {
return FunctionTypeImpl.relate(f1, f2, isSubtypeOf, instantiateToBounds,
parameterRelation: (p1, p2) => isSubtypeOf(p2.type, p1.type));
@@ -959,31 +936,6 @@
return _isFunctionSubtypeOf(t1, t2);
}
- FunctionType _replaceDynamicParameters(FunctionType t, DartType replaceWith) {
- if (!t.parameters.any((p) => p.type.isDynamic)) {
- return t;
- }
- ParameterElement shave(ParameterElement p) {
- if (p.type.isDynamic) {
- return new ParameterElementImpl.synthetic(
- // ignore: deprecated_member_use
- p.name,
- replaceWith,
- // ignore: deprecated_member_use
- p.parameterKind);
- }
- return p;
- }
-
- List<ParameterElement> parameters = t.parameters.map(shave).toList();
- FunctionElementImpl function = new FunctionElementImpl("", -1);
- function.isSynthetic = true;
- function.returnType = t.returnType;
- function.shareTypeParameters(t.typeFormals);
- function.shareParameters(parameters);
- return function.type = new FunctionTypeImpl(function);
- }
-
DartType _substituteForUnknownType(DartType type, {bool lowerBound: false}) {
if (identical(type, UnknownInferredType.instance)) {
if (lowerBound) {
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 302e7fc..8f774d5 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -208,7 +208,7 @@
}
}
-/// Filtered lints are ommitted from linter output.
+/// Filtered lints are omitted from linter output.
abstract class LintFilter {
bool filter(AnalysisError lint);
}
diff --git a/pkg/analyzer/lib/src/lint/options_rule_validator.dart b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
index 622aa31..2d6911a 100644
--- a/pkg/analyzer/lib/src/lint/options_rule_validator.dart
+++ b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/plugin/options.dart';
import 'package:analyzer/src/lint/registry.dart';
+import 'package:analyzer/src/plugin/options.dart';
import 'package:analyzer/src/util/yaml.dart';
import 'package:yaml/yaml.dart';
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index fc652f0..7d5a4a3 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -3,15 +3,15 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/error/error.dart' show AnalysisError;
-import 'package:analyzer/plugin/task.dart';
import 'package:analyzer/src/generated/engine.dart'
show InternalAnalysisContext;
+import 'package:analyzer/src/plugin/task.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/dart_work_manager.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/src/task/html_work_manager.dart';
import 'package:analyzer/src/task/options_work_manager.dart';
-import 'package:analyzer/task/model.dart';
import 'package:plugin/plugin.dart';
/**
@@ -172,8 +172,8 @@
/**
* Annotation describing the relationship between a getter in [EnginePlugin]
- * and the associated identifier (in '../../plugin/task.dart') which can be
- * passed to the extension manager to populate it.
+ * and the associated identifier (in 'task.dart') which can be passed to the
+ * extension manager to populate it.
*
* This annotation is not used at runtime; it is used to aid in static analysis
* of the task model during development.
diff --git a/pkg/analyzer/lib/plugin/options.dart b/pkg/analyzer/lib/src/plugin/options.dart
similarity index 100%
rename from pkg/analyzer/lib/plugin/options.dart
rename to pkg/analyzer/lib/src/plugin/options.dart
diff --git a/pkg/analyzer/lib/plugin/task.dart b/pkg/analyzer/lib/src/plugin/task.dart
similarity index 96%
rename from pkg/analyzer/lib/plugin/task.dart
rename to pkg/analyzer/lib/src/plugin/task.dart
index a9059af..8292485 100644
--- a/pkg/analyzer/lib/plugin/task.dart
+++ b/pkg/analyzer/lib/src/plugin/task.dart
@@ -6,11 +6,9 @@
* Support for client code that extends the analysis engine by adding new
* analysis tasks.
*/
-library analyzer.plugin.task;
-
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/plugin/engine_plugin.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:plugin/plugin.dart';
/**
diff --git a/pkg/analyzer/lib/src/source/custom_resolver.dart b/pkg/analyzer/lib/src/source/custom_resolver.dart
new file mode 100644
index 0000000..c50c77e
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/custom_resolver.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+class CustomUriResolver extends UriResolver {
+ final ResourceProvider resourceProvider;
+ final Map<String, String> _urlMappings;
+
+ CustomUriResolver(this.resourceProvider, this._urlMappings);
+
+ @override
+ Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+ String mapping = _urlMappings[uri.toString()];
+ if (mapping == null) {
+ return null;
+ }
+ Uri fileUri = new Uri.file(mapping);
+ if (!fileUri.isAbsolute) {
+ return null;
+ }
+ return resourceProvider
+ .getFile(resourceProvider.pathContext.fromUri(fileUri))
+ .createSource(actualUri ?? uri);
+ }
+}
diff --git a/pkg/analyzer/lib/src/source/package_map_provider.dart b/pkg/analyzer/lib/src/source/package_map_provider.dart
new file mode 100644
index 0000000..dff066c
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/package_map_provider.dart
@@ -0,0 +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.
+
+import 'package:analyzer/file_system/file_system.dart';
+
+/**
+ * Data structure output by PackageMapProvider. This contains both the package
+ * map and dependency information.
+ */
+class PackageMapInfo {
+ /**
+ * The package map itself. This is a map from package name to a list of
+ * the folders containing source code for the package.
+ *
+ * `null` if an error occurred.
+ */
+ Map<String, List<Folder>> packageMap;
+
+ /**
+ * Dependency information. This is a set of the paths which were consulted
+ * in order to generate the package map. If any of these files is
+ * modified, the package map will need to be regenerated.
+ */
+ Set<String> dependencies;
+
+ PackageMapInfo(this.packageMap, this.dependencies);
+}
+
+/**
+ * A PackageMapProvider is an entity capable of determining the mapping from
+ * package name to source directory for a given folder.
+ */
+abstract class PackageMapProvider {
+ /**
+ * Compute a package map for the given folder, if possible.
+ *
+ * If a package map can't be computed (e.g. because an error occurred), a
+ * [PackageMapInfo] will still be returned, but its packageMap will be null.
+ */
+ PackageMapInfo computePackageMap(Folder folder);
+}
diff --git a/pkg/analyzer/lib/src/source/path_filter.dart b/pkg/analyzer/lib/src/source/path_filter.dart
new file mode 100644
index 0000000..c43cae1
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/path_filter.dart
@@ -0,0 +1,75 @@
+// 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:analyzer/src/util/glob.dart';
+import 'package:path/path.dart' as path;
+
+/// Filter paths against a set of [_ignorePatterns] relative to a [root]
+/// directory. Paths outside of [root] are also ignored.
+class PathFilter {
+ /// The path context to use when manipulating paths.
+ final path.Context pathContext;
+
+ /// Path that all ignore patterns are relative to.
+ final String root;
+
+ /// List of ignore patterns that paths are tested against.
+ final List<Glob> _ignorePatterns = new List<Glob>();
+
+ /// Construct a new path filter rooted at [root] with [ignorePatterns].
+ /// If [pathContext] is not specified, then the system path context is used.
+ PathFilter(this.root, List<String> ignorePatterns, [path.Context pathContext])
+ : this.pathContext = pathContext ?? path.context {
+ setIgnorePatterns(ignorePatterns);
+ }
+
+ /// Returns true if [path] should be ignored. A path is ignored if it is not
+ /// contained in [root] or matches one of the ignore patterns.
+ /// [path] is absolute or relative to [root].
+ bool ignored(String path) {
+ path = _canonicalize(path);
+ return !_contained(path) || _match(path);
+ }
+
+ /// Set the ignore patterns.
+ void setIgnorePatterns(List<String> ignorePatterns) {
+ _ignorePatterns.clear();
+ if (ignorePatterns != null) {
+ for (var ignorePattern in ignorePatterns) {
+ _ignorePatterns.add(new Glob(pathContext.separator, ignorePattern));
+ }
+ }
+ }
+
+ @override
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ for (Glob pattern in _ignorePatterns) {
+ sb.write('$pattern ');
+ }
+ sb.writeln('');
+ return sb.toString();
+ }
+
+ /// Returns the absolute path of [path], relative to [root].
+ String _canonicalize(String path) =>
+ pathContext.normalize(pathContext.join(root, path));
+
+ /// Returns true when [path] is contained inside [root].
+ bool _contained(String path) => path.startsWith(root);
+
+ /// Returns true if [path] matches any ignore patterns.
+ bool _match(String path) {
+ path = _relative(path);
+ for (Glob glob in _ignorePatterns) {
+ if (glob.matches(path)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// Returns the relative portion of [path] from [root].
+ String _relative(String path) => pathContext.relative(path, from: root);
+}
diff --git a/pkg/analyzer/lib/src/source/pub_package_map_provider.dart b/pkg/analyzer/lib/src/source/pub_package_map_provider.dart
new file mode 100644
index 0000000..bcff683
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/pub_package_map_provider.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:core';
+import 'dart:io' as io;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/source/package_map_provider.dart';
+
+/**
+ * The function used to run pub list.
+ */
+typedef io.ProcessResult RunPubList(Folder folder);
+
+/**
+ * Implementation of PackageMapProvider that operates by executing pub.
+ */
+class PubPackageMapProvider implements PackageMapProvider {
+ static const String PUB_LIST_COMMAND = 'list-package-dirs';
+
+ /**
+ * The name of the 'pubspec.lock' file, which we assume is the dependency
+ * in the event that [PUB_LIST_COMMAND] fails.
+ */
+ static const String PUBSPEC_LOCK_NAME = 'pubspec.lock';
+
+ /**
+ * [ResourceProvider] that is used to create the [Folder]s that populate the
+ * package map.
+ */
+ final ResourceProvider resourceProvider;
+
+ /**
+ * Sdk that we use to find the pub executable.
+ */
+ final FolderBasedDartSdk sdk;
+
+ /**
+ * The function used to run pub list.
+ */
+ RunPubList _runPubList;
+
+ /**
+ * Construct a new instance.
+ * A [RunPubList] implementation may be injected for testing
+ */
+ PubPackageMapProvider(this.resourceProvider, this.sdk, [this._runPubList]) {
+ if (_runPubList == null) {
+ _runPubList = _runPubListDefault;
+ }
+ }
+
+ @override
+ PackageMapInfo computePackageMap(Folder folder) {
+ // If the pubspec.lock file does not exist, no need to run anything.
+ {
+ String lockPath = getPubspecLockPath(folder);
+ if (!resourceProvider.getFile(lockPath).exists) {
+ return computePackageMapError(folder);
+ }
+ }
+ // TODO(paulberry) make this asynchronous so that we can (a) do other
+ // analysis while it's in progress, and (b) time out if it takes too long
+ // to respond.
+ io.ProcessResult result;
+ try {
+ result = _runPubList(folder);
+ } on io.ProcessException catch (exception, stackTrace) {
+ AnalysisEngine.instance.logger.logInformation(
+ "Error running pub $PUB_LIST_COMMAND\n$exception\n$stackTrace");
+ }
+ if (result == null || result.exitCode != 0) {
+ String exitCode =
+ result != null ? 'exit code ${result.exitCode}' : 'null';
+ AnalysisEngine.instance.logger
+ .logInformation("pub $PUB_LIST_COMMAND failed: $exitCode");
+ return computePackageMapError(folder);
+ }
+ try {
+ PackageMapInfo packageMap =
+ parsePackageMap(json.decode(result.stdout), folder);
+ return packageMap;
+ } catch (exception, stackTrace) {
+ AnalysisEngine.instance.logger.logError(
+ "Malformed output from pub $PUB_LIST_COMMAND\n$exception\n$stackTrace");
+ }
+
+ return computePackageMapError(folder);
+ }
+
+ /**
+ * Create a PackageMapInfo object representing an error condition.
+ */
+ PackageMapInfo computePackageMapError(Folder folder) {
+ // Even if an error occurs, we still need to know the dependencies, so that
+ // we'll know when to try running "pub list-package-dirs" again.
+ // Unfortunately, "pub list-package-dirs" doesn't tell us dependencies when
+ // an error occurs, so just assume there is one dependency, "pubspec.lock".
+ String lockPath = getPubspecLockPath(folder);
+ List<String> dependencies = <String>[lockPath];
+ return new PackageMapInfo(null, dependencies.toSet());
+ }
+
+ /**
+ * Return the path to the `pubspec.lock` file in the given [folder].
+ */
+ String getPubspecLockPath(Folder folder) =>
+ resourceProvider.pathContext.join(folder.path, PUBSPEC_LOCK_NAME);
+
+ /**
+ * Decode the JSON output from pub into a package map. Paths in the
+ * output are considered relative to [folder].
+ */
+ PackageMapInfo parsePackageMap(Map obj, Folder folder) {
+ // The output of pub looks like this:
+ // {
+ // "packages": {
+ // "foo": "path/to/foo",
+ // "bar": ["path/to/bar1", "path/to/bar2"],
+ // "myapp": "path/to/myapp", // self link is included
+ // },
+ // "input_files": [
+ // "path/to/myapp/pubspec.lock"
+ // ]
+ // }
+ Map<String, List<Folder>> packageMap = new HashMap<String, List<Folder>>();
+ Map packages = obj['packages'];
+ processPaths(String packageName, List paths) {
+ List<Folder> folders = <Folder>[];
+ for (var path in paths) {
+ if (path is String) {
+ Resource resource = folder.getChildAssumingFolder(path);
+ if (resource is Folder) {
+ folders.add(resource);
+ }
+ }
+ }
+ if (folders.isNotEmpty) {
+ packageMap[packageName] = folders;
+ }
+ }
+
+ packages.forEach((key, value) {
+ if (value is String) {
+ processPaths(key, [value]);
+ } else if (value is List) {
+ processPaths(key, value);
+ }
+ });
+ Set<String> dependencies = new Set<String>();
+ List inputFiles = obj['input_files'];
+ if (inputFiles != null) {
+ for (var path in inputFiles) {
+ if (path is String) {
+ dependencies.add(folder.canonicalizePath(path));
+ }
+ }
+ }
+ return new PackageMapInfo(packageMap, dependencies);
+ }
+
+ /**
+ * Run pub list to determine the packages and input files.
+ */
+ io.ProcessResult _runPubListDefault(Folder folder) {
+ String executablePath = sdk.pubExecutable.path;
+ List<String> arguments = [PUB_LIST_COMMAND];
+ String workingDirectory = folder.path;
+ int subprocessId = AnalysisEngine.instance.instrumentationService
+ .logSubprocessStart(executablePath, arguments, workingDirectory);
+ io.ProcessResult result = io.Process
+ .runSync(executablePath, arguments, workingDirectory: workingDirectory);
+ AnalysisEngine.instance.instrumentationService.logSubprocessResult(
+ subprocessId, result.exitCode, result.stdout, result.stderr);
+ return result;
+ }
+}
diff --git a/pkg/analyzer/lib/src/source/sdk_ext.dart b/pkg/analyzer/lib/src/source/sdk_ext.dart
new file mode 100644
index 0000000..30be82a
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/sdk_ext.dart
@@ -0,0 +1,205 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:core';
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
+import 'package:analyzer/src/source/package_map_provider.dart'
+ show PackageMapProvider;
+import 'package:path/path.dart' as pathos;
+
+/// Given a packageMap (see [PackageMapProvider]), check in each package's lib
+/// directory for the existence of a `_sdkext` file. This file must contain a
+/// JSON encoded map. Each key in the map is a `dart:` library name. Each value
+/// is a path (relative to the directory containing `_sdkext`) to a dart script
+/// for the given library. For example:
+/// {
+/// "dart:sky": "../sdk_ext/dart_sky.dart"
+/// }
+///
+/// If a key doesn't begin with `dart:` it is ignored.
+class SdkExtUriResolver extends UriResolver {
+ static const String SDK_EXT_NAME = '_sdkext';
+ static const String DART_COLON_PREFIX = 'dart:';
+
+ final Map<String, String> _urlMappings = <String, String>{};
+
+ /**
+ * The absolute paths of the extension files that contributed to the
+ * [_urlMappings].
+ */
+ final List<String> extensionFilePaths = <String>[];
+
+ /// Construct a [SdkExtUriResolver] from a package map
+ /// (see [PackageMapProvider]).
+ SdkExtUriResolver(Map<String, List<Folder>> packageMap) {
+ if (packageMap == null) {
+ return;
+ }
+ packageMap.forEach(_processPackage);
+ }
+
+ /// Number of sdk extensions.
+ int get length => _urlMappings.length;
+
+ /**
+ * Return a table mapping the names of extensions to the paths where those
+ * extensions can be found.
+ */
+ Map<String, String> get urlMappings =>
+ new Map<String, String>.from(_urlMappings);
+
+ /// Return the path mapping for [libName] or null if there is none.
+ String operator [](String libName) => _urlMappings[libName];
+
+ /// Programmatically add a new SDK extension given a JSON description
+ /// ([sdkExtJSON]) and a lib directory ([libDir]).
+ void addSdkExt(String sdkExtJSON, Folder libDir) {
+ _processSdkExt(sdkExtJSON, libDir);
+ }
+
+ @override
+ Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
+ String libraryName = _libraryName(importUri);
+ String partPath = _partPath(importUri);
+ // Lookup library name in mappings.
+ String mapping = _urlMappings[libraryName];
+ if (mapping == null) {
+ // Not found.
+ return null;
+ }
+ // This mapping points to the main entry file of the sdk extension.
+ Uri libraryEntry = new Uri.file(mapping);
+ if (!libraryEntry.isAbsolute) {
+ // We expect an absolute path.
+ return null;
+ }
+
+ if (partPath != null) {
+ return _resolvePart(libraryEntry, partPath, importUri);
+ } else {
+ return _resolveEntry(libraryEntry, importUri);
+ }
+ }
+
+ @override
+ Uri restoreAbsolute(Source source) {
+ String extensionName = _findExtensionNameFor(source.fullName);
+ if (extensionName != null) {
+ return Uri.parse(extensionName);
+ }
+ // TODO(johnmccutchan): Handle restoring parts.
+ return null;
+ }
+
+ /// Return the extension name for [fullName] or `null`.
+ String _findExtensionNameFor(String fullName) {
+ var result;
+ _urlMappings.forEach((extensionName, pathMapping) {
+ if (pathMapping == fullName) {
+ result = extensionName;
+ }
+ });
+ return result;
+ }
+
+ /// Return the library name of [importUri].
+ String _libraryName(Uri importUri) {
+ var uri = importUri.toString();
+ int index = uri.indexOf('/');
+ if (index >= 0) {
+ return uri.substring(0, index);
+ }
+ return uri;
+ }
+
+ /// Return the part path of [importUri].
+ String _partPath(Uri importUri) {
+ var uri = importUri.toString();
+ int index = uri.indexOf('/');
+ if (index >= 0) {
+ return uri.substring(index + 1);
+ }
+ return null;
+ }
+
+ /// Given a package [name] and a list of folders ([libDirs]),
+ /// add any found sdk extensions.
+ void _processPackage(String name, List<Folder> libDirs) {
+ for (var libDir in libDirs) {
+ var sdkExt = _readDotSdkExt(libDir);
+ if (sdkExt != null) {
+ _processSdkExt(sdkExt, libDir);
+ }
+ }
+ }
+
+ /// Given the JSON for an SDK extension ([sdkExtJSON]) and a folder
+ /// ([libDir]), setup the uri mapping.
+ void _processSdkExt(String sdkExtJSON, Folder libDir) {
+ var sdkExt;
+ try {
+ sdkExt = json.decode(sdkExtJSON);
+ } catch (e) {
+ return;
+ }
+ if ((sdkExt == null) || (sdkExt is! Map)) {
+ return;
+ }
+ bool contributed = false;
+ sdkExt.forEach((k, v) {
+ if (_processSdkExtension(k, v, libDir)) {
+ contributed = true;
+ }
+ });
+ if (contributed) {
+ extensionFilePaths.add(libDir.getChild(SDK_EXT_NAME).path);
+ }
+ }
+
+ /// Install the mapping from [name] to [libDir]/[file].
+ bool _processSdkExtension(String name, String file, Folder libDir) {
+ if (!name.startsWith(DART_COLON_PREFIX)) {
+ // SDK extensions must begin with 'dart:'.
+ return false;
+ }
+ var key = name;
+ var value = libDir.canonicalizePath(file);
+ _urlMappings[key] = value;
+ return true;
+ }
+
+ /// Read the contents of [libDir]/[SDK_EXT_NAME] as a string.
+ /// Returns null if the file doesn't exist.
+ String _readDotSdkExt(Folder libDir) {
+ File file = libDir.getChild(SDK_EXT_NAME);
+ try {
+ return file.readAsStringSync();
+ } on FileSystemException {
+ // File can't be read.
+ return null;
+ }
+ }
+
+ /// Resolve an import of an sdk extension.
+ Source _resolveEntry(Uri libraryEntry, Uri importUri) {
+ // Library entry.
+ JavaFile javaFile = new JavaFile.fromUri(libraryEntry);
+ return new FileBasedSource(javaFile, importUri);
+ }
+
+ /// Resolve a 'part' statement inside an sdk extension.
+ Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) {
+ // Library part.
+ var directory = pathos.dirname(libraryEntry.path);
+ var partUri = new Uri.file(pathos.join(directory, partPath));
+ assert(partUri.isAbsolute);
+ JavaFile javaFile = new JavaFile.fromUri(partUri);
+ return new FileBasedSource(javaFile, importUri);
+ }
+}
diff --git a/pkg/analyzer/lib/src/summary/expr_builder.dart b/pkg/analyzer/lib/src/summary/expr_builder.dart
index 1a57d3c..63bd2b3 100644
--- a/pkg/analyzer/lib/src/summary/expr_builder.dart
+++ b/pkg/analyzer/lib/src/summary/expr_builder.dart
@@ -426,12 +426,12 @@
PropertyAccessorElement _getStringLengthElement() =>
resynthesizer.typeProvider.stringType.getGetter('length');
- FormalParameter _makeParameter(ParameterElementImpl param) {
+ FormalParameter _makeParameter(ParameterElement param) {
SimpleFormalParameterImpl simpleParam =
AstTestFactory.simpleFormalParameter(null, param.name);
simpleParam.identifier.staticElement = param;
simpleParam.element = param;
- var unlinkedParam = param.unlinkedParam;
+ var unlinkedParam = (param as ParameterElementImpl).unlinkedParam;
if (unlinkedParam.kind == UnlinkedParamKind.positional) {
return AstTestFactory.positionalFormalParameter(simpleParam, null);
} else if (unlinkedParam.kind == UnlinkedParamKind.named) {
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 7554f34..fa604ed 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -4130,6 +4130,27 @@
@override
bool get isExplicitlyCovariant => enclosingElement.variable.isCovariant;
+ bool get isInitializingFormal => unlinkedParam.isInitializingFormal;
+
+ @override
+ bool get isNamed => parameterKind == ParameterKind.NAMED;
+
+ @override
+ bool get isNotOptional => parameterKind == ParameterKind.REQUIRED;
+
+ @override
+ bool get isOptional =>
+ parameterKind == ParameterKind.NAMED ||
+ parameterKind == ParameterKind.POSITIONAL;
+
+ @override
+ bool get isOptionalPositional => parameterKind == ParameterKind.POSITIONAL;
+
+ @override
+ bool get isPositional =>
+ parameterKind == ParameterKind.POSITIONAL ||
+ parameterKind == ParameterKind.REQUIRED;
+
@override
bool get isSynthetic => true;
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 1b88697..3744121 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -13,10 +13,10 @@
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
import 'package:front_end/src/base/source.dart';
/**
diff --git a/pkg/analyzer/lib/src/summary/prelink.dart b/pkg/analyzer/lib/src/summary/prelink.dart
index e3c4401..15c4b7c 100644
--- a/pkg/analyzer/lib/src/summary/prelink.dart
+++ b/pkg/analyzer/lib/src/summary/prelink.dart
@@ -62,6 +62,33 @@
}
/**
+ * A node in computing exported namespaces.
+ */
+class _ExportNamespace {
+ static int nextId = 0;
+
+ /**
+ * The export namespace, full (with all exports included), or partial (with
+ * public namespace, and only some of the exports included).
+ */
+ final _Namespace namespace;
+
+ /**
+ * This field is set to non-zero when we start computing the export namespace
+ * for the corresponding library, and is set back to zero when we finish
+ * computation.
+ */
+ int id = 0;
+
+ /**
+ * Whether the [namespace] is full, so we don't need chasing exports.
+ */
+ bool isFull = false;
+
+ _ExportNamespace(this.namespace);
+}
+
+/**
* A [_Meaning] stores all the information necessary to find the declaration
* referred to by a name in a namespace.
*/
@@ -230,6 +257,11 @@
*/
final List<_Namespace> dependencyToPublicNamespace = <_Namespace>[];
+ /**
+ * Map from absolute URI of a library to its export namespace.
+ */
+ final Map<String, _ExportNamespace> exportNamespaces = {};
+
_Prelinker(this.definingUnitUri, this.definingUnit, this.getPart,
this.getImport, this.getDeclaredVariable) {
partCache[definingUnitUri] = definingUnit;
@@ -296,35 +328,76 @@
* information from the library and the transitive closure of its exports.
*/
_Namespace computeExportNamespace(String absoluteUri) {
- Set<String> seenUris = new Set<String>();
- _Namespace chaseExports(String absoluteUri, NameFilter filter) {
- _Namespace exportedNamespace = aggregatePublicNamespace(absoluteUri);
- if (seenUris.add(absoluteUri)) {
- UnlinkedPublicNamespace publicNamespace = getImportCached(absoluteUri);
- if (publicNamespace != null) {
- for (UnlinkedExportPublic export in publicNamespace.exports) {
- String unlinkedExportUri =
- _selectUri(export.uri, export.configurations);
- String exportUri = resolveUri(absoluteUri, unlinkedExportUri);
- if (exportUri != null) {
- NameFilter newFilter = filter.merge(
- new NameFilter.forUnlinkedCombinators(export.combinators));
- _Namespace exportNamespace = chaseExports(exportUri, newFilter);
- exportNamespace.forEach((String name, _Meaning meaning) {
- if (newFilter.accepts(name) &&
- !exportedNamespace.definesLibraryName(name)) {
- exportedNamespace.add(name, meaning);
- }
- });
+ int firstCycleIdOfLastCall = 0;
+ _Namespace chaseExports(String absoluteUri) {
+ _ExportNamespace exportNamespace = getExportNamespace(absoluteUri);
+
+ // If the export namespace is ready, return it.
+ if (exportNamespace.isFull) {
+ firstCycleIdOfLastCall = 0;
+ return exportNamespace.namespace;
+ }
+
+ // If we are computing the export namespace for this library, and we
+ // reached here, then we found a cycle.
+ if (exportNamespace.id != 0) {
+ firstCycleIdOfLastCall = exportNamespace.id;
+ return null;
+ }
+
+ // Give each library a unique identifier.
+ exportNamespace.id = _ExportNamespace.nextId++;
+
+ // Append from exports.
+ int firstCycleId = 0;
+ UnlinkedPublicNamespace publicNamespace = getImportCached(absoluteUri);
+ if (publicNamespace != null) {
+ for (UnlinkedExportPublic export in publicNamespace.exports) {
+ String unlinkedExportUri =
+ _selectUri(export.uri, export.configurations);
+ String exportUri = resolveUri(absoluteUri, unlinkedExportUri);
+ if (exportUri != null) {
+ NameFilter filter =
+ new NameFilter.forUnlinkedCombinators(export.combinators);
+ _Namespace exported = chaseExports(exportUri);
+ exported?.forEach((String name, _Meaning meaning) {
+ if (filter.accepts(name) &&
+ !exportNamespace.namespace.definesLibraryName(name)) {
+ exportNamespace.namespace.add(name, meaning);
+ }
+ });
+ if (firstCycleIdOfLastCall != 0) {
+ if (firstCycleId == 0 || firstCycleId > firstCycleIdOfLastCall) {
+ firstCycleId = firstCycleIdOfLastCall;
+ }
}
}
}
- seenUris.remove(absoluteUri);
}
- return exportedNamespace;
+
+ // If this library is the first component of the cycle, then we are at
+ // the beginning of this cycle, and combination of partial export
+ // namespaces of other exported libraries and declarations of this
+ // library is the full export namespace of this library.
+ if (firstCycleId != 0 && firstCycleId == exportNamespace.id) {
+ firstCycleId = 0;
+ }
+
+ // We're done with this library, successfully or not.
+ exportNamespace.id = 0;
+
+ // If no cycle detected in exports, mark the export namespace as full.
+ if (firstCycleId == 0) {
+ exportNamespace.isFull = true;
+ }
+
+ // Return the full or partial result.
+ firstCycleIdOfLastCall = firstCycleId;
+ return exportNamespace.namespace;
}
- return chaseExports(absoluteUri, NameFilter.identity);
+ _ExportNamespace.nextId = 1;
+ return chaseExports(absoluteUri);
}
/**
@@ -431,6 +504,21 @@
}
/**
+ * Return the [_ExportNamespace] for the library with the given [absoluteUri].
+ * The export namespace might be full (will all exports included), or
+ * partial (with public namespace, and only some of the exports included).
+ */
+ _ExportNamespace getExportNamespace(String absoluteUri) {
+ _ExportNamespace exportNamespace = exportNamespaces[absoluteUri];
+ if (exportNamespace == null) {
+ _Namespace publicNamespace = aggregatePublicNamespace(absoluteUri);
+ exportNamespace = new _ExportNamespace(publicNamespace);
+ exportNamespaces[absoluteUri] = exportNamespace;
+ }
+ return exportNamespace;
+ }
+
+ /**
* Wrapper around [getImport] that caches the return value in [importCache].
*/
UnlinkedPublicNamespace getImportCached(String absoluteUri) {
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index e03b7aa..f15fcd2 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -19,6 +19,7 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/expr_builder.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
@@ -82,8 +83,10 @@
});
// Add all the names from [exportNames].
for (LinkedExportName exportName in exportNames) {
- definedNames.putIfAbsent(
- exportName.name, () => buildExportName(exportName));
+ String name = exportName.name;
+ if (!definedNames.containsKey(name)) {
+ definedNames[name] = buildExportName(exportName);
+ }
}
return new Namespace(definedNames);
}
@@ -584,7 +587,12 @@
/**
* The URI of [librarySource].
*/
- String libraryUri;
+ Uri libraryUri;
+
+ /**
+ * The URI of [librarySource].
+ */
+ String libraryUriStr;
/**
* Indicates whether [librarySource] is the `dart:core` library.
@@ -605,8 +613,9 @@
_LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
this.unlinkedUnits, this.librarySource) {
- libraryUri = librarySource.uri.toString();
- isCoreLibrary = libraryUri == 'dart:core';
+ libraryUri = librarySource.uri;
+ libraryUriStr = libraryUri.toString();
+ isCoreLibrary = libraryUriStr == 'dart:core';
}
@override
@@ -752,28 +761,23 @@
List<String> getReferencedLocationComponents(
int dependencyIndex, int unit, String name) {
if (dependencyIndex == 0) {
- String referencedLibraryUri = libraryUri;
String partUri;
if (unit != 0) {
String uri = unlinkedUnits[0].publicNamespace.parts[unit - 1];
- Source partSource =
- summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
- partUri = partSource.uri.toString();
+ partUri = _resolveRelativeUri(uri);
} else {
- partUri = referencedLibraryUri;
+ partUri = libraryUriStr;
}
- return <String>[referencedLibraryUri, partUri, name];
+ return <String>[libraryUriStr, partUri, name];
}
+
LinkedDependency dependency = linkedLibrary.dependencies[dependencyIndex];
- Source referencedLibrarySource = summaryResynthesizer.sourceFactory
- .resolveUri(librarySource, dependency.uri);
- String referencedLibraryUri = referencedLibrarySource.uri.toString();
+ String referencedLibraryUri = _resolveRelativeUri(dependency.uri);
+
String partUri;
if (unit != 0) {
String uri = dependency.parts[unit - 1];
- Source partSource =
- summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
- partUri = partSource.uri.toString();
+ partUri = _resolveRelativeUri(uri);
} else {
partUri = referencedLibraryUri;
}
@@ -791,6 +795,15 @@
resynthesizedUnits[absoluteUri] = unit;
}
}
+
+ /**
+ * Resolve the [relativeUriStr] against [libraryUri] using Dart rules.
+ */
+ String _resolveRelativeUri(String relativeUriStr) {
+ Uri relativeUri = Uri.parse(relativeUriStr);
+ Uri resolvedUri = resolveRelativeUri(libraryUri, relativeUri);
+ return resolvedUri.toString();
+ }
}
/**
diff --git a/pkg/analyzer/lib/task/dart.dart b/pkg/analyzer/lib/src/task/api/dart.dart
similarity index 98%
rename from pkg/analyzer/lib/task/dart.dart
rename to pkg/analyzer/lib/src/task/api/dart.dart
index d4a651b..44ef9b8 100644
--- a/pkg/analyzer/lib/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/api/dart.dart
@@ -2,16 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.task.dart;
-
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/model.dart';
/**
* The analysis errors associated with a [Source] representing a compilation
diff --git a/pkg/analyzer/lib/task/general.dart b/pkg/analyzer/lib/src/task/api/general.dart
similarity index 90%
rename from pkg/analyzer/lib/task/general.dart
rename to pkg/analyzer/lib/src/task/api/general.dart
index c40ff4c..2f7ab11 100644
--- a/pkg/analyzer/lib/task/general.dart
+++ b/pkg/analyzer/lib/src/task/api/general.dart
@@ -2,10 +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.
-library analyzer.task.general;
-
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
/**
* The content of a [Source].
diff --git a/pkg/analyzer/lib/task/html.dart b/pkg/analyzer/lib/src/task/api/html.dart
similarity index 92%
rename from pkg/analyzer/lib/task/html.dart
rename to pkg/analyzer/lib/src/task/api/html.dart
index 9df8394..4005bcc 100644
--- a/pkg/analyzer/lib/task/html.dart
+++ b/pkg/analyzer/lib/src/task/api/html.dart
@@ -2,11 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.task.html;
-
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:html/dom.dart';
/**
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/src/task/api/model.dart
similarity index 100%
rename from pkg/analyzer/lib/task/model.dart
rename to pkg/analyzer/lib/src/task/api/model.dart
diff --git a/pkg/analyzer/lib/task/yaml.dart b/pkg/analyzer/lib/src/task/api/yaml.dart
similarity index 90%
rename from pkg/analyzer/lib/task/yaml.dart
rename to pkg/analyzer/lib/src/task/api/yaml.dart
index 3888bf7..8bfe390 100644
--- a/pkg/analyzer/lib/task/yaml.dart
+++ b/pkg/analyzer/lib/src/task/api/yaml.dart
@@ -2,11 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.task.yaml;
-
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:yaml/yaml.dart';
/**
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index f2e8703..d117708 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -13,6 +13,7 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/dart/ast/ast.dart'
show NamespaceDirectiveImpl, UriBasedDirectiveImpl, UriValidationCode;
@@ -38,6 +39,9 @@
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/plugin/engine_plugin.dart';
import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/src/task/general.dart';
import 'package:analyzer/src/task/html.dart';
@@ -45,9 +49,6 @@
import 'package:analyzer/src/task/model.dart';
import 'package:analyzer/src/task/strong/checker.dart';
import 'package:analyzer/src/task/strong_mode.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
/**
* The [ResultCachingPolicy] for ASTs.
@@ -3075,7 +3076,7 @@
.group(1)
.split(',')
.map((String code) => code.trim().toLowerCase());
- LineInfo_Location location = info.getLocation(match.start);
+ CharacterLocation location = info.getLocation(match.start);
int lineNumber = location.lineNumber;
String beforeMatch = content.substring(
info.getOffsetOfLine(lineNumber - 1),
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 0a56cd8..5225f5e 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.task.dart_work_manager;
-
import 'dart:collection';
import 'package:analyzer/error/error.dart';
@@ -12,10 +10,10 @@
show AnalysisEngine, AnalysisErrorInfo, CacheState, InternalAnalysisContext;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/model.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';
/**
* The manager for Dart specific analysis.
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index c92370d..66eba45 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.task.driver;
-
import 'dart:async';
import 'dart:collection';
@@ -12,9 +10,9 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/inputs.dart';
import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/task/model.dart';
final PerformanceTag analysisDriverProcessOutputs =
_taskDriverTag.createChild('processOutputs');
diff --git a/pkg/analyzer/lib/src/task/general.dart b/pkg/analyzer/lib/src/task/general.dart
index 064fd20..446f14a 100644
--- a/pkg/analyzer/lib/src/task/general.dart
+++ b/pkg/analyzer/lib/src/task/general.dart
@@ -2,13 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.task.general;
-
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
/**
* A task that gets the contents of the source associated with an analysis
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index 76ef914..8de0347e 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.task.html;
-
import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/context/cache.dart';
@@ -12,11 +10,11 @@
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/plugin/engine_plugin.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/html.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/general.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/html.dart';
-import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart';
import 'package:html/parser.dart';
import 'package:source_span/source_span.dart';
diff --git a/pkg/analyzer/lib/src/task/html_work_manager.dart b/pkg/analyzer/lib/src/task/html_work_manager.dart
index d8bc76f..a7038d1 100644
--- a/pkg/analyzer/lib/src/task/html_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/html_work_manager.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.task.html_work_manager;
-
import 'dart:collection';
import 'package:analyzer/error/error.dart';
@@ -12,9 +10,9 @@
show AnalysisEngine, AnalysisErrorInfo, CacheState, InternalAnalysisContext;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/api/html.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/html.dart';
-import 'package:analyzer/task/html.dart';
-import 'package:analyzer/task/model.dart';
/**
* The manager for HTML specific analysis.
diff --git a/pkg/analyzer/lib/src/task/inputs.dart b/pkg/analyzer/lib/src/task/inputs.dart
index 66650c3..d490238 100644
--- a/pkg/analyzer/lib/src/task/inputs.dart
+++ b/pkg/analyzer/lib/src/task/inputs.dart
@@ -4,7 +4,7 @@
import 'dart:collection';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
/**
* A function that converts an object of the type [B] into a [TaskInput].
diff --git a/pkg/analyzer/lib/src/task/manager.dart b/pkg/analyzer/lib/src/task/manager.dart
index 059257f..40778cb 100644
--- a/pkg/analyzer/lib/src/task/manager.dart
+++ b/pkg/analyzer/lib/src/task/manager.dart
@@ -2,12 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.task.manager;
-
import 'dart:collection';
import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
/**
* An object that manages the information about the tasks that have been
diff --git a/pkg/analyzer/lib/src/task/model.dart b/pkg/analyzer/lib/src/task/model.dart
index 4f99b8c..a84a960 100644
--- a/pkg/analyzer/lib/src/task/model.dart
+++ b/pkg/analyzer/lib/src/task/model.dart
@@ -2,11 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.task.model;
-
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/inputs.dart';
-import 'package:analyzer/task/model.dart';
/**
* The default [ResultCachingPolicy], results are never flushed.
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 0c23e88..dcc5210 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -5,9 +5,8 @@
import 'dart:collection';
import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/plugin/options.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -16,10 +15,11 @@
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/options_rule_validator.dart';
import 'package:analyzer/src/lint/registry.dart';
+import 'package:analyzer/src/plugin/options.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/general.dart';
import 'package:analyzer/src/util/yaml.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
import 'package:source_span/source_span.dart';
import 'package:yaml/yaml.dart';
@@ -156,9 +156,6 @@
/// Lazily populated set of error codes (hashed for speedy lookup).
static HashSet<String> _errorCodes;
- /// Lazily populated set of lint codes.
- Set<String> _lintCodes;
-
/// Legal error code names.
static Set<String> get errorCodes {
if (_errorCodes == null) {
@@ -169,6 +166,9 @@
return _errorCodes;
}
+ /// Lazily populated set of lint codes.
+ Set<String> _lintCodes;
+
Set<String> get lintCodes {
if (_lintCodes == null) {
_lintCodes = new Set.from(
diff --git a/pkg/analyzer/lib/src/task/options_work_manager.dart b/pkg/analyzer/lib/src/task/options_work_manager.dart
index d78a21c..fab4ebe 100644
--- a/pkg/analyzer/lib/src/task/options_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/options_work_manager.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.task.options_work_manager;
-
import 'dart:collection';
import 'package:analyzer/error/error.dart';
@@ -11,8 +9,8 @@
import 'package:analyzer/src/generated/engine.dart'
show AnalysisEngine, AnalysisErrorInfo, CacheState, InternalAnalysisContext;
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/task/model.dart';
/// The manager for analysis options specific analysis.
class OptionsWorkManager implements WorkManager {
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index b6f3d3e..6cfa78a 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -72,45 +72,6 @@
return expression.staticType;
}
-bool hasStrictArrow(Expression expression) {
- var element = _getKnownElement(expression);
- return element is FunctionElement || element is MethodElement;
-}
-
-/// Given a generic class [element] find its covariant upper bound, using
-/// the type system [rules].
-///
-/// Unlike [TypeSystem.instantiateToBounds], this will change `dynamic` into
-/// `Object` to work around an issue with fuzzy arrows.
-InterfaceType _getCovariantUpperBound(TypeSystem rules, ClassElement element) {
- var upperBound = rules.instantiateToBounds(element.type) as InterfaceType;
- var typeArgs = upperBound.typeArguments;
- // TODO(jmesserly): remove this. It is a workaround for fuzzy arrows.
- // To prevent extra checks due to fuzzy arrows, we need to instantiate with
- // `Object` rather than `dynamic`. Consider a case like:
- //
- // class C<T> {
- // void forEach(f(T t)) {}
- // }
- //
- // If we try `(dynamic) ~> void <: (T) ~> void` with fuzzy arrows, we will
- // treat `dynamic` as `bottom` and get `(bottom) -> void <: (T) -> void`
- // which indicates that a check is required on the parameter `f`. This check
- // is not sufficient when `T` is `dynamic`, however, because calling a
- // function with a fuzzy arrow type is not safe and requires a dynamic call.
- // See: https://github.com/dart-lang/sdk/issues/29295
- //
- // For all other values of T, the check is unnecessary: it is sound to pass
- // a function that accepts any Object.
- if (typeArgs.any((t) => t.isDynamic)) {
- var newTypeArgs = typeArgs
- .map((t) => t.isDynamic ? rules.typeProvider.objectType : t)
- .toList();
- upperBound = element.type.instantiate(newTypeArgs);
- }
- return upperBound;
-}
-
DartType _elementType(Element e) {
if (e == null) {
// Malformed code - just return dynamic.
@@ -1084,77 +1045,34 @@
/// Returns `true` if the expression is a dynamic function call or method
/// invocation.
bool _isDynamicCall(InvocationExpression call, FunctionType ft) {
- if (ft == null) return true;
- // Dynamic as the parameter type is treated as bottom. A function with
- // a dynamic parameter type requires a dynamic call in general.
- // However, as an optimization, if we have an original definition, we know
- // dynamic is reified as Object - in this case a regular call is fine.
- if (hasStrictArrow(call.function)) {
- return false;
- }
- // TODO(leafp): Get rid of this case when we stop ignoring fuzzy arrows.
- // We're already not doing this everywhere we would need to for soundness
- // (because of generics), but for now we catch most cases here.
- return rules.anyParameterType(ft, (pt) => pt.isDynamic);
+ return ft == null;
}
/// Given an expression [expr] of type [fromType], returns true if an implicit
/// downcast is required, false if it is not, or null if the types are
/// unrelated.
- ///
- /// This also issues fuzzy arrow hints (if any).
bool _checkFunctionTypeCasts(
Expression expr, FunctionType to, DartType fromType) {
- var strict = hasStrictArrow(expr);
- var toFuzzy = rules.functionTypeToFuzzyType(to);
bool callTearoff = false;
FunctionType from;
if (fromType is FunctionType) {
from = fromType;
} else if (fromType is InterfaceType) {
from = rules.getCallMethodType(fromType);
- // Methods are always strict
- strict = true;
callTearoff = true;
}
if (from == null) {
return null; // unrelated
}
- var fromFuzzy = strict ? from : rules.functionTypeToFuzzyType(from);
-
if (rules.isSubtypeOf(from, to)) {
- // Sound subtype, so no fuzzy arrow warning.
- //
- // However we may still need cast, because the from type is fuzzy and the
- // to type isn't. Or if we have an call tearoff.
- return callTearoff || !rules.isSubtypeOf(fromFuzzy, toFuzzy);
- }
-
- // If it's a subtype in the fuzzy system, don't cast, since we do
- // dynamic calls for the check.
- if (rules.isSubtypeOf(fromFuzzy, toFuzzy)) {
- // A subtype in the fuzzy system, but reverse subtype in sound system.
- // This will eventually become a downcast (which will probably fail).
- // But for the transition, it is better to issue a fuzzy arrow hint
- // since we still do the dynamic calls anyway.
- _recordMessage(
- expr, StrongModeCode.USES_DYNAMIC_AS_BOTTOM, [fromType, to]);
+ // Sound subtype.
+ // However we may still need cast if we have a call tearoff.
return callTearoff;
}
if (rules.isSubtypeOf(to, from)) {
- // Assignable in the sound system, but needs cast.
- //
- // Either unrelated in fuzzy system, or already a cast, so just cast
- // and don't warn.
- return true;
- }
-
- // Only assignable with fuzzy arrows, and it needs a cast
- if (rules.isSubtypeOf(toFuzzy, fromFuzzy)) {
- _recordMessage(
- expr, StrongModeCode.USES_DYNAMIC_AS_BOTTOM, [fromType, to]);
+ // Assignable, but needs cast.
return true;
}
@@ -1230,14 +1148,6 @@
/// the AST node.
void _recordImplicitCast(Expression expr, DartType to,
{DartType from, bool opAssign: false}) {
- // We place record some legacy casts on places that had them for fuzzy
- // arrows, but where they aren't required using sound subtyping. We
- // don't want to issue any of the warnings below for these.
- if (rules.isSubtypeOf(from, to)) {
- _markImplicitCast(expr, to, opAssign: opAssign);
- return;
- }
-
// If this is an implicit tearoff, we need to mark the cast, but we don't
// want to warn if it's a legal subtype.
if (from is InterfaceType && rules.acceptsFunctionType(to)) {
@@ -1523,7 +1433,8 @@
if (members.isEmpty) return covariantChecks;
for (var iface in covariantInterfaces) {
- var unsafeSupertype = _getCovariantUpperBound(rules, iface);
+ var unsafeSupertype =
+ rules.instantiateToBounds(iface.type) as InterfaceType;
for (var m in members) {
_findCovariantChecksForMember(m, unsafeSupertype, covariantChecks);
}
diff --git a/pkg/analyzer/lib/src/task/yaml.dart b/pkg/analyzer/lib/src/task/yaml.dart
index 4024039..431cf30 100644
--- a/pkg/analyzer/lib/src/task/yaml.dart
+++ b/pkg/analyzer/lib/src/task/yaml.dart
@@ -2,18 +2,16 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.task.yaml;
-
import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
+import 'package:analyzer/src/task/api/yaml.dart';
import 'package:analyzer/src/task/general.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
-import 'package:analyzer/task/yaml.dart';
import 'package:source_span/source_span.dart';
import 'package:yaml/yaml.dart';
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 48ec171..1444d1b 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -14,7 +14,6 @@
front_end: 0.1.0-alpha.11
glob: ^1.0.3
html: '>=0.12.0 <1.14.0'
- isolate: '>=0.2.2 <2.0.0'
kernel: 0.3.0-alpha.11
meta: ^1.0.2
package_config: '>=0.1.5 <2.0.0'
@@ -23,7 +22,6 @@
source_span: ^1.2.0
watcher: '>=0.9.6 <0.10.0'
yaml: ^2.1.2
- cli_util: ^0.1.0
dev_dependencies:
- test_reflective_loader: ^0.1.0
test: ^0.12.0
+ test_reflective_loader: ^0.1.0
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 4bd1324..746ca53 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -192,7 +192,7 @@
foo(x) => 1;
var v = const A(foo);''');
await computeAnalysisResult(source);
- assertErrors(source, [StrongModeCode.INVALID_CAST_FUNCTION]);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index b2f5e2d..5809f09 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library engine.declaration_resolver_test;
-
import 'dart:async';
import 'package:analyzer/dart/ast/ast.dart';
@@ -14,8 +12,8 @@
import 'package:analyzer/src/generated/declaration_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/dart.dart';
import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/dart.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 59dd90c..043f1a3 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.generated.engine_test;
-
import 'dart:async';
import 'package:analyzer/dart/ast/ast.dart';
@@ -20,7 +18,7 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/string_source.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:html/dom.dart' show Document;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index 7ffd79f..a7b6f00 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -244,8 +244,9 @@
}
@override
- void beginFormalParameter(Token token, MemberKind kind) {
- super.beginFormalParameter(token, kind);
+ void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+ Token varFinalOrConst) {
+ super.beginFormalParameter(token, kind, covariantToken, varFinalOrConst);
begin('FormalParameter');
}
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 8190532..b47a19e 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1453,7 +1453,7 @@
}
@override
- declare(String name, Builder builder, int charOffset, Uri fileUri) {
+ declare(String name, Builder builder, Uri fileUri) {
_locals[name] = builder;
return null;
}
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 0a53f95..0454057 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -2,9 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.generated.scanner_test;
-
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
@@ -79,19 +78,6 @@
@reflectiveTest
class LineInfoTest extends EngineTestCase {
- void test_translate_missing_closing_gt_error() {
- // Ensure that the UnmatchedToken error for missing '>' is translated
- // to the correct analyzer error code.
- // See https://github.com/dart-lang/sdk/issues/30320
- String source = '<!-- @Component(';
- GatheringErrorListener listener = new GatheringErrorListener();
- _scanWithListener(source, listener);
- listener.assertErrorsWithCodes(const [
- ScannerErrorCode.EXPECTED_TOKEN,
- ScannerErrorCode.EXPECTED_TOKEN,
- ]);
- }
-
void test_lineInfo_multilineComment() {
String source = "/*\r\n *\r\n */";
_assertLineInfo(source, [
@@ -149,6 +135,19 @@
lineStarts, orderedEquals([0, 5, 7, 9, fe.Scanner.useFasta ? 12 : 11]));
}
+ void test_translate_missing_closing_gt_error() {
+ // Ensure that the UnmatchedToken error for missing '>' is translated
+ // to the correct analyzer error code.
+ // See https://github.com/dart-lang/sdk/issues/30320
+ String source = '<!-- @Component(';
+ GatheringErrorListener listener = new GatheringErrorListener();
+ _scanWithListener(source, listener);
+ listener.assertErrorsWithCodes(const [
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ]);
+ }
+
void _assertLineInfo(
String source, List<ScannerTest_ExpectedLocation> expectedLocations) {
GatheringErrorListener listener = new GatheringErrorListener();
@@ -159,7 +158,7 @@
int count = expectedLocations.length;
for (int i = 0; i < count; i++) {
ScannerTest_ExpectedLocation expectedLocation = expectedLocations[i];
- LineInfo_Location location = info.getLocation(expectedLocation._offset);
+ CharacterLocation location = info.getLocation(expectedLocation._offset);
expect(location.lineNumber, expectedLocation._lineNumber,
reason: 'Line number in location $i');
expect(location.columnNumber, expectedLocation._columnNumber,
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 0194fd9..b7ead13 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -1533,10 +1533,10 @@
}
''');
await computeAnalysisResult(source);
- _expectInferenceError(
- source,
- [StrongModeCode.COULD_NOT_INFER, StrongModeCode.INVALID_CAST_FUNCTION],
- r'''
+ _expectInferenceError(source, [
+ StrongModeCode.COULD_NOT_INFER,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ ], r'''
Couldn't infer type parameter 'T'.
Tried to infer 'dynamic' for 'T' which doesn't work:
@@ -1704,8 +1704,10 @@
num test(Iterable values) => values.fold(values.first as num, max);
''');
var analysisResult = await computeAnalysisResult(source);
- assertErrors(source,
- [StrongModeCode.COULD_NOT_INFER, StrongModeCode.INVALID_CAST_FUNCTION]);
+ assertErrors(source, [
+ StrongModeCode.COULD_NOT_INFER,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ ]);
verify([source]);
var unit = analysisResult.unit;
var fold = (AstFinder
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index c184019..7781977 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -2,14 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.generated.utilities_test;
-
import 'dart:collection';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
@@ -2549,21 +2548,21 @@
void test_firstLine() {
LineInfo info = new LineInfo(<int>[0, 12, 34]);
- LineInfo_Location location = info.getLocation(4);
+ CharacterLocation location = info.getLocation(4);
expect(location.lineNumber, 1);
expect(location.columnNumber, 5);
}
void test_lastLine() {
LineInfo info = new LineInfo(<int>[0, 12, 34]);
- LineInfo_Location location = info.getLocation(36);
+ CharacterLocation location = info.getLocation(36);
expect(location.lineNumber, 3);
expect(location.columnNumber, 3);
}
void test_middleLine() {
LineInfo info = new LineInfo(<int>[0, 12, 34]);
- LineInfo_Location location = info.getLocation(12);
+ CharacterLocation location = info.getLocation(12);
expect(location.lineNumber, 2);
expect(location.columnNumber, 1);
}
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index 1b53283..00e24ad 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -6,7 +6,7 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/util/yaml.dart';
diff --git a/pkg/analyzer/test/source/error_processor_test.dart b/pkg/analyzer/test/source/error_processor_test.dart
index 7cf74fc..d631f72 100644
--- a/pkg/analyzer/test/source/error_processor_test.dart
+++ b/pkg/analyzer/test/source/error_processor_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analyzer/test/source/package_map_provider_test.dart b/pkg/analyzer/test/source/package_map_provider_test.dart
index 5959e42..7d78522 100644
--- a/pkg/analyzer/test/source/package_map_provider_test.dart
+++ b/pkg/analyzer/test/source/package_map_provider_test.dart
@@ -2,14 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.source.package_map_provider_test;
-
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_provider.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/source/package_map_provider.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/source/path_filter_test.dart b/pkg/analyzer/test/source/path_filter_test.dart
index 172a421..0dcba2e 100644
--- a/pkg/analyzer/test/source/path_filter_test.dart
+++ b/pkg/analyzer/test/source/path_filter_test.dart
@@ -2,9 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.source.path_filter_test;
-
-import 'package:analyzer/source/path_filter.dart';
+import 'package:analyzer/src/source/path_filter.dart';
import 'package:path/path.dart';
import 'package:test/test.dart';
diff --git a/pkg/analyzer/test/source/sdk_ext_test.dart b/pkg/analyzer/test/source/sdk_ext_test.dart
index 0e7fff9..b09c36b 100644
--- a/pkg/analyzer/test/source/sdk_ext_test.dart
+++ b/pkg/analyzer/test/source/sdk_ext_test.dart
@@ -2,11 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.source.sdk_ext_test;
-
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/src/source/sdk_ext.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index 0e60d81..103433e 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.context.abstract_context;
-
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
@@ -14,8 +12,8 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/driver.dart';
-import 'package:analyzer/task/model.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
import 'package:test/test.dart';
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 9fb27cd..01fbb86 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -2,14 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.context.context_builder_test;
-
-import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/command_line/arguments.dart';
import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/context/source.dart';
import 'package:analyzer/src/generated/bazel.dart';
import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index 235e254..32b2cbd 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -12,8 +12,8 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/model.dart';
-import 'package:analyzer/task/model.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index dea470e..14565dc 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.context.context_test;
-
import 'dart:async';
import 'dart:collection';
@@ -25,10 +23,10 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/model.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:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index 3cae769..7dc865f 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -98,6 +98,97 @@
unorderedEquals(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']));
}
+ test_exportedTopLevelDeclarations_cycle() {
+ String a = _p('/aaa/lib/a.dart');
+ String b = _p('/aaa/lib/b.dart');
+ String c = _p('/aaa/lib/c.dart');
+ provider.newFile(a, r'''
+export 'b.dart';
+class A {}
+''');
+ provider.newFile(b, r'''
+export 'c.dart';
+class B {}
+''');
+ provider.newFile(c, r'''
+export 'a.dart';
+class C {}
+''');
+ _assertExportedTopLevelDeclarations(a, ['A', 'B', 'C']);
+
+ // We asked for 'a', and it was computed.
+ // But 'b' and 'c' are not computed, because we detect that there is
+ // cycle with 'a', so we cannot get all exported declarations of 'a'.
+ _assertHasComputedExportedDeclarations([a]);
+ }
+
+ test_exportedTopLevelDeclarations_cycle_anotherOutsideCycle() {
+ String a = _p('/aaa/lib/a.dart');
+ String b = _p('/aaa/lib/b.dart');
+ String c = _p('/aaa/lib/c.dart');
+ String d = _p('/aaa/lib/d.dart');
+ provider.newFile(a, r'''
+export 'b.dart';
+class A {}
+''');
+ provider.newFile(b, r'''
+export 'c.dart';
+class B {}
+''');
+ provider.newFile(c, r'''
+export 'b.dart';
+export 'd.dart';
+class C {}
+''');
+ provider.newFile(d, r'''
+class D {}
+''');
+ _assertExportedTopLevelDeclarations(a, ['A', 'B', 'C', 'D']);
+
+ // To compute 'a' we compute 'b'.
+ // But 'c' is not computed, because of the cycle [b, c].
+ // However 'd' is not a part of a cycle, so it is computed too.
+ _assertHasComputedExportedDeclarations([a, b, d]);
+ }
+
+ test_exportedTopLevelDeclarations_cycle_onSequence() {
+ String a = _p('/aaa/lib/a.dart');
+ String b = _p('/aaa/lib/b.dart');
+ String c = _p('/aaa/lib/c.dart');
+ String d = _p('/aaa/lib/d.dart');
+ String e = _p('/aaa/lib/e.dart');
+ provider.newFile(a, r'''
+export 'b.dart';
+class A {}
+''');
+ provider.newFile(b, r'''
+export 'c.dart';
+class B {}
+''');
+ provider.newFile(c, r'''
+export 'd.dart';
+class C {}
+''');
+ provider.newFile(d, r'''
+export 'e.dart';
+class D {}
+''');
+ provider.newFile(e, r'''
+export 'c.dart';
+class E {}
+''');
+ // We compute 'a'.
+ // To compute it we also compute 'b' and 'c'.
+ // But 'd' and 'e' are not computed, because of the cycle [c, d, e].
+ _assertExportedTopLevelDeclarations(a, ['A', 'B', 'C', 'D', 'E']);
+ _assertHasComputedExportedDeclarations([a, b, c]);
+
+ // We compute 'd', and try to compute 'e', because 'd' needs 'e'; 'e' can
+ // be computed because 'c' is ready, so the cycle [c, d, e] is broken.
+ _assertExportedTopLevelDeclarations(d, ['C', 'D', 'E']);
+ _assertHasComputedExportedDeclarations([a, b, c, d, e]);
+ }
+
test_exportedTopLevelDeclarations_export() {
String a = _p('/aaa/lib/a.dart');
String b = _p('/aaa/lib/b.dart');
@@ -108,10 +199,8 @@
export 'a.dart';
class B {}
''');
- FileState file = fileSystemState.getFileForPath(b);
- Map<String, TopLevelDeclaration> declarations =
- file.exportedTopLevelDeclarations;
- expect(declarations.keys, unorderedEquals(['A', 'B']));
+ _assertExportedTopLevelDeclarations(b, ['A', 'B']);
+ _assertHasComputedExportedDeclarations([a, b]);
}
test_exportedTopLevelDeclarations_export2_show() {
@@ -133,6 +222,7 @@
class C {}
''');
_assertExportedTopLevelDeclarations(c, ['A2', 'B1', 'C']);
+ _assertHasComputedExportedDeclarations([a, b, c]);
}
test_exportedTopLevelDeclarations_export_flushOnChange() {
@@ -763,6 +853,12 @@
expect(_excludeSdk(actual), unorderedEquals(expected));
}
+ void _assertHasComputedExportedDeclarations(List<String> expectedPathList) {
+ FileSystemStateTestView test = fileSystemState.test;
+ expect(test.librariesWithComputedExportedDeclarations.map((f) => f.path),
+ unorderedEquals(expectedPathList));
+ }
+
void _assertIsUnresolvedFile(FileState file) {
expect(file.path, isNull);
expect(file.uri, isNull);
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/assert_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/assert_statement_test.dart
index 6163277..f169558 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/assert_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/assert_statement_test.dart
@@ -12,61 +12,52 @@
class AssertStatementTest extends PartialCodeTest {
buildAll() {
+ List<String> allExceptEof =
+ PartialCodeTest.statementSuffixes.map((t) => t.name).toList();
buildTests(
'assert_statement',
[
new TestDescriptor(
'keyword',
'assert',
- [
- ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.EXPECTED_TOKEN
- ],
- "assert (_s_);",
- allFailing: true),
+ [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ "assert (_s_);"),
new TestDescriptor(
'leftParen',
'assert (',
[
ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_TOKEN,
+ ScannerErrorCode.EXPECTED_TOKEN,
ParserErrorCode.EXPECTED_TOKEN
],
"assert (_s_);",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor(
'condition',
'assert (a',
- [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
"assert (a);",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor(
'comma',
'assert (a,',
- [
- ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.EXPECTED_TOKEN
- ],
- "assert (a, _s_);",
- allFailing: true),
+ [ScannerErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ "assert (a,);",
+ failing: allExceptEof),
new TestDescriptor(
'message',
'assert (a, b',
- [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
"assert (a, b);",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor(
'trailingComma',
'assert (a, b,',
- [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
"assert (a, b,);",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor('rightParen', 'assert (a, b)',
- [ParserErrorCode.EXPECTED_TOKEN], "assert (a, b);",
- allFailing: true),
+ [ParserErrorCode.EXPECTED_TOKEN], "assert (a, b);"),
],
PartialCodeTest.statementSuffixes,
head: 'f() { ',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
index 9ba13da..5f08265 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
@@ -34,12 +34,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class _s_ {}',
- failing: <String>[
- 'typedef',
- 'functionNonVoid',
- 'getter',
- 'setter'
- ]),
+ failing: ['functionNonVoid', 'getter']),
new TestDescriptor('named', 'class A',
[ParserErrorCode.MISSING_CLASS_BODY], 'class A {}'),
new TestDescriptor(
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart
index 75a64f1..799cf53 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart
@@ -12,6 +12,8 @@
class ForEachStatementTest extends PartialCodeTest {
buildAll() {
+ List<String> allExceptEof =
+ PartialCodeTest.statementSuffixes.map((t) => t.name).toList();
//
// Without a preceding 'await', anything that doesn't contain the `in`
// keyword will be interpreted as a normal for statement.
@@ -25,16 +27,21 @@
[
ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_IDENTIFIER,
ScannerErrorCode.EXPECTED_TOKEN
],
- 'for (var a in _s_) {}',
- allFailing: true),
+ 'for (var a in _s_) _s_;',
+ failing: allExceptEof),
new TestDescriptor(
'iterator',
'for (var a in b',
- [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
- 'for (var a in b) {}',
- allFailing: true),
+ [
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ 'for (var a in b) _s_;',
+ failing: allExceptEof),
],
PartialCodeTest.statementSuffixes,
head: 'f() { ',
@@ -46,69 +53,66 @@
buildTests(
'forEach_statement',
[
- new TestDescriptor(
- 'await_keyword',
- 'await for',
- [
- ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_TOKEN,
- ScannerErrorCode.EXPECTED_TOKEN
- ],
- 'await for (_s_ in _s_) {}',
- allFailing: true),
+ new TestDescriptor('await_keyword', 'await for',
+ [ParserErrorCode.EXPECTED_TOKEN], 'await for (_s_ in _s_) _s_;'),
new TestDescriptor(
'await_leftParen',
'await for (',
[
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_TOKEN,
- ScannerErrorCode.EXPECTED_TOKEN
+ ParserErrorCode.EXPECTED_TOKEN
],
- "await for (_s_ in _s_) {}",
- allFailing: true),
+ "await for (_s_ in _s_) _s_;",
+ failing: allExceptEof),
new TestDescriptor(
'await_variableName',
'await for (a',
[
- ParserErrorCode.EXPECTED_TOKEN,
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.EXPECTED_TOKEN,
- ScannerErrorCode.EXPECTED_TOKEN
+ ParserErrorCode.EXPECTED_TOKEN
],
- "await for (a in _s_) {}",
- allFailing: true),
+ "await for (a in _s_) _s_;",
+ failing: allExceptEof),
new TestDescriptor(
'await_typeAndVariableName',
'await for (A a',
[
- ParserErrorCode.EXPECTED_TOKEN,
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.EXPECTED_TOKEN,
- ScannerErrorCode.EXPECTED_TOKEN
+ ParserErrorCode.EXPECTED_TOKEN
],
- "await for (a in _s_) {}",
- allFailing: true),
+ "await for (A a in _s_) _s_;",
+ failing: allExceptEof),
new TestDescriptor(
'await_in',
'await for (A a in',
[
+ ScannerErrorCode.EXPECTED_TOKEN,
ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_TOKEN,
- ScannerErrorCode.EXPECTED_TOKEN
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TOKEN
],
- "await for (a in _s_) {}",
- allFailing: true),
+ "await for (A a in _s_) _s_;",
+ failing: allExceptEof),
new TestDescriptor(
'await_stream',
'await for (A a in b',
- [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
- "await for (a in b) {}",
- allFailing: true),
+ [
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "await for (A a in b) _s_;",
+ failing: allExceptEof),
],
PartialCodeTest.statementSuffixes,
head: 'f() async { ',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/for_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/for_statement_test.dart
index 9aac678..4106cdf 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/for_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/for_statement_test.dart
@@ -18,7 +18,7 @@
'for_statement',
[
new TestDescriptor('keyword', 'for', [ParserErrorCode.EXPECTED_TOKEN],
- 'for (;;) {}'),
+ 'for (;;) _s_;'),
new TestDescriptor(
'emptyParen',
'for ()',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart
index d3764ef..eb6dfc6 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart
@@ -12,6 +12,8 @@
class ImportDirectivesTest extends PartialCodeTest {
buildAll() {
+ List<String> allExceptEof =
+ PartialCodeTest.prePartSuffixes.map((t) => t.name).toList();
buildTests(
'import_directive',
[
@@ -25,6 +27,55 @@
[ParserErrorCode.EXPECTED_TOKEN], "import '';"),
new TestDescriptor('fullUri', "import 'a.dart'",
[ParserErrorCode.EXPECTED_TOKEN], "import 'a.dart';"),
+ new TestDescriptor(
+ 'if',
+ "import 'a.dart' if",
+ [
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_STRING_LITERAL
+ ],
+ "import 'a.dart' if (_s_) '';"),
+ new TestDescriptor(
+ 'ifParen',
+ "import 'a.dart' if (",
+ [
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_STRING_LITERAL,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "import 'a.dart' if (_s_) '';",
+ failing: allExceptEof),
+ new TestDescriptor(
+ 'ifId',
+ "import 'a.dart' if (b",
+ [
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_STRING_LITERAL
+ ],
+ "import 'a.dart' if (b) '';",
+ failing: allExceptEof),
+ new TestDescriptor(
+ 'ifEquals',
+ "import 'a.dart' if (b ==",
+ [
+ ParserErrorCode.EXPECTED_STRING_LITERAL,
+ ParserErrorCode.EXPECTED_TOKEN,
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_STRING_LITERAL
+ ],
+ "import 'a.dart' if (b == '') '';",
+ failing: allExceptEof),
+ new TestDescriptor(
+ 'ifCondition',
+ "import 'a.dart' if (b)",
+ [
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_STRING_LITERAL
+ ],
+ "import 'a.dart' if (b) '';"),
],
PartialCodeTest.prePartSuffixes);
}
diff --git a/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
index db16be7..fde9bac 100644
--- a/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
+++ b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
@@ -7,9 +7,9 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 05648d9..2965261 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.summary.resynthesize_ast_test;
-
import 'dart:async';
import 'package:analyzer/dart/ast/ast.dart';
@@ -22,8 +20,8 @@
import 'package:analyzer/src/summary/summarize_ast.dart';
import 'package:analyzer/src/summary/summarize_elements.dart'
show PackageBundleAssembler;
-import 'package:analyzer/task/dart.dart' show PARSED_UNIT;
-import 'package:analyzer/task/general.dart';
+import 'package:analyzer/src/task/api/dart.dart' show PARSED_UNIT;
+import 'package:analyzer/src/task/api/general.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 5961afb..0362a9f 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -9154,6 +9154,35 @@
''');
}
+ test_setter_inferred_type_conflictingInheritance() async {
+ var library = await checkLibrary('''
+class A {
+ int t;
+}
+class B extends A {
+ double t;
+}
+class C extends A implements B {
+}
+class D extends C {
+ void set t(p) {}
+}
+''');
+ checkElementText(library, r'''
+class A {
+ int t;
+}
+class B extends A {
+ double t;
+}
+class C extends A implements B {
+}
+class D extends C {
+ void set t(dynamic p) {}
+}
+''');
+ }
+
test_setter_inferred_type_nonStatic_implicit_param() async {
var library =
await checkLibrary('class C extends D { void set f(value) {} }'
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 7e36ed3..d6e3c01 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.task.dart_test;
-
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/ast/token.dart';
@@ -21,12 +19,12 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/src/task/strong/ast_properties.dart' as strong_ast;
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
import 'package:front_end/src/scanner/scanner.dart' as fe;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
index cc4fa43..1a83d55 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -20,11 +20,11 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/dart_work_manager.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index 55a613d5..5834950 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -5,10 +5,10 @@
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/src/task/inputs.dart';
import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/task/model.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/task/general_test.dart b/pkg/analyzer/test/src/task/general_test.dart
index 0caea7e..e5e3b2b 100644
--- a/pkg/analyzer/test/src/task/general_test.dart
+++ b/pkg/analyzer/test/src/task/general_test.dart
@@ -4,9 +4,9 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/general.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/task/html_test.dart b/pkg/analyzer/test/src/task/html_test.dart
index 3095299..eb1b24d 100644
--- a/pkg/analyzer/test/src/task/html_test.dart
+++ b/pkg/analyzer/test/src/task/html_test.dart
@@ -2,13 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.task.html_test;
-
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/html.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/html.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/html.dart';
-import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -312,19 +311,19 @@
expect(lineInfo, isNotNull);
{
int offset = code.indexOf('<!DOCTYPE');
- LineInfo_Location location = lineInfo.getLocation(offset);
+ CharacterLocation location = lineInfo.getLocation(offset);
expect(location.lineNumber, 1);
expect(location.columnNumber, 1);
}
{
int offset = code.indexOf('<html>');
- LineInfo_Location location = lineInfo.getLocation(offset);
+ CharacterLocation location = lineInfo.getLocation(offset);
expect(location.lineNumber, 2);
expect(location.columnNumber, 1);
}
{
int offset = code.indexOf('<title>');
- LineInfo_Location location = lineInfo.getLocation(offset);
+ CharacterLocation location = lineInfo.getLocation(offset);
expect(location.lineNumber, 4);
expect(location.columnNumber, 5);
}
diff --git a/pkg/analyzer/test/src/task/html_work_manager_test.dart b/pkg/analyzer/test/src/task/html_work_manager_test.dart
index b09a365..714894a 100644
--- a/pkg/analyzer/test/src/task/html_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/html_work_manager_test.dart
@@ -17,12 +17,12 @@
ChangeNoticeImpl,
InternalAnalysisContext;
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/html.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/src/task/html_work_manager.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/html.dart';
-import 'package:analyzer/task/model.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/task/inputs_test.dart b/pkg/analyzer/test/src/task/inputs_test.dart
index bdbf9ae..7bde7f7 100644
--- a/pkg/analyzer/test/src/task/inputs_test.dart
+++ b/pkg/analyzer/test/src/task/inputs_test.dart
@@ -2,9 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/inputs.dart';
import 'package:analyzer/src/task/model.dart';
-import 'package:analyzer/task/model.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/task/manager_test.dart b/pkg/analyzer/test/src/task/manager_test.dart
index 3a406b0..662e940 100644
--- a/pkg/analyzer/test/src/task/manager_test.dart
+++ b/pkg/analyzer/test/src/task/manager_test.dart
@@ -2,11 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.task.manager_test;
-
import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/task/model.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/task/model_test.dart b/pkg/analyzer/test/src/task/model_test.dart
index e698152..e364dc3 100644
--- a/pkg/analyzer/test/src/task/model_test.dart
+++ b/pkg/analyzer/test/src/task/model_test.dart
@@ -2,12 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.task.model_test;
-
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/model.dart';
-import 'package:analyzer/task/model.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 98a9fcf..0b6ec9f 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -7,15 +7,15 @@
import 'package:analyzer/analyzer.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/registry.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:yaml/yaml.dart';
@@ -255,7 +255,6 @@
removeCode(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER);
removeCode(StrongModeCode.TOP_LEVEL_INSTANCE_METHOD);
removeCode(StrongModeCode.TOP_LEVEL_UNSUPPORTED);
- removeCode(StrongModeCode.USES_DYNAMIC_AS_BOTTOM);
} else if (errorType == TodoCode) {
declaredNames.remove('TODO_REGEX');
}
@@ -544,15 +543,6 @@
''', [AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE]);
}
- test_analyzer_lint_codes_recognized() {
- Registry.ruleRegistry.register(new TestRule());
- validate('''
-analyzer:
- errors:
- fantastic_test_rule: ignore
- ''', []);
- }
-
test_analyzer_language_supported() {
validate('''
analyzer:
@@ -577,6 +567,15 @@
''', [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
}
+ test_analyzer_lint_codes_recognized() {
+ Registry.ruleRegistry.register(new TestRule());
+ validate('''
+analyzer:
+ errors:
+ fantastic_test_rule: ignore
+ ''', []);
+ }
+
test_analyzer_strong_mode_error_code_supported() {
validate('''
analyzer:
diff --git a/pkg/analyzer/test/src/task/options_work_manager_test.dart b/pkg/analyzer/test/src/task/options_work_manager_test.dart
index d8a0ec7..8845781 100644
--- a/pkg/analyzer/test/src/task/options_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/options_work_manager_test.dart
@@ -15,11 +15,11 @@
ChangeNoticeImpl,
InternalAnalysisContext;
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/dart.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/task/options_work_manager.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/model.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index dc58944..3852241 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -482,24 +482,24 @@
void main() {
var a = new A();
bar(a);
- (/*info:DYNAMIC_INVOKE*/bar1(a));
+ (bar1(a));
var b = bar;
- (/*info:DYNAMIC_INVOKE*/b(a));
+ (b(a));
var f1 = foo;
f1("hello");
dynamic f2 = foo;
(/*info:DYNAMIC_INVOKE*/f2("hello"));
- DynFun f3 = /*warning:USES_DYNAMIC_AS_BOTTOM*/foo;
- (/*info:DYNAMIC_INVOKE*/f3("hello"));
- (/*info:DYNAMIC_INVOKE*/f3(42));
+ DynFun f3 = /*error:INVALID_CAST_FUNCTION*/foo;
+ (f3("hello"));
+ (f3(42));
StrFun f4 = foo;
f4("hello");
a.baz1("hello");
var b1 = a.baz1;
- (/*info:DYNAMIC_INVOKE*/b1("hello"));
+ (b1("hello"));
A.baz2("hello");
var b2 = A.baz2;
- (/*info:DYNAMIC_INVOKE*/b2("hello"));
+ (b2("hello"));
dynamic a1 = new B();
(/*info:DYNAMIC_INVOKE*/a1.x);
@@ -673,14 +673,14 @@
/*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(3);
}
{
- A f = /*warning:USES_DYNAMIC_AS_BOTTOM,error:INVALID_CAST_NEW_EXPR*/new B();
+ A f = /*error:INVALID_ASSIGNMENT*/new B();
B b = new B();
- f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/b;
+ f = /* error:INVALID_ASSIGNMENT*/b;
int x;
double y;
- x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
- y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
- /*info:DYNAMIC_INVOKE*/f(3.0);
+ x = /*info:DYNAMIC_CAST*/f(3);
+ y = /*info:DYNAMIC_CAST*/f(3);
+ f(3.0);
}
{
dynamic g = new B();
@@ -688,9 +688,9 @@
/*info:DYNAMIC_INVOKE*/g.col(42.0);
/*info:DYNAMIC_INVOKE*/g.foo(42.0);
/*info:DYNAMIC_INVOKE*/g.x;
- A f = /*warning:USES_DYNAMIC_AS_BOTTOM, error:INVALID_CAST_NEW_EXPR*/new B();
+ A f = /* error:INVALID_ASSIGNMENT*/new B();
B b = new B();
- f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/b;
+ f = /*error:INVALID_ASSIGNMENT*/b;
/*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(42.0);
/*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/foo(42.0);
/*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_GETTER*/x;
@@ -1196,14 +1196,14 @@
{
BotA f;
f = topA;
- f = /*error:INVALID_CAST_FUNCTION*/topTop;
+ f = /*error:INVALID_ASSIGNMENT*/topTop;
f = aa;
f = /*error:INVALID_ASSIGNMENT*/aTop;
f = botA;
f = /*info:DOWN_CAST_COMPOSITE*/botTop;
apply<BotA>(
topA,
- /*error:INVALID_CAST_FUNCTION*/topTop,
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/topTop,
aa,
/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/aTop,
botA,
@@ -1221,14 +1221,14 @@
{
AA f;
f = topA;
- f = /*error:INVALID_CAST_FUNCTION*/topTop;
+ f = /*error:INVALID_ASSIGNMENT*/topTop;
f = aa;
f = /*error:INVALID_CAST_FUNCTION*/aTop; // known function
f = /*info:DOWN_CAST_COMPOSITE*/botA;
f = /*info:DOWN_CAST_COMPOSITE*/botTop;
apply<AA>(
topA,
- /*error:INVALID_CAST_FUNCTION*/topTop,
+ /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/topTop,
aa,
/*error:INVALID_CAST_FUNCTION*/aTop, // known function
/*info:DOWN_CAST_COMPOSITE*/botA,
@@ -1297,212 +1297,6 @@
''');
}
- test_fuzzyArrowLegacyAssignability_GlobalInference() async {
- // Test for legacy fuzzy arrow support on assignability, pending
- // cleanup. https://github.com/dart-lang/sdk/issues/29630
- // Tests impact of https://github.com/dart-lang/sdk/issues/32114
- // on fuzzy arrow warnings
- await checkFile('''
- typedef T Fn<T>(T x);
- typedef T FnB<T extends int>(T x);
-
- class I2i {
- int call(int x) => x;
- }
- class D2i {
- int call(dynamic x) => x as int;
- }
- class I2d {
- dynamic call(int x) => x;
- }
- class D2d {
- dynamic call(dynamic x) => x;
- }
- Fn global0;
- var inferred0 = global0;
- FnB global1;
- var inferred1 = global1;
-
- void test0() {
- int Function(int) i2i;
- int Function(dynamic) d2i;
- dynamic Function(int) i2d;
- dynamic Function(dynamic) d2d;
- I2i ci2i;
- D2i cd2i;
- I2d ci2d;
- D2d cd2d;
-
- {
- var f = inferred0;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2i;
- f = d2i;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2d;
- f = d2d;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/ci2i;
- f = cd2i;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/ci2d;
- f = cd2d;
- }
- {
- var f = inferred1;
- f = i2i;
- f = d2i;
- f = /*info:DOWN_CAST_COMPOSITE*/i2d; // Real downcast
- f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/d2d; // Fuzzy downcast
- f = ci2i;
- f = cd2i;
- f = /*info:DOWN_CAST_COMPOSITE*/ci2d;
- f = /*info:DOWN_CAST_COMPOSITE*/cd2d;
- }
- }
- ''');
- }
-
- test_fuzzyArrowLegacyAssignability() async {
- // Test for legacy fuzzy arrow support on assignability, pending
- // cleanup. https://github.com/dart-lang/sdk/issues/29630
- await checkFile('''
-
- class I2i {
- int call(int x) => x;
- }
- class D2i {
- int call(dynamic x) => x as int;
- }
- class I2d {
- dynamic call(int x) => x;
- }
- class D2d {
- dynamic call(dynamic x) => x;
- }
-
- void test0() {
- int Function(int) i2i;
- int Function(dynamic) d2i;
- dynamic Function(int) i2d;
- dynamic Function(dynamic) d2d;
- I2i ci2i;
- D2i cd2i;
- I2d ci2d;
- D2d cd2d;
-
- {
- int Function(int) f;
- f = i2i;
- f = d2i;
- f = /*info:DOWN_CAST_COMPOSITE*/i2d;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/d2d;
- f = ci2i;
- f = cd2i;
- f = /*info:DOWN_CAST_COMPOSITE*/ci2d;
- f = /*info:DOWN_CAST_COMPOSITE*/cd2d;
- }
- {
- int Function(dynamic) f;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2i;
- f = d2i;
- f = /*info:DOWN_CAST_COMPOSITE*/i2d;
- f = /*info:DOWN_CAST_COMPOSITE*/d2d;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM,info:DOWN_CAST_COMPOSITE*/ci2i;
- f = cd2i;
- f = /*info:DOWN_CAST_COMPOSITE*/ci2d;
- f = /*info:DOWN_CAST_COMPOSITE*/cd2d;
- }
- {
- dynamic Function(int) f;
- f = i2i;
- f = d2i;
- f = i2d;
- f = d2d;
- f = ci2i;
- f = cd2i;
- f = ci2d;
- f = cd2d;
- }
- {
- dynamic Function(dynamic) f;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2i;
- f = d2i;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2d;
- f = d2d;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM,info:DOWN_CAST_COMPOSITE*/ci2i;
- f = cd2i;
- f = /*warning:USES_DYNAMIC_AS_BOTTOM,info:DOWN_CAST_COMPOSITE*/ci2d;
- f = cd2d;
- }
- }
- ''');
- }
-
- test_functionTypingAndSubtyping_dynamicFunctions_closuresAreNotFuzzy() async {
- // Regression test for definite function cases
- // https://github.com/dart-lang/sdk/issues/26118
- // https://github.com/dart-lang/sdk/issues/26156
- // https://github.com/dart-lang/sdk/issues/28087
- await checkFile('''
-void takesF(void f(int x)) {}
-
-typedef void TakesInt(int x);
-
-void update(_) {}
-void updateOpt([_]) {}
-void updateOptNum([num x]) {}
-
-class Callable {
- void call(_) {}
-}
-
-class A {
- TakesInt f;
- A(TakesInt g) {
- f = update;
- f = updateOpt;
- f = updateOptNum;
- f = new Callable();
- }
- TakesInt g(bool a, bool b) {
- if (a) {
- return update;
- } else if (b) {
- return updateOpt;
- } else if (a) {
- return updateOptNum;
- } else {
- return new Callable();
- }
- }
-}
-
-void test0() {
- takesF(update);
- takesF(updateOpt);
- takesF(updateOptNum);
- takesF(new Callable());
- TakesInt f;
- f = update;
- f = updateOpt;
- f = updateOptNum;
- f = new Callable();
- new A(update);
- new A(updateOpt);
- new A(updateOptNum);
- new A(new Callable());
-}
-
-void test1() {
- void takesF(f(int x)) => null;
- takesF(/*info:INFERRED_TYPE_CLOSURE*/(dynamic y) => 3);
-}
-
-void test2() {
- int x;
- int f<T>(T t, callback(T x)) { return 3; }
- f(x, /*info:INFERRED_TYPE_CLOSURE*/(y) => 3);
-}
-''');
- }
-
test_functionTypingAndSubtyping_functionLiteralVariance() async {
await checkFile('''
class A {}
@@ -3228,20 +3022,6 @@
''');
}
- test_leastUpperBounds_fuzzyArrows() async {
- await checkFile(r'''
-typedef String TakesA<T>(T item);
-
-void main() {
- TakesA<int> f;
- TakesA<dynamic> g;
- TakesA<String> h;
- g = /*warning:USES_DYNAMIC_AS_BOTTOM*/h;
- f = f ?? g;
-}
-''');
- }
-
test_loadLibrary() async {
addFile('''library lib1;''', name: '/lib1.dart');
await checkFile(r'''
@@ -4609,11 +4389,6 @@
await super.test_covariantOverride_fields();
}
- @override
- test_fuzzyArrowLegacyAssignability_GlobalInference() async {
- await super.test_fuzzyArrowLegacyAssignability_GlobalInference();
- }
-
@override // Passes with driver
test_interfacesFromMixinsUsedTwiceAreChecked() =>
super.test_interfacesFromMixinsUsedTwiceAreChecked();
diff --git a/pkg/analyzer/test/src/task/test_support.dart b/pkg/analyzer/test/src/task/test_support.dart
index f501e54..7415324 100644
--- a/pkg/analyzer/test/src/task/test_support.dart
+++ b/pkg/analyzer/test/src/task/test_support.dart
@@ -2,11 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.task.test_support;
-
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/task/model.dart';
+import 'package:analyzer/src/task/api/model.dart';
/**
* A configurable analysis task that can be used by tests.
diff --git a/pkg/analyzer/test/src/task/yaml_test.dart b/pkg/analyzer/test/src/task/yaml_test.dart
index 4601360..e8f8352 100644
--- a/pkg/analyzer/test/src/task/yaml_test.dart
+++ b/pkg/analyzer/test/src/task/yaml_test.dart
@@ -2,12 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.task.yaml_test;
-
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/task/api/yaml.dart';
import 'package:analyzer/src/task/yaml.dart';
-import 'package:analyzer/task/general.dart';
-import 'package:analyzer/task/yaml.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:yaml/yaml.dart';
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index f2bbd10..6866377 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -458,16 +458,6 @@
}
@override
- void handleModifier(Token token) {
- debugEvent("Modifier");
- }
-
- @override
- void handleModifiers(int count) {
- debugEvent("Modifiers");
- }
-
- @override
void handleQualified(Token period) {
debugEvent("Qualified");
String suffix = pop();
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index dbb7b1d..e3ddb67 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -199,8 +199,9 @@
TypeProvider typeProvider = await driver.currentSession.typeProvider;
String dartDartPath = path.join(rootDir, 'lib', 'src', 'task', 'dart.dart');
- String taskPath = path.join(rootDir, 'lib', 'plugin', 'task.dart');
- String modelPath = path.join(rootDir, 'lib', 'task', 'model.dart');
+ String taskPath = path.join(rootDir, 'lib', 'src', 'plugin', 'task.dart');
+ String modelPath =
+ path.join(rootDir, 'lib', 'src', 'task', 'api', 'model.dart');
String enginePluginPath =
path.join(rootDir, 'lib', 'src', 'plugin', 'engine_plugin.dart');
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 9dcf36b..ca20983 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -10,11 +10,7 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/package_map_provider.dart';
import 'package:analyzer/source/package_map_resolver.dart';
-import 'package:analyzer/source/path_filter.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
-import 'package:analyzer/source/sdk_ext.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -30,6 +26,10 @@
import 'package:analyzer/src/generated/utilities_general.dart'
show PerformanceTag;
import 'package:analyzer/src/pubspec/pubspec_validator.dart';
+import 'package:analyzer/src/source/package_map_provider.dart';
+import 'package:analyzer/src/source/path_filter.dart';
+import 'package:analyzer/src/source/pub_package_map_provider.dart';
+import 'package:analyzer/src/source/sdk_ext.dart';
import 'package:analyzer/src/source/source_resource.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index cb023c4..0c84618 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -2,9 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer_cli.src.error_formatter;
-
import 'package:analyzer/error/error.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_cli/src/ansi.dart';
@@ -263,7 +262,7 @@
void formatError(
Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
Source source = error.source;
- LineInfo_Location location = errorToLine[error].getLocation(error.offset);
+ CharacterLocation location = errorToLine[error].getLocation(error.offset);
ErrorSeverity severity = _severityProcessor(error);
@@ -324,7 +323,7 @@
void formatError(
Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
Source source = error.source;
- LineInfo_Location location = errorToLine[error].getLocation(error.offset);
+ CharacterLocation location = errorToLine[error].getLocation(error.offset);
int length = error.length;
ErrorSeverity severity = _severityProcessor(error);
diff --git a/pkg/analyzer_cli/lib/src/perf_report.dart b/pkg/analyzer_cli/lib/src/perf_report.dart
index 60acdf1..110fa0f 100644
--- a/pkg/analyzer_cli/lib/src/perf_report.dart
+++ b/pkg/analyzer_cli/lib/src/perf_report.dart
@@ -2,14 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer_cli.src.perf_report;
-
import 'dart:convert' show JsonEncoder;
import 'dart:io' show Platform;
import 'package:analyzer/src/generated/utilities_general.dart'
show PerformanceTag;
-import 'package:analyzer/task/model.dart' show AnalysisTask;
+import 'package:analyzer/src/task/api/model.dart' show AnalysisTask;
import 'package:analyzer_cli/src/error_formatter.dart';
import 'package:analyzer_cli/src/options.dart' show CommandLineOptions;
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index f0e587d..4943ea9 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -9,7 +9,6 @@
analyzer: ^0.27.0
args: '>=0.13.0 <2.0.0'
bazel_worker: ^0.1.0
- cli_util: ^0.1.0
collection: ^1.14.1
linter: ^0.1.16
package_config: '>=0.1.5 <2.0.0'
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 78f7a70..9fb32f4 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -6,8 +6,8 @@
import 'dart:io';
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index 84bd9a3..985464c 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_cli/src/options.dart';
@@ -84,7 +85,7 @@
}
class MockLineInfo implements LineInfo {
- MockLineInfo_Location defaultLocation;
+ CharacterLocation defaultLocation;
MockLineInfo({this.defaultLocation});
@@ -99,7 +100,7 @@
}
@override
- LineInfo_Location getLocation(int offset) {
+ CharacterLocation getLocation(int offset) {
if (defaultLocation != null) {
return defaultLocation;
}
@@ -117,16 +118,6 @@
}
}
-class MockLineInfo_Location implements LineInfo_Location {
- @override
- int lineNumber;
-
- @override
- int columnNumber;
-
- MockLineInfo_Location(this.lineNumber, this.columnNumber);
-}
-
class MockSource implements Source {
@override
String fullName;
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
index 4f4bc85..a86c03d 100644
--- a/pkg/analyzer_cli/test/reporter_test.dart
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer_cli/src/ansi.dart' as ansi;
import 'package:analyzer_cli/src/error_formatter.dart';
@@ -71,7 +72,7 @@
MockAnalysisErrorInfo mockError(ErrorType type, ErrorSeverity severity) {
// ErrorInfo
- var location = new MockLineInfo_Location(3, 3);
+ var location = new CharacterLocation(3, 3);
var lineInfo = new MockLineInfo(defaultLocation: location);
// Details
diff --git a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
index ba03cb8..5778af8 100644
--- a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
+++ b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
@@ -277,9 +277,11 @@
if (json is int) {
return json;
} else if (json is String) {
- return int.parse(json, onError: (String value) {
+ int value = int.tryParse(json);
+ if (value == null) {
throw mismatch(jsonPath, 'int', json);
- });
+ }
+ return value;
}
throw mismatch(jsonPath, 'int', json);
}
diff --git a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
index e562071..66b0ed6 100644
--- a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
+++ b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/error/error.dart' as analyzer;
import 'package:analyzer/exception/exception.dart' as analyzer;
import 'package:analyzer/source/error_processor.dart' as analyzer;
+import 'package:analyzer/source/line_info.dart' as analyzer;
import 'package:analyzer/src/generated/engine.dart' as analyzer;
import 'package:analyzer/src/generated/source.dart' as analyzer;
import 'package:analyzer/src/generated/utilities_dart.dart' as analyzer;
@@ -35,7 +36,7 @@
int startLine = -1;
int startColumn = -1;
if (lineInfo != null) {
- analyzer.LineInfo_Location lineLocation = lineInfo.getLocation(offset);
+ analyzer.CharacterLocation lineLocation = lineInfo.getLocation(offset);
if (lineLocation != null) {
startLine = lineLocation.lineNumber;
startColumn = lineLocation.columnNumber;
@@ -338,7 +339,7 @@
try {
analyzer.LineInfo lineInfo = unitElement.lineInfo;
if (lineInfo != null) {
- analyzer.LineInfo_Location offsetLocation =
+ analyzer.CharacterLocation offsetLocation =
lineInfo.getLocation(range.offset);
startLine = offsetLocation.lineNumber;
startColumn = offsetLocation.columnNumber;
diff --git a/pkg/analyzer_plugin/test/plugin/mocks.dart b/pkg/analyzer_plugin/test/plugin/mocks.dart
index a9ff4d8..1ccb601 100644
--- a/pkg/analyzer_plugin/test/plugin/mocks.dart
+++ b/pkg/analyzer_plugin/test/plugin/mocks.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/timestamped_data.dart';
@@ -22,8 +23,15 @@
Set<String> addedFiles = new HashSet<String>();
MockAnalysisDriver()
- : super(new AnalysisDriverScheduler(null), null, null, null, null, null,
- new SourceFactory([]), new AnalysisOptionsImpl());
+ : super(
+ new AnalysisDriverScheduler(null),
+ null,
+ new MockResourceProvider(),
+ null,
+ new FileContentOverlay(),
+ null,
+ new SourceFactory([]),
+ new AnalysisOptionsImpl());
@override
bool get hasFilesToAnalyze => false;
@@ -115,6 +123,11 @@
}
}
+class MockResourceProvider implements ResourceProvider {
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
/**
* A concrete implementation of a server plugin that is suitable for testing.
*/
diff --git a/pkg/compiler/README.md b/pkg/compiler/README.md
index 6764816..16abf7b 100644
--- a/pkg/compiler/README.md
+++ b/pkg/compiler/README.md
@@ -390,11 +390,6 @@
representation of JSInt31, JSArray, and other implementation-specific
elements.
-* `lib/src/dart2js_resolver.dart`: a script to run the compiler up to resolution
- and to generate a serialized json representation of the element model.
-
- AI: delete.
-
* `lib/src/deferred_load.dart`: general analysis for deferred loading. This is
where we compute how to split the code in different JS chunks or fragments.
This is run after resolution, but at a time when no code is generated yet, so
@@ -608,11 +603,6 @@
* `lib/src/inferrer/map_tracer.dart`
* `lib/src/inferrer/builder.dart`
-* Serialization (`lib/src/serialization/*`: the compiler had support to emit a
- serialized form of the element model. This is likely going to be deleted in
- the near future (it was created before we had the intent to use kernel as a
- serialization format).
-
---------
_TODO: complete the documentation for the following files_.
@@ -782,7 +772,6 @@
`lib/src/js_backend/no_such_method_registry.dart`
`lib/src/js_backend/constant_system_javascript.dart`
`lib/src/js_backend/backend.dart`
-`lib/src/js_backend/backend_serialization.dart`
`lib/src/js_backend/checked_mode_helpers.dart`
`lib/src/js_backend/constant_handler_javascript.dart`
diff --git a/pkg/compiler/lib/compiler_new.dart b/pkg/compiler/lib/compiler_new.dart
index 23dda02..7d0fd23 100644
--- a/pkg/compiler/lib/compiler_new.dart
+++ b/pkg/compiler/lib/compiler_new.dart
@@ -25,7 +25,7 @@
enum InputKind {
/// Data is read as UTF8 either as a [String] or a zero-terminated
/// `List<int>`.
- utf8,
+ UTF8,
/// Data is read as bytes in a `List<int>`.
binary,
@@ -49,7 +49,7 @@
/// Returns a future that completes to the source corresponding to [uri].
/// If an exception occurs, the future completes with this exception.
///
- /// If [inputKind] is `InputKind.utf8` the source can be represented either as
+ /// If [inputKind] is `InputKind.UTF8` the source can be represented either as
/// a zero-terminated `List<int>` of UTF-8 bytes or as a [String]. If
/// [inputKind] is `InputKind.binary` the source is a read a `List<int>`.
///
@@ -59,7 +59,7 @@
/// scanner is more efficient in this case. In either case, the data structure
/// is expected to hold a zero element at the last position. If this is not
/// the case, the entire data structure is copied before scanning.
- Future<Input> readFromUri(Uri uri, {InputKind inputKind: InputKind.utf8});
+ Future<Input> readFromUri(Uri uri, {InputKind inputKind: InputKind.UTF8});
}
/// Output types used in `CompilerOutput.createOutputSink`.
@@ -73,9 +73,6 @@
/// A source map for a JavaScript output.
sourceMap,
- /// Serialization data output.
- serializationData,
-
/// Additional information requested by the user, such dump info or a deferred
/// map.
info,
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index cfeecb1..8ff3879 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -116,7 +116,7 @@
// [Future] to ensure that we never execute an asynchronous action without
// setting up the current element of the compiler.
return new Future.sync(
- () => callUserProvider(resourceUri, api.InputKind.utf8))
+ () => callUserProvider(resourceUri, api.InputKind.UTF8))
.then((api.Input sourceFile) {
// We use [readableUri] as the URI for the script since need to preserve
// the scheme in the script because [Script.uri] is used for resolving
@@ -223,17 +223,6 @@
Future<Null> setupSdk() {
Future future = new Future.value(null);
- if (options.resolutionInputs != null) {
- future = Future.forEach(options.resolutionInputs, (Uri resolutionInput) {
- reporter.log('Reading serialized data from ${resolutionInput}');
- Future<SourceFile> future =
- callUserProvider(resolutionInput, api.InputKind.utf8);
- return future.then((SourceFile sourceFile) {
- serialization.deserializeFromText(
- resolutionInput, sourceFile.slowText());
- });
- });
- }
if (resolvedUriTranslator.isNotSet) {
future = future.then((_) {
return platform_configuration
@@ -276,11 +265,11 @@
timings.writeln("Timings:");
Duration totalDuration = measurer.wallClock.elapsed;
Duration asyncDuration = measurer.asyncWallClock.elapsed;
- Duration cumulatedDuration = Duration.ZERO;
+ Duration cumulatedDuration = Duration.zero;
for (final task in tasks) {
String running = task.isRunning ? "*" : "";
Duration duration = task.duration;
- if (duration != Duration.ZERO) {
+ if (duration != Duration.zero) {
cumulatedDuration += duration;
timings.writeln(' $running${task.name} took'
' ${duration.inMilliseconds}msec');
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index 1c761db..0ab7475 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -8,8 +8,6 @@
import '../constants/expressions.dart' show ConstantExpression;
import '../elements/resolution_types.dart'
show ResolutionDartType, ResolutionInterfaceType;
-import '../serialization/serialization.dart'
- show DeserializerPlugin, SerializerPlugin;
import '../tree/tree.dart' show Node;
import '../universe/world_impact.dart' show WorldImpact;
@@ -45,11 +43,3 @@
return worldImpact;
}
}
-
-/// Interface for serialization of backend specific data.
-class BackendSerialization {
- const BackendSerialization();
-
- SerializerPlugin get serializer => const SerializerPlugin();
- DeserializerPlugin get deserializer => const DeserializerPlugin();
-}
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 3e4bd26..3965ba8 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -151,9 +151,6 @@
Element element, TypeAnnotation node);
/// Returns `true` if [element] has been resolved.
- // TODO(johnniwinther): Normalize semantics between normal and deserialized
- // elements; deserialized elements are always resolved but the method will
- // return `false`.
bool hasBeenResolved(Element element);
/// Resolve [element] if it has not already been resolved.
diff --git a/pkg/compiler/lib/src/common/tasks.dart b/pkg/compiler/lib/src/common/tasks.dart
index 79fc988..5c75e93 100644
--- a/pkg/compiler/lib/src/common/tasks.dart
+++ b/pkg/compiler/lib/src/common/tasks.dart
@@ -49,7 +49,7 @@
}
Duration get duration {
- if (_isDisabled) return Duration.ZERO;
+ if (_isDisabled) return Duration.zero;
Duration total = _watch.elapsed;
for (GenericTask subtask in _subtasks.values) {
total += subtask.duration;
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 693f8fd..8a93589 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -199,9 +199,6 @@
}
if (element.hasConstant) {
if (element.constant != null) {
- if (compiler.serialization.supportsDeserialization) {
- evaluate(element.constant);
- }
assert(
hasConstantValue(element.constant),
failedAt(
@@ -331,11 +328,6 @@
expression != null,
failedAt(CURRENT_ELEMENT_SPANNABLE,
"ConstantExpression is null in getConstantValue."));
- // TODO(johnniwinther): ensure expressions have been evaluated at this
- // point. This can't be enabled today due to dartbug.com/26406.
- if (compiler.serialization.supportsDeserialization) {
- evaluate(expression);
- }
ConstantValue value = constantValueMap[expression];
if (value == null &&
expression != null &&
@@ -971,16 +963,6 @@
if (constructor.isFromEnvironmentConstructor) {
return createFromEnvironmentConstant(node, constructedType, constructor,
callStructure, normalizedArguments, concreteArguments);
- } else if (compiler.serialization.isDeserialized(constructor)) {
- ConstructedConstantExpression expression =
- new ConstructedConstantExpression(type, constructor, callStructure,
- concreteArguments.map((c) => c.expression).toList());
- return new AstConstant(
- context,
- node,
- expression,
- expression.evaluate(
- new AstEvaluationEnvironment(compiler), constantSystem));
} else {
return makeConstructedConstant(
compiler,
@@ -1262,30 +1244,13 @@
CallStructure callStructure, ConstructorElement targetConstructor) {
ResolutionInterfaceType type =
constructedType.asInstanceOf(targetConstructor.enclosingClass);
- if (compiler.serialization.isDeserialized(targetConstructor)) {
- List<ConstantExpression> arguments =
- compiledArguments.map((c) => c.expression).toList();
- ConstructedConstantExpression expression =
- new ConstructedConstantExpression(
- type, targetConstructor, callStructure, arguments);
-
- InstanceData instanceData = expression
- .computeInstanceData(new AstEvaluationEnvironment(compiler));
- instanceData.fieldMap.forEach((_field, ConstantExpression expression) {
- FieldElement field = _field;
- ConstantValue value = expression.evaluate(
- new AstEvaluationEnvironment(compiler), constantSystem);
- fieldValues[field] = new AstConstant(context, null, expression, value);
- });
- } else {
- ConstructorEvaluator evaluator =
- new ConstructorEvaluator(type, targetConstructor, handler, compiler);
- evaluator.evaluateConstructorFieldValues(compiledArguments);
- // Copy over the fieldValues from the super/redirect-constructor.
- // No need to go through [updateFieldValue] because the
- // assignments have already been checked in checked mode.
- evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
- }
+ ConstructorEvaluator evaluator =
+ new ConstructorEvaluator(type, targetConstructor, handler, compiler);
+ evaluator.evaluateConstructorFieldValues(compiledArguments);
+ // Copy over the fieldValues from the super/redirect-constructor.
+ // No need to go through [updateFieldValue] because the
+ // assignments have already been checked in checked mode.
+ evaluator.fieldValues.forEach((key, value) => fieldValues[key] = value);
}
/**
@@ -1469,7 +1434,7 @@
}
@override
- ResolutionInterfaceType substByContext(
+ ResolutionDartType substByContext(
ResolutionDartType base, ResolutionInterfaceType target) {
return base.substByContext(target);
}
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 1767742..e63edc3 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -60,7 +60,6 @@
import 'resolved_uri_translator.dart';
import 'scanner/scanner_task.dart' show ScannerTask;
import 'script.dart' show Script;
-import 'serialization/task.dart' show SerializationTask;
import 'ssa/nodes.dart' show HInstruction;
import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token;
import 'tree/tree.dart' show Node, TypeAnnotation;
@@ -142,7 +141,6 @@
ParserTask parser;
PatchParserTask patchParser;
LibraryLoaderTask libraryLoader;
- SerializationTask serialization;
ResolverTask resolver;
TypeCheckerTask checker;
GlobalTypeInferenceTask globalInference;
@@ -213,16 +211,12 @@
tasks = [
dietParser = new DietParserTask(idGenerator, backend, reporter, measurer),
scanner = createScannerTask(),
- serialization = new SerializationTask(this),
patchParser = new PatchParserTask(this),
libraryLoader = frontendStrategy.createLibraryLoader(
resolvedUriTranslator,
- options.compileOnly
- ? new _NoScriptLoader(this)
- : new _ScriptLoader(this),
+ new _ScriptLoader(this),
provider,
new _ElementScanner(scanner),
- serialization,
resolvePatchUri,
patchParser,
environment,
@@ -242,9 +236,6 @@
selfTask,
];
if (options.useKernel) tasks.add(kernelFrontEndTask);
- if (options.resolveOnly) {
- serialization.supportSerialization = true;
- }
_parsingContext =
new ParsingContext(reporter, parser, scanner, patchParser, backend);
@@ -544,19 +535,11 @@
deferredLoadTask.beforeResolution(rootLibrary);
impactStrategy = backend.createImpactStrategy(
supportDeferredLoad: deferredLoadTask.isProgramSplit,
- supportDumpInfo: options.dumpInfo,
- supportSerialization: serialization.supportSerialization);
+ supportDumpInfo: options.dumpInfo);
phase = PHASE_RESOLVING;
resolutionEnqueuer.applyImpact(mainImpact);
- if (options.resolveOnly) {
- libraryLoader.libraries.where((LibraryEntity library) {
- return !serialization.isDeserialized(library);
- }).forEach((LibraryEntity library) {
- reporter.log('Enqueuing ${library.canonicalUri}');
- resolutionEnqueuer.applyImpact(computeImpactForLibrary(library));
- });
- } else if (analyzeAll) {
+ if (analyzeAll) {
libraryLoader.libraries.forEach((LibraryEntity library) {
reporter.log('Enqueuing ${library.canonicalUri}');
resolutionEnqueuer.applyImpact(computeImpactForLibrary(library));
@@ -599,15 +582,6 @@
}
}
- if (options.resolveOnly && !compilationFailed) {
- reporter.log('Serializing to ${options.resolutionOutput}');
- serialization.serializeToSink(
- outputProvider.createOutputSink(
- '', 'data', api.OutputType.serializationData),
- libraryLoader.libraries.where((LibraryEntity library) {
- return !serialization.isDeserialized(library);
- }));
- }
if (options.analyzeOnly) return;
assert(mainFunction != null);
@@ -717,24 +691,7 @@
registerStaticUse(loadLibrary);
}
}
- if (serialization.supportSerialization) {
- for (MetadataAnnotation metadata in import.metadata) {
- metadata.ensureResolved(resolution);
- }
- }
});
- if (serialization.supportSerialization) {
- library.exports.forEach((ExportElement export) {
- for (MetadataAnnotation metadata in export.metadata) {
- metadata.ensureResolved(resolution);
- }
- });
- library.compilationUnits.forEach((CompilationUnitElement unit) {
- for (MetadataAnnotation metadata in unit.metadata) {
- metadata.ensureResolved(resolution);
- }
- });
- }
} else {
ElementEnvironment elementEnvironment =
frontendStrategy.elementEnvironment;
@@ -1418,17 +1375,12 @@
@override
void ensureResolved(Element element) {
- if (_compiler.serialization.isDeserialized(element)) {
- return;
- }
computeWorldImpact(element);
}
@override
void ensureClassMembers(ClassElement element) {
- if (!_compiler.serialization.isDeserialized(element)) {
- _compiler.resolver.checkClass(element);
- }
+ _compiler.resolver.checkClass(element);
}
@override
@@ -1439,9 +1391,6 @@
bool hasResolvedAst(ExecutableElement element) {
assert(element.isDeclaration,
failedAt(element, "Element $element must be the declaration."));
- if (_compiler.serialization.isDeserialized(element)) {
- return _compiler.serialization.hasResolvedAst(element);
- }
return hasBeenResolved(element.memberContext.declaration) &&
element.hasResolvedAst;
}
@@ -1452,9 +1401,6 @@
failedAt(element, "Element $element must be the declaration."));
assert(hasResolvedAst(element),
failedAt(element, "ResolvedAst not available for $element."));
- if (_compiler.serialization.isDeserialized(element)) {
- return _compiler.serialization.getResolvedAst(element);
- }
return element.resolvedAst;
}
@@ -1468,9 +1414,6 @@
bool hasResolutionImpact(Element element) {
assert(element.isDeclaration,
failedAt(element, "Element $element must be the declaration."));
- if (_compiler.serialization.isDeserialized(element)) {
- return _compiler.serialization.hasResolutionImpact(element);
- }
return _resolutionImpactCache.containsKey(element);
}
@@ -1478,12 +1421,7 @@
ResolutionImpact getResolutionImpact(Element element) {
assert(element.isDeclaration,
failedAt(element, "Element $element must be the declaration."));
- ResolutionImpact resolutionImpact;
- if (_compiler.serialization.isDeserialized(element)) {
- resolutionImpact = _compiler.serialization.getResolutionImpact(element);
- } else {
- resolutionImpact = _resolutionImpactCache[element];
- }
+ ResolutionImpact resolutionImpact = _resolutionImpactCache[element];
assert(resolutionImpact != null,
failedAt(element, "ResolutionImpact not available for $element."));
return resolutionImpact;
@@ -1525,8 +1463,7 @@
assert(!element.isSynthesized || tree == null, failedAt(element));
ResolutionImpact resolutionImpact = _compiler.resolver.resolve(element);
- if (_compiler.serialization.supportSerialization ||
- retainCachesForTesting) {
+ if (retainCachesForTesting) {
// [ResolutionImpact] is currently only used by serialization. The
// enqueuer uses the [WorldImpact] which is always cached.
// TODO(johnniwinther): Align these use cases better; maybe only
@@ -1559,7 +1496,6 @@
assert(element.isDeclaration,
failedAt(element, "Element $element must be the declaration."));
if (retainCachesForTesting) return;
- if (_compiler.serialization.isDeserialized(element)) return;
assert(_worldImpactCache[element] != null,
failedAt(element, "WorldImpact not computed for $element."));
_worldImpactCache[element] = const WorldImpact();
@@ -1582,11 +1518,7 @@
@override
ResolutionWorkItem createWorkItem(MemberElement element) {
- if (_compiler.serialization.isDeserialized(element)) {
- return _compiler.serialization.createResolutionWorkItem(element);
- } else {
- return new ResolutionWorkItem(this, element);
- }
+ return new ResolutionWorkItem(this, element);
}
ConstantValue _proxyConstant;
@@ -1637,23 +1569,6 @@
compiler.readBinary(uri, spannable);
}
-/// [ScriptLoader] used to ensure that scripts are not loaded accidentally
-/// through the [LibraryLoader] when `CompilerOptions.compileOnly` is `true`.
-class _NoScriptLoader implements ScriptLoader {
- Compiler compiler;
- _NoScriptLoader(this.compiler);
-
- Future<Script> readScript(Uri uri, [Spannable spannable]) {
- throw compiler.reporter
- .internalError(spannable, "Script loading of '$uri' is not enabled.");
- }
-
- Future<Binary> readBinary(Uri uri, [Spannable spannable]) {
- throw compiler.reporter
- .internalError(spannable, "Script loading of '$uri' is not enabled.");
- }
-}
-
class _ElementScanner implements ElementScanner {
ScannerTask scanner;
_ElementScanner(this.scanner);
diff --git a/pkg/compiler/lib/src/constants/evaluation.dart b/pkg/compiler/lib/src/constants/evaluation.dart
index 7a20827..92dca21 100644
--- a/pkg/compiler/lib/src/constants/evaluation.dart
+++ b/pkg/compiler/lib/src/constants/evaluation.dart
@@ -39,7 +39,7 @@
/// Performs the substitution of the type arguments of [target] for their
/// corresponding type variables in [type].
- InterfaceType substByContext(
+ DartType substByContext(
covariant DartType base, covariant InterfaceType target);
void reportWarning(
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 2a6813c..b86d8e7 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -847,16 +847,55 @@
@override
ConstantValue evaluate(
EvaluationEnvironment environment, ConstantSystem constantSystem) {
+ // Running example for comments:
+ //
+ // class A<T> {
+ // final T t;
+ // const A(dynamic t) : this.t = t; // implicitly `t as A.T`
+ // }
+ // class B<S> extends A<S> {
+ // const B(dynamic s) : super(s);
+ // }
+ // main() => const B<num>(0);
+ //
+ // We visit `t as A.T` while evaluating `const B<num>(0)`.
+
+ // The expression value is `0`.
ConstantValue expressionValue =
expression.evaluate(environment, constantSystem);
+
+ // The expression type is `int`.
DartType expressionType =
expressionValue.getType(environment.commonElements);
+
+ // The `as` type is `A.T`.
+ DartType typeInContext = type;
+
+ // The enclosing type is `B<num>`.
DartType enclosingType = environment.enclosingConstructedType;
- DartType superType = enclosingType != null
- ? environment.substByContext(type, enclosingType)
- : type;
+ if (enclosingType != null) {
+ ClassEntity contextClass;
+ type.forEachTypeVariable((TypeVariableType type) {
+ if (type.element.typeDeclaration is ClassEntity) {
+ // We find `A` from `A.T`. Since we don't have nested classes, class
+ // based type variables can only come from the same class.
+ contextClass = type.element.typeDeclaration;
+ }
+ });
+ if (contextClass != null) {
+ // The enclosing type `B<num>` as an instance of `A` is `A<num>`.
+ enclosingType =
+ environment.types.asInstanceOf(enclosingType, contextClass);
+ }
+ // `A.T` in the context of the enclosing type `A<num>` is `num`.
+ typeInContext = enclosingType != null
+ ? environment.substByContext(typeInContext, enclosingType)
+ : typeInContext;
+ }
+ // Check that the expression type, `int`, is a subtype of the type in
+ // context, `num`.
if (!constantSystem.isSubtype(
- environment.types, expressionType, superType)) {
+ environment.types, expressionType, typeInContext)) {
// TODO(sigmund): consider reporting different messages and error
// locations for implicit vs explicit casts.
environment.reportError(expression, MessageKind.INVALID_CONSTANT_CAST,
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 230350a..9fd6a9b 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -278,11 +278,11 @@
factory DoubleConstantValue(double value) {
if (value.isNaN) {
- return const DoubleConstantValue._internal(double.NAN);
- } else if (value == double.INFINITY) {
- return const DoubleConstantValue._internal(double.INFINITY);
- } else if (value == -double.INFINITY) {
- return const DoubleConstantValue._internal(-double.INFINITY);
+ return const DoubleConstantValue._internal(double.nan);
+ } else if (value == double.infinity) {
+ return const DoubleConstantValue._internal(double.infinity);
+ } else if (value == -double.infinity) {
+ return const DoubleConstantValue._internal(-double.infinity);
} else if (value == 0.0 && !value.isNegative) {
return const DoubleConstantValue._internal(0.0);
} else if (value == 1.0) {
@@ -305,9 +305,9 @@
bool get isOne => doubleValue == 1.0;
- bool get isPositiveInfinity => doubleValue == double.INFINITY;
+ bool get isPositiveInfinity => doubleValue == double.infinity;
- bool get isNegativeInfinity => doubleValue == -double.INFINITY;
+ bool get isNegativeInfinity => doubleValue == -double.infinity;
DartType getType(CommonElements types) => types.doubleType;
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index c1d77eb..b73c362 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -5,7 +5,7 @@
library dart2js.cmdline;
import 'dart:async' show Future;
-import 'dart:convert' show UTF8, LineSplitter;
+import 'dart:convert' show utf8, LineSplitter;
import 'dart:io' show exit, File, FileMode, Platform, stdin, stderr;
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
@@ -15,10 +15,7 @@
import '../compiler_new.dart' as api;
import 'commandline_options.dart';
-import 'common/names.dart' show Uris;
import 'filenames.dart';
-import 'io/source_file.dart';
-import 'null_compiler_output.dart';
import 'options.dart' show CompilerOptions;
import 'source_file_provider.dart';
import 'util/command_line.dart';
@@ -832,11 +829,7 @@
throw _EXIT_SIGNAL;
};
- if (USE_SERIALIZED_DART_CORE) {
- _useSerializedDataForDartCore(compileFunc);
- }
-
- var stream = stdin.transform(UTF8.decoder).transform(new LineSplitter());
+ var stream = stdin.transform(utf8.decoder).transform(new LineSplitter());
var subscription;
fe.InitializedCompilerState kernelInitializedCompilerState;
subscription = stream.listen((line) {
@@ -872,189 +865,3 @@
});
});
}
-
-// TODO(johnniwinther): Add corresponding options to the test script and change
-// these to use 'bool.fromEnvironment'.
-final bool USE_SERIALIZED_DART_CORE =
- Platform.environment['USE_SERIALIZED_DART_CORE'] == 'true';
-
-final bool SERIALIZED_COMPILATION =
- Platform.environment['SERIALIZED_COMPILATION'] == 'true';
-
-/// Mock URI used only in testing when [USE_SERIALIZED_DART_CORE] or
-/// [SERIALIZED_COMPILATION] is enabled.
-final Uri _SERIALIZED_DART_CORE_URI = Uri.parse('file:core.data');
-final Uri _SERIALIZED_TEST_URI = Uri.parse('file:test.data');
-
-void _useSerializedDataForDartCore(CompileFunc oldCompileFunc) {
- /// Run the [oldCompileFunc] with [serializedData] added as resolution input.
- Future<api.CompilationResult> compileWithSerializedData(
- CompilerOptions compilerOptions,
- api.CompilerInput compilerInput,
- api.CompilerDiagnostics compilerDiagnostics,
- api.CompilerOutput compilerOutput,
- List<_SerializedData> serializedData,
- {bool compileOnly: false}) {
- api.CompilerInput input = compilerInput;
- CompilerOptions options = compilerOptions;
- if (serializedData != null && serializedData.isNotEmpty) {
- Map<Uri, String> dataMap = <Uri, String>{};
- for (_SerializedData data in serializedData) {
- dataMap[data.uri] = data.data;
- }
- input = new _CompilerInput(input, dataMap);
- List<Uri> resolutionInputs = dataMap.keys.toList();
- if (compilerOptions.resolutionInputs != null) {
- for (Uri uri in compilerOptions.resolutionInputs) {
- if (!dataMap.containsKey(uri)) {
- resolutionInputs.add(uri);
- }
- }
- }
- options
- ..resolutionInputs = resolutionInputs
- ..compileOnly = compileOnly;
- }
- return oldCompileFunc(options, input, compilerDiagnostics, compilerOutput);
- }
-
- /// Serialize [entryPoint] using [serializedData] if provided.
- Future<api.CompilationResult> serialize(
- Uri entryPoint,
- Uri serializedUri,
- CompilerOptions compilerOptions,
- api.CompilerInput compilerInput,
- api.CompilerDiagnostics compilerDiagnostics,
- api.CompilerOutput compilerOutput,
- [List<_SerializedData> serializedData]) {
- compilerOptions
- ..entryPoint = entryPoint
- ..resolutionOutput = serializedUri
- ..analyzeAll = true
- ..analyzeOnly = true
- ..resolveOnly = true;
- return compileWithSerializedData(compilerOptions, compilerInput,
- compilerDiagnostics, compilerOutput, serializedData);
- }
-
- // Local cache for the serialized data for dart:core.
- _SerializedData serializedDartCore;
-
- /// Serialize the entry point using serialized data from dart:core and run
- /// [oldCompileFunc] using serialized data for whole program.
- Future<api.CompilationResult> compileFromSerializedData(
- CompilerOptions compilerOptions,
- api.CompilerInput compilerInput,
- api.CompilerDiagnostics compilerDiagnostics,
- api.CompilerOutput compilerOutput) async {
- _CompilerOutput output = new _CompilerOutput(_SERIALIZED_TEST_URI);
- api.CompilationResult result = await serialize(
- compilerOptions.entryPoint,
- output.uri,
- compilerOptions,
- compilerInput,
- compilerDiagnostics,
- output,
- [serializedDartCore]);
- if (!result.isSuccess) {
- return result;
- }
- return compileWithSerializedData(
- compilerOptions,
- compilerInput,
- compilerDiagnostics,
- compilerOutput,
- [serializedDartCore, output.serializedData],
- compileOnly: true);
- }
-
- /// Compiles the entry point using the serialized data from dart:core.
- Future<api.CompilationResult> compileWithSerializedDartCoreData(
- CompilerOptions compilerOptions,
- api.CompilerInput compilerInput,
- api.CompilerDiagnostics compilerDiagnostics,
- api.CompilerOutput compilerOutput) async {
- return compileWithSerializedData(compilerOptions, compilerInput,
- compilerDiagnostics, compilerOutput, [serializedDartCore]);
- }
-
- /// Serialize dart:core data into [serializedDartCore] and setup the
- /// [compileFunc] to run the compiler using this data.
- Future<api.CompilationResult> generateSerializedDataForDartCore(
- CompilerOptions compilerOptions,
- api.CompilerInput compilerInput,
- api.CompilerDiagnostics compilerDiagnostics,
- api.CompilerOutput compilerOutput) async {
- _CompilerOutput output = new _CompilerOutput(_SERIALIZED_DART_CORE_URI);
- await serialize(Uris.dart_core, output.uri, compilerOptions, compilerInput,
- compilerDiagnostics, output);
- serializedDartCore = output.serializedData;
- if (SERIALIZED_COMPILATION) {
- compileFunc = compileFromSerializedData;
- } else {
- compileFunc = compileWithSerializedDartCoreData;
- }
- return compileFunc(
- compilerOptions, compilerInput, compilerDiagnostics, compilerOutput);
- }
-
- compileFunc = generateSerializedDataForDartCore;
-}
-
-class _CompilerInput implements api.CompilerInput {
- final api.CompilerInput _input;
- final Map<Uri, String> _data;
-
- _CompilerInput(this._input, this._data);
-
- @override
- Future<api.Input> readFromUri(Uri uri,
- {api.InputKind inputKind: api.InputKind.utf8}) {
- String data = _data[uri];
- if (data != null) {
- return new Future.value(new StringSourceFile.fromUri(uri, data));
- }
- return _input.readFromUri(uri, inputKind: inputKind);
- }
-}
-
-class _SerializedData {
- final Uri uri;
- final String data;
-
- _SerializedData(this.uri, this.data);
-}
-
-class _CompilerOutput extends NullCompilerOutput {
- final Uri uri;
- _BufferedOutputSink sink;
-
- _CompilerOutput(this.uri);
-
- @override
- api.OutputSink createOutputSink(
- String name, String extension, api.OutputType type) {
- if (name == '' && extension == 'data') {
- return sink = new _BufferedOutputSink();
- }
- return super.createOutputSink(name, extension, type);
- }
-
- _SerializedData get serializedData {
- return new _SerializedData(uri, sink.sb.toString());
- }
-}
-
-class _BufferedOutputSink implements api.OutputSink {
- StringBuffer sb = new StringBuffer();
-
- @override
- void add(String event) {
- sb.write(event);
- }
-
- @override
- void close() {
- // Do nothing.
- }
-}
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index afceb3d..ad5e6f2 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -474,6 +474,8 @@
impact,
new WorldImpactVisitorImpl(visitDynamicUse: (dynamicUse) {
selections.addAll(closedWorld
+ // TODO(het): Handle `call` on `Closure` through
+ // `world.includesClosureCall`.
.locateMembers(dynamicUse.selector, dynamicUse.mask)
.map((MemberEntity e) => new Selection(e, dynamicUse.mask)));
}, visitStaticUse: (staticUse) {
diff --git a/pkg/compiler/lib/src/frontend_strategy.dart b/pkg/compiler/lib/src/frontend_strategy.dart
index e06ed4f..b6943cb 100644
--- a/pkg/compiler/lib/src/frontend_strategy.dart
+++ b/pkg/compiler/lib/src/frontend_strategy.dart
@@ -28,7 +28,6 @@
import 'native/resolver.dart';
import 'patch_parser.dart';
import 'resolved_uri_translator.dart';
-import 'serialization/task.dart';
import 'universe/class_hierarchy_builder.dart';
import 'universe/world_builder.dart';
import 'universe/world_impact.dart';
@@ -42,7 +41,6 @@
ScriptLoader scriptLoader,
api.CompilerInput compilerInput,
ElementScanner scriptScanner,
- LibraryDeserializer deserializer,
PatchResolverFunction patchResolverFunc,
PatchParserTask patchParser,
Environment environment,
@@ -153,8 +151,7 @@
}
/// Class that deletes the contents of an [WorldImpact] cache.
-// TODO(redemption): this can be deleted when we sunset the old front end and
-// delete serialization.
+// TODO(redemption): this can be deleted when we sunset the old front end.
abstract class ImpactCacheDeleter {
bool retainCachesForTesting;
diff --git a/pkg/compiler/lib/src/inferrer/builder.dart b/pkg/compiler/lib/src/inferrer/builder.dart
index 6deee5e..bf8b69d 100644
--- a/pkg/compiler/lib/src/inferrer/builder.dart
+++ b/pkg/compiler/lib/src/inferrer/builder.dart
@@ -1206,28 +1206,34 @@
void checkIfExposesThis(Selector selector, TypeMask mask) {
if (isThisExposed) return;
- inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
- if (element.isField) {
- FieldElement field = element;
- ResolvedAst elementResolvedAst = field.resolvedAst;
- if (!selector.isSetter &&
- isInClassOrSubclass(field) &&
- !field.isFinal &&
- locals.fieldScope.readField(field) == null &&
- elementResolvedAst.body == null) {
- // If the field is being used before this constructor
- // actually had a chance to initialize it, say it can be
- // null.
- inferrer.recordTypeOfField(field, types.nullType);
- }
- // Accessing a field does not expose [:this:].
- return true;
- }
+ if (inferrer.closedWorld.includesClosureCall(selector, mask)) {
// TODO(ngeoffray): We could do better here if we knew what we
// are calling does not expose this.
isThisExposed = true;
- return false;
- });
+ } else {
+ inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
+ if (element.isField) {
+ FieldElement field = element;
+ ResolvedAst elementResolvedAst = field.resolvedAst;
+ if (!selector.isSetter &&
+ isInClassOrSubclass(field) &&
+ !field.isFinal &&
+ locals.fieldScope.readField(field) == null &&
+ elementResolvedAst.body == null) {
+ // If the field is being used before this constructor
+ // actually had a chance to initialize it, say it can be
+ // null.
+ inferrer.recordTypeOfField(field, types.nullType);
+ }
+ // Accessing a field does not expose [:this:].
+ return true;
+ }
+ // TODO(ngeoffray): We could do better here if we knew what we
+ // are calling does not expose this.
+ isThisExposed = true;
+ return false;
+ });
+ }
}
bool get inInstanceContext {
@@ -2004,16 +2010,19 @@
(node.asSendSet() != null) &&
(node.asSendSet().receiver != null) &&
node.asSendSet().receiver.isThis()) {
- Iterable<MemberEntity> targets = closedWorld.locateMembers(
- setterSelector, types.newTypedSelector(thisType, setterMask));
- // We just recognized a field initialization of the form:
- // `this.foo = 42`. If there is only one target, we can update
- // its type.
- if (targets.length == 1) {
- MemberElement single = targets.first;
- if (single.isField) {
- FieldElement field = single;
- locals.updateField(field, rhsType);
+ TypeMask typedMask = types.newTypedSelector(thisType, setterMask);
+ if (!closedWorld.includesClosureCall(setterSelector, typedMask)) {
+ Iterable<MemberEntity> targets =
+ closedWorld.locateMembers(setterSelector, typedMask);
+ // We just recognized a field initialization of the form:
+ // `this.foo = 42`. If there is only one target, we can update
+ // its type.
+ if (targets.length == 1) {
+ MemberElement single = targets.first;
+ if (single.isField) {
+ FieldElement field = single;
+ locals.updateField(field, rhsType);
+ }
}
}
}
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 367e64e..100fbdb 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -129,27 +129,33 @@
// We already consider `this` to have been exposed.
return;
}
- _inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
- if (element.isField) {
- FieldEntity field = element;
- if (!selector.isSetter &&
- _isInClassOrSubclass(field) &&
- field.isAssignable &&
- _locals.fieldScope.readField(field) == null &&
- getFieldInitializer(_elementMap, field) == null) {
- // If the field is being used before this constructor
- // actually had a chance to initialize it, say it can be
- // null.
- _inferrer.recordTypeOfField(field, _types.nullType);
- }
- // Accessing a field does not expose `this`.
- return true;
- }
+ if (_inferrer.closedWorld.includesClosureCall(selector, mask)) {
// TODO(ngeoffray): We could do better here if we knew what we
// are calling does not expose this.
_markThisAsExposed();
- return false;
- });
+ } else {
+ _inferrer.forEachElementMatching(selector, mask, (MemberEntity element) {
+ if (element != null && element.isField) {
+ FieldEntity field = element;
+ if (!selector.isSetter &&
+ _isInClassOrSubclass(field) &&
+ field.isAssignable &&
+ _locals.fieldScope.readField(field) == null &&
+ getFieldInitializer(_elementMap, field) == null) {
+ // If the field is being used before this constructor
+ // actually had a chance to initialize it, say it can be
+ // null.
+ _inferrer.recordTypeOfField(field, _types.nullType);
+ }
+ // Accessing a field does not expose `this`.
+ return true;
+ }
+ // TODO(ngeoffray): We could do better here if we knew what we
+ // are calling does not expose this.
+ _markThisAsExposed();
+ return false;
+ });
+ }
}
TypeInformation run() {
@@ -1209,16 +1215,19 @@
}
if (_inGenerativeConstructor && node.receiver is ir.ThisExpression) {
- Iterable<MemberEntity> targets = _closedWorld.locateMembers(
- selector, _types.newTypedSelector(receiverType, mask));
- // We just recognized a field initialization of the form:
- // `this.foo = 42`. If there is only one target, we can update
- // its type.
- if (targets.length == 1) {
- MemberEntity single = targets.first;
- if (single.isField) {
- FieldEntity field = single;
- _locals.updateField(field, rhsType);
+ TypeMask typedMask = _types.newTypedSelector(receiverType, mask);
+ if (!_closedWorld.includesClosureCall(selector, typedMask)) {
+ Iterable<MemberEntity> targets =
+ _closedWorld.locateMembers(selector, typedMask);
+ // We just recognized a field initialization of the form:
+ // `this.foo = 42`. If there is only one target, we can update
+ // its type.
+ if (targets.length == 1) {
+ MemberEntity single = targets.first;
+ if (single.isField) {
+ FieldEntity field = single;
+ _locals.updateField(field, rhsType);
+ }
}
}
}
diff --git a/pkg/compiler/lib/src/inferrer/closure_tracer.dart b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
index 174089d..1c131cb 100644
--- a/pkg/compiler/lib/src/inferrer/closure_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/closure_tracer.dart
@@ -115,13 +115,14 @@
super.visitDynamicCallSiteTypeInformation(info);
if (info.selector.isCall) {
if (info.arguments.contains(currentUser)) {
- if (!info.targets.every((element) => element.isFunction)) {
+ if (info.hasClosureCallTargets ||
+ info.concreteTargets.any((element) => !element.isFunction)) {
bailout('Passed to a closure');
}
- if (info.targets.any(_checkIfFunctionApply)) {
+ if (info.concreteTargets.any(_checkIfFunctionApply)) {
_tagAsFunctionApplyTarget("dynamic call");
}
- } else if (info.targets.any((element) => _checkIfCurrentUser(element))) {
+ } else if (info.concreteTargets.any(_checkIfCurrentUser)) {
_registerCallForLaterAnalysis(info);
}
} else if (info.selector.isGetter &&
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index 02f075e..44c7969 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -635,13 +635,16 @@
print('${info.getInferredSignature(types)} for '
'${info.debugName}');
} else if (info is DynamicCallSiteTypeInformation) {
- for (MemberEntity target in info.targets) {
+ if (info.hasClosureCallTargets) {
+ print('<Closure.call>');
+ }
+ for (MemberEntity target in info.concreteTargets) {
if (target is FunctionEntity) {
- print(
- '${types.getInferredSignatureOfMethod(target)} for ${target}');
+ print('${types.getInferredSignatureOfMethod(target)} '
+ 'for ${target}');
} else {
- print(
- '${types.getInferredTypeOfMember(target).type} for ${target}');
+ print('${types.getInferredTypeOfMember(target).type} '
+ 'for ${target}');
}
}
} else if (info is StaticCallSiteTypeInformation) {
@@ -1034,6 +1037,9 @@
inLoop: inLoop);
}
+ if (closedWorld.includesClosureCall(selector, mask)) {
+ sideEffectsBuilder.setAllSideEffectsAndDependsOnSomething();
+ }
closedWorld.locateMembers(selector, mask).forEach((callee) {
updateSideEffects(sideEffectsBuilder, selector, callee);
});
diff --git a/pkg/compiler/lib/src/inferrer/list_tracer.dart b/pkg/compiler/lib/src/inferrer/list_tracer.dart
index 2659ae7..7043105 100644
--- a/pkg/compiler/lib/src/inferrer/list_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/list_tracer.dart
@@ -206,7 +206,8 @@
assignments.add(inferrer.types.nullType);
}
} else if (selector.isCall &&
- !info.targets.every((element) => element.isFunction)) {
+ (info.hasClosureCallTargets ||
+ info.concreteTargets.any((element) => !element.isFunction))) {
bailout('Passed to a closure');
return;
}
diff --git a/pkg/compiler/lib/src/inferrer/map_tracer.dart b/pkg/compiler/lib/src/inferrer/map_tracer.dart
index c4e8dd6..83ad71c 100644
--- a/pkg/compiler/lib/src/inferrer/map_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/map_tracer.dart
@@ -122,7 +122,8 @@
}
}
} else if (selector.isCall &&
- !info.targets.every((element) => element.isFunction)) {
+ (info.hasClosureCallTargets ||
+ info.concreteTargets.any((element) => !element.isFunction))) {
bailout('Passed to a closure');
return;
}
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index 5b199eb..b1ed67d 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -388,7 +388,7 @@
}
Iterable<TypeInformation> inferredTargetTypes =
- info.targets.map((MemberEntity entity) {
+ info.concreteTargets.map((MemberEntity entity) {
return inferrer.types.getInferredTypeOfMember(entity);
});
if (inferredTargetTypes.any((user) => user == currentUser)) {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 19410c0..d0d98eb 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -131,11 +131,16 @@
}
TypeMask result = const TypeMask.nonNullEmpty();
- Iterable<MemberEntity> elements =
- inferrer.closedWorld.locateMembers(selector, mask);
- for (MemberEntity element in elements) {
- TypeMask type = inferrer.typeOfMemberWithSelector(element, selector).type;
- result = result.union(type, inferrer.closedWorld);
+ if (inferrer.closedWorld.includesClosureCall(selector, mask)) {
+ result = inferrer.commonMasks.dynamicType;
+ } else {
+ Iterable<MemberEntity> elements =
+ inferrer.closedWorld.locateMembers(selector, mask);
+ for (MemberEntity element in elements) {
+ TypeMask type =
+ inferrer.typeOfMemberWithSelector(element, selector).type;
+ result = result.union(type, inferrer.closedWorld);
+ }
}
return result;
}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 1ad7fc5..a5ea018 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -789,11 +789,34 @@
TypeMask potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
if (inferrer.options.parameterCheckPolicy.isTrusted ||
inferrer.trustTypeAnnotations(_method)) {
- // When type assertions are enabled (aka checked mode), we have to always
- // ignore type annotations to ensure that the checks are actually inserted
- // into the function body and retained until runtime.
- // TODO(sigmund): is this still applicable? investigate if we can use also
- // narrow when isChecked is true.
+ // In checked or strong mode we don't trust the types of the arguments
+ // passed to a parameter. The means that the checking of a parameter is
+ // based on the actual arguments.
+ //
+ // With --trust-type-annotations or --omit-implicit-checks we _do_ trust
+ // the arguments passed to a parameter - and we never check them.
+ //
+ // In all these cases we _do_ trust the static type of a parameter within
+ // the method itself. For instance:
+ //
+ // method(int i) => i;
+ // main() {
+ // dynamic f = method;
+ // f(0); // valid call
+ // f(''); // invalid call
+ // }
+ //
+ // Here, in all cases, we infer the returned value of `method` to be an
+ // `int`. In checked and strong mode we infer the parameter of `method` to
+ // be either `int` or `String` and therefore insert a check at the entry
+ // of 'method'. With --trust-type-annotations or --omit-implicit-checks we
+ // (unsoundly) infer the parameter to be `int` and leave the parameter
+ // unchecked, and `method` will at runtime actually return a `String` from
+ // the second invocation.
+ //
+ // The trusting of the parameter types within the body of the method is
+ // is done through `LocalsHandler.update` called in
+ // `KernelTypeGraphBuilder.handleParameter`.
assert(!inferrer.options.enableTypeAssertions);
return _narrowType(inferrer.closedWorld, mask, _type);
}
@@ -978,9 +1001,10 @@
final CallType _callType;
final TypeInformation receiver;
final bool isConditional;
+ bool _hasClosureCallTargets;
- /// Cached targets of this call.
- Iterable<MemberEntity> targets;
+ /// Cached concrete targets of this call.
+ Iterable<MemberEntity> _concreteTargets;
DynamicCallSiteTypeInformation(
MemberTypeInformation context,
@@ -1000,12 +1024,14 @@
void addToGraph(InferrerEngine inferrer) {
assert(receiver != null);
TypeMask typeMask = computeTypedSelector(inferrer);
- targets = inferrer.closedWorld.locateMembers(selector, typeMask);
+ _hasClosureCallTargets =
+ inferrer.closedWorld.includesClosureCall(selector, typeMask);
+ _concreteTargets = inferrer.closedWorld.locateMembers(selector, typeMask);
receiver.addUser(this);
if (arguments != null) {
arguments.forEach((info) => info.addUser(this));
}
- for (MemberEntity element in targets) {
+ for (MemberEntity element in _concreteTargets) {
MemberTypeInformation callee =
inferrer.types.getInferredTypeOfMember(element);
callee.addCall(caller, _call);
@@ -1016,7 +1042,15 @@
}
}
- Iterable<MemberEntity> get callees => targets;
+ /// `true` if this invocation can hit a 'call' method on a closure.
+ bool get hasClosureCallTargets => _hasClosureCallTargets;
+
+ /// All concrete targets of this invocation. If [hasClosureCallTargets] is
+ /// `true` the invocation can additional target an unknown set of 'call'
+ /// methods on closures.
+ Iterable<MemberEntity> get concreteTargets => _concreteTargets;
+
+ Iterable<MemberEntity> get callees => _concreteTargets;
TypeMask computeTypedSelector(InferrerEngine inferrer) {
TypeMask receiverType = receiver.type;
@@ -1031,7 +1065,7 @@
}
bool targetsIncludeComplexNoSuchMethod(InferrerEngine inferrer) {
- return targets.any((MemberEntity e) {
+ return _concreteTargets.any((MemberEntity e) {
return e.isFunction &&
e.isInstanceMember &&
e.name == Identifiers.noSuchMethod_ &&
@@ -1146,7 +1180,7 @@
}
TypeMask computeType(InferrerEngine inferrer) {
- Iterable<MemberEntity> oldTargets = targets;
+ Iterable<MemberEntity> oldTargets = _concreteTargets;
TypeMask typeMask = computeTypedSelector(inferrer);
inferrer.updateSelectorInMember(
caller, _callType, _call, selector, typeMask);
@@ -1160,15 +1194,17 @@
// the untyped selector (through noSuchMethod's `Invocation`
// and a call to `delegate`), we iterate over all these methods to
// update their parameter types.
- targets = inferrer.closedWorld.locateMembers(selector, maskToUse);
+ _hasClosureCallTargets =
+ inferrer.closedWorld.includesClosureCall(selector, maskToUse);
+ _concreteTargets = inferrer.closedWorld.locateMembers(selector, maskToUse);
Iterable<MemberEntity> typedTargets = canReachAll
? inferrer.closedWorld.locateMembers(selector, typeMask)
- : targets;
+ : _concreteTargets;
// Update the call graph if the targets could have changed.
- if (!identical(targets, oldTargets)) {
+ if (!identical(_concreteTargets, oldTargets)) {
// Add calls to new targets to the graph.
- targets
+ _concreteTargets
.where((target) => !oldTargets.contains(target))
.forEach((MemberEntity element) {
MemberTypeInformation callee =
@@ -1182,7 +1218,7 @@
// Walk over the old targets, and remove calls that cannot happen anymore.
oldTargets
- .where((target) => !targets.contains(target))
+ .where((target) => !_concreteTargets.contains(target))
.forEach((MemberEntity element) {
MemberTypeInformation callee =
inferrer.types.getInferredTypeOfMember(element);
@@ -1196,55 +1232,59 @@
// Walk over the found targets, and compute the joined union type mask
// for all these targets.
- TypeMask result =
- inferrer.types.joinTypeMasks(targets.map((MemberEntity element) {
- // If [canReachAll] is true, then we are iterating over all
- // targets that satisfy the untyped selector. We skip the return
- // type of the targets that can only be reached through
- // `Invocation.delegate`. Note that the `noSuchMethod` targets
- // are included in [typedTargets].
- if (canReachAll && !typedTargets.contains(element)) {
- return const TypeMask.nonNullEmpty();
- }
- if (inferrer.returnsListElementType(selector, typeMask)) {
- ContainerTypeMask containerTypeMask = receiver.type;
- return containerTypeMask.elementType;
- } else if (inferrer.returnsMapValueType(selector, typeMask)) {
- if (typeMask.isDictionary) {
- TypeMask arg = arguments.positional[0].type;
- if (arg is ValueTypeMask && arg.value.isString) {
- DictionaryTypeMask dictionaryTypeMask = typeMask;
- StringConstantValue value = arg.value;
- String key = value.stringValue;
- if (dictionaryTypeMask.typeMap.containsKey(key)) {
- if (debug.VERBOSE) {
- print("Dictionary lookup for $key yields "
- "${dictionaryTypeMask.typeMap[key]}.");
+ TypeMask result;
+ if (_hasClosureCallTargets) {
+ result = inferrer.commonMasks.dynamicType;
+ } else {
+ result = inferrer.types
+ .joinTypeMasks(_concreteTargets.map((MemberEntity element) {
+ // If [canReachAll] is true, then we are iterating over all
+ // targets that satisfy the untyped selector. We skip the return
+ // type of the targets that can only be reached through
+ // `Invocation.delegate`. Note that the `noSuchMethod` targets
+ // are included in [typedTargets].
+ if (canReachAll && !typedTargets.contains(element)) {
+ return const TypeMask.nonNullEmpty();
+ }
+ if (inferrer.returnsListElementType(selector, typeMask)) {
+ ContainerTypeMask containerTypeMask = receiver.type;
+ return containerTypeMask.elementType;
+ } else if (inferrer.returnsMapValueType(selector, typeMask)) {
+ if (typeMask.isDictionary) {
+ TypeMask arg = arguments.positional[0].type;
+ if (arg is ValueTypeMask && arg.value.isString) {
+ DictionaryTypeMask dictionaryTypeMask = typeMask;
+ StringConstantValue value = arg.value;
+ String key = value.stringValue;
+ if (dictionaryTypeMask.typeMap.containsKey(key)) {
+ if (debug.VERBOSE) {
+ print("Dictionary lookup for $key yields "
+ "${dictionaryTypeMask.typeMap[key]}.");
+ }
+ return dictionaryTypeMask.typeMap[key];
+ } else {
+ // The typeMap is precise, so if we do not find the key, the lookup
+ // will be [null] at runtime.
+ if (debug.VERBOSE) {
+ print("Dictionary lookup for $key yields [null].");
+ }
+ return inferrer.types.nullType.type;
}
- return dictionaryTypeMask.typeMap[key];
- } else {
- // The typeMap is precise, so if we do not find the key, the lookup
- // will be [null] at runtime.
- if (debug.VERBOSE) {
- print("Dictionary lookup for $key yields [null].");
- }
- return inferrer.types.nullType.type;
}
}
+ MapTypeMask mapTypeMask = typeMask;
+ if (debug.VERBOSE) {
+ print("Map lookup for $selector yields ${mapTypeMask.valueType}.");
+ }
+ return mapTypeMask.valueType;
+ } else {
+ TypeInformation info =
+ handleIntrisifiedSelector(selector, typeMask, inferrer);
+ if (info != null) return info.type;
+ return inferrer.typeOfMemberWithSelector(element, selector).type;
}
- MapTypeMask mapTypeMask = typeMask;
- if (debug.VERBOSE) {
- print("Map lookup for $selector yields ${mapTypeMask.valueType}.");
- }
- return mapTypeMask.valueType;
- } else {
- TypeInformation info =
- handleIntrisifiedSelector(selector, typeMask, inferrer);
- if (info != null) return info.type;
- return inferrer.typeOfMemberWithSelector(element, selector).type;
- }
- }));
-
+ }));
+ }
if (isConditional && receiver.type.isNullable) {
// Conditional call sites (e.g. `a?.b`) may be null if the receiver is
// null.
@@ -1256,9 +1296,11 @@
void giveUp(InferrerEngine inferrer, {bool clearAssignments: true}) {
if (!abandonInferencing) {
inferrer.updateSelectorInMember(caller, _callType, _call, selector, mask);
- Iterable<MemberEntity> oldTargets = targets;
- targets = inferrer.closedWorld.locateMembers(selector, mask);
- for (MemberEntity element in targets) {
+ Iterable<MemberEntity> oldTargets = _concreteTargets;
+ _hasClosureCallTargets =
+ inferrer.closedWorld.includesClosureCall(selector, mask);
+ _concreteTargets = inferrer.closedWorld.locateMembers(selector, mask);
+ for (MemberEntity element in _concreteTargets) {
if (!oldTargets.contains(element)) {
MemberTypeInformation callee =
inferrer.types.getInferredTypeOfMember(element);
@@ -1273,7 +1315,7 @@
}
void removeAndClearReferences(InferrerEngine inferrer) {
- for (MemberEntity element in targets) {
+ for (MemberEntity element in _concreteTargets) {
MemberTypeInformation callee =
inferrer.types.getInferredTypeOfMember(element);
callee.removeUser(this);
@@ -1292,9 +1334,8 @@
bool hasStableType(InferrerEngine inferrer) {
return receiver.isStable &&
- targets.every((MemberEntity element) {
- return inferrer.types.getInferredTypeOfMember(element).isStable;
- }) &&
+ _concreteTargets.every((MemberEntity element) =>
+ inferrer.types.getInferredTypeOfMember(element).isStable) &&
(arguments == null || arguments.every((info) => info.isStable)) &&
super.hasStableType(inferrer);
}
diff --git a/pkg/compiler/lib/src/io/source_file.dart b/pkg/compiler/lib/src/io/source_file.dart
index 494111d..8cfa41e 100644
--- a/pkg/compiler/lib/src/io/source_file.dart
+++ b/pkg/compiler/lib/src/io/source_file.dart
@@ -4,7 +4,7 @@
library dart2js.io.source_file;
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
import 'dart:math';
import 'dart:typed_data' show Uint8List;
@@ -19,7 +19,7 @@
/// The absolute URI of the source file.
Uri get uri;
- InputKind get inputKind => InputKind.utf8;
+ InputKind get inputKind => InputKind.UTF8;
kernel.Source cachedKernelSource;
@@ -188,7 +188,7 @@
String slowText() {
// Don't convert the trailing zero byte.
- return UTF8.decoder
+ return utf8.decoder
.convert(zeroTerminatedContent, 0, zeroTerminatedContent.length - 1);
}
@@ -248,7 +248,7 @@
String slowText() => text;
List<int> slowUtf8ZeroTerminatedBytes() {
- return _zeroTerminateIfNecessary(UTF8.encode(text));
+ return _zeroTerminateIfNecessary(utf8.encode(text));
}
String slowSubstring(int start, int end) => text.substring(start, end);
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 798fd5c..4043360 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -57,7 +57,6 @@
import '../world.dart' show ClosedWorld, ClosedWorldRefiner;
import 'annotations.dart' as optimizerHints;
import 'backend_impact.dart';
-import 'backend_serialization.dart' show JavaScriptBackendSerialization;
import 'backend_usage.dart';
import 'checked_mode_helpers.dart';
import 'codegen_listener.dart';
@@ -414,9 +413,6 @@
/// The strategy used for collecting and emitting source information.
SourceInformationStrategy sourceInformationStrategy;
- /// Interface for serialization of backend specific data.
- JavaScriptBackendSerialization serialization;
-
NativeDataBuilderImpl _nativeDataBuilder;
NativeDataBuilder get nativeDataBuilder => _nativeDataBuilder;
final NativeDataResolver _nativeDataResolver;
@@ -461,7 +457,6 @@
patchResolverTask = new PatchResolverTask(compiler);
functionCompiler = new SsaFunctionCompiler(
this, compiler.measurer, sourceInformationStrategy);
- serialization = new JavaScriptBackendSerialization(this);
}
/// The [ConstantSystem] used to interpret compile-time constants for this
@@ -943,14 +938,12 @@
/// This method is called immediately after the [library] and its parts have
/// been loaded.
void setAnnotations(LibraryEntity library) {
- if (!compiler.serialization.isDeserialized(library)) {
- AnnotationProcessor processor =
- compiler.frontendStrategy.annotationProcesser;
- if (canLibraryUseNative(library)) {
- processor.extractNativeAnnotations(library);
- }
- processor.extractJsInteropAnnotations(library);
+ AnnotationProcessor processor =
+ compiler.frontendStrategy.annotationProcesser;
+ if (canLibraryUseNative(library)) {
+ processor.extractNativeAnnotations(library);
}
+ processor.extractJsInteropAnnotations(library);
Uri uri = library.canonicalUri;
if (uri == Uris.dart_html) {
htmlLibraryIsLoaded = true;
@@ -1229,14 +1222,11 @@
/// Creates an impact strategy to use for compilation.
ImpactStrategy createImpactStrategy(
- {bool supportDeferredLoad: true,
- bool supportDumpInfo: true,
- bool supportSerialization: true}) {
+ {bool supportDeferredLoad: true, bool supportDumpInfo: true}) {
return new JavaScriptImpactStrategy(
impactCacheDeleter, compiler.dumpInfoTask,
supportDeferredLoad: supportDeferredLoad,
- supportDumpInfo: supportDumpInfo,
- supportSerialization: supportSerialization);
+ supportDumpInfo: supportDumpInfo);
}
EnqueueTask makeEnqueuer() => new EnqueueTask(compiler);
@@ -1247,19 +1237,16 @@
final DumpInfoTask dumpInfoTask;
final bool supportDeferredLoad;
final bool supportDumpInfo;
- final bool supportSerialization;
JavaScriptImpactStrategy(this.impactCacheDeleter, this.dumpInfoTask,
- {this.supportDeferredLoad,
- this.supportDumpInfo,
- this.supportSerialization});
+ {this.supportDeferredLoad, this.supportDumpInfo});
@override
void visitImpact(var impactSource, WorldImpact impact,
WorldImpactVisitor visitor, ImpactUseCase impactUse) {
// TODO(johnniwinther): Compute the application strategy once for each use.
if (impactUse == ResolutionEnqueuer.IMPACT_USE) {
- if (supportDeferredLoad || supportSerialization) {
+ if (supportDeferredLoad) {
impact.apply(visitor);
} else {
impact.apply(visitor);
@@ -1280,9 +1267,7 @@
@override
void onImpactUsed(ImpactUseCase impactUse) {
- if (impactUse == DeferredLoadTask.IMPACT_USE && !supportSerialization) {
- // TODO(johnniwinther): Allow emptying when serialization has been
- // performed.
+ if (impactUse == DeferredLoadTask.IMPACT_USE) {
impactCacheDeleter.emptyCache();
}
}
diff --git a/pkg/compiler/lib/src/js_backend/backend_serialization.dart b/pkg/compiler/lib/src/js_backend/backend_serialization.dart
deleted file mode 100644
index 5d46196..0000000
--- a/pkg/compiler/lib/src/js_backend/backend_serialization.dart
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library js_backend.serialization;
-
-import '../common/backend_api.dart' show BackendSerialization;
-import '../elements/elements.dart';
-import '../elements/resolution_types.dart';
-import '../elements/types.dart';
-import '../js/js.dart' as js;
-import '../native/native.dart';
-import '../resolution/resolution_strategy.dart';
-import '../serialization/keys.dart';
-import '../serialization/serialization.dart'
- show DeserializerPlugin, ObjectDecoder, ObjectEncoder, SerializerPlugin;
-import '../universe/side_effects.dart';
-import 'js_backend.dart';
-import 'native_data.dart';
-
-const String _BACKEND_DATA_TAG = 'jsBackendData';
-const Key DART_TYPES_RETURNED = const Key('dartTypesReturned');
-const Key THIS_TYPES_RETURNED = const Key('thisTypesReturned');
-const Key SPECIAL_TYPES_RETURNED = const Key('specialTypesReturned');
-const Key DART_TYPES_INSTANTIATED = const Key('dartTypesInstantiated');
-const Key THIS_TYPES_INSTANTIATED = const Key('thisTypesInstantiated');
-const Key SPECIAL_TYPES_INSTANTIATED = const Key('specialTypesInstantiated');
-const Key CODE_TEMPLATE = const Key('codeTemplate');
-const Key SIDE_EFFECTS = const Key('sideEffects');
-const Key THROW_BEHAVIOR = const Key('throwBehavior');
-const Key IS_ALLOCATION = const Key('isAllocation');
-const Key USE_GVN = const Key('useGvn');
-
-class JavaScriptBackendSerialization implements BackendSerialization {
- final JavaScriptBackendSerializer serializer;
- final JavaScriptBackendDeserializer deserializer;
-
- JavaScriptBackendSerialization(JavaScriptBackend backend)
- : serializer = new JavaScriptBackendSerializer(backend),
- deserializer = new JavaScriptBackendDeserializer(backend);
-}
-
-const Key JS_INTEROP_LIBRARY_NAME = const Key('jsInteropLibraryName');
-const Key JS_INTEROP_CLASS_NAME = const Key('jsInteropClassName');
-const Key JS_INTEROP_MEMBER_NAME = const Key('jsInteropMemberName');
-const Key NATIVE_MEMBER_NAME = const Key('nativeMemberName');
-const Key NATIVE_CLASS_TAG_INFO = const Key('nativeClassTagInfo');
-const Key NATIVE_METHOD_BEHAVIOR = const Key('nativeMethodBehavior');
-const Key NATIVE_FIELD_LOAD_BEHAVIOR = const Key('nativeFieldLoadBehavior');
-const Key NATIVE_FIELD_STORE_BEHAVIOR = const Key('nativeFieldStoreBehavior');
-
-class JavaScriptBackendSerializer implements SerializerPlugin {
- final JavaScriptBackend _backend;
-
- JavaScriptBackendSerializer(this._backend);
-
- NativeBasicDataImpl get nativeBasicData =>
- _backend.compiler.frontendStrategy.nativeBasicData;
- NativeDataBuilderImpl get nativeData => _backend.nativeDataBuilder;
-
- @override
- void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
- ObjectEncoder encoder;
- ObjectEncoder getEncoder() {
- return encoder ??= createEncoder(_BACKEND_DATA_TAG);
- }
-
- String jsInteropLibraryName = nativeData.jsInteropLibraries[element];
- if (jsInteropLibraryName != null) {
- getEncoder().setString(JS_INTEROP_LIBRARY_NAME, jsInteropLibraryName);
- }
- String jsInteropClassName = nativeData.jsInteropClasses[element];
- if (jsInteropClassName != null) {
- getEncoder().setString(JS_INTEROP_CLASS_NAME, jsInteropClassName);
- }
- String jsInteropMemberName = nativeData.jsInteropMembers[element];
- if (jsInteropMemberName != null) {
- getEncoder().setString(JS_INTEROP_MEMBER_NAME, jsInteropMemberName);
- }
- String nativeMemberName = nativeData.nativeMemberName[element];
- if (nativeMemberName != null) {
- getEncoder().setString(NATIVE_MEMBER_NAME, nativeMemberName);
- }
- NativeClassTag nativeClassTagInfo =
- nativeBasicData.nativeClassTagInfo[element];
- if (nativeClassTagInfo != null) {
- getEncoder().setString(NATIVE_CLASS_TAG_INFO, nativeClassTagInfo.text);
- }
- NativeBehavior nativeMethodBehavior =
- nativeData.nativeMethodBehavior[element];
- if (nativeMethodBehavior != null) {
- NativeBehaviorSerialization.serializeNativeBehavior(nativeMethodBehavior,
- getEncoder().createObject(NATIVE_METHOD_BEHAVIOR));
- }
- NativeBehavior nativeFieldLoadBehavior =
- nativeData.nativeFieldLoadBehavior[element];
- if (nativeFieldLoadBehavior != null) {
- NativeBehaviorSerialization.serializeNativeBehavior(
- nativeFieldLoadBehavior,
- getEncoder().createObject(NATIVE_FIELD_LOAD_BEHAVIOR));
- }
- NativeBehavior nativeFieldStoreBehavior =
- nativeData.nativeFieldStoreBehavior[element];
- if (nativeFieldStoreBehavior != null) {
- NativeBehaviorSerialization.serializeNativeBehavior(
- nativeFieldStoreBehavior,
- getEncoder().createObject(NATIVE_FIELD_STORE_BEHAVIOR));
- }
- }
-
- @override
- void onData(covariant NativeBehavior behavior, ObjectEncoder encoder) {
- NativeBehaviorSerialization.serializeNativeBehavior(behavior, encoder);
- }
-}
-
-class JavaScriptBackendDeserializer implements DeserializerPlugin {
- final JavaScriptBackend _backend;
-
- JavaScriptBackendDeserializer(this._backend);
-
- NativeBasicDataBuilderImpl get nativeBasicData {
- ResolutionFrontEndStrategy frontendStrategy =
- _backend.compiler.frontendStrategy;
- return frontendStrategy.nativeBasicDataBuilder;
- }
-
- NativeDataBuilderImpl get nativeData => _backend.nativeDataBuilder;
-
- @override
- void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
- ObjectDecoder decoder = getDecoder(_BACKEND_DATA_TAG);
- if (decoder != null) {
- if (element is LibraryElement) {
- String jsInteropLibraryName =
- decoder.getString(JS_INTEROP_LIBRARY_NAME, isOptional: true);
- if (jsInteropLibraryName != null) {
- nativeData.jsInteropLibraries[element] = jsInteropLibraryName;
- }
- } else if (element is ClassElement) {
- String jsInteropClassName =
- decoder.getString(JS_INTEROP_CLASS_NAME, isOptional: true);
- if (jsInteropClassName != null) {
- nativeData.jsInteropClasses[element] = jsInteropClassName;
- }
- String nativeClassTagInfo =
- decoder.getString(NATIVE_CLASS_TAG_INFO, isOptional: true);
- if (nativeClassTagInfo != null) {
- nativeBasicData.nativeClassTagInfo[element] =
- new NativeClassTag(nativeClassTagInfo);
- }
- } else if (element is MemberElement) {
- String jsInteropMemberName =
- decoder.getString(JS_INTEROP_MEMBER_NAME, isOptional: true);
- if (jsInteropMemberName != null) {
- nativeData.jsInteropMembers[element] = jsInteropMemberName;
- }
- String nativeMemberName =
- decoder.getString(NATIVE_MEMBER_NAME, isOptional: true);
- if (nativeMemberName != null) {
- nativeData.nativeMemberName[element] = nativeMemberName;
- }
-
- if (element is MethodElement) {
- ObjectDecoder nativeMethodBehavior =
- decoder.getObject(NATIVE_METHOD_BEHAVIOR, isOptional: true);
- if (nativeMethodBehavior != null) {
- nativeData.nativeMethodBehavior[element] =
- NativeBehaviorSerialization
- .deserializeNativeBehavior(nativeMethodBehavior);
- }
- } else if (element is FieldElement) {
- ObjectDecoder nativeFieldLoadBehavior =
- decoder.getObject(NATIVE_FIELD_LOAD_BEHAVIOR, isOptional: true);
- if (nativeFieldLoadBehavior != null) {
- nativeData.nativeFieldLoadBehavior[element] =
- NativeBehaviorSerialization
- .deserializeNativeBehavior(nativeFieldLoadBehavior);
- }
- ObjectDecoder nativeFieldStoreBehavior =
- decoder.getObject(NATIVE_FIELD_STORE_BEHAVIOR, isOptional: true);
- if (nativeFieldStoreBehavior != null) {
- nativeData.nativeFieldStoreBehavior[element] =
- NativeBehaviorSerialization
- .deserializeNativeBehavior(nativeFieldStoreBehavior);
- }
- }
- }
- }
- }
-
- @override
- NativeBehavior onData(ObjectDecoder decoder) {
- return NativeBehaviorSerialization.deserializeNativeBehavior(decoder);
- }
-}
-
-class NativeBehaviorSerialization {
- static const int NORMAL_TYPE = 0;
- static const int THIS_TYPE = 1;
- static const int SPECIAL_TYPE = 2;
-
- static int getTypeKind(var type) {
- if (type is DartType) {
- // TODO(johnniwinther): Remove this when annotation are no longer resolved
- // to this-types.
- if (type is InterfaceType &&
- type.typeArguments.isNotEmpty &&
- type.typeArguments.first is TypeVariableType) {
- return THIS_TYPE;
- }
- return NORMAL_TYPE;
- }
- return SPECIAL_TYPE;
- }
-
- /// Returns a list of the non-this-type [ResolutionDartType]s in [types].
- static List<ResolutionDartType> filterDartTypes(List types) {
- return types.where((type) => getTypeKind(type) == NORMAL_TYPE).toList();
- }
-
- // TODO(johnniwinther): Remove this when annotation are no longer resolved
- // to this-types.
- /// Returns a list of the classes of this-types in [types].
- static List<Element> filterThisTypes(List types) {
- return types
- .where((type) => getTypeKind(type) == THIS_TYPE)
- .map((type) => type.element)
- .toList();
- }
-
- /// Returns a list of the names of the [SpecialType]s in [types].
- static List<String> filterSpecialTypes(List types) {
- return types.where((type) => getTypeKind(type) == SPECIAL_TYPE).map((t) {
- SpecialType type = t;
- return type.name;
- }).toList();
- }
-
- static void serializeNativeBehavior(
- NativeBehavior behavior, ObjectEncoder encoder) {
- encoder.setTypes(
- DART_TYPES_RETURNED, filterDartTypes(behavior.typesReturned));
- encoder.setElements(
- THIS_TYPES_RETURNED, filterThisTypes(behavior.typesReturned));
- encoder.setStrings(
- SPECIAL_TYPES_RETURNED, filterSpecialTypes(behavior.typesReturned));
-
- encoder.setTypes(
- DART_TYPES_INSTANTIATED, filterDartTypes(behavior.typesInstantiated));
- encoder.setElements(
- THIS_TYPES_INSTANTIATED, filterThisTypes(behavior.typesInstantiated));
- encoder.setStrings(SPECIAL_TYPES_INSTANTIATED,
- filterSpecialTypes(behavior.typesInstantiated));
-
- if (behavior.codeTemplateText != null) {
- encoder.setString(CODE_TEMPLATE, behavior.codeTemplateText);
- }
-
- encoder.setInt(SIDE_EFFECTS, behavior.sideEffects.flags);
- encoder.setEnum(THROW_BEHAVIOR, behavior.throwBehavior);
- encoder.setBool(IS_ALLOCATION, behavior.isAllocation);
- encoder.setBool(USE_GVN, behavior.useGvn);
- }
-
- static NativeBehavior deserializeNativeBehavior(ObjectDecoder decoder) {
- SideEffects sideEffects =
- new SideEffects.fromFlags(decoder.getInt(SIDE_EFFECTS));
- NativeBehavior behavior = new NativeBehavior.internal(sideEffects);
-
- behavior.typesReturned
- .addAll(decoder.getTypes(DART_TYPES_RETURNED, isOptional: true));
- behavior.typesReturned.addAll(decoder
- .getElements(THIS_TYPES_RETURNED, isOptional: true)
- .map((dynamic element) => element.thisType)
- .toList());
- behavior.typesReturned.addAll(decoder
- .getStrings(SPECIAL_TYPES_RETURNED, isOptional: true)
- .map(SpecialType.fromName));
-
- behavior.typesInstantiated
- .addAll(decoder.getTypes(DART_TYPES_INSTANTIATED, isOptional: true));
- behavior.typesInstantiated.addAll(decoder
- .getElements(THIS_TYPES_INSTANTIATED, isOptional: true)
- .map((dynamic element) => element.thisType)
- .toList());
- behavior.typesInstantiated.addAll(decoder
- .getStrings(SPECIAL_TYPES_INSTANTIATED, isOptional: true)
- .map(SpecialType.fromName));
-
- behavior.codeTemplateText =
- decoder.getString(CODE_TEMPLATE, isOptional: true);
- if (behavior.codeTemplateText != null) {
- behavior.codeTemplate = js.js.parseForeignJS(behavior.codeTemplateText);
- }
-
- behavior.throwBehavior =
- decoder.getEnum(THROW_BEHAVIOR, NativeThrowBehavior.values);
- behavior.isAllocation = decoder.getBool(IS_ALLOCATION);
- behavior.useGvn = decoder.getBool(USE_GVN);
- return behavior;
- }
-}
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 12ef4a4..064aa93 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -146,9 +146,9 @@
double value = constant.doubleValue;
if (value.isNaN) {
return js("0/0");
- } else if (value == double.INFINITY) {
+ } else if (value == double.infinity) {
return js("1/0");
- } else if (value == -double.INFINITY) {
+ } else if (value == -double.infinity) {
return js("-1/0");
} else {
String shortened = _shortenExponentialRepresentation("$value");
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
index cbeefd6..a2bd855 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -203,7 +203,7 @@
if (constant.isInt) {
IntConstantValue intConstant = constant;
int value = intConstant.intValue;
- if (value >= -double.MAX_FINITE && value <= double.MAX_FINITE) {
+ if (value >= -double.maxFinite && value <= double.maxFinite) {
return tryToRound(value);
}
}
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 9cfe111..813ea76 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -1667,20 +1667,16 @@
}
});
- codegenWorldBuilder.instantiatedTypes.forEach((t) {
- liveTypeVisitor.visitType(t, false);
+ codegenWorldBuilder.instantiatedTypes.forEach((InterfaceType type) {
+ liveTypeVisitor.visitType(type, false);
ClassUse classUse =
- classUseMap.putIfAbsent(t.element, () => new ClassUse());
+ classUseMap.putIfAbsent(type.element, () => new ClassUse());
classUse.instance = true;
- });
-
- for (InterfaceType instantiatedType
- in codegenWorldBuilder.instantiatedTypes) {
- FunctionType callType = _types.getCallType(instantiatedType);
+ FunctionType callType = _types.getCallType(type);
if (callType != null) {
testedTypeVisitor.visitType(callType, false);
}
- }
+ });
for (FunctionEntity element
in codegenWorldBuilder.staticFunctionsNeedingGetter) {
@@ -2409,6 +2405,9 @@
}
class TypeVisitor extends ResolutionDartTypeVisitor<void, bool> {
+ Set<FunctionTypeVariable> _visitedFunctionTypeVariables =
+ new Set<FunctionTypeVariable>();
+
final void Function(ClassEntity entity, {bool inTypeArgument}) onClass;
final void Function(TypeVariableEntity entity, {bool inTypeArgument})
onTypeVariable;
@@ -2451,6 +2450,7 @@
visitTypes(type.parameterTypes, true);
visitTypes(type.optionalParameterTypes, true);
visitTypes(type.namedParameterTypes, true);
+ _visitedFunctionTypeVariables.removeAll(type.typeVariables);
}
@override
@@ -2460,7 +2460,9 @@
@override
visitFunctionTypeVariable(FunctionTypeVariable type, bool inTypeArgument) {
- visitType(type.bound, inTypeArgument);
+ if (_visitedFunctionTypeVariables.add(type)) {
+ visitType(type.bound, inTypeArgument);
+ }
}
}
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 2561648..ad8f33b 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -5,7 +5,7 @@
library dart2js.js_emitter.program_builder;
import 'dart:io';
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode;
import '../../closure.dart' show ClosureConversionTask, ClosureFieldElement;
import '../../common.dart';
@@ -315,7 +315,7 @@
}
String data = new File(allocatedClassesPath).readAsStringSync();
- Set<String> allocatedClassesKeys = JSON.decode(data).keys.toSet();
+ Set<String> allocatedClassesKeys = jsonDecode(data).keys.toSet();
Set<ClassEntity> allocatedClasses = new Set<ClassEntity>();
// Collects all super and mixin classes of a class.
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 15e1ad0..ecf8d0a 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -1817,7 +1817,7 @@
DartTypes get types => _elementMap.types;
@override
- InterfaceType substByContext(DartType base, InterfaceType target) {
+ DartType substByContext(DartType base, InterfaceType target) {
return _elementMap._substByContext(base, target);
}
diff --git a/pkg/compiler/lib/src/kernel/front_end_adapter.dart b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
index 9a4097f..2b00b61 100644
--- a/pkg/compiler/lib/src/kernel/front_end_adapter.dart
+++ b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
@@ -37,7 +37,7 @@
api.Input input;
try {
input = await fs.inputProvider
- .readFromUri(uri, inputKind: api.InputKind.utf8);
+ .readFromUri(uri, inputKind: api.InputKind.UTF8);
} catch (e) {
throw new fe.FileSystemException(uri, '$e');
}
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index ef19c0b..1872ee8 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -36,7 +36,6 @@
import '../options.dart';
import '../patch_parser.dart';
import '../resolved_uri_translator.dart';
-import '../serialization/task.dart';
import '../universe/class_hierarchy_builder.dart';
import '../universe/world_builder.dart';
import '../universe/world_impact.dart';
@@ -77,7 +76,6 @@
ScriptLoader scriptLoader,
api.CompilerInput compilerInput,
ElementScanner scriptScanner,
- LibraryDeserializer deserializer,
PatchResolverFunction patchResolverFunc,
PatchParserTask patchParser,
env.Environment environment,
diff --git a/pkg/compiler/lib/src/kernel/types.dart b/pkg/compiler/lib/src/kernel/types.dart
index b4be3ff..3f6a1a6 100644
--- a/pkg/compiler/lib/src/kernel/types.dart
+++ b/pkg/compiler/lib/src/kernel/types.dart
@@ -95,9 +95,8 @@
final KernelToElementMapBase elementMap;
_KernelOrderedTypeSetBuilder(this.elementMap, ClassEntity cls)
- : super(cls,
- reporter: elementMap.reporter,
- objectType: elementMap.commonElements.objectType);
+ : super(cls, elementMap.commonElements.objectType,
+ reporter: elementMap.reporter);
// TODO(sigmund): delete once Issue #31118 is fixed.
@override
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 33ca393..b96adbd 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -45,7 +45,6 @@
import 'patch_parser.dart' show PatchParserTask;
import 'resolved_uri_translator.dart';
import 'script.dart';
-import 'serialization/serialization.dart' show LibraryDeserializer;
import 'tree/tree.dart';
import 'util/util.dart' show Link, LinkBuilder;
@@ -217,9 +216,7 @@
}
}
-/// Interface for an entity that provide libraries. For instance from normal
-/// library loading or from deserialization.
-// TODO(johnniwinther): Use this to integrate deserialized libraries better.
+/// Interface for an entity that provide libraries.
abstract class LibraryProvider {
/// Looks up the library with the [canonicalUri].
LibraryEntity lookupLibrary(Uri canonicalUri);
@@ -335,10 +332,6 @@
/// about imports and exports. Used when loading libraries from source.
final ElementScanner scanner;
- /// Provides a diet element model for a library. Used when loading libraries
- /// from a serialized form.
- final LibraryDeserializer deserializer;
-
/// Definitions provided via the `-D` command line flags. Used to resolve
/// conditional imports.
final Environment environment;
@@ -360,7 +353,6 @@
this.uriTranslator,
this.scriptLoader,
this.scanner,
- this.deserializer,
this._patchResolverFunc,
this._patchParserTask,
this.environment,
@@ -671,29 +663,6 @@
});
}
- /// Loads the deserialized [library] with the [handler].
- ///
- /// All libraries imported or exported transitively from [library] will be
- /// loaded as well.
- Future<LibraryElement> loadDeserializedLibrary(
- LibraryDependencyHandler handler, LibraryElement library) {
- libraryCanonicalUriMap[library.canonicalUri] = library;
- handler.registerNewLibrary(library);
- return Future.forEach(library.imports, (ImportElement import) {
- Uri resolvedUri = library.canonicalUri.resolveUri(import.uri);
- return createLibrary(handler, library, resolvedUri, library);
- }).then((_) {
- return Future.forEach(library.exports, (ExportElement export) {
- Uri resolvedUri = library.canonicalUri.resolveUri(export.uri);
- return createLibrary(handler, library, resolvedUri, library);
- }).then((_) {
- // TODO(johnniwinther): Shouldn't there be an [ImportElement] for the
- // implicit import of dart:core?
- return createLibrary(handler, library, Uris.dart_core, library);
- }).then((_) => library);
- });
- }
-
Future<Script> _readScript(
Spannable spannable, Uri readableUri, Uri resolvedUri) {
if (readableUri == null) {
@@ -718,10 +687,6 @@
if (library != null) {
return new Future.value(library);
}
- library = await deserializer.readLibrary(resolvedUri);
- if (library != null) {
- return loadDeserializedLibrary(handler, library);
- }
return reporter.withCurrentElement(importingLibrary, () {
return _readScript(spannable, readableUri, resolvedUri)
.then((Script script) async {
@@ -770,9 +735,7 @@
if (element.isPlatformLibrary &&
// Don't patch library currently disallowed.
!element.isSynthesized &&
- !element.isPatched &&
- // Don't patch deserialized libraries.
- !deserializer.isDeserialized(element)) {
+ !element.isPatched) {
// Apply patch, if any.
Uri patchUri = _patchResolverFunc(element.canonicalUri.path);
if (patchUri != null) {
@@ -1690,44 +1653,6 @@
String toString() => 'root=$rootLibrary,libraries=${_newLibraries}';
}
-// TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems
-// rather low-level. It might be more practical to split the library-loading
-// task itself. The task would continue to do the work of recursively loading
-// dependencies, but it can delegate to a set of subloaders how to do the actual
-// loading. We would then have a list of subloaders that use different
-// implementations: in-memory cache, deserialization, scanning from files.
-//
-// For example, the API might look like this:
-//
-// /// APIs to create [LibraryElement] and [CompilationUnitElements] given it's
-// /// URI.
-// abstract class SubLoader {
-// /// Return the library corresponding to the script at [uri].
-// ///
-// /// Use [spannable] for error reporting.
-// Future<LibraryElement> createLibrary(Uri uri, [Spannable spannable]);
-//
-// /// Return the compilation unit at [uri] that is a part of [library].
-// Future<CompilationUnitElement> createUnit(Uri uri, LibraryElement library,
-// [Spannable spannable]);
-// }
-//
-// /// A [SubLoader] that parses a serialized form of the element model to
-// /// produce the results.
-// class DeserializingUnitElementCreator implements SubLoader {
-// ...
-// }
-//
-// /// A [SubLoader] that finds the script sources and does a diet parse
-// /// on them to produces the results.
-// class ScanningUnitElementCreator implements SubLoader {
-// ...
-// }
-//
-// Each subloader would internally create what they need (a scanner, a
-// deserializer), and we wouldn't need to create abstractions to pass in
-// something that is only used by the loader.
-
/// API used by the library loader to request scripts from the compiler system.
abstract class ScriptLoader {
/// Load script from a readable [uri], report any errors using the location of
diff --git a/pkg/compiler/lib/src/native/resolver.dart b/pkg/compiler/lib/src/native/resolver.dart
index 5ecdf95..9f7ff83 100644
--- a/pkg/compiler/lib/src/native/resolver.dart
+++ b/pkg/compiler/lib/src/native/resolver.dart
@@ -280,22 +280,6 @@
}
@override
- bool _processMethodAnnotations(MethodElement method) {
- if (_compiler.serialization.isDeserialized(method)) {
- return false;
- }
- return super._processMethodAnnotations(method);
- }
-
- @override
- bool _processFieldAnnotations(FieldElement element) {
- if (_compiler.serialization.isDeserialized(element)) {
- return false;
- }
- return super._processFieldAnnotations(element);
- }
-
- @override
NativeBehavior resolveJsCall(Send node, ForeignResolver resolver) {
return NativeBehavior.ofJsCallSend(
node, _reporter, _compiler.parsingContext, commonElements, resolver);
diff --git a/pkg/compiler/lib/src/old_to_new_api.dart b/pkg/compiler/lib/src/old_to_new_api.dart
index 78f85d1..0363419 100644
--- a/pkg/compiler/lib/src/old_to_new_api.dart
+++ b/pkg/compiler/lib/src/old_to_new_api.dart
@@ -22,10 +22,10 @@
LegacyCompilerInput(this._inputProvider);
@override
- Future<Input> readFromUri(Uri uri, {InputKind inputKind: InputKind.utf8}) {
+ Future<Input> readFromUri(Uri uri, {InputKind inputKind: InputKind.UTF8}) {
return _inputProvider(uri).then((/*String|List<int>*/ data) {
switch (inputKind) {
- case InputKind.utf8:
+ case InputKind.UTF8:
SourceFile sourceFile;
if (data is List<int>) {
sourceFile = new Utf8BytesSourceFile(uri, data);
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 607e8e6..f72edf3 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -187,18 +187,6 @@
/// Location of the kernel platform `.dill` files.
Uri platformBinaries;
- /// The locations of serialized data used for resolution.
- List<Uri> resolutionInputs;
-
- /// The location of the serialized data from resolution.
- Uri resolutionOutput;
-
- /// If `true`, sources are resolved and serialized.
- bool resolveOnly = false;
-
- /// If `true`, sources are only available from serialized data.
- bool compileOnly = false;
-
/// URI where the compiler should generate the output source map file.
Uri sourceMapUri;
@@ -339,7 +327,6 @@
..librariesSpecificationUri = _resolveLibrariesSpecification(libraryRoot)
..platformBinaries =
platformBinaries ?? _extractUriOption(options, '--platform-binaries=')
- ..resolveOnly = _hasOption(options, Flags.resolveOnly)
..sourceMapUri = _extractUriOption(options, '--source-map=')
..strongMode = _hasOption(options, Flags.strongMode)
..omitImplicitChecks = _hasOption(options, Flags.omitImplicitChecks)
@@ -383,8 +370,7 @@
}
void deriveOptions() {
- if (resolveOnly) analyzeAll = true;
- if (analyzeSignaturesOnly || analyzeAll || resolveOnly) analyzeOnly = true;
+ if (analyzeSignaturesOnly || analyzeAll) analyzeOnly = true;
if (useKernel) generateCodeWithCompileTimeErrors = false;
if (platformConfigUri == null) {
platformConfigUri = _resolvePlatformConfig(libraryRoot, null, const []);
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index a134269..860d67f 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -164,12 +164,9 @@
final DiagnosticReporter reporter;
final ClassEntity cls;
- InterfaceType _objectType;
+ final InterfaceType _objectType;
- // TODO(johnniwinther): Provide access to `Object` in deserialization and
- // make [objectType] mandatory.
- OrderedTypeSetBuilderBase(this.cls, {this.reporter, InterfaceType objectType})
- : this._objectType = objectType;
+ OrderedTypeSetBuilderBase(this.cls, this._objectType, {this.reporter});
InterfaceType getThisType(covariant ClassEntity cls);
InterfaceType substByContext(
@@ -311,9 +308,9 @@
}
class ResolutionOrderedTypeSetBuilder extends OrderedTypeSetBuilderBase {
- ResolutionOrderedTypeSetBuilder(ClassElement cls,
- {DiagnosticReporter reporter, InterfaceType objectType})
- : super(cls, reporter: reporter, objectType: objectType);
+ ResolutionOrderedTypeSetBuilder(ClassElement cls, InterfaceType objectType,
+ {DiagnosticReporter reporter})
+ : super(cls, objectType, reporter: reporter);
InterfaceType getThisType(ClassElement cls) => cls.thisType;
@@ -326,18 +323,4 @@
OrderedTypeSet getOrderedTypeSet(ClassElement cls) =>
cls.allSupertypesAndSelf;
-
- OrderedTypeSet createOrderedTypeSet(
- InterfaceType supertype, Link<DartType> interfaces) {
- if (_objectType == null) {
- // Find `Object` through in hierarchy. This is used for serialization
- // where it is assumed that the hierarchy is valid.
- ResolutionInterfaceType objectType = supertype;
- while (!objectType.isObject) {
- objectType = objectType.element.supertype;
- }
- _objectType = objectType;
- }
- return super.createOrderedTypeSet(supertype, interfaces);
- }
}
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 3f77774..71ea505 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -569,21 +569,6 @@
}
@override
- void handleModifier(Token token) {
- pushNode(new Identifier(token));
- }
-
- @override
- void handleModifiers(int count) {
- if (count == 0) {
- pushNode(Modifiers.EMPTY);
- } else {
- NodeList modifierNodes = makeNodeList(count, null, null, ' ');
- pushNode(new Modifiers(modifierNodes));
- }
- }
-
- @override
Token handleUnrecoverableError(Token token, Message message) {
Token next = handleError(token, message);
if (next == null &&
diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart
index bb0925d..4ac6f34 100644
--- a/pkg/compiler/lib/src/parser/node_listener.dart
+++ b/pkg/compiler/lib/src/parser/node_listener.dart
@@ -273,6 +273,24 @@
}
@override
+ void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+ Token varFinalOrConst) {
+ if (covariantToken == null && varFinalOrConst == null) {
+ pushNode(Modifiers.EMPTY);
+ } else {
+ Link<Node> poppedNodes = const Link<Node>();
+ if (covariantToken != null) {
+ poppedNodes = poppedNodes.prepend(new Identifier(covariantToken));
+ }
+ if (varFinalOrConst != null) {
+ poppedNodes = poppedNodes.prepend(new Identifier(varFinalOrConst));
+ }
+ NodeList modifierNodes = new NodeList(null, poppedNodes, null, ' ');
+ pushNode(new Modifiers(modifierNodes));
+ }
+ }
+
+ @override
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
Expression name = popNode();
@@ -1080,7 +1098,12 @@
pushNode(factoryNode);
++modifierCount;
}
- handleModifiers(modifierCount);
+ if (modifierCount == 0) {
+ pushNode(Modifiers.EMPTY);
+ } else {
+ NodeList modifierNodes = makeNodeList(modifierCount, null, null, ' ');
+ pushNode(new Modifiers(modifierNodes));
+ }
modifiers = popNode();
pushNode(new FunctionExpression(
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
index 9ba287b..30e5f0d 100644
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -546,8 +546,9 @@
if (cls.allSupertypesAndSelf != null) return;
final ResolutionInterfaceType supertype = cls.supertype;
if (supertype != null) {
- cls.allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(cls,
- reporter: reporter, objectType: commonElements.objectType)
+ cls.allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(
+ cls, commonElements.objectType,
+ reporter: reporter)
.createOrderedTypeSet(supertype, cls.interfaces);
} else {
assert(cls == resolution.commonElements.objectClass);
diff --git a/pkg/compiler/lib/src/resolution/deferred_load.dart b/pkg/compiler/lib/src/resolution/deferred_load.dart
index 1ed033a..e826a25 100644
--- a/pkg/compiler/lib/src/resolution/deferred_load.dart
+++ b/pkg/compiler/lib/src/resolution/deferred_load.dart
@@ -161,12 +161,6 @@
treeElements
.forEachConstantNode((ast.Node node, ConstantExpression expression) {
if (metadataNodes.contains(node)) return;
- if (compiler.serialization.isDeserialized(element)) {
- if (!expression.isPotential) {
- // Enforce evaluation of [expression].
- backend.constants.getConstantValue(expression);
- }
- }
// Explicitly depend on the backend constants.
if (backend.constants.hasConstantValue(expression)) {
diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
index 7691c5a..c4bfb96 100644
--- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
@@ -39,7 +39,6 @@
import '../native/resolver.dart';
import '../patch_parser.dart';
import '../resolved_uri_translator.dart';
-import '../serialization/task.dart';
import '../tree/tree.dart' show Node;
import '../universe/call_structure.dart';
import '../universe/class_hierarchy_builder.dart';
@@ -81,7 +80,6 @@
ScriptLoader scriptLoader,
api.CompilerInput compilerInput,
ElementScanner scriptScanner,
- LibraryDeserializer deserializer,
PatchResolverFunction patchResolverFunc,
PatchParserTask patchParser,
Environment environment,
@@ -91,7 +89,6 @@
uriTranslator,
scriptLoader,
scriptScanner,
- deserializer,
patchResolverFunc,
patchParser,
environment,
diff --git a/pkg/compiler/lib/src/serialization/constant_serialization.dart b/pkg/compiler/lib/src/serialization/constant_serialization.dart
deleted file mode 100644
index 46fade8..0000000
--- a/pkg/compiler/lib/src/serialization/constant_serialization.dart
+++ /dev/null
@@ -1,459 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.constants;
-
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../elements/elements.dart'
- show
- ConstructorElement,
- FieldElement,
- LocalVariableElement,
- MethodElement,
- ImportElement;
-import '../elements/entities.dart' show FieldEntity;
-import '../elements/operators.dart';
-import '../elements/resolution_types.dart';
-import '../universe/call_structure.dart' show CallStructure;
-import 'keys.dart';
-import 'serialization.dart';
-
-/// Visitor that serializes a [ConstantExpression] by encoding it into an
-/// [ObjectEncoder].
-///
-/// This class is called from the [Serializer] when a [ConstantExpression] needs
-/// serialization. The [ObjectEncoder] ensures that any [Element],
-/// [ResolutionDartType], and other [ConstantExpression] that the serialized
-/// [ConstantExpression] depends upon are also serialized.
-class ConstantSerializer
- extends ConstantExpressionVisitor<dynamic, ObjectEncoder> {
- const ConstantSerializer();
-
- @override
- void visitBinary(BinaryConstantExpression exp, ObjectEncoder encoder) {
- encoder.setEnum(Key.OPERATOR, exp.operator.kind);
- encoder.setConstant(Key.LEFT, exp.left);
- encoder.setConstant(Key.RIGHT, exp.right);
- }
-
- @override
- void visitConcatenate(
- ConcatenateConstantExpression exp, ObjectEncoder encoder) {
- encoder.setConstants(Key.ARGUMENTS, exp.expressions);
- }
-
- @override
- void visitConditional(
- ConditionalConstantExpression exp, ObjectEncoder encoder) {
- encoder.setConstant(Key.CONDITION, exp.condition);
- encoder.setConstant(Key.TRUE, exp.trueExp);
- encoder.setConstant(Key.FALSE, exp.falseExp);
- }
-
- @override
- void visitConstructed(
- ConstructedConstantExpression exp, ObjectEncoder encoder) {
- ConstructorElement constructor = exp.target;
- ResolutionInterfaceType type = exp.type;
- encoder.setElement(Key.ELEMENT, constructor);
- encoder.setType(Key.TYPE, type);
- encoder.setStrings(Key.NAMES, exp.callStructure.namedArguments);
- encoder.setConstants(Key.ARGUMENTS, exp.arguments);
- }
-
- @override
- void visitFunction(FunctionConstantExpression exp, ObjectEncoder encoder) {
- MethodElement function = exp.element;
- encoder.setElement(Key.ELEMENT, function);
- }
-
- @override
- void visitIdentical(IdenticalConstantExpression exp, ObjectEncoder encoder) {
- encoder.setConstant(Key.LEFT, exp.left);
- encoder.setConstant(Key.RIGHT, exp.right);
- }
-
- @override
- void visitList(ListConstantExpression exp, ObjectEncoder encoder) {
- ResolutionInterfaceType type = exp.type;
- encoder.setType(Key.TYPE, type);
- encoder.setConstants(Key.VALUES, exp.values);
- }
-
- @override
- void visitMap(MapConstantExpression exp, ObjectEncoder encoder) {
- ResolutionInterfaceType type = exp.type;
- encoder.setType(Key.TYPE, type);
- encoder.setConstants(Key.KEYS, exp.keys);
- encoder.setConstants(Key.VALUES, exp.values);
- }
-
- @override
- void visitBool(BoolConstantExpression exp, ObjectEncoder encoder) {
- encoder.setBool(Key.VALUE, exp.boolValue);
- }
-
- @override
- void visitInt(IntConstantExpression exp, ObjectEncoder encoder) {
- encoder.setInt(Key.VALUE, exp.intValue);
- }
-
- @override
- void visitDouble(DoubleConstantExpression exp, ObjectEncoder encoder) {
- encoder.setDouble(Key.VALUE, exp.doubleValue);
- }
-
- @override
- void visitString(StringConstantExpression exp, ObjectEncoder encoder) {
- encoder.setString(Key.VALUE, exp.stringValue);
- }
-
- @override
- void visitNull(NullConstantExpression exp, ObjectEncoder encoder) {
- // No additional data needed.
- }
-
- @override
- void visitSymbol(SymbolConstantExpression exp, ObjectEncoder encoder) {
- encoder.setString(Key.NAME, exp.name);
- }
-
- @override
- void visitType(TypeConstantExpression exp, ObjectEncoder encoder) {
- encoder.setType(Key.TYPE, exp.type);
- encoder.setString(Key.NAME, exp.name);
- }
-
- @override
- void visitUnary(UnaryConstantExpression exp, ObjectEncoder encoder) {
- encoder.setEnum(Key.OPERATOR, exp.operator.kind);
- encoder.setConstant(Key.EXPRESSION, exp.expression);
- }
-
- @override
- void visitField(FieldConstantExpression exp, ObjectEncoder encoder) {
- FieldElement field = exp.element;
- encoder.setElement(Key.ELEMENT, field);
- }
-
- @override
- void visitLocalVariable(
- LocalVariableConstantExpression exp, ObjectEncoder encoder) {
- LocalVariableElement local = exp.element;
- encoder.setElement(Key.ELEMENT, local);
- }
-
- @override
- void visitPositional(PositionalArgumentReference exp, ObjectEncoder encoder) {
- encoder.setInt(Key.INDEX, exp.index);
- }
-
- @override
- void visitNamed(NamedArgumentReference exp, ObjectEncoder encoder) {
- encoder.setString(Key.NAME, exp.name);
- }
-
- @override
- void visitBoolFromEnvironment(
- BoolFromEnvironmentConstantExpression exp, ObjectEncoder encoder) {
- encoder.setConstant(Key.NAME, exp.name);
- if (exp.defaultValue != null) {
- encoder.setConstant(Key.DEFAULT, exp.defaultValue);
- }
- }
-
- @override
- void visitIntFromEnvironment(
- IntFromEnvironmentConstantExpression exp, ObjectEncoder encoder) {
- encoder.setConstant(Key.NAME, exp.name);
- if (exp.defaultValue != null) {
- encoder.setConstant(Key.DEFAULT, exp.defaultValue);
- }
- }
-
- @override
- void visitStringFromEnvironment(
- StringFromEnvironmentConstantExpression exp, ObjectEncoder encoder) {
- encoder.setConstant(Key.NAME, exp.name);
- if (exp.defaultValue != null) {
- encoder.setConstant(Key.DEFAULT, exp.defaultValue);
- }
- }
-
- @override
- void visitStringLength(
- StringLengthConstantExpression exp, ObjectEncoder encoder) {
- encoder.setConstant(Key.EXPRESSION, exp.expression);
- }
-
- @override
- void visitDeferred(DeferredConstantExpression exp, ObjectEncoder encoder) {
- encoder.setElement(Key.IMPORT, exp.import as ImportElement);
- encoder.setConstant(Key.EXPRESSION, exp.expression);
- }
-
- @override
- void visitAssert(AssertConstantExpression exp, ObjectEncoder context) {
- throw new UnsupportedError("AssertConstantExpression is not supported.");
- }
-
- @override
- void visitAs(AsConstantExpression exp, ObjectEncoder encoder) {
- throw new UnsupportedError("AsConstantExpression is not supported.");
- }
-}
-
-/// Utility class for deserializing [ConstantExpression]s.
-///
-/// This is used by the [Deserializer].
-class ConstantDeserializer {
- /// Deserializes a [ConstantExpression] from an [ObjectDecoder].
- ///
- /// The class is called from the [Deserializer] when a [ConstantExpression]
- /// needs deserialization. The [ObjectDecoder] ensures that any [Element],
- /// [ResolutionDartType], and other [ConstantExpression] that the deserialized
- /// [ConstantExpression] depends upon are available.
- static ConstantExpression deserialize(ObjectDecoder decoder) {
- ConstantExpressionKind kind =
- decoder.getEnum(Key.KIND, ConstantExpressionKind.values);
- switch (kind) {
- case ConstantExpressionKind.BINARY:
- BinaryOperator operator = BinaryOperator
- .fromKind(decoder.getEnum(Key.OPERATOR, BinaryOperatorKind.values));
- return new BinaryConstantExpression(decoder.getConstant(Key.LEFT),
- operator, decoder.getConstant(Key.RIGHT));
- case ConstantExpressionKind.BOOL:
- return new BoolConstantExpression(decoder.getBool(Key.VALUE));
- case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT:
- return new BoolFromEnvironmentConstantExpression(
- decoder.getConstant(Key.NAME),
- decoder.getConstant(Key.DEFAULT, isOptional: true));
- case ConstantExpressionKind.CONCATENATE:
- return new ConcatenateConstantExpression(
- decoder.getConstants(Key.ARGUMENTS));
- case ConstantExpressionKind.CONDITIONAL:
- return new ConditionalConstantExpression(
- decoder.getConstant(Key.CONDITION),
- decoder.getConstant(Key.TRUE),
- decoder.getConstant(Key.FALSE));
- case ConstantExpressionKind.CONSTRUCTED:
- ResolutionInterfaceType type = decoder.getType(Key.TYPE);
- ConstructorElement constructor = decoder.getElement(Key.ELEMENT);
- List<String> names = decoder.getStrings(Key.NAMES, isOptional: true);
- List<ConstantExpression> arguments =
- decoder.getConstants(Key.ARGUMENTS, isOptional: true);
- return new ConstructedConstantExpression(type, constructor,
- new CallStructure(arguments.length, names), arguments);
- case ConstantExpressionKind.DOUBLE:
- return new DoubleConstantExpression(decoder.getDouble(Key.VALUE));
- case ConstantExpressionKind.ERRONEOUS:
- break;
- case ConstantExpressionKind.FUNCTION:
- MethodElement function = decoder.getElement(Key.ELEMENT);
- return new FunctionConstantExpression(function, function.type);
- case ConstantExpressionKind.IDENTICAL:
- return new IdenticalConstantExpression(
- decoder.getConstant(Key.LEFT), decoder.getConstant(Key.RIGHT));
- case ConstantExpressionKind.INT:
- return new IntConstantExpression(decoder.getInt(Key.VALUE));
- case ConstantExpressionKind.INT_FROM_ENVIRONMENT:
- return new IntFromEnvironmentConstantExpression(
- decoder.getConstant(Key.NAME),
- decoder.getConstant(Key.DEFAULT, isOptional: true));
- case ConstantExpressionKind.LIST:
- ResolutionInterfaceType type = decoder.getType(Key.TYPE);
- return new ListConstantExpression(
- type, decoder.getConstants(Key.VALUES, isOptional: true));
- case ConstantExpressionKind.MAP:
- ResolutionInterfaceType type = decoder.getType(Key.TYPE);
- return new MapConstantExpression(
- type,
- decoder.getConstants(Key.KEYS, isOptional: true),
- decoder.getConstants(Key.VALUES, isOptional: true));
- case ConstantExpressionKind.NULL:
- return new NullConstantExpression();
- case ConstantExpressionKind.STRING:
- return new StringConstantExpression(decoder.getString(Key.VALUE));
- case ConstantExpressionKind.STRING_FROM_ENVIRONMENT:
- return new StringFromEnvironmentConstantExpression(
- decoder.getConstant(Key.NAME),
- decoder.getConstant(Key.DEFAULT, isOptional: true));
- case ConstantExpressionKind.STRING_LENGTH:
- return new StringLengthConstantExpression(
- decoder.getConstant(Key.EXPRESSION));
- case ConstantExpressionKind.SYMBOL:
- return new SymbolConstantExpression(decoder.getString(Key.NAME));
- case ConstantExpressionKind.TYPE:
- return new TypeConstantExpression(
- decoder.getType(Key.TYPE), decoder.getString(Key.NAME));
- case ConstantExpressionKind.UNARY:
- UnaryOperator operator = UnaryOperator
- .fromKind(decoder.getEnum(Key.OPERATOR, UnaryOperatorKind.values));
- return new UnaryConstantExpression(
- operator, decoder.getConstant(Key.EXPRESSION));
- case ConstantExpressionKind.FIELD:
- FieldElement field = decoder.getElement(Key.ELEMENT);
- return new FieldConstantExpression(field);
- case ConstantExpressionKind.LOCAL_VARIABLE:
- LocalVariableElement local = decoder.getElement(Key.ELEMENT);
- return new LocalVariableConstantExpression(local);
-
- case ConstantExpressionKind.POSITIONAL_REFERENCE:
- return new PositionalArgumentReference(decoder.getInt(Key.INDEX));
- case ConstantExpressionKind.NAMED_REFERENCE:
- return new NamedArgumentReference(decoder.getString(Key.NAME));
- case ConstantExpressionKind.DEFERRED:
- return new DeferredConstantExpression(
- decoder.getConstant(Key.EXPRESSION),
- decoder.getElement(Key.IMPORT) as ImportElement);
- case ConstantExpressionKind.SYNTHETIC:
- case ConstantExpressionKind.ASSERT:
- case ConstantExpressionKind.AS:
- }
- throw new UnsupportedError("Unexpected constant kind: ${kind} in $decoder");
- }
-}
-
-/// Visitor that serializes a [ConstantConstructor] by encoding it into an
-/// [ObjectEncoder].
-///
-/// This class is called from the [ConstructorSerializer] when the [Serializer]
-/// is serializing constant constructor. The [ObjectEncoder] ensures that any
-/// [Element], [ResolutionDartType], and [ConstantExpression] that the
-/// serialized [ConstantConstructor] depends upon are also serialized.
-class ConstantConstructorSerializer
- extends ConstantConstructorVisitor<dynamic, ObjectEncoder> {
- const ConstantConstructorSerializer();
-
- @override
- void visit(ConstantConstructor constantConstructor, ObjectEncoder encoder) {
- encoder.setEnum(Key.KIND, constantConstructor.kind);
- constantConstructor.accept(this, encoder);
- }
-
- @override
- void visitGenerative(
- GenerativeConstantConstructor constructor, ObjectEncoder encoder) {
- ResolutionInterfaceType type = constructor.type;
- encoder.setType(Key.TYPE, type);
- MapEncoder defaults = encoder.createMap(Key.DEFAULTS);
- constructor.defaultValues.forEach((key, e) {
- defaults.setConstant('$key', e);
- });
- ListEncoder fields = encoder.createList(Key.FIELDS);
- constructor.fieldMap.forEach((FieldEntity _f, ConstantExpression e) {
- FieldElement f = _f;
- ObjectEncoder fieldSerializer = fields.createObject();
- fieldSerializer.setElement(Key.FIELD, f);
- fieldSerializer.setConstant(Key.CONSTANT, e);
- });
- if (constructor.superConstructorInvocation != null) {
- encoder.setConstant(
- Key.CONSTRUCTOR, constructor.superConstructorInvocation);
- }
- }
-
- @override
- void visitRedirectingFactory(
- RedirectingFactoryConstantConstructor constructor,
- ObjectEncoder encoder) {
- encoder.setConstant(
- Key.CONSTRUCTOR, constructor.targetConstructorInvocation);
- }
-
- @override
- void visitRedirectingGenerative(
- RedirectingGenerativeConstantConstructor constructor,
- ObjectEncoder encoder) {
- MapEncoder defaults = encoder.createMap(Key.DEFAULTS);
- constructor.defaultValues.forEach((key, ConstantExpression e) {
- defaults.setConstant('$key', e);
- });
- encoder.setConstant(Key.CONSTRUCTOR, constructor.thisConstructorInvocation);
- }
-
- @override
- void visitErroneous(
- ErroneousConstantConstructor constructor, ObjectEncoder arg) {
- throw new UnsupportedError("ConstantConstructorSerializer.visitErroneous");
- }
-}
-
-/// Utility class for deserializing [ConstantConstructor]s.
-///
-/// This is used by the [ConstructorElementZ].
-class ConstantConstructorDeserializer {
- /// Deserializes a [ConstantConstructor] from an [ObjectDecoder].
- ///
- /// The class is called from the [Deserializer] when a constant constructor
- /// needs deserialization. The [ObjectDecoder] ensures that any [Element],
- /// [ResolutionDartType], and [ConstantExpression] that the deserialized
- /// [ConstantConstructor] depends upon are available.
- // ignore: MISSING_RETURN
- static ConstantConstructor deserialize(ObjectDecoder decoder) {
- ConstantConstructorKind kind =
- decoder.getEnum(Key.KIND, ConstantConstructorKind.values);
-
- ResolutionDartType readType() {
- return decoder.getType(Key.TYPE);
- }
-
- Map<dynamic /*int|String*/, ConstantExpression> readDefaults() {
- Map<dynamic, ConstantExpression> defaultValues =
- <dynamic, ConstantExpression>{};
- if (decoder.containsKey(Key.DEFAULTS)) {
- MapDecoder defaultsMap = decoder.getMap(Key.DEFAULTS);
- defaultsMap.forEachKey((String key) {
- int index = int.parse(key, onError: (_) => null);
- if (index != null) {
- defaultValues[index] = defaultsMap.getConstant(key);
- } else {
- defaultValues[key] = defaultsMap.getConstant(key);
- }
- });
- }
- return defaultValues;
- }
-
- Map<FieldElement, ConstantExpression> readFields() {
- Map<FieldElement, ConstantExpression> fieldMap =
- <FieldElement, ConstantExpression>{};
- if (decoder.containsKey(Key.FIELDS)) {
- ListDecoder fieldsList = decoder.getList(Key.FIELDS);
- for (int i = 0; i < fieldsList.length; i++) {
- ObjectDecoder object = fieldsList.getObject(i);
- FieldElement field = object.getElement(Key.FIELD);
- ConstantExpression constant = object.getConstant(Key.CONSTANT);
- fieldMap[field] = constant;
- }
- }
- return fieldMap;
- }
-
- ConstructedConstantExpression readConstructorInvocation() {
- return decoder.getConstant(Key.CONSTRUCTOR, isOptional: true);
- }
-
- switch (kind) {
- case ConstantConstructorKind.GENERATIVE:
- ResolutionInterfaceType type = readType();
- return new GenerativeConstantConstructor(
- type,
- readDefaults(),
- readFields(),
- const <AssertConstantExpression>[],
- readConstructorInvocation());
- case ConstantConstructorKind.REDIRECTING_GENERATIVE:
- return new RedirectingGenerativeConstantConstructor(
- readDefaults(), readConstructorInvocation());
- case ConstantConstructorKind.REDIRECTING_FACTORY:
- return new RedirectingFactoryConstantConstructor(
- readConstructorInvocation());
- case ConstantConstructorKind.ERRONEOUS:
- throw new UnsupportedError(
- 'Unsupported constant constructor kind: $kind');
- }
- }
-}
diff --git a/pkg/compiler/lib/src/serialization/element_serialization.dart b/pkg/compiler/lib/src/serialization/element_serialization.dart
deleted file mode 100644
index 5fa61a0..0000000
--- a/pkg/compiler/lib/src/serialization/element_serialization.dart
+++ /dev/null
@@ -1,958 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.elements;
-
-import '../common.dart';
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../diagnostics/messages.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart'
- show
- AmbiguousImportX,
- DeferredLoaderGetterElementX,
- ErroneousElementX,
- WarnOnUseElementX,
- WrappedMessage;
-import 'constant_serialization.dart';
-import 'keys.dart';
-import 'modelz.dart';
-import 'serialization.dart';
-import 'serialization_util.dart';
-
-/// Enum kinds used for encoding [Element]s.
-enum SerializedElementKind {
- ERROR,
- LIBRARY,
- COMPILATION_UNIT,
- CLASS,
- ENUM,
- NAMED_MIXIN_APPLICATION,
- GENERATIVE_CONSTRUCTOR,
- DEFAULT_CONSTRUCTOR,
- FACTORY_CONSTRUCTOR,
- REDIRECTING_FACTORY_CONSTRUCTOR,
- FORWARDING_CONSTRUCTOR,
- TOPLEVEL_FIELD,
- STATIC_FIELD,
- INSTANCE_FIELD,
- ENUM_CONSTANT,
- TOPLEVEL_FUNCTION,
- TOPLEVEL_GETTER,
- TOPLEVEL_SETTER,
- STATIC_FUNCTION,
- STATIC_GETTER,
- STATIC_SETTER,
- INSTANCE_FUNCTION,
- INSTANCE_GETTER,
- INSTANCE_SETTER,
- LOCAL_FUNCTION,
- TYPEDEF,
- TYPEVARIABLE,
- PARAMETER,
- INITIALIZING_FORMAL,
- IMPORT,
- EXPORT,
- PREFIX,
- DEFERRED_LOAD_LIBRARY,
- LOCAL_VARIABLE,
- WARN_ON_USE,
- AMBIGUOUS,
- EXTERNAL_LIBRARY,
- EXTERNAL_LIBRARY_MEMBER,
- EXTERNAL_CLASS_MEMBER,
- EXTERNAL_CONSTRUCTOR,
-}
-
-/// Set of serializers used to serialize different kinds of elements by
-/// encoding into them into [ObjectEncoder]s.
-///
-/// This class is called from the [Serializer] when an [Element] needs
-/// serialization. The [ObjectEncoder] ensures that any [Element],
-/// [ResolutionDartType], and [ConstantExpression] that the serialized [Element]
-/// depends upon are also serialized.
-const List<ElementSerializer> ELEMENT_SERIALIZERS = const [
- const ErrorSerializer(),
- const LibrarySerializer(),
- const CompilationUnitSerializer(),
- const PrefixSerializer(),
- const DeferredLoadLibrarySerializer(),
- const ClassSerializer(),
- const ConstructorSerializer(),
- const FieldSerializer(),
- const FunctionSerializer(),
- const TypedefSerializer(),
- const TypeVariableSerializer(),
- const ParameterSerializer(),
- const ImportSerializer(),
- const ExportSerializer(),
- const LocalVariableSerializer(),
- const WarnOnUseSerializer(),
- const AmbiguousSerializer(),
-];
-
-/// Interface for a function that can serialize a set of element kinds.
-abstract class ElementSerializer {
- /// Returns the [SerializedElementKind] for [element] if this serializer
- /// supports serialization of [element] or `null` otherwise.
- SerializedElementKind getSerializedKind(Element element);
-
- /// Serializes [element] into the [encoder] using the [kind] computed
- /// by [getSerializedKind].
- void serialize(covariant Element element, ObjectEncoder encoder,
- SerializedElementKind kind);
-}
-
-class SerializerUtil {
- /// Serialize the declared members of [element] into [encoder].
- static void serializeMembers(
- Iterable<Element> members, ObjectEncoder encoder) {
- MapEncoder mapEncoder = encoder.createMap(Key.MEMBERS);
- for (Element member in members) {
- String name = member.name;
- if (member.isSetter) {
- name = '$name,=';
- }
- mapEncoder.setElement(name, member);
- }
- }
-
- /// Serialize the source position of [element] into [encoder].
- static void serializePosition(Element element, ObjectEncoder encoder) {
- if (element.sourcePosition != null) {
- SourceSpan position = element.sourcePosition;
- encoder.setInt(Key.OFFSET, position.begin);
- // TODO(johnniwinther): What is the base URI in the case?
- if (position.uri != element.compilationUnit.script.resourceUri) {
- encoder.setUri(Key.URI, element.library.canonicalUri, position.uri);
- }
- int length = position.end - position.begin;
- if (element.name.length != length) {
- encoder.setInt(Key.LENGTH, length);
- }
- }
- }
-
- /// Serialize the metadata of [element] into [encoder].
- static void serializeMetadata(Element element, ObjectEncoder encoder) {
- ListEncoder list;
-
- void encodeAnnotation(MetadataAnnotation metadata) {
- ObjectEncoder object = list.createObject();
- object.setElement(Key.ELEMENT, metadata.annotatedElement);
- SourceSpan sourcePosition = metadata.sourcePosition;
- // TODO(johnniwinther): What is the base URI here?
- object.setUri(Key.URI, sourcePosition.uri, sourcePosition.uri);
- object.setInt(Key.OFFSET, sourcePosition.begin);
- object.setInt(Key.LENGTH, sourcePosition.end - sourcePosition.begin);
- object.setConstant(Key.CONSTANT, metadata.constant);
- }
-
- if (element.metadata.isNotEmpty) {
- list = encoder.createList(Key.METADATA);
- element.metadata.forEach(encodeAnnotation);
- }
- if (element.isPatched && element.implementation.metadata.isNotEmpty) {
- list ??= encoder.createList(Key.METADATA);
- element.implementation.metadata.forEach(encodeAnnotation);
- }
- }
-
- /// Serialize the parent relation for [element] into [encoder], i.e library,
- /// enclosing class, and compilation unit references.
- static void serializeParentRelation(Element element, ObjectEncoder encoder) {
- if (element.enclosingClass != null) {
- encoder.setElement(Key.CLASS, element.enclosingClass);
- if (element.enclosingClass.compilationUnit != element.compilationUnit) {
- encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
- }
- } else {
- encoder.setElement(Key.LIBRARY, element.library);
- encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
- }
- }
-
- /// Serialize the parameters of [element] into [encoder].
- static void serializeParameters(
- FunctionElement element, ObjectEncoder encoder) {
- ResolutionFunctionType type = element.type;
- encoder.setType(Key.RETURN_TYPE, type.returnType);
- encoder.setElements(Key.PARAMETERS, element.parameters);
- }
-
- /// Returns a function that adds the underlying declared elements for a
- /// particular element into [set].
- ///
- /// For instance, for an [AbstractFieldElement] the getter and setter elements
- /// are added, if available.
- static flattenElements(Set<Element> set) {
- return (Element element) {
- if (element.isPatch) return;
- // TODO(johnniwinther): Handle ambiguous elements.
- if (element.isAmbiguous) return;
- if (element.isAbstractField) {
- AbstractFieldElement abstractField = element;
- if (abstractField.getter != null) {
- set.add(abstractField.getter);
- }
- if (abstractField.setter != null) {
- set.add(abstractField.setter);
- }
- } else {
- set.add(element);
- }
- };
- }
-}
-
-class ErrorSerializer implements ElementSerializer {
- const ErrorSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isError) {
- return SerializedElementKind.ERROR;
- }
- return null;
- }
-
- void serialize(ErroneousElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- encoder.setElement(Key.ENCLOSING, element.enclosingElement);
- encoder.setString(Key.NAME, element.name);
- encoder.setEnum(Key.MESSAGE_KIND, element.messageKind);
- serializeMessageArguments(encoder, Key.ARGUMENTS, element.messageArguments);
- }
-}
-
-class LibrarySerializer implements ElementSerializer {
- const LibrarySerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isLibrary) {
- return SerializedElementKind.LIBRARY;
- }
- return null;
- }
-
- static List<Element> getMembers(LibraryElement element) {
- List<Element> members = <Element>[];
- element.implementation.forEachLocalMember((Element member) {
- if (!member.isPatch) {
- members.add(member);
- }
- });
- return members;
- }
-
- static List<CompilationUnitElement> getCompilationUnits(
- LibraryElement element) {
- List<CompilationUnitElement> compilationUnits = <CompilationUnitElement>[];
- compilationUnits.addAll(element.compilationUnits.toList());
- if (element.isPatched) {
- compilationUnits.addAll(element.implementation.compilationUnits.toList());
- }
- return compilationUnits;
- }
-
- static List<ImportElement> getImports(LibraryElement element) {
- List<ImportElement> imports = <ImportElement>[];
- imports.addAll(element.imports);
- if (element.isPatched) {
- imports.addAll(element.implementation.imports);
- }
- return imports;
- }
-
- static List<Element> getImportedElements(LibraryElement element) {
- Set<Element> importedElements = new Set<Element>();
- element.forEachImport(SerializerUtil.flattenElements(importedElements));
- if (element.isPatched) {
- element.implementation
- .forEachImport(SerializerUtil.flattenElements(importedElements));
- }
- return importedElements.toList();
- }
-
- static List<Element> getExportedElements(LibraryElement element) {
- Set<Element> exportedElements = new Set<Element>();
- element.forEachExport(SerializerUtil.flattenElements(exportedElements));
- return exportedElements.toList();
- }
-
- void serialize(LibraryElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- SerializerUtil.serializeMetadata(element, encoder);
- encoder.setUri(
- Key.CANONICAL_URI, element.canonicalUri, element.canonicalUri);
- encoder.setString(Key.LIBRARY_NAME, element.libraryName);
- SerializerUtil.serializeMembers(getMembers(element), encoder);
- encoder.setElement(Key.COMPILATION_UNIT, element.entryCompilationUnit);
- encoder.setElements(Key.COMPILATION_UNITS, getCompilationUnits(element));
- encoder.setElements(Key.IMPORTS, getImports(element));
- encoder.setElements(Key.EXPORTS, element.exports);
-
- List<Element> importedElements = getImportedElements(element);
- encoder.setElements(Key.IMPORT_SCOPE, importedElements);
- encoder.setElements(Key.EXPORT_SCOPE, getExportedElements(element));
-
- Map<Element, Iterable<ImportElement>> importsForMap =
- <Element, Iterable<ImportElement>>{};
-
- /// Map imports for [importedElement] in importsForMap.
- ///
- /// Imports are mapped to [AbstractFieldElement] which are not serialized
- /// so we use getter (or setter if there is no getter) as the key.
- void addImportsForElement(Element importedElement) {
- Element key = importedElement;
- if (importedElement.isDeferredLoaderGetter) {
- // Use [importedElement].
- } else if (importedElement.isGetter) {
- GetterElement getter = importedElement;
- importedElement = getter.abstractField;
- } else if (importedElement.isSetter) {
- SetterElement setter = importedElement;
- if (setter.getter != null) {
- return;
- }
- importedElement = setter.abstractField;
- }
- importsForMap.putIfAbsent(
- key, () => element.getImportsFor(importedElement));
- }
-
- for (ImportElement import in getImports(element)) {
- if (import.prefix != null) {
- Set<Element> importedElements = new Set<Element>();
- import.prefix.forEachLocalMember(
- SerializerUtil.flattenElements(importedElements));
- importedElements.forEach(addImportsForElement);
- }
- }
- importedElements.forEach(addImportsForElement);
-
- ListEncoder importsForEncoder = encoder.createList(Key.IMPORTS_FOR);
- importsForMap
- .forEach((Element importedElement, Iterable<ImportElement> imports) {
- ObjectEncoder objectEncoder = importsForEncoder.createObject();
- objectEncoder.setElement(Key.ELEMENT, importedElement);
- objectEncoder.setElements(Key.IMPORTS, imports);
- });
- }
-}
-
-class CompilationUnitSerializer implements ElementSerializer {
- const CompilationUnitSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isCompilationUnit) {
- return SerializedElementKind.COMPILATION_UNIT;
- }
- return null;
- }
-
- void serialize(CompilationUnitElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- SerializerUtil.serializeMetadata(element, encoder);
- encoder.setElement(Key.LIBRARY, element.library);
- encoder.setUri(
- Key.URI, element.library.canonicalUri, element.script.resourceUri);
- List<Element> elements = <Element>[];
- element.forEachLocalMember((e) {
- if (!element.isPatch) {
- elements.add(e);
- }
- });
- encoder.setElements(Key.ELEMENTS, elements);
- }
-}
-
-class ClassSerializer implements ElementSerializer {
- const ClassSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isClass) {
- ClassElement cls = element;
- if (cls.isEnumClass) {
- return SerializedElementKind.ENUM;
- } else if (cls.isMixinApplication) {
- if (!cls.isUnnamedMixinApplication) {
- return SerializedElementKind.NAMED_MIXIN_APPLICATION;
- }
- } else {
- return SerializedElementKind.CLASS;
- }
- }
- return null;
- }
-
- static List<Element> getMembers(ClassElement element) {
- List<Element> members = <Element>[];
- element.forEachLocalMember(members.add);
- if (element.isPatched) {
- element.implementation.forEachLocalMember((Element member) {
- if (!member.isPatch) {
- members.add(member);
- }
- });
- }
- return members;
- }
-
- void serialize(
- ClassElement element, ObjectEncoder encoder, SerializedElementKind kind) {
- SerializerUtil.serializeMetadata(element, encoder);
- encoder.setElement(Key.LIBRARY, element.library);
- encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
- encoder.setString(Key.NAME, element.name);
- SerializerUtil.serializePosition(element, encoder);
- encoder.setTypes(Key.TYPE_VARIABLES, element.typeVariables);
- encoder.setBool(Key.IS_ABSTRACT, element.isAbstract);
- SerializerUtil.serializeMembers(getMembers(element), encoder);
- encoder.setBool(Key.IS_PROXY, element.isProxy);
- encoder.setBool(Key.IS_INJECTED, element.isInjected);
- if (kind == SerializedElementKind.ENUM) {
- EnumClassElement enumClass = element;
- encoder.setElements(Key.FIELDS, enumClass.enumValues);
- }
- if (element.isObject) return;
-
- List<ResolutionInterfaceType> mixins = <ResolutionInterfaceType>[];
- ClassElement superclass = element.superclass;
- while (superclass.isUnnamedMixinApplication) {
- MixinApplicationElement mixinElement = superclass;
- mixins.add(element.thisType.asInstanceOf(mixinElement.mixin));
- superclass = mixinElement.superclass;
- }
- mixins = mixins.reversed.toList();
- ResolutionInterfaceType supertype =
- element.thisType.asInstanceOf(superclass);
-
- encoder.setType(Key.SUPERTYPE, supertype);
- encoder.setTypes(Key.MIXINS, mixins);
- encoder.setTypes(Key.INTERFACES, element.interfaces.toList());
- ResolutionFunctionType callType = element.declaration.callType;
- if (callType != null) {
- encoder.setType(Key.CALL_TYPE, element.callType);
- }
-
- if (element.isMixinApplication) {
- MixinApplicationElement mixinElement = element;
- encoder.setType(Key.MIXIN, mixinElement.mixinType);
- }
- }
-}
-
-class ConstructorSerializer implements ElementSerializer {
- const ConstructorSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isGenerativeConstructor) {
- ConstructorElement constructor = element;
- if (constructor.enclosingClass.isNamedMixinApplication) {
- return SerializedElementKind.FORWARDING_CONSTRUCTOR;
- } else if (constructor.definingConstructor != null) {
- return SerializedElementKind.DEFAULT_CONSTRUCTOR;
- } else {
- return SerializedElementKind.GENERATIVE_CONSTRUCTOR;
- }
- } else if (element.isFactoryConstructor) {
- ConstructorElement constructor = element;
- if (constructor.isRedirectingFactory) {
- return SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR;
- } else {
- return SerializedElementKind.FACTORY_CONSTRUCTOR;
- }
- }
- return null;
- }
-
- void serialize(ConstructorElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- SerializerUtil.serializeParentRelation(element, encoder);
- if (kind == SerializedElementKind.FORWARDING_CONSTRUCTOR) {
- serializeElementReference(element.enclosingClass, Key.ELEMENT, Key.NAME,
- encoder, element.definingConstructor);
- } else {
- SerializerUtil.serializeMetadata(element, encoder);
- encoder.setType(Key.TYPE, element.type);
- encoder.setString(Key.NAME, element.name);
- SerializerUtil.serializePosition(element, encoder);
- SerializerUtil.serializeParameters(element, encoder);
- encoder.setBool(Key.IS_CONST, element.isConst);
- encoder.setBool(Key.IS_EXTERNAL, element.isExternal);
- encoder.setBool(Key.IS_INJECTED, element.isInjected);
- if (element.isConst && !element.isFromEnvironmentConstructor) {
- ConstantConstructor constantConstructor = element.constantConstructor;
- ObjectEncoder constantEncoder = encoder.createObject(Key.CONSTRUCTOR);
- const ConstantConstructorSerializer()
- .visit(constantConstructor, constantEncoder);
- }
- if (kind == SerializedElementKind.GENERATIVE_CONSTRUCTOR) {
- encoder.setBool(Key.IS_REDIRECTING, element.isRedirectingGenerative);
- }
- encoder.setElement(Key.EFFECTIVE_TARGET, element.effectiveTarget);
- if (kind == SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR) {
- encoder.setType(
- Key.EFFECTIVE_TARGET_TYPE,
- element
- .computeEffectiveTargetType(element.enclosingClass.thisType));
- encoder.setElement(Key.IMMEDIATE_REDIRECTION_TARGET,
- element.immediateRedirectionTarget);
- encoder.setBool(Key.EFFECTIVE_TARGET_IS_MALFORMED,
- element.isEffectiveTargetMalformed);
- if (element.redirectionDeferredPrefix != null) {
- encoder.setElement(Key.PREFIX, element.redirectionDeferredPrefix);
- }
- }
- }
- }
-}
-
-class FieldSerializer implements ElementSerializer {
- const FieldSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isField) {
- if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_FIELD;
- if (element.isStatic) {
- if (element is EnumConstantElement) {
- return SerializedElementKind.ENUM_CONSTANT;
- }
- return SerializedElementKind.STATIC_FIELD;
- }
- if (element.isInstanceMember) return SerializedElementKind.INSTANCE_FIELD;
- }
- return null;
- }
-
- void serialize(
- FieldElement element, ObjectEncoder encoder, SerializedElementKind kind) {
- encoder.setString(Key.NAME, element.name);
- SerializerUtil.serializeMetadata(element, encoder);
- SerializerUtil.serializePosition(element, encoder);
- encoder.setType(Key.TYPE, element.type);
- encoder.setBool(Key.IS_FINAL, element.isFinal);
- encoder.setBool(Key.IS_CONST, element.isConst);
- encoder.setBool(Key.IS_INJECTED, element.isInjected);
- ConstantExpression constant = element.constant;
- if (constant != null) {
- encoder.setConstant(Key.CONSTANT, constant);
- }
- SerializerUtil.serializeParentRelation(element, encoder);
- if (element is EnumConstantElement) {
- EnumConstantElement enumConstant = element;
- encoder.setInt(Key.INDEX, enumConstant.index);
- }
- }
-}
-
-class FunctionSerializer implements ElementSerializer {
- const FunctionSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isDeferredLoaderGetter) {
- return null;
- }
- if (element.isFunction) {
- if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_FUNCTION;
- if (element.isStatic) return SerializedElementKind.STATIC_FUNCTION;
- if (element.isInstanceMember) {
- return SerializedElementKind.INSTANCE_FUNCTION;
- }
- if (element.isLocal) {
- return SerializedElementKind.LOCAL_FUNCTION;
- }
- }
- if (element.isGetter) {
- if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_GETTER;
- if (element.isStatic) return SerializedElementKind.STATIC_GETTER;
- if (element.isInstanceMember) {
- return SerializedElementKind.INSTANCE_GETTER;
- }
- }
- if (element.isSetter) {
- if (element.isTopLevel) return SerializedElementKind.TOPLEVEL_SETTER;
- if (element.isStatic) return SerializedElementKind.STATIC_SETTER;
- if (element.isInstanceMember) {
- return SerializedElementKind.INSTANCE_SETTER;
- }
- }
- return null;
- }
-
- void serialize(FunctionElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- encoder.setString(Key.NAME, element.name);
- SerializerUtil.serializeMetadata(element, encoder);
- SerializerUtil.serializePosition(element, encoder);
- SerializerUtil.serializeParameters(element, encoder);
- encoder.setType(Key.TYPE, element.type);
- if (element.isFunction) {
- encoder.setBool(Key.IS_OPERATOR, element.isOperator);
- encoder.setEnum(Key.ASYNC_MARKER, element.asyncMarker);
- } else if (element.isGetter) {
- encoder.setEnum(Key.ASYNC_MARKER, element.asyncMarker);
- }
- SerializerUtil.serializeParentRelation(element, encoder);
- encoder.setBool(Key.IS_EXTERNAL, element.isExternal);
- encoder.setBool(Key.IS_ABSTRACT, element.isAbstract);
- encoder.setBool(Key.IS_INJECTED, element.isInjected);
- if (element.isLocal) {
- LocalFunctionElement localFunction = element;
- encoder.setElement(
- Key.EXECUTABLE_CONTEXT, localFunction.executableContext);
- }
- encoder.setTypes(Key.TYPE_VARIABLES, element.typeVariables);
- }
-}
-
-class TypedefSerializer implements ElementSerializer {
- const TypedefSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isTypedef) {
- return SerializedElementKind.TYPEDEF;
- }
- return null;
- }
-
- void serialize(TypedefElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- encoder.setString(Key.NAME, element.name);
- SerializerUtil.serializeMetadata(element, encoder);
- SerializerUtil.serializePosition(element, encoder);
- encoder.setType(Key.ALIAS, element.alias);
- encoder.setElement(Key.LIBRARY, element.library);
- encoder.setTypes(Key.TYPE_VARIABLES, element.typeVariables);
- encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
- }
-}
-
-class TypeVariableSerializer implements ElementSerializer {
- const TypeVariableSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isTypeVariable) {
- return SerializedElementKind.TYPEVARIABLE;
- }
- return null;
- }
-
- void serialize(TypeVariableElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- encoder.setElement(Key.TYPE_DECLARATION, element.typeDeclaration);
- encoder.setString(Key.NAME, element.name);
- SerializerUtil.serializeMetadata(element, encoder);
- SerializerUtil.serializePosition(element, encoder);
- encoder.setType(Key.TYPE, element.type);
- encoder.setInt(Key.INDEX, element.index);
- encoder.setType(Key.BOUND, element.bound);
- }
-}
-
-class ParameterSerializer implements ElementSerializer {
- const ParameterSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isRegularParameter) {
- return SerializedElementKind.PARAMETER;
- } else if (element.isInitializingFormal) {
- return SerializedElementKind.INITIALIZING_FORMAL;
- }
- return null;
- }
-
- void serialize(ParameterElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- encoder.setElement(Key.FUNCTION, element.functionDeclaration);
- encoder.setString(Key.NAME, element.name);
- SerializerUtil.serializeMetadata(element, encoder);
- SerializerUtil.serializePosition(element, encoder);
- encoder.setType(Key.TYPE, element.type);
- encoder.setBool(Key.IS_OPTIONAL, element.isOptional);
- encoder.setBool(Key.IS_NAMED, element.isNamed);
- encoder.setBool(Key.IS_FINAL, element.isFinal);
- if (element.isOptional) {
- encoder.setConstant(Key.CONSTANT, element.constant);
- }
- if (element.isInitializingFormal) {
- InitializingFormalElement initializingFormal = element;
- encoder.setElement(Key.FIELD, initializingFormal.fieldElement);
- }
- }
-}
-
-class LocalVariableSerializer implements ElementSerializer {
- const LocalVariableSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isVariable) {
- return SerializedElementKind.LOCAL_VARIABLE;
- }
- return null;
- }
-
- void serialize(LocalVariableElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- encoder.setString(Key.NAME, element.name);
- SerializerUtil.serializeMetadata(element, encoder);
- SerializerUtil.serializePosition(element, encoder);
- encoder.setType(Key.TYPE, element.type);
- encoder.setBool(Key.IS_FINAL, element.isFinal);
- encoder.setBool(Key.IS_CONST, element.isConst);
- if (element.isConst) {
- ConstantExpression constant = element.constant;
- encoder.setConstant(Key.CONSTANT, constant);
- }
- encoder.setElement(Key.EXECUTABLE_CONTEXT, element.executableContext);
- }
-}
-
-class ImportSerializer implements ElementSerializer {
- const ImportSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isImport) {
- return SerializedElementKind.IMPORT;
- }
- return null;
- }
-
- void serialize(ImportElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- SerializerUtil.serializeMetadata(element, encoder);
- encoder.setElement(Key.LIBRARY, element.library);
- encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
- encoder.setElement(Key.LIBRARY_DEPENDENCY, element.importedLibrary);
- if (element.prefix != null) {
- encoder.setElement(Key.PREFIX, element.prefix);
- }
- encoder.setBool(Key.IS_DEFERRED, element.isDeferred);
- // TODO(johnniwinther): What is the base for the URI?
- encoder.setUri(Key.URI, element.uri, element.uri);
- }
-}
-
-class ExportSerializer implements ElementSerializer {
- const ExportSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isExport) {
- return SerializedElementKind.EXPORT;
- }
- return null;
- }
-
- void serialize(ExportElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- SerializerUtil.serializeMetadata(element, encoder);
- encoder.setElement(Key.LIBRARY, element.library);
- encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
- encoder.setElement(Key.LIBRARY_DEPENDENCY, element.exportedLibrary);
- // TODO(johnniwinther): What is the base for the URI?
- encoder.setUri(Key.URI, element.uri, element.uri);
- }
-}
-
-class PrefixSerializer implements ElementSerializer {
- const PrefixSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isPrefix) {
- return SerializedElementKind.PREFIX;
- }
- return null;
- }
-
- void serialize(PrefixElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- encoder.setString(Key.NAME, element.name);
- encoder.setElement(Key.LIBRARY, element.library);
- encoder.setElement(Key.COMPILATION_UNIT, element.compilationUnit);
- encoder.setBool(Key.IS_DEFERRED, element.isDeferred);
- Set<Element> members = new Set<Element>();
- element.forEachLocalMember(SerializerUtil.flattenElements(members));
- encoder.setElements(Key.MEMBERS, members);
- if (element.isDeferred) {
- encoder.setElement(Key.IMPORT, element.deferredImport);
- encoder.setElement(Key.GETTER, element.loadLibrary);
- }
- }
-}
-
-class DeferredLoadLibrarySerializer implements ElementSerializer {
- const DeferredLoadLibrarySerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isDeferredLoaderGetter) {
- return SerializedElementKind.DEFERRED_LOAD_LIBRARY;
- }
- return null;
- }
-
- void serialize(GetterElement element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- encoder.setElement(Key.PREFIX, element.enclosingElement);
- }
-}
-
-class WarnOnUseSerializer implements ElementSerializer {
- const WarnOnUseSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isWarnOnUse) {
- return SerializedElementKind.WARN_ON_USE;
- }
- return null;
- }
-
- void serialize(WarnOnUseElementX element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- encoder.setElement(Key.ENCLOSING, element.enclosingElement);
- encoder.setElement(Key.ELEMENT, element.wrappedElement);
- serializeWrappedMessage(encoder, Key.WARNING, element.warning);
- serializeWrappedMessage(encoder, Key.INFO, element.info);
- }
-}
-
-class AmbiguousSerializer implements ElementSerializer {
- const AmbiguousSerializer();
-
- SerializedElementKind getSerializedKind(Element element) {
- if (element.isAmbiguous) {
- return SerializedElementKind.AMBIGUOUS;
- }
- return null;
- }
-
- void serialize(AmbiguousImportX element, ObjectEncoder encoder,
- SerializedElementKind kind) {
- // TODO(johnniwinther): Also support [DuplicateElementX] if serialization
- // of code with compile-time errors is supported.
- encoder.setElement(Key.ENCLOSING, element.enclosingElement);
- encoder.setElement(Key.EXISTING, element.existingElement);
- encoder.setElement(Key.NEW, element.newElement);
- encoder.setEnum(Key.MESSAGE_KIND, element.messageKind);
- serializeMessageArguments(encoder, Key.ARGUMENTS, element.messageArguments);
- }
-}
-
-/// Utility class for deserializing [Element]s.
-///
-/// This is used by the [Deserializer].
-class ElementDeserializer {
- /// Deserializes an [Element] from an [ObjectDecoder].
- ///
- /// The class is called from the [Deserializer] when an [Element]
- /// needs deserialization. The [ObjectDecoder] ensures that any [Element],
- /// [ResolutionDartType], and [ConstantExpression] that the deserialized
- /// [Element] depends upon are available.
- static Element deserialize(
- ObjectDecoder decoder, SerializedElementKind elementKind) {
- switch (elementKind) {
- case SerializedElementKind.ERROR:
- Element enclosing = decoder.getElement(Key.ENCLOSING);
- String name = decoder.getString(Key.NAME);
- MessageKind messageKind =
- decoder.getEnum(Key.MESSAGE_KIND, MessageKind.values);
- Map<String, String> arguments =
- deserializeMessageArguments(decoder, Key.ARGUMENTS);
- return new ErroneousElementX(messageKind, arguments, name, enclosing);
- case SerializedElementKind.LIBRARY:
- return new LibraryElementZ(decoder);
- case SerializedElementKind.COMPILATION_UNIT:
- return new CompilationUnitElementZ(decoder);
- case SerializedElementKind.CLASS:
- return new ClassElementZ(decoder);
- case SerializedElementKind.ENUM:
- return new EnumClassElementZ(decoder);
- case SerializedElementKind.NAMED_MIXIN_APPLICATION:
- return new NamedMixinApplicationElementZ(decoder);
- case SerializedElementKind.TOPLEVEL_FIELD:
- return new TopLevelFieldElementZ(decoder);
- case SerializedElementKind.STATIC_FIELD:
- return new StaticFieldElementZ(decoder);
- case SerializedElementKind.ENUM_CONSTANT:
- return new EnumConstantElementZ(decoder);
- case SerializedElementKind.INSTANCE_FIELD:
- return new InstanceFieldElementZ(decoder);
- case SerializedElementKind.GENERATIVE_CONSTRUCTOR:
- return new GenerativeConstructorElementZ(decoder);
- case SerializedElementKind.DEFAULT_CONSTRUCTOR:
- return new DefaultConstructorElementZ(decoder);
- case SerializedElementKind.FACTORY_CONSTRUCTOR:
- return new FactoryConstructorElementZ(decoder);
- case SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR:
- return new RedirectingFactoryConstructorElementZ(decoder);
- case SerializedElementKind.FORWARDING_CONSTRUCTOR:
- ClassElement cls = decoder.getElement(Key.CLASS);
- Element definingConstructor =
- deserializeElementReference(cls, Key.ELEMENT, Key.NAME, decoder);
- return new ForwardingConstructorElementZ(cls, definingConstructor);
- case SerializedElementKind.TOPLEVEL_FUNCTION:
- return new TopLevelFunctionElementZ(decoder);
- case SerializedElementKind.STATIC_FUNCTION:
- return new StaticFunctionElementZ(decoder);
- case SerializedElementKind.INSTANCE_FUNCTION:
- return new InstanceFunctionElementZ(decoder);
- case SerializedElementKind.LOCAL_FUNCTION:
- return new LocalFunctionElementZ(decoder);
- case SerializedElementKind.TOPLEVEL_GETTER:
- return new TopLevelGetterElementZ(decoder);
- case SerializedElementKind.STATIC_GETTER:
- return new StaticGetterElementZ(decoder);
- case SerializedElementKind.INSTANCE_GETTER:
- return new InstanceGetterElementZ(decoder);
- case SerializedElementKind.TOPLEVEL_SETTER:
- return new TopLevelSetterElementZ(decoder);
- case SerializedElementKind.STATIC_SETTER:
- return new StaticSetterElementZ(decoder);
- case SerializedElementKind.INSTANCE_SETTER:
- return new InstanceSetterElementZ(decoder);
- case SerializedElementKind.TYPEDEF:
- return new TypedefElementZ(decoder);
- case SerializedElementKind.TYPEVARIABLE:
- return new TypeVariableElementZ(decoder);
- case SerializedElementKind.PARAMETER:
- return new LocalParameterElementZ(decoder);
- case SerializedElementKind.INITIALIZING_FORMAL:
- return new InitializingFormalElementZ(decoder);
- case SerializedElementKind.IMPORT:
- return new ImportElementZ(decoder);
- case SerializedElementKind.EXPORT:
- return new ExportElementZ(decoder);
- case SerializedElementKind.PREFIX:
- return new PrefixElementZ(decoder);
- case SerializedElementKind.DEFERRED_LOAD_LIBRARY:
- return new DeferredLoaderGetterElementX(decoder.getElement(Key.PREFIX));
- case SerializedElementKind.LOCAL_VARIABLE:
- return new LocalVariableElementZ(decoder);
- case SerializedElementKind.WARN_ON_USE:
- Element enclosing = decoder.getElement(Key.ENCLOSING);
- Element element = decoder.getElement(Key.ELEMENT);
- WrappedMessage warning =
- deserializeWrappedMessage(decoder, Key.WARNING);
- WrappedMessage info = deserializeWrappedMessage(decoder, Key.INFO);
- return new WarnOnUseElementX(warning, info, enclosing, element);
- case SerializedElementKind.AMBIGUOUS:
- Element enclosingElement = decoder.getElement(Key.ENCLOSING);
- Element existingElement = decoder.getElement(Key.EXISTING);
- Element newElement = decoder.getElement(Key.NEW);
- MessageKind messageKind =
- decoder.getEnum(Key.MESSAGE_KIND, MessageKind.values);
- Map messageArguments =
- deserializeMessageArguments(decoder, Key.ARGUMENTS);
- return new AmbiguousImportX(messageKind, messageArguments,
- enclosingElement, existingElement, newElement);
- case SerializedElementKind.EXTERNAL_LIBRARY:
- case SerializedElementKind.EXTERNAL_LIBRARY_MEMBER:
- case SerializedElementKind.EXTERNAL_CLASS_MEMBER:
- case SerializedElementKind.EXTERNAL_CONSTRUCTOR:
- break;
- }
- throw new UnsupportedError("Unexpected element kind '${elementKind}.");
- }
-}
diff --git a/pkg/compiler/lib/src/serialization/impact_serialization.dart b/pkg/compiler/lib/src/serialization/impact_serialization.dart
deleted file mode 100644
index 1d14bb7..0000000
--- a/pkg/compiler/lib/src/serialization/impact_serialization.dart
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.impact;
-
-import '../common/resolution.dart';
-import '../constants/expressions.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/resolution_types.dart';
-import '../universe/call_structure.dart';
-import '../universe/feature.dart';
-import '../universe/selector.dart';
-import '../universe/use.dart';
-import '../universe/world_impact.dart';
-import '../util/enumset.dart';
-import 'keys.dart';
-import 'serialization.dart';
-import 'serialization_util.dart';
-
-/// Visitor that serializes a [ResolutionImpact] object using an
-/// [ObjectEncoder].
-class ImpactSerializer implements WorldImpactVisitor {
- final Element element;
- final ObjectEncoder objectEncoder;
- final ListEncoder staticUses;
- final ListEncoder dynamicUses;
- final ListEncoder typeUses;
- final SerializerPlugin nativeDataSerializer;
-
- ImpactSerializer(
- this.element, ObjectEncoder objectEncoder, this.nativeDataSerializer)
- : this.objectEncoder = objectEncoder,
- staticUses = objectEncoder.createList(Key.STATIC_USES),
- dynamicUses = objectEncoder.createList(Key.DYNAMIC_USES),
- typeUses = objectEncoder.createList(Key.TYPE_USES);
-
- void serialize(ResolutionImpact resolutionImpact) {
- resolutionImpact.apply(this);
- objectEncoder.setStrings(Key.SYMBOLS, resolutionImpact.constSymbolNames);
- objectEncoder.setConstants(
- Key.CONSTANTS, resolutionImpact.constantLiterals);
- objectEncoder.setEnums(Key.FEATURES, resolutionImpact.features);
- if (resolutionImpact.listLiterals.isNotEmpty) {
- ListEncoder encoder = objectEncoder.createList(Key.LISTS);
- for (ListLiteralUse use in resolutionImpact.listLiterals) {
- ObjectEncoder useEncoder = encoder.createObject();
- ResolutionInterfaceType type = use.type;
- useEncoder.setType(Key.TYPE, type);
- useEncoder.setBool(Key.IS_CONST, use.isConstant);
- useEncoder.setBool(Key.IS_EMPTY, use.isEmpty);
- }
- }
- if (resolutionImpact.mapLiterals.isNotEmpty) {
- ListEncoder encoder = objectEncoder.createList(Key.MAPS);
- for (MapLiteralUse use in resolutionImpact.mapLiterals) {
- ObjectEncoder useEncoder = encoder.createObject();
- ResolutionInterfaceType type = use.type;
- useEncoder.setType(Key.TYPE, type);
- useEncoder.setBool(Key.IS_CONST, use.isConstant);
- useEncoder.setBool(Key.IS_EMPTY, use.isEmpty);
- }
- }
- if (resolutionImpact.nativeData.isNotEmpty) {
- ListEncoder encoder = objectEncoder.createList(Key.NATIVE);
- for (dynamic data in resolutionImpact.nativeData) {
- nativeDataSerializer.onData(data, encoder.createObject());
- }
- }
- }
-
- @override
- void visitDynamicUse(DynamicUse dynamicUse) {
- ObjectEncoder object = dynamicUses.createObject();
- serializeSelector(dynamicUse.selector, object);
- }
-
- @override
- void visitStaticUse(StaticUse staticUse) {
- ObjectEncoder object = staticUses.createObject();
- object.setEnum(Key.KIND, staticUse.kind);
- serializeElementReference(
- element, Key.ELEMENT, Key.NAME, object, staticUse.element);
- ResolutionInterfaceType type = staticUse.type;
- if (type != null) {
- object.setType(Key.TYPE, type);
- }
- if (staticUse.callStructure != null) {
- serializeCallStructure(
- staticUse.callStructure, object.createObject(Key.CALL_STRUCTURE));
- }
- }
-
- @override
- void visitTypeUse(TypeUse typeUse) {
- ObjectEncoder object = typeUses.createObject();
- object.setEnum(Key.KIND, typeUse.kind);
- object.setType(Key.TYPE, typeUse.type);
- }
-
- @override
- void visitConstantUse(ConstantUse typeUse) {
- throw new UnsupportedError("ConstantUse serialization is not supported.");
- }
-}
-
-/// A deserialized [WorldImpact] object.
-class DeserializedResolutionImpact extends WorldImpact
- implements ResolutionImpact {
- final Iterable<String> constSymbolNames;
- final Iterable<ConstantExpression> constantLiterals;
- final Iterable<DynamicUse> dynamicUses;
- final EnumSet<Feature> _features;
- final Iterable<ListLiteralUse> listLiterals;
- final Iterable<MapLiteralUse> mapLiterals;
- final Iterable<StaticUse> staticUses;
- final Iterable<TypeUse> typeUses;
- final Iterable<dynamic> nativeData;
- final Iterable<ClassEntity> seenClasses;
-
- DeserializedResolutionImpact(
- {this.constSymbolNames: const <String>[],
- this.constantLiterals: const <ConstantExpression>[],
- this.dynamicUses: const <DynamicUse>[],
- EnumSet<Feature> features,
- this.listLiterals: const <ListLiteralUse>[],
- this.mapLiterals: const <MapLiteralUse>[],
- this.staticUses: const <StaticUse>[],
- this.typeUses: const <TypeUse>[],
- this.nativeData: const <dynamic>[],
- this.seenClasses: const <ClassEntity>[]})
- : this._features = features;
-
- @override
- bool get isEmpty => false;
-
- Iterable<Feature> get features {
- return _features != null
- ? _features.iterable(Feature.values)
- : const <Feature>[];
- }
-}
-
-class ImpactDeserializer {
- /// Deserializes a [WorldImpact] from [objectDecoder].
- static ResolutionImpact deserializeImpact(Element element,
- ObjectDecoder objectDecoder, DeserializerPlugin nativeDataDeserializer) {
- ListDecoder staticUseDecoder = objectDecoder.getList(Key.STATIC_USES);
- List<StaticUse> staticUses = <StaticUse>[];
- for (int index = 0; index < staticUseDecoder.length; index++) {
- ObjectDecoder object = staticUseDecoder.getObject(index);
- StaticUseKind kind = object.getEnum(Key.KIND, StaticUseKind.values);
- Element usedElement =
- deserializeElementReference(element, Key.ELEMENT, Key.NAME, object);
- ResolutionInterfaceType type = object.getType(Key.TYPE, isOptional: true);
- ObjectDecoder callStructureObject =
- object.getObject(Key.CALL_STRUCTURE, isOptional: true);
- CallStructure callStructure;
- if (callStructureObject != null) {
- callStructure = deserializeCallStructure(callStructureObject);
- }
- staticUses.add(new StaticUse.internal(usedElement, kind,
- type: type, callStructure: callStructure));
- }
-
- ListDecoder dynamicUseDecoder = objectDecoder.getList(Key.DYNAMIC_USES);
- List<DynamicUse> dynamicUses = <DynamicUse>[];
- for (int index = 0; index < dynamicUseDecoder.length; index++) {
- ObjectDecoder object = dynamicUseDecoder.getObject(index);
- Selector selector = deserializeSelector(object);
- dynamicUses.add(new DynamicUse(selector));
- }
-
- ListDecoder typeUseDecoder = objectDecoder.getList(Key.TYPE_USES);
- List<TypeUse> typeUses = <TypeUse>[];
- for (int index = 0; index < typeUseDecoder.length; index++) {
- ObjectDecoder object = typeUseDecoder.getObject(index);
- TypeUseKind kind = object.getEnum(Key.KIND, TypeUseKind.values);
- ResolutionDartType type = object.getType(Key.TYPE);
- typeUses.add(new TypeUse.internal(type, kind));
- }
-
- List<String> constSymbolNames =
- objectDecoder.getStrings(Key.SYMBOLS, isOptional: true);
-
- List<ConstantExpression> constantLiterals =
- objectDecoder.getConstants(Key.CONSTANTS, isOptional: true);
-
- EnumSet<Feature> features =
- objectDecoder.getEnums(Key.FEATURES, isOptional: true);
-
- ListDecoder listLiteralDecoder =
- objectDecoder.getList(Key.LISTS, isOptional: true);
- List<ListLiteralUse> listLiterals = const <ListLiteralUse>[];
- if (listLiteralDecoder != null) {
- listLiterals = <ListLiteralUse>[];
- for (int i = 0; i < listLiteralDecoder.length; i++) {
- ObjectDecoder useDecoder = listLiteralDecoder.getObject(i);
- ResolutionInterfaceType type = useDecoder.getType(Key.TYPE);
- bool isConstant = useDecoder.getBool(Key.IS_CONST);
- bool isEmpty = useDecoder.getBool(Key.IS_EMPTY);
- listLiterals.add(
- new ListLiteralUse(type, isConstant: isConstant, isEmpty: isEmpty));
- }
- }
-
- ListDecoder mapLiteralDecoder =
- objectDecoder.getList(Key.MAPS, isOptional: true);
- List<MapLiteralUse> mapLiterals = const <MapLiteralUse>[];
- if (mapLiteralDecoder != null) {
- mapLiterals = <MapLiteralUse>[];
- for (int i = 0; i < mapLiteralDecoder.length; i++) {
- ObjectDecoder useDecoder = mapLiteralDecoder.getObject(i);
- ResolutionInterfaceType type = useDecoder.getType(Key.TYPE);
- bool isConstant = useDecoder.getBool(Key.IS_CONST);
- bool isEmpty = useDecoder.getBool(Key.IS_EMPTY);
- mapLiterals.add(
- new MapLiteralUse(type, isConstant: isConstant, isEmpty: isEmpty));
- }
- }
-
- ListDecoder nativeDataDecoder =
- objectDecoder.getList(Key.NATIVE, isOptional: true);
- List<dynamic> nativeData = const <dynamic>[];
- if (nativeDataDecoder != null) {
- nativeData = <dynamic>[];
- for (int i = 0; i < nativeDataDecoder.length; i++) {
- dynamic data =
- nativeDataDeserializer.onData(nativeDataDecoder.getObject(i));
- if (data != null) {
- nativeData.add(data);
- }
- }
- }
-
- return new DeserializedResolutionImpact(
- constSymbolNames: constSymbolNames,
- constantLiterals: constantLiterals,
- dynamicUses: dynamicUses,
- features: features,
- listLiterals: listLiterals,
- mapLiterals: mapLiterals,
- staticUses: staticUses,
- typeUses: typeUses,
- nativeData: nativeData);
- }
-}
diff --git a/pkg/compiler/lib/src/serialization/json_serializer.dart b/pkg/compiler/lib/src/serialization/json_serializer.dart
deleted file mode 100644
index b075e5b..0000000
--- a/pkg/compiler/lib/src/serialization/json_serializer.dart
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.json;
-
-import 'dart:convert';
-
-import 'keys.dart';
-import 'serialization.dart';
-import 'values.dart';
-
-/// Serialization encoder for JSON.
-class JsonSerializationEncoder implements SerializationEncoder {
- const JsonSerializationEncoder();
-
- String encode(ObjectValue objectValue) {
- try {
- return new JsonEncoder.withIndent(' ')
- .convert(const JsonValueEncoder().convert(objectValue));
- } on JsonUnsupportedObjectError catch (e) {
- throw 'Error encoding `${e.unsupportedObject}` '
- '(${e.unsupportedObject.runtimeType})';
- }
- }
-}
-
-/// Serialization decoder for JSON.
-class JsonSerializationDecoder implements SerializationDecoder {
- const JsonSerializationDecoder();
-
- Map decode(String text) => JSON.decode(text);
-
- /// Returns the name of the [key] which used for to store a [Key] into a
- /// [Map]; corresponding to the encoding of object properties in
- /// [JsonValueEncoder.visitObject].
- getObjectPropertyValue(Key key) => key.name;
-}
-
-/// A [ValueVisitor] that computes a JSON object value.
-class JsonValueEncoder implements ValueVisitor {
- const JsonValueEncoder();
-
- convert(Value value) => visit(value, null);
-
- @override
- visit(Value value, [arg]) => value.accept(this, arg);
-
- @override
- bool visitBool(BoolValue value, arg) => value.value;
-
- @override
- visitConstant(ConstantValue value, arg) => visit(value.id);
-
- @override
- visitDouble(DoubleValue value, arg) {
- double d = value.value;
- if (d.isNaN) {
- return 'NaN';
- } else if (d.isInfinite) {
- if (d.isNegative) {
- return '-Infinity';
- } else {
- return 'Infinity';
- }
- }
- return d;
- }
-
- @override
- visitElement(ElementValue value, arg) => visit(value.id);
-
- @override
- visitEnum(EnumValue value, arg) => value.value.index;
-
- @override
- int visitInt(IntValue value, arg) => value.value;
-
- @override
- List visitList(ListValue value, arg) => value.values.map(visit).toList();
-
- @override
- Map visitMap(MapValue value, arg) {
- Map<String, dynamic> map = <String, dynamic>{};
- value.map.forEach((String key, Value value) {
- map[key] = visit(value);
- });
- return map;
- }
-
- @override
- Map visitObject(ObjectValue value, arg) {
- Map<String, dynamic> map = <String, dynamic>{};
- value.map.forEach((Key key, Value value) {
- map[key.name] = visit(value);
- });
- return map;
- }
-
- @override
- String visitString(StringValue value, arg) => value.value;
-
- @override
- visitType(TypeValue value, arg) => visit(value.id);
-
- @override
- visitUri(UriValue value, arg) => '${value.value}';
-}
-
-/// [ValueVisitor] that generates a verbose JSON-like output.
-class PrettyPrintEncoder implements ValueVisitor<dynamic, String> {
- StringBuffer buffer;
-
- String toText(Value value) {
- buffer = new StringBuffer();
- visit(value, '');
- String text = buffer.toString();
- buffer = null;
- return text;
- }
-
- @override
- void visit(Value value, String indentation) {
- value.accept(this, indentation);
- }
-
- @override
- void visitBool(BoolValue value, String indentation) {
- buffer.write(value.value);
- }
-
- @override
- void visitConstant(ConstantValue value, String indentation) {
- buffer.write('Constant(${value.id}):${value.constant.toDartText()}');
- }
-
- @override
- void visitDouble(DoubleValue value, String indentation) {
- buffer.write(value.value);
- }
-
- @override
- void visitElement(ElementValue value, String indentation) {
- buffer.write('Element(${value.id}):${value.element}');
- }
-
- @override
- void visitEnum(EnumValue value, String indentation) {
- buffer.write(value.value);
- }
-
- @override
- void visitInt(IntValue value, String indentation) {
- buffer.write(value.value);
- }
-
- @override
- void visitList(ListValue value, String indentation) {
- if (value.values.isEmpty) {
- buffer.write('[]');
- } else {
- buffer.write('[');
- bool needsComma = false;
- String nextIndentation = '${indentation} ';
- for (Value element in value.values) {
- if (needsComma) {
- buffer.write(',');
- }
- buffer.write('\n$nextIndentation');
- visit(element, nextIndentation);
- needsComma = true;
- }
- buffer.write('\n$indentation]');
- }
- }
-
- @override
- void visitMap(MapValue value, String indentation) {
- if (value.map.isEmpty) {
- buffer.write('{}');
- } else {
- buffer.write('{');
- bool needsComma = false;
- String nextIndentation = '${indentation} ';
- value.map.forEach((String key, Value subvalue) {
- if (needsComma) {
- buffer.write(',');
- }
- buffer.write('\n$nextIndentation$key: ');
- visit(subvalue, nextIndentation);
- needsComma = true;
- });
- buffer.write('\n$indentation}');
- }
- }
-
- @override
- void visitObject(ObjectValue value, String indentation) {
- if (value.map.isEmpty) {
- buffer.write('{}');
- } else {
- buffer.write('{');
- bool needsComma = false;
- String nextIndentation = '${indentation} ';
- value.map.forEach((Key key, Value subvalue) {
- if (needsComma) {
- buffer.write(',');
- }
- buffer.write('\n$nextIndentation$key: ');
- visit(subvalue, nextIndentation);
- needsComma = true;
- });
- buffer.write('\n$indentation}');
- }
- }
-
- @override
- void visitString(StringValue value, String indentation) {
- buffer.write('"${value.value}"');
- }
-
- @override
- void visitType(TypeValue value, String indentation) {
- buffer.write('Type(${value.id}):${value.type}');
- }
-
- @override
- void visitUri(UriValue value, String indentation) {
- buffer.write('Uri(${value.value})');
- }
-}
diff --git a/pkg/compiler/lib/src/serialization/keys.dart b/pkg/compiler/lib/src/serialization/keys.dart
deleted file mode 100644
index 928bbc7..0000000
--- a/pkg/compiler/lib/src/serialization/keys.dart
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.keys;
-
-/// Keys used for serialization.
-class Key {
- static const Key ALIAS = const Key('alias');
- static const Key ARGUMENTS = const Key('arguments');
- static const Key ASYNC_MARKER = const Key('asyncMarker');
- static const Key BODY = const Key('body');
- static const Key BOUND = const Key('bound');
- static const Key CACHED_TYPE = const Key('cachedType');
- static const Key CALL_STRUCTURE = const Key('callStructure');
- static const Key CALL_TYPE = const Key('callType');
- static const Key CANONICAL_URI = const Key('canonicalUri');
- static const Key CLASS = const Key('class');
- static const Key COMPILATION_UNIT = const Key('compilation-unit');
- static const Key COMPILATION_UNITS = const Key('compilation-units');
- static const Key CONDITION = const Key('condition');
- static const Key CONSTANT = const Key('constant');
- static const Key CONSTANTS = const Key('constants');
- static const Key CONSTRUCTOR = const Key('constructor');
- static const Key CONTAINS_TRY = const Key('containsTryStatement');
- static const Key DATA = const Key('data');
- static const Key DEFAULT = const Key('default');
- static const Key DEFAULTS = const Key('defaults');
- static const Key DYNAMIC_USES = const Key('dynamic-uses');
- static const Key EFFECTIVE_TARGET = const Key('effectiveTarget');
- static const Key EFFECTIVE_TARGET_TYPE = const Key('effectiveTargetType');
- static const Key EFFECTIVE_TARGET_IS_MALFORMED =
- const Key('effectiveTargetIsMalformed');
- static const Key ELEMENT = const Key('element');
- static const Key ELEMENTS = const Key('elements');
- static const Key ENCLOSING = const Key('enclosing');
- static const Key EXECUTABLE_CONTEXT = const Key('executable-context');
- static const Key EXISTING = const Key('existing');
- static const Key EXPORTS = const Key('exports');
- static const Key EXPORT_SCOPE = const Key('export-scope');
- static const Key EXPRESSION = const Key('expression');
- static const Key FALSE = const Key('false');
- static const Key FEATURES = const Key('features');
- static const Key FIELD = const Key('field');
- static const Key FIELDS = const Key('fields');
- static const Key FUNCTION = const Key('function');
- static const Key GET_OR_SET = const Key('getOrSet');
- static const Key GETTER = const Key('getter');
- static const Key ID = const Key('id');
- static const Key IMMEDIATE_REDIRECTION_TARGET =
- const Key('immediateRedirectionTarget');
- static const Key IMPACTS = const Key('impacts');
- static const Key IMPORT = const Key('import');
- static const Key IMPORTS = const Key('imports');
- static const Key IMPORTS_FOR = const Key('importsFor');
- static const Key IMPORT_SCOPE = const Key('import-scope');
- static const Key INDEX = const Key('index');
- static const Key INFO = const Key('info');
- static const Key INTERFACES = const Key('interfaces');
- static const Key IS_ABSTRACT = const Key('isAbstract');
- static const Key IS_BREAK_TARGET = const Key('isBreakTarget');
- static const Key IS_CONST = const Key('isConst');
- static const Key IS_CONTINUE_TARGET = const Key('isContinueTarget');
- static const Key IS_DEFERRED = const Key('isDeferred');
- static const Key IS_EMPTY = const Key('isEmpty');
- static const Key IS_EXTERNAL = const Key('isExternal');
- static const Key IS_FINAL = const Key('isFinal');
- static const Key IS_INJECTED = const Key('isInjected');
- static const Key IS_METHOD_TYPE_VARIABLE_TYPE =
- const Key('isMethodTypeVariableType');
- static const Key IS_NAMED = const Key('isNamed');
- static const Key IS_OPERATOR = const Key('isOperator');
- static const Key IS_OPTIONAL = const Key('isOptional');
- static const Key IS_PROXY = const Key('isProxy');
- static const Key IS_REDIRECTING = const Key('isRedirecting');
- static const Key IS_SETTER = const Key('isSetter');
- static const Key IS_UNNAMED_MIXIN_APPLICATION =
- const Key('isUnnamedMixinApplication');
- static const Key JUMP_TARGET = const Key('jumpTarget');
- static const Key JUMP_TARGETS = const Key('jumpTargets');
- static const Key JUMP_TARGET_DEFINITION = const Key('jumpTargetDefinition');
- static const Key KEYS = const Key('keys');
- static const Key KIND = const Key('kind');
- static const Key LABEL_DEFINITION = const Key('labelDefinition');
- static const Key LABEL_DEFINITIONS = const Key('labelDefinitions');
- static const Key LABELS = const Key('labels');
- static const Key LEFT = const Key('left');
- static const Key LENGTH = const Key('length');
- static const Key LIBRARY = const Key('library');
- static const Key LIBRARY_DEPENDENCY = const Key('library-dependency');
- static const Key LIBRARY_NAME = const Key('library-name');
- static const Key LISTS = const Key('lists');
- static const Key MAPS = const Key('maps');
- static const Key MEMBERS = const Key('members');
- static const Key MESSAGE_KIND = const Key('messageKind');
- static const Key METADATA = const Key('metadata');
- static const Key MIXIN = const Key('mixin');
- static const Key MIXINS = const Key('mixins');
- static const Key NAME = const Key('name');
- static const Key NAMES = const Key('names');
- static const Key NAMED_ARGUMENTS = const Key('named-arguments');
- static const Key NAMED_PARAMETERS = const Key('named-parameters');
- static const Key NAMED_PARAMETER_TYPES = const Key('named-parameter-types');
- static const Key NATIVE = const Key('native');
- static const Key NESTING_LEVEL = const Key('nestingLevel');
- static const Key NEW = const Key('new');
- static const Key NEW_STRUCTURE = const Key('newStructure');
- static const Key NODE = const Key('node');
- static const Key OFFSET = const Key('offset');
- static const Key OPERATOR = const Key('operator');
- static const Key OPTIONAL_PARAMETER_TYPES =
- const Key('optional-parameter-types');
- static const Key PARAMETERS = const Key('parameters');
- static const Key PARAMETER_TYPES = const Key('parameter-types');
- static const Key PREFIX = const Key('prefix');
- static const Key RETURN_TYPE = const Key('return-type');
- static const Key RIGHT = const Key('right');
- static const Key SELECTOR = const Key('selector');
- static const Key SEMANTICS = const Key('semantics');
- static const Key SEND_STRUCTURE = const Key('sendStructure');
- static const Key SETTER = const Key('setter');
- static const Key SOURCE_SPAN = const Key('sourceSpan');
- static const Key STATIC_USES = const Key('static-uses');
- static const Key SUB_KIND = const Key('subKind');
- static const Key SUPERTYPE = const Key('supertype');
- static const Key SUPERTYPES = const Key('supertypes');
- static const Key SYMBOLS = const Key('symbols');
- static const Key TAGS = const Key('tags');
- static const Key TARGET_LABEL = const Key('targetLabel');
- static const Key TRUE = const Key('true');
- static const Key TYPE = const Key('type');
- static const Key TYPES = const Key('types');
- static const Key TYPE_ARGUMENTS = const Key('type-arguments');
- static const Key TYPE_DECLARATION = const Key('type-declaration');
- static const Key TYPE_USES = const Key('type-uses');
- static const Key TYPE_VARIABLES = const Key('type-variables');
- static const Key URI = const Key('uri');
- static const Key VALUE = const Key('value');
- static const Key VALUES = const Key('values');
- static const Key WARNING = const Key('warning');
-
- final String name;
-
- const Key(this.name);
-
- String toString() => name;
-}
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
deleted file mode 100644
index 34549ec..0000000
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ /dev/null
@@ -1,2487 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Implementation of the element model used for deserialiation.
-///
-/// These classes are created by [ElementDeserializer] triggered by the
-/// [Deserializer].
-
-library dart2js.serialization.modelz;
-
-import '../common.dart';
-import '../common/resolution.dart' show Resolution;
-import '../constants/constructors.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/common.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/modelx.dart' show FunctionSignatureX;
-import '../elements/names.dart';
-import '../elements/visitor.dart';
-import '../io/source_file.dart';
-import '../ordered_typeset.dart';
-import '../resolution/class_members.dart' as class_members;
-import '../resolution/scope.dart' show Scope;
-import '../resolution/tree_elements.dart' show TreeElements;
-import '../script.dart';
-import '../serialization/constant_serialization.dart';
-import 'package:front_end/src/fasta/scanner.dart' show Token;
-import '../tree/tree.dart';
-import '../util/util.dart' show Link, LinkBuilder;
-import 'keys.dart';
-import 'serialization.dart';
-
-/// Compute a [Link] from an [Iterable].
-Link toLink(Iterable iterable) {
- LinkBuilder builder = new LinkBuilder();
- for (var element in iterable) {
- builder.addLast(element);
- }
- return builder.toLink();
-}
-
-abstract class ElementZ extends Element with ElementCommon {
- String toString() {
- if (enclosingElement == null || isTopLevel) return 'Z$kind($name)';
- return 'Z$kind(${enclosingElement.name}#$name)';
- }
-
- _unsupported(text) => throw new UnsupportedError('${this}.$text');
-
- @override
- AnalyzableElement get analyzableElement {
- Element element = this;
- if (element is AnalyzableElement) {
- return element;
- } else if (enclosingElement != null) {
- return enclosingElement.analyzableElement;
- }
- return null;
- }
-
- @override
- FunctionElement asFunctionElement() => null;
-
- @override
- Scope buildScope() => _unsupported('buildScope');
-
- @override
- ClassElement get enclosingClass => null;
-
- @override
- LibraryElement get implementationLibrary => library;
-
- @override
- bool get isAbstract => false;
-
- @override
- bool get isClassMember => false;
-
- @override
- bool get isClosure => false;
-
- @override
- bool get isConst => false;
-
- @override
- bool get isDeferredLoaderGetter => false;
-
- @override
- bool get isFinal => false;
-
- @override
- bool get isInstanceMember => false;
-
- @override
- bool get isLocal => false;
-
- @override
- bool get isMixinApplication => false;
-
- @override
- bool get isOperator => false;
-
- @override
- bool get isStatic => false;
-
- @override
- bool get isSynthesized => false;
-
- @override
- bool get isTopLevel => false;
-
- @override
- Iterable<MetadataAnnotation> get metadata => const <MetadataAnnotation>[];
-
- @override
- Token get position => _unsupported('position');
-}
-
-abstract class DeserializedElementZ extends ElementZ {
- ObjectDecoder _decoder;
- List<MetadataAnnotation> _metadata;
-
- DeserializedElementZ(this._decoder);
-
- @override
- String get name => _decoder.getString(Key.NAME);
-
- // TODO(johnniwinther): Should this be cached?
- @override
- int get sourceOffset => _decoder.getInt(Key.OFFSET, isOptional: true);
-
- @override
- SourceSpan get sourcePosition {
- // TODO(johnniwinther): Should this be cached?
- int offset = sourceOffset;
- if (offset == null) return null;
- Uri uri = _decoder.getUri(Key.URI, isOptional: true);
- if (uri == null) {
- uri = compilationUnit.script.readableUri;
- }
- int length = _decoder.getInt(Key.LENGTH, isOptional: true);
- if (length == null) {
- length = name.length;
- }
- return new SourceSpan(uri, offset, offset + length);
- }
-
- @override
- Iterable<MetadataAnnotation> get metadata {
- if (_metadata == null) {
- _metadata = <MetadataAnnotation>[];
- ListDecoder list = _decoder.getList(Key.METADATA, isOptional: true);
- if (list != null) {
- for (int index = 0; index < list.length; index++) {
- ObjectDecoder object = list.getObject(index);
- Element element = object.getElement(Key.ELEMENT);
- Uri uri = object.getUri(Key.URI);
- int offset = object.getInt(Key.OFFSET);
- int length = object.getInt(Key.LENGTH);
- ConstantExpression constant = object.getConstant(Key.CONSTANT);
- _metadata.add(new MetadataAnnotationZ(
- element, new SourceSpan(uri, offset, offset + length), constant));
- }
- }
- }
- return _metadata;
- }
-}
-
-/// Deserializer for a collection of member elements serialized as a map from
-/// names to element declarations.
-///
-/// The serialized data contains the declared getters and setters but lookup
-/// into the map returns an [AbstractFieldElement] for pairs of corresponding
-/// getters and setters.
-///
-/// The underlying map encoding allows for lazy computation of the members upon
-/// query.
-class MappedContainer {
- Map<String, Element> _lookupCache = {};
-
- Element lookup(String name, MapDecoder members) {
- if (_lookupCache.containsKey(name)) {
- Element element = _lookupCache[name];
- if (element != null) {
- return element;
- }
- }
- if (members == null) {
- return null;
- }
- bool hasId = members.containsKey(name);
- String setterName = '$name,=';
- bool hasSetterId = members.containsKey(setterName);
- Element element;
- SetterElement setterElement;
- if (!hasId && !hasSetterId) {
- _lookupCache[name] = null;
- return null;
- }
- bool isAccessor = false;
- if (hasId) {
- element = members.getElement(name);
- isAccessor = element.isGetter;
- }
- if (hasSetterId) {
- setterElement = members.getElement(setterName);
- isAccessor = true;
- }
- if (isAccessor) {
- element = new AbstractFieldElementZ(name, element, setterElement);
- }
- _lookupCache[name] = element;
- return element;
- }
-}
-
-/// Deserializer for a collection of member elements serialized as a list of
-/// element declarations.
-///
-/// The serialized data contains the declared getters and setters but lookup
-/// into the map returns an [AbstractFieldElement] for pairs of corresponding
-/// getters and setters.
-///
-/// The underlying list encoding requires the complete lookup map to be computed
-/// before query.
-class ListedContainer {
- final Map<String, Element> _lookupMap = <String, Element>{};
-
- ListedContainer(List<Element> elements) {
- Set<String> accessorNames = new Set<String>();
- Map<String, Element> getters = <String, Element>{};
- Map<String, Element> setters = <String, Element>{};
- for (Element element in elements) {
- String name = element.name;
- if (element.isDeferredLoaderGetter) {
- // Store directly.
- // TODO(johnniwinther): Should modelx be normalized to put `loadLibrary`
- // in an [AbstractFieldElement] instead?
- _lookupMap[name] = element;
- } else if (element.isGetter) {
- accessorNames.add(name);
- getters[name] = element;
- // Inserting [element] here to ensure insert order of [name].
- _lookupMap[name] = element;
- } else if (element.isSetter) {
- accessorNames.add(name);
- setters[name] = element;
- // Inserting [element] here to ensure insert order of [name].
- _lookupMap[name] = element;
- } else {
- _lookupMap[name] = element;
- }
- }
- for (String name in accessorNames) {
- _lookupMap[name] =
- new AbstractFieldElementZ(name, getters[name], setters[name]);
- }
- }
-
- Element lookup(String name) => _lookupMap[name];
-
- void forEach(f(Element element)) => _lookupMap.values.forEach(f);
-
- Iterable<Element> get values => _lookupMap.values;
-}
-
-abstract class AnalyzableElementMixin implements AnalyzableElement, ElementZ {
- @override
- bool get hasTreeElements => _unsupported('hasTreeElements');
-
- @override
- TreeElements get treeElements => _unsupported('treeElements');
-}
-
-abstract class AstElementMixinZ<N extends Node>
- implements AstElement, ElementZ {
- ResolvedAst _resolvedAst;
-
- // TODO(johnniwinther): This is needed for the token invariant assertion. Find
- // another way to bypass the test for modelz.
- @override
- bool get hasNode => false;
-
- @override
- bool get hasResolvedAst => _resolvedAst != null;
-
- @override
- N get node => _unsupported('node');
-
- @override
- ResolvedAst get resolvedAst {
- assert(_resolvedAst != null,
- failedAt(this, "ResolvedAst has not been set for $this."));
- return _resolvedAst;
- }
-
- void set resolvedAst(ResolvedAst value) {
- assert(_resolvedAst == null,
- failedAt(this, "ResolvedAst has already been set for $this."));
- _resolvedAst = value;
- }
-}
-
-abstract class ContainerMixin
- implements DeserializedElementZ, ScopeContainerElement {
- MappedContainer _membersMap = new MappedContainer();
-
- @override
- Element localLookup(String name) {
- return _membersMap.lookup(
- name, _decoder.getMap(Key.MEMBERS, isOptional: true));
- }
-
- @override
- void forEachLocalMember(f(Element element)) {
- MapDecoder members = _decoder.getMap(Key.MEMBERS, isOptional: true);
- if (members == null) return;
- members.forEachKey((String key) {
- Element member = members.getElement(key);
- if (member != null) {
- f(member);
- }
- });
- }
-}
-
-class AbstractFieldElementZ extends ElementZ
- with AbstractFieldElementCommon
- implements AbstractFieldElement {
- final String name;
- final GetterElementZ getter;
- final SetterElementZ setter;
-
- factory AbstractFieldElementZ(
- String name, GetterElement getter, SetterElement setter) {
- if (getter?.abstractField != null) {
- return getter.abstractField;
- } else if (setter?.abstractField != null) {
- return setter.abstractField;
- } else {
- return new AbstractFieldElementZ._(name, getter, setter);
- }
- }
-
- AbstractFieldElementZ._(this.name, this.getter, this.setter) {
- if (getter != null) {
- getter.abstractField = this;
- getter.setter = setter;
- }
- if (setter != null) {
- setter.abstractField = this;
- setter.getter = getter;
- }
- }
-
- FunctionElement get _canonicalElement => getter != null ? getter : setter;
-
- @override
- ElementKind get kind => ElementKind.ABSTRACT_FIELD;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitAbstractFieldElement(this, arg);
- }
-
- @override
- LibraryElement get library => _canonicalElement.library;
-
- @override
- CompilationUnitElement get compilationUnit {
- return _canonicalElement.compilationUnit;
- }
-
- @override
- Element get enclosingElement => _canonicalElement.enclosingElement;
-
- @override
- int get sourceOffset => _canonicalElement.sourceOffset;
-
- @override
- SourceSpan get sourcePosition => _canonicalElement.sourcePosition;
-
- @override
- ClassElement get enclosingClass => _canonicalElement.enclosingClass;
-
- @override
- bool get isClassMember => _canonicalElement.isClassMember;
-
- @override
- bool get isInstanceMember => _canonicalElement.isInstanceMember;
-
- @override
- bool get isStatic => _canonicalElement.isStatic;
-
- @override
- bool get isTopLevel => _canonicalElement.isTopLevel;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class LibraryElementZ extends DeserializedElementZ
- with AnalyzableElementMixin, ContainerMixin, LibraryElementCommon
- implements LibraryElement {
- Uri _canonicalUri;
- CompilationUnitElement _entryCompilationUnit;
- Link<CompilationUnitElement> _compilationUnits;
- List<ImportElement> _imports;
- List<ExportElement> _exports;
- ListedContainer _exportsMap;
- ListedContainer _importsMap;
- Map<Element, List<ImportElement>> _importsFor;
-
- LibraryElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ElementKind get kind => ElementKind.LIBRARY;
-
- @override
- Element get enclosingElement => null;
-
- @override
- SourceSpan get sourcePosition => entryCompilationUnit.sourcePosition;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitLibraryElement(this, arg);
- }
-
- @override
- LibraryElement get library => this;
-
- @override
- CompilationUnitElement get compilationUnit => entryCompilationUnit;
-
- @override
- Uri get canonicalUri {
- if (_canonicalUri == null) {
- _canonicalUri = _decoder.getUri(Key.CANONICAL_URI);
- }
- return _canonicalUri;
- }
-
- @override
- CompilationUnitElement get entryCompilationUnit {
- if (_entryCompilationUnit == null) {
- _entryCompilationUnit = _decoder.getElement(Key.COMPILATION_UNIT);
- }
- return _entryCompilationUnit;
- }
-
- @override
- Link<CompilationUnitElement> get compilationUnits {
- if (_compilationUnits == null) {
- _compilationUnits = toLink(_decoder.getElements(Key.COMPILATION_UNITS));
- }
- return _compilationUnits;
- }
-
- @override
- bool get hasLibraryName {
- return libraryName != '';
- }
-
- @override
- String get libraryName {
- return _decoder.getString(Key.LIBRARY_NAME);
- }
-
- @override
- bool get exportsHandled => true;
-
- void _ensureExports() {
- if (_exportsMap == null) {
- _exportsMap = new ListedContainer(
- _decoder.getElements(Key.EXPORT_SCOPE, isOptional: true));
- }
- }
-
- @override
- void forEachExport(f(Element element)) {
- _ensureExports();
- _exportsMap.forEach(f);
- }
-
- @override
- Element find(String elementName) {
- Element element = localLookup(elementName);
- if (element == null) {
- _ensureImports();
- element = _importsMap.lookup(elementName);
- }
- return element;
- }
-
- @override
- Element findLocal(String elementName) {
- return localLookup(elementName);
- }
-
- @override
- Element findExported(String elementName) {
- _ensureExports();
- return _exportsMap.lookup(elementName);
- }
-
- void _ensureImports() {
- if (_importsMap == null) {
- _importsMap = new ListedContainer(
- _decoder.getElements(Key.IMPORT_SCOPE, isOptional: true));
- _importsFor = <Element, List<ImportElement>>{};
-
- ListDecoder importsDecoder = _decoder.getList(Key.IMPORTS_FOR);
- for (int index = 0; index < importsDecoder.length; index++) {
- ObjectDecoder objectDecoder = importsDecoder.getObject(index);
- Element key = objectDecoder.getElement(Key.ELEMENT);
- List<ImportElement> imports =
- objectDecoder.getElements(Key.IMPORTS, isOptional: true);
-
- // Imports are mapped to [AbstractFieldElement] which are not serialized
- // so we use getter (or setter if there is no getter) as the key.
- Element importedElement = key;
- if (key.isDeferredLoaderGetter) {
- // Use as [importedElement].
- } else if (key.isAccessor) {
- AccessorElement accessor = key;
- importedElement = accessor.abstractField;
- }
- _importsFor[importedElement] = imports;
- }
- }
- }
-
- @override
- void forEachImport(f(Element element)) {
- _ensureImports();
- _importsMap.forEach(f);
- }
-
- @override
- Iterable<ImportElement> getImportsFor(Element element) {
- _ensureImports();
- return _importsFor[element] ?? const <ImportElement>[];
- }
-
- String toString() {
- return 'Zlibrary(${canonicalUri})';
- }
-
- @override
- Iterable<ExportElement> get exports {
- if (_exports == null) {
- _exports = _decoder.getElements(Key.EXPORTS, isOptional: true);
- }
- return _exports;
- }
-
- @override
- Iterable<ImportElement> get imports {
- if (_imports == null) {
- _imports = _decoder.getElements(Key.IMPORTS, isOptional: true);
- }
- return _imports;
- }
-}
-
-class ScriptZ implements Script {
- final Uri resourceUri;
- SourceFile _file;
- bool _isSynthesized = false;
-
- ScriptZ(this.resourceUri);
-
- @override
- Script copyWithFile(SourceFile file) {
- throw new UnsupportedError('ScriptZ.copyWithFile');
- }
-
- @override
- SourceFile get file {
- if (_file == null) {
- throw new UnsupportedError('ScriptZ.file');
- }
- return _file;
- }
-
- void set file(SourceFile value) {
- _file = value;
- }
-
- // TODO(johnniwinther): Decide if it is meaningful to serialize erroneous
- // elements.
- @override
- bool get isSynthesized => _isSynthesized;
-
- void set isSynthesized(bool value) {
- _isSynthesized = value;
- }
-
- @override
- String get name {
- if (_file != null) {
- return _file.filename;
- }
- return resourceUri.toString();
- }
-
- // TODO(johnniwinther): Support the distinction between [readableUri] and
- // [resourceUri]; needed for platform libraries.
- @override
- Uri get readableUri => resourceUri;
-
- @override
- String get text {
- if (_file != null) {
- return _file.slowText();
- }
- throw new UnsupportedError('ScriptZ.text');
- }
-}
-
-class CompilationUnitElementZ extends DeserializedElementZ
- with LibraryMemberMixin, CompilationUnitElementCommon
- implements CompilationUnitElement {
- List<Element> _members;
- Script _script;
-
- CompilationUnitElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ElementKind get kind => ElementKind.COMPILATION_UNIT;
-
- @override
- CompilationUnitElement get compilationUnit => this;
-
- @override
- Element get enclosingElement => library;
-
- @override
- SourceSpan get sourcePosition => new SourceSpan(script.resourceUri, 0, 0);
-
- @override
- bool get isTopLevel => false;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitCompilationUnitElement(this, arg);
- }
-
- @override
- void forEachLocalMember(f(Element element)) {
- if (_members == null) {
- _members = _decoder.getElements(Key.ELEMENTS, isOptional: true);
- }
- _members.forEach(f);
- }
-
- @override
- Script get script {
- if (_script == null) {
- Uri resolvedUri = _decoder.getUri(Key.URI);
- _script = new ScriptZ(resolvedUri);
- }
- return _script;
- }
-
- @override
- String get name => script.name;
-}
-
-abstract class LibraryMemberMixin implements DeserializedElementZ {
- LibraryElement _library;
- CompilationUnitElement _compilationUnit;
-
- @override
- LibraryElement get library {
- if (_library == null) {
- _library = _decoder.getElement(Key.LIBRARY);
- }
- return _library;
- }
-
- @override
- CompilationUnitElement get compilationUnit {
- if (_compilationUnit == null) {
- _compilationUnit = _decoder.getElement(Key.COMPILATION_UNIT);
- }
- return _compilationUnit;
- }
-
- @override
- Element get enclosingElement => compilationUnit;
-
- @override
- ClassElement get enclosingClass => null;
-
- @override
- bool get isTopLevel => true;
-
- @override
- bool get isStatic => false;
-}
-
-abstract class ClassMemberMixin implements DeserializedElementZ {
- ClassElement _class;
- CompilationUnitElement _compilationUnit;
-
- @override
- Element get enclosingElement => enclosingClass;
-
- @override
- ClassElement get enclosingClass {
- if (_class == null) {
- _class = _decoder.getElement(Key.CLASS);
- }
- return _class;
- }
-
- @override
- bool get isClassMember => true;
-
- @override
- LibraryElement get library => enclosingClass.library;
-
- @override
- CompilationUnitElement get compilationUnit {
- if (_compilationUnit == null) {
- _compilationUnit =
- _decoder.getElement(Key.COMPILATION_UNIT, isOptional: true);
- if (_compilationUnit == null) {
- _compilationUnit = enclosingClass.compilationUnit;
- }
- }
- return _compilationUnit;
- }
-}
-
-abstract class InstanceMemberMixin implements DeserializedElementZ {
- @override
- bool get isTopLevel => false;
-
- @override
- bool get isStatic => false;
-
- @override
- bool get isInstanceMember => true;
-
- @override
- bool get isClassMember => true;
-}
-
-abstract class StaticMemberMixin implements DeserializedElementZ {
- @override
- bool get isTopLevel => false;
-
- @override
- bool get isStatic => true;
-
- @override
- bool get isClassMember => true;
-}
-
-abstract class TypedElementMixin<T extends ResolutionDartType>
- implements DeserializedElementZ, TypedElement {
- T _type;
-
- @override
- T get type {
- if (_type == null) {
- _type = _decoder.getType(Key.TYPE);
- }
- return _type;
- }
-
- @override
- T computeType(Resolution resolution) => type;
-}
-
-abstract class ParametersMixin
- implements DeserializedElementZ, FunctionTypedElement {
- FunctionSignature _functionSignature;
- List<ParameterElement> _parameters;
-
- bool get hasFunctionSignature => true;
-
- @override
- FunctionSignature get functionSignature {
- if (_functionSignature == null) {
- List<Element> requiredParameters = [];
- List<Element> optionalParameters = [];
- List<Element> orderedOptionalParameters = [];
- int requiredParameterCount = 0;
- int optionalParameterCount = 0;
- bool optionalParametersAreNamed = false;
- List<ResolutionDartType> parameterTypes = <ResolutionDartType>[];
- List<ResolutionDartType> optionalParameterTypes = <ResolutionDartType>[];
- for (ParameterElement parameter in parameters) {
- if (parameter.isOptional) {
- optionalParameterCount++;
- optionalParameters.add(parameter);
- orderedOptionalParameters.add(parameter);
- if (parameter.isNamed) {
- optionalParametersAreNamed = true;
- } else {
- optionalParameterTypes.add(parameter.type);
- }
- } else {
- requiredParameterCount++;
- requiredParameters.add(parameter);
- parameterTypes.add(parameter.type);
- }
- }
- List<String> namedParameters = const <String>[];
- List<ResolutionDartType> namedParameterTypes =
- const <ResolutionDartType>[];
- if (optionalParametersAreNamed) {
- namedParameters = <String>[];
- namedParameterTypes = <ResolutionDartType>[];
- orderedOptionalParameters.sort((Element a, Element b) {
- return a.name.compareTo(b.name);
- });
- for (ParameterElement parameter in orderedOptionalParameters) {
- namedParameters.add(parameter.name);
- namedParameterTypes.add(parameter.type);
- }
- }
- List<ResolutionDartType> typeVariables =
- _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
-
- ResolutionFunctionType type = new ResolutionFunctionType(
- this,
- _decoder.getType(Key.RETURN_TYPE),
- parameterTypes,
- optionalParameterTypes,
- namedParameters,
- namedParameterTypes);
- _functionSignature = new FunctionSignatureX(
- typeVariables: typeVariables,
- requiredParameters: requiredParameters,
- requiredParameterCount: requiredParameterCount,
- optionalParameters: optionalParameters,
- optionalParameterCount: optionalParameterCount,
- optionalParametersAreNamed: optionalParametersAreNamed,
- orderedOptionalParameters: orderedOptionalParameters,
- type: type);
- }
- return _functionSignature;
- }
-
- List<ParameterElement> get parameters {
- if (_parameters == null) {
- _parameters = _decoder.getElements(Key.PARAMETERS, isOptional: true);
- }
- return _parameters;
- }
-
- ParameterStructure get parameterStructure =>
- functionSignature.parameterStructure;
-}
-
-abstract class FunctionTypedElementMixin
- implements FunctionElement, DeserializedElementZ {
- @override
- FunctionElement asFunctionElement() => this;
-
- @override
- bool get isExternal {
- return _decoder.getBool(Key.IS_EXTERNAL,
- isOptional: true, defaultValue: false);
- }
-
- @override
- List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
-}
-
-abstract class ClassElementMixin
- implements ElementZ, ClassElement, class_members.ClassMemberMixin {
- bool _isResolved = false;
-
- ResolutionInterfaceType _createType(List<ResolutionDartType> typeArguments) {
- return new ResolutionInterfaceType(this, typeArguments);
- }
-
- @override
- ElementKind get kind => ElementKind.CLASS;
-
- @override
- bool get hasConstructor => _unsupported('hasConstructor');
-
- @override
- bool get hasIncompleteHierarchy => _unsupported('hasIncompleteHierarchy');
-
- @override
- bool get hasLocalScopeMembers => _unsupported('hasLocalScopeMembers');
-
- @override
- bool get isEnumClass => false;
-
- @override
- ConstructorElement lookupDefaultConstructor() {
- ConstructorElement constructor = lookupConstructor("");
- if (constructor != null &&
- constructor.functionSignature.requiredParameterCount == 0) {
- return constructor;
- }
- return null;
- }
-
- @override
- ClassElement get superclass => supertype != null ? supertype.element : null;
-
- @override
- void ensureResolved(Resolution resolution) {
- if (!_isResolved) {
- _isResolved = true;
- // TODO(johnniwinther): Avoid eager computation of all members. `call` is
- // always needed, but the remaining should be computed on-demand or on
- // type instantiation.
- class_members.MembersCreator.computeAllClassMembers(resolution, this);
- resolution.registerClass(this);
- }
- }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class ClassElementZ extends DeserializedElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ,
- ClassElementCommon,
- class_members.ClassMemberMixin,
- ContainerMixin,
- LibraryMemberMixin,
- TypeDeclarationMixin,
- ClassElementMixin
- implements ClassElement {
- bool _isObject;
- ResolutionInterfaceType _supertype;
- OrderedTypeSet _allSupertypesAndSelf;
- Link<ResolutionDartType> _interfaces;
- ResolutionFunctionType _callType;
-
- ClassElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- List<ResolutionDartType> _getTypeVariables() {
- return _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
- }
-
- void _ensureSuperHierarchy() {
- if (_interfaces == null) {
- ResolutionInterfaceType supertype =
- _decoder.getType(Key.SUPERTYPE, isOptional: true);
- if (supertype == null) {
- _isObject = true;
- _allSupertypesAndSelf = new OrderedTypeSet.singleton(thisType);
- _interfaces = const Link<ResolutionDartType>();
- } else {
- _isObject = false;
- _interfaces =
- toLink(_decoder.getTypes(Key.INTERFACES, isOptional: true));
- List<ResolutionInterfaceType> mixins =
- _decoder.getTypes(Key.MIXINS, isOptional: true);
- for (ResolutionInterfaceType mixin in mixins) {
- MixinApplicationElement mixinElement =
- new UnnamedMixinApplicationElementZ(this, supertype, mixin);
- supertype = mixinElement.thisType
- .subst(typeVariables, mixinElement.typeVariables);
- }
- _supertype = supertype;
- _allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(this)
- .createOrderedTypeSet(_supertype, _interfaces);
- _callType = _decoder.getType(Key.CALL_TYPE, isOptional: true);
- }
- }
- }
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitClassElement(this, arg);
- }
-
- @override
- ResolutionDartType get supertype {
- _ensureSuperHierarchy();
- return _supertype;
- }
-
- @override
- bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
-
- @override
- bool get isObject {
- _ensureSuperHierarchy();
- return _isObject;
- }
-
- @override
- OrderedTypeSet get allSupertypesAndSelf {
- _ensureSuperHierarchy();
- return _allSupertypesAndSelf;
- }
-
- @override
- Link<ResolutionDartType> get interfaces {
- _ensureSuperHierarchy();
- return _interfaces;
- }
-
- @override
- bool get isProxy => _decoder.getBool(Key.IS_PROXY);
-
- @override
- bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
-
- @override
- bool get isUnnamedMixinApplication => false;
-
- @override
- ResolutionFunctionType get callType {
- _ensureSuperHierarchy();
- // TODO(johnniwinther): Why can't this always be computed in ensureResolved?
- return _callType;
- }
-
- ResolutionInterfaceType get thisType => super.thisType;
-
- ResolutionInterfaceType get rawType => super.rawType;
-}
-
-abstract class MixinApplicationElementMixin
- implements ElementZ, MixinApplicationElement {
- @override
- bool get isMixinApplication => true;
-
- @override
- ClassElement get mixin => mixinType.element;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class NamedMixinApplicationElementZ extends ClassElementZ
- with MixinApplicationElementMixin {
- Link<Element> _constructors;
- ResolutionInterfaceType _mixinType;
-
- NamedMixinApplicationElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ResolutionInterfaceType get mixinType =>
- _mixinType ??= _decoder.getType(Key.MIXIN);
-
- @override
- ClassElement get subclass => null;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class UnnamedMixinApplicationElementZ extends ElementZ
- with
- ClassElementCommon,
- ClassElementMixin,
- class_members.ClassMemberMixin,
- // ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_MIXIN
- TypeDeclarationMixin,
- AnalyzableElementMixin,
- AstElementMixinZ,
- MixinApplicationElementCommon,
- MixinApplicationElementMixin {
- final String name;
- final ClassElement subclass;
- final ResolutionInterfaceType _supertypeBase;
- final ResolutionInterfaceType _mixinBase;
- ResolutionInterfaceType _supertype;
- Link<ResolutionDartType> _interfaces;
- OrderedTypeSet _allSupertypesAndSelf;
- Link<ConstructorElement> _constructors;
-
- UnnamedMixinApplicationElementZ(this.subclass,
- ResolutionInterfaceType supertype, ResolutionInterfaceType mixin)
- : this._supertypeBase = supertype,
- this._mixinBase = mixin,
- this.name = "${supertype.name}+${mixin.name}";
-
- @override
- CompilationUnitElement get compilationUnit => subclass.compilationUnit;
-
- @override
- bool get isTopLevel => true;
-
- @override
- bool get isAbstract => true;
-
- @override
- bool get isUnnamedMixinApplication => true;
-
- Link<ConstructorElement> get constructors {
- if (_constructors == null) {
- LinkBuilder<ConstructorElement> builder =
- new LinkBuilder<ConstructorElement>();
- for (ConstructorElement definingConstructor in superclass.constructors) {
- if (definingConstructor.isGenerativeConstructor &&
- definingConstructor.memberName.isAccessibleFrom(library)) {
- ForwardingConstructorElementZ constructor =
- new ForwardingConstructorElementZ(this, definingConstructor);
- constructor.resolvedAst = new SynthesizedResolvedAst(
- constructor, ResolvedAstKind.FORWARDING_CONSTRUCTOR);
- builder.addLast(constructor);
- }
- }
- _constructors = builder.toLink();
- }
- return _constructors;
- }
-
- @override
- List<ResolutionDartType> _getTypeVariables() {
- // Create synthetic type variables for the mixin application.
- List<ResolutionDartType> typeVariables = <ResolutionDartType>[];
- int index = 0;
- for (ResolutionTypeVariableType type in subclass.typeVariables) {
- SyntheticTypeVariableElementZ typeVariableElement =
- new SyntheticTypeVariableElementZ(this, index, type.name);
- ResolutionTypeVariableType typeVariable =
- new ResolutionTypeVariableType(typeVariableElement);
- typeVariables.add(typeVariable);
- index++;
- }
- // Setup bounds on the synthetic type variables.
- for (ResolutionTypeVariableType type in subclass.typeVariables) {
- ResolutionTypeVariableType typeVariable =
- typeVariables[type.element.index];
- SyntheticTypeVariableElementZ typeVariableElement = typeVariable.element;
- typeVariableElement._type = typeVariable;
- typeVariableElement._bound =
- type.element.bound.subst(typeVariables, subclass.typeVariables);
- }
- return typeVariables;
- }
-
- @override
- ResolutionInterfaceType get supertype {
- if (_supertype == null) {
- // Substitute the type variables in [_supertypeBase] provided by
- // [_subclass] with the type variables in this unnamed mixin application.
- //
- // For instance
- // class S<S.T> {}
- // class M<M.T> {}
- // class C<C.T> extends S<C.T> with M<C.T> {}
- // the unnamed mixin application should be
- // abstract class S+M<S+M.T> extends S<S+M.T> implements M<S+M.T> {}
- // but the supertype is provided as S<C.T> and we need to substitute S+M.T
- // for C.T.
- _supertype = _supertypeBase.subst(typeVariables, subclass.typeVariables);
- }
- return _supertype;
- }
-
- @override
- Link<ResolutionDartType> get interfaces {
- if (_interfaces == null) {
- // Substitute the type variables in [_mixinBase] provided by
- // [_subclass] with the type variables in this unnamed mixin application.
- //
- // For instance
- // class S<S.T> {}
- // class M<M.T> {}
- // class C<C.T> extends S<C.T> with M<C.T> {}
- // the unnamed mixin application should be
- // abstract class S+M<S+M.T> extends S<S+M.T> implements M<S+M.T> {}
- // but the mixin is provided as M<C.T> and we need to substitute S+M.T
- // for C.T.
- _interfaces = const Link<ResolutionDartType>()
- .prepend(_mixinBase.subst(typeVariables, subclass.typeVariables));
- }
- return _interfaces;
- }
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitMixinApplicationElement(this, arg);
- }
-
- @override
- OrderedTypeSet get allSupertypesAndSelf {
- if (_allSupertypesAndSelf == null) {
- _allSupertypesAndSelf = new ResolutionOrderedTypeSetBuilder(this)
- .createOrderedTypeSet(supertype, interfaces);
- }
- return _allSupertypesAndSelf;
- }
-
- @override
- Element get enclosingElement => subclass.enclosingElement;
-
- @override
- bool get isObject => false;
-
- @override
- bool get isProxy => false;
-
- @override
- LibraryElement get library => enclosingElement.library;
-
- @override
- ResolutionInterfaceType get mixinType => interfaces.head;
-
- @override
- int get sourceOffset => subclass.sourceOffset;
-
- @override
- SourceSpan get sourcePosition => subclass.sourcePosition;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class EnumClassElementZ extends ClassElementZ implements EnumClassElement {
- List<FieldElement> _enumValues;
-
- EnumClassElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- bool get isEnumClass => true;
-
- @override
- List<EnumConstantElement> get enumValues {
- if (_enumValues == null) {
- _enumValues = _decoder.getElements(Key.FIELDS);
- }
- return _enumValues;
- }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-abstract class ConstructorElementZ extends DeserializedElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ<FunctionExpression>,
- ClassMemberMixin,
- FunctionTypedElementMixin,
- ParametersMixin,
- TypedElementMixin<ResolutionFunctionType>,
- MemberElementMixin,
- ConstructorElementCommon
- implements
- ConstructorElement,
- // TODO(johnniwinther): Sort out whether a constructor is a method.
- MethodElement {
- ConstantConstructor _constantConstructor;
- ConstructorElement _effectiveTarget;
-
- ConstructorElementZ(ObjectDecoder decoder) : super(decoder);
-
- accept(ElementVisitor visitor, arg) {
- return visitor.visitConstructorElement(this, arg);
- }
-
- @override
- bool get isConst => _decoder.getBool(Key.IS_CONST);
-
- @override
- bool get isExternal => _decoder.getBool(Key.IS_EXTERNAL);
-
- @override
- bool get isMarkedExternal => isExternal;
-
- @override
- bool get isDefaultConstructor => false;
-
- ConstantConstructor get constantConstructor {
- if (isConst && _constantConstructor == null) {
- ObjectDecoder data =
- _decoder.getObject(Key.CONSTRUCTOR, isOptional: true);
- if (data == null) {
- assert(isFromEnvironmentConstructor || isExternal);
- return null;
- }
- _constantConstructor = ConstantConstructorDeserializer.deserialize(data);
- }
- return _constantConstructor;
- }
-
- @override
- AsyncMarker get asyncMarker => AsyncMarker.SYNC;
-
- @override
- ConstructorElement get definingConstructor => null;
-
- @override
- bool get hasEffectiveTarget => true;
-
- @override
- ConstructorElement get effectiveTarget {
- if (_effectiveTarget == null) {
- _effectiveTarget =
- _decoder.getElement(Key.EFFECTIVE_TARGET, isOptional: true);
- if (_effectiveTarget == null) {
- _effectiveTarget = this;
- }
- }
- return _effectiveTarget;
- }
-
- @override
- ConstructorElement get immediateRedirectionTarget => null;
-
- // TODO(johnniwinther): Should serialization support erroneous element
- // relations?
- @override
- bool get isEffectiveTargetMalformed => false;
-
- @override
- bool get isCyclicRedirection => false;
-
- @override
- bool get isRedirectingFactory => false;
-
- @override
- bool get isRedirectingGenerative => false;
-
- @override
- PrefixElement get redirectionDeferredPrefix => null;
-
- @override
- ResolutionDartType computeEffectiveTargetType(
- ResolutionInterfaceType newType) =>
- newType;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class GenerativeConstructorElementZ extends ConstructorElementZ {
- GenerativeConstructorElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
-
- @override
- bool get isRedirectingGenerative => _decoder.getBool(Key.IS_REDIRECTING);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class DefaultConstructorElementZ extends ConstructorElementZ {
- DefaultConstructorElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
-
- @override
- bool get isSynthesized => true;
-
- @override
- bool get isDefaultConstructor => true;
-
- @override
- ConstructorElement get definingConstructor {
- return enclosingClass.superclass.lookupConstructor('');
- }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class FactoryConstructorElementZ extends ConstructorElementZ {
- FactoryConstructorElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class RedirectingFactoryConstructorElementZ extends ConstructorElementZ {
- ResolutionDartType _effectiveTargetType;
- ConstructorElement _immediateRedirectionTarget;
- PrefixElement _redirectionDeferredPrefix;
- bool _effectiveTargetIsMalformed;
-
- RedirectingFactoryConstructorElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
-
- @override
- bool get isRedirectingFactory => true;
-
- void _ensureEffectiveTarget() {
- if (_effectiveTarget == null) {
- _effectiveTarget =
- _decoder.getElement(Key.EFFECTIVE_TARGET, isOptional: true);
- if (_effectiveTarget == null) {
- _effectiveTarget = this;
- _effectiveTargetType = enclosingClass.thisType;
- _effectiveTargetIsMalformed = false;
- } else {
- _effectiveTargetType = _decoder.getType(Key.EFFECTIVE_TARGET_TYPE);
- _effectiveTargetIsMalformed =
- _decoder.getBool(Key.EFFECTIVE_TARGET_IS_MALFORMED);
- }
- }
- }
-
- bool get isEffectiveTargetMalformed {
- _ensureEffectiveTarget();
- return _effectiveTargetIsMalformed;
- }
-
- @override
- ConstructorElement get effectiveTarget {
- _ensureEffectiveTarget();
- return _effectiveTarget;
- }
-
- @override
- ResolutionDartType computeEffectiveTargetType(
- ResolutionInterfaceType newType) {
- _ensureEffectiveTarget();
- return _effectiveTargetType.substByContext(newType);
- }
-
- void _ensureRedirection() {
- if (_immediateRedirectionTarget == null) {
- _immediateRedirectionTarget =
- _decoder.getElement(Key.IMMEDIATE_REDIRECTION_TARGET);
- _redirectionDeferredPrefix =
- _decoder.getElement(Key.PREFIX, isOptional: true);
- }
- }
-
- @override
- ConstructorElement get immediateRedirectionTarget {
- _ensureRedirection();
- return _immediateRedirectionTarget;
- }
-
- @override
- PrefixElement get redirectionDeferredPrefix {
- _ensureRedirection();
- return _redirectionDeferredPrefix;
- }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class ForwardingConstructorElementZ extends ElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ<FunctionExpression>
- implements
- ConstructorElement,
- // TODO(johnniwinther): Sort out whether a constructor is a method.
- MethodElement {
- final MixinApplicationElement enclosingClass;
- final ConstructorElement definingConstructor;
-
- ForwardingConstructorElementZ(this.enclosingClass, this.definingConstructor);
-
- @override
- CompilationUnitElement get compilationUnit => enclosingClass.compilationUnit;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitConstructorElement(this, arg);
- }
-
- @override
- AsyncMarker get asyncMarker => AsyncMarker.SYNC;
-
- @override
- ResolutionDartType computeEffectiveTargetType(
- ResolutionInterfaceType newType) {
- return enclosingClass.thisType.substByContext(newType);
- }
-
- @override
- ResolutionDartType computeType(Resolution resolution) => type;
-
- @override
- bool get isConst => false;
-
- @override
- bool get isClassMember => true;
-
- @override
- bool get isDefaultConstructor => false;
-
- @override
- ConstantConstructor get constantConstructor => null;
-
- @override
- bool get hasEffectiveTarget => true;
-
- @override
- ConstructorElement get effectiveTarget => this;
-
- @override
- Element get enclosingElement => enclosingClass;
-
- @override
- FunctionSignature get functionSignature {
- // TODO(johnniwinther): Ensure that the function signature (and with it the
- // function type) substitutes type variables correctly.
- return definingConstructor.functionSignature;
- }
-
- @override
- ParameterStructure get parameterStructure {
- return functionSignature.parameterStructure;
- }
-
- @override
- bool get hasFunctionSignature {
- return _unsupported('hasFunctionSignature');
- }
-
- @override
- ConstructorElement get immediateRedirectionTarget => null;
-
- @override
- bool get isCyclicRedirection => false;
-
- @override
- bool get isEffectiveTargetMalformed => false;
-
- @override
- bool get isExternal => false;
-
- @override
- bool get isMarkedExternal => false;
-
- @override
- bool get isFromEnvironmentConstructor => false;
-
- @override
- bool get isIntFromEnvironmentConstructor => false;
-
- @override
- bool get isBoolFromEnvironmentConstructor => false;
-
- @override
- bool get isStringFromEnvironmentConstructor => false;
-
- @override
- bool get isRedirectingFactory => false;
-
- @override
- bool get isRedirectingGenerative => false;
-
- @override
- bool get isSynthesized => true;
-
- @override
- ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
-
- @override
- LibraryElement get library => enclosingClass.library;
-
- @override
- MemberElement get memberContext => this;
-
- @override
- Name get memberName => definingConstructor.memberName;
-
- @override
- String get name => definingConstructor.name;
-
- @override
- List<MethodElement> get nestedClosures => const <MethodElement>[];
-
- @override
- List<ParameterElement> get parameters {
- // TODO(johnniwinther): We need to create synthetic parameters that
- // substitute type variables.
- return definingConstructor.parameters;
- }
-
- // TODO: implement redirectionDeferredPrefix
- @override
- PrefixElement get redirectionDeferredPrefix => null;
-
- @override
- int get sourceOffset => enclosingClass.sourceOffset;
-
- @override
- SourceSpan get sourcePosition => enclosingClass.sourcePosition;
-
- @override
- ResolutionFunctionType get type {
- // TODO(johnniwinther): Ensure that the function type substitutes type
- // variables correctly.
- return definingConstructor.type;
- }
-
- @override
- List<ResolutionDartType> get typeVariables => _unsupported("typeVariables");
-}
-
-abstract class MemberElementMixin
- implements DeserializedElementZ, MemberElement {
- final List<MethodElement> nestedClosures = <MethodElement>[];
-
- @override
- MemberElement get memberContext => this;
-
- @override
- Name get memberName => new Name(name, library);
-
- @override
- bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
-}
-
-abstract class FieldElementZ extends DeserializedElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ<VariableDefinitions>,
- TypedElementMixin,
- MemberElementMixin
- implements FieldElement {
- bool _isConst;
- ConstantExpression _constant;
-
- FieldElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ElementKind get kind => ElementKind.FIELD;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitFieldElement(this, arg);
- }
-
- @override
- bool get isFinal => _decoder.getBool(Key.IS_FINAL);
-
- void _ensureConstant() {
- if (_isConst == null) {
- _isConst = _decoder.getBool(Key.IS_CONST);
- _constant = _decoder.getConstant(Key.CONSTANT, isOptional: true);
- }
- }
-
- @override
- bool get isConst {
- _ensureConstant();
- return _isConst;
- }
-
- @override
- bool get hasConstant => true;
-
- @override
- ConstantExpression get constant {
- _ensureConstant();
- return _constant;
- }
-
- @override
- Expression get initializer => _unsupported('initializer');
-}
-
-class TopLevelFieldElementZ extends FieldElementZ with LibraryMemberMixin {
- TopLevelFieldElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-class StaticFieldElementZ extends FieldElementZ
- with ClassMemberMixin, StaticMemberMixin {
- StaticFieldElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class EnumConstantElementZ extends StaticFieldElementZ
- implements EnumConstantElement {
- EnumConstantElementZ(ObjectDecoder decoder) : super(decoder);
-
- int get index => _decoder.getInt(Key.INDEX);
-}
-
-class InstanceFieldElementZ extends FieldElementZ
- with ClassMemberMixin, InstanceMemberMixin {
- InstanceFieldElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-abstract class FunctionElementZ extends DeserializedElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ<FunctionExpression>,
- ParametersMixin,
- FunctionTypedElementMixin,
- TypedElementMixin<ResolutionFunctionType>,
- MemberElementMixin
- implements MethodElement {
- FunctionElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ElementKind get kind => ElementKind.FUNCTION;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitMethodElement(this, arg);
- }
-
- @override
- AsyncMarker get asyncMarker {
- return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
- }
-
- @override
- bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
-
- @override
- bool get isOperator => _decoder.getBool(Key.IS_OPERATOR);
-
- @override
- bool get isMarkedExternal => isExternal;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class TopLevelFunctionElementZ extends FunctionElementZ
- with LibraryMemberMixin {
- TopLevelFunctionElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class StaticFunctionElementZ extends FunctionElementZ
- with ClassMemberMixin, StaticMemberMixin {
- StaticFunctionElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class InstanceFunctionElementZ extends FunctionElementZ
- with ClassMemberMixin, InstanceMemberMixin {
- InstanceFunctionElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-abstract class LocalExecutableMixin
- implements DeserializedElementZ, ExecutableElement, LocalElement {
- ExecutableElement _executableContext;
-
- @override
- Element get enclosingElement => executableContext;
-
- @override
- ClassElementZ get enclosingClass => memberContext.enclosingClass;
-
- @override
- ExecutableElement get executableContext {
- if (_executableContext == null) {
- _executableContext = _decoder.getElement(Key.EXECUTABLE_CONTEXT);
- }
- return _executableContext;
- }
-
- @override
- MemberElement get memberContext => executableContext.memberContext;
-
- @override
- bool get isLocal => true;
-
- @override
- LibraryElement get library => memberContext.library;
-
- @override
- CompilationUnitElement get compilationUnit {
- return memberContext.compilationUnit;
- }
-
- @override
- bool get hasTreeElements => memberContext.hasTreeElements;
-
- @override
- TreeElements get treeElements => memberContext.treeElements;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class LocalFunctionElementZ extends DeserializedElementZ
- with
- LocalExecutableMixin,
- AstElementMixinZ<FunctionExpression>,
- ParametersMixin,
- FunctionTypedElementMixin,
- TypedElementMixin<ResolutionFunctionType>
- implements LocalFunctionElement {
- LocalFunctionElementZ(ObjectDecoder decoder) : super(decoder);
-
- MethodElement callMethod;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitLocalFunctionElement(this, arg);
- }
-
- @override
- ElementKind get kind => ElementKind.FUNCTION;
-
- @override
- AsyncMarker get asyncMarker {
- return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
- }
-
- @override
- bool get isMarkedExternal => false;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-abstract class GetterElementZ extends DeserializedElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ<FunctionExpression>,
- FunctionTypedElementMixin,
- ParametersMixin,
- TypedElementMixin<ResolutionFunctionType>,
- MemberElementMixin
- implements GetterElement {
- AbstractFieldElement abstractField;
- SetterElement setter;
-
- GetterElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ElementKind get kind => ElementKind.GETTER;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitGetterElement(this, arg);
- }
-
- @override
- bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
-
- @override
- bool get isMarkedExternal => isExternal;
-
- @override
- AsyncMarker get asyncMarker {
- return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
- }
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class TopLevelGetterElementZ extends GetterElementZ with LibraryMemberMixin {
- TopLevelGetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class StaticGetterElementZ extends GetterElementZ
- with ClassMemberMixin, StaticMemberMixin {
- StaticGetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class InstanceGetterElementZ extends GetterElementZ
- with ClassMemberMixin, InstanceMemberMixin {
- InstanceGetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-abstract class SetterElementZ extends DeserializedElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ<FunctionExpression>,
- FunctionTypedElementMixin,
- ParametersMixin,
- TypedElementMixin<ResolutionFunctionType>,
- MemberElementMixin
- implements SetterElement {
- AbstractFieldElement abstractField;
- GetterElement getter;
-
- SetterElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- ElementKind get kind => ElementKind.SETTER;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitSetterElement(this, arg);
- }
-
- @override
- bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
-
- @override
- bool get isMarkedExternal => isExternal;
-
- @override
- AsyncMarker get asyncMarker => AsyncMarker.SYNC;
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class TopLevelSetterElementZ extends SetterElementZ with LibraryMemberMixin {
- TopLevelSetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class StaticSetterElementZ extends SetterElementZ
- with ClassMemberMixin, StaticMemberMixin {
- StaticSetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-// ignore: STRONG_MODE_INVALID_METHOD_OVERRIDE_FROM_BASE
-class InstanceSetterElementZ extends SetterElementZ
- with ClassMemberMixin, InstanceMemberMixin {
- InstanceSetterElementZ(ObjectDecoder decoder) : super(decoder);
-}
-
-abstract class TypeDeclarationMixin
- implements ElementZ, TypeDeclarationElement {
- List<ResolutionDartType> _typeVariables;
- GenericType _rawType;
- GenericType _thisType;
- Name _memberName;
-
- Name get memberName {
- if (_memberName == null) {
- _memberName = new Name(name, library);
- }
- return _memberName;
- }
-
- List<ResolutionDartType> _getTypeVariables();
-
- void _ensureTypes() {
- if (_typeVariables == null) {
- _typeVariables = _getTypeVariables();
- _rawType = _createType(new List<ResolutionDartType>.filled(
- _typeVariables.length, const ResolutionDynamicType()));
- _thisType = _createType(_typeVariables);
- }
- }
-
- GenericType _createType(List<ResolutionDartType> typeArguments);
-
- @override
- List<ResolutionDartType> get typeVariables {
- _ensureTypes();
- return _typeVariables;
- }
-
- @override
- GenericType get rawType {
- _ensureTypes();
- return _rawType;
- }
-
- @override
- GenericType get thisType {
- _ensureTypes();
- return _thisType;
- }
-
- @override
- GenericType computeType(Resolution resolution) => thisType;
-
- @override
- bool get isResolved => true;
-}
-
-class TypedefElementZ extends DeserializedElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ<Node>,
- LibraryMemberMixin,
- ParametersMixin,
- TypeDeclarationMixin
- implements TypedefElement {
- ResolutionDartType _alias;
-
- TypedefElementZ(ObjectDecoder decoder) : super(decoder);
-
- ResolutionTypedefType _createType(List<ResolutionDartType> typeArguments) {
- return new ResolutionTypedefType(this, typeArguments);
- }
-
- @override
- List<ResolutionDartType> _getTypeVariables() {
- return _decoder.getTypes(Key.TYPE_VARIABLES, isOptional: true);
- }
-
- @override
- ElementKind get kind => ElementKind.TYPEDEF;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitTypedefElement(this, arg);
- }
-
- @override
- ResolutionDartType get alias {
- if (_alias == null) {
- _alias = _decoder.getType(Key.ALIAS);
- }
- return _alias;
- }
-
- @override
- void ensureResolved(Resolution resolution) {}
-
- @override
- void checkCyclicReference(Resolution resolution) {}
-
- ResolutionTypedefType get thisType => super.thisType;
-
- ResolutionTypedefType get rawType => super.rawType;
-}
-
-class TypeVariableElementZ extends DeserializedElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ<Node>,
- TypedElementMixin<ResolutionTypeVariableType>
- implements TypeVariableElement {
- GenericElement _typeDeclaration;
- ResolutionTypeVariableType _type;
- ResolutionDartType _bound;
- Name _memberName;
-
- TypeVariableElementZ(ObjectDecoder decoder) : super(decoder);
-
- Name get memberName {
- if (_memberName == null) {
- _memberName = new Name(name, library);
- }
- return _memberName;
- }
-
- @override
- ElementKind get kind => ElementKind.TYPE_VARIABLE;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitTypeVariableElement(this, arg);
- }
-
- @override
- CompilationUnitElement get compilationUnit {
- return typeDeclaration.compilationUnit;
- }
-
- @override
- Element get enclosingElement => typeDeclaration;
-
- @override
- ClassElementZ get enclosingClass => typeDeclaration;
-
- @override
- int get index => _decoder.getInt(Key.INDEX);
-
- @override
- GenericElement get typeDeclaration {
- if (_typeDeclaration == null) {
- _typeDeclaration = _decoder.getElement(Key.TYPE_DECLARATION);
- }
- return _typeDeclaration;
- }
-
- ResolutionDartType get bound {
- if (_bound == null) {
- _bound = _decoder.getType(Key.BOUND);
- }
- return _bound;
- }
-
- @override
- LibraryElement get library => typeDeclaration.library;
-}
-
-class SyntheticTypeVariableElementZ extends ElementZ
- with AnalyzableElementMixin, AstElementMixinZ<Node>
- implements TypeVariableElement {
- final TypeDeclarationElement typeDeclaration;
- final int index;
- final String name;
- ResolutionTypeVariableType _type;
- ResolutionDartType _bound;
- Name _memberName;
-
- SyntheticTypeVariableElementZ(this.typeDeclaration, this.index, this.name);
-
- Name get memberName {
- if (_memberName == null) {
- _memberName = new Name(name, library);
- }
- return _memberName;
- }
-
- @override
- ElementKind get kind => ElementKind.TYPE_VARIABLE;
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitTypeVariableElement(this, arg);
- }
-
- @override
- CompilationUnitElement get compilationUnit {
- return typeDeclaration.compilationUnit;
- }
-
- @override
- ResolutionTypeVariableType get type {
- assert(_type != null,
- failedAt(this, "Type variable type has not been set on $this."));
- return _type;
- }
-
- @override
- ResolutionTypeVariableType computeType(Resolution resolution) => type;
-
- @override
- Element get enclosingElement => typeDeclaration;
-
- @override
- ClassElementZ get enclosingClass => typeDeclaration;
-
- ResolutionDartType get bound {
- assert(_bound != null,
- failedAt(this, "Type variable bound has not been set on $this."));
- return _bound;
- }
-
- @override
- LibraryElement get library => typeDeclaration.library;
-
- @override
- int get sourceOffset => typeDeclaration.sourceOffset;
-
- @override
- SourceSpan get sourcePosition => typeDeclaration.sourcePosition;
-}
-
-abstract class ParameterElementZ extends DeserializedElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ<VariableDefinitions>,
- TypedElementMixin
- implements ParameterElement {
- FunctionElement _functionDeclaration;
- ConstantExpression _constant;
- ResolutionDartType _type;
-
- ParameterElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- bool get isFinal => _decoder.getBool(Key.IS_FINAL);
-
- @override
- bool get isConst => false;
-
- @override
- bool get hasConstant => true;
-
- @override
- ConstantExpression get constant {
- if (isOptional) {
- if (_constant == null) {
- _constant = _decoder.getConstant(Key.CONSTANT);
- }
- return _constant;
- }
- return null;
- }
-
- @override
- CompilationUnitElement get compilationUnit {
- return functionDeclaration.compilationUnit;
- }
-
- @override
- ExecutableElement get executableContext => functionDeclaration;
-
- @override
- Element get enclosingElement => functionDeclaration;
-
- @override
- FunctionElement get functionDeclaration {
- if (_functionDeclaration == null) {
- _functionDeclaration = _decoder.getElement(Key.FUNCTION);
- }
- return _functionDeclaration;
- }
-
- @override
- FunctionSignature get functionSignature => _unsupported('functionSignature');
-
- // TODO(johnniwinther): Remove [initializer] and [node] on
- // [ParameterElementZ] when the inference does need these.
- @override
- Expression initializer;
-
- @override
- VariableDefinitions node;
-
- @override
- bool get isNamed => _decoder.getBool(Key.IS_NAMED);
-
- @override
- bool get isOptional => _decoder.getBool(Key.IS_OPTIONAL);
-
- @override
- LibraryElement get library => executableContext.library;
-
- @override
- MemberElement get memberContext => executableContext.memberContext;
-
- @override
- List<ResolutionDartType> get typeVariables => functionSignature.typeVariables;
-}
-
-class LocalParameterElementZ extends ParameterElementZ
- implements LocalParameterElement {
- LocalParameterElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitParameterElement(this, arg);
- }
-
- @override
- bool get isLocal => true;
-
- @override
- ElementKind get kind => ElementKind.PARAMETER;
-
- @override
- bool get isUnnamed => false;
-}
-
-class InitializingFormalElementZ extends LocalParameterElementZ
- implements InitializingFormalElement {
- FieldElement _fieldElement;
-
- InitializingFormalElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- FieldElement get fieldElement {
- if (_fieldElement == null) {
- _fieldElement = _decoder.getElement(Key.FIELD);
- }
- return _fieldElement;
- }
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitFieldParameterElement(this, arg);
- }
-
- @override
- ElementKind get kind => ElementKind.INITIALIZING_FORMAL;
-
- @override
- bool get isLocal => true;
-
- ConstructorElementZ get functionDeclaration => super.functionDeclaration;
-}
-
-class LocalVariableElementZ extends DeserializedElementZ
- with
- AnalyzableElementMixin,
- AstElementMixinZ<VariableDefinitions>,
- LocalExecutableMixin,
- TypedElementMixin
- implements LocalVariableElement {
- bool _isConst;
- ConstantExpression _constant;
-
- LocalVariableElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- accept(ElementVisitor visitor, arg) {
- return visitor.visitLocalVariableElement(this, arg);
- }
-
- @override
- ElementKind get kind => ElementKind.VARIABLE;
-
- @override
- bool get isFinal => _decoder.getBool(Key.IS_FINAL);
-
- @override
- bool get isConst {
- if (_isConst == null) {
- _constant = _decoder.getConstant(Key.CONSTANT, isOptional: true);
- _isConst = _constant != null;
- }
- return _isConst;
- }
-
- @override
- bool get hasConstant => true;
-
- @override
- ConstantExpression get constant {
- if (isConst) {
- return _constant;
- }
- return null;
- }
-
- @override
- Expression get initializer => _unsupported('initializer');
-}
-
-class ImportElementZ extends DeserializedElementZ
- with LibraryMemberMixin
- implements ImportElement {
- bool _isDeferred;
- PrefixElement _prefix;
- LibraryElement _importedLibrary;
- Uri _uri;
-
- ImportElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- String get name => '';
-
- @override
- accept(ElementVisitor visitor, arg) => visitor.visitImportElement(this, arg);
-
- @override
- ElementKind get kind => ElementKind.IMPORT;
-
- @override
- LibraryElement get importedLibrary {
- if (_importedLibrary == null) {
- _importedLibrary = _decoder.getElement(Key.LIBRARY_DEPENDENCY);
- }
- return _importedLibrary;
- }
-
- void _ensurePrefixResolved() {
- if (_isDeferred == null) {
- _isDeferred = _decoder.getBool(Key.IS_DEFERRED);
- _prefix = _decoder.getElement(Key.PREFIX, isOptional: true);
- }
- }
-
- LibraryElement get enclosingLibrary => library;
-
- @override
- bool get isDeferred {
- _ensurePrefixResolved();
- return _isDeferred;
- }
-
- @override
- PrefixElement get prefix {
- _ensurePrefixResolved();
- return _prefix;
- }
-
- @override
- Uri get uri {
- if (_uri == null) {
- _uri = _decoder.getUri(Key.URI);
- }
- return _uri;
- }
-
- @override
- Import get node => _unsupported('node');
-
- String toString() => 'Z$kind($uri)';
-}
-
-class ExportElementZ extends DeserializedElementZ
- with LibraryMemberMixin
- implements ExportElement {
- LibraryElement _exportedLibrary;
- Uri _uri;
-
- ExportElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- String get name => '';
-
- @override
- accept(ElementVisitor visitor, arg) => visitor.visitExportElement(this, arg);
-
- @override
- ElementKind get kind => ElementKind.EXPORT;
-
- @override
- LibraryElement get exportedLibrary {
- if (_exportedLibrary == null) {
- _exportedLibrary = _decoder.getElement(Key.LIBRARY_DEPENDENCY);
- }
- return _exportedLibrary;
- }
-
- @override
- Uri get uri {
- if (_uri == null) {
- _uri = _decoder.getUri(Key.URI);
- }
- return _uri;
- }
-
- @override
- Export get node => _unsupported('node');
-
- String toString() => 'Z$kind($uri)';
-}
-
-class PrefixElementZ extends DeserializedElementZ
- with LibraryMemberMixin
- implements PrefixElement {
- bool _isDeferred;
- ImportElement _deferredImport;
- GetterElement _loadLibrary;
- ListedContainer _members;
-
- PrefixElementZ(ObjectDecoder decoder) : super(decoder);
-
- @override
- accept(ElementVisitor visitor, arg) => visitor.visitPrefixElement(this, arg);
-
- @override
- bool get isTopLevel => false;
-
- void _ensureDeferred() {
- if (_isDeferred == null) {
- _isDeferred = _decoder.getBool(Key.IS_DEFERRED);
- if (_isDeferred) {
- _deferredImport = _decoder.getElement(Key.IMPORT);
- _loadLibrary = _decoder.getElement(Key.GETTER);
- }
- }
- }
-
- @override
- ImportElement get deferredImport {
- _ensureDeferred();
- return _deferredImport;
- }
-
- @override
- bool get isDeferred {
- _ensureDeferred();
- return _isDeferred;
- }
-
- @override
- GetterElement get loadLibrary {
- return _loadLibrary;
- }
-
- @override
- ElementKind get kind => ElementKind.PREFIX;
-
- void _ensureMembers() {
- if (_members == null) {
- _members = new ListedContainer(
- _decoder.getElements(Key.MEMBERS, isOptional: true));
- }
- }
-
- @override
- Element lookupLocalMember(String memberName) {
- _ensureMembers();
- return _members.lookup(memberName);
- }
-
- @override
- void forEachLocalMember(void f(Element member)) {
- _ensureMembers();
- _members.forEach(f);
- }
-}
-
-class MetadataAnnotationZ implements MetadataAnnotation {
- final Element annotatedElement;
- final SourceSpan sourcePosition;
- final ConstantExpression constant;
-
- MetadataAnnotationZ(
- this.annotatedElement, this.sourcePosition, this.constant);
-
- @override
- MetadataAnnotation ensureResolved(Resolution resolution) {
- // Do nothing.
- return this;
- }
-
- @override
- Node get node => throw new UnsupportedError('${this}.node');
-
- @override
- bool get hasNode => false;
-
- String toString() => 'MetadataAnnotationZ(${constant.toDartText()})';
-}
diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
deleted file mode 100644
index 3983391..0000000
--- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
+++ /dev/null
@@ -1,718 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.resolved_ast;
-
-import 'package:front_end/src/fasta/parser.dart' show Parser, ParserError;
-import 'package:front_end/src/fasta/scanner.dart';
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../constants/expressions.dart';
-import '../diagnostics/diagnostic_listener.dart';
-import '../elements/elements.dart';
-import '../elements/jumps.dart';
-import '../elements/modelx.dart';
-import '../elements/resolution_types.dart';
-import '../parser/node_listener.dart' show NodeListener;
-import '../resolution/enum_creator.dart';
-import '../resolution/send_structure.dart';
-import '../resolution/tree_elements.dart';
-import '../tree/tree.dart';
-import '../universe/selector.dart';
-import 'keys.dart';
-import 'modelz.dart';
-import 'serialization.dart';
-import 'serialization_util.dart';
-
-/// Visitor that computes a node-index mapping.
-class AstIndexComputer extends Visitor {
- final Map<Node, int> nodeIndices = <Node, int>{};
- final List<Node> nodeList = <Node>[];
-
- @override
- visitNode(Node node) {
- nodeIndices.putIfAbsent(node, () {
- // Some nodes (like Modifier and empty NodeList) can be reused.
- nodeList.add(node);
- return nodeIndices.length;
- });
- node.visitChildren(this);
- }
-}
-
-/// The kind of AST node. Used for determining how to deserialize
-/// [ResolvedAst]s.
-enum AstKind {
- ENUM_CONSTRUCTOR,
- ENUM_CONSTANT,
- ENUM_INDEX_FIELD,
- ENUM_NAME_FIELD,
- ENUM_VALUES_FIELD,
- ENUM_TO_STRING,
- FACTORY,
- FIELD,
- FUNCTION,
-}
-
-/// Serializer for [ResolvedAst]s.
-class ResolvedAstSerializer extends Visitor {
- final SerializerPlugin nativeDataSerializer;
- final ObjectEncoder objectEncoder;
- final ResolvedAst resolvedAst;
- final AstIndexComputer indexComputer = new AstIndexComputer();
- final Map<int, ObjectEncoder> nodeData = <int, ObjectEncoder>{};
- ListEncoder _nodeDataEncoder;
-
- ResolvedAstSerializer(
- this.objectEncoder, this.resolvedAst, this.nativeDataSerializer);
-
- AstElement get element => resolvedAst.element;
-
- TreeElements get elements => resolvedAst.elements;
-
- Node get root => resolvedAst.node;
-
- Map<Node, int> get nodeIndices => indexComputer.nodeIndices;
- List<Node> get nodeList => indexComputer.nodeList;
-
- Map<JumpTarget, int> jumpTargetMap = <JumpTarget, int>{};
- Map<LabelDefinition, int> labelDefinitionMap = <LabelDefinition, int>{};
-
- /// Returns the unique id for [jumpTarget], creating it if necessary.
- int getJumpTargetId(JumpTarget jumpTarget) {
- return jumpTargetMap.putIfAbsent(jumpTarget, () => jumpTargetMap.length);
- }
-
- /// Returns the unique id for [labelDefinition], creating it if necessary.
- int getLabelDefinitionId(LabelDefinition labelDefinition) {
- return labelDefinitionMap.putIfAbsent(
- labelDefinition, () => labelDefinitionMap.length);
- }
-
- /// Serializes [resolvedAst] into [objectEncoder].
- void serialize() {
- objectEncoder.setEnum(Key.KIND, resolvedAst.kind);
- switch (resolvedAst.kind) {
- case ResolvedAstKind.PARSED:
- serializeParsed();
- break;
- case ResolvedAstKind.DEFAULT_CONSTRUCTOR:
- case ResolvedAstKind.FORWARDING_CONSTRUCTOR:
- case ResolvedAstKind.DEFERRED_LOAD_LIBRARY:
- // No additional properties.
- break;
- }
- }
-
- /// Serialize [ResolvedAst] that is defined in terms of an AST together with
- /// [TreeElements].
- void serializeParsed() {
- objectEncoder.setUri(Key.URI, resolvedAst.sourceUri, resolvedAst.sourceUri);
- AstKind kind;
- if (element.enclosingClass is EnumClassElement) {
- if (element.name == 'index') {
- kind = AstKind.ENUM_INDEX_FIELD;
- } else if (element.name == '_name') {
- kind = AstKind.ENUM_NAME_FIELD;
- } else if (element.name == 'values') {
- kind = AstKind.ENUM_VALUES_FIELD;
- } else if (element.name == 'toString') {
- kind = AstKind.ENUM_TO_STRING;
- } else if (element.isConstructor) {
- kind = AstKind.ENUM_CONSTRUCTOR;
- } else {
- assert(element.isConst,
- failedAt(element, "Unexpected enum member: $element"));
- kind = AstKind.ENUM_CONSTANT;
- }
- } else {
- // [element] has a body that we'll need to re-parse. We store where to
- // start parsing from.
- objectEncoder.setInt(Key.OFFSET, root.getBeginToken().charOffset);
- if (element.isFactoryConstructor) {
- kind = AstKind.FACTORY;
- } else if (element.isField) {
- kind = AstKind.FIELD;
- } else {
- kind = AstKind.FUNCTION;
- FunctionExpression functionExpression = root.asFunctionExpression();
- if (functionExpression.getOrSet != null) {
- // Getters/setters need the get/set token to be parsed.
- objectEncoder.setInt(
- Key.GET_OR_SET, functionExpression.getOrSet.charOffset);
- }
- }
- }
- objectEncoder.setEnum(Key.SUB_KIND, kind);
- root.accept(indexComputer);
- objectEncoder.setBool(Key.CONTAINS_TRY, elements.containsTryStatement);
- if (resolvedAst.body != null) {
- int index = nodeIndices[resolvedAst.body];
- assert(
- index != null,
- failedAt(
- element,
- "No index for body of $element: "
- "${resolvedAst.body} ($nodeIndices)."));
- objectEncoder.setInt(Key.BODY, index);
- }
- root.accept(this);
- if (jumpTargetMap.isNotEmpty) {
- ListEncoder list = objectEncoder.createList(Key.JUMP_TARGETS);
- for (JumpTarget jumpTarget in jumpTargetMap.keys) {
- serializeJumpTarget(jumpTarget, list.createObject());
- }
- }
- if (labelDefinitionMap.isNotEmpty) {
- ListEncoder list = objectEncoder.createList(Key.LABEL_DEFINITIONS);
- for (LabelDefinition labelDefinition in labelDefinitionMap.keys) {
- serializeLabelDefinition(labelDefinition, list.createObject());
- }
- }
-
- if (element is FunctionElement) {
- serializeParameterNodes(element);
- }
- }
-
- void serializeParameterNodes(FunctionElement function) {
- function.functionSignature.forEachParameter((_parameter) {
- ParameterElement parameter = _parameter;
- ParameterElement parameterImpl = parameter.implementation;
- // TODO(johnniwinther): Should we support element->node mapping as well?
- getNodeDataEncoder(parameterImpl.node)
- .setElement(PARAMETER_NODE, parameter);
- if (parameter.initializer != null) {
- getNodeDataEncoder(parameterImpl.initializer)
- .setElement(PARAMETER_INITIALIZER, parameter);
- }
- });
- }
-
- /// Serialize [target] into [encoder].
- void serializeJumpTarget(JumpTargetX jumpTarget, ObjectEncoder encoder) {
- encoder.setElement(Key.EXECUTABLE_CONTEXT, jumpTarget.executableContext);
- encoder.setInt(Key.NODE, nodeIndices[jumpTarget.statement]);
- encoder.setInt(Key.NESTING_LEVEL, jumpTarget.nestingLevel);
- encoder.setBool(Key.IS_BREAK_TARGET, jumpTarget.isBreakTarget);
- encoder.setBool(Key.IS_CONTINUE_TARGET, jumpTarget.isContinueTarget);
- if (jumpTarget.labels.isNotEmpty) {
- List<int> labelIdList = <int>[];
- for (LabelDefinition label in jumpTarget.labels) {
- labelIdList.add(getLabelDefinitionId(label));
- }
- encoder.setInts(Key.LABELS, labelIdList);
- }
- }
-
- /// Serialize [label] into [encoder].
- void serializeLabelDefinition(
- LabelDefinitionX labelDefinition, ObjectEncoder encoder) {
- encoder.setInt(Key.NODE, nodeIndices[labelDefinition.label]);
- encoder.setString(Key.NAME, labelDefinition.labelName);
- encoder.setBool(Key.IS_BREAK_TARGET, labelDefinition.isBreakTarget);
- encoder.setBool(Key.IS_CONTINUE_TARGET, labelDefinition.isContinueTarget);
- encoder.setInt(Key.JUMP_TARGET, getJumpTargetId(labelDefinition.target));
- }
-
- /// Computes the [ListEncoder] for serializing data for nodes.
- ListEncoder get nodeDataEncoder {
- if (_nodeDataEncoder == null) {
- _nodeDataEncoder = objectEncoder.createList(Key.DATA);
- }
- return _nodeDataEncoder;
- }
-
- /// Computes the [ObjectEncoder] for serializing data for [node].
- ObjectEncoder getNodeDataEncoder(Node node) {
- assert(node != null, failedAt(element, "Node must be non-null."));
- int id = nodeIndices[node];
- assert(id != null, failedAt(element, "Node without id: $node"));
- return nodeData.putIfAbsent(id, () {
- ObjectEncoder objectEncoder = nodeDataEncoder.createObject();
- objectEncoder.setInt(Key.ID, id);
- return objectEncoder;
- });
- }
-
- @override
- visitNode(Node node) {
- Element nodeElement = elements[node];
- if (nodeElement != null) {
- serializeElementReference(element, Key.ELEMENT, Key.NAME,
- getNodeDataEncoder(node), nodeElement);
- }
- ResolutionDartType type = elements.getType(node);
- if (type != null) {
- getNodeDataEncoder(node).setType(Key.TYPE, type);
- }
- Selector selector = elements.getSelector(node);
- if (selector != null) {
- serializeSelector(
- selector, getNodeDataEncoder(node).createObject(Key.SELECTOR));
- }
- ConstantExpression constant = elements.getConstant(node);
- if (constant != null) {
- getNodeDataEncoder(node).setConstant(Key.CONSTANT, constant);
- }
- ResolutionDartType cachedType = elements.typesCache[node];
- if (cachedType != null) {
- getNodeDataEncoder(node).setType(Key.CACHED_TYPE, cachedType);
- }
- JumpTarget jumpTargetDefinition = elements.getTargetDefinition(node);
- if (jumpTargetDefinition != null) {
- getNodeDataEncoder(node).setInt(
- Key.JUMP_TARGET_DEFINITION, getJumpTargetId(jumpTargetDefinition));
- }
- var nativeData = elements.getNativeData(node);
- if (nativeData != null) {
- nativeDataSerializer.onData(
- nativeData, getNodeDataEncoder(node).createObject(Key.NATIVE));
- }
- node.visitChildren(this);
- }
-
- @override
- visitSend(Send node) {
- visitExpression(node);
- SendStructure structure = elements.getSendStructure(node);
- if (structure != null) {
- serializeSendStructure(
- structure, getNodeDataEncoder(node).createObject(Key.SEND_STRUCTURE));
- }
- }
-
- @override
- visitNewExpression(NewExpression node) {
- visitExpression(node);
- NewStructure structure = elements.getNewStructure(node);
- if (structure != null) {
- serializeNewStructure(
- structure, getNodeDataEncoder(node).createObject(Key.NEW_STRUCTURE));
- }
- }
-
- @override
- visitGotoStatement(GotoStatement node) {
- visitStatement(node);
- JumpTarget jumpTarget = elements.getTargetOf(node);
- if (jumpTarget != null) {
- getNodeDataEncoder(node)
- .setInt(Key.JUMP_TARGET, getJumpTargetId(jumpTarget));
- }
- if (node.target != null) {
- LabelDefinition targetLabel = elements.getTargetLabel(node);
- if (targetLabel != null) {
- getNodeDataEncoder(node)
- .setInt(Key.TARGET_LABEL, getLabelDefinitionId(targetLabel));
- }
- }
- }
-
- @override
- visitLabel(Label node) {
- visitNode(node);
- LabelDefinition labelDefinition = elements.getLabelDefinition(node);
- if (labelDefinition != null) {
- getNodeDataEncoder(node)
- .setInt(Key.LABEL_DEFINITION, getLabelDefinitionId(labelDefinition));
- }
- }
-
- @override
- visitFunctionExpression(FunctionExpression node) {
- visitExpression(node);
- Element function = elements.getFunctionDefinition(node);
- if (function != null && function.isFunction && function.isLocal) {
- // Mark root nodes of local functions; these need their own ResolvedAst.
- getNodeDataEncoder(node).setElement(Key.FUNCTION, function);
- serializeParameterNodes(function);
- }
- }
-}
-
-class ResolvedAstDeserializer {
- /// Find the [Token] at [offset] searching through successors of [token].
- static Token findTokenInStream(Token token, int offset) {
- while (token.charOffset <= offset && token.next != token) {
- if (token.charOffset == offset) {
- return token;
- }
- token = token.next;
- }
- return null;
- }
-
- /// Deserializes the [ResolvedAst]s for [element] and its nested local
- /// functions from [objectDecoder] and adds these to [resolvedAstMap].
- /// [parsing] and [getBeginToken] are used for parsing the [Node] for
- /// [element] from its source code.
- static void deserialize(
- Element element,
- ObjectDecoder objectDecoder,
- ParsingContext parsing,
- Token getBeginToken(Uri uri, int charOffset),
- DeserializerPlugin nativeDataDeserializer) {
- ResolvedAstKind kind =
- objectDecoder.getEnum(Key.KIND, ResolvedAstKind.values);
- switch (kind) {
- case ResolvedAstKind.PARSED:
- deserializeParsed(element, objectDecoder, parsing, getBeginToken,
- nativeDataDeserializer);
- break;
- case ResolvedAstKind.DEFAULT_CONSTRUCTOR:
- case ResolvedAstKind.FORWARDING_CONSTRUCTOR:
- (element as AstElementMixinZ).resolvedAst =
- new SynthesizedResolvedAst(element, kind);
- break;
- case ResolvedAstKind.DEFERRED_LOAD_LIBRARY:
- break;
- }
- }
-
- /// Deserialize the [ResolvedAst]s for the member [element] (constructor,
- /// method, or field) and its nested closures. The [ResolvedAst]s are added
- /// to [resolvedAstMap].
- static void deserializeParsed(
- AstElementMixinZ element,
- ObjectDecoder objectDecoder,
- ParsingContext parsing,
- Token getBeginToken(Uri uri, int charOffset),
- DeserializerPlugin nativeDataDeserializer) {
- DiagnosticReporter reporter = parsing.reporter;
- Uri uri = objectDecoder.getUri(Key.URI);
-
- /// Returns the first [Token] for parsing the [Node] for [element].
- Token readBeginToken() {
- int charOffset = objectDecoder.getInt(Key.OFFSET);
- Token beginToken = getBeginToken(uri, charOffset);
- if (beginToken == null) {
- // TODO(johnniwinther): Handle unfound tokens by adding an erroneous
- // resolved ast kind.
- reporter.internalError(
- element, "No token found for $element in $uri @ $charOffset");
- }
- return beginToken;
- }
-
- /// Create the [Node] for the element by parsing the source code.
- Node doParse(parse(Parser parser)) {
- return parsing.measure(() {
- return reporter.withCurrentElement(element, () {
- NodeListener listener = new NodeListener(
- parsing.getScannerOptionsFor(element), reporter, null);
- listener.memberErrors = listener.memberErrors.prepend(false);
- try {
- Parser parser = new Parser(listener);
- parse(parser);
- } on ParserError catch (e) {
- reporter.internalError(element, '$e');
- }
- return listener.popNode();
- });
- });
- }
-
- /// Computes the [Node] for the element based on the [AstKind].
- // ignore: MISSING_RETURN
- Node computeNode(AstKind kind) {
- switch (kind) {
- case AstKind.ENUM_INDEX_FIELD:
- AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
- Identifier identifier = builder.identifier('index');
- VariableDefinitions node = new VariableDefinitions(
- null,
- builder.modifiers(isFinal: true),
- new NodeList.singleton(identifier));
- return node;
- case AstKind.ENUM_NAME_FIELD:
- AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
- Identifier identifier = builder.identifier('_name');
- VariableDefinitions node = new VariableDefinitions(
- null,
- builder.modifiers(isFinal: true),
- new NodeList.singleton(identifier));
- return node;
- case AstKind.ENUM_VALUES_FIELD:
- EnumClassElement enumClass = element.enclosingClass;
- AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
- List<Node> valueReferences = <Node>[];
- for (EnumConstantElement enumConstant in enumClass.enumValues) {
- AstBuilder valueBuilder =
- new AstBuilder(enumConstant.sourcePosition.begin);
- Identifier name = valueBuilder.identifier(enumConstant.name);
-
- // Add reference for the `values` field.
- valueReferences.add(valueBuilder.reference(name));
- }
-
- Identifier valuesIdentifier = builder.identifier('values');
- // TODO(johnniwinther): Add type argument.
- Expression initializer =
- builder.listLiteral(valueReferences, isConst: true);
-
- Node definition =
- builder.createDefinition(valuesIdentifier, initializer);
- VariableDefinitions node = new VariableDefinitions(
- null,
- builder.modifiers(isStatic: true, isConst: true),
- new NodeList.singleton(definition));
- return node;
- case AstKind.ENUM_TO_STRING:
- EnumClassElement enumClass = element.enclosingClass;
- AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
- List<LiteralMapEntry> mapEntries = <LiteralMapEntry>[];
- for (EnumConstantElement enumConstant in enumClass.enumValues) {
- AstBuilder valueBuilder =
- new AstBuilder(enumConstant.sourcePosition.begin);
- Identifier name = valueBuilder.identifier(enumConstant.name);
-
- // Add map entry for `toString` implementation.
- mapEntries.add(valueBuilder.mapLiteralEntry(
- valueBuilder.literalInt(enumConstant.index),
- valueBuilder
- .literalString('${enumClass.name}.${name.source}')));
- }
-
- // TODO(johnniwinther): Support return type. Note `String` might be
- // prefixed or not imported within the current library.
- FunctionExpression toStringNode = builder.functionExpression(
- Modifiers.EMPTY,
- 'toString',
- null,
- builder.argumentList([]),
- builder.returnStatement(
- builder.reference(builder.identifier('_name'))));
- return toStringNode;
- case AstKind.ENUM_CONSTRUCTOR:
- AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
- VariableDefinitions indexDefinition =
- builder.initializingFormal('index');
- VariableDefinitions nameDefinition =
- builder.initializingFormal('_name');
- FunctionExpression constructorNode = builder.functionExpression(
- builder.modifiers(isConst: true),
- element.enclosingClass.name,
- null,
- builder.argumentList([indexDefinition, nameDefinition]),
- builder.emptyStatement());
- return constructorNode;
- case AstKind.ENUM_CONSTANT:
- EnumConstantElementZ enumConstant = element;
- EnumClassElement enumClass = element.enclosingClass;
- int index = enumConstant.index;
- AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
- Identifier name = builder.identifier(element.name);
-
- String enumString = "${enumClass.name}.${element.name}";
- Expression initializer = builder.newExpression(
- enumClass.name,
- builder.argumentList([
- builder.literalInt(index),
- builder.literalString(enumString)
- ]),
- isConst: true);
- SendSet definition = builder.createDefinition(name, initializer);
-
- VariableDefinitions node = new VariableDefinitions(
- null,
- builder.modifiers(isStatic: true, isConst: true),
- new NodeList.singleton(definition));
- return node;
- case AstKind.FACTORY:
- Token beginToken = readBeginToken();
- return doParse((parser) => parser.parseClassMember(beginToken));
- case AstKind.FIELD:
- Token beginToken = readBeginToken();
- return doParse((parser) => parser.parseClassMember(beginToken));
- case AstKind.FUNCTION:
- Token beginToken = readBeginToken();
- int getOrSetOffset =
- objectDecoder.getInt(Key.GET_OR_SET, isOptional: true);
- Token getOrSet;
- if (getOrSetOffset != null) {
- getOrSet = findTokenInStream(beginToken, getOrSetOffset);
- if (getOrSet == null) {
- reporter.internalError(
- element,
- "No token found for $element in "
- "${uri} @ $getOrSetOffset");
- }
- }
- return doParse((parser) {
- parser.parseClassMember(beginToken);
- });
- }
- }
-
- AstKind kind = objectDecoder.getEnum(Key.SUB_KIND, AstKind.values);
- Node root = computeNode(kind);
- TreeElementMapping elements = new TreeElementMapping(element);
- AstIndexComputer indexComputer = new AstIndexComputer();
- List<Node> nodeList = indexComputer.nodeList;
- root.accept(indexComputer);
- elements.containsTryStatement = objectDecoder.getBool(Key.CONTAINS_TRY);
-
- Node body;
- int bodyNodeIndex = objectDecoder.getInt(Key.BODY, isOptional: true);
- if (bodyNodeIndex != null) {
- assert(
- bodyNodeIndex < nodeList.length,
- failedAt(
- element,
- "Body node index ${bodyNodeIndex} out of range. "
- "Node count: ${nodeList.length}"));
- body = nodeList[bodyNodeIndex];
- }
-
- List<JumpTarget> jumpTargets = <JumpTarget>[];
- Map<JumpTarget, List<int>> jumpTargetLabels = <JumpTarget, List<int>>{};
- List<LabelDefinition> labelDefinitions = <LabelDefinition>[];
-
- ListDecoder jumpTargetsDecoder =
- objectDecoder.getList(Key.JUMP_TARGETS, isOptional: true);
- if (jumpTargetsDecoder != null) {
- for (int i = 0; i < jumpTargetsDecoder.length; i++) {
- ObjectDecoder decoder = jumpTargetsDecoder.getObject(i);
- ExecutableElement executableContext =
- decoder.getElement(Key.EXECUTABLE_CONTEXT);
- Node statement = nodeList[decoder.getInt(Key.NODE)];
- int nestingLevel = decoder.getInt(Key.NESTING_LEVEL);
- JumpTargetX jumpTarget =
- new JumpTargetX(statement, nestingLevel, executableContext);
- jumpTarget.isBreakTarget = decoder.getBool(Key.IS_BREAK_TARGET);
- jumpTarget.isContinueTarget = decoder.getBool(Key.IS_CONTINUE_TARGET);
- jumpTargetLabels[jumpTarget] =
- decoder.getInts(Key.LABELS, isOptional: true);
- jumpTargets.add(jumpTarget);
- }
- }
-
- ListDecoder labelDefinitionsDecoder =
- objectDecoder.getList(Key.LABEL_DEFINITIONS, isOptional: true);
- if (labelDefinitionsDecoder != null) {
- for (int i = 0; i < labelDefinitionsDecoder.length; i++) {
- ObjectDecoder decoder = labelDefinitionsDecoder.getObject(i);
- Label label = nodeList[decoder.getInt(Key.NODE)];
- String labelName = decoder.getString(Key.NAME);
- JumpTarget target = jumpTargets[decoder.getInt(Key.JUMP_TARGET)];
- LabelDefinitionX labelDefinition =
- new LabelDefinitionX(label, labelName, target);
- labelDefinition.isBreakTarget = decoder.getBool(Key.IS_BREAK_TARGET);
- labelDefinition.isContinueTarget =
- decoder.getBool(Key.IS_CONTINUE_TARGET);
- labelDefinitions.add(labelDefinition);
- }
- }
- jumpTargetLabels.forEach((JumpTarget jumpTarget, List<int> labelIds) {
- if (labelIds.isEmpty) return;
- List<LabelDefinition> labels = <LabelDefinition>[];
- for (int labelId in labelIds) {
- labels.add(labelDefinitions[labelId]);
- }
- JumpTargetX target = jumpTarget;
- target.labels = labels;
- });
-
- ListDecoder dataDecoder = objectDecoder.getList(Key.DATA, isOptional: true);
- if (dataDecoder != null) {
- for (int i = 0; i < dataDecoder.length; i++) {
- ObjectDecoder objectDecoder = dataDecoder.getObject(i);
- int id = objectDecoder.getInt(Key.ID);
- Node node = nodeList[id];
- Element nodeElement = deserializeElementReference(
- element, Key.ELEMENT, Key.NAME, objectDecoder,
- isOptional: true);
- if (nodeElement != null) {
- elements[node] = nodeElement;
- }
- ResolutionDartType type =
- objectDecoder.getType(Key.TYPE, isOptional: true);
- if (type != null) {
- elements.setType(node, type);
- }
- ObjectDecoder selectorDecoder =
- objectDecoder.getObject(Key.SELECTOR, isOptional: true);
- if (selectorDecoder != null) {
- elements.setSelector(node, deserializeSelector(selectorDecoder));
- }
- ConstantExpression constant =
- objectDecoder.getConstant(Key.CONSTANT, isOptional: true);
- if (constant != null) {
- elements.setConstant(node, constant);
- }
- ResolutionDartType cachedType =
- objectDecoder.getType(Key.CACHED_TYPE, isOptional: true);
- if (cachedType != null) {
- elements.typesCache[node] = cachedType;
- }
- ObjectDecoder sendStructureDecoder =
- objectDecoder.getObject(Key.SEND_STRUCTURE, isOptional: true);
- if (sendStructureDecoder != null) {
- elements.setSendStructure(
- node, deserializeSendStructure(sendStructureDecoder));
- }
- ObjectDecoder newStructureDecoder =
- objectDecoder.getObject(Key.NEW_STRUCTURE, isOptional: true);
- if (newStructureDecoder != null) {
- elements.setNewStructure(
- node, deserializeNewStructure(newStructureDecoder));
- }
- int targetDefinitionId =
- objectDecoder.getInt(Key.JUMP_TARGET_DEFINITION, isOptional: true);
- if (targetDefinitionId != null) {
- elements.defineTarget(node, jumpTargets[targetDefinitionId]);
- }
- int targetOfId =
- objectDecoder.getInt(Key.JUMP_TARGET, isOptional: true);
- if (targetOfId != null) {
- elements.registerTargetOf(node, jumpTargets[targetOfId]);
- }
- int labelDefinitionId =
- objectDecoder.getInt(Key.LABEL_DEFINITION, isOptional: true);
- if (labelDefinitionId != null) {
- elements.defineLabel(node, labelDefinitions[labelDefinitionId]);
- }
- int targetLabelId =
- objectDecoder.getInt(Key.TARGET_LABEL, isOptional: true);
- if (targetLabelId != null) {
- elements.registerTargetLabel(node, labelDefinitions[targetLabelId]);
- }
- ObjectDecoder nativeDataDecoder =
- objectDecoder.getObject(Key.NATIVE, isOptional: true);
- if (nativeDataDecoder != null) {
- var nativeData = nativeDataDeserializer.onData(nativeDataDecoder);
- if (nativeData != null) {
- elements.registerNativeData(node, nativeData);
- }
- }
- LocalFunctionElementZ function =
- objectDecoder.getElement(Key.FUNCTION, isOptional: true);
- if (function != null) {
- FunctionExpression functionExpression = node;
- function.resolvedAst = new ParsedResolvedAst(function,
- functionExpression, functionExpression.body, elements, uri);
- }
- // TODO(johnniwinther): Remove these when inference doesn't need `.node`
- // and `.initializer` of [ParameterElement]s.
- ParameterElementZ parameter =
- objectDecoder.getElement(PARAMETER_NODE, isOptional: true);
- if (parameter != null) {
- parameter.node = node;
- }
- parameter =
- objectDecoder.getElement(PARAMETER_INITIALIZER, isOptional: true);
- if (parameter != null) {
- parameter.initializer = node;
- }
- }
- }
- element.resolvedAst =
- new ParsedResolvedAst(element, root, body, elements, uri);
- }
-}
-
-const Key PARAMETER_NODE = const Key('parameter.node');
-const Key PARAMETER_INITIALIZER = const Key('parameter.initializer');
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
deleted file mode 100644
index 592687e..0000000
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ /dev/null
@@ -1,1163 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization;
-
-import 'package:front_end/src/scanner/token.dart' show TokenType;
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../library_loader.dart' show LibraryProvider;
-import '../util/enumset.dart';
-import 'constant_serialization.dart';
-import 'element_serialization.dart';
-import 'json_serializer.dart';
-import 'keys.dart';
-import 'type_serialization.dart';
-import 'values.dart';
-
-export 'task.dart' show LibraryDeserializer;
-
-final Map<String, String> canonicalNames = computeCanonicalNames();
-
-Map<String, String> computeCanonicalNames() {
- Map<String, String> result = <String, String>{};
- for (TokenType type in TokenType.all) {
- result[type.value] = type.value;
- }
- return result;
-}
-
-/// An object that supports the encoding an [ObjectValue] for serialization.
-///
-/// The [ObjectEncoder] ensures that nominality and circularities of
-/// non-primitive values like [Element], [ResolutionDartType] and
-/// [ConstantExpression] are handled.
-class ObjectEncoder extends AbstractEncoder<Key> {
- /// Creates an [ObjectEncoder] in the scope of [serializer] that uses [map]
- /// as its internal storage.
- ObjectEncoder(Serializer serializer, Map<dynamic, Value> map)
- : super(serializer, map);
-
- String get _name => 'Object';
-}
-
-/// An object that supports the encoding a [MapValue] for serialization.
-///
-/// The [MapEncoder] ensures that nominality and circularities of
-/// non-primitive values like [Element], [ResolutionDartType] and
-/// [ConstantExpression] are handled.
-class MapEncoder extends AbstractEncoder<String> {
- /// Creates an [MapEncoder] in the scope of [serializer] that uses [map]
- /// as its internal storage.
- MapEncoder(Serializer serializer, Map<String, Value> map)
- : super(serializer, map);
-
- String get _name => 'Map';
-}
-
-/// An object that supports the encoding a [ListValue] containing [ObjectValue]s
-/// or [MapValue]s.
-///
-/// The [ListEncoder] ensures that nominality and circularities of
-/// non-primitive values like [Element], [ResolutionDartType] and
-/// [ConstantExpression] are handled.
-class ListEncoder {
- final Serializer _serializer;
- final List<Value> _list;
-
- /// Creates an [ListEncoder] in the scope of [_serializer] that uses [_list]
- /// as its internal storage.
- ListEncoder(this._serializer, this._list);
-
- /// Creates an [ObjectEncoder] and adds it to the encoded list.
- ObjectEncoder createObject() {
- Map<Key, Value> map = <Key, Value>{};
- _list.add(new ObjectValue(map));
- return new ObjectEncoder(_serializer, map);
- }
-
- /// Creates an [ObjectEncoder] and adds it to the encoded list.
- MapEncoder createMap() {
- Map<String, Value> map = {};
- _list.add(new MapValue(map));
- return new MapEncoder(_serializer, map);
- }
-}
-
-/// Abstract base implementation for [ObjectEncoder] and [MapEncoder].
-abstract class AbstractEncoder<K> {
- final Serializer _serializer;
- final Map<K, Value> _map;
-
- AbstractEncoder(this._serializer, this._map);
-
- /// The name of the encoder kind. Use for error reporting.
- String get _name;
-
- void _checkKey(K key) {
- if (_map.containsKey(key)) {
- throw new StateError("$_name value '$key' already in $_map.");
- }
- }
-
- /// Maps the [key] entry to the [value] in the encoded object.
- void setValue(K key, Value value) {
- _checkKey(key);
- _map[key] = value;
- }
-
- /// Maps the [key] entry to the enum [value] in the encoded object.
- void setEnum(K key, var value) {
- _checkKey(key);
- _map[key] = new EnumValue(value);
- }
-
- /// Maps the [key] entry to the set of enum [values] in the encoded object.
- void setEnums(K key, Iterable values) {
- setEnumSet(key, new EnumSet.fromValues(values));
- }
-
- /// Maps the [key] entry to the enum [set] in the encoded object.
- void setEnumSet(K key, EnumSet set) {
- _checkKey(key);
- _map[key] = new IntValue(set.value);
- }
-
- /// Maps the [key] entry to the [element] in the encoded object.
- void setElement(K key, Element element) {
- _checkKey(key);
- _map[key] = _serializer.createElementValue(element);
- }
-
- /// Maps the [key] entry to the [elements] in the encoded object.
- ///
- /// If [elements] is empty, it is skipped.
- void setElements(K key, Iterable<Element> elements) {
- _checkKey(key);
- if (elements.isNotEmpty) {
- _map[key] =
- new ListValue(elements.map(_serializer.createElementValue).toList());
- }
- }
-
- /// Maps the [key] entry to the [constant] in the encoded object.
- void setConstant(K key, ConstantExpression constant) {
- _checkKey(key);
- _map[key] = _serializer.createConstantValue(constant);
- }
-
- /// Maps the [key] entry to the [constants] in the encoded object.
- ///
- /// If [constants] is empty, it is skipped.
- void setConstants(K key, Iterable<ConstantExpression> constants) {
- _checkKey(key);
- if (constants.isNotEmpty) {
- _map[key] = new ListValue(
- constants.map(_serializer.createConstantValue).toList());
- }
- }
-
- /// Maps the [key] entry to the [type] in the encoded object.
- void setType(K key, ResolutionDartType type) {
- _checkKey(key);
- _map[key] = _serializer.createTypeValue(type);
- }
-
- /// Maps the [key] entry to the [types] in the encoded object.
- ///
- /// If [types] is empty, it is skipped.
- void setTypes(K key, Iterable<ResolutionDartType> types) {
- _checkKey(key);
- if (types.isNotEmpty) {
- _map[key] =
- new ListValue(types.map(_serializer.createTypeValue).toList());
- }
- }
-
- /// Maps the [key] entry to the [uri] in the encoded object using [baseUri] to
- /// relatives the encoding.
- ///
- /// For instance, a source file like `sdk/lib/core/string.dart` should be
- /// serialized relative to the library root.
- void setUri(K key, Uri baseUri, Uri uri) {
- _checkKey(key);
- _map[key] = new UriValue(baseUri, uri);
- }
-
- /// Maps the [key] entry to the string [value] in the encoded object.
- void setString(K key, String value) {
- _checkKey(key);
- _map[key] = new StringValue(value);
- }
-
- /// Maps the [key] entry to the string [values] in the encoded object.
- ///
- /// If [values] is empty, it is skipped.
- void setStrings(K key, Iterable<String> values) {
- _checkKey(key);
- if (values.isNotEmpty) {
- _map[key] = new ListValue(values.map((v) => new StringValue(v)).toList());
- }
- }
-
- /// Maps the [key] entry to the bool [value] in the encoded object.
- void setBool(K key, bool value) {
- _checkKey(key);
- _map[key] = new BoolValue(value);
- }
-
- /// Maps the [key] entry to the int [value] in the encoded object.
- void setInt(K key, int value) {
- _checkKey(key);
- _map[key] = new IntValue(value);
- }
-
- /// Maps the [key] entry to the int [values] in this serializer.
- ///
- /// If [values] is empty, it is skipped.
- void setInts(K key, Iterable<int> values) {
- _checkKey(key);
- if (values.isNotEmpty) {
- _map[key] = new ListValue(values.map((v) => new IntValue(v)).toList());
- }
- }
-
- /// Maps the [key] entry to the double [value] in the encoded object.
- void setDouble(K key, double value) {
- _checkKey(key);
- _map[key] = new DoubleValue(value);
- }
-
- /// Creates and returns an [ObjectEncoder] that is mapped to the [key]
- /// entry in the encoded object.
- ObjectEncoder createObject(K key) {
- Map<Key, Value> map = <Key, Value>{};
- _map[key] = new ObjectValue(map);
- return new ObjectEncoder(_serializer, map);
- }
-
- /// Creates and returns a [MapEncoder] that is mapped to the [key] entry
- /// in the encoded object.
- MapEncoder createMap(K key) {
- Map<String, Value> map = <String, Value>{};
- _map[key] = new MapValue(map);
- return new MapEncoder(_serializer, map);
- }
-
- /// Creates and returns a [ListEncoder] that is mapped to the [key] entry
- /// in the encoded object.
- ListEncoder createList(K key) {
- List<Value> list = <Value>[];
- _map[key] = new ListValue(list);
- return new ListEncoder(_serializer, list);
- }
-
- String toString() => _map.toString();
-}
-
-/// [ObjectDecoder] reads serialized values from a [Map] encoded from an
-/// [ObjectValue] where properties are stored using [Key] values as keys.
-class ObjectDecoder extends AbstractDecoder<dynamic, Key> {
- /// Creates an [ObjectDecoder] that decodes [map] into deserialized values
- /// using [deserializer] to create canonicalized values.
- ObjectDecoder(Deserializer deserializer, Map map) : super(deserializer, map);
-
- @override
- _getKeyValue(Key key) => _deserializer.decoder.getObjectPropertyValue(key);
-}
-
-/// [MapDecoder] reads serialized values from a [Map] encoded from an
-/// [MapValue] where entries are stored using [String] values as keys.
-class MapDecoder extends AbstractDecoder<String, String> {
- /// Creates an [MapDecoder] that decodes [map] into deserialized values
- /// using [deserializer] to create canonicalized values.
- MapDecoder(Deserializer deserializer, Map<String, dynamic> map)
- : super(deserializer, map);
-
- @override
- String _getKeyValue(String key) => key;
-
- /// Applies [f] to every key in the decoded [Map].
- void forEachKey(f(String key)) {
- _map.keys.forEach(f);
- }
-}
-
-/// [ListDecoder] reads serialized map or object values from a [List].
-class ListDecoder {
- final Deserializer _deserializer;
- final List _list;
-
- /// Creates a [ListDecoder] that decodes [_list] using [_deserializer] to
- /// create canonicalized values.
- ListDecoder(this._deserializer, this._list);
-
- /// The number of values in the decoded list.
- int get length => _list.length;
-
- /// Returns an [ObjectDecoder] for the [index]th object value in the decoded
- /// list.
- ObjectDecoder getObject(int index) {
- return new ObjectDecoder(_deserializer, _list[index]);
- }
-
- /// Returns an [MapDecoder] for the [index]th map value in the decoded list.
- MapDecoder getMap(int index) {
- return new MapDecoder(_deserializer, _list[index]);
- }
-}
-
-/// Abstract base implementation for [ObjectDecoder] and [MapDecoder].
-abstract class AbstractDecoder<M, K> {
- final Deserializer _deserializer;
- final Map<M, dynamic> _map;
-
- AbstractDecoder(this._deserializer, this._map) {
- assert(_deserializer != null);
- assert(_map != null);
- }
-
- /// Returns the value for [key] defined by the [SerializationDecoder] in used
- /// [_deserializer].
- M _getKeyValue(K key);
-
- /// Returns `true` if [key] has an associated value in the decoded object.
- bool containsKey(K key) => _map.containsKey(_getKeyValue(key));
-
- /// Returns the enum value from the [enumValues] associated with [key] in the
- /// decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// [defaultValue] is returned, otherwise an exception is thrown.
- getEnum(K key, List enumValues, {bool isOptional: false, defaultValue}) {
- int value = _map[_getKeyValue(key)];
- if (value == null) {
- if (isOptional || defaultValue != null) {
- return defaultValue;
- }
- throw new StateError("enum value '$key' not found in $_map.");
- }
- return enumValues[value];
- }
-
- /// Returns the set of enum values associated with [key] in the decoded
- /// object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// [defaultValue] is returned, otherwise an exception is thrown.
- EnumSet getEnums(K key, {bool isOptional: false}) {
- int value = _map[_getKeyValue(key)];
- if (value == null) {
- if (isOptional) {
- return const EnumSet.fixed(0);
- }
- throw new StateError("enum values '$key' not found in $_map.");
- }
- return new EnumSet.fixed(value);
- }
-
- /// Returns the [Element] value associated with [key] in the decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// `null` is returned, otherwise an exception is thrown.
- Element getElement(K key, {bool isOptional: false}) {
- int id = _map[_getKeyValue(key)];
- if (id == null) {
- if (isOptional) {
- return null;
- }
- throw new StateError("Element value '$key' not found in $_map.");
- }
- return _deserializer.deserializeElement(id);
- }
-
- /// Returns the list of [Element] values associated with [key] in the decoded
- /// object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// and empty [List] is returned, otherwise an exception is thrown.
- List<Element> getElements(K key, {bool isOptional: false}) {
- List<int> list = _map[_getKeyValue(key)];
- if (list == null) {
- if (isOptional) {
- return const [];
- }
- throw new StateError("Elements value '$key' not found in $_map.");
- }
- return list.map(_deserializer.deserializeElement).toList();
- }
-
- /// Returns the [ConstantExpression] value associated with [key] in the
- /// decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// `null` is returned, otherwise an exception is thrown.
- ConstantExpression getConstant(K key, {bool isOptional: false}) {
- int id = _map[_getKeyValue(key)];
- if (id == null) {
- if (isOptional) {
- return null;
- }
- throw new StateError("Constant value '$key' not found in $_map.");
- }
- return _deserializer.deserializeConstant(id);
- }
-
- /// Returns the list of [ConstantExpression] values associated with [key] in
- /// the decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// and empty [List] is returned, otherwise an exception is thrown.
- List<ConstantExpression> getConstants(K key, {bool isOptional: false}) {
- List<int> list = _map[_getKeyValue(key)];
- if (list == null) {
- if (isOptional) {
- return const [];
- }
- throw new StateError("Constants value '$key' not found in $_map.");
- }
- return list.map(_deserializer.deserializeConstant).toList();
- }
-
- /// Returns the [ResolutionDartType] value associated with [key] in the
- /// decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// `null` is returned, otherwise an exception is thrown.
- ResolutionDartType getType(K key, {bool isOptional: false}) {
- int id = _map[_getKeyValue(key)];
- if (id == null) {
- if (isOptional) {
- return null;
- }
- throw new StateError("Type value '$key' not found in $_map.");
- }
- return _deserializer.deserializeType(id);
- }
-
- /// Returns the list of [ResolutionDartType] values associated with [key] in
- /// the decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// and empty [List] is returned, otherwise an exception is thrown.
- List<ResolutionDartType> getTypes(K key, {bool isOptional: false}) {
- List<int> list = _map[_getKeyValue(key)];
- if (list == null) {
- if (isOptional) {
- return const [];
- }
- throw new StateError("Types value '$key' not found in $_map.");
- }
- return list.map(_deserializer.deserializeType).toList();
- }
-
- /// Returns the [Uri] value associated with [key] in the decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// [defaultValue] is returned, otherwise an exception is thrown.
- Uri getUri(K key, {bool isOptional: false, Uri defaultValue}) {
- String value = _map[_getKeyValue(key)];
- if (value == null) {
- if (isOptional || defaultValue != null) {
- return defaultValue;
- }
- throw new StateError("Uri value '$key' not found in $_map.");
- }
- return Uri.parse(value);
- }
-
- /// Returns the [String] value associated with [key] in the decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// [defaultValue] is returned, otherwise an exception is thrown.
- String getString(K key, {bool isOptional: false, String defaultValue}) {
- String value = _map[_getKeyValue(key)];
- if (value == null) {
- if (isOptional || defaultValue != null) {
- return defaultValue;
- }
- throw new StateError("String value '$key' not found in $_map.");
- }
- return canonicalNames[value] ?? value;
- }
-
- /// Returns the list of [String] values associated with [key] in the decoded
- /// object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// and empty [List] is returned, otherwise an exception is thrown.
- List<String> getStrings(K key, {bool isOptional: false}) {
- List list = _map[_getKeyValue(key)];
- if (list == null) {
- if (isOptional) {
- return const [];
- }
- throw new StateError("Strings value '$key' not found in $_map.");
- }
- return list;
- }
-
- /// Returns the [bool] value associated with [key] in the decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// [defaultValue] is returned, otherwise an exception is thrown.
- bool getBool(K key, {bool isOptional: false, bool defaultValue}) {
- bool value = _map[_getKeyValue(key)];
- if (value == null) {
- if (isOptional || defaultValue != null) {
- return defaultValue;
- }
- throw new StateError("bool value '$key' not found in $_map.");
- }
- return value;
- }
-
- /// Returns the [int] value associated with [key] in the decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// [defaultValue] is returned, otherwise an exception is thrown.
- int getInt(K key, {bool isOptional: false, int defaultValue}) {
- int value = _map[_getKeyValue(key)];
- if (value == null) {
- if (isOptional || defaultValue != null) {
- return defaultValue;
- }
- throw new StateError("int value '$key' not found in $_map.");
- }
- return value;
- }
-
- /// Returns the list of [int] values associated with [key] in the decoded
- /// object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// and empty [List] is returned, otherwise an exception is thrown.
- List<int> getInts(K key, {bool isOptional: false}) {
- List list = _map[_getKeyValue(key)];
- if (list == null) {
- if (isOptional) {
- return const [];
- }
- throw new StateError("Ints value '$key' not found in $_map.");
- }
- return list;
- }
-
- /// Returns the [double] value associated with [key] in the decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// [defaultValue] is returned, otherwise an exception is thrown.
- double getDouble(K key, {bool isOptional: false, double defaultValue}) {
- var value = _map[_getKeyValue(key)];
- if (value == null) {
- if (isOptional || defaultValue != null) {
- return defaultValue;
- }
- throw new StateError("double value '$key' not found in $_map.");
- }
- // Support alternative encoding of NaN and +/- infinity for JSON.
- if (value == 'NaN') {
- return double.NAN;
- } else if (value == '-Infinity') {
- return double.NEGATIVE_INFINITY;
- } else if (value == 'Infinity') {
- return double.INFINITY;
- }
- return value;
- }
-
- /// Returns an [ObjectDecoder] for the map value associated with [key] in the
- /// decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// `null` is returned, otherwise an exception is thrown.
- ObjectDecoder getObject(K key, {bool isOptional: false}) {
- Map map = _map[_getKeyValue(key)];
- if (map == null) {
- if (isOptional) {
- return null;
- }
- throw new StateError("Object value '$key' not found in $_map.");
- }
- return new ObjectDecoder(_deserializer, map);
- }
-
- /// Returns an [MapDecoder] for the map value associated with [key] in the
- /// decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// `null` is returned, otherwise an exception is thrown.
- MapDecoder getMap(K key, {bool isOptional: false}) {
- Map map = _map[_getKeyValue(key)];
- if (map == null) {
- if (isOptional) {
- return null;
- }
- throw new StateError("Map value '$key' not found in $_map.");
- }
- return new MapDecoder(_deserializer, map);
- }
-
- /// Returns an [ListDecoder] for the list value associated with [key] in the
- /// decoded object.
- ///
- /// If no value is associated with [key], then if [isOptional] is `true`,
- /// `null` is returned, otherwise an exception is thrown.
- ListDecoder getList(K key, {bool isOptional: false}) {
- List list = _map[_getKeyValue(key)];
- if (list == null) {
- if (isOptional) {
- return null;
- }
- throw new StateError("List value '$key' not found in $_map.");
- }
- return new ListDecoder(_deserializer, list);
- }
-}
-
-/// A nominal object containing its serialized value.
-class DataObject {
- /// The id for the object.
- final Value id;
-
- /// The serialized value of the object.
- final ObjectValue objectValue;
-
- DataObject(Value id, EnumValue kind)
- : this.id = id,
- this.objectValue =
- new ObjectValue(<Key, Value>{Key.ID: id, Key.KIND: kind});
-
- Map<Key, Value> get map => objectValue.map;
-}
-
-/// Function used to filter which element serialized.
-typedef bool ElementMatcher(Element element);
-
-bool includeAllElements(Element element) => true;
-
-/// Serializer for the transitive closure of a collection of libraries.
-///
-/// The serializer creates an [ObjectValue] model of the [Element],
-/// [ResolutionDartType] and [ConstantExpression] values in the transitive
-/// closure of the serialized libraries.
-///
-/// The model layout of the produced [objectValue] is:
-///
-/// { // Header object
-/// Key.ELEMENTS: [
-/// {...}, // [ObjectValue] of the 0th [Element].
-/// ...
-/// {...}, // [ObjectValue] of the n-th [Element].
-/// ],
-/// Key.TYPES: [
-/// {...}, // [ObjectValue] of the 0th [DartType].
-/// ...
-/// {...}, // [ObjectValue] of the n-th [DartType].
-/// ],
-/// Key.CONSTANTS: [
-/// {...}, // [ObjectValue] of the 0th [ConstantExpression].
-/// ...
-/// {...}, // [ObjectValue] of the n-th [ConstantExpression].
-/// ],
-/// }
-///
-// TODO(johnniwinther): Support dependencies between serialized subcomponent.
-class Serializer {
- List<SerializerPlugin> plugins = <SerializerPlugin>[];
-
- Map<Element, DataObject> _elementMap = <Element, DataObject>{};
- Map<ConstantExpression, DataObject> _constantMap =
- <ConstantExpression, DataObject>{};
- Map<ResolutionDartType, DataObject> _typeMap =
- <ResolutionDartType, DataObject>{};
- List _pendingList = [];
- ElementMatcher shouldInclude;
-
- // TODO(johnniwinther): Replace [includeElement] with a general strategy.
- Serializer({this.shouldInclude: includeAllElements});
-
- /// Add the transitive closure of [library] to this serializer.
- void serialize(LibraryElement library) {
- // Call [_getElementId] for its side-effect: To create a
- // [DataObject] for [library]. If not already created, this will
- // put the serialization of [library] in the work queue.
- _getElementId(library);
- }
-
- void _emptyWorklist() {
- while (_pendingList.isNotEmpty) {
- _pendingList.removeLast()();
- }
- }
-
- /// Returns the id [Value] for [element].
- ///
- /// If [element] has no [DataObject], a new [DataObject] is created and
- /// encoding the [ObjectValue] for [element] is put into the work queue of
- /// this serializer.
- Value _getElementId(Element element) {
- if (element == null) {
- throw new ArgumentError('Serializer._getElementDataObject(null)');
- }
- element = element.declaration;
- DataObject dataObject = _elementMap[element];
- if (dataObject == null) {
- if (!shouldInclude(element)) {
- /// Helper used to check that external references are serialized by
- /// the right kind.
- bool verifyElement(var found, var expected) {
- if (found == null) return false;
- found = found.declaration;
- if (found == expected) return true;
- if (found.isAbstractField && expected.isGetter) {
- return found.getter == expected;
- }
- if (found.isAbstractField && expected.isSetter) {
- return found.setter == expected;
- }
- return false;
- }
-
- if (element.isLibrary) {
- LibraryElement library = element;
- _elementMap[element] = dataObject = new DataObject(
- new IntValue(_elementMap.length),
- new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY));
- ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
- encoder.setUri(Key.URI, library.canonicalUri, library.canonicalUri);
- } else if (element.isConstructor) {
- assert(
- verifyElement(
- element.enclosingClass.implementation
- .lookupConstructor(element.name),
- element),
- failedAt(
- element,
- "Element $element is not found as a "
- "constructor of ${element.enclosingClass.implementation}."));
- Value classId = _getElementId(element.enclosingClass);
- _elementMap[element] = dataObject = new DataObject(
- new IntValue(_elementMap.length),
- new EnumValue(SerializedElementKind.EXTERNAL_CONSTRUCTOR));
- ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
- encoder.setValue(Key.CLASS, classId);
- encoder.setString(Key.NAME, element.name);
- } else if (element.isClassMember) {
- assert(
- verifyElement(
- element.enclosingClass.lookupLocalMember(element.name),
- element),
- failedAt(
- element,
- "Element $element is not found as a "
- "class member of ${element.enclosingClass}."));
- Value classId = _getElementId(element.enclosingClass);
- _elementMap[element] = dataObject = new DataObject(
- new IntValue(_elementMap.length),
- new EnumValue(SerializedElementKind.EXTERNAL_CLASS_MEMBER));
- ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
- encoder.setValue(Key.CLASS, classId);
- encoder.setString(Key.NAME, element.name);
- if (element.isAccessor) {
- encoder.setBool(Key.GETTER, element.isGetter);
- }
- } else {
- assert(
- verifyElement(
- element.library.implementation.find(element.name), element),
- failedAt(
- element,
- "Element $element is not found as a "
- "library member of ${element.library.implementation}."));
- Value libraryId = _getElementId(element.library);
- _elementMap[element] = dataObject = new DataObject(
- new IntValue(_elementMap.length),
- new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY_MEMBER));
- ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
- encoder.setValue(Key.LIBRARY, libraryId);
- encoder.setString(Key.NAME, element.name);
- if (element.isAccessor) {
- encoder.setBool(Key.GETTER, element.isGetter);
- }
- }
- } else {
- // Run through [ELEMENT_SERIALIZERS] sequentially to find the one that
- // deals with [element].
- for (ElementSerializer serializer in ELEMENT_SERIALIZERS) {
- SerializedElementKind kind = serializer.getSerializedKind(element);
- if (kind != null) {
- _elementMap[element] = dataObject = new DataObject(
- new IntValue(_elementMap.length), new EnumValue(kind));
- // Delay the serialization of the element itself to avoid loops, and
- // to keep the call stack small.
- _pendingList.add(() {
- ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
- serializer.serialize(element, encoder, kind);
-
- MapEncoder pluginData;
- for (SerializerPlugin plugin in plugins) {
- plugin.onElement(element, (String tag) {
- if (pluginData == null) {
- pluginData = encoder.createMap(Key.DATA);
- }
- return pluginData.createObject(tag);
- });
- }
- });
- }
- }
- }
- }
- if (dataObject == null) {
- throw new UnsupportedError(
- 'Unsupported element: $element (${element.kind})');
- }
- return dataObject.id;
- }
-
- /// Creates the [ElementValue] for [element].
- ///
- /// If [element] has not already been serialized, it is added to the work
- /// queue of this serializer.
- ElementValue createElementValue(Element element) {
- return new ElementValue(element, _getElementId(element));
- }
-
- /// Returns the id [Value] for [constant].
- ///
- /// If [constant] has no [DataObject], a new [DataObject] is created and
- /// encoding the [ObjectValue] for [constant] is put into the work queue of
- /// this serializer.
- Value _getConstantId(ConstantExpression constant) {
- return _constantMap.putIfAbsent(constant, () {
- DataObject dataObject = new DataObject(
- new IntValue(_constantMap.length), new EnumValue(constant.kind));
- // Delay the serialization of the constant itself to avoid loops, and to
- // keep the call stack small.
- _pendingList.add(() => _encodeConstant(constant, dataObject));
- return dataObject;
- }).id;
- }
-
- /// Encodes [constant] into the [ObjectValue] of [dataObject].
- void _encodeConstant(ConstantExpression constant, DataObject dataObject) {
- const ConstantSerializer()
- .visit(constant, new ObjectEncoder(this, dataObject.map));
- }
-
- /// Creates the [ConstantValue] for [constant].
- ///
- /// If [constant] has not already been serialized, it is added to the work
- /// queue of this serializer.
- ConstantValue createConstantValue(ConstantExpression constant) {
- return new ConstantValue(constant, _getConstantId(constant));
- }
-
- /// Returns the id [Value] for [type].
- ///
- /// If [type] has no [DataObject], a new [DataObject] is created and
- /// encoding the [ObjectValue] for [type] is put into the work queue of this
- /// serializer.
- Value _getTypeId(ResolutionDartType type) {
- DataObject dataObject = _typeMap[type];
- if (dataObject == null) {
- _typeMap[type] = dataObject = new DataObject(
- new IntValue(_typeMap.length), new EnumValue(type.kind));
- // Delay the serialization of the type itself to avoid loops, and to keep
- // the call stack small.
- _pendingList.add(() => _encodeType(type, dataObject));
- }
- return dataObject.id;
- }
-
- /// Encodes [type] into the [ObjectValue] of [dataObject].
- void _encodeType(ResolutionDartType type, DataObject dataObject) {
- const TypeSerializer().visit(type, new ObjectEncoder(this, dataObject.map));
- }
-
- /// Creates the [TypeValue] for [type].
- ///
- /// If [type] has not already been serialized, it is added to the work
- /// queue of this serializer.
- TypeValue createTypeValue(ResolutionDartType type) {
- return new TypeValue(type, _getTypeId(type));
- }
-
- ObjectValue get objectValue {
- _emptyWorklist();
-
- Map<Key, Value> map = <Key, Value>{};
- map[Key.ELEMENTS] =
- new ListValue(_elementMap.values.map((l) => l.objectValue).toList());
- if (_typeMap.isNotEmpty) {
- map[Key.TYPES] =
- new ListValue(_typeMap.values.map((l) => l.objectValue).toList());
- }
- if (_constantMap.isNotEmpty) {
- map[Key.CONSTANTS] =
- new ListValue(_constantMap.values.map((l) => l.objectValue).toList());
- }
- return new ObjectValue(map);
- }
-
- String toText(SerializationEncoder encoder) {
- return encoder.encode(objectValue);
- }
-
- String prettyPrint() {
- PrettyPrintEncoder encoder = new PrettyPrintEncoder();
- return encoder.toText(objectValue);
- }
-}
-
-/// Plugin for serializing additional data for an [Element].
-class SerializerPlugin {
- const SerializerPlugin();
-
- /// Called upon the serialization of [element].
- ///
- /// Use [creatorEncoder] to create a data object with id [tag] for storing
- /// additional data for [element].
- void onElement(Element element, ObjectEncoder createEncoder(String tag)) {}
-
- /// Called to serialize custom [data].
- void onData(var data, ObjectEncoder encoder) {}
-}
-
-/// Plugin for deserializing additional data for an [Element].
-class DeserializerPlugin {
- const DeserializerPlugin();
-
- /// Called upon the deserialization of [element].
- ///
- /// Use [getDecoder] to retrieve the data object with id [tag] stored for
- /// [element]. If not object is stored for [tag], [getDecoder] returns `null`.
- void onElement(Element element, ObjectDecoder getDecoder(String tag)) {}
-
- /// Called to deserialize custom data from [decoder].
- dynamic onData(ObjectDecoder decoder) => null;
-}
-
-/// Context for parallel deserialization.
-class DeserializationContext {
- final DiagnosticReporter reporter;
- final Resolution resolution;
- final LibraryProvider libraryProvider;
- Map<Uri, LibraryElement> _uriMap = <Uri, LibraryElement>{};
- List<Deserializer> deserializers = <Deserializer>[];
- List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
-
- DeserializationContext(this.reporter, this.resolution, this.libraryProvider);
-
- LibraryElement lookupLibrary(Uri uri) {
- // TODO(johnniwinther): Move this to the library loader by making a
- // [Deserializer] a [LibraryProvider].
- return _uriMap.putIfAbsent(uri, () {
- Uri foundUri;
- LibraryElement foundLibrary;
- for (Deserializer deserializer in deserializers) {
- LibraryElement library = deserializer.lookupLibrary(uri);
- if (library != null) {
- if (foundLibrary != null) {
- reporter.reportErrorMessage(NO_LOCATION_SPANNABLE,
- MessageKind.DUPLICATE_SERIALIZED_LIBRARY, {
- 'libraryUri': uri,
- 'sourceUri1': foundUri,
- 'sourceUri2': deserializer.sourceUri
- });
- }
- foundUri = deserializer.sourceUri;
- foundLibrary = library;
- }
- }
- return foundLibrary;
- });
- }
-
- LibraryElement findLibrary(Uri uri) {
- LibraryElement library = lookupLibrary(uri);
- return library ?? libraryProvider.lookupLibrary(uri);
- }
-}
-
-/// Deserializer for a closed collection of libraries.
-// TODO(johnniwinther): Support per-library deserialization and dependencies
-// between deserialized subcomponent.
-class Deserializer {
- final DeserializationContext context;
- final SerializationDecoder decoder;
- final Uri sourceUri;
- ObjectDecoder _headerObject;
- ListDecoder _elementList;
- ListDecoder _typeList;
- ListDecoder _constantList;
- Map<int, Element> _elementMap = {};
- Map<int, ResolutionDartType> _typeMap = {};
- Map<int, ConstantExpression> _constantMap = {};
-
- Deserializer.fromText(
- this.context, this.sourceUri, String text, this.decoder) {
- _headerObject = new ObjectDecoder(this, decoder.decode(text));
- }
-
- /// Returns the [ListDecoder] for the [Element]s in this deserializer.
- ListDecoder get elements {
- if (_elementList == null) {
- _elementList = _headerObject.getList(Key.ELEMENTS);
- }
- return _elementList;
- }
-
- /// Returns the [ListDecoder] for the [ResolutionDartType]s in this
- /// deserializer.
- ListDecoder get types {
- if (_typeList == null) {
- _typeList = _headerObject.getList(Key.TYPES);
- }
- return _typeList;
- }
-
- /// Returns the [ListDecoder] for the [ConstantExpression]s in this
- /// deserializer.
- ListDecoder get constants {
- if (_constantList == null) {
- _constantList = _headerObject.getList(Key.CONSTANTS);
- }
- return _constantList;
- }
-
- /// Returns the [LibraryElement] for [uri] if part of the deserializer.
- LibraryElement lookupLibrary(Uri uri) {
- // TODO(johnniwinther): Libraries should be stored explicitly in the header.
- ListDecoder list = elements;
- for (int i = 0; i < list.length; i++) {
- ObjectDecoder object = list.getObject(i);
- SerializedElementKind kind =
- object.getEnum(Key.KIND, SerializedElementKind.values);
- if (kind == SerializedElementKind.LIBRARY) {
- Uri libraryUri = object.getUri(Key.CANONICAL_URI);
- if (libraryUri == uri) {
- return deserializeElement(object.getInt(Key.ID));
- }
- }
- }
- return null;
- }
-
- /// Returns the deserialized [Element] for [id].
- Element deserializeElement(int id) {
- if (id == null) throw new ArgumentError('Deserializer.getElement(null)');
- Element element = _elementMap[id];
- if (element == null) {
- ObjectDecoder decoder = elements.getObject(id);
- SerializedElementKind elementKind =
- decoder.getEnum(Key.KIND, SerializedElementKind.values);
- if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY) {
- Uri uri = decoder.getUri(Key.URI);
- element = context.findLibrary(uri);
- if (element == null) {
- throw new StateError("Missing library for $uri.");
- }
- } else if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY_MEMBER) {
- LibraryElement library = decoder.getElement(Key.LIBRARY);
- String name = decoder.getString(Key.NAME);
- bool isGetter = decoder.getBool(Key.GETTER, isOptional: true);
- element = library.find(name);
- if (element == null) {
- throw new StateError("Missing library member for $name in $library.");
- }
- if (isGetter != null) {
- AbstractFieldElement abstractField = element;
- element = isGetter ? abstractField.getter : abstractField.setter;
- if (element == null) {
- throw new StateError(
- "Missing ${isGetter ? 'getter' : 'setter'} for "
- "$name in $library.");
- }
- }
- } else if (elementKind == SerializedElementKind.EXTERNAL_CLASS_MEMBER) {
- ClassElement cls = decoder.getElement(Key.CLASS);
- cls.ensureResolved(context.resolution);
- String name = decoder.getString(Key.NAME);
- bool isGetter = decoder.getBool(Key.GETTER, isOptional: true);
- element = cls.lookupLocalMember(name);
- if (element == null) {
- throw new StateError("Missing class member for $name in $cls.");
- }
- if (isGetter != null) {
- AbstractFieldElement abstractField = element;
- element = isGetter ? abstractField.getter : abstractField.setter;
- if (element == null) {
- throw new StateError(
- "Missing ${isGetter ? 'getter' : 'setter'} for $name in $cls.");
- }
- }
- } else if (elementKind == SerializedElementKind.EXTERNAL_CONSTRUCTOR) {
- ClassElement cls = decoder.getElement(Key.CLASS);
- cls.ensureResolved(context.resolution);
- String name = decoder.getString(Key.NAME);
- element = cls.lookupConstructor(name);
- if (element == null) {
- throw new StateError("Missing constructor for $name in $cls.");
- }
- } else {
- element = ElementDeserializer.deserialize(decoder, elementKind);
- }
- _elementMap[id] = element;
-
- MapDecoder pluginData = decoder.getMap(Key.DATA, isOptional: true);
- // Call plugins even when there is no data, so they can take action in
- // this case.
- for (DeserializerPlugin plugin in context.plugins) {
- plugin.onElement(element,
- (String tag) => pluginData?.getObject(tag, isOptional: true));
- }
- }
- return element;
- }
-
- /// Returns the deserialized [ResolutionDartType] for [id].
- ResolutionDartType deserializeType(int id) {
- if (id == null) throw new ArgumentError('Deserializer.getType(null)');
- return _typeMap.putIfAbsent(id, () {
- return TypeDeserializer.deserialize(types.getObject(id));
- });
- }
-
- /// Returns the deserialized [ConstantExpression] for [id].
- ConstantExpression deserializeConstant(int id) {
- if (id == null) throw new ArgumentError('Deserializer.getConstant(null)');
- return _constantMap.putIfAbsent(id, () {
- return ConstantDeserializer.deserialize(constants.getObject(id));
- });
- }
-}
-
-/// Strategy used by [Serializer] to define the memory and output encoding.
-abstract class SerializationEncoder {
- /// Encode [objectValue] into text.
- String encode(ObjectValue objectValue);
-}
-
-/// Strategy used by [Deserializer] for decoding and reading data from a
-/// serialized output.
-abstract class SerializationDecoder {
- /// Decode [text] into [Map] containing the data corresponding to an encoding
- /// of the serializer header object.
- Map decode(String text);
-
- /// Returns the value used to store [key] as a property in the encoding an
- /// [ObjectValue].
- ///
- /// Different encodings have different restrictions and capabilities as how
- /// to store a [Key] value. For instance: A JSON encoding needs to convert
- /// [Key] to a [String] to store it in a JSON object; a Dart encoding can
- /// choose to store a [Key] as an [int] or as the [Key] itself.
- getObjectPropertyValue(Key key);
-}
diff --git a/pkg/compiler/lib/src/serialization/serialization_util.dart b/pkg/compiler/lib/src/serialization/serialization_util.dart
deleted file mode 100644
index 16e1e4e..0000000
--- a/pkg/compiler/lib/src/serialization/serialization_util.dart
+++ /dev/null
@@ -1,613 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.util;
-
-import '../common.dart';
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../diagnostics/messages.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart' show WrappedMessage;
-import '../elements/names.dart';
-import '../elements/operators.dart';
-import '../resolution/access_semantics.dart';
-import '../resolution/send_structure.dart';
-import '../universe/call_structure.dart';
-import '../universe/selector.dart';
-import 'keys.dart';
-import 'serialization.dart';
-
-/// Serialize [name] into [encoder].
-void serializeName(Name name, ObjectEncoder encoder) {
- encoder.setString(Key.NAME, name.text);
- encoder.setBool(Key.IS_SETTER, name.isSetter);
- if (name.library != null) {
- LibraryElement library = name.library;
- encoder.setElement(Key.LIBRARY, library);
- }
-}
-
-/// Deserialize a [Name] from [decoder].
-Name deserializeName(ObjectDecoder decoder) {
- String name = decoder.getString(Key.NAME);
- bool isSetter = decoder.getBool(Key.IS_SETTER);
- LibraryElement library = decoder.getElement(Key.LIBRARY, isOptional: true);
- return new Name(name, library, isSetter: isSetter);
-}
-
-/// Serialize [callStructure] into [encoder].
-void serializeCallStructure(
- CallStructure callStructure, ObjectEncoder encoder) {
- encoder.setInt(Key.ARGUMENTS, callStructure.argumentCount);
- encoder.setStrings(Key.NAMED_ARGUMENTS, callStructure.namedArguments);
-}
-
-/// Serialize [selector] into [encoder].
-void serializeSelector(Selector selector, ObjectEncoder encoder) {
- encoder.setEnum(Key.KIND, selector.kind);
- serializeCallStructure(selector.callStructure, encoder);
- serializeName(selector.memberName, encoder);
-}
-
-/// Deserialize a [CallStructure] from [decoder].
-CallStructure deserializeCallStructure(ObjectDecoder decoder) {
- int argumentCount = decoder.getInt(Key.ARGUMENTS);
- List<String> namedArguments =
- decoder.getStrings(Key.NAMED_ARGUMENTS, isOptional: true);
- return new CallStructure(argumentCount, namedArguments);
-}
-
-/// Deserialize a [Selector] from [decoder].
-Selector deserializeSelector(ObjectDecoder decoder) {
- SelectorKind kind = decoder.getEnum(Key.KIND, SelectorKind.values);
- CallStructure callStructure = deserializeCallStructure(decoder);
- return new Selector(kind, deserializeName(decoder), callStructure);
-}
-
-/// Serialize [sendStructure] into [encoder].
-void serializeSendStructure(
- SendStructure sendStructure, ObjectEncoder encoder) {
- encoder.setEnum(Key.KIND, sendStructure.kind);
- switch (sendStructure.kind) {
- case SendStructureKind.IF_NULL:
- case SendStructureKind.LOGICAL_AND:
- case SendStructureKind.LOGICAL_OR:
- case SendStructureKind.NOT:
- case SendStructureKind.INVALID_UNARY:
- case SendStructureKind.INVALID_BINARY:
- // No additional properties.
- break;
- case SendStructureKind.IS:
- IsStructure structure = sendStructure;
- encoder.setType(Key.TYPE, structure.type);
- break;
- case SendStructureKind.IS_NOT:
- IsNotStructure structure = sendStructure;
- encoder.setType(Key.TYPE, structure.type);
- break;
- case SendStructureKind.AS:
- AsStructure structure = sendStructure;
- encoder.setType(Key.TYPE, structure.type);
- break;
- case SendStructureKind.INVOKE:
- InvokeStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- serializeSelector(structure.selector, encoder.createObject(Key.SELECTOR));
- break;
- case SendStructureKind.INCOMPATIBLE_INVOKE:
- IncompatibleInvokeStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- serializeSelector(structure.selector, encoder.createObject(Key.SELECTOR));
- break;
- case SendStructureKind.GET:
- GetStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- break;
- case SendStructureKind.SET:
- SetStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- break;
- case SendStructureKind.UNARY:
- UnaryStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- encoder.setEnum(Key.OPERATOR, structure.operator.kind);
- break;
- case SendStructureKind.INDEX:
- IndexStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- break;
- case SendStructureKind.EQUALS:
- EqualsStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- break;
- case SendStructureKind.NOT_EQUALS:
- NotEqualsStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- break;
- case SendStructureKind.BINARY:
- BinaryStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- encoder.setEnum(Key.OPERATOR, structure.operator.kind);
- break;
- case SendStructureKind.INDEX_SET:
- IndexSetStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- break;
- case SendStructureKind.INDEX_PREFIX:
- IndexPrefixStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- encoder.setEnum(Key.OPERATOR, structure.operator.kind);
- break;
- case SendStructureKind.INDEX_POSTFIX:
- IndexPostfixStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- encoder.setEnum(Key.OPERATOR, structure.operator.kind);
- break;
- case SendStructureKind.COMPOUND:
- CompoundStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- encoder.setEnum(Key.OPERATOR, structure.operator.kind);
- break;
- case SendStructureKind.SET_IF_NULL:
- SetIfNullStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- break;
- case SendStructureKind.COMPOUND_INDEX_SET:
- CompoundIndexSetStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- encoder.setEnum(Key.OPERATOR, structure.operator.kind);
- break;
- case SendStructureKind.INDEX_SET_IF_NULL:
- IndexSetIfNullStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- break;
- case SendStructureKind.PREFIX:
- PrefixStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- encoder.setEnum(Key.OPERATOR, structure.operator.kind);
- break;
- case SendStructureKind.POSTFIX:
- PostfixStructure structure = sendStructure;
- serializeAccessSemantics(
- structure.semantics, encoder.createObject(Key.SEMANTICS));
- encoder.setEnum(Key.OPERATOR, structure.operator.kind);
- break;
- case SendStructureKind.DEFERRED_PREFIX:
- DeferredPrefixStructure structure = sendStructure;
- encoder.setElement(Key.PREFIX, structure.prefix);
- serializeSendStructure(
- structure.sendStructure, encoder.createObject(Key.SEND_STRUCTURE));
- break;
- }
-}
-
-/// Deserialize a [SendStructure] from [decoder].
-// ignore: MISSING_RETURN
-SendStructure deserializeSendStructure(ObjectDecoder decoder) {
- SendStructureKind kind = decoder.getEnum(Key.KIND, SendStructureKind.values);
- switch (kind) {
- case SendStructureKind.IF_NULL:
- return const IfNullStructure();
- case SendStructureKind.LOGICAL_AND:
- return const LogicalAndStructure();
- case SendStructureKind.LOGICAL_OR:
- return const LogicalOrStructure();
- case SendStructureKind.IS:
- return new IsStructure(decoder.getType(Key.TYPE));
- case SendStructureKind.IS_NOT:
- return new IsNotStructure(decoder.getType(Key.TYPE));
- case SendStructureKind.AS:
- return new AsStructure(decoder.getType(Key.TYPE));
- case SendStructureKind.INVOKE:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- Selector selector = deserializeSelector(decoder.getObject(Key.SELECTOR));
- return new InvokeStructure(semantics, selector);
- case SendStructureKind.INCOMPATIBLE_INVOKE:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- Selector selector = deserializeSelector(decoder.getObject(Key.SELECTOR));
- return new IncompatibleInvokeStructure(semantics, selector);
- case SendStructureKind.GET:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new GetStructure(semantics);
- case SendStructureKind.SET:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new SetStructure(semantics);
- case SendStructureKind.NOT:
- return const NotStructure();
- case SendStructureKind.UNARY:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new UnaryStructure(
- semantics,
- UnaryOperator.fromKind(
- decoder.getEnum(Key.OPERATOR, UnaryOperatorKind.values)));
- case SendStructureKind.INVALID_UNARY:
- return new InvalidUnaryStructure();
- case SendStructureKind.INDEX:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new IndexStructure(semantics);
- case SendStructureKind.EQUALS:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new EqualsStructure(semantics);
- case SendStructureKind.NOT_EQUALS:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new NotEqualsStructure(semantics);
- case SendStructureKind.BINARY:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new BinaryStructure(
- semantics,
- BinaryOperator.fromKind(
- decoder.getEnum(Key.OPERATOR, BinaryOperatorKind.values)));
- case SendStructureKind.INVALID_BINARY:
- return const InvalidBinaryStructure();
- case SendStructureKind.INDEX_SET:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new IndexSetStructure(semantics);
- case SendStructureKind.INDEX_PREFIX:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new IndexPrefixStructure(
- semantics,
- IncDecOperator.fromKind(
- decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
- case SendStructureKind.INDEX_POSTFIX:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new IndexPostfixStructure(
- semantics,
- IncDecOperator.fromKind(
- decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
- case SendStructureKind.COMPOUND:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new CompoundStructure(
- semantics,
- AssignmentOperator.fromKind(
- decoder.getEnum(Key.OPERATOR, AssignmentOperatorKind.values)));
- case SendStructureKind.SET_IF_NULL:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new SetIfNullStructure(semantics);
- case SendStructureKind.COMPOUND_INDEX_SET:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new CompoundIndexSetStructure(
- semantics,
- AssignmentOperator.fromKind(
- decoder.getEnum(Key.OPERATOR, AssignmentOperatorKind.values)));
- case SendStructureKind.INDEX_SET_IF_NULL:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new IndexSetIfNullStructure(semantics);
- case SendStructureKind.PREFIX:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new PrefixStructure(
- semantics,
- IncDecOperator.fromKind(
- decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
- case SendStructureKind.POSTFIX:
- AccessSemantics semantics =
- deserializeAccessSemantics(decoder.getObject(Key.SEMANTICS));
- return new PostfixStructure(
- semantics,
- IncDecOperator.fromKind(
- decoder.getEnum(Key.OPERATOR, IncDecOperatorKind.values)));
- case SendStructureKind.DEFERRED_PREFIX:
- PrefixElement prefix = decoder.getElement(Key.PREFIX);
- SendStructure sendStructure =
- deserializeSendStructure(decoder.getObject(Key.SEND_STRUCTURE));
- return new DeferredPrefixStructure(prefix, sendStructure);
- }
-}
-
-/// Serialize [newStructure] into [encoder].
-void serializeNewStructure(NewStructure newStructure, ObjectEncoder encoder) {
- encoder.setEnum(Key.KIND, newStructure.kind);
- switch (newStructure.kind) {
- case NewStructureKind.NEW_INVOKE:
- NewInvokeStructure structure = newStructure;
- encoder.setEnum(Key.SUB_KIND, structure.semantics.kind);
- encoder.setElement(Key.ELEMENT, structure.semantics.element);
- encoder.setType(Key.TYPE, structure.semantics.type);
- serializeSelector(structure.selector, encoder.createObject(Key.SELECTOR));
- break;
- case NewStructureKind.CONST_INVOKE:
- ConstInvokeStructure structure = newStructure;
- encoder.setEnum(Key.SUB_KIND, structure.constantInvokeKind);
- encoder.setConstant(Key.CONSTANT, structure.constant);
- break;
- case NewStructureKind.LATE_CONST:
- throw new UnsupportedError(
- 'Unsupported NewStructure kind ${newStructure.kind}.');
- }
-}
-
-/// Deserialize a [NewStructure] from [decoder].
-// ignore: MISSING_RETURN
-NewStructure deserializeNewStructure(ObjectDecoder decoder) {
- NewStructureKind kind = decoder.getEnum(Key.KIND, NewStructureKind.values);
- switch (kind) {
- case NewStructureKind.NEW_INVOKE:
- ConstructorAccessKind constructorAccessKind =
- decoder.getEnum(Key.SUB_KIND, ConstructorAccessKind.values);
- Element element = decoder.getElement(Key.ELEMENT);
- ResolutionDartType type = decoder.getType(Key.TYPE);
- ConstructorAccessSemantics semantics =
- new ConstructorAccessSemantics(constructorAccessKind, element, type);
- Selector selector = deserializeSelector(decoder.getObject(Key.SELECTOR));
- return new NewInvokeStructure(semantics, selector);
-
- case NewStructureKind.CONST_INVOKE:
- ConstantInvokeKind constantInvokeKind =
- decoder.getEnum(Key.SUB_KIND, ConstantInvokeKind.values);
- ConstantExpression constant = decoder.getConstant(Key.CONSTANT);
- return new ConstInvokeStructure(constantInvokeKind, constant);
- case NewStructureKind.LATE_CONST:
- throw new UnsupportedError('Unsupported NewStructure kind $kind.');
- }
-}
-
-/// Serialize [semantics] into [encoder].
-void serializeAccessSemantics(
- AccessSemantics semantics, ObjectEncoder encoder) {
- encoder.setEnum(Key.KIND, semantics.kind);
- switch (semantics.kind) {
- case AccessKind.EXPRESSION:
- case AccessKind.THIS:
- // No additional properties.
- break;
- case AccessKind.THIS_PROPERTY:
- case AccessKind.DYNAMIC_PROPERTY:
- case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
- serializeName(semantics.name, encoder);
- break;
- case AccessKind.CLASS_TYPE_LITERAL:
- case AccessKind.TYPEDEF_TYPE_LITERAL:
- case AccessKind.DYNAMIC_TYPE_LITERAL:
- encoder.setConstant(Key.CONSTANT, semantics.constant);
- break;
- case AccessKind.LOCAL_FUNCTION:
- case AccessKind.LOCAL_VARIABLE:
- case AccessKind.FINAL_LOCAL_VARIABLE:
- case AccessKind.PARAMETER:
- case AccessKind.FINAL_PARAMETER:
- case AccessKind.STATIC_FIELD:
- case AccessKind.FINAL_STATIC_FIELD:
- case AccessKind.STATIC_METHOD:
- case AccessKind.STATIC_GETTER:
- case AccessKind.STATIC_SETTER:
- case AccessKind.TOPLEVEL_FIELD:
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- case AccessKind.TOPLEVEL_METHOD:
- case AccessKind.TOPLEVEL_GETTER:
- case AccessKind.TOPLEVEL_SETTER:
- case AccessKind.SUPER_FIELD:
- case AccessKind.SUPER_FINAL_FIELD:
- case AccessKind.SUPER_METHOD:
- case AccessKind.SUPER_GETTER:
- case AccessKind.SUPER_SETTER:
- case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
- case AccessKind.UNRESOLVED:
- case AccessKind.UNRESOLVED_SUPER:
- case AccessKind.INVALID:
- encoder.setElement(Key.ELEMENT, semantics.element);
- break;
- case AccessKind.COMPOUND:
- CompoundAccessSemantics compoundAccess = semantics;
- encoder.setEnum(Key.SUB_KIND, compoundAccess.compoundAccessKind);
- encoder.setElement(Key.GETTER, semantics.getter);
- encoder.setElement(Key.SETTER, semantics.setter);
- break;
- case AccessKind.CONSTANT:
- throw new UnsupportedError('Unsupported access kind: ${semantics.kind}');
- }
-}
-
-/// Deserialize a [AccessSemantics] from [decoder].
-// ignore: MISSING_RETURN
-AccessSemantics deserializeAccessSemantics(ObjectDecoder decoder) {
- AccessKind kind = decoder.getEnum(Key.KIND, AccessKind.values);
- switch (kind) {
- case AccessKind.EXPRESSION:
- return const DynamicAccess.expression();
- case AccessKind.THIS:
- return const DynamicAccess.thisAccess();
- case AccessKind.THIS_PROPERTY:
- return new DynamicAccess.thisProperty(deserializeName(decoder));
- case AccessKind.DYNAMIC_PROPERTY:
- return new DynamicAccess.dynamicProperty(deserializeName(decoder));
- case AccessKind.CONDITIONAL_DYNAMIC_PROPERTY:
- return new DynamicAccess.ifNotNullProperty(deserializeName(decoder));
- case AccessKind.CLASS_TYPE_LITERAL:
- case AccessKind.TYPEDEF_TYPE_LITERAL:
- case AccessKind.DYNAMIC_TYPE_LITERAL:
- return new ConstantAccess(kind, decoder.getConstant(Key.CONSTANT));
-
- case AccessKind.LOCAL_FUNCTION:
- case AccessKind.LOCAL_VARIABLE:
- case AccessKind.FINAL_LOCAL_VARIABLE:
- case AccessKind.PARAMETER:
- case AccessKind.FINAL_PARAMETER:
- case AccessKind.STATIC_FIELD:
- case AccessKind.FINAL_STATIC_FIELD:
- case AccessKind.STATIC_METHOD:
- case AccessKind.STATIC_GETTER:
- case AccessKind.STATIC_SETTER:
- case AccessKind.TOPLEVEL_FIELD:
- case AccessKind.FINAL_TOPLEVEL_FIELD:
- case AccessKind.TOPLEVEL_METHOD:
- case AccessKind.TOPLEVEL_GETTER:
- case AccessKind.TOPLEVEL_SETTER:
- case AccessKind.SUPER_FIELD:
- case AccessKind.SUPER_FINAL_FIELD:
- case AccessKind.SUPER_METHOD:
- case AccessKind.SUPER_GETTER:
- case AccessKind.SUPER_SETTER:
- case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
- case AccessKind.UNRESOLVED:
- case AccessKind.UNRESOLVED_SUPER:
- case AccessKind.INVALID:
- return new StaticAccess.internal(kind, decoder.getElement(Key.ELEMENT));
-
- case AccessKind.COMPOUND:
- CompoundAccessKind compoundAccessKind =
- decoder.getEnum(Key.SUB_KIND, CompoundAccessKind.values);
- Element getter = decoder.getElement(Key.GETTER);
- Element setter = decoder.getElement(Key.SETTER);
- return new CompoundAccessSemantics(compoundAccessKind, getter, setter);
- case AccessKind.CONSTANT:
- throw new UnsupportedError('Unsupported access kind: $kind');
- }
-}
-
-/// Serialize a reference from [context] to an [element] which might be a member
-/// of an unnamed mixin application. If it is, [element] is by serialized
-/// indirectly by name in the [nameKey] of [encoder], otherwise [element] is
-/// serialized directly in [elementKey] in [encoder].
-void serializeElementReference(Element context, Key elementKey, Key nameKey,
- ObjectEncoder encoder, Element element) {
- if (element.isGenerativeConstructor &&
- element.enclosingClass.isUnnamedMixinApplication) {
- assert(
- element.isConstructor,
- failedAt(
- element,
- "Unexpected reference of forwarding constructor "
- "${element} from $context."));
- encoder.setString(nameKey, element.name);
- } else {
- encoder.setElement(elementKey, element);
- }
-}
-
-/// Deserialize a reference from [context] to an [Element] which might be a
-/// member of an unnamed mixin application. If it is, the [Element] is by
-/// deserialized indirectly by name from [nameKey] in [decoder], otherwise
-/// the [Element] is deserialized directly from [elementKey] in [encoder].
-Element deserializeElementReference(
- Element context, Key elementKey, Key nameKey, ObjectDecoder decoder,
- {bool isOptional: false}) {
- Element element = decoder.getElement(elementKey, isOptional: true);
- if (element == null) {
- String elementName = decoder.getString(nameKey, isOptional: isOptional);
- if (elementName == null) {
- return null;
- }
- ClassElement cls;
- if (context is ClassElement) {
- assert(
- context.isNamedMixinApplication,
- failedAt(
- NO_LOCATION_SPANNABLE,
- "Unexpected reference of forwarding constructor "
- "'${elementName}' from $context."));
- cls = context;
- } else {
- assert(
- context.isConstructor,
- failedAt(
- NO_LOCATION_SPANNABLE,
- "Unexpected reference of forwarding constructor "
- "'${elementName}' from $context."));
- cls = context.enclosingClass;
- }
- ClassElement superclass = cls.superclass;
- element = superclass.lookupConstructor(elementName);
- assert(
- element != null,
- failedAt(
- NO_LOCATION_SPANNABLE,
- "Unresolved reference of forwarding constructor "
- "'${elementName}' from $context."));
- }
- return element;
-}
-
-void serializeMessageArguments(
- ObjectEncoder encoder, Key key, Map<String, dynamic> messageArguments) {
- if (messageArguments.isNotEmpty) {
- MapEncoder mapEncoder = encoder.createMap(Key.ARGUMENTS);
- messageArguments.forEach((String key, var value) {
- mapEncoder.setString(key, Message.convertToString(value));
- });
- }
-}
-
-Map<String, String> deserializeMessageArguments(
- ObjectDecoder decoder, Key key) {
- Map<String, String> arguments = <String, String>{};
- MapDecoder mapDecoder = decoder.getMap(key, isOptional: true);
- if (mapDecoder != null) {
- mapDecoder.forEachKey((String key) {
- arguments[key] = mapDecoder.getString(key);
- });
- }
- return arguments;
-}
-
-void serializeSourceSpan(ObjectEncoder encoder, SourceSpan sourceSpan) {
- encoder.setUri(Key.URI, sourceSpan.uri, sourceSpan.uri);
- encoder.setInt(Key.OFFSET, sourceSpan.begin);
- encoder.setInt(Key.LENGTH, sourceSpan.end - sourceSpan.begin);
-}
-
-SourceSpan deserializeSourceSpan(ObjectDecoder decoder) {
- Uri uri = decoder.getUri(Key.URI);
- int offset = decoder.getInt(Key.OFFSET);
- int length = decoder.getInt(Key.LENGTH);
- return new SourceSpan(uri, offset, offset + length);
-}
-
-void serializeWrappedMessage(
- ObjectEncoder encoder, Key key, WrappedMessage message) {
- ObjectEncoder object = encoder.createObject(key);
- if (message.sourceSpan != null) {
- serializeSourceSpan(
- object.createObject(Key.SOURCE_SPAN), message.sourceSpan);
- }
- object.setEnum(Key.KIND, message.messageKind);
- serializeMessageArguments(object, Key.ARGUMENTS, message.messageArguments);
-}
-
-WrappedMessage deserializeWrappedMessage(ObjectDecoder decoder, Key key) {
- ObjectDecoder object = decoder.getObject(key);
- SourceSpan sourceSpan;
- ObjectDecoder sourceSpanDecoder =
- object.getObject(Key.SOURCE_SPAN, isOptional: true);
- if (sourceSpanDecoder != null) {
- sourceSpan = deserializeSourceSpan(sourceSpanDecoder);
- }
- MessageKind messageKind = object.getEnum(Key.KIND, MessageKind.values);
- Map<String, dynamic> messageArguments =
- deserializeMessageArguments(object, Key.ARGUMENTS);
- return new WrappedMessage(sourceSpan, messageKind, messageArguments);
-}
diff --git a/pkg/compiler/lib/src/serialization/system.dart b/pkg/compiler/lib/src/serialization/system.dart
deleted file mode 100644
index 8ae4efc..0000000
--- a/pkg/compiler/lib/src/serialization/system.dart
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_system;
-
-import 'dart:async';
-
-import '../common.dart';
-import '../common/resolution.dart';
-import '../compiler.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../script.dart';
-import '../serialization/impact_serialization.dart';
-import 'package:front_end/src/fasta/scanner.dart';
-import '../universe/call_structure.dart';
-import '../universe/use.dart';
-import '../universe/world_impact.dart';
-import 'modelz.dart';
-import 'resolved_ast_serialization.dart';
-import 'serialization.dart';
-import 'task.dart';
-
-class ResolutionDeserializerSystem extends DeserializerSystem {
- final Compiler _compiler;
- final Resolution resolution;
- final DeserializationContext deserializationContext;
- final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
-
- factory ResolutionDeserializerSystem(Compiler compiler,
- {bool deserializeCompilationDataForTesting: false}) {
- DeserializationContext context = new DeserializationContext(
- compiler.reporter, compiler.resolution, compiler.libraryLoader);
- DeserializerPlugin backendDeserializer =
- compiler.backend.serialization.deserializer;
- context.plugins.add(backendDeserializer);
- if (compiler.options.resolveOnly && !deserializeCompilationDataForTesting) {
- return new ResolutionDeserializerSystem._(
- compiler, compiler.resolution, context);
- } else {
- ResolutionImpactDeserializer resolutionImpactDeserializer =
- new ResolutionImpactDeserializer(backendDeserializer);
- context.plugins.add(resolutionImpactDeserializer);
- ResolvedAstDeserializerPlugin resolvedAstDeserializer =
- new ResolvedAstDeserializerPlugin(
- compiler.parsingContext, backendDeserializer);
- context.plugins.add(resolvedAstDeserializer);
- return new CompilationDeserializerSystem._(compiler, compiler.resolution,
- context, resolutionImpactDeserializer, resolvedAstDeserializer);
- }
- }
-
- ResolutionDeserializerSystem._(
- this._compiler, this.resolution, this.deserializationContext);
-
- @override
- Future<LibraryElement> readLibrary(Uri resolvedUri) {
- LibraryElement library = deserializationContext.lookupLibrary(resolvedUri);
- if (library != null) {
- deserializedLibraries.add(library);
- return onReadLibrary(library);
- }
- return new Future<LibraryElement>.value(library);
- }
-
- Future<LibraryElement> onReadLibrary(LibraryElement library) {
- return new Future<LibraryElement>.value(library);
- }
-
- // TODO(johnniwinther): Remove the need for this method.
- @override
- bool hasResolvedAst(ExecutableElement element) {
- return getResolvedAst(element) != null;
- }
-
- @override
- ResolvedAst getResolvedAst(ExecutableElement element) => null;
-
- @override
- bool hasResolutionImpact(Element element) => true;
-
- @override
- ResolutionImpact getResolutionImpact(Element element) {
- return const ResolutionImpact();
- }
-
- @override
- WorldImpact computeWorldImpact(Element element) {
- ResolutionImpact resolutionImpact = getResolutionImpact(element);
- assert(resolutionImpact != null,
- failedAt(element, 'No impact found for $element (${element.library})'));
- if (element is ExecutableElement) {
- getResolvedAst(element);
- }
- if (element.isField && !element.isConst) {
- FieldElement field = element;
- if (field.isTopLevel || field.isStatic) {
- if (field.constant == null) {
- // TODO(johnniwinther): Find a cleaner way to do this. Maybe
- // `Feature.LAZY_FIELD` of the resolution impact should be used
- // instead.
- _compiler.backend.constants.registerLazyStatic(field);
- }
- }
- }
- return resolution.transformResolutionImpact(element, resolutionImpact);
- }
-
- @override
- bool isDeserialized(Entity entity) {
- Element element = entity;
- return deserializedLibraries.contains(element.library);
- }
-}
-
-class CompilationDeserializerSystem extends ResolutionDeserializerSystem {
- final ResolutionImpactDeserializer _resolutionImpactDeserializer;
- final ResolvedAstDeserializerPlugin _resolvedAstDeserializer;
-
- CompilationDeserializerSystem._(
- Compiler compiler,
- Resolution resolution,
- DeserializationContext deserializationContext,
- this._resolutionImpactDeserializer,
- this._resolvedAstDeserializer)
- : super._(compiler, resolution, deserializationContext);
-
- @override
- Future<LibraryElement> onReadLibrary(LibraryElement library) {
- return Future.forEach(library.compilationUnits,
- (CompilationUnitElement compilationUnit) {
- ScriptZ script = compilationUnit.script;
- return _compiler.readScript(script.readableUri).then((Script newScript) {
- script.file = newScript.file;
- script.isSynthesized = newScript.isSynthesized;
- _resolvedAstDeserializer.scripts[script.resourceUri] = script;
- });
- }).then((_) => library);
- }
-
- @override
- ResolvedAst getResolvedAst(ExecutableElement element) {
- return _resolvedAstDeserializer.getResolvedAst(element);
- }
-
- @override
- bool hasResolutionImpact(Element element) {
- if (element.isConstructor &&
- element.enclosingClass.isUnnamedMixinApplication) {
- return true;
- }
- return _resolutionImpactDeserializer.hasResolutionImpact(element);
- }
-
- @override
- ResolutionImpact getResolutionImpact(Element element) {
- if (element.isConstructor &&
- element.enclosingClass.isUnnamedMixinApplication) {
- ConstructorElement constructor = element;
- ClassElement superclass = constructor.enclosingClass.superclass;
- ConstructorElement superclassConstructor =
- superclass.lookupConstructor(constructor.name);
- assert(
- superclassConstructor != null,
- failedAt(
- element,
- "Superclass constructor '${constructor.name}' called from "
- "${element} not found in ${superclass}."));
- // TODO(johnniwinther): Compute callStructure. Currently not used.
- CallStructure callStructure;
- return _resolutionImpactDeserializer.registerResolutionImpact(constructor,
- () {
- List<TypeUse> typeUses = <TypeUse>[];
- void addCheckedModeCheck(ResolutionDartType type) {
- if (!type.isDynamic) {
- typeUses.add(new TypeUse.checkedModeCheck(type));
- }
- }
-
- ResolutionFunctionType type = constructor.type;
- // TODO(johnniwinther): Remove this substitution when synthesized
- // constructors handle type variables correctly.
- type = type.substByContext(constructor.enclosingClass
- .asInstanceOf(constructor.enclosingClass));
- type.parameterTypes.forEach(addCheckedModeCheck);
- type.optionalParameterTypes.forEach(addCheckedModeCheck);
- type.namedParameterTypes.forEach(addCheckedModeCheck);
- return new DeserializedResolutionImpact(staticUses: <StaticUse>[
- new StaticUse.superConstructorInvoke(
- superclassConstructor, callStructure)
- ], typeUses: typeUses);
- });
- }
- return _resolutionImpactDeserializer.getResolutionImpact(element);
- }
-}
-
-const String WORLD_IMPACT_TAG = 'worldImpact';
-
-class ResolutionImpactSerializer extends SerializerPlugin {
- final Resolution resolution;
- final SerializerPlugin nativeDataSerializer;
-
- ResolutionImpactSerializer(this.resolution, this.nativeDataSerializer);
-
- @override
- void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
- if (resolution.hasBeenResolved(element)) {
- ResolutionImpact impact = resolution.getResolutionImpact(element);
- ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG);
- new ImpactSerializer(element, encoder, nativeDataSerializer)
- .serialize(impact);
- }
- }
-}
-
-class ResolutionImpactDeserializer extends DeserializerPlugin {
- Map<Element, ObjectDecoder> _decoderMap = <Element, ObjectDecoder>{};
- Map<Element, ResolutionImpact> _impactMap = <Element, ResolutionImpact>{};
- final DeserializerPlugin nativeDataDeserializer;
-
- ResolutionImpactDeserializer(this.nativeDataDeserializer);
-
- @override
- void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
- ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG);
- if (decoder != null) {
- _decoderMap[element] = decoder;
- }
- }
-
- bool hasResolutionImpact(Element element) {
- return _impactMap.containsKey(element) || _decoderMap.containsKey(element);
- }
-
- ResolutionImpact registerResolutionImpact(
- Element element, ResolutionImpact ifAbsent()) {
- return _impactMap.putIfAbsent(element, ifAbsent);
- }
-
- ResolutionImpact getResolutionImpact(Element element) {
- return registerResolutionImpact(element, () {
- ObjectDecoder decoder = _decoderMap[element];
- if (decoder != null) {
- _decoderMap.remove(element);
- return ImpactDeserializer.deserializeImpact(
- element, decoder, nativeDataDeserializer);
- }
- return null;
- });
- }
-}
-
-const String RESOLVED_AST_TAG = 'resolvedAst';
-
-class ResolvedAstSerializerPlugin extends SerializerPlugin {
- final Resolution resolution;
- final SerializerPlugin nativeDataSerializer;
-
- ResolvedAstSerializerPlugin(this.resolution, this.nativeDataSerializer);
-
- @override
- void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
- assert(element.isDeclaration,
- failedAt(element, "Element $element must be the declaration"));
- if (element.isError) return;
- if (element is MemberElement) {
- assert(resolution.hasResolvedAst(element),
- failedAt(element, "Element $element must have a resolved ast"));
- ResolvedAst resolvedAst = resolution.getResolvedAst(element);
- ObjectEncoder objectEncoder = createEncoder(RESOLVED_AST_TAG);
- new ResolvedAstSerializer(
- objectEncoder, resolvedAst, nativeDataSerializer)
- .serialize();
- }
- }
-}
-
-class ResolvedAstDeserializerPlugin extends DeserializerPlugin {
- final ParsingContext parsingContext;
- final DeserializerPlugin nativeDataDeserializer;
- final Map<Uri, Script> scripts = <Uri, Script>{};
-
- Map<MemberElement, ObjectDecoder> _decoderMap =
- <MemberElement, ObjectDecoder>{};
- Map<Uri, Token> beginTokenMap = <Uri, Token>{};
-
- ResolvedAstDeserializerPlugin(
- this.parsingContext, this.nativeDataDeserializer);
-
- bool hasResolvedAst(ExecutableElement element) {
- return getResolvedAst(element) != null;
- }
-
- ResolvedAst getResolvedAst(ExecutableElement element) {
- if (element.hasResolvedAst) {
- return element.resolvedAst;
- }
-
- ObjectDecoder decoder = _decoderMap[element.memberContext];
- if (decoder != null) {
- ResolvedAstDeserializer.deserialize(element.memberContext, decoder,
- parsingContext, findToken, nativeDataDeserializer);
- _decoderMap.remove(element);
- assert(element.hasResolvedAst,
- failedAt(element, "ResolvedAst not computed for $element."));
- return element.resolvedAst;
- }
- return null;
- }
-
- Token findToken(Uri uri, int offset) {
- Token beginToken = beginTokenMap.putIfAbsent(uri, () {
- Script script = scripts[uri];
- if (script == null) {
- parsingContext.reporter.internalError(NO_LOCATION_SPANNABLE,
- 'No source file found for $uri in:\n ${scripts.keys.join('\n ')}');
- }
- if (script.isSynthesized) return null;
- return parsingContext.scanner.scanFile(script.file);
- });
- if (beginToken == null) return null;
- return ResolvedAstDeserializer.findTokenInStream(beginToken, offset);
- }
-
- @override
- void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
- ObjectDecoder decoder = getDecoder(RESOLVED_AST_TAG);
- if (decoder != null) {
- _decoderMap[element] = decoder;
- }
- }
-}
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
deleted file mode 100644
index d052e4e..0000000
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.task;
-
-import 'dart:async' show Future;
-
-import '../../compiler_new.dart';
-import '../common/resolution.dart' show ResolutionImpact, ResolutionWorkItem;
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart' show Compiler;
-import '../elements/elements.dart';
-import '../elements/entities.dart' show Entity;
-import '../universe/world_impact.dart' show WorldImpact;
-import 'json_serializer.dart';
-import 'serialization.dart';
-import 'system.dart';
-
-/// A deserializer that can load a library element by reading it's information
-/// from a serialized form.
-abstract class LibraryDeserializer {
- /// Loads the [LibraryElement] associated with a library under [uri], or null
- /// if no serialized information is available for the given library.
- Future<LibraryElement> readLibrary(Uri uri);
-
- /// Returns `true` if [element] has been deserialized.
- bool isDeserialized(Entity element);
-}
-
-/// Task that supports deserialization of elements.
-class SerializationTask extends CompilerTask implements LibraryDeserializer {
- final Compiler compiler;
- SerializationTask(Compiler compiler)
- : compiler = compiler,
- super(compiler.measurer);
-
- DeserializerSystem deserializer;
-
- String get name => 'Serialization';
-
- /// If `true`, data must be retained to support serialization.
- // TODO(johnniwinther): Make this more precise in terms of what needs to be
- // retained, for instance impacts, resolution data etc.
- bool supportSerialization = false;
-
- /// Set this flag to also deserialize [ResolvedAst]s and [ResolutionImpact]s
- /// in `resolveOnly` mode. Use this for testing only.
- bool deserializeCompilationDataForTesting = false;
-
- /// If `true`, deserialized data is supported.
- bool get supportsDeserialization => deserializer != null;
-
- /// Returns the [LibraryElement] for [resolvedUri] if available from
- /// serialization.
- Future<LibraryElement> readLibrary(Uri resolvedUri) {
- if (deserializer == null) return new Future<LibraryElement>.value();
- return deserializer.readLibrary(resolvedUri);
- }
-
- /// Returns `true` if [element] has been deserialized.
- bool isDeserialized(Entity element) {
- return deserializer != null && deserializer.isDeserialized(element);
- }
-
- bool hasResolutionImpact(Element element) {
- return deserializer != null && deserializer.hasResolutionImpact(element);
- }
-
- ResolutionImpact getResolutionImpact(Element element) {
- return deserializer != null
- ? deserializer.getResolutionImpact(element)
- : null;
- }
-
- /// Creates the [ResolutionWorkItem] for the deserialized [element].
- ResolutionWorkItem createResolutionWorkItem(MemberElement element) {
- assert(deserializer != null);
- assert(isDeserialized(element));
- return new DeserializedResolutionWorkItem(
- element, deserializer.computeWorldImpact(element));
- }
-
- bool hasResolvedAst(ExecutableElement element) {
- return deserializer != null ? deserializer.hasResolvedAst(element) : false;
- }
-
- ResolvedAst getResolvedAst(ExecutableElement element) {
- return deserializer != null ? deserializer.getResolvedAst(element) : null;
- }
-
- Serializer createSerializer(Iterable<LibraryElement> libraries) {
- return measure(() {
- assert(supportSerialization);
-
- Serializer serializer =
- new Serializer(shouldInclude: (e) => libraries.contains(e.library));
- SerializerPlugin backendSerializer =
- compiler.backend.serialization.serializer;
- serializer.plugins.add(backendSerializer);
- serializer.plugins.add(new ResolutionImpactSerializer(
- compiler.resolution, backendSerializer));
- serializer.plugins.add(new ResolvedAstSerializerPlugin(
- compiler.resolution, backendSerializer));
-
- for (LibraryElement library in libraries) {
- serializer.serialize(library);
- }
- return serializer;
- });
- }
-
- void serializeToSink(OutputSink sink, Iterable<LibraryElement> libraries) {
- measure(() {
- sink
- ..add(createSerializer(libraries)
- .toText(const JsonSerializationEncoder()))
- ..close();
- });
- }
-
- void deserializeFromText(Uri sourceUri, String serializedData) {
- measure(() {
- if (deserializer == null) {
- deserializer = new ResolutionDeserializerSystem(compiler,
- deserializeCompilationDataForTesting:
- deserializeCompilationDataForTesting);
- }
- ResolutionDeserializerSystem deserializerImpl = deserializer;
- DeserializationContext context = deserializerImpl.deserializationContext;
- Deserializer dataDeserializer = new Deserializer.fromText(
- context, sourceUri, serializedData, const JsonSerializationDecoder());
- context.deserializers.add(dataDeserializer);
- });
- }
-}
-
-/// A [ResolutionWorkItem] for a deserialized element.
-///
-/// This will not resolve the element but only compute the [WorldImpact].
-class DeserializedResolutionWorkItem implements ResolutionWorkItem {
- final MemberElement element;
- final WorldImpact worldImpact;
-
- DeserializedResolutionWorkItem(this.element, this.worldImpact);
-
- @override
- WorldImpact run() {
- return worldImpact;
- }
-}
-
-/// The interface for a system that supports deserialization of libraries and
-/// elements.
-abstract class DeserializerSystem {
- Future<LibraryElement> readLibrary(Uri resolvedUri);
- bool isDeserialized(Entity element);
- bool hasResolvedAst(ExecutableElement element);
- ResolvedAst getResolvedAst(ExecutableElement element);
- bool hasResolutionImpact(Element element);
- ResolutionImpact getResolutionImpact(Element element);
- WorldImpact computeWorldImpact(Element element);
-}
diff --git a/pkg/compiler/lib/src/serialization/type_serialization.dart b/pkg/compiler/lib/src/serialization/type_serialization.dart
deleted file mode 100644
index 5702f3b..0000000
--- a/pkg/compiler/lib/src/serialization/type_serialization.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.types;
-
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import 'keys.dart';
-import 'serialization.dart';
-
-/// Visitor that serializes a [ResolutionDartType] by encoding it into an
-/// [ObjectEncoder].
-///
-/// This class is called from the [Serializer] when a [ResolutionDartType] needs
-/// serialization. The [ObjectEncoder] ensures that any [Element], and other
-/// [ResolutionDartType] that the serialized [ResolutionDartType] depends upon
-/// are also serialized.
-class TypeSerializer extends ResolutionDartTypeVisitor<dynamic, ObjectEncoder> {
- const TypeSerializer();
-
- void visitType(ResolutionDartType type, ObjectEncoder encoder) {
- throw new UnsupportedError('Unsupported type: $type');
- }
-
- void visitVoidType(ResolutionVoidType type, ObjectEncoder encoder) {}
-
- void visitTypeVariableType(
- ResolutionTypeVariableType type, ObjectEncoder encoder) {
- encoder.setElement(Key.ELEMENT, type.element);
- encoder.setBool(
- Key.IS_METHOD_TYPE_VARIABLE_TYPE, type is MethodTypeVariableType);
- }
-
- void visitFunctionType(ResolutionFunctionType type, ObjectEncoder encoder) {
- // TODO(johnniwinther): Support encoding of `type.element`.
- encoder.setType(Key.RETURN_TYPE, type.returnType);
- encoder.setTypes(Key.PARAMETER_TYPES, type.parameterTypes);
- encoder.setTypes(Key.OPTIONAL_PARAMETER_TYPES, type.optionalParameterTypes);
- encoder.setStrings(Key.NAMED_PARAMETERS, type.namedParameters);
- encoder.setTypes(Key.NAMED_PARAMETER_TYPES, type.namedParameterTypes);
- }
-
- void visitMalformedType(MalformedType type, ObjectEncoder encoder) {
- encoder.setElement(Key.ELEMENT, type.element);
- }
-
- void visitInterfaceType(ResolutionInterfaceType type, ObjectEncoder encoder) {
- encoder.setElement(Key.ELEMENT, type.element);
- encoder.setTypes(Key.TYPE_ARGUMENTS, type.typeArguments);
- }
-
- void visitTypedefType(ResolutionTypedefType type, ObjectEncoder encoder) {
- encoder.setElement(Key.ELEMENT, type.element);
- encoder.setTypes(Key.TYPE_ARGUMENTS, type.typeArguments);
- }
-
- void visitDynamicType(ResolutionDynamicType type, ObjectEncoder encoder) {}
-}
-
-/// Utility class for deserializing [ResolutionDartType]s.
-///
-/// This is used by the [Deserializer].
-class TypeDeserializer {
- /// Deserializes a [ResolutionDartType] from an [ObjectDecoder].
- ///
- /// The class is called from the [Deserializer] when a [ResolutionDartType]
- /// needs deserialization. The [ObjectDecoder] ensures that any [Element],
- /// other [ResolutionDartType] that the deserialized [ResolutionDartType]
- /// depends upon are available.
- // ignore: MISSING_RETURN
- static ResolutionDartType deserialize(ObjectDecoder decoder) {
- ResolutionTypeKind typeKind =
- decoder.getEnum(Key.KIND, ResolutionTypeKind.values);
- switch (typeKind) {
- case ResolutionTypeKind.INTERFACE:
- return new ResolutionInterfaceType(decoder.getElement(Key.ELEMENT),
- decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true));
- case ResolutionTypeKind.FUNCTION:
- // TODO(johnniwinther): Support decoding of `type.element`.
- return new ResolutionFunctionType.synthesized(
- decoder.getType(Key.RETURN_TYPE),
- decoder.getTypes(Key.PARAMETER_TYPES, isOptional: true),
- decoder.getTypes(Key.OPTIONAL_PARAMETER_TYPES, isOptional: true),
- decoder.getStrings(Key.NAMED_PARAMETERS, isOptional: true),
- decoder.getTypes(Key.NAMED_PARAMETER_TYPES, isOptional: true));
- case ResolutionTypeKind.TYPE_VARIABLE:
- TypeVariableElement element = decoder.getElement(Key.ELEMENT);
- if (decoder.getBool(Key.IS_METHOD_TYPE_VARIABLE_TYPE)) {
- return new MethodTypeVariableType(element);
- }
- return new ResolutionTypeVariableType(element);
- case ResolutionTypeKind.TYPEDEF:
- return new ResolutionTypedefType(decoder.getElement(Key.ELEMENT),
- decoder.getTypes(Key.TYPE_ARGUMENTS, isOptional: true));
- case ResolutionTypeKind.MALFORMED_TYPE:
- // TODO(johnniwinther): Do we need the 'userProvidedBadType' or maybe
- // just a toString of it?
- return new MalformedType(decoder.getElement(Key.ELEMENT), null);
- case ResolutionTypeKind.DYNAMIC:
- return const ResolutionDynamicType();
- case ResolutionTypeKind.VOID:
- return const ResolutionVoidType();
- }
- }
-}
diff --git a/pkg/compiler/lib/src/serialization/values.dart b/pkg/compiler/lib/src/serialization/values.dart
deleted file mode 100644
index e0c712b..0000000
--- a/pkg/compiler/lib/src/serialization/values.dart
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Class hierarchy for semantic wrapping of serializable values.
-
-library dart2js.serialization.values;
-
-import '../constants/expressions.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import 'keys.dart';
-
-/// Intermediate representation of a serializable value.
-///
-/// Serializable values are
-/// * [bool],
-/// * [int],
-/// * [double],
-/// * [String],
-/// * enum values,
-/// * [ConstantExpression],
-/// * [DartType],
-/// * [Element],
-/// * [Uri],
-/// * lists of serializeable values,
-/// * maps from arbitrary strings to serializable values; these are called
-/// `Map` values, and
-/// * maps from [Key] to serializable values; these are called `Object`
-/// values.
-///
-/// The distinction between map and object values is chosen to provide a more
-/// robust and checkable implementation of the latter; since the keys are drawn
-/// from a fixed typed set of values, consistency between serialization and
-/// deserialization is more easily maintained.
-abstract class Value {
- accept(ValueVisitor visitor, arg);
-}
-
-class ElementValue implements Value {
- final Element element;
- final Value id;
-
- ElementValue(this.element, this.id);
-
- accept(ValueVisitor visitor, arg) => visitor.visitElement(this, arg);
-
- String toString() => element.toString();
-}
-
-class TypeValue implements Value {
- final ResolutionDartType type;
- final Value id;
-
- TypeValue(this.type, this.id);
-
- accept(ValueVisitor visitor, arg) => visitor.visitType(this, arg);
-
- String toString() => type.toString();
-}
-
-class ConstantValue implements Value {
- final ConstantExpression constant;
- final Value id;
-
- ConstantValue(this.constant, this.id);
-
- accept(ValueVisitor visitor, arg) => visitor.visitConstant(this, arg);
-
- String toString() => constant.toDartText();
-}
-
-abstract class PrimitiveValue implements Value {
- get value;
-
- String toString() => value.toString();
-}
-
-class BoolValue extends PrimitiveValue {
- final bool value;
-
- BoolValue(this.value);
-
- accept(ValueVisitor visitor, arg) => visitor.visitBool(this, arg);
-}
-
-class IntValue extends PrimitiveValue {
- final int value;
-
- IntValue(this.value);
-
- accept(ValueVisitor visitor, arg) => visitor.visitInt(this, arg);
-}
-
-class DoubleValue extends PrimitiveValue {
- final double value;
-
- DoubleValue(this.value);
-
- accept(ValueVisitor visitor, arg) => visitor.visitDouble(this, arg);
-}
-
-class StringValue extends PrimitiveValue {
- final String value;
-
- StringValue(this.value);
-
- accept(ValueVisitor visitor, arg) => visitor.visitString(this, arg);
-}
-
-class ObjectValue implements Value {
- final Map<Key, Value> map;
-
- ObjectValue(this.map);
-
- accept(ValueVisitor visitor, arg) => visitor.visitObject(this, arg);
-
- String toString() => map.toString();
-}
-
-class MapValue implements Value {
- final Map<String, Value> map;
-
- MapValue(this.map);
-
- accept(ValueVisitor visitor, arg) => visitor.visitMap(this, arg);
-
- String toString() => map.toString();
-}
-
-class ListValue implements Value {
- final List<Value> values;
-
- ListValue(this.values);
-
- accept(ValueVisitor visitor, arg) => visitor.visitList(this, arg);
-
- String toString() => values.toString();
-}
-
-class EnumValue implements Value {
- final value;
-
- EnumValue(this.value);
-
- accept(ValueVisitor visitor, arg) => visitor.visitEnum(this, arg);
-
- String toString() => value.toString();
-}
-
-class UriValue implements Value {
- final Uri baseUri;
- final Uri value;
-
- UriValue(this.baseUri, this.value);
-
- accept(ValueVisitor visitor, arg) => visitor.visitUri(this, arg);
-
- String toString() => value.toString();
-}
-
-/// Visitor for the [Value] class hierarchy.
-abstract class ValueVisitor<R, A> {
- R visit(Value value, A arg);
-
- R visitElement(ElementValue value, A arg);
- R visitType(TypeValue value, A arg);
- R visitConstant(ConstantValue value, A arg);
- R visitBool(BoolValue value, A arg);
- R visitInt(IntValue value, A arg);
- R visitDouble(DoubleValue value, A arg);
- R visitString(StringValue value, A arg);
- R visitObject(ObjectValue value, A arg);
- R visitMap(MapValue value, A arg);
- R visitList(ListValue value, A arg);
- R visitEnum(EnumValue value, A arg);
- R visitUri(UriValue value, A arg);
-}
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index 638a8a1..e7c0f61 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -28,7 +28,7 @@
Future<api.Input> readBytesFromUri(Uri resourceUri, api.InputKind inputKind) {
api.Input input;
switch (inputKind) {
- case api.InputKind.utf8:
+ case api.InputKind.UTF8:
input = utf8SourceFiles[resourceUri];
break;
case api.InputKind.binary:
@@ -51,7 +51,7 @@
List<int> source;
try {
source = readAll(resourceUri.toFilePath(),
- zeroTerminated: inputKind == api.InputKind.utf8);
+ zeroTerminated: inputKind == api.InputKind.UTF8);
} on FileSystemException catch (ex) {
String message = ex.osError?.message;
String detail = message != null ? ' ($message)' : '';
@@ -60,7 +60,7 @@
dartCharactersRead += source.length;
api.Input input;
switch (inputKind) {
- case api.InputKind.utf8:
+ case api.InputKind.UTF8:
input = utf8SourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
resourceUri, relativizeUri(resourceUri), source);
break;
@@ -76,7 +76,7 @@
/// returned.
api.Input autoReadFromFile(Uri resourceUri) {
try {
- return _readFromFileSync(resourceUri, InputKind.utf8);
+ return _readFromFileSync(resourceUri, InputKind.UTF8);
} catch (e) {
// Silence the error. The [resourceUri] was not requested by the user and
// was only needed to give better error messages.
@@ -120,7 +120,7 @@
dartCharactersRead += totalLength;
api.Input input;
switch (inputKind) {
- case api.InputKind.utf8:
+ case api.InputKind.UTF8:
input = utf8SourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
resourceUri, resourceUri.toString(), result);
break;
@@ -175,7 +175,7 @@
@override
Future<api.Input<List<int>>> readFromUri(Uri uri,
- {InputKind inputKind: InputKind.utf8}) =>
+ {InputKind inputKind: InputKind.UTF8}) =>
readBytesFromUri(uri, inputKind);
}
@@ -311,7 +311,6 @@
class RandomAccessFileOutputProvider implements CompilerOutput {
final Uri out;
final Uri sourceMapOut;
- final Uri resolutionOutput;
final MessageCallback onInfo;
final MessageCallback onFailure;
@@ -322,7 +321,7 @@
List<String> allOutputFiles = <String>[];
RandomAccessFileOutputProvider(this.out, this.sourceMapOut,
- {this.onInfo, this.onFailure, this.resolutionOutput});
+ {this.onInfo, this.onFailure});
Uri createUri(String name, String extension, OutputType type) {
Uri uri;
@@ -346,12 +345,6 @@
case OutputType.jsPart:
uri = out.resolve('$name.$extension');
break;
- case OutputType.serializationData:
- if (resolutionOutput == null) {
- onFailure('Serialization target unspecified.');
- }
- uri = resolutionOutput;
- break;
case OutputType.info:
if (name == '') {
name = out.pathSegments.last;
@@ -473,7 +466,7 @@
@override
Future<api.Input> readFromUri(Uri uri,
- {InputKind inputKind: InputKind.utf8}) async {
+ {InputKind inputKind: InputKind.UTF8}) async {
var resolvedUri = uri;
var path = uri.path;
if (path.startsWith('/bazel-root')) {
@@ -488,7 +481,7 @@
}
api.Input result = await readBytesFromUri(resolvedUri, inputKind);
switch (inputKind) {
- case InputKind.utf8:
+ case InputKind.UTF8:
utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri];
break;
case InputKind.binary:
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index f16c027..37c4541 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -4142,7 +4142,7 @@
return false;
}
- MemberElement element = closedWorld.locateSingleElement(selector, mask);
+ MemberElement element = closedWorld.locateSingleMember(selector, mask);
if (element != null &&
!element.isField &&
!(element.isGetter && selector.isCall) &&
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index ff53f88..efed6ee 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -3817,7 +3817,7 @@
return false;
}
- MemberEntity element = closedWorld.locateSingleElement(selector, mask);
+ MemberEntity element = closedWorld.locateSingleMember(selector, mask);
if (element != null &&
!element.isField &&
!(element.isGetter && selector.isCall) &&
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 24193c7..f108912 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -2907,18 +2907,18 @@
HInstruction input = node.checkedInput;
TypeMask inputType = node.inputType ?? input.instructionType;
TypeMask checkedType = node.checkedType;
- // Figure out if it is beneficial to turn this into a null check.
- // V8 generally prefers 'typeof' checks, but for integers and
- // indexable primitives we cannot compile this test into a single
- // typeof check so the null check is cheaper.
+ // This path is no longer used for indexable primitive types.
+ assert(
+ !checkedType.satisfies(_commonElements.jsIndexableClass, _closedWorld));
+ // Figure out if it is beneficial to use a null check. V8 generally prefers
+ // 'typeof' checks, but for integers we cannot compile this test into a
+ // single typeof check so the null check is cheaper.
bool isIntCheck = checkedType.containsOnlyInt(_closedWorld);
bool turnIntoNumCheck =
isIntCheck && inputType.containsOnlyInt(_closedWorld);
bool turnIntoNullCheck = !turnIntoNumCheck &&
(checkedType.nullable() == inputType) &&
- (isIntCheck ||
- checkedType.satisfies(
- _commonElements.jsIndexableClass, _closedWorld));
+ isIntCheck;
if (turnIntoNullCheck) {
use(input);
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index d98db39..c476754 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -970,6 +970,10 @@
if (right.isConstantNull() || left.isPrimitiveOrNull(closedWorld)) {
return newBuiltinVariant(instruction, closedWorld);
}
+ if (closedWorld.includesClosureCall(
+ instruction.selector, instructionType)) {
+ return null;
+ }
Iterable<MemberEntity> matches =
closedWorld.locateMembers(instruction.selector, instructionType);
// This test relies on `Object.==` and `Interceptor.==` always being
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 9960352..fbe8edd 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -3151,7 +3151,9 @@
}
bool get hasTypeRepresentation {
- return typeExpression.isInterfaceType && inputs.length > 1;
+ return typeExpression != null &&
+ typeExpression.isInterfaceType &&
+ inputs.length > 1;
}
HInstruction get typeRepresentation => inputs[1];
@@ -3194,8 +3196,8 @@
receiverTypeCheckSelector == other.receiverTypeCheckSelector;
}
- String toString() => 'HTypeConversion(type=$typeExpression,kind=$kind,'
- '${hasTypeRepresentation ? 'representation=$typeRepresentation,' : ''}'
+ String toString() => 'HTypeConversion(type=$typeExpression, kind=$kind, '
+ '${hasTypeRepresentation ? 'representation=$typeRepresentation, ' : ''}'
'checkedInput=$checkedInput)';
}
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 889cddf..40c6687 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -534,7 +534,7 @@
TypeMask receiverType = node.getDartReceiver(_closedWorld).instructionType;
MemberEntity element =
- _closedWorld.locateSingleElement(node.selector, receiverType);
+ _closedWorld.locateSingleMember(node.selector, receiverType);
// TODO(ngeoffray): Also fold if it's a getter or variable.
if (element != null &&
element.isFunction
@@ -1056,7 +1056,7 @@
if (field != null) return directFieldGet(receiver, field);
if (node.element == null) {
- MemberEntity element = _closedWorld.locateSingleElement(
+ MemberEntity element = _closedWorld.locateSingleMember(
node.selector, receiver.instructionType);
if (element != null && element.name == node.selector.name) {
node.element = element;
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index 6c0df7e..02bdb6b 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -508,7 +508,24 @@
assert(node.inputs.length == 1);
rest = "";
}
- return "TypeConversion: $checkedInput to ${node.instructionType}$rest";
+ String kind = _typeConversionKind(node);
+ return "TypeConversion: $kind $checkedInput to ${node.instructionType}$rest";
+ }
+
+ String _typeConversionKind(HTypeConversion node) {
+ switch (node.kind) {
+ case HTypeConversion.CHECKED_MODE_CHECK:
+ return 'CHECKED_MODE';
+ case HTypeConversion.ARGUMENT_TYPE_CHECK:
+ return 'ARGUMENT';
+ case HTypeConversion.CAST_TYPE_CHECK:
+ return 'CAST';
+ case HTypeConversion.BOOLEAN_CONVERSION_CHECK:
+ return 'BOOLEAN_CONVERSION';
+ case HTypeConversion.RECEIVER_TYPE_CHECK:
+ return 'RECEIVER';
+ }
+ return '?';
}
String visitTypeKnown(HTypeKnown node) {
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 0831c6e..1d4a182 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -11,6 +11,22 @@
import 'nodes.dart';
import 'optimize.dart';
+/// Type propagation and conditioning check insertion.
+///
+/// 1. Type propagation (dataflow) to determine the types of all nodes.
+///
+/// 2. HTypeKnown node insertion captures type strengthening.
+///
+/// 3. Conditioning check insertion inserts receiver and argument checks on
+/// calls where that call is expected to be replaced with an instruction with
+/// a narrower domain. For example `{Null,int} + {int}` would insert an
+/// receiver check to strengthen the types to `{int} + {int}` to allow the
+/// call of `operator+` to be replaced with a HAdd instruction.
+///
+/// Analysis and node insertion are done together, since insertion improves the
+/// type propagation results.
+// TODO(sra): The InvokeDynamicSpecializer should be consulted for better
+// targeted conditioning checks.
class SsaTypePropagator extends HBaseVisitor implements OptimizationPhase {
final Map<int, HInstruction> workmap = new Map<int, HInstruction>();
final List<int> worklist = new List<int>();
@@ -21,7 +37,7 @@
final CompilerOptions options;
final CommonElements commonElements;
final ClosedWorld closedWorld;
- String get name => 'type propagator';
+ String get name => 'SsaTypePropagator';
SsaTypePropagator(
this.results, this.options, this.commonElements, this.closedWorld);
@@ -283,16 +299,18 @@
HTypeConversion.RECEIVER_TYPE_CHECK);
return true;
} else if (instruction.element == null) {
+ if (closedWorld.includesClosureCall(
+ instruction.selector, instruction.mask)) {
+ return false;
+ }
Iterable<MemberEntity> targets =
closedWorld.locateMembers(instruction.selector, instruction.mask);
if (targets.length == 1) {
MemberEntity target = targets.first;
ClassEntity cls = target.enclosingClass;
TypeMask type = new TypeMask.nonNullSubclass(cls, closedWorld);
- // TODO(ngeoffray): We currently only optimize on primitive
- // types.
- if (!type.satisfies(commonElements.jsIndexableClass, closedWorld) &&
- !type.containsOnlyNum(closedWorld) &&
+ // We currently only optimize on some primitive types.
+ if (!type.containsOnlyNum(closedWorld) &&
!type.containsOnlyBool(closedWorld)) {
return false;
}
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index 1bd4289..932a128 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -540,8 +540,9 @@
return closedWorld.needsNoSuchMethod(base, selector, _classQuery);
}
- MemberEntity locateSingleElement(Selector selector, ClosedWorld closedWorld) {
+ MemberEntity locateSingleMember(Selector selector, ClosedWorld closedWorld) {
if (isEmptyOrNull) return null;
+ if (closedWorld.includesClosureCall(selector, this)) return null;
Iterable<MemberEntity> targets = closedWorld.locateMembers(selector, this);
if (targets.length != 1) return null;
MemberEntity result = targets.first;
diff --git a/pkg/compiler/lib/src/types/forwarding_type_mask.dart b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
index 974f255..0bfed426 100644
--- a/pkg/compiler/lib/src/types/forwarding_type_mask.dart
+++ b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
@@ -103,8 +103,8 @@
return forwardTo.canHit(element, selector, closedWorld);
}
- MemberEntity locateSingleElement(Selector selector, ClosedWorld closedWorld) {
- return forwardTo.locateSingleElement(selector, closedWorld);
+ MemberEntity locateSingleMember(Selector selector, ClosedWorld closedWorld) {
+ return forwardTo.locateSingleMember(selector, closedWorld);
}
bool equalsDisregardNull(other) {
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index dd8a7b0..7af49b4 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -370,5 +370,5 @@
* on this mask. Returns null if there is none.
*/
// TODO(johnniwinther): Move this method to [World].
- MemberEntity locateSingleElement(Selector selector, ClosedWorld closedWorld);
+ MemberEntity locateSingleMember(Selector selector, ClosedWorld closedWorld);
}
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 543ee11..178f878 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -338,10 +338,10 @@
return disjointMasks.any((e) => e.canHit(element, selector, closedWorld));
}
- MemberEntity locateSingleElement(Selector selector, ClosedWorld closedWorld) {
+ MemberEntity locateSingleMember(Selector selector, ClosedWorld closedWorld) {
MemberEntity candidate;
for (FlatTypeMask mask in disjointMasks) {
- MemberEntity current = mask.locateSingleElement(selector, closedWorld);
+ MemberEntity current = mask.locateSingleMember(selector, closedWorld);
if (current == null) {
return null;
} else if (candidate == null) {
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 8ef7d5b..183575c 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -7,8 +7,9 @@
import 'dart:collection' show Queue;
import 'closure.dart';
import 'common.dart';
-import 'constants/constant_system.dart';
+import 'common/names.dart';
import 'common_elements.dart' show CommonElements, ElementEnvironment;
+import 'constants/constant_system.dart';
import 'elements/entities.dart';
import 'elements/elements.dart'
show
@@ -300,6 +301,14 @@
/// Returns all resolved typedefs.
Iterable<TypedefEntity> get allTypedefs;
+ /// Returns `true` if [selector] on [mask] can hit a `call` method on a
+ /// subclass of `Closure`.
+ ///
+ /// Every implementation of `Closure` has a 'call' method with its own
+ /// signature so it cannot be modelled by a [FunctionEntity]. Also,
+ /// call-methods for tear-off are not part of the element model.
+ bool includesClosureCall(Selector selector, TypeMask mask);
+
/// Returns the mask for the potential receivers of a dynamic call to
/// [selector] on [mask].
///
@@ -316,7 +325,7 @@
/// Returns the single [MemberEntity] that matches a call to [selector] on a
/// receiver of type [mask]. If multiple targets exist, `null` is returned.
- MemberEntity locateSingleElement(Selector selector, TypeMask mask);
+ MemberEntity locateSingleMember(Selector selector, TypeMask mask);
/// Returns the single field that matches a call to [selector] on a
/// receiver of type [mask]. If multiple targets exist or the single target
@@ -1036,8 +1045,23 @@
}
}
+ /// Returns `true` if [selector] on [mask] can hit a `call` method on a
+ /// subclass of `Closure`.
+ ///
+ /// Every implementation of `Closure` has a 'call' method with its own
+ /// signature so it cannot be modelled by a [FunctionEntity]. Also,
+ /// call-methods for tear-off are not part of the element model.
+ bool includesClosureCall(Selector selector, TypeMask mask) {
+ return selector.name == Identifiers.call &&
+ (mask == null ||
+ mask.containsMask(commonMasks.functionType, closedWorld));
+ }
+
TypeMask computeReceiverType(Selector selector, TypeMask mask) {
_ensureFunctionSet();
+ if (includesClosureCall(selector, mask)) {
+ return commonMasks.dynamicType;
+ }
return _allFunctions.receiverType(selector, mask, this);
}
@@ -1054,13 +1078,16 @@
}
FieldEntity locateSingleField(Selector selector, TypeMask mask) {
- MemberEntity result = locateSingleElement(selector, mask);
+ MemberEntity result = locateSingleMember(selector, mask);
return (result != null && result.isField) ? result : null;
}
- MemberEntity locateSingleElement(Selector selector, TypeMask mask) {
+ MemberEntity locateSingleMember(Selector selector, TypeMask mask) {
+ if (includesClosureCall(selector, mask)) {
+ return null;
+ }
mask ??= commonMasks.dynamicType;
- return mask.locateSingleElement(selector, this);
+ return mask.locateSingleMember(selector, this);
}
TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
@@ -1093,7 +1120,9 @@
SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask) {
// We're not tracking side effects of closures.
- if (selector.isClosureCall) return new SideEffects();
+ if (selector.isClosureCall || includesClosureCall(selector, mask)) {
+ return new SideEffects();
+ }
SideEffects sideEffects = new SideEffects.empty();
_ensureFunctionSet();
for (MemberEntity e in _allFunctions.filter(selector, mask, this)) {
diff --git a/pkg/compiler/testing_dart.json b/pkg/compiler/testing_dart.json
index aa78e3e..f36c8ad 100644
--- a/pkg/compiler/testing_dart.json
+++ b/pkg/compiler/testing_dart.json
@@ -63,12 +63,6 @@
"^tests/compiler/dart2js/rti/emission/future_or_future_or_generic_strong\\.dart",
"^tests/compiler/dart2js/rti/emission/future_or_future_or_strong\\.dart",
"^tests/compiler/dart2js/rti/emission/future_or_generic2_strong\\.dart",
- "^tests/compiler/dart2js/serialization/analysis_test_helper\\.dart",
- "^tests/compiler/dart2js/serialization/compilation_test_helper\\.dart",
- "^tests/compiler/dart2js/serialization/duplicate_library_test\\.dart",
- "^tests/compiler/dart2js/serialization/equivalence_test\\.dart",
- "^tests/compiler/dart2js/serialization/model_test_helper\\.dart",
- "^tests/compiler/dart2js/serialization/test_helper\\.dart",
"^tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper\\.dart",
"^tests/compiler/dart2js/sourcemaps/diff_view\\.dart",
"^tests/compiler/dart2js/sourcemaps/html_parts\\.dart",
diff --git a/pkg/compiler/tool/track_memory.dart b/pkg/compiler/tool/track_memory.dart
index 75d6d14..f6ef38d 100644
--- a/pkg/compiler/tool/track_memory.dart
+++ b/pkg/compiler/tool/track_memory.dart
@@ -66,7 +66,7 @@
Future _sendMessage(String method, [Map args = const {}]) {
var id = _requestId++;
_pendingResponses[id] = new Completer();
- socket.add(JSON.encode({
+ socket.add(jsonEncode({
'jsonrpc': '2.0',
'id': '$id',
'method': '$method',
@@ -77,7 +77,7 @@
/// Handle all responses
void _handleResponse(Object s) {
- var json = JSON.decode(s);
+ var json = jsonDecode(s);
if (json['method'] != 'streamNotify') {
var id = json['id'];
if (id is String) id = int.parse(id);
diff --git a/pkg/dart_messages/bin/publish.dart b/pkg/dart_messages/bin/publish.dart
index cf4ac90..2b609e6 100644
--- a/pkg/dart_messages/bin/publish.dart
+++ b/pkg/dart_messages/bin/publish.dart
@@ -47,7 +47,7 @@
///
/// The parameter [str] may be `null` in which case the result is "null".
String escapeString(String str) {
- return JSON.encode(str);
+ return jsonEncode(str);
}
/// Emits the messages in dart2js format.
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 9c93e2c..48eaedb 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -129,9 +129,6 @@
JS.Identifier _extensionSymbolsModule;
final _extensionSymbols = new Map<String, JS.TemporaryId>();
- JS.Identifier _runtimeModule;
- final namedArgumentTemp = new JS.TemporaryId('opts');
-
/// The type provider from the current Analysis [context].
final TypeProvider types;
@@ -341,14 +338,14 @@
if (isBuildingSdk) {
// Don't allow these to be renamed when we're building the SDK.
// There is JS code in dart:* that depends on their names.
- _runtimeModule = new JS.Identifier('dart');
+ runtimeModule = new JS.Identifier('dart');
_extensionSymbolsModule = new JS.Identifier('dartx');
} else {
// Otherwise allow these to be renamed so users can write them.
- _runtimeModule = new JS.TemporaryId('dart');
+ runtimeModule = new JS.TemporaryId('dart');
_extensionSymbolsModule = new JS.TemporaryId('dartx');
}
- _typeTable = new TypeTable(_runtimeModule);
+ _typeTable = new TypeTable(runtimeModule);
// Initialize our library variables.
var exports = <JS.NameSpecifier>[];
@@ -362,7 +359,7 @@
if (unit.element != library.definingCompilationUnit) continue;
var libraryTemp = isSdkInternalRuntime(library)
- ? _runtimeModule
+ ? runtimeModule
: new JS.TemporaryId(jsLibraryName(_libraryRoot, library));
_libraries[library] = libraryTemp;
emitLibrary(libraryTemp);
@@ -446,7 +443,7 @@
// This data is only required for debugging.
_moduleItems.add(js
.statement('#.trackLibraries(#, #, ${JSModuleFile.sourceMapHoleID});', [
- _runtimeModule,
+ runtimeModule,
js.string(name),
new JS.ObjectInitializer(properties, multiline: true)
]));
@@ -503,7 +500,7 @@
JS.PropertyAccess access;
for (var part in parts) {
access = new JS.PropertyAccess(
- access ?? _callHelper('global'), js.escapedString(part, "'"));
+ access ?? runtimeCall('global'), js.escapedString(part, "'"));
}
return access;
}
@@ -575,7 +572,7 @@
var imports =
libraries.map((l) => new JS.NameSpecifier(_imports[l])).toList();
if (module == coreModuleName) {
- imports.add(new JS.NameSpecifier(_runtimeModule));
+ imports.add(new JS.NameSpecifier(runtimeModule));
imports.add(new JS.NameSpecifier(_extensionSymbolsModule));
}
@@ -780,7 +777,7 @@
var callMethod = from.lookUpInheritedMethod('call');
if (callMethod != null) {
var callName = _emitMemberName('call', type: from, element: callMethod);
- var callTearoff = _callHelper('bindCall(#, #)', [jsFrom, callName]);
+ var callTearoff = runtimeCall('bindCall(#, #)', [jsFrom, callName]);
if (rules.isSubtypeOf(callMethod.type, to)) return callTearoff;
// We may still need an implicit coercion as well, if another downcast
@@ -796,7 +793,7 @@
// TODO(jmesserly): fuse this with notNull check.
// TODO(jmesserly): this does not correctly distinguish user casts from
// required-for-soundness casts.
- return _callHelper('asInt(#)', jsFrom);
+ return runtimeCall('asInt(#)', jsFrom);
}
// A no-op in JavaScript.
@@ -858,7 +855,7 @@
}
JS.Expression body = closureAnnotate(
- _callHelper('typedef(#, () => #)', [
+ runtimeCall('typedef(#, () => #)', [
js.string(element.name, "'"),
_emitFunctionType(type, nameType: false)
]),
@@ -965,8 +962,8 @@
var jsPeerNames = _extensionTypes.getNativePeers(classElem);
if (jsPeerNames.length == 1 && classElem.typeParameters.isNotEmpty) {
// Special handling for JSArray<E>
- body.add(_callHelperStatement('setExtensionBaseClass(#, #.global.#);',
- [className, _runtimeModule, jsPeerNames[0]]));
+ body.add(runtimeStatement('setExtensionBaseClass(#, #.global.#)',
+ [className, runtimeModule, jsPeerNames[0]]));
}
var finishGenericTypeTest = _emitClassTypeTests(classElem, className, body);
@@ -1009,7 +1006,7 @@
case 'Future':
case 'Stream':
case 'StreamSubscription':
- return _callHelper('is' + c.name);
+ return runtimeCall('is' + c.name);
}
}
return null;
@@ -1044,13 +1041,13 @@
' if (typeof o == "string" || o == null) return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_String(o) {'
' if (typeof o == "string" || o == null) return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
if (classElem == functionClass) {
@@ -1062,13 +1059,13 @@
' if (typeof o == "function" || o == null) return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_Function(o) {'
' if (typeof o == "function" || o == null) return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
if (classElem == intClass) {
@@ -1083,14 +1080,14 @@
' return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_int(o) {'
' if ((typeof o == "number" && Math.floor(o) == o) || o == null)'
' return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
if (classElem == nullClass) {
@@ -1101,13 +1098,13 @@
' if (o == null) return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_Null(o) {'
' if (o == null) return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
if (classElem == numClass || classElem == doubleClass) {
@@ -1119,13 +1116,13 @@
' if (typeof o == "number" || o == null) return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_num(o) {'
' if (typeof o == "number" || o == null) return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
if (classElem == boolClass) {
@@ -1137,13 +1134,13 @@
' if (o === true || o === false || o == null) return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_bool(o) {'
' if (o === true || o === false || o == null) return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
}
@@ -1164,18 +1161,18 @@
if (o == null || #.is(o) || #.is(o)) return o;
return #.as(o, this, false);
}
- ''', [className, typeT, futureOfT, _runtimeModule]));
+ ''', [className, typeT, futureOfT, runtimeModule]));
body.add(js.statement('''
#._check = function check_FutureOr(o) {
if (o == null || #.is(o) || #.is(o)) return o;
return #.as(o, this, true);
}
- ''', [className, typeT, futureOfT, _runtimeModule]));
+ ''', [className, typeT, futureOfT, runtimeModule]));
return null;
}
}
- body.add(_callHelperStatement('addTypeTests(#);', [className]));
+ body.add(runtimeStatement('addTypeTests(#)', [className]));
if (classElem.typeParameters.isEmpty) return null;
@@ -1200,8 +1197,7 @@
// Return this `addTypeTests` call so we can emit it outside of the generic
// type parameter scope.
- return _callHelperStatement(
- 'addTypeTests(#, #);', [defaultInst, isClassSymbol]);
+ return runtimeStatement('addTypeTests(#, #)', [defaultInst, isClassSymbol]);
}
void _emitSymbols(Iterable<JS.TemporaryId> vars, List<JS.ModuleItem> body) {
@@ -1266,7 +1262,7 @@
genericArgs.add(js.call('(#) => { #; }', [jsFormals, deferredBaseClass]));
}
- var genericCall = _callHelper('generic(#)', [genericArgs]);
+ var genericCall = runtimeCall('generic(#)', [genericArgs]);
var genericName = _emitTopLevelNameNoInterop(element, suffix: '\$');
return js.statement('{ # = #; # = #(); }',
@@ -1357,7 +1353,7 @@
mixinCtor = js.statement('#.#.call(this);', [
emitClassRef(mixin),
_usesMixinNew(mixin.element)
- ? _callHelper('mixinNew')
+ ? runtimeCall('mixinNew')
: _constructorName('')
]);
}
@@ -1381,7 +1377,7 @@
// Unroll mixins.
var mixinLength = classElem.mixins.length;
if (shouldDefer(supertype)) {
- deferredSupertypes.add(_callHelperStatement('setBaseClass(#, #)', [
+ deferredSupertypes.add(runtimeStatement('setBaseClass(#, #)', [
getBaseClass(isMixinAliasClass(classElem) ? 0 : mixinLength),
emitDeferredType(supertype),
]));
@@ -1403,8 +1399,8 @@
var mixinClass = deferMixin ? emitDeferredType(m) : emitClassRef(m);
var classExpr = deferMixin ? getBaseClass(0) : className;
- mixinBody.add(
- _callHelperStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
+ mixinBody
+ .add(runtimeStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
_topLevelClass = savedTopLevel;
@@ -1415,7 +1411,7 @@
// We do this with the following pattern:
//
// mixinMembers(C, class C$ extends M { <methods> });
- mixinBody.add(_callHelperStatement('mixinMembers(#, #)', [
+ mixinBody.add(runtimeStatement('mixinMembers(#, #)', [
classExpr,
new JS.ClassExpression(
new JS.TemporaryId(classElem.name), mixinClass, methods)
@@ -1447,11 +1443,11 @@
hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(m.element);
if (shouldDefer(m)) {
- deferredSupertypes.add(_callHelperStatement('mixinMembers(#, #)',
+ deferredSupertypes.add(runtimeStatement('mixinMembers(#, #)',
[getBaseClass(mixinLength - i), emitDeferredType(m)]));
} else {
- body.add(_callHelperStatement(
- 'mixinMembers(#, #)', [mixinId, emitClassRef(m)]));
+ body.add(
+ runtimeStatement('mixinMembers(#, #)', [mixinId, emitClassRef(m)]));
}
baseClass = mixinId;
@@ -1513,7 +1509,7 @@
new JS.Method(_propertyName('constructor'), js.fun(r'''function() {
throw Error("use `new " + #.typeName(#.getReifiedType(this)) +
".new(...)` to create a Dart object");
- }''', [_runtimeModule, _runtimeModule])));
+ }''', [runtimeModule, runtimeModule])));
} else if (classElem.isEnum) {
// Generate Enum.toString()
var fields = classElem.fields.where((f) => f.type == type).toList();
@@ -1733,34 +1729,42 @@
invocationProps.add(new JS.Property(js.string(name), value));
}
- var args = _emitParametersForElement(method);
var typeParams = _emitTypeFormals(method.type.typeFormals);
- var fnArgs = new List<JS.Parameter>.from(typeParams)..addAll(args);
-
+ var fnArgs = new List<JS.Parameter>.from(typeParams);
JS.Expression positionalArgs;
- List<JS.Statement> optionalArgInit = [];
- if (method.type.optionalParameterTypes.isNotEmpty) {
- positionalArgs = new JS.TemporaryId('args');
- var requiredParameterCount = method.type.normalParameterTypes.length;
- optionalArgInit.add(js.statement(
- 'let # = [#]', [positionalArgs, args.take(requiredParameterCount)]));
- optionalArgInit.addAll(args.skip(requiredParameterCount).map((p) =>
- js.statement('if (# !== void 0) #.push(#)', [p, positionalArgs, p])));
- } else {
- if (method.type.namedParameterTypes.isNotEmpty) {
- addProperty('namedArguments', args.removeLast());
- }
- positionalArgs = new JS.ArrayInitializer(args);
- }
- if (method is MethodElement) {
- addProperty('isMethod', js.boolean(true));
- } else {
- var property = method as PropertyAccessorElement;
- if (property.isGetter) {
+ if (method is PropertyAccessorElement) {
+ if (method.isGetter) {
addProperty('isGetter', js.boolean(true));
- } else if (property.isSetter) {
+ positionalArgs = new JS.ArrayInitializer([]);
+ } else {
+ assert(method.isSetter);
addProperty('isSetter', js.boolean(true));
+ var valueArg = new JS.TemporaryId('value');
+ positionalArgs = new JS.ArrayInitializer([valueArg]);
+ fnArgs.add(valueArg);
+ }
+ } else {
+ addProperty('isMethod', js.boolean(true));
+ if (method.type.namedParameterTypes.isNotEmpty) {
+ // Named parameters need to be emitted in the correct position (after
+ // positional arguments) so we can detect them reliably.
+ var args = _emitParametersForElement(method);
+ fnArgs.addAll(args);
+ addProperty('namedArguments', args.removeLast());
+ positionalArgs = new JS.ArrayInitializer(args);
+ } else {
+ // In case we have optional parameters, we need to use rest args,
+ // because sometimes mocks want to detect whether optional arguments
+ // were passed, and this does not work reliably with undefined (should
+ // not normally appear in DDC, but it can result from JS interop).
+ //
+ // TODO(jmesserly): perhaps we need to use rest args or destructuring
+ // to get reliable optional argument passing in other scenarios? It
+ // doesn't seem to occur outside of tests, perhaps due to the
+ // combination of mockito and protobufs.
+ positionalArgs = new JS.TemporaryId('args');
+ fnArgs.add(new JS.RestParameter(positionalArgs));
}
}
@@ -1770,7 +1774,7 @@
var fnBody =
js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [
- _runtimeModule,
+ runtimeModule,
_declareMemberName(method),
positionalArgs,
new JS.ObjectInitializer(invocationProps)
@@ -1780,9 +1784,8 @@
fnBody = js.call('#._check(#)', [_emitType(method.returnType), fnBody]);
}
- var fn = new JS.Fun(
- fnArgs, js.block('{ #; return #; }', [optionalArgInit, fnBody]),
- typeParams: typeParams);
+ var fn =
+ new JS.Fun(fnArgs, fnBody.toReturn().toBlock(), typeParams: typeParams);
return new JS.Method(
_declareMemberName(method,
@@ -1899,7 +1902,7 @@
return new JS.Method(
js.call('Symbol.iterator'),
js.call('function() { return new #.JsIterator(this.#); }',
- [_runtimeModule, _emitMemberName('iterator', type: t)]) as JS.Fun);
+ [runtimeModule, _emitMemberName('iterator', type: t)]) as JS.Fun);
}
JS.Expression _instantiateAnnotation(Annotation node) {
@@ -1920,11 +1923,11 @@
ClassElement classElem, String jsPeerName, List<JS.Statement> body) {
var className = _emitTopLevelName(classElem);
if (isPrimitiveType(classElem.type)) {
- body.add(_callHelperStatement(
- 'definePrimitiveHashCode(#.prototype)', className));
+ body.add(
+ runtimeStatement('definePrimitiveHashCode(#.prototype)', className));
}
- body.add(_callHelperStatement(
- 'registerExtension(#, #);', [js.string(jsPeerName), className]));
+ body.add(runtimeStatement(
+ 'registerExtension(#, #)', [js.string(jsPeerName), className]));
}
/// Defines all constructors for this class as ES5 constructors.
@@ -1986,7 +1989,7 @@
body.add(
js.statement('(#[#] = function() { # }).prototype = #.prototype;', [
className,
- _callHelper('mixinNew'),
+ runtimeCall('mixinNew'),
[_initializeFields(fields)],
className
]));
@@ -2009,7 +2012,7 @@
var ctorName = _constructorName(name);
if (JS.invalidStaticFieldName(name)) {
jsCtor =
- _callHelper('defineValue(#, #, #)', [className, ctorName, jsCtor]);
+ runtimeCall('defineValue(#, #, #)', [className, ctorName, jsCtor]);
} else {
jsCtor = js.call('#.# = #', [className, ctorName, jsCtor]);
}
@@ -2031,7 +2034,7 @@
];
// TODO(jmesserly): should this be the job of `declareMemberName`?
if (JS.invalidStaticFieldName(e.name)) {
- body.add(_callHelperStatement('defineValue(#, #, #)', args));
+ body.add(runtimeStatement('defineValue(#, #, #)', args));
} else {
body.add(js.statement('#.# = #', args));
}
@@ -2044,7 +2047,7 @@
// static const E id_i = const E(i);
values.add(new JS.PropertyAccess(
_emitStaticClassName(classElem), _declareMemberName(f.getter)));
- var enumValue = _callHelper('const(new (#.#)(#))', [
+ var enumValue = runtimeCall('const(new (#.#)(#))', [
_emitConstructorAccess(type),
_constructorName(''),
js.number(index++)
@@ -2071,7 +2074,7 @@
// Metadata
if (options.emitMetadata && metadata.isNotEmpty) {
body.add(js.statement('#[#.metadata] = () => [#];',
- [className, _runtimeModule, metadata.map(_instantiateAnnotation)]));
+ [className, runtimeModule, metadata.map(_instantiateAnnotation)]));
}
}
@@ -2100,7 +2103,7 @@
.map((e) => _propertyName(JS.memberNameForDartMember(e)))
.toList();
body.add(js.statement('#.#(#, #);', [
- _runtimeModule,
+ runtimeModule,
helperName,
className,
new JS.ArrayInitializer(names, multiline: names.length > 4)
@@ -2117,7 +2120,7 @@
Map<Element, Declaration> annotatedMembers, List<JS.Statement> body) {
if (classElem.interfaces.isNotEmpty) {
body.add(js.statement('#[#.implements] = () => [#];',
- [className, _runtimeModule, classElem.interfaces.map(_emitType)]));
+ [className, runtimeModule, classElem.interfaces.map(_emitType)]));
}
void emitSignature(String name, List<JS.Property> elements) {
@@ -2126,10 +2129,10 @@
if (!name.startsWith('Static')) {
var proto = classElem.type.isObject
? js.call('Object.create(null)')
- : _callHelper('get${name}s(#.__proto__)', [className]);
+ : runtimeCall('get${name}s(#.__proto__)', [className]);
elements.insert(0, new JS.Property(_propertyName('__proto__'), proto));
}
- body.add(_callHelperStatement('set${name}Signature(#, () => #)', [
+ body.add(runtimeStatement('set${name}Signature(#, () => #)', [
className,
new JS.ObjectInitializer(elements, multiline: elements.length > 1)
]));
@@ -2291,9 +2294,10 @@
}
// Add static property dart._runtimeType to Object.
+ //
// All other Dart classes will (statically) inherit this property.
if (classElem == objectClass) {
- body.add(_callHelperStatement('tagComputed(#, () => #.#);',
+ body.add(runtimeStatement('lazyFn(#, () => #.#)',
[className, emitLibraryName(coreLibrary), 'Type']));
}
}
@@ -2669,8 +2673,8 @@
}
props.add(pairCode);
}
- return _callHelperStatement('copyProperties(#, { # });',
- [emitLibraryName(currentLibrary), props]);
+ return runtimeStatement(
+ 'copyProperties(#, { # })', [emitLibraryName(currentLibrary), props]);
}
var body = <JS.Statement>[];
@@ -2754,7 +2758,7 @@
{bool topLevel: false}) {
var lazy = topLevel && !_typeIsLoaded(type);
var typeRep = _emitFunctionType(type, lazy: lazy);
- return _callHelper(lazy ? 'lazyFn(#, #)' : 'fn(#, #)', [fn, typeRep]);
+ return runtimeCall(lazy ? 'lazyFn(#, #)' : 'fn(#, #)', [fn, typeRep]);
}
/// Emits an arrow FunctionExpression node.
@@ -2874,7 +2878,7 @@
for (var t in typeFormals) {
t = covariantParams.lookup(t) as TypeParameterElement;
if (t != null) {
- body.add(_callHelperStatement('checkTypeBound(#, #, #)',
+ body.add(runtimeStatement('checkTypeBound(#, #, #)',
[_emitType(t.type), _emitType(t.bound), _propertyName(t.name)]));
}
}
@@ -2960,7 +2964,7 @@
// dart:_runtime/generators.dart has an example of the generated code.
var asyncStarParam = new JS.TemporaryId('stream');
var gen = emitGeneratorFn([asyncStarParam], asyncStarParam);
- return _callHelper('asyncStar(#, #)', [_emitType(returnType), gen]);
+ return runtimeCall('asyncStar(#, #)', [_emitType(returnType), gen]);
}
// `async` works similar to `sync*`:
@@ -3019,7 +3023,7 @@
simpleId.receiver.sourceInformation = _nodeSpan(prefix.prefix);
}
if (typeArgs == null) return simpleId;
- return _callHelper('gbind(#, #)', [simpleId, typeArgs]);
+ return runtimeCall('gbind(#, #)', [simpleId, typeArgs]);
}
/// Emits a simple identifier, handling implicit `this` as well as
@@ -3059,7 +3063,7 @@
// If the type is a type literal expression in Dart code, wrap the raw
// runtime type in a "Type" instance.
if (!_isInForeignJS && _isTypeLiteral(node)) {
- typeName = _callHelper('wrapType(#)', typeName);
+ typeName = runtimeCall('wrapType(#)', typeName);
}
return typeName;
@@ -3101,7 +3105,7 @@
var nativeName = _extensionTypes.getNativePeers(classElem);
if (nativeName.isNotEmpty) {
var memberName = getAnnotationName(element, isJSName) ?? member;
- return _callHelper('global.#.#', [nativeName[0], memberName]);
+ return runtimeCall('global.#.#', [nativeName[0], memberName]);
}
}
@@ -3116,7 +3120,7 @@
return _emitFunctionTagged(
new JS.PropertyAccess(target, member), element.type);
}
- return _callHelper('bind(#, #)', [target, member]);
+ return runtimeCall('bind(#, #)', [target, member]);
}
return new JS.PropertyAccess(target, member);
}
@@ -3198,7 +3202,7 @@
args.add(new JS.ArrayInitializer(
metadata.map(_instantiateAnnotation).toList()));
}
- return _callHelper(isFinal ? 'finalFieldType(#)' : 'fieldType(#)', [args]);
+ return runtimeCall(isFinal ? 'finalFieldType(#)' : 'fieldType(#)', [args]);
}
JS.ArrayInitializer _emitTypeNames(
@@ -3277,7 +3281,7 @@
} else {
helperCall = 'fnType(#)';
}
- fullType = _callHelper(helperCall, [typeParts]);
+ fullType = runtimeCall(helperCall, [typeParts]);
if (!nameType) return fullType;
return _typeTable.nameFunctionType(type, fullType, lazy: lazy);
}
@@ -3310,11 +3314,11 @@
JS.Expression _emitType(DartType type, {bool nameType: true}) {
// The void and dynamic types are not defined in core.
if (type.isVoid) {
- return _callHelper('void');
+ return runtimeCall('void');
} else if (type.isDynamic) {
- return _callHelper('dynamic');
+ return runtimeCall('dynamic');
} else if (type.isBottom) {
- return _callHelper('bottom');
+ return runtimeCall('bottom');
}
var element = type.element;
@@ -3336,11 +3340,11 @@
// Anonymous JS types do not have a corresponding concrete JS type so we
// have to use a helper to define them.
if (_isObjectLiteral(element)) {
- return _callHelper('anonymousJSType(#)', js.escapedString(element.name));
+ return runtimeCall('anonymousJSType(#)', js.escapedString(element.name));
}
var jsName = _getJSNameWithoutGlobal(element);
if (jsName != null) {
- return _callHelper('lazyJSType(() => #, #)',
+ return runtimeCall('lazyJSType(() => #, #)',
[_emitJSInteropForGlobal(jsName), js.escapedString(jsName)]);
}
@@ -3481,7 +3485,7 @@
}
if (isDynamicInvoke(target)) {
- return _callHelper('dput$_replSuffix(#, #, #)', [
+ return runtimeCall('dput$_replSuffix(#, #, #)', [
_visitExpression(target),
_emitMemberName(id.name),
_visitExpression(right)
@@ -3499,16 +3503,16 @@
return _badAssignment('Unhandled assignment', left, right);
}
- // TODO(jmesserly): remove this. Instead handle REPL private name lookups in
- // _emitMemberName (by using `dart.privateName` if we're in REPL mode,
- // refactored from the current `dart._dhelperRepl`).
+ // TODO(jmesserly): can we encapsulate REPL name lookups and remove this?
+ // _emitMemberName would be a nice place to handle it, but we don't have
+ // access to the target expression there (needed for `dart.replNameLookup`).
String get _replSuffix => options.replCompile ? 'Repl' : '';
JS.Expression _badAssignment(String problem, Expression lhs, Expression rhs) {
// TODO(sra): We should get here only for compiler bugs or weirdness due to
// --unsafe-force-compile. Once those paths have been addressed, throw at
// compile time.
- return _callHelper('throwUnimplementedError((#, #, #))',
+ return runtimeCall('throwUnimplementedError((#, #, #))',
[js.string('$lhs ='), _visitExpression(rhs), js.string(problem)]);
}
@@ -3627,7 +3631,7 @@
visitMethodInvocation(MethodInvocation node) {
if (_isDeferredLoadLibrary(node.target, node.methodName)) {
// We are calling loadLibrary() on a deferred library prefix.
- return _callHelper('loadLibrary()');
+ return runtimeCall('loadLibrary()');
}
if (node.operator?.lexeme == '?.' && isNullable(node.target)) {
@@ -3768,7 +3772,7 @@
JS.Expression jsTarget = _emitTarget(target, element, isStatic);
if (_isObjectMemberCall(target, name)) {
assert(typeArgs == null); // Object methods don't take type args.
- return _callHelper('#(#, #)', [name, jsTarget, args]);
+ return runtimeCall('#(#, #)', [name, jsTarget, args]);
}
jsTarget = _emitTargetAccess(jsTarget, jsName, element, node.methodName);
@@ -3823,7 +3827,7 @@
jsCode += ', [#])';
}
- return _callHelper(jsCode, jsArgs);
+ return runtimeCall(jsCode, jsArgs);
}
bool _doubleEqIsIdentity(Expression left, Expression right) {
@@ -3856,7 +3860,7 @@
{bool negated = false}) {
if (arguments.length != 2) {
// Shouldn't happen in typechecked code
- return _callHelper(
+ return runtimeCall(
'throw(Error("compile error: calls to `identical` require 2 args")');
}
var left = arguments[0];
@@ -4168,6 +4172,7 @@
_emitAssert(node.condition, node.message);
JS.Statement _emitAssert(Expression condition, Expression message) {
+ if (!options.enableAsserts) return new JS.EmptyStatement();
// TODO(jmesserly): only emit in checked mode.
var conditionType = condition.staticType;
var jsCondition = _visitExpression(condition);
@@ -4175,15 +4180,15 @@
if (conditionType is FunctionType &&
conditionType.parameters.isEmpty &&
conditionType.returnType == types.boolType) {
- jsCondition = _callHelper('test(#())', jsCondition);
+ jsCondition = runtimeCall('test(#())', jsCondition);
} else if (conditionType != types.boolType) {
- jsCondition = _callHelper('dassert(#)', jsCondition);
+ jsCondition = runtimeCall('dassert(#)', jsCondition);
} else if (isNullable(condition)) {
- jsCondition = _callHelper('test(#)', jsCondition);
+ jsCondition = runtimeCall('test(#)', jsCondition);
}
return js.statement(' if (!#) #.assertFailed(#);', [
jsCondition,
- _runtimeModule,
+ runtimeModule,
message != null ? [_visitExpression(message)] : []
]);
}
@@ -4378,7 +4383,7 @@
}
}
- return _callHelperStatement('defineLazy(#, { # });', [objExpr, accessors]);
+ return runtimeStatement('defineLazy(#, { # })', [objExpr, accessors]);
}
PropertyAccessorElement _findAccessor(VariableElement element,
@@ -4584,7 +4589,7 @@
}
JS.Statement _nullParameterCheck(JS.Expression param) {
- var call = _callHelper('argumentError((#))', [param]);
+ var call = runtimeCall('argumentError((#))', [param]);
return js.statement('if (# == null) #;', [param, call]);
}
@@ -4592,7 +4597,7 @@
if (expr == null) return null;
var jsExpr = _visitExpression(expr);
if (!isNullable(expr)) return jsExpr;
- return _callHelper('notNull(#)', jsExpr);
+ return runtimeCall('notNull(#)', jsExpr);
}
JS.Expression _emitEqualityOperator(BinaryExpression node, Token op) {
@@ -4640,7 +4645,7 @@
if (isNullable(left)) {
var code = negated ? '!#.equals(#, #)' : '#.equals(#, #)';
return js.call(code,
- [_runtimeModule, _visitExpression(left), _visitExpression(right)]);
+ [runtimeModule, _visitExpression(left), _visitExpression(right)]);
}
// Otherwise we emit a call to the == method.
@@ -4974,7 +4979,7 @@
}
JS.Expression _emitConst(JS.Expression expr()) =>
- _cacheConst(() => _callHelper('const(#)', expr()));
+ _cacheConst(() => runtimeCall('const(#)', expr()));
/// Returns a new expression, which can be be used safely *once* on the
/// left hand side, and *once* on the right side of an assignment.
@@ -5193,7 +5198,7 @@
visitPrefixedIdentifier(PrefixedIdentifier node) {
if (_isDeferredLoadLibrary(node.prefix, node.identifier)) {
// We are tearing off "loadLibrary" on a library prefix.
- return _callHelper('loadLibrary');
+ return runtimeCall('loadLibrary');
}
if (isLibraryPrefix(node.prefix)) {
@@ -5277,7 +5282,7 @@
var jsName = _emitMemberName(memberName,
type: receiverType, isStatic: isStatic, element: accessor);
if (isDynamicInvoke(receiver)) {
- return _callHelper(
+ return runtimeCall(
'dload$_replSuffix(#, #)', [_visitExpression(receiver), jsName]);
}
@@ -5295,9 +5300,9 @@
JS.Expression result;
if (_isObjectMemberCall(receiver, memberName)) {
if (_isObjectMethod(memberName)) {
- result = _callHelper('bind(#, #)', [jsTarget, jsName]);
+ result = runtimeCall('bind(#, #)', [jsTarget, jsName]);
} else {
- result = _callHelper('#(#)', [memberName, jsTarget]);
+ result = runtimeCall('#(#)', [memberName, jsTarget]);
}
} else if (accessor is MethodElement &&
_reifyTearoff(accessor, accessNode)) {
@@ -5306,10 +5311,10 @@
_emitTargetAccess(jsTarget, jsName, accessor, memberId),
accessor.type);
} else if (isSuper) {
- result = _callHelper('bind(this, #, #)',
+ result = runtimeCall('bind(this, #, #)',
[jsName, _emitTargetAccess(jsTarget, jsName, accessor, memberId)]);
} else {
- result = _callHelper('bind(#, #)', [jsTarget, jsName]);
+ result = runtimeCall('bind(#, #)', [jsTarget, jsName]);
}
} else {
result = _emitTargetAccess(jsTarget, jsName, accessor, memberId);
@@ -5318,7 +5323,7 @@
var typeArgs = _getTypeArgs(accessor, resultType);
return typeArgs == null
? result
- : _callHelper('gbind(#, #)', [result, typeArgs]);
+ : runtimeCall('gbind(#, #)', [result, typeArgs]);
}
bool _reifyTearoff(ExecutableElement element, Expression node) {
@@ -5353,10 +5358,10 @@
// dynamic dispatch
var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name];
if (dynamicHelper != null) {
- return _callHelper('$dynamicHelper(#, #)',
+ return runtimeCall('$dynamicHelper(#, #)',
[_visitExpression(target), _visitExpressionList(args)]);
} else {
- return _callHelper('dsend(#, #, [#])',
+ return runtimeCall('dsend(#, #, [#])',
[_visitExpression(target), memberName, _visitExpressionList(args)]);
}
}
@@ -5408,12 +5413,12 @@
@override
JS.Expression visitThrowExpression(ThrowExpression node) {
- return _callHelper('throw(#)', _visitExpression(node.expression));
+ return runtimeCall('throw(#)', _visitExpression(node.expression));
}
@override
JS.Expression visitRethrowExpression(RethrowExpression node) {
- return _callHelper('rethrow(#)', _visitExpression(_catchParameter));
+ return runtimeCall('rethrow(#)', _visitExpression(_catchParameter));
}
/// Visits a statement, and ensures the resulting AST handles block scope
@@ -5627,7 +5632,7 @@
vars.add(stackVar.name);
body.add(js.statement('let # = #.stackTrace(#);', [
_emitVariableDef(stackVar),
- _runtimeModule,
+ runtimeModule,
_emitSimpleIdentifier(name)
]));
}
@@ -5737,7 +5742,7 @@
DartType elementType, List<JS.Expression> elements) {
// dart.constList helper internally depends on _interceptors.JSArray.
_declareBeforeUse(_jsArray);
- return _callHelper('constList([#], #)', [elements, _emitType(elementType)]);
+ return runtimeCall('constList([#], #)', [elements, _emitType(elementType)]);
}
JS.Expression _emitList(DartType itemType, List<JS.Expression> items) {
@@ -5773,7 +5778,7 @@
return js.call('new #.from(#)', [mapType, emitEntries()]);
}
var typeArgs = type.typeArguments;
- return _cacheConst(() => _callHelper('constMap(#, #, #)',
+ return _cacheConst(() => runtimeCall('constMap(#, #, #)',
[_emitType(typeArgs[0]), _emitType(typeArgs[1]), emitEntries()]));
}
@@ -5826,7 +5831,7 @@
}
}
return new JS.TaggedTemplate(
- _callHelper('str'), new JS.TemplateString(strings, interpolations));
+ runtimeCall('str'), new JS.TemplateString(strings, interpolations));
}
@override
@@ -5977,10 +5982,10 @@
}
if (node is AsExpression && CoercionReifier.isImplicit(node)) {
assert(node.staticType == types.boolType);
- return _callHelper('dtest(#)', _visitExpression(node.expression));
+ return runtimeCall('dtest(#)', _visitExpression(node.expression));
}
var result = _visitExpression(node);
- if (isNullable(node)) result = _callHelper('test(#)', result);
+ if (isNullable(node)) result = runtimeCall('test(#)', result);
return result;
}
@@ -6277,27 +6282,7 @@
return DynamicTypeImpl.instance;
}
- JS.Expression _callHelper(String code, [args]) {
- if (args is List) {
- args.insert(0, _runtimeModule);
- } else if (args != null) {
- args = [_runtimeModule, args];
- } else {
- args = _runtimeModule;
- }
- return js.call('#.$code', args);
- }
-
- JS.Statement _callHelperStatement(String code, args) {
- if (args is List) {
- args.insert(0, _runtimeModule);
- } else {
- args = [_runtimeModule, args];
- }
- return js.statement('#.$code', args);
- }
-
- JS.Expression _throwUnsafe(String message) => _callHelper(
+ JS.Expression _throwUnsafe(String message) => runtimeCall(
'throw(Error(#))', js.escapedString("compile error: $message"));
JS.Node _unreachable(AstNode node) {
diff --git a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
index c06fbec..3b3ad50 100644
--- a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/analyzer.dart'
show AnalysisError, CompilationUnit, ErrorSeverity;
+import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/element/element.dart' show LibraryElement;
import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
import 'package:analyzer/file_system/physical_file_system.dart'
@@ -112,16 +113,19 @@
context.resultProvider =
new InputPackagesResultProvider(context, summaryData);
}
- options.declaredVariables.forEach(context.declaredVariables.define);
- context.declaredVariables
- ..define('dart.isVM', 'false')
+ var variables = <String, String>{};
+ variables.addAll(options.declaredVariables);
+ variables.addAll({
+ 'dart.isVM': 'false',
// TODO(vsm): Should this be hardcoded?
- ..define('dart.library.html', 'true')
- ..define('dart.library.io', 'false')
- ..define('dart.library.ui', 'false')
- ..define('dart.library.mirrors', 'false')
- ..define('dart.library.isolate', 'false');
+ 'dart.library.html': 'true',
+ 'dart.library.io': 'false',
+ 'dart.library.ui': 'false',
+ 'dart.library.mirrors': 'false',
+ 'dart.library.isolate': 'false'
+ });
+ context.declaredVariables = new DeclaredVariables.fromMap(variables);
if (!context.analysisOptions.strongMode) {
throw new ArgumentError('AnalysisContext must be strong mode');
}
@@ -260,6 +264,9 @@
/// Whether to preserve metdata only accessible via mirrors.
final bool emitMetadata;
+ // Whether to enable assertions.
+ final bool enableAsserts;
+
/// Whether to force compilation of code with static errors.
final bool unsafeForceCompile;
@@ -287,6 +294,7 @@
this.unsafeForceCompile: false,
this.replCompile: false,
this.emitMetadata: false,
+ this.enableAsserts: true,
this.closure: false,
this.bazelMapping: const {},
this.summaryOutPath});
@@ -300,6 +308,7 @@
unsafeForceCompile = args['unsafe-force-compile'] as bool,
replCompile = args['repl-compile'] as bool,
emitMetadata = args['emit-metadata'] as bool,
+ enableAsserts = args['enable-asserts'] as bool,
closure = args['closure-experimental'] as bool,
bazelMapping =
_parseBazelMappings(args['bazel-mapping'] as List<String>),
@@ -323,22 +332,19 @@
..addFlag('inline-source-map',
help: 'emit source mapping inline', defaultsTo: false, hide: hide)
..addFlag('emit-metadata',
- help: 'emit metadata annotations queriable via mirrors',
- defaultsTo: false,
- hide: hide)
+ help: 'emit metadata annotations queriable via mirrors', hide: hide)
+ ..addFlag('enable-asserts',
+ help: 'enable assertions', defaultsTo: true, hide: hide)
..addFlag('closure-experimental',
help: 'emit Closure Compiler-friendly code (experimental)',
- defaultsTo: false,
hide: hide)
..addFlag('unsafe-force-compile',
help: 'Compile code even if it has errors. ಠ_ಠ\n'
'This has undefined behavior!',
- defaultsTo: false,
hide: hide)
..addFlag('repl-compile',
help: 'Compile code more permissively when in REPL mode\n'
'allowing access to private members across library boundaries.',
- defaultsTo: false,
hide: hide)
..addMultiOption('bazel-mapping',
help:
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 165028a..10e9782 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -19,6 +19,9 @@
/// This lets DDC use the setter method's return value directly.
final List<JS.Identifier> _operatorSetResultStack = [];
+ JS.Identifier runtimeModule;
+ final namedArgumentTemp = new JS.TemporaryId('opts');
+
/// When compiling the body of a `operator []=` method, this will be non-null
/// and will indicate the the value that should be returned from any `return;`
/// statements.
@@ -87,4 +90,36 @@
}
return value != null ? value.toReturn() : new JS.Return();
}
+
+ /// Prepends the `dart.` and then uses [js.call] to parse the specified JS
+ /// [code] template, passing [args].
+ ///
+ /// For example:
+ ///
+ /// runtimeCall('asInt(#)', expr)
+ ///
+ /// Generates a JS AST representing:
+ ///
+ /// dart.asInt(<expr>)
+ ///
+ JS.Expression runtimeCall(String code, [args]) {
+ if (args != null) {
+ var newArgs = <Object>[runtimeModule];
+ if (args is Iterable) {
+ newArgs.addAll(args);
+ } else {
+ newArgs.add(args);
+ }
+ args = newArgs;
+ } else {
+ args = runtimeModule;
+ }
+ return js.call('#.$code', args);
+ }
+
+ /// Calls [runtimeCall] and uses `toStatement()` to convert the resulting
+ /// expression into a statement.
+ JS.Statement runtimeStatement(String code, [args]) {
+ return runtimeCall(code, args).toStatement();
+ }
}
diff --git a/pkg/dev_compiler/lib/src/compiler/type_utilities.dart b/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
index 23b34e7d..c33df46 100644
--- a/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
+++ b/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
@@ -193,7 +193,7 @@
/// Given a type [type], and a JS expression [typeRep] which implements it,
/// add the type and its representation to the table, returning an
/// expression which implements the type (but which caches the value).
- JS.Expression nameType(InterfaceType type, JS.Expression typeRep) {
+ JS.Expression nameType(ParameterizedType type, JS.Expression typeRep) {
if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
return typeRep;
}
diff --git a/pkg/dev_compiler/lib/src/js_ast/template.dart b/pkg/dev_compiler/lib/src/js_ast/template.dart
index c52a3eb..5a06359 100644
--- a/pkg/dev_compiler/lib/src/js_ast/template.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/template.dart
@@ -154,14 +154,14 @@
static Instantiator<T> same<T extends Node>(T node) => (arguments) => node;
static Null makeNull(arguments) => null;
- Instantiator visit(Node node) {
+ Instantiator visit<T extends Node>(T node) {
if (forceCopy || analysis.containsInterpolatedNodes(node)) {
return node.accept(this);
}
- return same(node);
+ return same<T>(node);
}
- Instantiator visitNullable(Node node) {
+ Instantiator visitNullable<T extends Node>(T node) {
return node == null ? makeNull : visit(node);
}
@@ -498,7 +498,7 @@
node.keyword, declarationMakers.map((m) => m(a)).toList());
}
- Instantiator visitAssignment(Assignment node) {
+ Instantiator<Expression> visitAssignment(Assignment node) {
Instantiator makeLeftHandSide = visit(node.leftHandSide);
String op = node.op;
Instantiator makeValue = visitNullable(node.value);
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index a3be2ea..f19890f 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -106,11 +106,13 @@
Future<CompilerResult> _compile(List<String> args,
{fe.InitializedCompilerState compilerState}) async {
+ // TODO(jmesserly): refactor options to share code with dartdevc CLI.
var argParser = new ArgParser(allowTrailingOptions: true)
..addFlag('help',
abbr: 'h', help: 'Display this message.', negatable: false)
..addOption('out', abbr: 'o', help: 'Output file (required).')
..addOption('packages', help: 'The package spec file to use.')
+ // TODO(jmesserly): add verbose help to show hidden options
..addOption('dart-sdk-summary',
help: 'The path to the Dart SDK summary file.', hide: true)
..addMultiOption('summary',
@@ -120,7 +122,11 @@
..addFlag('source-map', help: 'emit source mapping', defaultsTo: true)
..addMultiOption('summary-input-dir')
..addOption('custom-app-scheme', defaultsTo: 'org-dartlang-app')
+ ..addFlag('emit-metadata',
+ help: '(deprecated) enables dart:mirrors for this module', hide: true)
+ ..addFlag('enable-asserts', help: 'enable assertions', defaultsTo: true)
// Ignore dart2js options that we don't support in DDC.
+ // TODO(jmesserly): add ignore-unrecognized-flag support.
..addFlag('enable-enum', hide: true)
..addFlag('experimental-trust-js-interop-type-annotations', hide: true)
..addFlag('trust-type-annotations', hide: true)
@@ -200,8 +206,15 @@
// TODO(jmesserly): Save .dill file so other modules can link in this one.
//await writeComponentToBinary(component, output);
- var jsModule = compileToJSModule(
- result.component, result.inputSummaries, summaryUris, declaredVariables);
+ var component = result.component;
+
+ var compiler = new ProgramCompiler(component,
+ declaredVariables: declaredVariables,
+ emitMetadata: argResults['emit-metadata'] as bool,
+ enableAsserts: argResults['enable-asserts'] as bool);
+ var jsModule =
+ compiler.emitProgram(component, result.inputSummaries, summaryUris);
+
var jsCode = jsProgramToCode(jsModule, moduleFormat,
buildSourceMap: argResults['source-map'] as bool,
jsUrl: path.toUri(output).toString(),
@@ -218,12 +231,6 @@
return new CompilerResult(compilerState, true);
}
-JS.Program compileToJSModule(Component p, List<Component> summaries,
- List<Uri> summaryUris, Map<String, String> declaredVariables) {
- var compiler = new ProgramCompiler(p, declaredVariables: declaredVariables);
- return compiler.emitProgram(p, summaries, summaryUris);
-}
-
/// The output of compiling a JavaScript module in a particular format.
/// This was copied from module_compiler.dart class "JSModuleCode".
class JSCode {
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index a6e12f2..7b95975 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -66,9 +66,6 @@
JS.Identifier _extensionSymbolsModule;
final _extensionSymbols = new Map<String, JS.TemporaryId>();
- JS.Identifier _runtimeModule;
- final namedArgumentTemp = new JS.TemporaryId('opts');
-
Set<Class> _pendingClasses;
/// Temporary variables mapped to their corresponding JavaScript variable.
@@ -134,6 +131,7 @@
final _superHelpers = new Map<String, JS.Method>();
final bool emitMetadata;
+ final bool enableAsserts;
final bool replCompile;
final Map<String, String> declaredVariables;
@@ -206,9 +204,9 @@
final NullableInference _nullableInference;
factory ProgramCompiler(Component component,
- // TODO(jmesserly): emitMetadata should default to false
- {bool emitMetadata: true,
+ {bool emitMetadata: false,
bool replCompile: false,
+ bool enableAsserts: true,
Map<String, String> declaredVariables: const {}}) {
var nativeTypes = new NativeTypeSet(component);
var types = new TypeSchemaEnvironment(
@@ -216,12 +214,16 @@
return new ProgramCompiler._(
nativeTypes, new JSTypeRep(types, nativeTypes.sdk),
emitMetadata: emitMetadata,
+ enableAsserts: enableAsserts,
replCompile: replCompile,
declaredVariables: declaredVariables);
}
ProgramCompiler._(NativeTypeSet nativeTypes, this._typeRep,
- {this.emitMetadata, this.replCompile, this.declaredVariables})
+ {this.emitMetadata,
+ this.enableAsserts,
+ this.replCompile,
+ this.declaredVariables})
: _extensionTypes = nativeTypes,
types = _typeRep.types,
coreTypes = nativeTypes.coreTypes,
@@ -276,15 +278,15 @@
if (ddcRuntime != null) {
// Don't allow these to be renamed when we're building the SDK.
// There is JS code in dart:* that depends on their names.
- _runtimeModule = new JS.Identifier('dart');
+ runtimeModule = new JS.Identifier('dart');
_extensionSymbolsModule = new JS.Identifier('dartx');
_nullableInference.allowNotNullDeclarations = true;
} else {
// Otherwise allow these to be renamed so users can write them.
- _runtimeModule = new JS.TemporaryId('dart');
+ runtimeModule = new JS.TemporaryId('dart');
_extensionSymbolsModule = new JS.TemporaryId('dartx');
}
- _typeTable = new TypeTable(_runtimeModule);
+ _typeTable = new TypeTable(runtimeModule);
// Initialize our library variables.
var items = <JS.ModuleItem>[];
@@ -299,7 +301,7 @@
for (var library in libraries) {
var libraryTemp = library == ddcRuntime
- ? _runtimeModule
+ ? runtimeModule
: new JS.TemporaryId(jsLibraryName(library));
_libraries[library] = libraryTemp;
emitLibrary(libraryTemp);
@@ -421,7 +423,7 @@
var imports =
libraries.map((l) => new JS.NameSpecifier(_imports[l])).toList();
if (module == coreModuleName) {
- imports.add(new JS.NameSpecifier(_runtimeModule));
+ imports.add(new JS.NameSpecifier(runtimeModule));
imports.add(new JS.NameSpecifier(_extensionSymbolsModule));
}
@@ -569,8 +571,8 @@
var jsPeerNames = _extensionTypes.getNativePeers(c);
if (jsPeerNames.length == 1 && c.typeParameters.isNotEmpty) {
// Special handling for JSArray<E>
- body.add(_callHelperStatement('setExtensionBaseClass(#, #.global.#);',
- [className, _runtimeModule, jsPeerNames[0]]));
+ body.add(runtimeStatement('setExtensionBaseClass(#, #.global.#)',
+ [className, runtimeModule, jsPeerNames[0]]));
}
var finishGenericTypeTest = _emitClassTypeTests(c, className, body);
@@ -620,7 +622,7 @@
genericArgs.add(js.call('(#) => { #; }', [jsFormals, deferredBaseClass]));
}
- var genericCall = _callHelper('generic(#)', [genericArgs]);
+ var genericCall = runtimeCall('generic(#)', [genericArgs]);
var genericName = _emitTopLevelNameNoInterop(c, suffix: '\$');
return js.statement('{ # = #; # = #(); }',
@@ -719,13 +721,16 @@
mixinCtor = js.statement('#.#.call(this);', [
emitClassRef(mixin),
_usesMixinNew(mixin.classNode)
- ? _callHelper('mixinNew')
+ ? runtimeCall('mixinNew')
: _constructorName('')
]);
}
for (var ctor in superclass.constructors) {
+ var savedUri = _currentUri;
+ _currentUri = ctor.enclosingClass.fileUri;
var jsParams = _emitFormalParameters(ctor.function);
+ _currentUri = savedUri;
var ctorBody = <JS.Statement>[];
if (mixinCtor != null) ctorBody.add(mixinCtor);
var name = ctor.name.name;
@@ -742,7 +747,7 @@
// Unroll mixins.
if (shouldDefer(supertype)) {
- deferredSupertypes.add(_callHelperStatement('setBaseClass(#, #)', [
+ deferredSupertypes.add(runtimeStatement('setBaseClass(#, #)', [
getBaseClass(isMixinAliasClass(c) ? 0 : mixins.length),
emitDeferredType(supertype),
]));
@@ -764,8 +769,8 @@
var mixinClass = deferMixin ? emitDeferredType(m) : emitClassRef(m);
var classExpr = deferMixin ? getBaseClass(0) : className;
- mixinBody.add(
- _callHelperStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
+ mixinBody
+ .add(runtimeStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
if (methods.isNotEmpty) {
// However we may need to add some methods to this class that call
@@ -774,7 +779,7 @@
// We do this with the following pattern:
//
// mixinMembers(C, class C$ extends M { <methods> });
- mixinBody.add(_callHelperStatement('mixinMembers(#, #)', [
+ mixinBody.add(runtimeStatement('mixinMembers(#, #)', [
classExpr,
new JS.ClassExpression(
new JS.TemporaryId(getLocalClassName(c)), mixinClass, methods)
@@ -809,11 +814,11 @@
hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(m.classNode);
if (shouldDefer(m)) {
- deferredSupertypes.add(_callHelperStatement('mixinMembers(#, #)',
+ deferredSupertypes.add(runtimeStatement('mixinMembers(#, #)',
[getBaseClass(mixins.length - i), emitDeferredType(m)]));
} else {
- body.add(_callHelperStatement(
- 'mixinMembers(#, #)', [mixinId, emitClassRef(m)]));
+ body.add(
+ runtimeStatement('mixinMembers(#, #)', [mixinId, emitClassRef(m)]));
}
baseClass = mixinId;
@@ -848,7 +853,7 @@
body.add(
js.statement('(#[#] = function() { # }).prototype = #.prototype;', [
className,
- _callHelper('mixinNew'),
+ runtimeCall('mixinNew'),
[_initializeFields(fields)],
className
]));
@@ -870,7 +875,7 @@
case 'Future':
case 'Stream':
case 'StreamSubscription':
- return _callHelper('is' + interface.name);
+ return runtimeCall('is' + interface.name);
}
}
return null;
@@ -908,13 +913,13 @@
' if (typeof o == "string" || o == null) return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_String(o) {'
' if (typeof o == "string" || o == null) return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
if (c == coreTypes.functionClass) {
@@ -926,13 +931,13 @@
' if (typeof o == "function" || o == null) return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_String(o) {'
' if (typeof o == "function" || o == null) return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
if (c == coreTypes.intClass) {
@@ -947,14 +952,14 @@
' return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_int(o) {'
' if ((typeof o == "number" && Math.floor(o) == o) || o == null)'
' return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
if (c == coreTypes.nullClass) {
@@ -965,13 +970,13 @@
' if (o == null) return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_Null(o) {'
' if (o == null) return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
if (c == coreTypes.numClass || c == coreTypes.doubleClass) {
@@ -983,13 +988,13 @@
' if (typeof o == "number" || o == null) return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_num(o) {'
' if (typeof o == "number" || o == null) return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
if (c == coreTypes.boolClass) {
@@ -1001,13 +1006,13 @@
' if (o === true || o === false || o == null) return o;'
' return #.as(o, #, false);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
body.add(js.statement(
'#._check = function check_bool(o) {'
' if (o === true || o === false || o == null) return o;'
' return #.as(o, #, true);'
'}',
- [className, _runtimeModule, className]));
+ [className, runtimeModule, className]));
return null;
}
}
@@ -1029,18 +1034,18 @@
if (o == null || #.is(o) || #.is(o)) return o;
return #.as(o, this, false);
}
- ''', [className, typeT, futureOfT, _runtimeModule]));
+ ''', [className, typeT, futureOfT, runtimeModule]));
body.add(js.statement('''
#._check = function check_FutureOr(o) {
if (o == null || #.is(o) || #.is(o)) return o;
return #.as(o, this, true);
}
- ''', [className, typeT, futureOfT, _runtimeModule]));
+ ''', [className, typeT, futureOfT, runtimeModule]));
return null;
}
}
- body.add(_callHelperStatement('addTypeTests(#);', [className]));
+ body.add(runtimeStatement('addTypeTests(#)', [className]));
if (c.typeParameters.isEmpty) return null;
@@ -1065,8 +1070,7 @@
// Return this `addTypeTests` call so we can emit it outside of the generic
// type parameter scope.
- return _callHelperStatement(
- 'addTypeTests(#, #);', [defaultInst, isClassSymbol]);
+ return runtimeStatement('addTypeTests(#, #)', [defaultInst, isClassSymbol]);
}
void _emitSymbols(Iterable<JS.TemporaryId> vars, List<JS.ModuleItem> body) {
@@ -1112,7 +1116,7 @@
if (emitMetadata && metadata.isNotEmpty) {
body.add(js.statement('#[#.metadata] = #;', [
className,
- _runtimeModule,
+ runtimeModule,
_arrowFunctionWithLetScope(() => new JS.ArrayInitializer(
metadata.map(_instantiateAnnotation).toList()))
]));
@@ -1141,7 +1145,7 @@
.map((e) => _propertyName(JS.memberNameForDartMember(e)))
.toList();
body.add(js.statement('#.#(#, #);', [
- _runtimeModule,
+ runtimeModule,
helperName,
className,
new JS.ArrayInitializer(names, multiline: names.length > 4)
@@ -1162,7 +1166,7 @@
if (c.implementedTypes.isNotEmpty) {
body.add(js.statement('#[#.implements] = () => [#];', [
className,
- _runtimeModule,
+ runtimeModule,
c.implementedTypes.map((i) => _emitType(i.asInterfaceType))
]));
}
@@ -1173,10 +1177,10 @@
if (!name.startsWith('Static')) {
var proto = c == coreTypes.objectClass
? js.call('Object.create(null)')
- : _callHelper('get${name}s(#.__proto__)', [className]);
+ : runtimeCall('get${name}s(#.__proto__)', [className]);
elements.insert(0, new JS.Property(_propertyName('__proto__'), proto));
}
- body.add(_callHelperStatement('set${name}Signature(#, () => #)', [
+ body.add(runtimeStatement('set${name}Signature(#, () => #)', [
className,
new JS.ObjectInitializer(elements, multiline: elements.length > 1)
]));
@@ -1297,7 +1301,7 @@
// Add static property dart._runtimeType to Object.
// All other Dart classes will (statically) inherit this property.
if (c == coreTypes.objectClass) {
- body.add(_callHelperStatement('tagComputed(#, () => #.#);',
+ body.add(runtimeStatement('lazyFn(#, () => #.#)',
[className, emitLibraryName(coreTypes.coreLibrary), 'Type']));
}
@@ -1315,7 +1319,7 @@
annotations.map(_instantiateAnnotation).toList()));
_currentUri = savedUri;
}
- return _callHelper(
+ return runtimeCall(
field.isFinal ? 'finalFieldType(#)' : 'fieldType(#)', [args]);
}
@@ -1540,7 +1544,7 @@
if (expr == null) return null;
var jsExpr = _visitExpression(expr);
if (!isNullable(expr)) return jsExpr;
- return _callHelper('notNull(#)', jsExpr);
+ return runtimeCall('notNull(#)', jsExpr);
}
/// If the class has only factory constructors, and it can be mixed in,
@@ -1562,7 +1566,7 @@
var args = [className, name, value];
if (name is JS.LiteralString &&
JS.invalidStaticFieldName(name.valueWithoutQuotes)) {
- return _callHelper('defineValue(#, #, #)', args);
+ return runtimeCall('defineValue(#, #, #)', args);
}
return js.call('#.# = #', args);
}
@@ -1581,7 +1585,7 @@
new JS.Method(_propertyName('constructor'), js.fun(r'''function() {
throw Error("use `new " + #.typeName(#.getReifiedType(this)) +
".new(...)` to create a Dart object");
- }''', [_runtimeModule, _runtimeModule])));
+ }''', [runtimeModule, runtimeModule])));
}
for (var m in c.fields) {
@@ -1624,9 +1628,10 @@
}
}
- for (Member m in _classProperties.mockMembers.values) {
- _addMockMembers(m, c, jsMethods);
- }
+ _classProperties.mockMembers.forEach((String name, Member member) {
+ jsMethods
+ .add(_implementMockMember(member, c, isSetter: name.endsWith('=')));
+ });
// If the type doesn't have an `iterator`, but claims to implement Iterable,
// we inject the adaptor method here, as it's less code size to put the
@@ -1818,49 +1823,51 @@
///
/// Same technique is applied if interface I has fields, and C doesn't declare
/// neither the fields nor the corresponding getters and setters.
- void _addMockMembers(Member member, Class c, List<JS.Method> jsMethods) {
+ JS.Method _implementMockMember(Member member, Class c, {bool isSetter}) {
JS.Method implementMockMember(
- List<TypeParameter> typeParameters,
+ ProcedureKind procedureKind, DartType returnType,
+ [List<TypeParameter> typeParameters,
List<JS.Parameter> positionalParameters,
- List<VariableDeclaration> namedParameters,
- int requiredParameterCount,
- ProcedureKind mockMemberKind,
- DartType returnType) {
- assert(mockMemberKind != ProcedureKind.Factory);
+ List<VariableDeclaration> namedParameters]) {
+ assert(procedureKind != ProcedureKind.Factory);
var invocationProps = <JS.Property>[];
addProperty(String name, JS.Expression value) {
invocationProps.add(new JS.Property(js.string(name), value));
}
- var args = positionalParameters;
- var typeParams = _emitTypeFormals(typeParameters);
- var fnArgs = new List<JS.Parameter>.from(typeParams)..addAll(args);
-
+ var typeParams = _emitTypeFormals(typeParameters ?? []);
+ var fnArgs = new List<JS.Parameter>.from(typeParams);
JS.Expression positionalArgs;
- List<JS.Statement> optionalArgInit = [];
- if (positionalParameters.length != requiredParameterCount) {
- positionalArgs = new JS.TemporaryId('args');
- optionalArgInit.add(js.statement('let # = [#]',
- [positionalArgs, args.take(requiredParameterCount)]));
- optionalArgInit.addAll(args.skip(requiredParameterCount).map((p) => js
- .statement('if (# !== void 0) #.push(#)', [p, positionalArgs, p])));
+ if (procedureKind == ProcedureKind.Getter) {
+ addProperty('isGetter', js.boolean(true));
+ positionalArgs = new JS.ArrayInitializer([]);
+ } else if (procedureKind == ProcedureKind.Setter) {
+ addProperty('isSetter', js.boolean(true));
+ var valueArg = new JS.TemporaryId('value');
+ positionalArgs = new JS.ArrayInitializer([valueArg]);
+ fnArgs.add(valueArg);
} else {
- positionalArgs = new JS.ArrayInitializer(args);
- if (namedParameters.isNotEmpty) {
- fnArgs.add(namedArgumentTemp);
- addProperty('namedArguments', namedArgumentTemp);
- }
- }
-
- if (mockMemberKind != ProcedureKind.Getter &&
- mockMemberKind != ProcedureKind.Setter) {
addProperty('isMethod', js.boolean(true));
- } else {
- if (mockMemberKind == ProcedureKind.Getter) {
- addProperty('isGetter', js.boolean(true));
- } else if (mockMemberKind == ProcedureKind.Setter) {
- addProperty('isSetter', js.boolean(true));
+ if (namedParameters.isNotEmpty) {
+ // Named parameters need to be emitted in the correct position (after
+ // positional arguments) so we can detect them reliably.
+ addProperty('namedArguments', namedArgumentTemp);
+ positionalArgs = new JS.ArrayInitializer(positionalParameters);
+ fnArgs.addAll(positionalParameters);
+ fnArgs.add(namedArgumentTemp);
+ } else {
+ // In case we have optional parameters, we need to use rest args,
+ // because sometimes mocks want to detect whether optional arguments
+ // were passed, and this does not work reliably with undefined (should
+ // not normally appear in DDC, but it can result from JS interop).
+ //
+ // TODO(jmesserly): perhaps we need to use rest args or destructuring
+ // to get reliable optional argument passing in other scenarios? It
+ // doesn't seem to occur outside of tests, perhaps due to the
+ // combination of mockito and protobufs.
+ positionalArgs = new JS.TemporaryId('args');
+ fnArgs.add(new JS.RestParameter(positionalArgs));
}
}
@@ -1870,7 +1877,7 @@
var fnBody =
js.call('this.noSuchMethod(new #.InvocationImpl.new(#, #, #))', [
- _runtimeModule,
+ runtimeModule,
_declareMemberName(member),
positionalArgs,
new JS.ObjectInitializer(invocationProps)
@@ -1881,36 +1888,34 @@
fnBody = js.call('#._check(#)', [_emitType(returnType), fnBody]);
}
- var fn = new JS.Fun(
- fnArgs, js.block('{ #; return #; }', [optionalArgInit, fnBody]),
+ var fn = new JS.Fun(fnArgs, fnBody.toReturn().toBlock(),
typeParams: typeParams);
return new JS.Method(
_declareMemberName(member,
useExtension: _extensionTypes.isNativeClass(c)),
fn,
- isGetter: mockMemberKind == ProcedureKind.Getter,
- isSetter: mockMemberKind == ProcedureKind.Setter,
+ isGetter: procedureKind == ProcedureKind.Getter,
+ isSetter: procedureKind == ProcedureKind.Setter,
isStatic: false);
}
if (member is Field) {
- jsMethods.add(implementMockMember(
- [], [], [], 0, ProcedureKind.Getter, member.type));
- if (!member.isFinal) {
- jsMethods.add(implementMockMember([], [new JS.TemporaryId('value')], [],
- 1, ProcedureKind.Setter, new VoidType()));
+ if (isSetter) {
+ return implementMockMember(ProcedureKind.Setter, new VoidType());
+ } else {
+ return implementMockMember(ProcedureKind.Getter, member.type);
}
} else {
var procedure = member as Procedure;
var f = procedure.function;
- jsMethods.add(implementMockMember(
+ assert(procedure.isSetter == isSetter);
+ return implementMockMember(
+ procedure.kind,
+ f.returnType,
f.typeParameters,
f.positionalParameters.map(_emitVariableRef).toList(),
- f.namedParameters,
- f.requiredParameterCount,
- procedure.kind,
- f.returnType));
+ f.namedParameters);
}
}
@@ -2044,7 +2049,7 @@
return new JS.Method(
js.call('Symbol.iterator'),
js.call('function() { return new #.JsIterator(this.#); }', [
- _runtimeModule,
+ runtimeModule,
_emitMemberName('iterator', type: iterable.asInterfaceType)
]) as JS.Fun);
}
@@ -2056,11 +2061,11 @@
Class c, String jsPeerName, List<JS.Statement> body) {
var className = _emitTopLevelName(c);
if (isPrimitiveType(c.rawType)) {
- body.add(_callHelperStatement(
- 'definePrimitiveHashCode(#.prototype)', className));
+ body.add(
+ runtimeStatement('definePrimitiveHashCode(#.prototype)', className));
}
- body.add(_callHelperStatement(
- 'registerExtension(#, #);', [js.string(jsPeerName), className]));
+ body.add(runtimeStatement(
+ 'registerExtension(#, #)', [js.string(jsPeerName), className]));
}
JS.Statement _emitJSType(Class c) {
@@ -2077,7 +2082,7 @@
void _emitTypedef(Typedef t) {
var savedUri = _currentUri;
_currentUri = t.fileUri;
- var body = _callHelper('typedef(#, () => #)',
+ var body = runtimeCall('typedef(#, () => #)',
[js.string(t.name, "'"), visitFunctionType(t.type)]);
JS.Statement result;
@@ -2151,7 +2156,7 @@
_currentUri = _currentLibrary.fileUri;
_currentUri = savedUri;
- return _callHelperStatement('defineLazy(#, { # });', [objExpr, accessors]);
+ return runtimeStatement('defineLazy(#, { # })', [objExpr, accessors]);
}
JS.Fun _emitStaticFieldInitializer(Field field) {
@@ -2446,7 +2451,7 @@
JS.PropertyAccess access;
for (var part in parts) {
access = new JS.PropertyAccess(
- access ?? _callHelper('global'), js.escapedString(part, "'"));
+ access ?? runtimeCall('global'), js.escapedString(part, "'"));
}
return access;
}
@@ -2464,7 +2469,7 @@
void _emitLibraryAccessors(Iterable<Procedure> accessors) {
if (accessors.isEmpty) return;
- _moduleItems.add(_callHelperStatement('copyProperties(#, { # });', [
+ _moduleItems.add(runtimeStatement('copyProperties(#, { # })', [
emitLibraryName(_currentLibrary),
accessors.map(_emitLibraryAccessor).toList()
]));
@@ -2499,7 +2504,11 @@
var nameExpr = _emitTopLevelName(p);
body.add(js.statement('# = #', [nameExpr, fn]));
- if (!isSdkInternalRuntime(_currentLibrary)) {
+ // Function types of top-level/static functions are only needed when
+ // dart:mirrors is enabled.
+ // TODO(jmesserly): do we even need this for mirrors, since statics are not
+ // commonly reflected on?
+ if (emitMetadata && _reifyFunctionType(p.function)) {
body.add(
_emitFunctionTagged(nameExpr, p.function.functionType, topLevel: true)
.toStatement());
@@ -2513,7 +2522,7 @@
{bool topLevel: false}) {
var lazy = topLevel && !_typeIsLoaded(type);
var typeRep = visitFunctionType(type, lazy: lazy);
- return _callHelper(lazy ? 'lazyFn(#, #)' : 'fn(#, #)', [fn, typeRep]);
+ return runtimeCall(lazy ? 'lazyFn(#, #)' : 'fn(#, #)', [fn, typeRep]);
}
bool _typeIsLoaded(DartType type) {
@@ -2537,7 +2546,7 @@
JS.Expression _emitInvalidNode(Node node, [String message = '']) {
if (message.isNotEmpty) message += ' ';
- return _callHelper('throwUnimplementedError(#)',
+ return runtimeCall('throwUnimplementedError(#)',
[js.escapedString('node <${node.runtimeType}> $message`$node`')]);
}
@@ -2548,13 +2557,13 @@
visitInvalidType(type) => defaultDartType(type);
@override
- visitDynamicType(type) => _callHelper('dynamic');
+ visitDynamicType(type) => runtimeCall('dynamic');
@override
- visitVoidType(type) => _callHelper('void');
+ visitVoidType(type) => runtimeCall('void');
@override
- visitBottomType(type) => _callHelper('bottom');
+ visitBottomType(type) => runtimeCall('bottom');
@override
visitInterfaceType(type, {bool lowerGeneric: false}) {
@@ -2575,12 +2584,12 @@
// Anonymous JS types do not have a corresponding concrete JS type so we
// have to use a helper to define them.
if (isJSAnonymousType(c)) {
- return _callHelper(
+ return runtimeCall(
'anonymousJSType(#)', js.escapedString(getLocalClassName(c)));
}
var jsName = _getJSNameWithoutGlobal(c);
if (jsName != null) {
- return _callHelper('lazyJSType(() => #, #)',
+ return runtimeCall('lazyJSType(() => #, #)',
[_emitJSInteropForGlobal(jsName), js.escapedString(jsName)]);
}
@@ -2674,7 +2683,7 @@
} else {
helperCall = 'fnType(#)';
}
- var typeRep = _callHelper(helperCall, [typeParts]);
+ var typeRep = runtimeCall(helperCall, [typeParts]);
return _cacheTypes
? _typeTable.nameFunctionType(type, typeRep, lazy: lazy)
: typeRep;
@@ -2896,7 +2905,7 @@
var gen = emitGeneratorFn((_) => [_asyncStarController]);
var returnType = _getExpectedReturnType(function, coreTypes.streamClass);
- return _callHelper('asyncStar(#, #)', [_emitType(returnType), gen]);
+ return runtimeCall('asyncStar(#, #)', [_emitType(returnType), gen]);
}
assert(function.asyncMarker == AsyncMarker.Async);
@@ -3023,7 +3032,7 @@
annotations.any(_nullableInference.isNullCheckAnnotation);
JS.Statement _nullParameterCheck(JS.Expression param) {
- var call = _callHelper('argumentError((#))', [param]);
+ var call = runtimeCall('argumentError((#))', [param]);
return js.statement('if (# == null) #;', [param, call]);
}
@@ -3049,7 +3058,7 @@
List<TypeParameter> typeFormals, List<JS.Statement> body) {
for (var t in typeFormals) {
if (t.isGenericCovariantImpl) {
- body.add(_callHelperStatement('checkTypeBound(#, #, #)', [
+ body.add(runtimeStatement('checkTypeBound(#, #, #)', [
_emitType(new TypeParameterType(t)),
_emitType(t.bound),
_propertyName(t.name)
@@ -3058,26 +3067,6 @@
}
}
- JS.Expression _callHelper(String code, [args]) {
- if (args is List) {
- args.insert(0, _runtimeModule);
- } else if (args != null) {
- args = [_runtimeModule, args];
- } else {
- args = _runtimeModule;
- }
- return js.call('#.$code', args);
- }
-
- JS.Statement _callHelperStatement(String code, args) {
- if (args is List) {
- args.insert(0, _runtimeModule);
- } else {
- args = [_runtimeModule, args];
- }
- return js.statement('#.$code', args);
- }
-
JS.Statement _visitStatement(Statement s) {
if (s == null) return null;
var result = s.accept(this) as JS.Statement;
@@ -3139,11 +3128,11 @@
if (node is AsExpression && node.isTypeError) {
assert(node.getStaticType(types) == types.boolType);
- return _callHelper('dtest(#)', _visitExpression(node.operand));
+ return runtimeCall('dtest(#)', _visitExpression(node.operand));
}
var result = _visitExpression(node);
- if (isNullable(node)) result = _callHelper('test(#)', result);
+ if (isNullable(node)) result = runtimeCall('test(#)', result);
return result;
}
@@ -3241,7 +3230,7 @@
@override
visitAssertStatement(AssertStatement node) {
- // TODO(jmesserly): only emit in checked mode.
+ if (!enableAsserts) return new JS.EmptyStatement();
var condition = node.condition;
var conditionType = condition.getStaticType(types);
var jsCondition = _visitExpression(condition);
@@ -3250,15 +3239,15 @@
if (conditionType is FunctionType &&
conditionType.requiredParameterCount == 0 &&
conditionType.returnType == boolType) {
- jsCondition = _callHelper('test(#())', jsCondition);
+ jsCondition = runtimeCall('test(#())', jsCondition);
} else if (conditionType != boolType) {
- jsCondition = _callHelper('dassert(#)', jsCondition);
+ jsCondition = runtimeCall('dassert(#)', jsCondition);
} else if (isNullable(condition)) {
- jsCondition = _callHelper('test(#)', jsCondition);
+ jsCondition = runtimeCall('test(#)', jsCondition);
}
return js.statement(' if (!#) #.assertFailed(#);', [
jsCondition,
- _runtimeModule,
+ runtimeModule,
node.message != null ? [_visitExpression(node.message)] : []
]);
}
@@ -3606,7 +3595,7 @@
vars.add(stackTrace.name);
body.add(js.statement('let # = #.stackTrace(#);', [
_emitVariableDef(stackTrace),
- _runtimeModule,
+ runtimeModule,
_emitVariableRef(name)
]));
}
@@ -3691,11 +3680,7 @@
} else {
declareFn = new JS.FunctionDeclaration(name, fn);
}
- // Function types of top-level/static functions are only needed when
- // dart:mirrors is enabled.
- // TODO(jmesserly): do we even need this for mirrors, since statics are not
- // commonly reflected on?
- if (emitMetadata && _reifyFunctionType(func)) {
+ if (_reifyFunctionType(func)) {
declareFn = new JS.Block([
declareFn,
_emitFunctionTagged(_emitVariableRef(node.variable), func.functionType)
@@ -3804,25 +3789,25 @@
// they can be hovered. Unfortunately this is not possible as Kernel does
// not store this data.
if (member == null) {
- return _callHelper('dload$_replSuffix(#, #)', [jsReceiver, jsName]);
+ return runtimeCall('dload$_replSuffix(#, #)', [jsReceiver, jsName]);
}
if (_isObjectMemberCall(receiver, memberName)) {
if (_isObjectMethod(memberName)) {
- return _callHelper('bind(#, #)', [jsReceiver, jsName]);
+ return runtimeCall('bind(#, #)', [jsReceiver, jsName]);
} else {
- return _callHelper('#(#)', [memberName, jsReceiver]);
+ return runtimeCall('#(#)', [memberName, jsReceiver]);
}
} else if (_reifyTearoff(member)) {
- return _callHelper('bind(#, #)', [jsReceiver, jsName]);
+ return runtimeCall('bind(#, #)', [jsReceiver, jsName]);
} else {
return new JS.PropertyAccess(jsReceiver, jsName);
}
}
- // TODO(jmesserly): remove this. Instead handle REPL private name lookups in
- // _emitMemberName (by using `dart.privateName` if we're in REPL mode,
- // refactored from the current `dart._dhelperRepl`).
+ // TODO(jmesserly): can we encapsulate REPL name lookups and remove this?
+ // _emitMemberName would be a nice place to handle it, but we don't have
+ // access to the target expression there (needed for `dart.replNameLookup`).
String get _replSuffix => replCompile ? 'Repl' : '';
JS.Expression _emitPropertySet(
@@ -3835,7 +3820,7 @@
var jsValue = _visitExpression(value);
if (member == null) {
- return _callHelper(
+ return runtimeCall(
'dput$_replSuffix(#, #, #)', [jsReceiver, jsName, jsValue]);
}
return js.call('#.# = #', [jsReceiver, jsName, jsValue]);
@@ -3846,7 +3831,7 @@
var target = node.interfaceTarget;
var jsTarget = _emitSuperTarget(target);
if (_reifyTearoff(target)) {
- return _callHelper('bind(this, #, #)', [jsTarget.selector, jsTarget]);
+ return runtimeCall('bind(this, #, #)', [jsTarget.selector, jsTarget]);
}
return jsTarget;
}
@@ -3924,7 +3909,7 @@
}
if (_isObjectMemberCall(receiver, name)) {
assert(arguments.types.isEmpty); // Object methods don't take type args.
- return _callHelper('#(#, #)', [name, jsReceiver, args]);
+ return runtimeCall('#(#, #)', [name, jsReceiver, args]);
}
// TODO(jmesserly): remove when Kernel desugars this for us.
// Handle `o.m(a)` where `o.m` is a getter returning a class with `call`.
@@ -3972,7 +3957,7 @@
jsCode += ', [#])';
}
- return _callHelper(jsCode, jsArgs);
+ return runtimeCall(jsCode, jsArgs);
}
bool _isDirectCallable(DartType t) =>
@@ -4269,7 +4254,7 @@
// a measurable performance effect (possibly the helper is simple enough to
// be inlined).
if (isNullable(left)) {
- return _callHelper(
+ return runtimeCall(
'equals(#, #)', [_visitExpression(left), _visitExpression(right)]);
}
@@ -4296,10 +4281,10 @@
// dynamic dispatch
var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name];
if (dynamicHelper != null) {
- return _callHelper('$dynamicHelper(#, #)',
+ return runtimeCall('$dynamicHelper(#, #)',
[_visitExpression(receiver), _visitExpressionList(args)]);
} else {
- return _callHelper('dsend(#, #, [#])', [
+ return runtimeCall('dsend(#, #, [#])', [
_visitExpression(receiver),
memberName,
_visitExpressionList(args)
@@ -4605,7 +4590,7 @@
{bool negated = false}) {
if (args.length != 2) {
// Shouldn't happen in typechecked code
- return _callHelper(
+ return runtimeCall(
'throw(Error("compile error: calls to `identical` require 2 args")');
}
var left = args[0];
@@ -4799,7 +4784,7 @@
}
if (expectString) strings.add('');
return new JS.TaggedTemplate(
- _callHelper('str'), new JS.TemplateString(strings, interpolations));
+ runtimeCall('str'), new JS.TemplateString(strings, interpolations));
}
@override
@@ -4871,7 +4856,7 @@
// TODO(jmesserly): fuse this with notNull check.
// TODO(jmesserly): this does not correctly distinguish user casts from
// required-for-soundness casts.
- return _callHelper('asInt(#)', jsFrom);
+ return runtimeCall('asInt(#)', jsFrom);
}
// A no-op in JavaScript.
@@ -4924,14 +4909,14 @@
}
JS.Expression _emitConst(JS.Expression expr()) =>
- _cacheConst(() => _callHelper('const(#)', expr()));
+ _cacheConst(() => runtimeCall('const(#)', expr()));
@override
visitTypeLiteral(TypeLiteral node) {
var typeRep = _emitType(node.type);
// If the type is a type literal expression in Dart code, wrap the raw
// runtime type in a "Type" instance.
- return _isInForeignJS ? typeRep : _callHelper('wrapType(#)', typeRep);
+ return _isInForeignJS ? typeRep : runtimeCall('wrapType(#)', typeRep);
}
@override
@@ -4939,12 +4924,12 @@
@override
visitRethrow(Rethrow node) {
- return _callHelper('rethrow(#)', _emitVariableRef(_catchParameter));
+ return runtimeCall('rethrow(#)', _emitVariableRef(_catchParameter));
}
@override
visitThrow(Throw node) =>
- _callHelper('throw(#)', _visitExpression(node.expression));
+ runtimeCall('throw(#)', _visitExpression(node.expression));
@override
visitListLiteral(ListLiteral node) {
@@ -4960,7 +4945,7 @@
DartType elementType, List<JS.Expression> elements) {
// dart.constList helper internally depends on _interceptors.JSArray.
_declareBeforeUse(_jsArrayClass);
- return _callHelper('constList([#], #)', [elements, _emitType(elementType)]);
+ return runtimeCall('constList([#], #)', [elements, _emitType(elementType)]);
}
JS.Expression _emitList(DartType itemType, List<JS.Expression> items) {
@@ -4995,7 +4980,7 @@
}
return js.call('new #.from(#)', [mapType, emitEntries()]);
}
- return _cacheConst(() => _callHelper('constMap(#, #, #)',
+ return _cacheConst(() => runtimeCall('constMap(#, #, #)',
[_emitType(node.keyType), _emitType(node.valueType), emitEntries()]));
}
@@ -5068,14 +5053,14 @@
@override
visitInstantiation(Instantiation node) {
- return _callHelper('gbind(#, #)', [
+ return runtimeCall('gbind(#, #)', [
_visitExpression(node.expression),
node.typeArguments.map(_emitType).toList()
]);
}
@override
- visitLoadLibrary(LoadLibrary node) => _callHelper('loadLibrary()');
+ visitLoadLibrary(LoadLibrary node) => runtimeCall('loadLibrary()');
// TODO(jmesserly): DDC loads all libraries eagerly.
// See
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index 84fc2e4..9f49edb 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -281,6 +281,16 @@
// called at runtime.)
var concreteMembers = new HashSet<String>();
+ void addMember(Member m, bool classIsAbstract, {bool isSetter: false}) {
+ var name = m.name.name;
+ if (isSetter) name += '=';
+ if (classIsAbstract || m.isAbstract) {
+ mockMembers[name] = m;
+ } else {
+ concreteMembers.add(name);
+ }
+ }
+
void visit(Class c, bool classIsAbstract) {
if (c == null) return;
visit(c.superclass, classIsAbstract);
@@ -288,13 +298,13 @@
for (var i in c.implementedTypes) visit(i.classNode, true);
for (var m in c.members) {
- if (m is Constructor) continue;
- if (m is Procedure && m.isStatic) continue;
-
- if (classIsAbstract || m.isAbstract) {
- mockMembers[m.name.name] = m;
- } else {
- concreteMembers.add(m.name.name);
+ if (m is Field) {
+ if (m.isStatic) continue;
+ addMember(m, classIsAbstract);
+ if (m.hasSetter) addMember(m, classIsAbstract, isSetter: true);
+ } else if (m is Procedure) {
+ if (m.isStatic) continue;
+ addMember(m, classIsAbstract, isSetter: m.isSetter);
}
}
}
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
index 1b1e938..a3de057 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
@@ -510,7 +510,7 @@
_isBrowserType(o)) {
return o;
} else if (JS('bool', '# instanceof Date', o)) {
- var ms = JS('num', '#.getTime()', o);
+ num ms = JS('!', '#.getTime()', o);
return new DateTime.fromMillisecondsSinceEpoch(ms);
} else if (o is _DartObject &&
JS('bool', 'dart.jsobject != dart.getReifiedType(#)', o)) {
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/js_util/dart2js/js_util_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/js_util/dart2js/js_util_dart2js.dart
index bb31232..0dfb1e5 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/js_util/dart2js/js_util_dart2js.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/js_util/dart2js/js_util_dart2js.dart
@@ -72,7 +72,7 @@
}
if (JS('bool', '# instanceof Array', arguments)) {
- int argumentCount = JS('int', '#.length', arguments);
+ int argumentCount = JS('!', '#.length', arguments);
switch (argumentCount) {
case 0:
return JS('Object', 'new #()', constr);
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/collection_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/collection_patch.dart
index 546c00b..4af9548 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/collection_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/collection_patch.dart
@@ -186,7 +186,7 @@
var k = key;
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
if (buckets != null) {
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
k = JS('', '#[#]', buckets, i);
if (k == key) return true;
}
@@ -204,7 +204,7 @@
var k = key;
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
if (buckets != null) {
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
k = JS('', '#[#]', buckets, i);
if (k == key) return JS('', '#', k);
}
@@ -224,12 +224,12 @@
var keyMap = _keyMap;
@notNull
var k = key;
- var hash = JS('int', '# & 0x3ffffff', k.hashCode);
+ int hash = JS('!', '# & 0x3ffffff', k.hashCode);
var buckets = JS('', '#.get(#)', keyMap, hash);
if (buckets == null) {
JS('', '#.set(#, [#])', keyMap, hash, key);
} else {
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
k = JS('', '#[#]', buckets, i);
if (k == key) return false;
}
@@ -255,7 +255,7 @@
}
JS('', '#.add(#)', map, key);
}
- if (length != JS('int', '#.size', map)) {
+ if (length != JS<int>('!', '#.size', map)) {
_modifications = (_modifications + 1) & 0x3ffffff;
}
}
@@ -267,10 +267,10 @@
dart.identityEquals)) {
@notNull
var k = key;
- var hash = JS('int', '# & 0x3ffffff', k.hashCode);
+ int hash = JS('!', '# & 0x3ffffff', k.hashCode);
var buckets = JS('', '#.get(#)', _keyMap, hash);
if (buckets == null) return false; // not found
- for (int i = 0, n = JS('int', '#.length', buckets);;) {
+ for (int i = 0, n = JS('!', '#.length', buckets);;) {
k = JS('', '#[#]', buckets, i);
if (k == key) {
key = k;
@@ -294,7 +294,7 @@
void clear() {
var map = _map;
- if (JS('int', '#.size', map) > 0) {
+ if (JS<int>('!', '#.size', map) > 0) {
JS('', '#.clear()', map);
JS('', '#.clear()', _keyMap);
_modifications = (_modifications + 1) & 0x3ffffff;
@@ -339,7 +339,7 @@
for (E key in objects) {
JS('', '#.add(#)', map, key);
}
- if (length != JS('int', '#.size', map)) {
+ if (length != JS<int>('!', '#.size', map)) {
_modifications = (_modifications + 1) & 0x3ffffff;
}
}
@@ -354,7 +354,7 @@
void clear() {
var map = _map;
- if (JS('int', '#.size', map) > 0) {
+ if (JS<int>('!', '#.size', map) > 0) {
JS('', '#.clear()', map);
_modifications = (_modifications + 1) & 0x3ffffff;
}
@@ -425,7 +425,7 @@
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
if (buckets != null) {
var equals = _equals;
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
E k = JS('', '#[#]', buckets, i);
if (equals(k, key)) return true;
}
@@ -439,7 +439,7 @@
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, _hashCode(key));
if (buckets != null) {
var equals = _equals;
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
E k = JS('', '#[#]', buckets, i);
if (equals(k, key)) return JS('', '#', k);
}
@@ -450,13 +450,13 @@
bool add(E key) {
var keyMap = _keyMap;
- var hash = JS('int', '# & 0x3ffffff', _hashCode(key));
+ var hash = JS<int>('!', '# & 0x3ffffff', _hashCode(key));
var buckets = JS('', '#.get(#)', keyMap, hash);
if (buckets == null) {
JS('', '#.set(#, [#])', keyMap, hash, key);
} else {
var equals = _equals;
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
E k = JS('', '#[#]', buckets, i);
if (equals(k, key)) return false;
}
@@ -474,12 +474,12 @@
bool remove(Object key) {
if (key is E) {
- var hash = JS('int', '# & 0x3ffffff', _hashCode(key));
+ var hash = JS<int>('!', '# & 0x3ffffff', _hashCode(key));
var keyMap = _keyMap;
var buckets = JS('', '#.get(#)', keyMap, hash);
if (buckets == null) return false; // not found
var equals = _equals;
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
E k = JS('', '#[#]', buckets, i);
if (equals(k, key)) {
if (n == 1) {
@@ -498,7 +498,7 @@
void clear() {
var map = _map;
- if (JS('int', '#.size', map) > 0) {
+ if (JS<int>('!', '#.size', map) > 0) {
JS('', '#.clear()', map);
JS('', '#.clear()', _keyMap);
_modifications = (_modifications + 1) & 0x3ffffff;
@@ -517,7 +517,7 @@
int get _modifications;
@notNull
- int get length => JS('int', '#.size', _map);
+ int get length => JS<int>('!', '#.size', _map);
@notNull
bool get isEmpty => JS('bool', '#.size == 0', _map);
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
index 21da3ab..b8ad752 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
@@ -368,7 +368,7 @@
if (JS('bool', '# === void 0', _length)) {
list = JS('', '[]');
} else {
- var length = JS('int', '#', _length);
+ int length = JS('!', '#', _length);
if (_length == null || length < 0) {
throw new ArgumentError(
"Length must be a non-negative integer: $_length");
@@ -2603,7 +2603,7 @@
var resultBits = new Uint8List(8);
var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
- if (length - 53 > maxDoubleExponent) return double.INFINITY;
+ if (length - 53 > maxDoubleExponent) return double.infinity;
// The most significant bit is for the sign.
if (_isNegative) resultBits[7] = 0x80;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/custom_hash_map.dart b/pkg/dev_compiler/tool/input_sdk/private/custom_hash_map.dart
index 3fa774e..578fbc1 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/custom_hash_map.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/custom_hash_map.dart
@@ -110,7 +110,7 @@
void operator []=(K key, V value) {
var keyMap = _keyMap;
- var hash = JS('int', '# & 0x3ffffff', _hashCode(key));
+ int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
var buckets = JS('', '#.get(#)', keyMap, hash);
if (buckets == null) {
JS('', '#.set(#, [#])', keyMap, hash, key);
@@ -134,7 +134,7 @@
V putIfAbsent(K key, V ifAbsent()) {
var keyMap = _keyMap;
- var hash = JS('int', '# & 0x3ffffff', _hashCode(key));
+ int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
var buckets = JS('', '#.get(#)', keyMap, hash);
if (buckets == null) {
JS('', '#.set(#, [#])', keyMap, hash, key);
@@ -154,7 +154,7 @@
V remove(Object key) {
if (key is K) {
- var hash = JS('int', '# & 0x3ffffff', _hashCode(key));
+ int hash = JS('!', '# & 0x3ffffff', _hashCode(key));
var keyMap = _keyMap;
var buckets = JS('', '#.get(#)', keyMap, hash);
if (buckets == null) return null; // not found
@@ -180,7 +180,7 @@
void clear() {
var map = _map;
- if (JS('int', '#.size', map) > 0) {
+ if (JS<int>('!', '#.size', map) > 0) {
JS('', '#.clear()', map);
JS('', '#.clear()', _keyMap);
_modifications = (_modifications + 1) & 0x3ffffff;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
index 48ef1ea..0f0c078 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
@@ -314,8 +314,8 @@
// symbol name.
var coreObjProto = JS('', '#.prototype', Object);
var names = getOwnPropertyNames(coreObjProto);
- for (int i = 0; i < JS('int', '#.length', names); ++i) {
- var name = JS('String', '#[#]', names, i);
+ for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) {
+ var name = JS<String>('!', '#[#]', names, i);
if (name == 'constructor') continue;
var desc = getOwnPropertyDescriptor(coreObjProto, name);
defineProperty(jsProto, JS('', '#.#', dartx, name), desc);
@@ -413,10 +413,10 @@
var member;
var p = proto;
for (;; p = JS('', '#.__proto__', p)) {
- member = JS('', 'Object.getOwnPropertyDescriptor(#, #)', p, name);
+ member = getOwnPropertyDescriptor(p, name);
if (member != null) break;
}
- JS('', 'Object.defineProperty(#, dartx[#], #)', proto, name, member);
+ defineProperty(proto, JS('', 'dartx[#]', name), member);
}
}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
index f094a48..6a36f63 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
@@ -91,6 +91,8 @@
return result;
}
+dloadRepl(obj, field) => dload(obj, replNameLookup(obj, field), false);
+
// Warning: dload, dput, and dsend assume they are never called on methods
// implemented by the Object base class as those methods can always be
// statically resolved.
@@ -131,6 +133,9 @@
// PageLoader code can generate the correct reified generic types.
dputMirror(obj, field, value) => dput(obj, field, value, true);
+dputRepl(obj, field, value) =>
+ dput(obj, replNameLookup(obj, field), value, false);
+
dput(obj, field, value, [mirrors = undefined]) {
var f = _canonicalMember(obj, field);
trackCall(obj);
@@ -153,12 +158,7 @@
/// Check that a function of a given type can be applied to
/// actuals.
-bool _checkApply(ftype, List actuals, namedActuals) {
- // TODO(vsm): Remove when we no longer need mirrors metadata.
- // An array is used to encode annotations attached to the type.
- FunctionType type =
- JS('!', '# instanceof Array ? #[0] : #', ftype, ftype, ftype);
-
+bool _checkApply(FunctionType type, List actuals, namedActuals) {
// Check for too few required arguments.
var actualsCount = JS('int', '#.length', actuals);
var required = type.args;
@@ -274,6 +274,10 @@
return $f.apply($obj, $args);
}
+ // TODO(vsm): Remove when we no longer need mirrors metadata.
+ // An array is used to encode annotations attached to the type.
+ if ($ftype instanceof Array) $ftype = $ftype[0];
+
// Apply type arguments
if ($ftype instanceof $GenericFunctionType) {
let formalCount = $ftype.formalCount;
@@ -290,7 +294,7 @@
return callNSM();
}
- if (${_checkApply(ftype, args, named)}) {
+ if ($_checkApply($ftype, $args, $named)) {
if ($typeArgs != null) $args = $typeArgs.concat($args);
if ($named != null) $args.push($named);
return $f.apply($obj, $args);
@@ -306,11 +310,11 @@
/// Helper for REPL dynamic invocation variants that make a best effort to
/// enable accessing private members across library boundaries.
-_dhelperRepl(object, field, callback) => JS('', '''(() => {
+replNameLookup(object, field) => JS('', '''(() => {
let rawField = $field;
if (typeof(field) == 'symbol') {
// test if the specified field exists in which case it is safe to use it.
- if ($field in $object) return $callback($field);
+ if ($field in $object) return $field;
// Symbol is from a different library. Make a best effort to
$field = $field.toString();
@@ -318,11 +322,11 @@
} else if ($field.charAt(0) != '_') {
// Not a private member so default call path is safe.
- return $callback($field);
+ return $field;
}
// If the exact field name is present, invoke callback with it.
- if ($field in $object) return $callback($field);
+ if ($field in $object) return $field;
// TODO(jacobr): warn if there are multiple private members with the same
// name which could happen if super classes in different libraries have
@@ -335,28 +339,21 @@
for (let s = 0; s < symbols.length; s++) {
let sym = symbols[s];
- if (target == sym.toString()) return $callback(sym);
+ if (target == sym.toString()) return sym;
}
proto = proto.__proto__;
}
// We didn't find a plausible alternate private symbol so just fall back
// to the regular field.
- return $callback(rawField);
+ return rawField;
})()''');
-dloadRepl(obj, field) => _dhelperRepl(obj, field, (f) => dload(obj, f, false));
-
-dputRepl(obj, field, value) =>
- _dhelperRepl(obj, field, (f) => dput(obj, f, value, false));
-
-callMethodRepl(obj, method, typeArgs, args, named) => _dhelperRepl(
- obj, method, (f) => callMethod(obj, f, typeArgs, args, method, named));
-
-dsendRepl(obj, method, args, [named = undefined]) =>
- callMethodRepl(obj, method, null, args, named);
-
-dgsendRepl(obj, typeArgs, method, args, [named = undefined]) =>
- callMethodRepl(obj, method, typeArgs, args, named);
+// TODO(jmesserly): the debugger extension hardcodes a call to this private
+// function. Fix that.
+@Deprecated('use replNameLookup')
+_dhelperRepl(obj, field, Function(Object) callback) {
+ return callback(replNameLookup(obj, field));
+}
/// Shared code for dsend, dindex, and dsetindex.
callMethod(obj, name, typeArgs, args, named, displayName) {
@@ -381,6 +378,12 @@
dgsend(obj, typeArgs, method, args, [named = undefined]) =>
callMethod(obj, method, typeArgs, args, named, method);
+dsendRepl(obj, method, args, [named = undefined]) =>
+ callMethod(obj, replNameLookup(obj, method), null, args, named, method);
+
+dgsendRepl(obj, typeArgs, method, args, [named = undefined]) =>
+ callMethod(obj, replNameLookup(obj, method), typeArgs, args, named, method);
+
dindex(obj, index) => callMethod(obj, '_get', null, [index], null, '[]');
dsetindex(obj, index, value) =>
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
index b1db5b6..874a3fa 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
@@ -44,16 +44,27 @@
/// different from the above objects, and are created by calling `wrapType()`
/// on a runtime type.
-/// Tag a closure with a type:
+/// Tag a closure with a type.
///
-/// `dart.fn(closure, t)` marks [closure] has having the runtime type [t].
-fn(closure, t) {
- JS('', '#[#] = #', closure, _runtimeType, t);
+/// `dart.fn(closure, type)` marks [closure] with the provided runtime [type].
+fn(closure, type) {
+ JS('', '#[#] = #', closure, _runtimeType, type);
return closure;
}
-lazyFn(closure, computeType) {
- defineLazyGetter(closure, _runtimeType, computeType);
+/// Tag a closure with a type that's computed lazily.
+///
+/// `dart.fn(closure, type)` marks [closure] with a getter that uses
+/// [computeType] to return the runtime type.
+///
+/// The getter/setter replaces the property with a value property, so the
+/// resulting function is compatible with [fn] and the type can be set again
+/// safely.
+lazyFn(closure, Object Function() computeType) {
+ defineAccessor(closure, _runtimeType,
+ get: () => defineValue(closure, _runtimeType, computeType()),
+ set: (value) => defineValue(closure, _runtimeType, value),
+ configurable: true);
return closure;
}
@@ -64,7 +75,7 @@
getFunctionType(obj) {
// TODO(vsm): Encode this properly on the function for Dart-generated code.
- var args = JS('List', 'Array(#.length).fill(#)', obj, dynamic);
+ var args = JS<List>('!', 'Array(#.length).fill(#)', obj, dynamic);
return fnType(bottom, args, JS('', 'void 0'));
}
@@ -113,16 +124,15 @@
return JS('Type', '#[#] = #', type, _typeObject, new WrappedType(type));
}
+/// The symbol used to store the cached `Type` object associated with a class.
+final _typeObject = JS('', 'Symbol("typeObject")');
+
/// Given a WrappedType, return the internal runtime type object.
unwrapType(WrappedType obj) => obj._wrappedType;
/// Return the module name for a raw library object.
getModuleName(value) => JS('', '#[#]', value, _moduleName);
-void tagComputed(value, compute) {
- defineGetter(value, _runtimeType, compute);
-}
-
var _loadedModules = JS('', 'new Map()');
var _loadedSourceMaps = JS('', 'new Map()');
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
index e9b6a27..3215fa5 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
@@ -7,9 +7,6 @@
final metadata = JS('', 'Symbol("metadata")');
-/// The symbol used to store the cached `Type` object associated with a class.
-final _typeObject = JS('', 'Symbol("typeObject")');
-
/// Types in dart are represented internally at runtime as follows.
///
/// - Normal nominal types, produced from classes, are represented
@@ -445,7 +442,7 @@
var result = name + '<';
var allDynamic = true;
- for (var i = 0, n = JS('int', '#.length', typeArgs); i < n; ++i) {
+ for (int i = 0, n = JS('!', '#.length', typeArgs); i < n; ++i) {
if (i > 0) result += ', ';
var typeArg = JS('', '#[#]', typeArgs, i);
if (JS('bool', '# !== #', typeArg, _dynamic)) allDynamic = false;
@@ -503,7 +500,7 @@
// purposes, such as when an error happens or if someone calls
// `Type.toString()`. So we could recover them lazily rather than eagerly.
// Alternatively we could synthesize new names.
- var str = JS('String', '#.toString()', _instantiateTypeParts);
+ String str = JS('!', '#.toString()', _instantiateTypeParts);
var hasParens = str[0] == '(';
var end = str.indexOf(hasParens ? ')' : '=>');
if (hasParens) {
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
index 590f850..80a84de 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
@@ -16,23 +16,16 @@
JS('', 'Object.defineProperty');
defineValue(obj, name, value) {
- defineProperty(obj, name,
- JS('', '{ value: #, configurable: true, writable: true }', value));
+ defineAccessor(obj, name, value: value, configurable: true, writable: true);
return value;
}
-void defineGetter(obj, name, getter) {
- defineProperty(obj, name, JS('', '{get: #}', getter));
-}
-
-void defineLazyGetter(obj, name, compute) {
- var x = null;
- defineProperty(
- obj,
- name,
- JS('', '{ get: () => # != null ? # : # = #(), configurable: true }', x, x,
- x, compute));
-}
+final Function(Object, Object,
+ {Object get,
+ Object set,
+ Object value,
+ bool configurable,
+ bool writable}) defineAccessor = JS('', 'Object.defineProperty');
final Function(Object, Object) getOwnPropertyDescriptor =
JS('', 'Object.getOwnPropertyDescriptor');
@@ -71,9 +64,7 @@
/// After initial get or set, it will replace itself with a value property.
// TODO(jmesserly): reusing descriptor objects has been shown to improve
// performance in other projects (e.g. webcomponents.js ShadowDOM polyfill).
-defineLazyField(to, name, desc) => JS(
- '',
- '''(() => {
+defineLazyField(to, name, desc) => JS('', '''(() => {
let init = $desc.get;
let value = null;
$desc.get = function() {
@@ -99,7 +90,7 @@
})()''');
copyTheseProperties(to, from, names) {
- for (var i = 0, n = JS('int', '#.length', names); i < n; ++i) {
+ for (int i = 0, n = JS('!', '#.length', names); i < n; ++i) {
var name = JS('', '#[#]', names, i);
if (name == 'constructor') continue;
copyProperty(to, from, name);
diff --git a/pkg/dev_compiler/tool/input_sdk/private/identity_hash_map.dart b/pkg/dev_compiler/tool/input_sdk/private/identity_hash_map.dart
index 8de3f2f..c2671eb 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/identity_hash_map.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/identity_hash_map.dart
@@ -60,7 +60,7 @@
void operator []=(K key, V value) {
var map = _map;
- var length = JS('int', '#.size', map);
+ int length = JS('!', '#.size', map);
JS('', '#.set(#, #)', map, key, value);
if (length != JS('int', '#.size', map)) {
_modifications = (_modifications + 1) & 0x3ffffff;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart b/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
index 32da1d3..20aee27 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
@@ -126,7 +126,7 @@
// TODO(jmesserly): remove these once we canonicalize tearoffs.
operator ==(other) {
if (other == null) return false;
- var boundObj = JS('Object|Null', '#._boundObject', this);
+ var boundObj = JS<Object>('', '#._boundObject', this);
if (boundObj == null) return JS('bool', '# === #', this, other);
return JS(
'bool',
@@ -138,10 +138,10 @@
}
get hashCode {
- var boundObj = JS('Object|Null', '#._boundObject', this);
+ var boundObj = JS<Object>('', '#._boundObject', this);
if (boundObj == null) return identityHashCode(this);
- var boundMethod = JS('Object', '#._boundMethod', this);
+ var boundMethod = JS<Object>('!', '#._boundMethod', this);
int hash = (17 * 31 + boundObj.hashCode) & 0x1fffffff;
return (hash * 31 + identityHashCode(boundMethod)) & 0x1fffffff;
}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
index 089d959..7157533 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
@@ -166,7 +166,7 @@
source)) {
return _parseDoubleError(source, handleError);
}
- var result = JS('num', r'parseFloat(#)', source);
+ num result = JS('!', r'parseFloat(#)', source);
if (result.isNaN) {
var trimmed = source.trim();
if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
@@ -194,7 +194,7 @@
if (performance == null) return;
if (JS('bool', 'typeof #.now != "function"', performance)) return;
timerFrequency = 1000000;
- timerTicks = () => (1000 * JS('num', '#.now()', performance)).floor();
+ timerTicks = () => (1000 * JS<num>('!', '#.now()', performance)).floor();
}
static int timerFrequency;
@@ -359,10 +359,10 @@
var jsMonth = month - 1;
num value;
if (isUtc) {
- value = JS('num', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day,
+ value = JS('!', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day,
hours, minutes, seconds, milliseconds);
} else {
- value = JS('num', r'new Date(#, #, #, #, #, #, #).valueOf()', years,
+ value = JS('!', r'new Date(#, #, #, #, #, #, #).valueOf()', years,
jsMonth, day, hours, minutes, seconds, milliseconds);
}
if (value.isNaN ||
@@ -374,14 +374,14 @@
return value;
}
- static patchUpY2K(value, years, isUtc) {
+ static num patchUpY2K(value, years, isUtc) {
var date = JS('', r'new Date(#)', value);
if (isUtc) {
- JS('num', r'#.setUTCFullYear(#)', date, years);
+ JS('', r'#.setUTCFullYear(#)', date, years);
} else {
- JS('num', r'#.setFullYear(#)', date, years);
+ JS('', r'#.setFullYear(#)', date, years);
}
- return JS('num', r'#.valueOf()', date);
+ return JS('!', r'#.valueOf()', date);
}
// Lazily keep a JS Date stored in the JS object.
@@ -397,49 +397,49 @@
// that the result is really an integer, because the JavaScript implementation
// may return -0.0 instead of 0.
- static getYear(DateTime receiver) {
+ static int getYear(DateTime receiver) {
return (receiver.isUtc)
? JS('int', r'(#.getUTCFullYear() + 0)', lazyAsJsDate(receiver))
: JS('int', r'(#.getFullYear() + 0)', lazyAsJsDate(receiver));
}
- static getMonth(DateTime receiver) {
+ static int getMonth(DateTime receiver) {
return (receiver.isUtc)
? JS('int', r'#.getUTCMonth() + 1', lazyAsJsDate(receiver))
: JS('int', r'#.getMonth() + 1', lazyAsJsDate(receiver));
}
- static getDay(DateTime receiver) {
+ static int getDay(DateTime receiver) {
return (receiver.isUtc)
? JS('int', r'(#.getUTCDate() + 0)', lazyAsJsDate(receiver))
: JS('int', r'(#.getDate() + 0)', lazyAsJsDate(receiver));
}
- static getHours(DateTime receiver) {
+ static int getHours(DateTime receiver) {
return (receiver.isUtc)
? JS('int', r'(#.getUTCHours() + 0)', lazyAsJsDate(receiver))
: JS('int', r'(#.getHours() + 0)', lazyAsJsDate(receiver));
}
- static getMinutes(DateTime receiver) {
+ static int getMinutes(DateTime receiver) {
return (receiver.isUtc)
? JS('int', r'(#.getUTCMinutes() + 0)', lazyAsJsDate(receiver))
: JS('int', r'(#.getMinutes() + 0)', lazyAsJsDate(receiver));
}
- static getSeconds(DateTime receiver) {
+ static int getSeconds(DateTime receiver) {
return (receiver.isUtc)
? JS('int', r'(#.getUTCSeconds() + 0)', lazyAsJsDate(receiver))
: JS('int', r'(#.getSeconds() + 0)', lazyAsJsDate(receiver));
}
- static getMilliseconds(DateTime receiver) {
+ static int getMilliseconds(DateTime receiver) {
return (receiver.isUtc)
? JS('int', r'(#.getUTCMilliseconds() + 0)', lazyAsJsDate(receiver))
: JS('int', r'(#.getMilliseconds() + 0)', lazyAsJsDate(receiver));
}
- static getWeekday(DateTime receiver) {
+ static int getWeekday(DateTime receiver) {
int weekday = (receiver.isUtc)
? JS('int', r'#.getUTCDay() + 0', lazyAsJsDate(receiver))
: JS('int', r'#.getDay() + 0', lazyAsJsDate(receiver));
@@ -447,9 +447,9 @@
return (weekday + 6) % 7 + 1;
}
- static valueFromDateString(str) {
+ static num valueFromDateString(str) {
if (str is! String) throw argumentErrorValue(str);
- var value = JS('num', r'Date.parse(#)', str);
+ num value = JS('!', r'Date.parse(#)', str);
if (value.isNaN) throw argumentErrorValue(str);
return value;
}
@@ -572,7 +572,7 @@
final _stackTrace = JS('', 'Symbol("_stackTrace")');
StackTrace getTraceFromException(exception) {
var error = dart.recordJsError(exception);
- var trace = JS('StackTrace|Null', '#[#]', error, _stackTrace);
+ StackTrace trace = JS('', '#[#]', error, _stackTrace);
if (trace != null) return trace;
trace = new _StackTrace(error);
JS('', '#[#] = #', error, _stackTrace, trace);
@@ -599,7 +599,7 @@
String trace;
if (JS('bool', '# !== null', _exception) &&
JS('bool', 'typeof # === "object"', _exception)) {
- trace = JS("String|Null", r"#.stack", _exception);
+ trace = JS("", r"#.stack", _exception);
if (trace != null && stackTraceMapper != null) {
trace = stackTraceMapper(trace);
}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart b/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
index 1694f8e..270f571 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
@@ -246,8 +246,8 @@
var unwrapped = dart.unwrapType(_cls);
// Only get metadata directly embedded on this class, not its
// superclasses.
- var fn = JS(
- 'Function|Null',
+ Function fn = JS(
+ '',
'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : null',
unwrapped,
unwrapped);
@@ -288,53 +288,64 @@
_declarations[symbol] =
new JsMethodMirror._instanceMethod(this, symbol, ft);
});
+
+ getterType(type) {
+ if (JS('bool', '# instanceof Array', type)) {
+ var array = JS('', '#.slice()', type);
+ type = JS('', '#[0]', array);
+ JS('', '#[0] = #', array, dart.fnType(type, []));
+ return array;
+ } else {
+ return dart.fnType(type, []);
+ }
+ }
+
var getters = _toDartMap(dart.getGetters(unwrapped));
getters.forEach((symbol, type) {
- var name = getName(symbol);
- if (JS('bool', '# instanceof Array', type)) {
- JS('', '#[0] = #(#[0], [])', type, dart.fnType, type);
- } else {
- type = dart.fnType(type, []);
- }
_declarations[symbol] =
- new JsMethodMirror._instanceMethod(this, symbol, type);
+ new JsMethodMirror._instanceMethod(this, symbol, getterType(type));
});
+
+ setterType(type) {
+ if (JS('bool', '# instanceof Array', type)) {
+ var array = JS('', '#.slice()', type);
+ type = JS('', '#[0]', array);
+ JS('', '#[0] = #', array, dart.fnType(dart.void_, [type]));
+ return array;
+ } else {
+ return dart.fnType(dart.void_, [type]);
+ }
+ }
+
var setters = _toDartMap(dart.getSetters(unwrapped));
setters.forEach((symbol, type) {
var name = getName(symbol) + '=';
// Create a separate symbol for the setter.
symbol = new PrivateSymbol(name, _getESSymbol(symbol));
- var ft = dart.fnType(dart.void_, [type]);
_declarations[symbol] =
- new JsMethodMirror._instanceMethod(this, symbol, ft);
+ new JsMethodMirror._instanceMethod(this, symbol, setterType(type));
});
+
var staticFields = _toDartMap(dart.getStaticFields(unwrapped));
staticFields.forEach((symbol, t) {
_declarations[symbol] = new JsVariableMirror._fromField(symbol, t);
});
var statics = _toDartMap(dart.getStaticMethods(unwrapped));
statics.forEach((symbol, ft) {
- var name = getName(symbol);
_declarations[symbol] =
new JsMethodMirror._staticMethod(this, symbol, ft);
});
+
var staticGetters = _toDartMap(dart.getStaticGetters(unwrapped));
staticGetters.forEach((symbol, type) {
- var name = getName(symbol);
- if (JS('bool', '# instanceof Array', type)) {
- JS('', '#[0] = #(#[0], [])', type, dart.fnType, type);
- } else {
- type = dart.fnType(type, []);
- }
_declarations[symbol] =
- new JsMethodMirror._staticMethod(this, symbol, type);
+ new JsMethodMirror._staticMethod(this, symbol, getterType(type));
});
+
var staticSetters = _toDartMap(dart.getStaticSetters(unwrapped));
staticSetters.forEach((symbol, type) {
- var name = getName(symbol);
- var ft = dart.fnType(dart.void_, [type]);
_declarations[symbol] =
- new JsMethodMirror._staticMethod(this, symbol, ft);
+ new JsMethodMirror._staticMethod(this, symbol, setterType(type));
});
_declarations =
new Map<Symbol, DeclarationMirror>.unmodifiable(_declarations);
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_number.dart b/pkg/dev_compiler/tool/input_sdk/private/js_number.dart
index eb86702..31a5f5d 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_number.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_number.dart
@@ -192,16 +192,16 @@
static String _handleIEtoString(String result) {
// Result is probably IE's untraditional format for large numbers,
// e.g., "8.0000000000008(e+15)" for 0x8000000000000800.toString(16).
- var match = JS('List|Null',
- r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result);
+ var match = JS<List>(
+ '', r'/^([\da-z]+)(?:\.([\da-z]+))?\(e\+(\d+)\)$/.exec(#)', result);
if (match == null) {
// Then we don't know how to handle it at all.
throw new UnsupportedError("Unexpected toString result: $result");
}
- result = JS('String', '#', match[1]);
- int exponent = JS("int", "+#", match[3]);
+ result = JS('!', '#', match[1]);
+ int exponent = JS("!", "+#", match[3]);
if (match[2] != null) {
- result = JS('String', '# + #', result, match[2]);
+ result = JS('!', '# + #', result, match[2]);
exponent -= JS<int>('!', '#.length', match[2]);
}
return result + "0" * exponent;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_string.dart b/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
index 65b77a8..9b57bf3 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
@@ -36,11 +36,11 @@
}
Match matchAsPrefix(@nullCheck String string, [@nullCheck int start = 0]) {
- final stringLength = JS('int', '#.length', string);
+ int stringLength = JS('!', '#.length', string);
if (start < 0 || start > stringLength) {
throw new RangeError.range(start, 0, stringLength);
}
- final thisLength = JS('int', '#.length', this);
+ int thisLength = JS('!', '#.length', this);
if (start + thisLength > stringLength) return null;
for (int i = 0; i < thisLength; i++) {
if (string.codeUnitAt(start + i) != this.codeUnitAt(i)) {
@@ -286,7 +286,7 @@
// Start by doing JS trim. Then check if it leaves a NEL at
// either end of the string.
- final result = JS('String', '#.trim()', this);
+ String result = JS('!', '#.trim()', this);
final length = result.length;
if (length == 0) return result;
int firstCode = result.codeUnitAt(0);
@@ -454,7 +454,7 @@
}
@notNull
- bool get isEmpty => JS('int', '#.length', this) == 0;
+ bool get isEmpty => JS<int>('!', '#.length', this) == 0;
@notNull
bool get isNotEmpty => !isEmpty;
@@ -479,9 +479,9 @@
// TODO(ahe): This method shouldn't have to use JS. Update when our
// optimizations are smarter.
int hash = 0;
- int length = JS('int', '#.length', this);
+ int length = JS('!', '#.length', this);
for (int i = 0; i < length; i++) {
- hash = 0x1fffffff & (hash + JS('int', r'#.charCodeAt(#)', this, i));
+ hash = 0x1fffffff & (hash + JS<int>('!', r'#.charCodeAt(#)', this, i));
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
hash = JS('int', '# ^ (# >> 6)', hash, hash);
}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/linked_hash_map.dart b/pkg/dev_compiler/tool/input_sdk/private/linked_hash_map.dart
index 8cc2af5..ea366ca 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/linked_hash_map.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/linked_hash_map.dart
@@ -68,7 +68,7 @@
LinkedMap.from(JSArray entries) {
var map = _map;
var keyMap = _keyMap;
- for (int i = 0, n = JS('int', '#.length', entries); i < n; i += 2) {
+ for (int i = 0, n = JS('!', '#.length', entries); i < n; i += 2) {
K key = JS('', '#[#]', entries, i);
V value = JS('', '#[#]', entries, i + 1);
if (key == null) {
@@ -82,7 +82,7 @@
}
@notNull
- int get length => JS('int', '#.size', _map);
+ int get length => JS<int>('!', '#.size', _map);
@notNull
bool get isEmpty => JS('bool', '#.size == 0', _map);
@@ -103,7 +103,7 @@
var k = key;
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
if (buckets != null) {
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
k = JS('', '#[#]', buckets, i);
if (k == key) return true;
}
@@ -132,7 +132,7 @@
}
JS('', '#.set(#, #)', _map, key, value);
});
- if (length != JS('int', '#.size', map)) {
+ if (length != JS<int>('!', '#.size', map)) {
_modifications = (_modifications + 1) & 0x3ffffff;
}
}
@@ -146,7 +146,7 @@
var k = key;
var buckets = JS('', '#.get(# & 0x3ffffff)', _keyMap, k.hashCode);
if (buckets != null) {
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
k = JS('', '#[#]', buckets, i);
if (k == key) return JS('', '#.get(#)', _map, k);
}
@@ -166,7 +166,7 @@
var map = _map;
int length = JS('', '#.size', map);
JS('', '#.set(#, #)', map, key, value);
- if (length != JS('int', '#.size', map)) {
+ if (length != JS<int>('!', '#.size', map)) {
_modifications = (_modifications + 1) & 0x3ffffff;
}
}
@@ -180,12 +180,12 @@
dart.identityEquals)) {
@notNull
K k = key;
- var hash = JS('int', '# & 0x3ffffff', k.hashCode);
+ var hash = JS<int>('!', '# & 0x3ffffff', k.hashCode);
var buckets = JS('', '#.get(#)', _keyMap, hash);
if (buckets == null) {
JS('', '#.set(#, [#])', _keyMap, hash, key);
} else {
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
k = JS('', '#[#]', buckets, i);
if (k == key) return JS('', '#.get(#)', map, k);
}
@@ -207,10 +207,10 @@
dart.identityEquals)) {
@notNull
var k = key;
- var hash = JS('int', '# & 0x3ffffff', k.hashCode);
+ var hash = JS<int>('!', '# & 0x3ffffff', k.hashCode);
var buckets = JS('', '#.get(#)', _keyMap, hash);
if (buckets == null) return null; // not found
- for (int i = 0, n = JS('int', '#.length', buckets);;) {
+ for (int i = 0, n = JS('!', '#.length', buckets);;) {
k = JS('', '#[#]', buckets, i);
if (k == key) {
key = k;
@@ -234,7 +234,7 @@
void clear() {
var map = _map;
- if (JS('int', '#.size', map) > 0) {
+ if (JS<int>('!', '#.size', map) > 0) {
JS('', '#.clear()', map);
JS('', '#.clear()', _keyMap);
_modifications = (_modifications + 1) & 0x3ffffff;
@@ -244,13 +244,13 @@
@NoReifyGeneric()
K putLinkedMapKey<K>(@notNull K key, keyMap) {
- var hash = JS('int', '# & 0x3ffffff', key.hashCode);
+ var hash = JS<int>('!', '# & 0x3ffffff', key.hashCode);
var buckets = JS('', '#.get(#)', keyMap, hash);
if (buckets == null) {
JS('', '#.set(#, [#])', keyMap, hash, key);
return key;
}
- for (int i = 0, n = JS('int', '#.length', buckets); i < n; i++) {
+ for (int i = 0, n = JS('!', '#.length', buckets); i < n; i++) {
@notNull
K k = JS('', '#[#]', buckets, i);
if (k == key) return k;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/native_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/native_helper.dart
index 063edc7..cc214e8 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/native_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/native_helper.dart
@@ -4,19 +4,6 @@
part of dart._js_helper;
-/**
- * Sets a JavaScript property on an object.
- */
-void defineProperty(var obj, String property, var value) {
- JS(
- 'void',
- 'Object.defineProperty(#, #, '
- '{value: #, enumerable: false, writable: true, configurable: true})',
- obj,
- property,
- value);
-}
-
// Obsolete in dart dev compiler. Added only so that the same version of
// dart:html can be used in dart2js an dev compiler.
F convertDartClosureToJS<F>(F closure, int arity) {
diff --git a/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart b/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart
index 73b1741..b108a7c 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart
@@ -151,7 +151,7 @@
int get offsetInBytes => _storage.offsetInBytes;
- int get elementSizeInBytes => Float32x4List.BYTES_PER_ELEMENT;
+ int get elementSizeInBytes => Float32x4List.bytesPerElement;
int get length => _storage.length ~/ 4;
@@ -229,7 +229,7 @@
int get offsetInBytes => _storage.offsetInBytes;
- int get elementSizeInBytes => Int32x4List.BYTES_PER_ELEMENT;
+ int get elementSizeInBytes => Int32x4List.bytesPerElement;
int get length => _storage.length ~/ 4;
@@ -306,7 +306,7 @@
int get offsetInBytes => _storage.offsetInBytes;
- int get elementSizeInBytes => Float64x2List.BYTES_PER_ELEMENT;
+ int get elementSizeInBytes => Float64x2List.bytesPerElement;
int get length => _storage.length ~/ 2;
@@ -451,9 +451,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 4` is greater than the length of this object.
*/
- double getFloat32(int byteOffset,
- [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _getFloat32(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+ double getFloat32(int byteOffset, [Endian endian = Endian.big]) =>
+ _getFloat32(byteOffset, Endian.little == endian);
@JSName('getFloat32')
@Returns('double')
@@ -467,9 +466,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 8` is greater than the length of this object.
*/
- double getFloat64(int byteOffset,
- [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _getFloat64(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+ double getFloat64(int byteOffset, [Endian endian = Endian.big]) =>
+ _getFloat64(byteOffset, Endian.little == endian);
@JSName('getFloat64')
@Returns('double')
@@ -485,8 +483,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 2` is greater than the length of this object.
*/
- int getInt16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _getInt16(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+ int getInt16(int byteOffset, [Endian endian = Endian.big]) =>
+ _getInt16(byteOffset, Endian.little == endian);
@JSName('getInt16')
@Returns('int')
@@ -502,8 +500,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 4` is greater than the length of this object.
*/
- int getInt32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _getInt32(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+ int getInt32(int byteOffset, [Endian endian = Endian.big]) =>
+ _getInt32(byteOffset, Endian.little == endian);
@JSName('getInt32')
@Returns('int')
@@ -519,7 +517,7 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 8` is greater than the length of this object.
*/
- int getInt64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) {
+ int getInt64(int byteOffset, [Endian endian = Endian.big]) {
throw new UnsupportedError('Int64 accessor not supported by dart2js.');
}
@@ -542,8 +540,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 2` is greater than the length of this object.
*/
- int getUint16(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _getUint16(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+ int getUint16(int byteOffset, [Endian endian = Endian.big]) =>
+ _getUint16(byteOffset, Endian.little == endian);
@JSName('getUint16')
@Returns('int')
@@ -558,8 +556,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 4` is greater than the length of this object.
*/
- int getUint32(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _getUint32(byteOffset, Endianness.LITTLE_ENDIAN == endian);
+ int getUint32(int byteOffset, [Endian endian = Endian.big]) =>
+ _getUint32(byteOffset, Endian.little == endian);
@JSName('getUint32')
@Returns('int')
@@ -574,7 +572,7 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 8` is greater than the length of this object.
*/
- int getUint64(int byteOffset, [Endianness endian = Endianness.BIG_ENDIAN]) {
+ int getUint64(int byteOffset, [Endian endian = Endian.big]) {
throw new UnsupportedError('Uint64 accessor not supported by dart2js.');
}
@@ -605,9 +603,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 4` is greater than the length of this object.
*/
- void setFloat32(int byteOffset, num value,
- [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _setFloat32(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+ void setFloat32(int byteOffset, num value, [Endian endian = Endian.big]) =>
+ _setFloat32(byteOffset, value, Endian.little == endian);
@JSName('setFloat32')
void _setFloat32(int byteOffset, num value, [bool littleEndian]) native;
@@ -620,9 +617,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 8` is greater than the length of this object.
*/
- void setFloat64(int byteOffset, num value,
- [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _setFloat64(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+ void setFloat64(int byteOffset, num value, [Endian endian = Endian.big]) =>
+ _setFloat64(byteOffset, value, Endian.little == endian);
@JSName('setFloat64')
void _setFloat64(int byteOffset, num value, [bool littleEndian]) native;
@@ -636,9 +632,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 2` is greater than the length of this object.
*/
- void setInt16(int byteOffset, int value,
- [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _setInt16(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+ void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+ _setInt16(byteOffset, value, Endian.little == endian);
@JSName('setInt16')
void _setInt16(int byteOffset, int value, [bool littleEndian]) native;
@@ -652,9 +647,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 4` is greater than the length of this object.
*/
- void setInt32(int byteOffset, int value,
- [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _setInt32(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+ void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+ _setInt32(byteOffset, value, Endian.little == endian);
@JSName('setInt32')
void _setInt32(int byteOffset, int value, [bool littleEndian]) native;
@@ -668,8 +662,7 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 8` is greater than the length of this object.
*/
- void setInt64(int byteOffset, int value,
- [Endianness endian = Endianness.BIG_ENDIAN]) {
+ void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) {
throw new UnsupportedError('Int64 accessor not supported by dart2js.');
}
@@ -693,9 +686,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 2` is greater than the length of this object.
*/
- void setUint16(int byteOffset, int value,
- [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _setUint16(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+ void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+ _setUint16(byteOffset, value, Endian.little == endian);
@JSName('setUint16')
void _setUint16(int byteOffset, int value, [bool littleEndian]) native;
@@ -709,9 +701,8 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 4` is greater than the length of this object.
*/
- void setUint32(int byteOffset, int value,
- [Endianness endian = Endianness.BIG_ENDIAN]) =>
- _setUint32(byteOffset, value, Endianness.LITTLE_ENDIAN == endian);
+ void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+ _setUint32(byteOffset, value, Endian.little == endian);
@JSName('setUint32')
void _setUint32(int byteOffset, int value, [bool littleEndian]) native;
@@ -725,8 +716,7 @@
* Throws [RangeError] if [byteOffset] is negative, or
* `byteOffset + 8` is greater than the length of this object.
*/
- void setUint64(int byteOffset, int value,
- [Endianness endian = Endianness.BIG_ENDIAN]) {
+ void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) {
throw new UnsupportedError('Uint64 accessor not supported by dart2js.');
}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/profile.dart b/pkg/dev_compiler/tool/input_sdk/private/profile.dart
index a325e27..8e3dd82 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/profile.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/profile.dart
@@ -59,7 +59,7 @@
// Ratio between total record count and sampled records count.
var recordRatio = _totalCallRecords / _callMethodRecords.length;
for (var record in _callMethodRecords) {
- var stackStr = JS('String', '#.stack', record.jsError);
+ String stackStr = JS<String>('!', '#.stack', record.jsError);
var frames = stackStr.split('\n');
// Skip first two lines as the first couple frames are from the dart
// runtime.
diff --git a/pkg/dev_compiler/tool/input_sdk/private/string_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/string_helper.dart
index c6f26fc..354716a 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/string_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/string_helper.dart
@@ -11,12 +11,12 @@
@notNull
String substring1Unchecked(receiver, startIndex) {
- return JS('String', '#.substring(#)', receiver, startIndex);
+ return JS('!', '#.substring(#)', receiver, startIndex);
}
@notNull
String substring2Unchecked(receiver, startIndex, endIndex) {
- return JS('String', '#.substring(#, #)', receiver, startIndex, endIndex);
+ return JS('!', '#.substring(#, #)', receiver, startIndex, endIndex);
}
@notNull
@@ -119,7 +119,7 @@
}
@notNull
-String stringReplaceJS(receiver, replacer, replacement) {
+String stringReplaceJS(String receiver, replacer, String replacement) {
// The JavaScript String.replace method recognizes replacement
// patterns in the replacement string. Dart does not have that
// behavior.
@@ -292,7 +292,7 @@
@notNull
String stringReplaceRangeUnchecked(
String receiver, int start, int end, String replacement) {
- var prefix = JS('String', '#.substring(0, #)', receiver, start);
- var suffix = JS('String', '#.substring(#)', receiver, end);
+ String prefix = JS('!', '#.substring(0, #)', receiver, start);
+ String suffix = JS('!', '#.substring(#)', receiver, end);
return "$prefix$replacement$suffix";
}
diff --git a/pkg/dev_compiler/tool/kernel_sdk.dart b/pkg/dev_compiler/tool/kernel_sdk.dart
index 2cc7b9c..f8cb4e7 100755
--- a/pkg/dev_compiler/tool/kernel_sdk.dart
+++ b/pkg/dev_compiler/tool/kernel_sdk.dart
@@ -10,6 +10,7 @@
import 'package:dev_compiler/src/compiler/module_builder.dart';
import 'package:dev_compiler/src/kernel/target.dart';
import 'package:dev_compiler/src/kernel/command.dart';
+import 'package:dev_compiler/src/kernel/compiler.dart';
import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/kernel_generator.dart';
import 'package:kernel/kernel.dart';
@@ -45,7 +46,8 @@
await new Directory(outputDir).create(recursive: true);
await writeComponentToBinary(component, outputPath);
- var jsModule = compileToJSModule(component, [], [], {});
+ var jsModule = new ProgramCompiler(component, declaredVariables: {})
+ .emitProgram(component, [], []);
var moduleFormats = {
'amd': ModuleFormat.amd,
'common': ModuleFormat.common,
diff --git a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
index f5066ed..45bec4f 100644
--- a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
@@ -97,7 +97,7 @@
Future<String> readAsString() async {
List<int> bytes = await readAsBytes();
try {
- return UTF8.decode(bytes);
+ return utf8.decode(bytes);
} on FormatException catch (e) {
throw new FileSystemException(uri, e.message);
}
@@ -118,10 +118,10 @@
/// If no file exists, one is created. If a file exists already, it is
/// overwritten.
void writeAsStringSync(String s) {
- // Note: the return type of UTF8.encode is List<int>, but in practice it
+ // Note: the return type of utf8.encode is List<int>, but in practice it
// always returns Uint8List. We rely on that for efficiency, so that we
// don't have to make an extra copy.
- _update(uri, UTF8.encode(s) as Uint8List);
+ _update(uri, utf8.encode(s) as Uint8List);
}
void _update(Uri uri, Uint8List data) {
diff --git a/pkg/front_end/lib/src/base/api_signature.dart b/pkg/front_end/lib/src/base/api_signature.dart
index f809dbb..80937d6 100644
--- a/pkg/front_end/lib/src/base/api_signature.dart
+++ b/pkg/front_end/lib/src/base/api_signature.dart
@@ -83,7 +83,7 @@
*/
void addDouble(double d) {
_makeRoom(8);
- _data.setFloat64(_offset, d, Endianness.LITTLE_ENDIAN);
+ _data.setFloat64(_offset, d, Endian.little);
_offset += 8;
}
@@ -92,7 +92,7 @@
*/
void addInt(int i) {
_makeRoom(4);
- _data.setUint32(_offset, i, Endianness.LITTLE_ENDIAN);
+ _data.setUint32(_offset, i, Endian.little);
_offset += 4;
}
@@ -100,7 +100,7 @@
* Collect a string.
*/
void addString(String s) {
- List<int> bytes = UTF8.encode(s);
+ List<int> bytes = utf8.encode(s);
addInt(bytes.length);
addBytes(bytes);
}
diff --git a/pkg/front_end/lib/src/base/flat_buffers.dart b/pkg/front_end/lib/src/base/flat_buffers.dart
index 6733ae1..3449a3b 100644
--- a/pkg/front_end/lib/src/base/flat_buffers.dart
+++ b/pkg/front_end/lib/src/base/flat_buffers.dart
@@ -57,19 +57,15 @@
Uint8List _asUint8LIst(int offset, int length) =>
_buffer.buffer.asUint8List(_buffer.offsetInBytes + offset, length);
- double _getFloat64(int offset) =>
- _buffer.getFloat64(offset, Endianness.LITTLE_ENDIAN);
+ double _getFloat64(int offset) => _buffer.getFloat64(offset, Endian.little);
- int _getInt32(int offset) =>
- _buffer.getInt32(offset, Endianness.LITTLE_ENDIAN);
+ int _getInt32(int offset) => _buffer.getInt32(offset, Endian.little);
int _getInt8(int offset) => _buffer.getInt8(offset);
- int _getUint16(int offset) =>
- _buffer.getUint16(offset, Endianness.LITTLE_ENDIAN);
+ int _getUint16(int offset) => _buffer.getUint16(offset, Endian.little);
- int _getUint32(int offset) =>
- _buffer.getUint32(offset, Endianness.LITTLE_ENDIAN);
+ int _getUint32(int offset) => _buffer.getUint32(offset, Endian.little);
int _getUint8(int offset) => _buffer.getUint8(offset);
@@ -453,7 +449,7 @@
if (value != def) {
return _strings.putIfAbsent(value, () {
// TODO(scheglov) optimize for ASCII strings
- List<int> bytes = UTF8.encode(value);
+ List<int> bytes = utf8.encode(value);
int length = bytes.length;
_prepare(4, 1, additionalBytes: length);
Offset<String> result = new Offset(_tail);
@@ -528,15 +524,15 @@
}
static void _setFloat64AtTail(ByteData _buf, int tail, double x) {
- _buf.setFloat64(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+ _buf.setFloat64(_buf.lengthInBytes - tail, x, Endian.little);
}
static void _setInt32AtTail(ByteData _buf, int tail, int x) {
- _buf.setInt32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+ _buf.setInt32(_buf.lengthInBytes - tail, x, Endian.little);
}
static void _setUint32AtTail(ByteData _buf, int tail, int x) {
- _buf.setUint32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+ _buf.setUint32(_buf.lengthInBytes - tail, x, Endian.little);
}
static void _setUint8AtTail(ByteData _buf, int tail, int x) {
@@ -665,7 +661,7 @@
if (_isLatin(bytes)) {
return new String.fromCharCodes(bytes);
}
- return UTF8.decode(bytes);
+ return utf8.decode(bytes);
}
static bool _isLatin(Uint8List bytes) {
@@ -941,14 +937,14 @@
*/
void output(ByteData buf, int bufOffset) {
// VTable size.
- buf.setUint16(bufOffset, numOfUint16 * 2, Endianness.LITTLE_ENDIAN);
+ buf.setUint16(bufOffset, numOfUint16 * 2, Endian.little);
bufOffset += 2;
// Table size.
- buf.setUint16(bufOffset, tableSize, Endianness.LITTLE_ENDIAN);
+ buf.setUint16(bufOffset, tableSize, Endian.little);
bufOffset += 2;
// Field offsets.
for (int fieldOffset in fieldOffsets) {
- buf.setUint16(bufOffset, fieldOffset, Endianness.LITTLE_ENDIAN);
+ buf.setUint16(bufOffset, fieldOffset, Endian.little);
bufOffset += 2;
}
}
diff --git a/pkg/front_end/lib/src/base/libraries_specification.dart b/pkg/front_end/lib/src/base/libraries_specification.dart
index addde5e..2f9f553 100644
--- a/pkg/front_end/lib/src/base/libraries_specification.dart
+++ b/pkg/front_end/lib/src/base/libraries_specification.dart
@@ -88,7 +88,7 @@
/// close attention to change them consistently.
// TODO(sigmund): move this file to a shared package.
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
import '../fasta/util/relativize.dart';
@@ -122,7 +122,7 @@
if (json == null) return const LibrariesSpecification();
var jsonData;
try {
- var data = JSON.decode(json);
+ var data = jsonDecode(json);
if (data is! Map) {
return _reportError('top-level specification is not a map');
}
@@ -196,7 +196,7 @@
/// Serialize this specification to json.
///
/// If possible serializes paths relative to [outputUri].
- String toJsonString(Uri outputUri) => JSON.encode(toJsonMap(outputUri));
+ String toJsonString(Uri outputUri) => jsonEncode(toJsonMap(outputUri));
Map toJsonMap(Uri outputUri) {
var result = {};
diff --git a/pkg/front_end/lib/src/byte_store/protected_file_byte_store.dart b/pkg/front_end/lib/src/byte_store/protected_file_byte_store.dart
index ccc2480..44d9156 100644
--- a/pkg/front_end/lib/src/byte_store/protected_file_byte_store.dart
+++ b/pkg/front_end/lib/src/byte_store/protected_file_byte_store.dart
@@ -133,7 +133,7 @@
static String _keysReadText(RandomAccessFile file) {
file.setPositionSync(0);
List<int> bytes = file.readSync(file.lengthSync());
- return UTF8.decode(bytes);
+ return utf8.decode(bytes);
}
static void _keysWrite(RandomAccessFile file, ProtectedKeys keys) {
diff --git a/pkg/front_end/lib/src/fasta/colors.dart b/pkg/front_end/lib/src/fasta/colors.dart
index c993caa..a59fe06 100644
--- a/pkg/front_end/lib/src/fasta/colors.dart
+++ b/pkg/front_end/lib/src/fasta/colors.dart
@@ -6,7 +6,7 @@
// merge these two packages.
library colors;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonEncode;
import 'dart:io' show Platform, Process, ProcessResult, stderr, stdout;
@@ -166,7 +166,7 @@
if (lines.length != 2) {
if (context.options.verbose) {
print("Not enabling colors, unexpected output from tput: "
- "${JSON.encode(result.stdout)}.");
+ "${jsonEncode(result.stdout)}.");
}
return false;
}
@@ -175,7 +175,7 @@
if (int.parse(numberOfColors, onError: (_) => -1) < 8) {
if (context.options.verbose) {
print("Not enabling colors, less than 8 colors supported: "
- "${JSON.encode(numberOfColors)}.");
+ "${jsonEncode(numberOfColors)}.");
}
return false;
}
@@ -184,7 +184,7 @@
if (ALL_CODES != allCodes) {
if (context.options.verbose) {
print("Not enabling colors, color codes don't match: "
- "${JSON.encode(ALL_CODES)} != ${JSON.encode(allCodes)}.");
+ "${jsonEncode(ALL_CODES)} != ${jsonEncode(allCodes)}.");
}
return false;
}
diff --git a/pkg/front_end/lib/src/fasta/deprecated_problems.dart b/pkg/front_end/lib/src/fasta/deprecated_problems.dart
index 935e73f..8ec0ce2 100644
--- a/pkg/front_end/lib/src/fasta/deprecated_problems.dart
+++ b/pkg/front_end/lib/src/fasta/deprecated_problems.dart
@@ -6,7 +6,7 @@
import 'dart:async' show Future;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonEncode;
import 'dart:io'
show ContentType, HttpClient, HttpClientRequest, SocketException, stderr;
@@ -116,7 +116,7 @@
if (charOffset != null) data["offset"] = charOffset;
data["error"] = safeToString(error);
data["trace"] = "$trace";
- String json = JSON.encode(data);
+ String json = jsonEncode(data);
HttpClient client = new HttpClient();
try {
Uri serverUri = Uri.parse(defaultServerAddress);
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index f6c436d..2b6c733 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -4,7 +4,7 @@
library fasta.dill_library_builder;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode;
import 'package:kernel/ast.dart'
show
@@ -87,7 +87,7 @@
if (name == "_exports#") {
Field field = member;
StringLiteral string = field.initializer;
- unserializableExports = JSON.decode(string.value);
+ unserializableExports = jsonDecode(string.value);
} else {
addBuilder(name, new DillMemberBuilder(member, this), member.fileOffset);
}
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 55c6075..41f5b16 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -1299,20 +1299,84 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)> templateDuplicatedName =
const Template<Message Function(String name)>(
- messageTemplate: r"""Duplicated name: '#name'.""",
+ messageTemplate: r"""'#name' is already declared in this scope.""",
withArguments: _withArgumentsDuplicatedName);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name)> codeDuplicatedName =
const Code<Message Function(String name)>(
- "DuplicatedName",
- templateDuplicatedName,
-);
+ "DuplicatedName", templateDuplicatedName,
+ severity: Severity.error);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsDuplicatedName(String name) {
return new Message(codeDuplicatedName,
- message: """Duplicated name: '$name'.""", arguments: {'name': name});
+ message: """'$name' is already declared in this scope.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)> templateDuplicatedNameCause =
+ const Template<Message Function(String name)>(
+ messageTemplate: r"""Previous declaration of '#name'.""",
+ withArguments: _withArgumentsDuplicatedNameCause);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeDuplicatedNameCause =
+ const Code<Message Function(String name)>(
+ "DuplicatedNameCause", templateDuplicatedNameCause,
+ severity: Severity.context);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsDuplicatedNameCause(String name) {
+ return new Message(codeDuplicatedNameCause,
+ message: """Previous declaration of '$name'.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String
+ name)> templateDuplicatedNamePreviouslyUsed = const Template<
+ Message Function(String name)>(
+ messageTemplate:
+ r"""Can't declare '#name' because it was already used in this scope.""",
+ withArguments: _withArgumentsDuplicatedNamePreviouslyUsed);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeDuplicatedNamePreviouslyUsed =
+ const Code<Message Function(String name)>(
+ "DuplicatedNamePreviouslyUsed", templateDuplicatedNamePreviouslyUsed,
+ severity: Severity.error);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsDuplicatedNamePreviouslyUsed(String name) {
+ return new Message(codeDuplicatedNamePreviouslyUsed,
+ message:
+ """Can't declare '$name' because it was already used in this scope.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+ templateDuplicatedNamePreviouslyUsedCause =
+ const Template<Message Function(String name)>(
+ messageTemplate: r"""Previous use of '#name'.""",
+ withArguments: _withArgumentsDuplicatedNamePreviouslyUsedCause);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+ codeDuplicatedNamePreviouslyUsedCause =
+ const Code<Message Function(String name)>(
+ "DuplicatedNamePreviouslyUsedCause",
+ templateDuplicatedNamePreviouslyUsedCause,
+ severity: Severity.context);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsDuplicatedNamePreviouslyUsedCause(String name) {
+ return new Message(codeDuplicatedNamePreviouslyUsedCause,
+ message: """Previous use of '$name'.""", arguments: {'name': name});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -4574,25 +4638,6 @@
tip: r"""Try moving the prefix before the combinators.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name)> templatePreviousUseOfName =
- const Template<Message Function(String name)>(
- messageTemplate: r"""Previous use of '#name'.""",
- withArguments: _withArgumentsPreviousUseOfName);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codePreviousUseOfName =
- const Code<Message Function(String name)>(
- "PreviousUseOfName",
- templatePreviousUseOfName,
-);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsPreviousUseOfName(String name) {
- return new Message(codePreviousUseOfName,
- message: """Previous use of '$name'.""", arguments: {'name': name});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codePrivateNamedParameter = messagePrivateNamedParameter;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 0ad547e..17a2764 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -157,21 +157,21 @@
await userCode.buildComponent(verify: c.options.verify);
} on KernelIncrementalTargetErroneousComponent {
List<Library> librariesWithSdk = userCode.component.libraries;
- List<Library> libraries = <Library>[];
+ List<Library> compiledLibraries = <Library>[];
for (Library lib in librariesWithSdk) {
if (lib.importUri.scheme == "dart") continue;
- libraries.add(lib);
+ compiledLibraries.add(lib);
break;
}
userCode.loader.builders.clear();
userCode = userCodeOld;
return new Component(
- libraries: libraries, uriToSource: <Uri, Source>{});
+ libraries: compiledLibraries, uriToSource: <Uri, Source>{});
}
userCodeOld?.loader?.builders?.clear();
userCodeOld = null;
- List<Library> libraries =
+ List<Library> compiledLibraries =
new List<Library>.from(userCode.loader.libraries);
Map<Uri, Source> uriToSource =
new Map<Uri, Source>.from(dillLoadedDataUriToSource);
@@ -180,28 +180,32 @@
? data.userLoadedUriMain
: componentWithDill.mainMethod;
+ List<Library> outputLibraries;
if (data.includeUserLoadedLibraries || fullComponent) {
- addReusedLibraries(
- libraries, mainMethod, entryPoint, reusedLibraries, data);
+ outputLibraries = computeTransitiveClosure(
+ compiledLibraries, mainMethod, entryPoint, reusedLibraries, data);
+ } else {
+ outputLibraries = compiledLibraries;
}
// Clean up.
userCode.loader.releaseAncillaryResources();
// This is the incremental component.
- return new Component(libraries: libraries, uriToSource: uriToSource)
+ return new Component(libraries: outputLibraries, uriToSource: uriToSource)
..mainMethod = mainMethod;
});
}
- void addReusedLibraries(
- List<Library> libraries,
+ List<Library> computeTransitiveClosure(
+ List<Library> inputLibraries,
Procedure mainMethod,
Uri entry,
List<LibraryBuilder> reusedLibraries,
IncrementalCompilerData data) {
+ List<Library> result = new List<Library>.from(inputLibraries);
Map<Uri, Library> libraryMap = <Uri, Library>{};
- for (Library library in libraries) {
+ for (Library library in inputLibraries) {
libraryMap[library.importUri] = library;
}
List<Uri> worklist = new List<Uri>.from(libraryMap.keys);
@@ -228,7 +232,7 @@
libraryMap.remove(uri);
Library library = potentiallyReferencedLibraries.remove(uri);
if (library != null) {
- libraries.add(library);
+ result.add(library);
}
}
}
@@ -238,16 +242,7 @@
userCode.loader.builders.remove(uri);
}
- // For now ensure original order of libraries to produce bit-perfect
- // output.
- libraries.sort((a, b) {
- int aOrder = data.importUriToOrder[a.importUri];
- int bOrder = data.importUriToOrder[b.importUri];
- if (aOrder != null && bOrder != null) return aOrder - bOrder;
- if (aOrder != null) return -1;
- if (bOrder != null) return 1;
- return 0;
- });
+ return result;
}
int prepareSummary(List<int> summaryBytes, UriTranslator uriTranslator,
@@ -279,8 +274,6 @@
if (await entity.exists()) {
List<int> initializationBytes = await entity.readAsBytes();
if (initializationBytes != null) {
- Set<Uri> prevLibraryUris = new Set<Uri>.from(
- data.component.libraries.map((Library lib) => lib.importUri));
ticker.logMs("Read $initializeFromDillUri");
Set<Uri> sdkUris = data.component.uriToSource.keys.toSet();
@@ -306,10 +299,6 @@
initializedFromDill = true;
bytesLength += initializationBytes.length;
- for (Library lib in data.component.libraries) {
- if (prevLibraryUris.contains(lib.importUri)) continue;
- data.importUriToOrder[lib.importUri] = data.importUriToOrder.length;
- }
data.userLoadedUriMain = data.component.mainMethod;
data.includeUserLoadedLibraries = true;
for (Uri uri in data.component.uriToSource.keys) {
@@ -354,9 +343,7 @@
return false;
}
- // Compute [builders] and [invalidatedImportUris].
- addBuilderAndInvalidateUris(Uri uri, LibraryBuilder library,
- [bool recursive = true]) {
+ addBuilderAndInvalidateUris(Uri uri, LibraryBuilder library) {
builders[uri] = library;
if (isInvalidated(uri, library.target.fileUri)) {
invalidatedImportUris.add(uri);
@@ -448,7 +435,6 @@
class IncrementalCompilerData {
bool includeUserLoadedLibraries;
- Map<Uri, int> importUriToOrder;
Procedure userLoadedUriMain;
Component component;
@@ -458,7 +444,6 @@
reset() {
includeUserLoadedLibraries = false;
- importUriToOrder = <Uri, int>{};
userLoadedUriMain = null;
component = null;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index d446340..0170666 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -14,7 +14,7 @@
import '../messages.dart' as messages show getLocationFromUri;
-import '../modifier.dart' show Modifier, constMask, finalMask;
+import '../modifier.dart' show Modifier, constMask, covariantMask, finalMask;
import '../parser.dart'
show
@@ -340,40 +340,53 @@
switchScope = outerSwitchScope;
}
- void declareVariable(VariableDeclaration variable, Scope scope) {
- // ignore: UNUSED_LOCAL_VARIABLE
- Statement discardedStatement;
+ void wrapVariableInitializerInError(
+ VariableDeclaration variable,
+ Template<Message Function(String name)> template,
+ List<LocatedMessage> context) {
String name = variable.name;
int offset = variable.fileOffset;
- if (scope.local[name] != null) {
+ Message message = template.withArguments(name);
+ if (variable.initializer == null) {
+ variable.initializer =
+ buildCompileTimeError(message, offset, name.length, context: context)
+ ..parent = variable;
+ } else {
+ variable.initializer = wrapInLocatedCompileTimeError(
+ variable.initializer, message.withLocation(uri, offset, name.length),
+ context: context)
+ ..parent = variable;
+ }
+ }
+
+ void declareVariable(VariableDeclaration variable, Scope scope) {
+ String name = variable.name;
+ Builder existing = scope.local[name];
+ if (existing != null) {
// This reports an error for duplicated declarations in the same scope:
// `{ var x; var x; }`
- discardedStatement = pop(); // TODO(ahe): Issue 29717.
- push(deprecated_buildCompileTimeErrorStatement(
- "'$name' already declared in this scope.", offset));
+ wrapVariableInitializerInError(
+ variable, fasta.templateDuplicatedName, <LocatedMessage>[
+ fasta.templateDuplicatedNameCause
+ .withArguments(name)
+ .withLocation(uri, existing.charOffset, name.length)
+ ]);
return;
}
- LocatedMessage error = scope.declare(
+ LocatedMessage context = scope.declare(
variable.name,
new KernelVariableBuilder(
variable, member ?? classBuilder ?? library, uri),
- variable.fileOffset,
uri);
- if (error != null) {
+ if (context != null) {
// This case is different from the above error. In this case, the problem
// is using `x` before it's declared: `{ var x; { print(x); var x;
// }}`. In this case, we want two errors, the `x` in `print(x)` and the
// second (or innermost declaration) of `x`.
- discardedStatement = pop(); // TODO(ahe): Issue 29717.
-
- // Reports the error on the last declaration of `x`.
- push(deprecated_buildCompileTimeErrorStatement(
- "Can't declare '$name' because it was already used in this scope.",
- offset));
-
- // Reports the error on `print(x)`.
- library.addCompileTimeError(
- error.messageObject, error.charOffset, error.length, error.uri);
+ wrapVariableInitializerInError(
+ variable,
+ fasta.templateDuplicatedNamePreviouslyUsed,
+ <LocatedMessage>[context]);
}
}
@@ -2065,6 +2078,13 @@
}
@override
+ void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+ Token varFinalOrConst) {
+ push((covariantToken != null ? covariantMask : 0) |
+ Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme));
+ }
+
+ @override
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
debugEvent("FormalParameter");
@@ -2077,7 +2097,7 @@
}
Identifier name = pop();
DartType type = pop();
- int modifiers = Modifier.validate(pop());
+ int modifiers = pop();
if (inCatchClause) {
modifiers |= finalMask;
}
@@ -2910,29 +2930,40 @@
variable.type = function.functionType;
if (isFunctionExpression) {
+ Expression oldInitializer = variable.initializer;
variable.initializer = new ShadowFunctionExpression(function)
..parent = variable
..fileOffset = formals.charOffset;
exitLocalScope();
- push(new ShadowNamedFunctionExpression(variable));
+ Expression expression = new ShadowNamedFunctionExpression(variable);
+ if (oldInitializer != null) {
+ // This must have been a compile-time error.
+ assert(isErroneousNode(oldInitializer));
+
+ push(new Let(
+ new VariableDeclaration.forValue(oldInitializer)
+ ..fileOffset = expression.fileOffset,
+ expression)
+ ..fileOffset = expression.fileOffset);
+ } else {
+ push(expression);
+ }
} else {
declaration.function = function;
function.parent = declaration;
- push(declaration);
- }
- } else if (declaration is ExpressionStatement) {
- // If [declaration] isn't a [FunctionDeclaration], it must be because
- // there was a compile-time error.
- // TODO(askesc): Be more specific about the error code when we have
- // errors represented as explicit invalid nodes.
- assert(library.loader.handledErrors.isNotEmpty);
+ if (variable.initializer != null) {
+ // This must have been a compile-time error.
+ assert(isErroneousNode(variable.initializer));
- // TODO(paulberry,ahe): ensure that when integrating with analyzer, type
- // inference is still performed for the dropped declaration.
- if (isFunctionExpression) {
- push(declaration.expression);
- } else {
- push(declaration);
+ push(new Block(<Statement>[
+ new ExpressionStatement(variable.initializer),
+ declaration
+ ])
+ ..fileOffset = declaration.fileOffset);
+ variable.initializer = null;
+ } else {
+ push(declaration);
+ }
}
} else {
return unhandled("${declaration.runtimeType}", "pushNamedFunction",
@@ -3216,6 +3247,8 @@
break;
case Assert.Expression:
+ // The parser has already reported an error indicating that assert
+ // cannot be used in an expression.
push(deprecated_buildCompileTimeError(
"`assert` can't be used as an expression."));
break;
@@ -3518,20 +3551,6 @@
}
@override
- void handleModifier(Token token) {
- debugEvent("Modifier");
- // TODO(ahe): Copied from outline_builder.dart.
- push(new Modifier.fromString(token.stringValue));
- }
-
- @override
- void handleModifiers(int count) {
- debugEvent("Modifiers");
- // TODO(ahe): Copied from outline_builder.dart.
- push(popList(count) ?? NullValue.Modifiers);
- }
-
- @override
void handleRecoverableError(
Message message, Token startToken, Token endToken) {
if (message == fasta.messageNativeClauseShouldBeAnnotation) {
@@ -3933,7 +3952,7 @@
Expression wrapInDeferredCheck(
Expression expression, KernelPrefixBuilder prefix, int charOffset) {
var check = new VariableDeclaration.forValue(
- new CheckLibraryIsLoaded(prefix.dependency))
+ forest.checkLibraryIsLoaded(prefix.dependency))
..fileOffset = charOffset;
return new ShadowDeferredCheck(check, expression);
}
@@ -3944,6 +3963,11 @@
node.fileOffset = offset;
return object;
}
+
+ bool isErroneousNode(TreeNode node) {
+ return library.loader.handledErrors.isNotEmpty &&
+ forest.isErroneousNode(node);
+ }
}
class Identifier {
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 6aff6ed..566ee45 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -11,10 +11,15 @@
Arguments,
DartType,
Expression,
+ ExpressionStatement,
+ InvalidExpression,
+ Let,
+ LibraryDependency,
MapEntry,
NamedExpression,
Statement,
- TreeNode;
+ TreeNode,
+ VariableDeclaration;
import '../parser.dart' show offsetForToken;
@@ -24,13 +29,16 @@
show
ShadowArguments,
ShadowBoolLiteral,
+ ShadowCheckLibraryIsLoaded,
ShadowDoubleLiteral,
ShadowIntLiteral,
ShadowListLiteral,
+ ShadowLoadLibrary,
ShadowMapLiteral,
ShadowNullLiteral,
ShadowStringLiteral,
ShadowSymbolLiteral,
+ ShadowSyntheticExpression,
ShadowTypeLiteral;
import 'forest.dart' show Forest;
@@ -135,4 +143,35 @@
@override
int readOffset(TreeNode node) => node.fileOffset;
+
+ @override
+ Expression loadLibrary(LibraryDependency dependency) {
+ return new ShadowLoadLibrary(dependency);
+ }
+
+ @override
+ Expression checkLibraryIsLoaded(LibraryDependency dependency) {
+ return new ShadowCheckLibraryIsLoaded(dependency);
+ }
+
+ @override
+ bool isErroneousNode(TreeNode node) {
+ if (node is ExpressionStatement) {
+ ExpressionStatement statement = node;
+ node = statement.expression;
+ }
+ if (node is VariableDeclaration) {
+ VariableDeclaration variable = node;
+ node = variable.initializer;
+ }
+ if (node is ShadowSyntheticExpression) {
+ ShadowSyntheticExpression synth = node;
+ node = synth.desugared;
+ }
+ if (node is Let) {
+ Let let = node;
+ node = let.variable.initializer;
+ }
+ return node is InvalidExpression;
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
index 07560d3..79859e9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
@@ -922,7 +922,7 @@
helper.addProblemErrorIfConst(
messageLoadLibraryTakesNoArguments, offset, 'loadLibrary'.length);
}
- return builder.createLoadLibrary(offset);
+ return builder.createLoadLibrary(offset, forest);
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 0656e8c..c9a526c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -50,6 +50,12 @@
int readOffset(covariant node);
+ Expression loadLibrary(covariant dependency);
+
+ Expression checkLibraryIsLoaded(covariant dependency);
+
+ bool isErroneousNode(covariant node);
+
// TODO(ahe): Remove this method when all users are moved here.
kernel.Arguments castArguments(Arguments arguments) {
dynamic a = arguments;
diff --git a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
index 7bbec74..e44e72d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
@@ -707,7 +707,8 @@
: super(helper, token);
Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- var read = helper.makeStaticGet(builder.createTearoffMethod(), token);
+ var read =
+ helper.makeStaticGet(builder.createTearoffMethod(helper.forest), token);
complexAssignment?.read = read;
return read;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 2d41321..4742c42 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -4,7 +4,7 @@
library fasta.kernel_library_builder;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonEncode;
import 'package:kernel/ast.dart';
@@ -840,7 +840,7 @@
if (unserializableExports != null) {
library.addMember(new Field(new Name("_exports#", library),
- initializer: new StringLiteral(JSON.encode(unserializableExports)),
+ initializer: new StringLiteral(jsonEncode(unserializableExports)),
isStatic: true,
isConst: true));
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index ecd17f9..36c7523 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -2382,6 +2382,27 @@
}
}
+/// Concrete shadow object representing a deferred load library call.
+class ShadowLoadLibrary extends LoadLibrary implements ShadowExpression {
+ ShadowLoadLibrary(LibraryDependency import) : super(import);
+
+ @override
+ DartType _inferExpression(ShadowTypeInferrer inferrer, DartType typeContext) {
+ return super.getStaticType(inferrer.typeSchemaEnvironment);
+ }
+}
+
+/// Concrete shadow object representing a deferred library-is-loaded check.
+class ShadowCheckLibraryIsLoaded extends CheckLibraryIsLoaded
+ implements ShadowExpression {
+ ShadowCheckLibraryIsLoaded(LibraryDependency import) : super(import);
+
+ @override
+ DartType _inferExpression(ShadowTypeInferrer inferrer, DartType typeContext) {
+ return super.getStaticType(inferrer.typeSchemaEnvironment);
+ }
+}
+
/// The result of inference for a RHS of an assignment.
class _ComplexAssignmentInferenceResult {
/// The resolved combiner [Procedure], e.g. `operator+` for `a += 2`, or
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_variable_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_variable_builder.dart
index 9dd42e2..65a3f94 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_variable_builder.dart
@@ -16,6 +16,9 @@
: variable = variable,
super(parent, variable.fileOffset, fileUri);
+ @override
+ int get charOffset => variable.fileOffset;
+
bool get isLocal => true;
bool get isConst => variable.isConst;
diff --git a/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
index 57eace4..67a9e22 100644
--- a/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
@@ -16,9 +16,9 @@
ProcedureKind,
ReturnStatement;
-import '../builder/builder.dart' show Builder;
+import 'kernel_builder.dart' show Builder, KernelLibraryBuilder;
-import 'kernel_library_builder.dart' show KernelLibraryBuilder;
+import 'forest.dart' show Forest;
/// Builder to represent the `deferLibrary.loadLibrary` calls and tear-offs.
class LoadLibraryBuilder extends Builder {
@@ -36,13 +36,13 @@
LoadLibraryBuilder(this.parent, this.importDependency, this.charOffset)
: super(parent, charOffset, parent.fileUri);
- LoadLibrary createLoadLibrary(int charOffset) {
- return new LoadLibrary(importDependency)..fileOffset = charOffset;
+ LoadLibrary createLoadLibrary(int charOffset, Forest forest) {
+ return forest.loadLibrary(importDependency)..fileOffset = charOffset;
}
- Procedure createTearoffMethod() {
+ Procedure createTearoffMethod(Forest forest) {
if (tearoff != null) return tearoff;
- LoadLibrary expression = createLoadLibrary(charOffset);
+ LoadLibrary expression = createLoadLibrary(charOffset, forest);
String prefix = expression.import.name;
tearoff = new Procedure(
new Name('__loadLibrary_$prefix', parent.target),
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index ac10060..aaac6e7 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -179,8 +179,7 @@
builders.forEach((Uri uri, LibraryBuilder library) {
if (library.loader == this) libraryCount++;
});
- double ms =
- elapsed.inMicroseconds / Duration.MICROSECONDS_PER_MILLISECOND;
+ double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
Message message = template.withArguments(
libraryCount,
byteCount,
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 6e9fb76..4cb980b 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -172,8 +172,10 @@
}
@override
- void beginFormalParameter(Token token, MemberKind kind) {
- listener?.beginFormalParameter(token, kind);
+ void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+ Token varFinalOrConst) {
+ listener?.beginFormalParameter(
+ token, kind, covariantToken, varFinalOrConst);
}
@override
@@ -1099,16 +1101,6 @@
}
@override
- void handleModifier(Token token) {
- listener?.handleModifier(token);
- }
-
- @override
- void handleModifiers(int count) {
- listener?.handleModifiers(count);
- }
-
- @override
void handleNamedArgument(Token colon) {
listener?.handleNamedArgument(colon);
}
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index aa0a7be..b72575b 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -29,12 +29,12 @@
/// Identifier is the start of a dotted name in a conditional import or
/// export.
- static const dottedName = const IdentifierContext('dottedName');
+ static const dottedName = const DottedNameIdentifierContext();
/// Identifier is part of a dotted name in a conditional import or export, but
/// it's not the first identifier of the dotted name.
static const dottedNameContinuation =
- const IdentifierContext('dottedNameContinuation', isContinuation: true);
+ const DottedNameIdentifierContext.continuation();
/// Identifier is one of the shown/hidden names in an import/export
/// combinator.
@@ -105,10 +105,8 @@
/// Identifier is the name being declared by a class declaration or a named
/// mixin application, for example, `Foo` in `class Foo = X with Y;`.
- static const classOrNamedMixinDeclaration = const IdentifierContext(
- 'classOrNamedMixinDeclaration',
- inDeclaration: true,
- isBuiltInIdentifierAllowed: false);
+ static const classOrNamedMixinDeclaration =
+ const ClassOrNamedMixinIdentifierContext();
/// Identifier is the name of a type variable being declared (e.g. `Foo` in
/// `class C<Foo extends num> {}`).
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index 0f22616..8922d33 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -17,6 +17,73 @@
import 'util.dart' show optional;
+/// See [IdentifierContext].classOrNamedMixin
+class ClassOrNamedMixinIdentifierContext extends IdentifierContext {
+ const ClassOrNamedMixinIdentifierContext()
+ : super('classOrNamedMixinDeclaration',
+ inDeclaration: true, isBuiltInIdentifierAllowed: false);
+
+ @override
+ Token ensureIdentifier(Token token, Parser parser) {
+ Token identifier = token.next;
+ assert(identifier.kind != IDENTIFIER_TOKEN);
+ if (identifier.type.isPseudo) {
+ return identifier;
+ }
+
+ if (looksLikeStartOfNextDeclaration(identifier) ||
+ isOneOfOrEof(
+ identifier, const ['<', '{', 'extends', 'with', 'implements'])) {
+ identifier = parser.insertSyntheticIdentifier(token, this,
+ message: fasta.templateExpectedIdentifier.withArguments(identifier));
+ } else if (identifier.type.isBuiltIn) {
+ parser.reportRecoverableErrorWithToken(
+ identifier, fasta.templateBuiltInIdentifierAsType);
+ } else {
+ parser.reportRecoverableErrorWithToken(
+ identifier, fasta.templateExpectedIdentifier);
+ if (!identifier.isKeywordOrIdentifier) {
+ // When in doubt, consume the token to ensure we make progress
+ // but insert a synthetic identifier to satisfy listeners.
+ identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ }
+ }
+ return identifier;
+ }
+}
+
+/// See [IdentifierContext].dottedName
+class DottedNameIdentifierContext extends IdentifierContext {
+ const DottedNameIdentifierContext() : super('dottedName');
+
+ const DottedNameIdentifierContext.continuation()
+ : super('dottedNameContinuation', isContinuation: true);
+
+ @override
+ Token ensureIdentifier(Token token, Parser parser) {
+ Token identifier = token.next;
+ assert(identifier.kind != IDENTIFIER_TOKEN);
+ if (identifier.isIdentifier) {
+ return identifier;
+ }
+
+ if (looksLikeStartOfNextDeclaration(identifier) ||
+ isOneOfOrEof(identifier, const ['.', '==', ')'])) {
+ identifier = parser.insertSyntheticIdentifier(token, this,
+ message: fasta.templateExpectedIdentifier.withArguments(identifier));
+ } else {
+ parser.reportRecoverableErrorWithToken(
+ identifier, fasta.templateExpectedIdentifier);
+ if (!identifier.isKeywordOrIdentifier) {
+ // When in doubt, consume the token to ensure we make progress
+ // but insert a synthetic identifier to satisfy listeners.
+ identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ }
+ }
+ return identifier;
+ }
+}
+
/// See [IdentifierContext].expression
class ExpressionIdentifierContext extends IdentifierContext {
const ExpressionIdentifierContext()
@@ -56,7 +123,7 @@
parser.reportRecoverableErrorWithToken(
next, fasta.templateExpectedIdentifier);
if (next.isKeywordOrIdentifier) {
- if (!isOneOfOrEof(next, ['as', 'is'])) {
+ if (!isOneOfOrEof(next, const ['as', 'is'])) {
return next;
}
} else if (!next.isOperator &&
@@ -109,15 +176,6 @@
}
return identifier;
}
-
- bool looksLikeStartOfNextDeclaration(Token token) =>
- token.isTopLevelKeyword ||
- optional('const', token) ||
- optional('get', token) ||
- optional('final', token) ||
- optional('set', token) ||
- optional('var', token) ||
- optional('void', token);
}
/// See [IdentifierContext].typeReference
@@ -201,3 +259,7 @@
}
return token.isEof;
}
+
+bool looksLikeStartOfNextDeclaration(Token token) =>
+ token.isTopLevelKeyword ||
+ isOneOfOrEof(token, const ['const', 'get', 'final', 'set', 'var', 'void']);
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 19ed1b1..79786ca 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -232,7 +232,8 @@
logEvent("FactoryMethod");
}
- void beginFormalParameter(Token token, MemberKind kind) {}
+ void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+ Token varFinalOrConst) {}
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
@@ -1059,14 +1060,6 @@
logEvent("LiteralNull");
}
- void handleModifier(Token token) {
- logEvent("Modifier");
- }
-
- void handleModifiers(int count) {
- logEvent("Modifiers");
- }
-
void handleNativeClause(Token nativeToken, bool hasName) {
logEvent("NativeClause");
}
diff --git a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
index 4b23332..9bf2da1 100644
--- a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
@@ -4,8 +4,6 @@
import '../../scanner/token.dart' show Token;
import '../messages.dart' as fasta;
-import 'formal_parameter_kind.dart' show FormalParameterKind;
-import 'member_kind.dart' show MemberKind;
import 'parser.dart' show Parser;
import 'type_continuation.dart' show TypeContinuation;
import 'util.dart' show optional;
@@ -33,12 +31,15 @@
TypeContinuation typeContinuationAfterVar(TypeContinuation typeContinuation) {
switch (typeContinuation) {
case TypeContinuation.NormalFormalParameter:
+ case TypeContinuation.NormalFormalParameterAfterVar:
return TypeContinuation.NormalFormalParameterAfterVar;
case TypeContinuation.OptionalPositionalFormalParameter:
+ case TypeContinuation.OptionalPositionalFormalParameterAfterVar:
return TypeContinuation.OptionalPositionalFormalParameterAfterVar;
case TypeContinuation.NamedFormalParameter:
+ case TypeContinuation.NamedFormalParameterAfterVar:
return TypeContinuation.NamedFormalParameterAfterVar;
default:
@@ -47,163 +48,8 @@
}
/// This class is used to parse modifiers in most locations where modifiers
-/// can occur. However, it isn't used when parsing a class or when parsing
-/// the modifiers of a member function (non-local),
-/// but is used when parsing their formal parameters.
-class ModifierContext {
- final Parser parser;
- MemberKind memberKind;
-
- /// When parsing the formal parameters of any function,
- /// [parameterKind] is non-null.
- final FormalParameterKind parameterKind;
-
- final bool isVarAllowed;
- TypeContinuation typeContinuation;
- int modifierCount = 0;
- Token varFinalOrConst;
-
- ModifierContext(this.parser, this.memberKind, this.parameterKind,
- this.isVarAllowed, this.typeContinuation);
-
- bool get isCovariantFinalAllowed =>
- memberKind != MemberKind.StaticField &&
- memberKind != MemberKind.NonStaticField;
-
- Token parseConst(Token token) {
- Token next = token.next;
- assert(optional('const', next));
- if (!isVarAllowed) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateExtraneousModifier);
- // TODO(danrubel): investigate why token must be included (fall through)
- // so that tests will pass. I think that it should not be included
- // because the 'const' is invalid in this situation.
- //
- // return token.next;
- }
- typeContinuation ??= TypeContinuation.Optional;
- varFinalOrConst ??= next;
- modifierCount++;
- return parser.parseModifier(token);
- }
-
- Token parseCovariantOpt(Token token) {
- Token next = token.next;
- assert(optional('covariant', next));
- // A built-in identifier can only be a modifier as long as it is
- // followed by another modifier or an identifier.
- // Otherwise, it is the identifier.
- if (!next.next.isKeywordOrIdentifier) {
- return token;
- }
- switch (memberKind) {
- case MemberKind.Local:
- case MemberKind.StaticField:
- case MemberKind.StaticMethod:
- case MemberKind.TopLevelField:
- case MemberKind.TopLevelMethod:
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateExtraneousModifier);
- return next;
-
- default:
- modifierCount++;
- return parser.parseModifier(token);
- }
- }
-
- Token parseExternalOpt(Token token) {
- Token next = token.next;
- assert(optional('external', next));
- // A built-in identifier can only be a modifier as long as it is
- // followed by another modifier or an identifier.
- // Otherwise, it is the identifier.
- if (!next.next.isKeywordOrIdentifier) {
- return token;
- }
- switch (memberKind) {
- case MemberKind.Factory:
- case MemberKind.NonStaticMethod:
- case MemberKind.StaticMethod:
- case MemberKind.TopLevelMethod:
- modifierCount++;
- return parser.parseModifier(token);
-
- case MemberKind.StaticField:
- case MemberKind.NonStaticField:
- parser.reportRecoverableError(next, fasta.messageExternalField);
- return next;
-
- default:
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateExtraneousModifier);
- return next;
- }
- }
-
- Token parseFinal(Token token) {
- Token next = token.next;
- assert(optional('final', next));
- if (!isVarAllowed && parameterKind == null) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateExtraneousModifier);
- return next;
- }
- typeContinuation ??= TypeContinuation.Optional;
- varFinalOrConst ??= next;
- modifierCount++;
- return parser.parseModifier(token);
- }
-
- Token parseStaticOpt(Token token) {
- Token next = token.next;
- assert(optional('static', next));
- // A built-in identifier can only be a modifier as long as it is
- // followed by another modifier or an identifier.
- // Otherwise, it is the identifier.
- if (!next.next.isKeywordOrIdentifier) {
- return token;
- }
- if (parameterKind != null) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateExtraneousModifier);
- return next;
- }
- switch (memberKind) {
- case MemberKind.NonStaticMethod:
- memberKind = MemberKind.StaticMethod;
- modifierCount++;
- return parser.parseModifier(token);
- case MemberKind.NonStaticField:
- memberKind = MemberKind.StaticField;
- modifierCount++;
- return parser.parseModifier(token);
- default:
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateExtraneousModifier);
- return next;
- }
- }
-
- Token parseVar(Token token) {
- Token next = token.next;
- assert(optional('var', next));
- if (!isVarAllowed && parameterKind == null) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateExtraneousModifier);
- return next;
- }
- typeContinuation = typeContinuationAfterVar(typeContinuation);
- varFinalOrConst ??= next;
- modifierCount++;
- return parser.parseModifier(token);
- }
-}
-
-/// This class parses modifiers in recovery situations,
-/// but does not call handleModifier or handleModifiers.
-class ModifierRecoveryContext2 {
+/// can occur, but does not call handleModifier or handleModifiers.
+class ModifierRecoveryContext {
final Parser parser;
Token abstractToken;
Token constToken;
@@ -220,7 +66,7 @@
// TODO(danrubel): Replace [ModifierRecoveryContext] and [ModifierContext]
// with this class.
- ModifierRecoveryContext2(this.parser);
+ ModifierRecoveryContext(this.parser);
/// Parse modifiers for class methods and fields.
Token parseClassMemberModifiers(Token token,
@@ -241,6 +87,26 @@
return token;
}
+ /// Parse modifiers for formal parameters.
+ Token parseFormalParameterModifiers(Token token, bool isStaticOrTopLevel,
+ {Token covariantToken, Token varFinalOrConst}) {
+ token = parseModifiers(token,
+ covariantToken: covariantToken, varFinalOrConst: varFinalOrConst);
+
+ if (isStaticOrTopLevel) {
+ reportExtraneousModifier(this.covariantToken);
+ this.covariantToken = null;
+ }
+ if (constToken != null) {
+ reportExtraneousModifier(constToken);
+ varFinalOrConst = null;
+ }
+ reportExtraneousModifier(abstractToken);
+ reportExtraneousModifier(externalToken);
+ reportExtraneousModifier(staticToken);
+ return token;
+ }
+
/// Parse modifiers after the `factory` token.
Token parseModifiersAfterFactory(Token token,
{Token externalToken, Token staticOrCovariant, Token varFinalOrConst}) {
@@ -545,241 +411,3 @@
}
}
}
-
-class ModifierRecoveryContext extends ModifierContext {
- Token constToken;
- Token covariantToken;
- Token externalToken;
- Token finalToken;
- Token staticToken;
- Token varToken;
-
- ModifierRecoveryContext(
- Parser parser,
- MemberKind memberKind,
- FormalParameterKind parameterKind,
- bool isVarAllowed,
- TypeContinuation typeContinuation)
- : super(
- parser, memberKind, parameterKind, isVarAllowed, typeContinuation);
-
- Token parseRecovery(Token token,
- {Token covariantToken, Token staticToken, Token varFinalOrConst}) {
- if (covariantToken != null) {
- this.covariantToken = covariantToken;
- ++modifierCount;
- }
- if (staticToken != null) {
- this.staticToken = staticToken;
- ++modifierCount;
- }
- if (varFinalOrConst != null) {
- this.varFinalOrConst = varFinalOrConst;
- ++modifierCount;
- if (optional('var', varFinalOrConst)) {
- varToken = varFinalOrConst;
- } else if (optional('final', varFinalOrConst)) {
- finalToken = varFinalOrConst;
- } else if (optional('const', varFinalOrConst)) {
- constToken = varFinalOrConst;
- } else {
- throw "Internal error: Unexpected varFinalOrConst '$varFinalOrConst'.";
- }
- }
-
- // Process invalid and out-of-order modifiers
- Token next = token.next;
- while (isModifier(next)) {
- final value = next.stringValue;
- if (identical('abstract', value)) {
- token = parseAbstract(token);
- } else if (identical('const', value)) {
- token = parseConst(token);
- } else if (identical('covariant', value)) {
- token = parseCovariantOpt(token);
- } else if (identical('external', value)) {
- token = parseExternalOpt(token);
- } else if (identical('final', value)) {
- token = parseFinal(token);
- } else if (identical('static', value)) {
- token = parseStaticOpt(token);
- } else if (identical('var', value)) {
- token = parseVar(token);
- } else {
- token = parseExtraneousModifier(token);
- }
- next = token.next;
- }
-
- return token;
- }
-
- Token parseAbstract(Token token) {
- assert(optional('abstract', token.next));
- if (memberKind == MemberKind.NonStaticField ||
- memberKind == MemberKind.NonStaticMethod ||
- memberKind == MemberKind.StaticField ||
- memberKind == MemberKind.StaticMethod) {
- parser.reportRecoverableError(
- token.next, fasta.messageAbstractClassMember);
- return token.next;
- }
- return parseExtraneousModifier(token);
- }
-
- @override
- Token parseConst(Token token) {
- Token next = token.next;
- if (constToken != null) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateDuplicatedModifier);
- return next;
- }
- constToken = next;
- if (covariantToken != null) {
- parser.reportRecoverableError(constToken, fasta.messageConstAndCovariant);
- return constToken;
- }
- if (finalToken != null) {
- parser.reportRecoverableError(constToken, fasta.messageConstAndFinal);
- return constToken;
- }
- if (varToken != null) {
- parser.reportRecoverableError(constToken, fasta.messageConstAndVar);
- return constToken;
- }
- return super.parseConst(token);
- }
-
- @override
- Token parseCovariantOpt(Token token) {
- Token next = token.next;
- if (covariantToken != null) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateDuplicatedModifier);
- return next;
- }
- covariantToken = next;
- if (constToken != null) {
- parser.reportRecoverableError(
- covariantToken, fasta.messageConstAndCovariant);
- return covariantToken;
- }
- if (staticToken != null) {
- parser.reportRecoverableError(
- covariantToken, fasta.messageCovariantAndStatic);
- return covariantToken;
- }
- if (varToken != null) {
- parser.reportRecoverableError(
- covariantToken, fasta.messageCovariantAfterVar);
- // fall through to parse modifier
- } else if (finalToken != null) {
- if (!isCovariantFinalAllowed) {
- parser.reportRecoverableError(
- covariantToken, fasta.messageFinalAndCovariant);
- return covariantToken;
- }
- parser.reportRecoverableError(
- covariantToken, fasta.messageCovariantAfterFinal);
- // fall through to parse modifier
- }
- return super.parseCovariantOpt(token);
- }
-
- @override
- Token parseExternalOpt(Token token) {
- Token next = token.next;
- if (externalToken != null) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateDuplicatedModifier);
- return next;
- }
- externalToken = token.next;
- return super.parseExternalOpt(token);
- }
-
- @override
- Token parseFinal(Token token) {
- Token next = token.next;
- if (finalToken != null) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateDuplicatedModifier);
- return next;
- }
- finalToken = next;
- if (constToken != null) {
- parser.reportRecoverableError(finalToken, fasta.messageConstAndFinal);
- return finalToken;
- }
- if (covariantToken != null && !isCovariantFinalAllowed) {
- parser.reportRecoverableError(finalToken, fasta.messageFinalAndCovariant);
- return finalToken;
- }
- if (varToken != null) {
- parser.reportRecoverableError(finalToken, fasta.messageFinalAndVar);
- return finalToken;
- }
- return super.parseFinal(token);
- }
-
- Token parseExtraneousModifier(Token token) {
- Token next = token.next;
- if (next.isModifier) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateExtraneousModifier);
- } else {
- // TODO(danrubel): Provide more specific error messages.
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateUnexpectedToken);
- }
- return next;
- }
-
- @override
- Token parseStaticOpt(Token token) {
- Token next = token.next;
- if (staticToken != null) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateDuplicatedModifier);
- return next;
- }
- staticToken = next;
- if (covariantToken != null) {
- parser.reportRecoverableError(
- staticToken, fasta.messageCovariantAndStatic);
- return staticToken;
- }
- if (constToken != null) {
- parser.reportRecoverableError(staticToken, fasta.messageStaticAfterConst);
- // fall through to parse modifier
- } else if (finalToken != null) {
- parser.reportRecoverableError(staticToken, fasta.messageStaticAfterFinal);
- // fall through to parse modifier
- } else if (varToken != null) {
- parser.reportRecoverableError(staticToken, fasta.messageStaticAfterVar);
- // fall through to parse modifier
- }
- return super.parseStaticOpt(token);
- }
-
- @override
- Token parseVar(Token token) {
- Token next = token.next;
- if (varToken != null) {
- parser.reportRecoverableErrorWithToken(
- next, fasta.templateDuplicatedModifier);
- return next;
- }
- varToken = next;
- if (constToken != null) {
- parser.reportRecoverableError(varToken, fasta.messageConstAndVar);
- return varToken;
- }
- if (finalToken != null) {
- parser.reportRecoverableError(varToken, fasta.messageFinalAndVar);
- return varToken;
- }
- return super.parseVar(token);
- }
-}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 4d9aac8..394e0d5 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -78,11 +78,7 @@
import 'member_kind.dart' show MemberKind;
import 'modifier_context.dart'
- show
- ModifierRecoveryContext,
- ModifierRecoveryContext2,
- isModifier,
- typeContinuationAfterVar;
+ show ModifierRecoveryContext, isModifier, typeContinuationAfterVar;
import 'recovery_listeners.dart'
show ClassHeaderRecoveryListener, ImportRecoveryListener;
@@ -757,17 +753,50 @@
/// ```
Token parseConditionalUri(Token token) {
Token ifKeyword = token = token.next;
- listener.beginConditionalUri(ifKeyword);
- token = expect('if', token);
- Token leftParen = token;
- expect('(', token);
- token = parseDottedName(token).next;
- Token equalitySign;
- if (optional('==', token)) {
- equalitySign = token;
- token = ensureLiteralString(token).next;
+ assert(optional('if', token));
+ listener.beginConditionalUri(token);
+ Token leftParen = token.next;
+ if (!optional('(', leftParen)) {
+ reportRecoverableError(
+ leftParen, fasta.templateExpectedButGot.withArguments('('));
+
+ int offset = leftParen.charOffset;
+ BeginToken openParen =
+ new SyntheticBeginToken(TokenType.OPEN_PAREN, offset);
+ Token next = openParen
+ .setNext(new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
+ next = next.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
+ openParen.endGroup = next;
+
+ token.setNext(openParen);
+ next.setNext(leftParen);
+ leftParen = openParen;
}
- expect(')', token);
+ token = leftParen;
+ token = parseDottedName(token);
+ Token next = token.next;
+ Token equalitySign;
+ if (optional('==', next)) {
+ equalitySign = next;
+ token = ensureLiteralString(next);
+ next = token.next;
+ }
+ if (next != leftParen.endGroup) {
+ reportRecoverableErrorWithToken(next, fasta.templateUnexpectedToken);
+ Token endGroup = leftParen.endGroup;
+ if (endGroup.isSynthetic) {
+ // The scanner did not place the synthetic ')' correctly, so move it.
+
+ // TODO(danrubel): Its costly to find the token before the endGroup.
+ // Consider beforeSynthetic field that points to the previous token
+ // only for synthetic tokens such as ')', '}', ']' so that the parser
+ // can easily move these to the correct location.
+ }
+ next = endGroup;
+ }
+ token = next;
+ assert(optional(')', token));
+
token = ensureLiteralString(token);
listener.endConditionalUri(ifKeyword, leftParen, equalitySign);
return token;
@@ -1192,19 +1221,16 @@
assert(parameterKind != null);
token = parseMetadataStar(token);
Token next = token.next;
- listener.beginFormalParameter(next, memberKind);
TypeContinuation typeContinuation =
typeContinuationFromFormalParameterKind(parameterKind);
+ Token covariantToken;
Token varFinalOrConst;
if (isModifier(next)) {
- int modifierCount = 0;
- Token covariantToken;
if (optional('covariant', next)) {
if (memberKind != MemberKind.StaticMethod &&
memberKind != MemberKind.TopLevelMethod) {
- covariantToken = token = parseModifier(token);
- ++modifierCount;
+ covariantToken = token = next;
next = token.next;
}
}
@@ -1212,36 +1238,33 @@
if (isModifier(next)) {
if (optional('var', next)) {
typeContinuation = typeContinuationAfterVar(typeContinuation);
- varFinalOrConst = token = parseModifier(token);
- ++modifierCount;
+ varFinalOrConst = token = next;
next = token.next;
} else if (optional('final', next)) {
- varFinalOrConst = token = parseModifier(token);
- ++modifierCount;
+ varFinalOrConst = token = next;
next = token.next;
}
if (isModifier(next)) {
// Recovery
- ModifierRecoveryContext modifierContext = new ModifierRecoveryContext(
- this, memberKind, parameterKind, false, typeContinuation);
- token = modifierContext.parseRecovery(token,
- covariantToken: covariantToken, varFinalOrConst: varFinalOrConst);
-
- modifierCount = modifierContext.modifierCount;
- covariantToken = modifierContext.covariantToken;
- varFinalOrConst = modifierContext.varFinalOrConst;
-
- memberKind = modifierContext.memberKind;
- typeContinuation = modifierContext.typeContinuation;
- varFinalOrConst = modifierContext.varFinalOrConst;
- modifierContext = null;
+ ModifierRecoveryContext context = new ModifierRecoveryContext(this);
+ token = context.parseFormalParameterModifiers(
+ token,
+ memberKind == MemberKind.StaticMethod ||
+ memberKind == MemberKind.TopLevelMethod,
+ covariantToken: covariantToken,
+ varFinalOrConst: varFinalOrConst);
+ covariantToken = context.covariantToken;
+ varFinalOrConst = context.varFinalOrConst;
+ if (varFinalOrConst != null && optional('var', varFinalOrConst)) {
+ typeContinuation = typeContinuationAfterVar(typeContinuation);
+ }
+ context = null;
}
}
- listener.handleModifiers(modifierCount);
- } else {
- listener.handleModifiers(0);
}
+ listener.beginFormalParameter(
+ next, memberKind, covariantToken, varFinalOrConst);
return parseType(
token, typeContinuation, null, memberKind, varFinalOrConst);
@@ -1952,9 +1975,7 @@
return true;
}
List<String> followingValues;
- if (context == IdentifierContext.classOrNamedMixinDeclaration) {
- followingValues = ['<', 'extends', 'with', 'implements', '{'];
- } else if (context == IdentifierContext.combinator) {
+ if (context == IdentifierContext.combinator) {
followingValues = [';'];
} else if (context == IdentifierContext.constructorReferenceContinuation) {
followingValues = ['.', ',', '(', ')', '[', ']', '}', ';'];
@@ -2043,9 +2064,7 @@
// could create a method to test whether a given token matches one of the
// patterns.
List<String> initialKeywords;
- if (context == IdentifierContext.classOrNamedMixinDeclaration) {
- initialKeywords = topLevelKeywords();
- } else if (context == IdentifierContext.fieldDeclaration) {
+ if (context == IdentifierContext.fieldDeclaration) {
initialKeywords = classMemberKeywords();
} else if (context == IdentifierContext.enumDeclaration) {
initialKeywords = topLevelKeywords();
@@ -2736,7 +2755,7 @@
next = token.next;
}
if (isModifier(next)) {
- ModifierRecoveryContext2 context = new ModifierRecoveryContext2(this);
+ ModifierRecoveryContext context = new ModifierRecoveryContext(this);
token = context.parseTopLevelModifiers(token,
externalToken: externalToken, varFinalOrConst: varFinalOrConst);
next = token.next;
@@ -3189,7 +3208,7 @@
if (!identical(next.kind, STRING_TOKEN)) {
Message message = fasta.templateExpectedString.withArguments(next);
Token newToken =
- new SyntheticStringToken(TokenType.STRING, '""', token.charOffset, 0);
+ new SyntheticStringToken(TokenType.STRING, '""', next.charOffset, 0);
rewriteAndRecover(token, message, newToken);
}
return parseLiteralString(token);
@@ -3303,13 +3322,6 @@
return 127;
}
- Token parseModifier(Token token) {
- token = token.next;
- assert(token.isModifier);
- listener.handleModifier(token);
- return token;
- }
-
Token parseNativeClause(Token token) {
Token nativeToken = token = token.next;
assert(optional('native', nativeToken));
@@ -3422,8 +3434,7 @@
next = token.next;
}
if (isModifier(next)) {
- ModifierRecoveryContext2 context =
- new ModifierRecoveryContext2(this);
+ ModifierRecoveryContext context = new ModifierRecoveryContext(this);
token = context.parseClassMemberModifiers(token,
externalToken: externalToken,
staticToken: staticToken,
@@ -3671,7 +3682,7 @@
if (!isValidTypeReference(token.next)) {
// Recovery
- ModifierRecoveryContext2 context = new ModifierRecoveryContext2(this);
+ ModifierRecoveryContext context = new ModifierRecoveryContext(this);
token = context.parseModifiersAfterFactory(token,
externalToken: externalToken,
staticOrCovariant: staticOrCovariant,
@@ -5401,8 +5412,8 @@
if (isModifier(next)) {
// Recovery
- ModifierRecoveryContext2 modifierContext =
- new ModifierRecoveryContext2(this);
+ ModifierRecoveryContext modifierContext =
+ new ModifierRecoveryContext(this);
token = modifierContext.parseVariableDeclarationModifiers(token,
varFinalOrConst: varFinalOrConst);
next = token.next;
@@ -5582,15 +5593,30 @@
BeginToken openParen =
token.setNext(new SyntheticBeginToken(TokenType.OPEN_PAREN, offset));
- Token semicolon =
- openParen.setNext(new SyntheticToken(TokenType.SEMICOLON, offset));
- semicolon =
- semicolon.setNext(new SyntheticToken(TokenType.SEMICOLON, offset));
+
+ Token loopPart;
+ if (awaitToken != null) {
+ loopPart = openParen.setNext(
+ new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
+ loopPart =
+ loopPart.setNext(new SyntheticKeywordToken(Keyword.IN, offset));
+ loopPart = loopPart.setNext(
+ new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
+ } else {
+ loopPart =
+ openParen.setNext(new SyntheticToken(TokenType.SEMICOLON, offset));
+ loopPart =
+ loopPart.setNext(new SyntheticToken(TokenType.SEMICOLON, offset));
+ }
+
Token closeParen =
- semicolon.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
+ loopPart.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
openParen.endGroup = closeParen;
- closeParen.setNext(leftParenthesis);
- insertBlock(closeParen);
+ Token identifier = closeParen
+ .setNext(new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
+ Token semicolon =
+ identifier.setNext(new SyntheticToken(TokenType.SEMICOLON, offset));
+ semicolon.setNext(leftParenthesis);
leftParenthesis = openParen;
}
@@ -5619,12 +5645,18 @@
// Recovery
reportRecoverableError(next, fasta.messageColonInPlaceOfIn);
// Fall through to process `for ( ... in ... )`
- } else {
+ } else if (awaitToken == null || optional(';', next)) {
// Process `for ( ... ; ... ; ... )`
if (awaitToken != null) {
reportRecoverableError(awaitToken, fasta.messageInvalidAwaitFor);
}
return parseForRest(token, forKeyword, leftParenthesis);
+ } else {
+ // Recovery
+ reportRecoverableError(
+ next, fasta.templateExpectedButGot.withArguments('in'));
+ next = token.setNext(
+ new SyntheticKeywordToken(Keyword.IN, next.offset)..setNext(next));
}
}
@@ -5709,8 +5741,12 @@
assert(optional('in', inKeyword) || optional(':', inKeyword));
listener.beginForInExpression(inKeyword.next);
token = parseExpression(inKeyword).next;
+ if (!optional(')', token)) {
+ reportRecoverableError(
+ token, fasta.templateExpectedButGot.withArguments(')'));
+ token = leftParenthesis.endGroup;
+ }
listener.endForInExpression(token);
- expect(')', token);
listener.beginForInBody(token.next);
LoopState savedLoopState = loopState;
loopState = LoopState.InsideLoop;
@@ -6153,13 +6189,30 @@
/// ;
/// ```
Token parseAssert(Token token, Assert kind) {
- Token assertKeyword = token.next;
- assert(optional('assert', assertKeyword));
- listener.beginAssert(assertKeyword, kind);
+ token = token.next;
+ assert(optional('assert', token));
+ listener.beginAssert(token, kind);
+ Token assertKeyword = token;
+ Token leftParenthesis = token.next;
+ if (!optional('(', leftParenthesis)) {
+ // Recovery
+ reportRecoverableError(
+ leftParenthesis, fasta.templateExpectedButGot.withArguments('('));
+ int offset = leftParenthesis.offset;
+
+ BeginToken openParen =
+ token.setNext(new SyntheticBeginToken(TokenType.OPEN_PAREN, offset));
+ Token identifier = openParen
+ .setNext(new SyntheticStringToken(TokenType.IDENTIFIER, '', offset));
+ Token closeParen =
+ identifier.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
+ openParen.endGroup = closeParen;
+ closeParen.setNext(leftParenthesis);
+
+ leftParenthesis = openParen;
+ }
+ token = leftParenthesis;
Token commaToken = null;
- token = assertKeyword.next;
- Token leftParenthesis = token;
- expect('(', token);
bool old = mayParseFunctionExpressions;
mayParseFunctionExpressions = true;
token = parseExpression(token).next;
@@ -6179,6 +6232,7 @@
while (optional(',', token)) {
Token begin = token.next;
token = parseExpression(token).next;
+ // TODO(danrubel): Consider removing the message argument.
listener.handleExtraneousExpression(
begin, fasta.messageAssertExtraneousArgument);
}
@@ -6186,13 +6240,15 @@
firstExtra, fasta.messageAssertExtraneousArgument);
}
}
- expect(')', token);
+ assert(optional(')', token));
mayParseFunctionExpressions = old;
- listener.endAssert(
- assertKeyword, kind, leftParenthesis, commaToken, token.next);
if (kind == Assert.Expression) {
reportRecoverableError(assertKeyword, fasta.messageAssertAsExpression);
+ } else if (kind == Assert.Statement) {
+ ensureSemicolon(token);
}
+ listener.endAssert(
+ assertKeyword, kind, leftParenthesis, commaToken, token.next);
return token;
}
@@ -6203,8 +6259,8 @@
/// ```
Token parseAssertStatement(Token token) {
assert(optional('assert', token.next));
- token = parseAssert(token, Assert.Statement);
- return ensureSemicolon(token);
+ // parseAssert ensures that there is a trailing semicolon.
+ return parseAssert(token, Assert.Statement).next;
}
/// ```
diff --git a/pkg/front_end/lib/src/fasta/parser/parser_main.dart b/pkg/front_end/lib/src/fasta/parser/parser_main.dart
index 1cd1820..a282842 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser_main.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser_main.dart
@@ -4,7 +4,7 @@
library fasta.parser.main;
-import 'dart:convert' show LineSplitter, UTF8;
+import 'dart:convert' show LineSplitter, utf8;
import 'dart:io' show File;
@@ -36,7 +36,7 @@
Uri uri = Uri.base.resolve(argument.substring(1));
await for (String file in new File.fromUri(uri)
.openRead()
- .transform(UTF8.decoder)
+ .transform(utf8.decoder)
.transform(const LineSplitter())) {
outLine(uri.resolve(file));
}
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info.dart b/pkg/front_end/lib/src/fasta/parser/type_info.dart
index 4b2394a..01e6edb 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info.dart
@@ -8,25 +8,17 @@
import '../scanner/token_constants.dart' show IDENTIFIER_TOKEN, KEYWORD_TOKEN;
-import '../util/link.dart' show Link;
-
-import 'identifier_context.dart' show IdentifierContext;
-
-import 'listener.dart' show Listener;
-
-import 'member_kind.dart' show MemberKind;
-
import 'parser.dart' show Parser;
import 'type_info_impl.dart'
show
+ ComplexTypeInfo,
NoTypeInfo,
PrefixedTypeInfo,
SimpleTypeArgumentsInfo,
SimpleTypeInfo,
VoidTypeInfo,
- looksLikeName,
- skipTypeArguments;
+ looksLikeName;
import 'util.dart' show optional;
@@ -46,6 +38,13 @@
/// code or during recovery.
Token ensureTypeNotVoid(Token token, Parser parser);
+ /// Call this function when the token after [token] must be a type or void.
+ /// This function will call the appropriate event methods on the [Parser]'s
+ /// listener to handle the type, inserting a synthetic type reference if
+ /// necessary. This may modify the token stream when parsing `>>` in valid
+ /// code or during recovery.
+ Token ensureTypeOrVoid(Token token, Parser parser);
+
/// Call this function to parse an optional type (not void) after [token].
/// This function will call the appropriate event methods on the [Parser]'s
/// listener to handle the type. This may modify the token stream
@@ -118,11 +117,12 @@
if (!isValidTypeReference(next)) {
if (next.type.isBuiltIn) {
Token afterType = next.next;
- if (optional('<', afterType) &&
- afterType.endGroup != null &&
- looksLikeName(afterType.endGroup.next)) {
- // Recovery: built-in used as a type
- return new ComplexTypeInfo(token).computeBuiltinAsType(required);
+ if (optional('<', afterType)) {
+ Token endGroup = afterType.endGroup;
+ if (endGroup != null && looksLikeName(endGroup.next)) {
+ // Recovery: built-in used as a type
+ return new ComplexTypeInfo(token).computeBuiltinAsType(required);
+ }
} else {
String value = next.stringValue;
if (!identical('get', value) &&
@@ -161,12 +161,13 @@
next = next.next;
if (optional('<', next)) {
- if (next.endGroup != null) {
+ Token endGroup = next.endGroup;
+ if (endGroup != null) {
next = next.next;
// identifier `<` `void` `>` is handled by ComplexTypeInfo.
if (isValidTypeReference(next) && !identical('void', next.stringValue)) {
next = next.next;
- if (optional('>', next)) {
+ if (next == endGroup) {
// We've seen identifier `<` identifier `>`
next = next.next;
if (!isGeneralizedFunctionType(next)) {
@@ -224,242 +225,3 @@
}
return noTypeInfo;
}
-
-/// Instances of [ComplexTypeInfo] are returned by [computeType] to represent
-/// type references that cannot be represented by the constants above.
-class ComplexTypeInfo implements TypeInfo {
- /// The first token in the type reference.
- final Token start;
-
- /// The last token in the type reference.
- Token end;
-
- /// Non-null if type arguments were seen during analysis.
- Token typeArguments;
-
- /// The tokens before the start of type variables of function types seen
- /// during analysis. Notice that the tokens in this list might precede
- /// either `'<'` or `'('` as not all function types have type parameters.
- Link<Token> typeVariableStarters = const Link<Token>();
-
- /// If the receiver represents a generalized function type then this indicates
- /// whether it has a return type, otherwise this is `null`.
- bool gftHasReturnType;
-
- ComplexTypeInfo(Token beforeStart) : this.start = beforeStart.next;
-
- @override
- bool get couldBeExpression => false;
-
- @override
- Token ensureTypeNotVoid(Token token, Parser parser) =>
- parseType(token, parser);
-
- @override
- Token parseTypeNotVoid(Token token, Parser parser) =>
- parseType(token, parser);
-
- @override
- Token parseType(Token token, Parser parser) {
- assert(identical(token.next, start));
- Listener listener = parser.listener;
-
- for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
- parser.parseTypeVariablesOpt(t.head);
- listener.beginFunctionType(start);
- }
-
- if (gftHasReturnType == false) {
- // A function type without return type.
- // Push the non-existing return type first. The loop below will
- // generate the full type.
- noTypeInfo.parseTypeNotVoid(token, parser);
- } else if (optional('void', token.next)) {
- token = voidTypeInfo.parseType(token, parser);
- } else {
- if (!optional('.', token.next.next)) {
- token = parser.ensureIdentifier(token, IdentifierContext.typeReference);
- } else {
- token = parser.ensureIdentifier(
- token, IdentifierContext.prefixedTypeReference);
- token = parser.parseQualifiedRest(
- token, IdentifierContext.typeReferenceContinuation);
- }
- token = parser.parseTypeArgumentsOpt(token);
- listener.handleType(start, token.next);
- }
-
- for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
- token = token.next;
- assert(optional('Function', token));
- Token functionToken = token;
- if (optional("<", token.next)) {
- // Skip type parameters, they were parsed above.
- token = token.next.endGroup;
- }
- token = parser.parseFormalParametersRequiredOpt(
- token, MemberKind.GeneralizedFunctionType);
- listener.endFunctionType(functionToken, token.next);
- }
-
- // There are two situations in which the [token] != [end]:
- // Valid code: identifier `<` identifier `<` identifier `>>`
- // where `>>` is replaced by two tokens.
- // Invalid code: identifier `<` identifier identifier `>`
- // where a synthetic `>` is inserted between the identifiers.
- assert(identical(token, end) || optional('>', token));
-
- // During recovery, [token] may be a synthetic that was inserted in the
- // middle of the type reference. In this situation, return [end] so that it
- // matches [skipType], and so that the next token to be parsed is correct.
- return token.isSynthetic ? end : token;
- }
-
- @override
- Token skipType(Token token) {
- return end;
- }
-
- /// Given `Function` non-identifier, compute the type
- /// and return the receiver or one of the [TypeInfo] constants.
- TypeInfo computeNoTypeGFT(bool required) {
- assert(optional('Function', start));
- computeRest(start, required);
-
- if (gftHasReturnType == null) {
- return required ? simpleTypeInfo : noTypeInfo;
- }
- assert(end != null);
- return this;
- }
-
- /// Given void `Function` non-identifier, compute the type
- /// and return the receiver or one of the [TypeInfo] constants.
- TypeInfo computeVoidGFT(bool required) {
- assert(optional('void', start));
- assert(optional('Function', start.next));
- computeRest(start.next, required);
-
- if (gftHasReturnType == null) {
- return voidTypeInfo;
- }
- assert(end != null);
- return this;
- }
-
- /// Given a builtin, return the receiver so that parseType will report
- /// an error for the builtin used as a type.
- TypeInfo computeBuiltinAsType(bool required) {
- assert(start.type.isBuiltIn);
- end = start;
- Token token = start.next;
- if (optional('<', token)) {
- typeArguments = token;
- token = skipTypeArguments(typeArguments);
- if (token == null) {
- token = typeArguments;
- typeArguments = null;
- } else {
- end = token;
- }
- }
- computeRest(token, required);
-
- assert(end != null);
- return this;
- }
-
- /// Given identifier `Function` non-identifier, compute the type
- /// and return the receiver or one of the [TypeInfo] constants.
- TypeInfo computeIdentifierGFT(bool required) {
- assert(isValidTypeReference(start));
- assert(optional('Function', start.next));
- computeRest(start.next, required);
-
- if (gftHasReturnType == null) {
- return simpleTypeInfo;
- }
- assert(end != null);
- return this;
- }
-
- /// Given identifier `<` ... `>`, compute the type
- /// and return the receiver or one of the [TypeInfo] constants.
- TypeInfo computeSimpleWithTypeArguments(bool required) {
- assert(isValidTypeReference(start));
- typeArguments = start.next;
- assert(optional('<', typeArguments));
-
- Token token = skipTypeArguments(typeArguments);
- if (token == null) {
- return required ? simpleTypeInfo : noTypeInfo;
- }
- end = token;
- computeRest(token.next, required);
-
- if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
- return noTypeInfo;
- }
- assert(end != null);
- return this;
- }
-
- /// Given identifier `.` identifier, compute the type
- /// and return the receiver or one of the [TypeInfo] constants.
- TypeInfo computePrefixedType(bool required) {
- assert(isValidTypeReference(start));
- Token token = start.next;
- assert(optional('.', token));
- token = token.next;
- assert(isValidTypeReference(token));
-
- end = token;
- token = token.next;
- if (optional('<', token)) {
- typeArguments = token;
- token = skipTypeArguments(token);
- if (token == null) {
- return required ? prefixedTypeInfo : noTypeInfo;
- }
- end = token;
- token = token.next;
- }
- computeRest(token, required);
-
- if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
- return noTypeInfo;
- }
- assert(end != null);
- return this;
- }
-
- void computeRest(Token token, bool required) {
- while (optional('Function', token)) {
- Token typeVariableStart = token;
- token = token.next;
- if (optional('<', token)) {
- token = token.endGroup;
- if (token == null) {
- break; // Not a function type.
- }
- assert(optional('>', token) || optional('>>', token));
- token = token.next;
- }
- if (!optional('(', token)) {
- break; // Not a function type.
- }
- token = token.endGroup;
- if (token == null) {
- break; // Not a function type.
- }
- if (!required && !token.next.isIdentifier) {
- break; // `Function` used as the name in a function declaration.
- }
- assert(optional(')', token));
- gftHasReturnType ??= typeVariableStart != start;
- typeVariableStarters = typeVariableStarters.prepend(typeVariableStart);
- end = token;
- token = token.next;
- }
- }
-}
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index 1a4c75b..08b2cce 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -8,14 +8,17 @@
import '../fasta_codes.dart' as fasta;
+import '../util/link.dart' show Link;
+
import 'identifier_context.dart' show IdentifierContext;
+import 'member_kind.dart' show MemberKind;
+
import 'listener.dart' show Listener;
import 'parser.dart' show Parser;
-import 'type_info.dart'
- show insertSyntheticIdentifierAfter, simpleTypeInfo, TypeInfo;
+import 'type_info.dart';
import 'util.dart' show optional;
@@ -31,10 +34,14 @@
parser.reportRecoverableErrorWithToken(
token.next, fasta.templateExpectedType);
insertSyntheticIdentifierAfter(token, parser);
- return simpleTypeInfo.parseTypeNotVoid(token, parser);
+ return simpleTypeInfo.parseType(token, parser);
}
@override
+ Token ensureTypeOrVoid(Token token, Parser parser) =>
+ ensureTypeNotVoid(token, parser);
+
+ @override
Token parseTypeNotVoid(Token token, Parser parser) =>
parseType(token, parser);
@@ -62,6 +69,10 @@
parseType(token, parser);
@override
+ Token ensureTypeOrVoid(Token token, Parser parser) =>
+ parseType(token, parser);
+
+ @override
Token parseTypeNotVoid(Token token, Parser parser) =>
parseType(token, parser);
@@ -104,6 +115,10 @@
parseType(token, parser);
@override
+ Token ensureTypeOrVoid(Token token, Parser parser) =>
+ parseType(token, parser);
+
+ @override
Token parseTypeNotVoid(Token token, Parser parser) =>
parseType(token, parser);
@@ -147,6 +162,10 @@
parseType(token, parser);
@override
+ Token ensureTypeOrVoid(Token token, Parser parser) =>
+ parseType(token, parser);
+
+ @override
Token parseTypeNotVoid(Token token, Parser parser) =>
parseType(token, parser);
@@ -182,6 +201,10 @@
}
@override
+ Token ensureTypeOrVoid(Token token, Parser parser) =>
+ parseType(token, parser);
+
+ @override
Token parseTypeNotVoid(Token token, Parser parser) =>
ensureTypeNotVoid(token, parser);
@@ -198,7 +221,8 @@
}
}
-bool looksLikeName(Token next) => next.isIdentifier || optional('this', next);
+bool looksLikeName(Token token) =>
+ token.isIdentifier || optional('this', token);
Token skipTypeArguments(Token token) {
assert(optional('<', token));
@@ -224,3 +248,249 @@
return endGroup;
}
+
+/// Instances of [ComplexTypeInfo] are returned by [computeType] to represent
+/// type references that cannot be represented by the constants above.
+class ComplexTypeInfo implements TypeInfo {
+ /// The first token in the type reference.
+ final Token start;
+
+ /// The last token in the type reference.
+ Token end;
+
+ /// Non-null if type arguments were seen during analysis.
+ Token typeArguments;
+
+ /// The tokens before the start of type variables of function types seen
+ /// during analysis. Notice that the tokens in this list might precede
+ /// either `'<'` or `'('` as not all function types have type parameters.
+ Link<Token> typeVariableStarters = const Link<Token>();
+
+ /// If the receiver represents a generalized function type then this indicates
+ /// whether it has a return type, otherwise this is `null`.
+ bool gftHasReturnType;
+
+ ComplexTypeInfo(Token beforeStart) : this.start = beforeStart.next;
+
+ @override
+ bool get couldBeExpression => false;
+
+ @override
+ Token ensureTypeNotVoid(Token token, Parser parser) =>
+ parseType(token, parser);
+
+ @override
+ Token ensureTypeOrVoid(Token token, Parser parser) =>
+ parseType(token, parser);
+
+ @override
+ Token parseTypeNotVoid(Token token, Parser parser) =>
+ parseType(token, parser);
+
+ @override
+ Token parseType(Token token, Parser parser) {
+ assert(identical(token.next, start));
+
+ for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
+ parser.parseTypeVariablesOpt(t.head);
+ parser.listener.beginFunctionType(start);
+ }
+
+ if (gftHasReturnType == false) {
+ // A function type without return type.
+ // Push the non-existing return type first. The loop below will
+ // generate the full type.
+ noTypeInfo.parseTypeNotVoid(token, parser);
+ } else {
+ Token start = token.next;
+ if (optional('void', start)) {
+ token = voidTypeInfo.parseType(token, parser);
+ } else {
+ if (!optional('.', start.next)) {
+ token =
+ parser.ensureIdentifier(token, IdentifierContext.typeReference);
+ } else {
+ token = parser.ensureIdentifier(
+ token, IdentifierContext.prefixedTypeReference);
+ token = parser.parseQualifiedRest(
+ token, IdentifierContext.typeReferenceContinuation);
+ }
+ token = parser.parseTypeArgumentsOpt(token);
+ parser.listener.handleType(start, token.next);
+ }
+ }
+
+ for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
+ token = token.next;
+ assert(optional('Function', token));
+ Token functionToken = token;
+ if (optional("<", token.next)) {
+ // Skip type parameters, they were parsed above.
+ token = token.next.endGroup;
+ }
+ token = parser.parseFormalParametersRequiredOpt(
+ token, MemberKind.GeneralizedFunctionType);
+ parser.listener.endFunctionType(functionToken, token.next);
+ }
+
+ // There are two situations in which the [token] != [end]:
+ // Valid code: identifier `<` identifier `<` identifier `>>`
+ // where `>>` is replaced by two tokens.
+ // Invalid code: identifier `<` identifier identifier `>`
+ // where a synthetic `>` is inserted between the identifiers.
+ assert(identical(token, end) || optional('>', token));
+
+ // During recovery, [token] may be a synthetic that was inserted in the
+ // middle of the type reference. In this situation, return [end] so that it
+ // matches [skipType], and so that the next token to be parsed is correct.
+ return token.isSynthetic ? end : token;
+ }
+
+ @override
+ Token skipType(Token token) {
+ return end;
+ }
+
+ /// Given `Function` non-identifier, compute the type
+ /// and return the receiver or one of the [TypeInfo] constants.
+ TypeInfo computeNoTypeGFT(bool required) {
+ assert(optional('Function', start));
+ computeRest(start, required);
+
+ if (gftHasReturnType == null) {
+ return required ? simpleTypeInfo : noTypeInfo;
+ }
+ assert(end != null);
+ return this;
+ }
+
+ /// Given void `Function` non-identifier, compute the type
+ /// and return the receiver or one of the [TypeInfo] constants.
+ TypeInfo computeVoidGFT(bool required) {
+ assert(optional('void', start));
+ assert(optional('Function', start.next));
+ computeRest(start.next, required);
+
+ if (gftHasReturnType == null) {
+ return voidTypeInfo;
+ }
+ assert(end != null);
+ return this;
+ }
+
+ /// Given a builtin, return the receiver so that parseType will report
+ /// an error for the builtin used as a type.
+ TypeInfo computeBuiltinAsType(bool required) {
+ assert(start.type.isBuiltIn);
+ end = start;
+ Token token = start.next;
+ if (optional('<', token)) {
+ typeArguments = token;
+ token = skipTypeArguments(typeArguments);
+ if (token == null) {
+ token = typeArguments;
+ typeArguments = null;
+ } else {
+ end = token;
+ }
+ }
+ computeRest(token, required);
+
+ assert(end != null);
+ return this;
+ }
+
+ /// Given identifier `Function` non-identifier, compute the type
+ /// and return the receiver or one of the [TypeInfo] constants.
+ TypeInfo computeIdentifierGFT(bool required) {
+ assert(isValidTypeReference(start));
+ assert(optional('Function', start.next));
+ computeRest(start.next, required);
+
+ if (gftHasReturnType == null) {
+ return simpleTypeInfo;
+ }
+ assert(end != null);
+ return this;
+ }
+
+ /// Given identifier `<` ... `>`, compute the type
+ /// and return the receiver or one of the [TypeInfo] constants.
+ TypeInfo computeSimpleWithTypeArguments(bool required) {
+ assert(isValidTypeReference(start));
+ typeArguments = start.next;
+ assert(optional('<', typeArguments));
+
+ Token token = skipTypeArguments(typeArguments);
+ if (token == null) {
+ return required ? simpleTypeInfo : noTypeInfo;
+ }
+ end = token;
+ computeRest(token.next, required);
+
+ if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
+ return noTypeInfo;
+ }
+ assert(end != null);
+ return this;
+ }
+
+ /// Given identifier `.` identifier, compute the type
+ /// and return the receiver or one of the [TypeInfo] constants.
+ TypeInfo computePrefixedType(bool required) {
+ assert(isValidTypeReference(start));
+ Token token = start.next;
+ assert(optional('.', token));
+ token = token.next;
+ assert(isValidTypeReference(token));
+
+ end = token;
+ token = token.next;
+ if (optional('<', token)) {
+ typeArguments = token;
+ token = skipTypeArguments(token);
+ if (token == null) {
+ return required ? prefixedTypeInfo : noTypeInfo;
+ }
+ end = token;
+ token = token.next;
+ }
+ computeRest(token, required);
+
+ if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
+ return noTypeInfo;
+ }
+ assert(end != null);
+ return this;
+ }
+
+ void computeRest(Token token, bool required) {
+ while (optional('Function', token)) {
+ Token typeVariableStart = token;
+ token = token.next;
+ if (optional('<', token)) {
+ token = token.endGroup;
+ if (token == null) {
+ break; // Not a function type.
+ }
+ assert(optional('>', token) || optional('>>', token));
+ token = token.next;
+ }
+ if (!optional('(', token)) {
+ break; // Not a function type.
+ }
+ token = token.endGroup;
+ if (token == null) {
+ break; // Not a function type.
+ }
+ if (!required && !token.next.isIdentifier) {
+ break; // `Function` used as the name in a function declaration.
+ }
+ assert(optional(')', token));
+ gftHasReturnType ??= typeVariableStart != start;
+ typeVariableStarters = typeVariableStarters.prepend(typeVariableStart);
+ end = token;
+ token = token.next;
+ }
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/scanner.dart b/pkg/front_end/lib/src/fasta/scanner.dart
index 4b83833..21de9c1 100644
--- a/pkg/front_end/lib/src/fasta/scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner.dart
@@ -4,7 +4,7 @@
library fasta.scanner;
-import 'dart:convert' show UNICODE_REPLACEMENT_CHARACTER_RUNE, UTF8;
+import 'dart:convert' show unicodeReplacementCharacterRune, utf8;
import '../scanner/token.dart' show Token;
@@ -34,7 +34,7 @@
export '../scanner/token.dart' show Keyword, Token;
-const int unicodeReplacementCharacter = UNICODE_REPLACEMENT_CHARACTER_RUNE;
+const int unicodeReplacementCharacter = unicodeReplacementCharacterRune;
typedef Token Recover(List<int> bytes, Token tokens, List<int> lineStarts);
@@ -88,7 +88,7 @@
{List<int> bytes, String source}) {
Token tokens = scanner.tokenize();
if (scanner.hasErrors) {
- if (bytes == null) bytes = UTF8.encode(source);
+ if (bytes == null) bytes = utf8.encode(source);
recover ??= defaultRecoveryStrategy;
tokens = recover(bytes, tokens, scanner.lineStarts);
}
diff --git a/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart
index 3947642..9442bf9 100644
--- a/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/utf8_bytes_scanner.dart
@@ -4,7 +4,7 @@
library fasta.scanner.utf8_bytes_scanner;
-import 'dart:convert' show UNICODE_BOM_CHARACTER_RUNE, UTF8;
+import 'dart:convert' show unicodeBomCharacterRune, utf8;
import '../../scanner/token.dart' show SyntheticStringToken, TokenType;
@@ -133,13 +133,13 @@
// TODO(lry): measurably slow, decode creates first a Utf8Decoder and a
// _Utf8Decoder instance. Also the sublist is eagerly allocated.
String codePoint =
- UTF8.decode(bytes.sublist(startOffset, end), allowMalformed: true);
+ utf8.decode(bytes.sublist(startOffset, end), allowMalformed: true);
if (codePoint.length == 0) {
// The UTF-8 decoder discards leading BOM characters.
// TODO(floitsch): don't just assume that removed characters were the
// BOM.
assert(containsBomAt(startOffset));
- codePoint = new String.fromCharCode(UNICODE_BOM_CHARACTER_RUNE);
+ codePoint = new String.fromCharCode(unicodeBomCharacterRune);
}
if (codePoint.length == 1) {
utf8Slack += (numBytes - 1);
@@ -176,7 +176,7 @@
int end = byteOffset;
// TODO(lry): this measurably slows down the scanner for files with unicode.
String s =
- UTF8.decode(bytes.sublist(startScanOffset, end), allowMalformed: true);
+ utf8.decode(bytes.sublist(startScanOffset, end), allowMalformed: true);
utf8Slack += (end - startScanOffset) - s.length;
}
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index be0d0d0..cdf9a9b 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -13,7 +13,7 @@
messageInternalProblemExtendingUnmodifiableScope,
templateAccessError,
templateDuplicatedName,
- templatePreviousUseOfName;
+ templateDuplicatedNamePreviouslyUsedCause;
import 'problems.dart' show internalProblem, unsupported;
@@ -201,18 +201,17 @@
/// Declares that the meaning of [name] in this scope is [builder].
///
- /// If name was used previously in this scope, this method returns an error
- /// that should be reported as a compile-time error. The position of this
- /// error is given by [charOffset] and [fileUri].
- LocatedMessage declare(
- String name, Builder builder, int charOffset, Uri fileUri) {
+ /// If name was used previously in this scope, this method returns a message
+ /// that can be used as context for reporting a compile-time error about
+ /// [name] being used before its declared. [fileUri] is used to bind the
+ /// location of this message.
+ LocatedMessage declare(String name, Builder builder, Uri fileUri) {
if (isModifiable) {
if (usedNames?.containsKey(name) ?? false) {
- return templatePreviousUseOfName
+ return templateDuplicatedNamePreviouslyUsedCause
.withArguments(name)
.withLocation(fileUri, usedNames[name], name.length);
}
- recordUse(name, charOffset, fileUri);
local[name] = builder;
} else {
internalProblem(
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index 445b4a5..68b1941 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -112,11 +112,6 @@
}
@override
- void handleModifiers(int count) {
- debugEvent("Modifiers");
- }
-
- @override
void handleNoTypeArguments(Token token) {
debugEvent("NoTypeArguments");
}
@@ -457,11 +452,6 @@
}
@override
- void handleModifier(Token token) {
- debugEvent("Modifier");
- }
-
- @override
void endConstructorReference(
Token start, Token periodBeforeName, Token endToken) {
debugEvent("ConstructorReference");
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 0bdf2dd..195f710 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -767,13 +767,20 @@
}
@override
+ void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+ Token varFinalOrConst) {
+ push((covariantToken != null ? covariantMask : 0) |
+ Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme));
+ }
+
+ @override
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
debugEvent("FormalParameter");
int charOffset = pop();
String name = pop();
TypeBuilder type = pop();
- int modifiers = Modifier.validate(pop());
+ int modifiers = pop();
List<MetadataBuilder> metadata = pop();
push(library.addFormalParameter(
metadata, modifiers, type, name, thisKeyword != null, charOffset));
@@ -1170,18 +1177,6 @@
}
@override
- void handleModifier(Token token) {
- debugEvent("Modifier");
- push(new Modifier.fromString(token.stringValue));
- }
-
- @override
- void handleModifiers(int count) {
- debugEvent("Modifiers");
- push(popList(count) ?? NullValue.Modifiers);
- }
-
- @override
void addCompileTimeError(Message message, int charOffset, int length,
{List<LocatedMessage> context}) {
library.addCompileTimeError(message, charOffset, length, uri,
diff --git a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
index 49b1793..009b3e0 100644
--- a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
+++ b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
@@ -127,9 +127,11 @@
.firstWhere((Library library) => library.importUri.scheme != "dart");
Uri uri = library.importUri;
Uri base = uri.resolve(".");
+ Uri dartBase = Uri.base;
StringBuffer buffer = new StringBuffer();
new Printer(buffer).writeLibraryFile(library);
String actual = "$buffer".replaceAll("$base", "org-dartlang-testcase:///");
+ actual = actual.replaceAll("$dartBase", "org-dartlang-testcase-sdk:///");
actual = actual.replaceAll("\\n", "\n");
File expectedFile = new File("${uri.toFilePath()}$suffix");
if (await expectedFile.exists()) {
diff --git a/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart b/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart
index e392ed6..b721d4e 100644
--- a/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart
+++ b/pkg/front_end/lib/src/fasta/testing/validating_instrumentation.dart
@@ -4,7 +4,7 @@
import 'dart:async' show Future;
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
import 'dart:io' show File;
@@ -106,7 +106,7 @@
var bytes = (await file.readAsBytes()).toList();
int convertOffset(int offset) {
if (offsetsCountCharacters) {
- return UTF8.encode(UTF8.decode(bytes).substring(0, offset)).length;
+ return utf8.encode(utf8.decode(bytes).substring(0, offset)).length;
} else {
return offset;
}
@@ -117,7 +117,7 @@
fixes.sort((a, b) => a.offset.compareTo(b.offset));
for (var fix in fixes.reversed) {
bytes.replaceRange(convertOffset(fix.offset),
- convertOffset(fix.offset + fix.length), UTF8.encode(fix.replacement));
+ convertOffset(fix.offset + fix.length), utf8.encode(fix.replacement));
}
await file.writeAsBytes(bytes);
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
index ced42ae..6fbd643 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
@@ -31,17 +31,29 @@
/// Concrete class derived from [InferenceNode] to represent type inference of
/// getters, setters, and fields based on inheritance.
-class AccessorInferenceNode extends MemberInferenceNode {
- AccessorInferenceNode(
- InterfaceResolver interfaceResolver,
- Procedure declaredMethod,
- List<Member> candidates,
- int start,
- int end,
- LibraryBuilder library,
- Uri fileUri)
- : super(interfaceResolver, declaredMethod, candidates, start, end,
- library, fileUri);
+class AccessorInferenceNode extends InferenceNode {
+ final InterfaceResolver _interfaceResolver;
+
+ /// The method whose return type and/or parameter types should be inferred.
+ final Procedure _declaredMethod;
+
+ /// A list containing the methods overridden by [_declaredMethod], if any.
+ final List<Member> _candidates;
+
+ /// The index of the first method in [_candidates] overridden by
+ /// [_declaredMethod].
+ final int _start;
+
+ /// The past-the-end index of the last method in [_candidates] overridden by
+ /// [_declaredMethod].
+ final int _end;
+
+ final LibraryBuilder _library;
+
+ final Uri _fileUri;
+
+ AccessorInferenceNode(this._interfaceResolver, this._declaredMethod,
+ this._candidates, this._start, this._end, this._library, this._fileUri);
String get _name {
if (_declaredMethod is! SyntheticAccessor && _declaredMethod.isSetter) {
@@ -69,7 +81,8 @@
noLength,
_fileUri);
} else {
- var inferredType = _matchTypes(overriddenTypes, _name, _offset);
+ var inferredType = _interfaceResolver.matchTypes(
+ overriddenTypes, _library, _name, _fileUri, _offset);
if (declaredMethod is SyntheticAccessor) {
declaredMethod._field.type = inferredType;
} else {
@@ -482,39 +495,31 @@
..isGenericContravariant = target.isGenericContravariant;
}
- /// Creates a forwarding stubs for this node if necessary, and propagates
+ /// Creates a forwarding stub for this node if necessary, and propagates
/// covariance information.
Procedure _finalize() {
- var inheritedMember = resolve();
- var inheritedMemberSubstitution =
- _interfaceResolver._substitutionFor(inheritedMember, enclosingClass);
+ var member = resolve();
+ var substitution =
+ _interfaceResolver._substitutionFor(member, enclosingClass);
bool isDeclaredInThisClass =
- identical(inheritedMember.enclosingClass, enclosingClass);
+ identical(member.enclosingClass, enclosingClass);
// Now decide whether we need a forwarding stub or not, and propagate
// covariance.
var covarianceFixes = <_CovarianceFix>[];
if (_interfaceResolver.strongMode) {
- _computeCovarianceFixes(
- inheritedMemberSubstitution, inheritedMember, covarianceFixes);
+ _computeCovarianceFixes(substitution, member, covarianceFixes);
}
if (!isDeclaredInThisClass &&
- (!identical(inheritedMember, _resolvedCandidate(_start)) ||
+ (!identical(member, _resolvedCandidate(_start)) ||
covarianceFixes.isNotEmpty)) {
- var stub =
- _createForwardingStub(inheritedMemberSubstitution, inheritedMember);
- var function = stub.function;
- for (var fix in covarianceFixes) {
- fix(function);
- }
- return stub;
- } else {
- var function = inheritedMember.function;
- for (var fix in covarianceFixes) {
- fix(function);
- }
- return inheritedMember;
+ member = _createForwardingStub(substitution, member);
}
+ var function = member.function;
+ for (var fix in covarianceFixes) {
+ fix(function);
+ }
+ return member;
}
/// Returns the [i]th element of [_candidates], finalizing it if necessary.
@@ -680,6 +685,129 @@
bool get isTypeInferencePrepared =>
_typeInferenceEngine.isTypeInferencePrepared;
+ /// Report an error if all types in [types] are not equal using `==`.
+ ///
+ /// Returns the type if there is at least one and they are all equal,
+ /// otherwise the type `dynamic`. [library], [name], [fileUri], and
+ /// [charOffset] are used to report the error.
+ DartType matchTypes(Iterable<DartType> types, LibraryBuilder library,
+ String name, Uri fileUri, int charOffset) {
+ DartType first;
+ for (var type in types) {
+ if (first == null) {
+ first = type;
+ } else if (first != type) {
+ // Types don't match. Report an error.
+ library.addCompileTimeError(
+ templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
+ charOffset,
+ noLength,
+ fileUri);
+ return const DynamicType();
+ }
+ }
+ // If there are no overridden types, infer `dynamic`.
+ return first ?? const DynamicType();
+ }
+
+ /// Computes the types of the methods overridden by [method] in [class_].
+ ///
+ /// The types have the type parameters of [class_] substituted appropriately.
+ ///
+ /// [candidates] has the list of inherited interface methods with the same
+ /// name as [method] as a sublist from [start] inclusive to [end] exclusive.
+ List<FunctionType> _computeMethodOverriddenTypes(Class class_,
+ Procedure method, List<Member> candidates, int start, int end) {
+ var overriddenTypes = <FunctionType>[];
+ var declaredTypeParameters = method.function.typeParameters;
+ for (int i = start; i < end; ++i) {
+ var candidate = candidates[i];
+ if (candidate is SyntheticAccessor) {
+ // This can happen if there are errors. Just skip this override.
+ continue;
+ }
+ var candidateFunction = candidate.function;
+ if (candidateFunction == null) {
+ // This can happen if there are errors. Just skip this override.
+ continue;
+ }
+ var substitution = _substitutionFor(candidate, class_);
+ FunctionType overriddenType =
+ substitution.substituteType(candidateFunction.functionType);
+ var overriddenTypeParameters = overriddenType.typeParameters;
+ if (overriddenTypeParameters.length != declaredTypeParameters.length) {
+ // Generic arity mismatch. Don't do any inference for this method.
+ // TODO(paulberry): report an error.
+ overriddenTypes.clear();
+ break;
+ } else if (overriddenTypeParameters.isNotEmpty) {
+ var substitutionMap = <TypeParameter, DartType>{};
+ for (int i = 0; i < declaredTypeParameters.length; ++i) {
+ substitutionMap[overriddenTypeParameters[i]] =
+ new TypeParameterType(declaredTypeParameters[i]);
+ }
+ overriddenType = substituteTypeParams(
+ overriddenType, substitutionMap, declaredTypeParameters);
+ }
+ overriddenTypes.add(overriddenType);
+ }
+ return overriddenTypes;
+ }
+
+ void inferMethodType(LibraryBuilder library, Class class_, Procedure method,
+ List<Member> candidates, int start, int end) {
+ var overriddenTypes =
+ _computeMethodOverriddenTypes(class_, method, candidates, start, end);
+ if (ShadowProcedure.hasImplicitReturnType(method) &&
+ method.name != indexSetName) {
+ method.function.returnType = matchTypes(
+ overriddenTypes.map((type) => type.returnType),
+ library,
+ method.name.name,
+ class_.fileUri,
+ method.fileOffset);
+ }
+ var positionalParameters = method.function.positionalParameters;
+ for (int i = 0; i < positionalParameters.length; ++i) {
+ if (ShadowVariableDeclaration
+ .isImplicitlyTyped(positionalParameters[i])) {
+ // Note that if the parameter is not present in the overridden method,
+ // getPositionalParameterType treats it as dynamic. This is consistent
+ // with the behavior called for in the informal top level type inference
+ // spec, which says:
+ //
+ // If there is no corresponding parameter position in the overridden
+ // method to infer from and the signatures are compatible, it is
+ // treated as dynamic (e.g. overriding a one parameter method with a
+ // method that takes a second optional parameter). Note: if there
+ // is no corresponding parameter position in the overriden method to
+ // infer from and the signatures are incompatible (e.g. overriding a
+ // one parameter method with a method that takes a second
+ // non-optional parameter), the inference result is not defined and
+ // tools are free to either emit an error, or to defer the error to
+ // override checking.
+ positionalParameters[i].type = matchTypes(
+ overriddenTypes.map((type) => getPositionalParameterType(type, i)),
+ library,
+ positionalParameters[i].name,
+ class_.fileUri,
+ positionalParameters[i].fileOffset);
+ }
+ }
+ var namedParameters = method.function.namedParameters;
+ for (int i = 0; i < namedParameters.length; i++) {
+ if (ShadowVariableDeclaration.isImplicitlyTyped(namedParameters[i])) {
+ var name = namedParameters[i].name;
+ namedParameters[i].type = matchTypes(
+ overriddenTypes.map((type) => getNamedParameterType(type, name)),
+ library,
+ namedParameters[i].name,
+ class_.fileUri,
+ namedParameters[i].fileOffset);
+ }
+ }
+ }
+
/// Populates [apiMembers] with a list of the implemented and inherited
/// members of the given [class_]'s interface.
///
@@ -729,34 +857,50 @@
InferenceNode getterInferenceNode;
if (getterStart < getterEnd) {
- if (declaredGetter != null) {
- getterInferenceNode = _createInferenceNode(
- class_,
- declaredGetter,
- candidates,
- inheritedGetterStart,
- getterEnd,
- inheritedSetterStart,
- setterEnd,
- library,
- class_.fileUri);
- }
- var forwardingNode = new ForwardingNode(
- this,
- getterInferenceNode,
- class_,
- name,
- _kindOf(candidates[getterStart]),
- candidates,
- getterStart,
- getterEnd);
- if (!forwardingNode.isGetter) {
- // Methods and operators can be finalized immediately.
- getters[getterIndex++] = forwardingNode.finalize();
- } else {
+ if (_kindOf(candidates[getterStart]) == ProcedureKind.Getter) {
+ // Member is a getter.
+ if (declaredGetter != null) {
+ getterInferenceNode = _createInferenceNode(
+ class_,
+ declaredGetter,
+ candidates,
+ inheritedGetterStart,
+ getterEnd,
+ inheritedSetterStart,
+ setterEnd,
+ library,
+ class_.fileUri);
+ }
// Getters need to be resolved later, as part of type
// inference, so just save the forwarding node for now.
- getters[getterIndex++] = forwardingNode;
+ getters[getterIndex++] = new ForwardingNode(
+ this,
+ getterInferenceNode,
+ class_,
+ name,
+ _kindOf(candidates[getterStart]),
+ candidates,
+ getterStart,
+ getterEnd);
+ } else {
+ // Member is a method.
+ if (strongMode &&
+ declaredGetter != null &&
+ _requiresTypeInference(declaredGetter)) {
+ inferMethodType(library, class_, declaredGetter, candidates,
+ inheritedGetterStart, getterEnd);
+ }
+ var forwardingNode = new ForwardingNode(
+ this,
+ null,
+ class_,
+ name,
+ _kindOf(candidates[getterStart]),
+ candidates,
+ getterStart,
+ getterEnd);
+ // Methods and operators can be finalized immediately.
+ getters[getterIndex++] = forwardingNode.finalize();
}
}
if (getterEnd < setterEnd) {
@@ -866,31 +1010,22 @@
int crossEnd,
LibraryBuilder library,
Uri fileUri) {
- if (!_requiresTypeInference(procedure)) return null;
- switch (procedure.kind) {
- case ProcedureKind.Getter:
- case ProcedureKind.Setter:
- if (strongMode && start < end) {
- return new AccessorInferenceNode(
- this, procedure, candidates, start, end, library, fileUri);
- } else if (strongMode && crossStart < crossEnd) {
- return new AccessorInferenceNode(this, procedure, candidates,
- crossStart, crossEnd, library, fileUri);
- } else if (procedure is SyntheticAccessor &&
- procedure._field.initializer != null) {
- var node = new FieldInitializerInferenceNode(
- _typeInferenceEngine, procedure._field, library);
- ShadowField.setInferenceNode(procedure._field, node);
- return node;
- }
- return null;
- default: // Method || Operator
- if (strongMode) {
- return new MethodInferenceNode(
- this, procedure, candidates, start, end, library, fileUri);
- }
- return null;
+ InferenceNode node;
+ if (procedure.isAccessor && _requiresTypeInference(procedure)) {
+ if (strongMode && start < end) {
+ node = new AccessorInferenceNode(
+ this, procedure, candidates, start, end, library, fileUri);
+ } else if (strongMode && crossStart < crossEnd) {
+ node = new AccessorInferenceNode(this, procedure, candidates,
+ crossStart, crossEnd, library, fileUri);
+ } else if (procedure is SyntheticAccessor &&
+ procedure._field.initializer != null) {
+ node = new FieldInitializerInferenceNode(
+ _typeInferenceEngine, procedure._field, library);
+ ShadowField.setInferenceNode(procedure._field, node);
+ }
}
+ return node;
}
/// Retrieves a list of the interface members of the given [class_].
@@ -1095,160 +1230,6 @@
}
}
-/// Abstract class derived from [InferenceNode] to represent type inference of
-/// methods, getters, and setters based on inheritance.
-abstract class MemberInferenceNode extends InferenceNode {
- final InterfaceResolver _interfaceResolver;
-
- /// The method whose return type and/or parameter types should be inferred.
- final Procedure _declaredMethod;
-
- /// A list containing the methods overridden by [_declaredMethod], if any.
- final List<Member> _candidates;
-
- /// The index of the first method in [_candidates] overridden by
- /// [_declaredMethod].
- final int _start;
-
- /// The past-the-end index of the last method in [_candidates] overridden by
- /// [_declaredMethod].
- final int _end;
-
- final LibraryBuilder _library;
-
- final Uri _fileUri;
-
- MemberInferenceNode(this._interfaceResolver, this._declaredMethod,
- this._candidates, this._start, this._end, this._library, this._fileUri);
-
- DartType _matchTypes(Iterable<DartType> types, String name, int charOffset) {
- var iterator = types.iterator;
- if (!iterator.moveNext()) {
- // No overridden types. Infer `dynamic`.
- return const DynamicType();
- }
- var inferredType = iterator.current;
- while (iterator.moveNext()) {
- if (inferredType != iterator.current) {
- // Types don't match. Report an error.
- _library.addCompileTimeError(
- templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
- charOffset,
- noLength,
- _fileUri);
- return const DynamicType();
- }
- }
- return inferredType;
- }
-}
-
-/// Concrete class derived from [InferenceNode] to represent type inference of
-/// methods.
-class MethodInferenceNode extends MemberInferenceNode {
- MethodInferenceNode(
- InterfaceResolver interfaceResolver,
- Procedure declaredMethod,
- List<Member> candidates,
- int start,
- int end,
- LibraryBuilder library,
- Uri fileUri)
- : super(interfaceResolver, declaredMethod, candidates, start, end,
- library, fileUri);
-
- @override
- void resolveInternal() {
- var declaredMethod = _declaredMethod;
- var overriddenTypes = _computeMethodOverriddenTypes();
- if (ShadowProcedure.hasImplicitReturnType(declaredMethod) &&
- _declaredMethod.name != indexSetName) {
- declaredMethod.function.returnType = _matchTypes(
- overriddenTypes.map((type) => type.returnType),
- declaredMethod.name.name,
- declaredMethod.fileOffset);
- }
- var positionalParameters = declaredMethod.function.positionalParameters;
- for (int i = 0; i < positionalParameters.length; i++) {
- if (ShadowVariableDeclaration
- .isImplicitlyTyped(positionalParameters[i])) {
- // Note that if the parameter is not present in the overridden method,
- // getPositionalParameterType treats it as dynamic. This is consistent
- // with the behavior called for in the informal top level type inference
- // spec, which says:
- //
- // If there is no corresponding parameter position in the overridden
- // method to infer from and the signatures are compatible, it is
- // treated as dynamic (e.g. overriding a one parameter method with a
- // method that takes a second optional parameter). Note: if there
- // is no corresponding parameter position in the overriden method to
- // infer from and the signatures are incompatible (e.g. overriding a
- // one parameter method with a method that takes a second
- // non-optional parameter), the inference result is not defined and
- // tools are free to either emit an error, or to defer the error to
- // override checking.
- positionalParameters[i].type = _matchTypes(
- overriddenTypes.map((type) => getPositionalParameterType(type, i)),
- positionalParameters[i].name,
- positionalParameters[i].fileOffset);
- }
- }
- var namedParameters = declaredMethod.function.namedParameters;
- for (int i = 0; i < namedParameters.length; i++) {
- if (ShadowVariableDeclaration.isImplicitlyTyped(namedParameters[i])) {
- var name = namedParameters[i].name;
- namedParameters[i].type = _matchTypes(
- overriddenTypes.map((type) => getNamedParameterType(type, name)),
- namedParameters[i].name,
- namedParameters[i].fileOffset);
- }
- }
- // Circularities should never occur with method inference, since the
- // inference of a method can only depend on the methods above it in the
- // class hierarchy.
- assert(!isCircular);
- }
-
- /// Computes the types of the methods overridden by [_declaredMethod], with
- /// appropriate type parameter substitutions.
- List<FunctionType> _computeMethodOverriddenTypes() {
- var overriddenTypes = <FunctionType>[];
- var declaredTypeParameters = _declaredMethod.function.typeParameters;
- for (int i = _start; i < _end; i++) {
- var candidate = _candidates[i];
- if (candidate is SyntheticAccessor) {
- // This can happen if there are errors. Just skip this override.
- continue;
- }
- var candidateFunction = candidate.function;
- if (candidateFunction == null) {
- // This can happen if there are errors. Just skip this override.
- continue;
- }
- var substitution = _interfaceResolver._substitutionFor(
- candidate, _declaredMethod.enclosingClass);
- FunctionType overriddenType =
- substitution.substituteType(candidateFunction.functionType);
- var overriddenTypeParameters = overriddenType.typeParameters;
- if (overriddenTypeParameters.length != declaredTypeParameters.length) {
- // Generic arity mismatch. Don't do any inference for this method.
- // TODO(paulberry): report an error.
- return <FunctionType>[];
- } else if (overriddenTypeParameters.isNotEmpty) {
- var substitutionMap = <TypeParameter, DartType>{};
- for (int i = 0; i < declaredTypeParameters.length; i++) {
- substitutionMap[overriddenTypeParameters[i]] =
- new TypeParameterType(declaredTypeParameters[i]);
- }
- overriddenType = substituteTypeParams(
- overriddenType, substitutionMap, declaredTypeParameters);
- }
- overriddenTypes.add(overriddenType);
- }
- return overriddenTypes;
- }
-}
-
/// A [SyntheticAccessor] represents the getter or setter implied by a field.
class SyntheticAccessor extends Procedure {
/// The field associated with the synthetic accessor.
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 87723e6..e1cb6ea 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -2,13 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE.md file.
-import 'package:front_end/src/base/instrumentation.dart';
-import 'package:front_end/src/fasta/builder/library_builder.dart';
-import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
-import 'package:front_end/src/fasta/messages.dart';
-import 'package:front_end/src/fasta/source/source_library_builder.dart';
-import 'package:front_end/src/fasta/type_inference/type_inferrer.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
import 'package:kernel/ast.dart'
show
Class,
@@ -24,9 +17,22 @@
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
+import '../../base/instrumentation.dart';
+
+import '../builder/library_builder.dart';
+
import '../deprecated_problems.dart' show Crash;
-import '../messages.dart' show getLocationFromNode, noLength;
+import '../kernel/kernel_shadow_ast.dart';
+
+import '../messages.dart'
+ show getLocationFromNode, noLength, templateCantInferTypeDueToCircularity;
+
+import '../source/source_library_builder.dart';
+
+import 'type_inferrer.dart';
+
+import 'type_schema_environment.dart';
/// Concrete class derived from [InferenceNode] to represent type inference of a
/// field based on its initializer.
diff --git a/pkg/front_end/lib/src/incremental/file_state.dart b/pkg/front_end/lib/src/incremental/file_state.dart
index 88a24b0..f8ab1a3 100644
--- a/pkg/front_end/lib/src/incremental/file_state.dart
+++ b/pkg/front_end/lib/src/incremental/file_state.dart
@@ -65,7 +65,7 @@
bool _gcMarked = false;
FileState._(this._fsState, this.uri, this.fileUri)
- : uriBytes = UTF8.encode(uri.toString());
+ : uriBytes = utf8.encode(uri.toString());
/// The MD5 signature of the file API as a byte array.
/// It depends on all non-comment tokens outside the block bodies.
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index f1273f6..25bcdaa 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1647,7 +1647,24 @@
template: "Duplicated definition of '#name'."
DuplicatedName:
- template: "Duplicated name: '#name'."
+ template: "'#name' is already declared in this scope."
+ severity: ERROR
+
+DuplicatedNameCause:
+ template: "Previous declaration of '#name'."
+ severity: CONTEXT
+
+DuplicatedNamePreviouslyUsed:
+ template: "Can't declare '#name' because it was already used in this scope."
+ severity: ERROR
+ analyzerCode: REFERENCED_BEFORE_DECLARATION
+ dart2jsCode: "*ignored*"
+ script:
+ - "main(arguments) { arguments; var arguments; }"
+
+DuplicatedNamePreviouslyUsedCause:
+ template: "Previous use of '#name'."
+ severity: CONTEXT
DuplicatedParameterName:
template: "Duplicated parameter name '#name'."
@@ -1810,9 +1827,6 @@
AccessError:
template: "Access error: '#name'."
-PreviousUseOfName:
- template: "Previous use of '#name'."
-
ExpressionNotMetadata:
template: "This can't be used as metadata; metadata should be a reference to a compile-time constant variable, or a call to a constant constructor."
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index 6d4b93b..b02c547 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -5,6 +5,7 @@
import 'package:front_end/src/fasta/messages.dart';
import 'package:front_end/src/fasta/parser.dart';
import 'package:front_end/src/fasta/parser/type_info.dart';
+import 'package:front_end/src/fasta/parser/type_info_impl.dart';
import 'package:front_end/src/fasta/scanner.dart';
import 'package:front_end/src/scanner/token.dart';
import 'package:test/test.dart';
@@ -19,14 +20,17 @@
@reflectiveTest
class TokenInfoTest {
void test_noType() {
- TypeInfo typeInfo = noTypeInfo;
- Token start = scanString('before ;').tokens;
- Token expectedEnd = start;
- expect(typeInfo.couldBeExpression, isFalse);
- expect(typeInfo.skipType(start), expectedEnd);
+ final Token start = scanString('before ;').tokens;
- TypeInfoListener listener = new TypeInfoListener();
- expect(typeInfo.ensureTypeNotVoid(start, new Parser(listener)),
+ expect(noTypeInfo.couldBeExpression, isFalse);
+ expect(noTypeInfo.skipType(start), start);
+ }
+
+ void test_noType_ensureTypeNotVoid() {
+ final Token start = scanString('before ;').tokens;
+ final TypeInfoListener listener = new TypeInfoListener();
+
+ expect(noTypeInfo.ensureTypeNotVoid(start, new Parser(listener)),
new isInstanceOf<SyntheticStringToken>());
expect(listener.calls, [
'handleIdentifier typeReference',
@@ -34,56 +38,99 @@
'handleType ;',
]);
expect(listener.errors, [new ExpectedError(codeExpectedType, 7, 1)]);
+ }
- listener = new TypeInfoListener();
- expect(typeInfo.parseTypeNotVoid(start, new Parser(listener)), expectedEnd);
+ void test_noType_ensureTypeOrVoid() {
+ final Token start = scanString('before ;').tokens;
+ final TypeInfoListener listener = new TypeInfoListener();
+
+ expect(noTypeInfo.ensureTypeOrVoid(start, new Parser(listener)),
+ new isInstanceOf<SyntheticStringToken>());
+ expect(listener.calls, [
+ 'handleIdentifier typeReference',
+ 'handleNoTypeArguments ;',
+ 'handleType ;',
+ ]);
+ expect(listener.errors, [new ExpectedError(codeExpectedType, 7, 1)]);
+ }
+
+ void test_noType_parseType() {
+ final Token start = scanString('before ;').tokens;
+ final TypeInfoListener listener = new TypeInfoListener();
+
+ expect(noTypeInfo.parseType(start, new Parser(listener)), start);
expect(listener.calls, ['handleNoType before']);
expect(listener.errors, isNull);
+ }
- listener = new TypeInfoListener();
- expect(typeInfo.parseType(start, new Parser(listener)), expectedEnd);
+ void test_noType_parseTypeNotVoid() {
+ final Token start = scanString('before ;').tokens;
+ final TypeInfoListener listener = new TypeInfoListener();
+
+ expect(noTypeInfo.parseTypeNotVoid(start, new Parser(listener)), start);
expect(listener.calls, ['handleNoType before']);
expect(listener.errors, isNull);
}
void test_voidType() {
- TypeInfo typeInfo = voidTypeInfo;
- Token start = scanString('before void ;').tokens;
- Token expectedEnd = start.next;
- expect(typeInfo.skipType(start), expectedEnd);
- expect(typeInfo.couldBeExpression, isFalse);
+ final Token start = scanString('before void ;').tokens;
- TypeInfoListener listener = new TypeInfoListener();
- expect(
- typeInfo.ensureTypeNotVoid(start, new Parser(listener)), expectedEnd);
+ expect(voidTypeInfo.skipType(start), start.next);
+ expect(voidTypeInfo.couldBeExpression, isFalse);
+ }
+
+ void test_voidType_ensureTypeNotVoid() {
+ final Token start = scanString('before void ;').tokens;
+ final TypeInfoListener listener = new TypeInfoListener();
+
+ expect(voidTypeInfo.ensureTypeNotVoid(start, new Parser(listener)),
+ start.next);
expect(listener.calls, [
'handleIdentifier void typeReference',
'handleNoTypeArguments ;',
'handleType void ;',
]);
expect(listener.errors, [new ExpectedError(codeInvalidVoid, 7, 4)]);
+ }
- listener = new TypeInfoListener();
- expect(typeInfo.parseTypeNotVoid(start, new Parser(listener)), expectedEnd);
- expect(listener.calls, [
- 'handleIdentifier void typeReference',
- 'handleNoTypeArguments ;',
- 'handleType void ;',
- ]);
- expect(listener.errors, [new ExpectedError(codeInvalidVoid, 7, 4)]);
+ void test_voidType_ensureTypeOrVoid() {
+ final Token start = scanString('before void ;').tokens;
+ final TypeInfoListener listener = new TypeInfoListener();
- listener = new TypeInfoListener();
- expect(typeInfo.parseType(start, new Parser(listener)), expectedEnd);
+ expect(voidTypeInfo.parseType(start, new Parser(listener)), start.next);
expect(listener.calls, ['handleVoidKeyword void']);
expect(listener.errors, isNull);
}
+ void test_voidType_parseType() {
+ final Token start = scanString('before void ;').tokens;
+ final TypeInfoListener listener = new TypeInfoListener();
+
+ expect(voidTypeInfo.parseType(start, new Parser(listener)), start.next);
+ expect(listener.calls, ['handleVoidKeyword void']);
+ expect(listener.errors, isNull);
+ }
+
+ void test_voidType_parseTypeNotVoid() {
+ final Token start = scanString('before void ;').tokens;
+ final TypeInfoListener listener = new TypeInfoListener();
+
+ expect(
+ voidTypeInfo.parseTypeNotVoid(start, new Parser(listener)), start.next);
+ expect(listener.calls, [
+ 'handleIdentifier void typeReference',
+ 'handleNoTypeArguments ;',
+ 'handleType void ;',
+ ]);
+ expect(listener.errors, [new ExpectedError(codeInvalidVoid, 7, 4)]);
+ }
+
void test_prefixedTypeInfo() {
- TypeInfo typeInfo = prefixedTypeInfo;
- Token start = scanString('before C.a ;').tokens;
- Token expectedEnd = start.next.next.next;
- expect(typeInfo.skipType(start), expectedEnd);
- expect(typeInfo.couldBeExpression, isTrue);
+ final Token start = scanString('before C.a ;').tokens;
+ final Token expectedEnd = start.next.next.next;
+
+ expect(prefixedTypeInfo.skipType(start), expectedEnd);
+ expect(prefixedTypeInfo.couldBeExpression, isTrue);
TypeInfoListener listener;
assertResult(Token actualEnd) {
@@ -99,21 +146,27 @@
}
listener = new TypeInfoListener();
- assertResult(typeInfo.ensureTypeNotVoid(start, new Parser(listener)));
+ assertResult(
+ prefixedTypeInfo.ensureTypeNotVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(typeInfo.parseTypeNotVoid(start, new Parser(listener)));
+ assertResult(
+ prefixedTypeInfo.ensureTypeOrVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(typeInfo.parseType(start, new Parser(listener)));
+ assertResult(
+ prefixedTypeInfo.parseTypeNotVoid(start, new Parser(listener)));
+
+ listener = new TypeInfoListener();
+ assertResult(prefixedTypeInfo.parseType(start, new Parser(listener)));
}
void test_simpleTypeInfo() {
- TypeInfo typeInfo = simpleTypeInfo;
- Token start = scanString('before C ;').tokens;
- Token expectedEnd = start.next;
- expect(typeInfo.skipType(start), expectedEnd);
- expect(typeInfo.couldBeExpression, isTrue);
+ final Token start = scanString('before C ;').tokens;
+ final Token expectedEnd = start.next;
+
+ expect(simpleTypeInfo.skipType(start), expectedEnd);
+ expect(simpleTypeInfo.couldBeExpression, isTrue);
TypeInfoListener listener;
assertResult(Token actualEnd) {
@@ -127,21 +180,24 @@
}
listener = new TypeInfoListener();
- assertResult(typeInfo.ensureTypeNotVoid(start, new Parser(listener)));
+ assertResult(simpleTypeInfo.ensureTypeNotVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(typeInfo.parseTypeNotVoid(start, new Parser(listener)));
+ assertResult(simpleTypeInfo.ensureTypeOrVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(typeInfo.parseType(start, new Parser(listener)));
+ assertResult(simpleTypeInfo.parseTypeNotVoid(start, new Parser(listener)));
+
+ listener = new TypeInfoListener();
+ assertResult(simpleTypeInfo.parseType(start, new Parser(listener)));
}
void test_simpleTypeArgumentsInfo() {
- TypeInfo typeInfo = simpleTypeArgumentsInfo;
- Token start = scanString('before C<T> ;').tokens;
- Token expectedEnd = start.next.next.next.next;
- expect(typeInfo.skipType(start), expectedEnd);
- expect(typeInfo.couldBeExpression, isFalse);
+ final Token start = scanString('before C<T> ;').tokens;
+ final Token expectedEnd = start.next.next.next.next;
+
+ expect(simpleTypeArgumentsInfo.skipType(start), expectedEnd);
+ expect(simpleTypeArgumentsInfo.couldBeExpression, isFalse);
TypeInfoListener listener;
assertResult(Token actualEnd) {
@@ -159,13 +215,20 @@
}
listener = new TypeInfoListener();
- assertResult(typeInfo.ensureTypeNotVoid(start, new Parser(listener)));
+ assertResult(
+ simpleTypeArgumentsInfo.ensureTypeNotVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(typeInfo.parseTypeNotVoid(start, new Parser(listener)));
+ assertResult(
+ simpleTypeArgumentsInfo.ensureTypeOrVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(typeInfo.parseType(start, new Parser(listener)));
+ assertResult(
+ simpleTypeArgumentsInfo.parseTypeNotVoid(start, new Parser(listener)));
+
+ listener = new TypeInfoListener();
+ assertResult(
+ simpleTypeArgumentsInfo.parseType(start, new Parser(listener)));
}
void test_computeType_basic() {
@@ -232,7 +295,6 @@
'beginMetadataStar int',
'endMetadataStar 0',
'beginFormalParameter int MemberKind.GeneralizedFunctionType',
- 'handleModifiers 0',
'handleIdentifier int typeReference',
'handleNoTypeArguments )',
'handleType int )',
@@ -258,7 +320,6 @@
'beginMetadataStar int',
'endMetadataStar 0',
'beginFormalParameter int MemberKind.GeneralizedFunctionType',
- 'handleModifiers 0',
'handleIdentifier int typeReference',
'handleNoTypeArguments )',
'handleType int )',
@@ -604,7 +665,6 @@
'beginMetadataStar int',
'endMetadataStar 0',
'beginFormalParameter int MemberKind.GeneralizedFunctionType',
- 'handleModifiers 0',
'handleIdentifier int typeReference',
'handleNoTypeArguments x',
'handleType int x',
@@ -618,7 +678,6 @@
'beginMetadataStar int',
'endMetadataStar 0',
'beginFormalParameter int MemberKind.GeneralizedFunctionType',
- 'handleModifiers 0',
'handleIdentifier int typeReference',
'handleNoTypeArguments x',
'handleType int x',
@@ -696,6 +755,7 @@
if (required == null) {
compute(expectedInfo, source, start, true, expectedAfter, expectedCalls,
expectedErrors);
+ start = scan(source);
compute(expectedInfo, source, start, false, expectedAfter, expectedCalls,
expectedErrors);
} else {
@@ -777,7 +837,8 @@
List<ExpectedError> errors;
@override
- void beginFormalParameter(Token token, MemberKind kind) {
+ void beginFormalParameter(Token token, MemberKind kind, Token covariantToken,
+ Token varFinalOrConst) {
calls.add('beginFormalParameter $token $kind');
}
@@ -860,11 +921,6 @@
}
@override
- void handleModifiers(int count) {
- calls.add('handleModifiers $count');
- }
-
- @override
void handleNoName(Token token) {
calls.add('handleNoName $token');
}
diff --git a/pkg/front_end/test/fasta/shaker_test.dart b/pkg/front_end/test/fasta/shaker_test.dart
index d86e4d9..1952495 100644
--- a/pkg/front_end/test/fasta/shaker_test.dart
+++ b/pkg/front_end/test/fasta/shaker_test.dart
@@ -16,7 +16,7 @@
library fasta.test.shaker_test;
import 'dart:async' show Future;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode;
import 'dart:io' show File;
export 'package:testing/testing.dart' show Chain, runMe;
@@ -60,7 +60,7 @@
final List<int> outlineBytes;
final ExpectationSet expectationSet =
- new ExpectationSet.fromJsonList(JSON.decode(EXPECTATIONS));
+ new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
TreeShakerContext(
this.outlineUri, this.options, this.outlineBytes, bool updateExpectations)
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 014f3a6..ee0b49b 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -8,7 +8,7 @@
import 'dart:io' show File, Platform;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode;
import 'package:front_end/src/api_prototype/standard_file_system.dart'
show StandardFileSystem;
@@ -115,7 +115,7 @@
Component platform;
final ExpectationSet expectationSet =
- new ExpectationSet.fromJsonList(JSON.decode(EXPECTATIONS));
+ new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
Expectation verificationError;
FastaContext(
diff --git a/pkg/front_end/test/incremental_bulk_compiler_full.dart b/pkg/front_end/test/incremental_bulk_compiler_full.dart
index ead6b7b..c0f5a87 100644
--- a/pkg/front_end/test/incremental_bulk_compiler_full.dart
+++ b/pkg/front_end/test/incremental_bulk_compiler_full.dart
@@ -20,11 +20,9 @@
import 'package:front_end/src/fasta/incremental_compiler.dart'
show IncrementalCompiler;
-import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
-
import 'package:front_end/src/fasta/severity.dart' show Severity;
-import 'package:kernel/kernel.dart' show Component, Library, Reference;
+import 'package:kernel/kernel.dart' show Component;
import 'package:kernel/text/ast_to_text.dart'
show globalDebuggingNames, NameSystem;
@@ -32,6 +30,8 @@
import 'package:testing/testing.dart'
show Chain, ChainContext, Result, Step, TestDescription, runMe;
+import 'incremental_utils.dart' as util;
+
main([List<String> arguments = const []]) =>
runMe(arguments, createContext, "../testing.json");
@@ -90,7 +90,7 @@
try {
IncrementalCompiler compiler =
new IncrementalKernelGenerator(getOptions(true), uri);
- oneShotSerialized = postProcess(await compiler.computeDelta());
+ oneShotSerialized = util.postProcess(await compiler.computeDelta());
} catch (e) {
oneShotFailed = true;
}
@@ -106,7 +106,7 @@
}
Component bulkCompiledComponent = await context.compiler
.computeDelta(entryPoint: uri, fullComponent: true);
- bulkSerialized = postProcess(bulkCompiledComponent);
+ bulkSerialized = util.postProcess(bulkCompiledComponent);
} catch (e) {
bulkFailed = true;
}
@@ -122,7 +122,7 @@
}
Component bulkCompiledComponent = await context.compiler
.computeDelta(entryPoint: uri, fullComponent: true);
- bulkSerialized2 = postProcess(bulkCompiledComponent);
+ bulkSerialized2 = util.postProcess(bulkCompiledComponent);
} catch (e) {
bulk2Failed = true;
}
@@ -148,23 +148,6 @@
return pass(description);
}
- List<int> postProcess(Component c) {
- c.libraries.sort((l1, l2) {
- return l1.fileUri.toString().compareTo(l2.fileUri.toString());
- });
-
- c.computeCanonicalNames();
- for (Library library in c.libraries) {
- library.additionalExports.sort((Reference r1, Reference r2) {
- return r1.canonicalName
- .toString()
- .compareTo(r2.canonicalName.toString());
- });
- }
-
- return serializeComponent(c);
- }
-
void checkIsEqual(List<int> a, List<int> b) {
int length = a.length;
if (b.length < length) {
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index 147487c..0bb2e82 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -27,19 +27,19 @@
import 'package:front_end/src/fasta/incremental_compiler.dart'
show IncrementalCompiler;
-import 'package:front_end/src/fasta/kernel/utils.dart'
- show writeComponentToFile, serializeComponent;
+import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
import 'package:front_end/src/fasta/severity.dart' show Severity;
-import 'package:kernel/kernel.dart'
- show Class, EmptyStatement, Library, Procedure, Component;
+import 'package:kernel/kernel.dart' show Component;
import "package:testing/testing.dart"
show Chain, ChainContext, Result, Step, TestDescription, runMe;
import "package:yaml/yaml.dart" show YamlMap, loadYamlNode;
+import "incremental_utils.dart" as util;
+
main([List<String> arguments = const []]) =>
runMe(arguments, createContext, "../testing.json");
@@ -191,7 +191,7 @@
Map<String, String> sourceFiles;
CompilerOptions options;
TestIncrementalCompiler compiler;
- for (var world in worlds) {
+ for (Map<String, dynamic> world in worlds) {
bool brandNewWorld = true;
if (world["worldType"] == "updated") {
brandNewWorld = false;
@@ -256,7 +256,7 @@
}
if (world["invalidate"] != null) {
- for (var filename in world["invalidate"]) {
+ for (String filename in world["invalidate"]) {
compiler.invalidate(base.resolve(filename));
}
}
@@ -274,7 +274,7 @@
} else if (world["warnings"] != true && gotWarning) {
throw "Got unexpected warnings(s): $formattedWarnings.";
}
- throwOnEmptyMixinBodies(component);
+ util.throwOnEmptyMixinBodies(component);
print("Compile took ${stopwatch.elapsedMilliseconds} ms");
newestWholeComponent = serializeComponent(component);
if (component.libraries.length != world["expectedLibraryCount"]) {
@@ -329,7 +329,7 @@
CompilerOptions getOptions(bool strong) {
final Uri sdkRoot = computePlatformBinariesLocation();
- var options = new CompilerOptions()
+ CompilerOptions options = new CompilerOptions()
..sdkRoot = sdkRoot
..librariesSpecificationUri = Uri.base.resolve("sdk/lib/libraries.json")
..onProblem = (FormattedMessage problem, Severity severity,
@@ -353,8 +353,8 @@
TestIncrementalCompiler compiler =
new TestIncrementalCompiler(options, input);
Component component = await compiler.computeDelta();
- throwOnEmptyMixinBodies(component);
- await writeComponentToFile(component, output);
+ util.throwOnEmptyMixinBodies(component);
+ new File.fromUri(output).writeAsBytesSync(util.postProcess(component));
return compiler.initializedFromDill;
}
@@ -367,10 +367,11 @@
for (Uri invalidateUri in invalidateUris) {
compiler.invalidate(invalidateUri);
}
- var initializedComponent = await compiler.computeDelta();
- throwOnEmptyMixinBodies(initializedComponent);
+ Component initializedComponent = await compiler.computeDelta();
+ util.throwOnEmptyMixinBodies(initializedComponent);
bool result = compiler.initializedFromDill;
- await writeComponentToFile(initializedComponent, output);
+ new File.fromUri(output)
+ .writeAsBytesSync(util.postProcess(initializedComponent));
int actuallyInvalidatedCount =
compiler.invalidatedImportUrisForTesting?.length ?? 0;
if (result && actuallyInvalidatedCount < invalidateUris.length) {
@@ -378,19 +379,20 @@
"got $actuallyInvalidatedCount");
}
- var initializedComponent2 = await compiler.computeDelta(fullComponent: true);
- throwOnEmptyMixinBodies(initializedComponent2);
+ Component initializedFullComponent =
+ await compiler.computeDelta(fullComponent: true);
+ util.throwOnEmptyMixinBodies(initializedFullComponent);
Expect.equals(initializedComponent.libraries.length,
- initializedComponent2.libraries.length);
+ initializedFullComponent.libraries.length);
Expect.equals(initializedComponent.uriToSource.length,
- initializedComponent2.uriToSource.length);
+ initializedFullComponent.uriToSource.length);
for (Uri invalidateUri in invalidateUris) {
compiler.invalidate(invalidateUri);
}
- var partialComponent = await compiler.computeDelta();
- throwOnEmptyMixinBodies(partialComponent);
+ Component partialComponent = await compiler.computeDelta();
+ util.throwOnEmptyMixinBodies(partialComponent);
actuallyInvalidatedCount =
(compiler.invalidatedImportUrisForTesting?.length ?? 0);
if (actuallyInvalidatedCount < invalidateUris.length) {
@@ -398,14 +400,14 @@
"got $actuallyInvalidatedCount");
}
- var emptyComponent = await compiler.computeDelta();
- throwOnEmptyMixinBodies(emptyComponent);
+ Component emptyComponent = await compiler.computeDelta();
+ util.throwOnEmptyMixinBodies(emptyComponent);
- var fullLibUris =
+ List<Uri> fullLibUris =
initializedComponent.libraries.map((lib) => lib.importUri).toList();
- var partialLibUris =
+ List<Uri> partialLibUris =
partialComponent.libraries.map((lib) => lib.importUri).toList();
- var emptyLibUris =
+ List<Uri> emptyLibUris =
emptyComponent.libraries.map((lib) => lib.importUri).toList();
Expect.isTrue(fullLibUris.length > partialLibUris.length ||
@@ -417,29 +419,6 @@
return result;
}
-void throwOnEmptyMixinBodies(Component component) {
- int empty = countEmptyMixinBodies(component);
- if (empty != 0) {
- throw "Expected 0 empty bodies in mixins, but found $empty";
- }
-}
-
-int countEmptyMixinBodies(Component component) {
- int empty = 0;
- for (Library lib in component.libraries) {
- for (Class c in lib.classes) {
- if (c.isSyntheticMixinImplementation) {
- for (Procedure p in c.procedures) {
- if (p.function.body is EmptyStatement) {
- empty++;
- }
- }
- }
- }
- }
- return empty;
-}
-
String substituteVariables(String source, Uri base) {
return source.replaceAll(r"${outDirUri}", "${base}");
}
diff --git a/pkg/front_end/test/incremental_utils.dart b/pkg/front_end/test/incremental_utils.dart
new file mode 100644
index 0000000..c8480bf
--- /dev/null
+++ b/pkg/front_end/test/incremental_utils.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
+
+import 'package:kernel/kernel.dart'
+ show Class, Component, EmptyStatement, Library, Procedure, Reference;
+
+List<int> postProcess(Component c) {
+ c.libraries.sort((l1, l2) {
+ return "${l1.fileUri}".compareTo("${l2.fileUri}");
+ });
+
+ c.computeCanonicalNames();
+ for (Library library in c.libraries) {
+ library.additionalExports.sort((Reference r1, Reference r2) {
+ return "${r1.canonicalName}".compareTo("${r2.canonicalName}");
+ });
+ }
+
+ return serializeComponent(c);
+}
+
+void throwOnEmptyMixinBodies(Component component) {
+ int empty = countEmptyMixinBodies(component);
+ if (empty != 0) {
+ throw "Expected 0 empty bodies in mixins, but found $empty";
+ }
+}
+
+int countEmptyMixinBodies(Component component) {
+ int empty = 0;
+ for (Library lib in component.libraries) {
+ for (Class c in lib.classes) {
+ if (c.isSyntheticMixinImplementation) {
+ for (Procedure p in c.procedures) {
+ if (p.function.body is EmptyStatement) {
+ empty++;
+ }
+ }
+ }
+ }
+ }
+ return empty;
+}
diff --git a/pkg/front_end/test/memory_file_system_test.dart b/pkg/front_end/test/memory_file_system_test.dart
index f679d0b..89f7335 100644
--- a/pkg/front_end/test/memory_file_system_test.dart
+++ b/pkg/front_end/test/memory_file_system_test.dart
@@ -98,7 +98,7 @@
test_readAsBytes_exists() async {
var s = 'contents';
file.writeAsStringSync(s);
- expect(await file.readAsBytes(), UTF8.encode(s));
+ expect(await file.readAsBytes(), utf8.encode(s));
}
test_readAsString_badUtf8() {
diff --git a/pkg/front_end/test/scanner_fasta_test.dart b/pkg/front_end/test/scanner_fasta_test.dart
index c21bdc9..0000f0c 100644
--- a/pkg/front_end/test/scanner_fasta_test.dart
+++ b/pkg/front_end/test/scanner_fasta_test.dart
@@ -40,7 +40,7 @@
expect(result.tokens?.type, same(Keyword.CLASS));
// UTF8 encode source with trailing zero
- List<int> bytes = UTF8.encode(source).toList();
+ List<int> bytes = utf8.encode(source).toList();
bytes.add(0);
result = usedForFuzzTesting.scan(bytes);
@@ -53,7 +53,7 @@
class ScannerTest_Fasta_UTF8 extends ScannerTest_Fasta {
@override
createScanner(String source, {bool genericMethodComments: false}) {
- List<int> encoded = UTF8.encode(source).toList(growable: true);
+ List<int> encoded = utf8.encode(source).toList(growable: true);
encoded.add(0); // Ensure 0 terminted bytes for UTF8 scanner
return new fasta.Utf8BytesScanner(encoded,
includeComments: true,
@@ -65,7 +65,7 @@
var hex = bytes.map((b) => '0x${b.toRadixString(16).toUpperCase()}');
print('$bytes\n[${hex.join(', ')}]');
try {
- UTF8.decode(bytes);
+ utf8.decode(bytes);
} catch (e) {
// Bad UTF-8 encoding
print(' This is invalid UTF-8, but scanner should not crash.');
@@ -712,7 +712,7 @@
@reflectiveTest
class ScannerTest_Fasta_Direct_UTF8 extends ScannerTest_Fasta_Direct {
createScanner(String source, {bool includeComments}) {
- List<int> encoded = UTF8.encode(source).toList(growable: true);
+ List<int> encoded = utf8.encode(source).toList(growable: true);
encoded.add(0); // Ensure 0 terminted bytes for UTF8 scanner
return new fasta.Utf8BytesScanner(encoded,
includeComments: includeComments);
diff --git a/pkg/front_end/test/scanner_replacement_test.dart b/pkg/front_end/test/scanner_replacement_test.dart
index 9cfcb94..984c877 100644
--- a/pkg/front_end/test/scanner_replacement_test.dart
+++ b/pkg/front_end/test/scanner_replacement_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
import 'package:front_end/src/fasta/scanner/recover.dart'
show defaultRecoveryStrategy;
@@ -57,7 +57,7 @@
assertValidTokenStream(tokens);
assertValidBeginTokens(tokens);
if (result.hasErrors) {
- List<int> bytes = UTF8.encode(source);
+ List<int> bytes = utf8.encode(source);
tokens = defaultRecoveryStrategy(bytes, tokens, result.lineStarts);
assertValidTokenStream(tokens, errorsFirst: true);
}
diff --git a/pkg/front_end/test/src/base/flat_buffers_test.dart b/pkg/front_end/test/src/base/flat_buffers_test.dart
index f94c7ed..facd4ae 100644
--- a/pkg/front_end/test/src/base/flat_buffers_test.dart
+++ b/pkg/front_end/test/src/base/flat_buffers_test.dart
@@ -64,21 +64,21 @@
// Convert byteList to a ByteData so that we can read data from it.
ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
// First 4 bytes are an offset to the table data.
- int tableDataLoc = byteData.getUint32(0, Endianness.LITTLE_ENDIAN);
+ int tableDataLoc = byteData.getUint32(0, Endian.little);
// Next 4 bytes are the file identifier.
expect(byteData.getUint8(4), 65); // 'a'
expect(byteData.getUint8(5), 122); // 'z'
expect(byteData.getUint8(6), 126); // '~'
expect(byteData.getUint8(7), 255); // 'ÿ'
// First 4 bytes of the table data are a backwards offset to the vtable.
- int vTableLoc = tableDataLoc -
- byteData.getInt32(tableDataLoc, Endianness.LITTLE_ENDIAN);
+ int vTableLoc =
+ tableDataLoc - byteData.getInt32(tableDataLoc, Endian.little);
// First 2 bytes of the vtable are the size of the vtable in bytes, which
// should be 4.
- expect(byteData.getUint16(vTableLoc, Endianness.LITTLE_ENDIAN), 4);
+ expect(byteData.getUint16(vTableLoc, Endian.little), 4);
// Next 2 bytes are the size of the object in bytes (including the vtable
// pointer), which should be 4.
- expect(byteData.getUint16(vTableLoc + 2, Endianness.LITTLE_ENDIAN), 4);
+ expect(byteData.getUint16(vTableLoc + 2, Endian.little), 4);
}
void test_low() {
@@ -128,23 +128,22 @@
// Convert byteList to a ByteData so that we can read data from it.
ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
// First 4 bytes are an offset to the table data.
- int tableDataLoc = byteData.getUint32(0, Endianness.LITTLE_ENDIAN);
+ int tableDataLoc = byteData.getUint32(0, Endian.little);
// First 4 bytes of the table data are a backwards offset to the vtable.
- int vTableLoc = tableDataLoc -
- byteData.getInt32(tableDataLoc, Endianness.LITTLE_ENDIAN);
+ int vTableLoc =
+ tableDataLoc - byteData.getInt32(tableDataLoc, Endian.little);
// First 2 bytes of the vtable are the size of the vtable in bytes, which
// should be 10.
- expect(byteData.getUint16(vTableLoc, Endianness.LITTLE_ENDIAN), 10);
+ expect(byteData.getUint16(vTableLoc, Endian.little), 10);
// Next 2 bytes are the size of the object in bytes (including the vtable
// pointer), which should be 16.
- expect(byteData.getUint16(vTableLoc + 2, Endianness.LITTLE_ENDIAN), 16);
+ expect(byteData.getUint16(vTableLoc + 2, Endian.little), 16);
// Remaining 6 bytes are the offsets within the object where the ints are
// located.
for (int i = 0; i < 3; i++) {
- int offset =
- byteData.getUint16(vTableLoc + 4 + 2 * i, Endianness.LITTLE_ENDIAN);
- expect(byteData.getInt32(tableDataLoc + offset, Endianness.LITTLE_ENDIAN),
- 10 + 10 * i);
+ int offset = byteData.getUint16(vTableLoc + 4 + 2 * i, Endian.little);
+ expect(
+ byteData.getInt32(tableDataLoc + offset, Endian.little), 10 + 10 * i);
}
}
diff --git a/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart b/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
index 56728d6..9ad0d40 100644
--- a/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
+++ b/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
@@ -9,7 +9,7 @@
import 'dart:async' show Completer, Future;
-import 'dart:convert' show LineSplitter, UTF8;
+import 'dart:convert' show LineSplitter, utf8;
import 'dart:io' show Directory, File, Platform, Process;
@@ -118,14 +118,14 @@
var completers =
new List.generate(expectedLines, (_) => new Completer<String>());
lines = completers.map((c) => c.future).toList();
- vm.stdout.transform(UTF8.decoder).transform(splitter).listen((line) {
+ vm.stdout.transform(utf8.decoder).transform(splitter).listen((line) {
Expect.isTrue(i < expectedLines);
completers[i++].complete(line);
}, onDone: () {
Expect.equals(expectedLines, i);
});
- vm.stderr.transform(UTF8.decoder).transform(splitter).toList().then((err) {
+ vm.stderr.transform(utf8.decoder).transform(splitter).toList().then((err) {
Expect.isTrue(err.isEmpty, err.join('\n'));
});
diff --git a/pkg/front_end/test/standard_file_system_test.dart b/pkg/front_end/test/standard_file_system_test.dart
index e78a3c7..bd67f3b 100644
--- a/pkg/front_end/test/standard_file_system_test.dart
+++ b/pkg/front_end/test/standard_file_system_test.dart
@@ -112,7 +112,7 @@
test_readAsBytes_exists() async {
var s = 'contents';
new io.File(path).writeAsStringSync(s);
- expect(await file.readAsBytes(), UTF8.encode(s));
+ expect(await file.readAsBytes(), utf8.encode(s));
}
test_readAsString_badUtf8() {
diff --git a/pkg/front_end/testcases/expression.status b/pkg/front_end/testcases/expression.status
new file mode 100644
index 0000000..de541b8
--- /dev/null
+++ b/pkg/front_end/testcases/expression.status
@@ -0,0 +1,52 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class_capture.expression: Crash
+class_getter.expression: Crash
+class_invalid_static.expression: Crash
+class_invalid_static_capture.expression: Crash
+class_invalid_static_getter.expression: Crash
+class_invalid_static_setter.expression: Crash
+class_method.expression: Crash
+class_setter.expression: Crash
+class_static.expression: Crash
+class_static2.expression: Crash
+class_static3.expression: Crash
+class_type_param_bound.expression: Crash
+class_type_param_bound_illegal.expression: Crash
+class_type_param_reference.expression: Crash
+class_type_param_reference_arg.expression: Crash
+class_type_param_reference_arg_inferred.expression: Crash
+class_type_param_reference_ctor.expression: Crash
+class_type_param_reference_ctor_inferred.expression: Crash
+class_type_param_reference_var.expression: Crash
+core_lib_imported.expression: Crash
+core_lib_internal.expression: Crash
+eval.dart: Crash
+invalid.expression: Crash
+invalid_type_variable.expression: Crash
+invalid_variable.expression: Crash
+lib_ctor.expression: Crash
+lib_external_ctor.expression: Crash
+lib_nonctor.expression: Crash
+lib_nonreference.expression: Crash
+lib_nonshown_ctor.expression: Crash
+lib_reference.expression: Crash
+lib_simple.expression: Crash
+missing_variable_types.expression: Crash
+noclass.expression: Crash
+nolib.expression: Crash
+param_assign.expression: Crash
+param_capture.expression: Crash
+param_conflict.expression: Crash
+param_conflict_class.expression: Crash
+param_method.expression: Crash
+type_param_bound.expression: Crash
+type_param_shadow.expression: Crash
+type_param_shadow_arg.expression: Crash
+type_param_shadow_arg_ctor_inferred.expression: Crash
+type_param_shadow_arg_inferred.expression: Crash
+type_param_shadow_ctor.expression: Crash
+type_param_shadow_var.expression: Crash
+
diff --git a/pkg/front_end/testcases/expression/class_capture.expression.yaml b/pkg/front_end/testcases/expression/class_capture.expression.yaml
new file mode 100644
index 0000000..8d7121f
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_capture.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+expression: |
+ () { return x + y; }
diff --git a/pkg/front_end/testcases/expression/class_capture.expression.yaml.expect b/pkg/front_end/testcases/expression/class_capture.expression.yaml.expect
new file mode 100644
index 0000000..e937d8c
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_capture.expression.yaml.expect
@@ -0,0 +1,6 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return () → dart.core::int {
+ return this.{main::B::x}.{dart.core::num::+}(this.{main::B::y});
+ };
diff --git a/pkg/front_end/testcases/expression/class_getter.expression.yaml b/pkg/front_end/testcases/expression/class_getter.expression.yaml
new file mode 100644
index 0000000..b633a11
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_getter.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+expression: |
+ z
diff --git a/pkg/front_end/testcases/expression/class_getter.expression.yaml.expect b/pkg/front_end/testcases/expression/class_getter.expression.yaml.expect
new file mode 100644
index 0000000..e8e5846
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_getter.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return this.{main::B::z};
diff --git a/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml
new file mode 100644
index 0000000..d607088
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#A"
+static: true
+expression: |
+ doit_with_this(3)
diff --git a/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect
new file mode 100644
index 0000000..1c3d9f3
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+ Method not found: 'doit_with_this'. (@0)
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], <dynamic>[3].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml b/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml
new file mode 100644
index 0000000..9e410c8
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+static: true
+expression: |
+ () { return x + y; }
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml.expect
new file mode 100644
index 0000000..6208070
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_capture.expression.yaml.expect
@@ -0,0 +1,8 @@
+Errors: {
+ Getter not found: 'y'. (@16)
+ Getter not found: 'x'. (@12)
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return () → dynamic {
+ return (throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#x, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})))).+(throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#y, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{}))));
+ };
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml b/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml
new file mode 100644
index 0000000..e9fa6d2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+static: true
+expression: |
+ z
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml.expect
new file mode 100644
index 0000000..1a79f8a
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_getter.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+ Getter not found: 'z'. (@0)
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#z, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml
new file mode 100644
index 0000000..17539fb
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+static: true
+expression: |
+ z = 2
diff --git a/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect
new file mode 100644
index 0000000..ff2d316
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_invalid_static_setter.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+ Setter not found: 'z'. (@0)
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#z, 34, const <dart.core::Type>[], <dynamic>[2].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_method.expression.yaml b/pkg/front_end/testcases/expression/class_method.expression.yaml
new file mode 100644
index 0000000..5a08e80
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_method.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#A"
+expression: |
+ doit_with_this(2)
diff --git a/pkg/front_end/testcases/expression/class_method.expression.yaml.expect b/pkg/front_end/testcases/expression/class_method.expression.yaml.expect
new file mode 100644
index 0000000..5c85dec
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_method.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return this.{main::A::doit_with_this}(2);
diff --git a/pkg/front_end/testcases/expression/class_setter.expression.yaml b/pkg/front_end/testcases/expression/class_setter.expression.yaml
new file mode 100644
index 0000000..44d76b6
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_setter.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#B"
+expression: |
+ z = 3
diff --git a/pkg/front_end/testcases/expression/class_setter.expression.yaml.expect b/pkg/front_end/testcases/expression/class_setter.expression.yaml.expect
new file mode 100644
index 0000000..8c53fc2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_setter.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return this.{main::B::z} = 3;
diff --git a/pkg/front_end/testcases/expression/class_static.expression.yaml b/pkg/front_end/testcases/expression/class_static.expression.yaml
new file mode 100644
index 0000000..51be2c2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static.expression.yaml
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#A"
+static: true
+expression: |
+ doit(3)
diff --git a/pkg/front_end/testcases/expression/class_static.expression.yaml.expect b/pkg/front_end/testcases/expression/class_static.expression.yaml.expect
new file mode 100644
index 0000000..8fc9b60
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return main::A::doit(3);
diff --git a/pkg/front_end/testcases/expression/class_static2.expression.yaml b/pkg/front_end/testcases/expression/class_static2.expression.yaml
new file mode 100644
index 0000000..2c8e2b0
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static2.expression.yaml
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#A"
+static: true
+expression: |
+ doit_with_this(2)
diff --git a/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect b/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect
new file mode 100644
index 0000000..2a1fd01
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static2.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+ Method not found: 'doit_with_this'. (@0)
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#doit_with_this, 32, const <dart.core::Type>[], <dynamic>[2].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/class_static3.expression.yaml b/pkg/front_end/testcases/expression/class_static3.expression.yaml
new file mode 100644
index 0000000..935b013
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static3.expression.yaml
@@ -0,0 +1,16 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+- entry_point: "eval.dart"
+ definitions: []
+ position: "eval.dart"
+ expression: |
+ globalVar + staticVar + 5
+
+- entry_point: "eval.dart"
+ definitions: []
+ position: "eval.dart#MyClass"
+ static: true
+ expression: |
+ globalVar + staticVar + 5
diff --git a/pkg/front_end/testcases/expression/class_static3.expression.yaml.expect b/pkg/front_end/testcases/expression/class_static3.expression.yaml.expect
new file mode 100644
index 0000000..7bc3bc9
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_static3.expression.yaml.expect
@@ -0,0 +1,9 @@
+Errors: {
+ Getter not found: 'staticVar'. (@12)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return #lib1::globalVar.{dart.core::num::+}((throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#staticVar, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})))) as{TypeError} dart.core::num).{dart.core::num::+}(5);
+Errors: {
+}
+static method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return #lib1::globalVar.{dart.core::num::+}(#lib1::MyClass::staticVar).{dart.core::num::+}(5);
diff --git a/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml
new file mode 100644
index 0000000..be7df51
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#C"
+expression: |
+ hasBound<T>()
diff --git a/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml.expect
new file mode 100644
index 0000000..2fef29d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_bound.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+ return main::hasBound<main::C::T>();
diff --git a/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml
new file mode 100644
index 0000000..d2b970d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+ hasBound<T>()
diff --git a/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml.expect
new file mode 100644
index 0000000..99f4ec9
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_bound_illegal.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+ return main::hasBound<main::A::T>();
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml
new file mode 100644
index 0000000..d5afdd7
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+ x is T
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml.expect
new file mode 100644
index 0000000..4dc0e4e
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+ return x is main::A::T;
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml
new file mode 100644
index 0000000..fa1365b
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+ id<T>(x)
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml.expect
new file mode 100644
index 0000000..9e1d05d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_arg.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+ return main::id<main::A::T>(x as{TypeError} main::A::T);
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml
new file mode 100644
index 0000000..900cff7
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml
@@ -0,0 +1,11 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+ () {
+ x = id(x);
+ }
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml.expect
new file mode 100644
index 0000000..f830c60
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_arg_inferred.expression.yaml.expect
@@ -0,0 +1,6 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+ return () → dart.core::Null {
+ x = main::id<dynamic>(x);
+ };
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml
new file mode 100644
index 0000000..7312962
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+ new A<T>()
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml.expect
new file mode 100644
index 0000000..979c5be
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_ctor.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+ return new main::A::•<main::A::T>();
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml
new file mode 100644
index 0000000..5ae73cf
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml
@@ -0,0 +1,11 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x"]
+position: "main.dart#A"
+expression: |
+ () {
+ x = new A();
+ }
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml.expect
new file mode 100644
index 0000000..5c172f4
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_ctor_inferred.expression.yaml.expect
@@ -0,0 +1,6 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x) → dynamic
+ return () → dart.core::Null {
+ x = new main::A::•<dynamic>();
+ };
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml b/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml
new file mode 100644
index 0000000..1426f35
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml
@@ -0,0 +1,12 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#A"
+expression: |
+ () {
+ T k = null;
+ return k;
+ }
diff --git a/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml.expect b/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml.expect
new file mode 100644
index 0000000..1404a49
--- /dev/null
+++ b/pkg/front_end/testcases/expression/class_type_param_reference_var.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return () → main::A::T {
+ main::A::T k = null;
+ return k;
+ };
diff --git a/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml b/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml
new file mode 100644
index 0000000..328df34
--- /dev/null
+++ b/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+- entry_point: "main.dart"
+ definitions: []
+ position: "dart:collection"
+ expression: |
+ identical(1, 1)
diff --git a/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml.expect b/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml.expect
new file mode 100644
index 0000000..dd6add4
--- /dev/null
+++ b/pkg/front_end/testcases/expression/core_lib_imported.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return dart.core::identical(1, 1);
diff --git a/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml b/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml
new file mode 100644
index 0000000..f3a1533
--- /dev/null
+++ b/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+- entry_point: "main.dart"
+ definitions: []
+ position: "dart:collection"
+ expression: |
+ null is Queue
diff --git a/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml.expect b/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml.expect
new file mode 100644
index 0000000..e5db5df
--- /dev/null
+++ b/pkg/front_end/testcases/expression/core_lib_internal.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return null is dart.collection::Queue<dynamic>;
diff --git a/pkg/front_end/testcases/expression/eval.dart b/pkg/front_end/testcases/expression/eval.dart
new file mode 100644
index 0000000..b905801
--- /dev/null
+++ b/pkg/front_end/testcases/expression/eval.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+int globalVar = 100;
+
+class MyClass {
+ static int staticVar = 1000;
+
+ static void method(int value) {}
+}
+
+void testFunction() {
+ int i = 0;
+ while (true) {
+ if (++i % 100000000 == 0) {
+ MyClass.method(10000);
+ }
+ }
+}
diff --git a/pkg/front_end/testcases/expression/invalid.expression.yaml b/pkg/front_end/testcases/expression/invalid.expression.yaml
new file mode 100644
index 0000000..410e7a9
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+ *foo(3,
diff --git a/pkg/front_end/testcases/expression/invalid.expression.yaml.expect b/pkg/front_end/testcases/expression/invalid.expression.yaml.expect
new file mode 100644
index 0000000..1ce824d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+ Expected an identifier, but got '*'. (@0)
+ Method not found: 'foo'. (@1)
+ Getter not found: ''. (@0)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return (throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#, 33, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})))).*(throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#foo, 32, const <dart.core::Type>[], <dynamic>[3].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{}))));
diff --git a/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml b/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml
new file mode 100644
index 0000000..79ff7ae
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+type_definitions: ["a#b"]
+position: "main.dart"
+expression: |
+ 3
diff --git a/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml.expect b/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml.expect
new file mode 100644
index 0000000..ba1f145
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid_type_variable.expression.yaml.expect
@@ -0,0 +1,3 @@
+Errors: {
+}
+<no procedure>
diff --git a/pkg/front_end/testcases/expression/invalid_variable.expression.yaml b/pkg/front_end/testcases/expression/invalid_variable.expression.yaml
new file mode 100644
index 0000000..3409817
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid_variable.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["a#b"]
+position: "main.dart"
+expression: |
+ 3
diff --git a/pkg/front_end/testcases/expression/invalid_variable.expression.yaml.expect b/pkg/front_end/testcases/expression/invalid_variable.expression.yaml.expect
new file mode 100644
index 0000000..ba1f145
--- /dev/null
+++ b/pkg/front_end/testcases/expression/invalid_variable.expression.yaml.expect
@@ -0,0 +1,3 @@
+Errors: {
+}
+<no procedure>
diff --git a/pkg/front_end/testcases/expression/lib_ctor.expression.yaml b/pkg/front_end/testcases/expression/lib_ctor.expression.yaml
new file mode 100644
index 0000000..9bfc310
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_ctor.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+ () { new A(); const A(); }
diff --git a/pkg/front_end/testcases/expression/lib_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_ctor.expression.yaml.expect
new file mode 100644
index 0000000..b4269a7
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_ctor.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return () → dart.core::Null {
+ new main::A::•<dynamic>();
+ const main::A::•<dynamic>();
+ };
diff --git a/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml b/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml
new file mode 100644
index 0000000..aac6c87
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+ () { new Process(); new File.fromUri(Uri.parse("file://test.dart")); }
diff --git a/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml.expect
new file mode 100644
index 0000000..a9ca37b
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_external_ctor.expression.yaml.expect
@@ -0,0 +1,8 @@
+Errors: {
+ The class 'Process' is abstract and can't be instantiated. (@9)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return () → dart.core::Null {
+ throw new dart.core::AbstractClassInstantiationError::•("Process");
+ dart.io::File::fromUri(dart.core::Uri::parse("file://test.dart"));
+ };
diff --git a/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml b/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml
new file mode 100644
index 0000000..4cf924a
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+ new Random();
diff --git a/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml.expect
new file mode 100644
index 0000000..b82b038
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonctor.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+ Method not found: 'Random'. (@4)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#Random, 32, const <dart.core::Type>[], const <dynamic>[], dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml
new file mode 100644
index 0000000..67849fd
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+ acos(1.0)
diff --git a/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect
new file mode 100644
index 0000000..d7a9a32
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonreference.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+ Method not found: 'acos'. (@0)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#acos, 32, const <dart.core::Type>[], <dynamic>[1.0].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml
new file mode 100644
index 0000000..dbc9544
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+ new Directory("test")
diff --git a/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
new file mode 100644
index 0000000..699e4fa
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
@@ -0,0 +1,5 @@
+Errors: {
+ Method not found: 'Directory'. (@4)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return throw new dart.core::NoSuchMethodError::withInvocation(null, new dart.core::_InvocationMirror::_withType(#Directory, 32, const <dart.core::Type>[], <dynamic>["test"].toList(growable: false), dart.core::Map::unmodifiable<dart.core::Symbol, dynamic>(const <dart.core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/expression/lib_reference.expression.yaml b/pkg/front_end/testcases/expression/lib_reference.expression.yaml
new file mode 100644
index 0000000..e4f0254
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_reference.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+ exit(2)
diff --git a/pkg/front_end/testcases/expression/lib_reference.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_reference.expression.yaml.expect
new file mode 100644
index 0000000..5f9d49f
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_reference.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return dart.io::exit(2);
diff --git a/pkg/front_end/testcases/expression/lib_simple.expression.yaml b/pkg/front_end/testcases/expression/lib_simple.expression.yaml
new file mode 100644
index 0000000..0e7ca4c
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_simple.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart"
+expression: |
+ doitstat(2)
diff --git a/pkg/front_end/testcases/expression/lib_simple.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_simple.expression.yaml.expect
new file mode 100644
index 0000000..c54d90c
--- /dev/null
+++ b/pkg/front_end/testcases/expression/lib_simple.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+ return main::doitstat(2);
diff --git a/pkg/front_end/testcases/expression/main.dart b/pkg/front_end/testcases/expression/main.dart
new file mode 100644
index 0000000..ba2d61d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/main.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library main;
+
+import 'dart:io' show File, Process, exit;
+
+int doitstat(int x) => x + 1;
+
+int globalVar = 6;
+
+class A<T> {
+ const A();
+ static int doit(int x) => x + 1;
+ static int staticVar = 3;
+ int doit_with_this(int x) => x + 1;
+}
+
+T id<T>(T x) => x;
+
+class B {
+ int x;
+ final int y;
+ String get z {
+ return "";
+ }
+
+ void set z(int _) {}
+}
+
+class Bound {}
+
+class C<T extends Bound> {}
+
+void hasBound<T extends Bound>() {}
+
+Object k;
+
+class D<T> {
+ Y id<Y>(Y x) => x;
+ m(List<T> l) {
+ assert(l is List<T>);
+ }
+
+ foo() {
+ List<T> s;
+ }
+}
+
+main() {
+ exit(0);
+}
diff --git a/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml b/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml
new file mode 100644
index 0000000..9411454
--- /dev/null
+++ b/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["s"]
+position: "main.dart#D"
+expression: |
+ m(id(s = []))
diff --git a/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml.expect b/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml.expect
new file mode 100644
index 0000000..6b64c73
--- /dev/null
+++ b/pkg/front_end/testcases/expression/missing_variable_types.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic s) → dynamic
+ return this.{main::D::m}(this.{main::D::id}<dart.core::List<main::D::T>>((s = <dynamic>[]) as{TypeError} dart.core::List<main::D::T>));
diff --git a/pkg/front_end/testcases/expression/noclass.expression.yaml b/pkg/front_end/testcases/expression/noclass.expression.yaml
new file mode 100644
index 0000000..ef09ec8
--- /dev/null
+++ b/pkg/front_end/testcases/expression/noclass.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "main.dart#NoClass"
+expression: |
+ 0
diff --git a/pkg/front_end/testcases/expression/noclass.expression.yaml.expect b/pkg/front_end/testcases/expression/noclass.expression.yaml.expect
new file mode 100644
index 0000000..ba1f145
--- /dev/null
+++ b/pkg/front_end/testcases/expression/noclass.expression.yaml.expect
@@ -0,0 +1,3 @@
+Errors: {
+}
+<no procedure>
diff --git a/pkg/front_end/testcases/expression/nolib.expression.yaml b/pkg/front_end/testcases/expression/nolib.expression.yaml
new file mode 100644
index 0000000..1502f41
--- /dev/null
+++ b/pkg/front_end/testcases/expression/nolib.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "nono.dart"
+expression: |
+ 0
diff --git a/pkg/front_end/testcases/expression/nolib.expression.yaml.expect b/pkg/front_end/testcases/expression/nolib.expression.yaml.expect
new file mode 100644
index 0000000..ba1f145
--- /dev/null
+++ b/pkg/front_end/testcases/expression/nolib.expression.yaml.expect
@@ -0,0 +1,3 @@
+Errors: {
+}
+<no procedure>
diff --git a/pkg/front_end/testcases/expression/param_assign.expression.yaml b/pkg/front_end/testcases/expression/param_assign.expression.yaml
new file mode 100644
index 0000000..a0262f1
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_assign.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x", "y"]
+position: "main.dart"
+expression: |
+ x = 3
diff --git a/pkg/front_end/testcases/expression/param_assign.expression.yaml.expect b/pkg/front_end/testcases/expression/param_assign.expression.yaml.expect
new file mode 100644
index 0000000..7f05f7a
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_assign.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x, dynamic y) → dynamic
+ return x = 3;
diff --git a/pkg/front_end/testcases/expression/param_capture.expression.yaml b/pkg/front_end/testcases/expression/param_capture.expression.yaml
new file mode 100644
index 0000000..72b991d
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_capture.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x", "y"]
+position: "main.dart"
+expression: |
+ () { x = x + y; }
diff --git a/pkg/front_end/testcases/expression/param_capture.expression.yaml.expect b/pkg/front_end/testcases/expression/param_capture.expression.yaml.expect
new file mode 100644
index 0000000..b8ea8d2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_capture.expression.yaml.expect
@@ -0,0 +1,6 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x, dynamic y) → dynamic
+ return () → dart.core::Null {
+ x = x.+(y);
+ };
diff --git a/pkg/front_end/testcases/expression/param_conflict.expression.yaml b/pkg/front_end/testcases/expression/param_conflict.expression.yaml
new file mode 100644
index 0000000..8304043
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_conflict.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["dostat", "y"]
+position: "main.dart"
+expression: |
+ dostat.foo()
diff --git a/pkg/front_end/testcases/expression/param_conflict.expression.yaml.expect b/pkg/front_end/testcases/expression/param_conflict.expression.yaml.expect
new file mode 100644
index 0000000..5c4a28c
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_conflict.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic dostat, dynamic y) → dynamic
+ return dostat.foo();
diff --git a/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml b/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml
new file mode 100644
index 0000000..48969a2
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["A", "y"]
+position: "main.dart"
+expression: |
+ A.foo(y)
diff --git a/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml.expect b/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml.expect
new file mode 100644
index 0000000..c66e526
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_conflict_class.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic A, dynamic y) → dynamic
+ return A.foo(y);
diff --git a/pkg/front_end/testcases/expression/param_method.expression.yaml b/pkg/front_end/testcases/expression/param_method.expression.yaml
new file mode 100644
index 0000000..da82702
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_method.expression.yaml
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x", "y"]
+position: "main.dart"
+expression: |
+ x.foo(y)
diff --git a/pkg/front_end/testcases/expression/param_method.expression.yaml.expect b/pkg/front_end/testcases/expression/param_method.expression.yaml.expect
new file mode 100644
index 0000000..4f6b188
--- /dev/null
+++ b/pkg/front_end/testcases/expression/param_method.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr(dynamic x, dynamic y) → dynamic
+ return x.foo(y);
diff --git a/pkg/front_end/testcases/expression/type_param_bound.expression.yaml b/pkg/front_end/testcases/expression/type_param_bound.expression.yaml
new file mode 100644
index 0000000..9c3a1ce
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_bound.expression.yaml
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+type_definitions: ["T"]
+position: "main.dart"
+expression: |
+ hasBound<T>()
diff --git a/pkg/front_end/testcases/expression/type_param_bound.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_bound.expression.yaml.expect
new file mode 100644
index 0000000..285eca0
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_bound.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
+ return main::hasBound<main::debugExpr::T>();
diff --git a/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml
new file mode 100644
index 0000000..4a291a5
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x"]
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+ x is T
diff --git a/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml.expect
new file mode 100644
index 0000000..dfc583e
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>(dynamic x) → dynamic
+ return x is main::A::debugExpr::T;
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml
new file mode 100644
index 0000000..412fea8
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x"]
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+ id<T>(x)
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml.expect
new file mode 100644
index 0000000..1a951e3
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>(dynamic x) → dynamic
+ return main::id<main::A::debugExpr::T>(x as{TypeError} main::A::debugExpr::T);
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml
new file mode 100644
index 0000000..94e653b
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml
@@ -0,0 +1,12 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+ () {
+ T k = new A();
+ }
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect
new file mode 100644
index 0000000..6368c6b
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_ctor_inferred.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+ A value of type 'main::A<dynamic>' can't be assigned to a variable of type 'main::A::debugExpr::T'. (@17)
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
+ return () → dart.core::Null {
+ main::A::debugExpr::T k = let final dynamic #t1 = new main::A::•<dynamic>() in let dynamic _ = null in invalid-expression "Error: A value of type 'main::A<dynamic>' can't be assigned to a variable of type 'main::A::debugExpr::T'.\nTry changing the type of the left hand side, or casting the right hand side to 'main::A::debugExpr::T'.";
+ };
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml
new file mode 100644
index 0000000..fa853f1
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml
@@ -0,0 +1,13 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+ () {
+ T k = null;
+ k = id(k);
+ }
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml.expect
new file mode 100644
index 0000000..77370b6
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_arg_inferred.expression.yaml.expect
@@ -0,0 +1,7 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
+ return () → dart.core::Null {
+ main::A::debugExpr::T k = null;
+ k = main::id<main::A::debugExpr::T>(k);
+ };
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml
new file mode 100644
index 0000000..6dacbfb
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+ new A<T>()
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml.expect
new file mode 100644
index 0000000..87f7a81
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_ctor.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>() → dynamic
+ return new main::A::•<main::A::debugExpr::T>();
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml b/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml
new file mode 100644
index 0000000..bf266c6
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml
@@ -0,0 +1,12 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: ["x"]
+type_definitions: ["T"]
+position: "main.dart#A"
+expression: |
+ () {
+ T x = null;
+ }
diff --git a/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml.expect b/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml.expect
new file mode 100644
index 0000000..0fb5c63
--- /dev/null
+++ b/pkg/front_end/testcases/expression/type_param_shadow_var.expression.yaml.expect
@@ -0,0 +1,6 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr<T extends dynamic>(dynamic x) → dynamic
+ return () → dart.core::Null {
+ main::A::debugExpr::T x = null;
+ };
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
index c9e0195..d336e98 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_invalidate_on_export_of_main.yaml
@@ -2,7 +2,7 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE.md file.
-# Invalidate nothing when the entrypoint just exports another file
+# Invalidate nothing when the entrypoint just exports another file
# (which has main).
type: basic
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
index b71b402..544bc96 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.expect
@@ -2,15 +2,16 @@
import self as self;
import "dart:core" as core;
-static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Previous use of 'g'.
- /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
- ^"]/* from null */;
static method test() → dynamic {
function f() → dynamic
return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
g() => 0;
^";
+ function g() → dynamic
+ return 0;
+ }
dynamic v = f;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
index b71b402..544bc96 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
@@ -2,15 +2,16 @@
import self as self;
import "dart:core" as core;
-static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Previous use of 'g'.
- /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
- ^"]/* from null */;
static method test() → dynamic {
function f() → dynamic
return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
g() => 0;
^";
+ function g() → dynamic
+ return 0;
+ }
dynamic v = f;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
index 6343ea9..1b564d8 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
@@ -4,15 +4,17 @@
static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Method not found: 'g'.
/*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
- ^", "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Previous use of 'g'.
- /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
^"]/* from null */;
static method test() → dynamic {
function f() → dynamic
return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
g() => 0;
^";
+ function g() → dynamic
+ return 0;
+ }
() → dynamic v = f;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
index 6343ea9..fa37ad4 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
@@ -4,15 +4,17 @@
static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Method not found: 'g'.
/*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
- ^", "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Previous use of 'g'.
- /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
^"]/* from null */;
static method test() → dynamic {
function f() → dynamic
return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
- invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+ {
+ let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
g() => 0;
^";
+ function g() → dynamic
+ return 0;
+ }
() → dynamic v = f;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart b/pkg/front_end/testcases/named_function_scope.dart
new file mode 100644
index 0000000..bb6e8aa
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*@testedFeatures=error,warning,context*/
+
+class T {}
+
+class V {}
+
+test() {
+ T t;
+ V v;
+ {
+ // This doesn't cause an error as the previous use of T is in an enclosing
+ // scope.
+ T() {}
+ }
+ {
+ // This doesn't cause an error as the previous use of V is in an enclosing
+ // scope.
+ var v;
+ }
+ {
+ T t;
+ // This doesn't cause a scope error as the named function expression has
+ // its own scope.
+ var x = /*@error=NamedFunctionExpression*/ T() {};
+ }
+ {
+ /*@context=DuplicatedNamePreviouslyUsedCause*/ V v;
+ // This causes an error, V is already used in this scope.
+ var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+ }
+ {
+ /*@context=DuplicatedNamePreviouslyUsedCause*/ V v;
+ // This causes an error, V is already used in this scope.
+ var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+ }
+ {
+ // This causes a scope error as T is already used in the function-type
+ // scope (the return type).
+ var x =
+ /*@error=ReturnTypeFunctionExpression*/
+ /*@context=DuplicatedNamePreviouslyUsedCause*/
+ T
+ /*@error=NamedFunctionExpression*/
+ /*@error=DuplicatedNamePreviouslyUsed*/
+ T() {};
+ }
+ {
+ // This causes a scope error: using the outer definition of `V` as a type
+ // when defining `V`.
+ /*@context=DuplicatedNamePreviouslyUsedCause*/
+ V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+ }
+ {
+ // This causes a scope error as T is already defined as a type variable in
+ // the function-type scope.
+ var x =
+ /*@error=NamedFunctionExpression*/
+ /*@error=DuplicatedName*/
+ T< /*@context=DuplicatedNameCause*/ T>() {};
+ }
+ {
+ /*@context=DuplicatedNamePreviouslyUsedCause*/
+ T t;
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+ }
+ {
+ /*@context=DuplicatedNamePreviouslyUsedCause*/
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+ }
+ {
+ /*@context=DuplicatedNamePreviouslyUsedCause*/
+ T t;
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+ }
+ {
+ /*@context=DuplicatedNamePreviouslyUsedCause*/
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+ }
+ {
+ void T(/*@error=NotAType*/ T t) {}
+ }
+}
+
+void main() {
+}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.direct.expect b/pkg/front_end/testcases/named_function_scope.dart.direct.expect
new file mode 100644
index 0000000..a6a572a
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.direct.expect
@@ -0,0 +1,102 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class T extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class V extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
+ var x = /*@error=NamedFunctionExpression*/ T() {};
+ ^", "pkg/front_end/testcases/named_function_scope.dart:46:9: Error: A function expression can't have a return type.
+ T
+ ^", "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: A function expression can't have a name.
+ T() {};
+ ^", "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: A function expression can't have a name.
+ T< /*@context=DuplicatedNameCause*/ T>() {};
+ ^"]/* from null */;
+static method test() → dynamic {
+ self::T t;
+ self::V v;
+ {
+ function T() → dynamic {}
+ }
+ {
+ dynamic v;
+ }
+ {
+ self::T t;
+ dynamic x = let final () → dynamic T = () → dynamic {} in T;
+ }
+ {
+ self::V v;
+ dynamic V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:33:49: Error: Can't declare 'V' because it was already used in this scope.
+ var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+ ^";
+ }
+ {
+ self::V v;
+ dynamic V = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:38:49: Error: Can't declare 'V' because it was already used in this scope.
+ var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+ ^" in let final dynamic #t2 = null in null;
+ }
+ {
+ dynamic x = let final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: Can't declare 'T' because it was already used in this scope.
+ T() {};
+ ^" in let final () → self::T T = () → self::T {} in T;
+ }
+ {
+ self::V V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:55:47: Error: Can't declare 'V' because it was already used in this scope.
+ V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+ ^";
+ }
+ {
+ dynamic x = let final dynamic #t4 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: 'T' is already declared in this scope.
+ T< /*@context=DuplicatedNameCause*/ T>() {};
+ ^" in let final <T extends core::Object>() → dynamic T = <T extends core::Object>() → dynamic {} in T;
+ }
+ {
+ self::T t;
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+ ^";
+ function T() → self::T {}
+ }
+ }
+ {
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+ ^";
+ function T() → self::T {}
+ }
+ }
+ {
+ self::T t;
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+ ^";
+ function T(self::T t) → self::T {}
+ }
+ }
+ {
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+ ^";
+ function T(self::T t) → self::T {}
+ }
+ }
+ {
+ function T(invalid-type t) → void {}
+ }
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
new file mode 100644
index 0000000..a6a572a
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
@@ -0,0 +1,102 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class T extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class V extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
+ var x = /*@error=NamedFunctionExpression*/ T() {};
+ ^", "pkg/front_end/testcases/named_function_scope.dart:46:9: Error: A function expression can't have a return type.
+ T
+ ^", "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: A function expression can't have a name.
+ T() {};
+ ^", "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: A function expression can't have a name.
+ T< /*@context=DuplicatedNameCause*/ T>() {};
+ ^"]/* from null */;
+static method test() → dynamic {
+ self::T t;
+ self::V v;
+ {
+ function T() → dynamic {}
+ }
+ {
+ dynamic v;
+ }
+ {
+ self::T t;
+ dynamic x = let final () → dynamic T = () → dynamic {} in T;
+ }
+ {
+ self::V v;
+ dynamic V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:33:49: Error: Can't declare 'V' because it was already used in this scope.
+ var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+ ^";
+ }
+ {
+ self::V v;
+ dynamic V = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:38:49: Error: Can't declare 'V' because it was already used in this scope.
+ var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+ ^" in let final dynamic #t2 = null in null;
+ }
+ {
+ dynamic x = let final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: Can't declare 'T' because it was already used in this scope.
+ T() {};
+ ^" in let final () → self::T T = () → self::T {} in T;
+ }
+ {
+ self::V V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:55:47: Error: Can't declare 'V' because it was already used in this scope.
+ V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+ ^";
+ }
+ {
+ dynamic x = let final dynamic #t4 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: 'T' is already declared in this scope.
+ T< /*@context=DuplicatedNameCause*/ T>() {};
+ ^" in let final <T extends core::Object>() → dynamic T = <T extends core::Object>() → dynamic {} in T;
+ }
+ {
+ self::T t;
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+ ^";
+ function T() → self::T {}
+ }
+ }
+ {
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+ ^";
+ function T() → self::T {}
+ }
+ }
+ {
+ self::T t;
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+ ^";
+ function T(self::T t) → self::T {}
+ }
+ }
+ {
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+ ^";
+ function T(self::T t) → self::T {}
+ }
+ }
+ {
+ function T(invalid-type t) → void {}
+ }
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.outline.expect b/pkg/front_end/testcases/named_function_scope.dart.outline.expect
new file mode 100644
index 0000000..95be2cd
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.outline.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class T extends core::Object {
+ synthetic constructor •() → void
+ ;
+}
+class V extends core::Object {
+ synthetic constructor •() → void
+ ;
+}
+static method test() → dynamic
+ ;
+static method main() → void
+ ;
diff --git a/pkg/front_end/testcases/named_function_scope.dart.strong.expect b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
new file mode 100644
index 0000000..c207784
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
@@ -0,0 +1,104 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class T extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class V extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
+ var x = /*@error=NamedFunctionExpression*/ T() {};
+ ^", "pkg/front_end/testcases/named_function_scope.dart:46:9: Error: A function expression can't have a return type.
+ T
+ ^", "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: A function expression can't have a name.
+ T() {};
+ ^", "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: A function expression can't have a name.
+ T< /*@context=DuplicatedNameCause*/ T>() {};
+ ^", "pkg/front_end/testcases/named_function_scope.dart:84:32: Error: 'T' isn't a type.
+ void T(/*@error=NotAType*/ T t) {}
+ ^"]/* from null */;
+static method test() → dynamic {
+ self::T t;
+ self::V v;
+ {
+ function T() → core::Null {}
+ }
+ {
+ dynamic v;
+ }
+ {
+ self::T t;
+ () → core::Null x = let final () → core::Null T = () → core::Null {} in T;
+ }
+ {
+ self::V v;
+ dynamic V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:33:49: Error: Can't declare 'V' because it was already used in this scope.
+ var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+ ^";
+ }
+ {
+ self::V v;
+ dynamic V = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:38:49: Error: Can't declare 'V' because it was already used in this scope.
+ var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+ ^" in let final dynamic #t2 = null in null;
+ }
+ {
+ dynamic x = let final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: Can't declare 'T' because it was already used in this scope.
+ T() {};
+ ^" in let final () → self::T T = () → self::T {} in T;
+ }
+ {
+ self::V V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:55:47: Error: Can't declare 'V' because it was already used in this scope.
+ V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+ ^" as{TypeError} self::V;
+ }
+ {
+ dynamic x = let final dynamic #t4 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: 'T' is already declared in this scope.
+ T< /*@context=DuplicatedNameCause*/ T>() {};
+ ^" in let final <T extends core::Object>() → dynamic T = <T extends core::Object>() → dynamic {} in T;
+ }
+ {
+ self::T t;
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+ ^";
+ function T() → self::T {}
+ }
+ }
+ {
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+ ^";
+ function T() → self::T {}
+ }
+ }
+ {
+ self::T t;
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+ ^";
+ function T(self::T t) → self::T {}
+ }
+ }
+ {
+ {
+ let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+ ^";
+ function T(self::T t) → self::T {}
+ }
+ }
+ {
+ function T(invalid-type t) → void {}
+ }
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
new file mode 100644
index 0000000..4fcb933
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
@@ -0,0 +1,104 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class T extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class V extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
+ var x = /*@error=NamedFunctionExpression*/ T() {};
+ ^", "pkg/front_end/testcases/named_function_scope.dart:46:9: Error: A function expression can't have a return type.
+ T
+ ^", "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: A function expression can't have a name.
+ T() {};
+ ^", "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: A function expression can't have a name.
+ T< /*@context=DuplicatedNameCause*/ T>() {};
+ ^", "pkg/front_end/testcases/named_function_scope.dart:84:32: Error: 'T' isn't a type.
+ void T(/*@error=NotAType*/ T t) {}
+ ^"]/* from null */;
+static method test() → dynamic {
+ self::T t;
+ self::V v;
+ {
+ function T() → core::Null {}
+ }
+ {
+ dynamic v;
+ }
+ {
+ self::T t;
+ () → core::Null x = let final () → core::Null T = () → core::Null {} in T;
+ }
+ {
+ self::V v;
+ dynamic V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:33:49: Error: Can't declare 'V' because it was already used in this scope.
+ var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+ ^";
+ }
+ {
+ self::V v;
+ dynamic V = let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:38:49: Error: Can't declare 'V' because it was already used in this scope.
+ var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+ ^" in let final<BottomType> #t2 = null in null;
+ }
+ {
+ dynamic x = let final dynamic #t3 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:49:9: Error: Can't declare 'T' because it was already used in this scope.
+ T() {};
+ ^" in let final () → self::T T = () → self::T {} in T;
+ }
+ {
+ self::V V = invalid-expression "pkg/front_end/testcases/named_function_scope.dart:55:47: Error: Can't declare 'V' because it was already used in this scope.
+ V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+ ^" as{TypeError} self::V;
+ }
+ {
+ dynamic x = let final dynamic #t4 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:63:9: Error: 'T' is already declared in this scope.
+ T< /*@context=DuplicatedNameCause*/ T>() {};
+ ^" in let final <T extends core::Object>() → dynamic T = <T extends core::Object>() → dynamic {} in T;
+ }
+ {
+ self::T t;
+ {
+ let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:68:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+ ^";
+ function T() → self::T {}
+ }
+ }
+ {
+ {
+ let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:72:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+ ^";
+ function T() → self::T {}
+ }
+ }
+ {
+ self::T t;
+ {
+ let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:77:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+ ^";
+ function T(self::T t) → self::T {}
+ }
+ }
+ {
+ {
+ let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:81:47: Error: Can't declare 'T' because it was already used in this scope.
+ T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+ ^";
+ function T(self::T t) → self::T {}
+ }
+ }
+ {
+ function T(invalid-type t) → void {}
+ }
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect b/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect
index f52c009..01ccbc1 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.direct.expect
@@ -1,13 +1,11 @@
library;
import self as self;
+import "dart:core" as core;
-static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Previous use of 'i'.
- for (int i = i;; false) {}
- ^"]/* from null */;
static method bad() → dynamic {
- for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+ for (core::int i = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
for (int i = i;; false) {}
- ^"; ; false) {
+ ^" in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null; ; false) {
}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
index f52c009..01ccbc1 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
@@ -1,13 +1,11 @@
library;
import self as self;
+import "dart:core" as core;
-static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Previous use of 'i'.
- for (int i = i;; false) {}
- ^"]/* from null */;
static method bad() → dynamic {
- for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+ for (core::int i = let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
for (int i = i;; false) {}
- ^"; ; false) {
+ ^" in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null; ; false) {
}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
index 95a6e96..2f59826 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
@@ -1,15 +1,14 @@
library;
import self as self;
+import "dart:core" as core;
static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Getter not found: 'i'.
for (int i = i;; false) {}
- ^", "pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Previous use of 'i'.
- for (int i = i;; false) {}
^"]/* from null */;
static method bad() → dynamic {
- for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+ for (core::int i = (let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
for (int i = i;; false) {}
- ^"; ; false) {
+ ^" in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null) as{TypeError} core::int; ; false) {
}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
index 95a6e96..609e28a 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
@@ -1,15 +1,14 @@
library;
import self as self;
+import "dart:core" as core;
static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Getter not found: 'i'.
for (int i = i;; false) {}
- ^", "pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Previous use of 'i'.
- for (int i = i;; false) {}
^"]/* from null */;
static method bad() → dynamic {
- for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+ for (core::int i = (let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
for (int i = i;; false) {}
- ^"; ; false) {
+ ^" in let final<BottomType> #t2 = let<BottomType> _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#i, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in null) as{TypeError} core::int; ; false) {
}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31184.dart.direct.expect
index f7b5642..4796ca3 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.direct.expect
@@ -8,7 +8,7 @@
for (int i = 0, i > 10; i++) {}
^"]/* from null */;
static method bad() → dynamic {
- for (core::int i = 0, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' already declared in this scope.
+ for (core::int i = 0, core::int i = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
for (int i = 0, i > 10; i++) {}
^"; (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).>(10); i = i.+(1)) {
}
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect
index f7b5642..4796ca3 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect
@@ -8,7 +8,7 @@
for (int i = 0, i > 10; i++) {}
^"]/* from null */;
static method bad() → dynamic {
- for (core::int i = 0, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' already declared in this scope.
+ for (core::int i = 0, core::int i = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
for (int i = 0, i > 10; i++) {}
^"; (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).>(10); i = i.+(1)) {
}
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect
index 6f23240..63579fd 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect
@@ -10,9 +10,9 @@
for (int i = 0, i > 10; i++) {}
^"]/* from null */;
static method bad() → dynamic {
- for (core::int i = 0, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' already declared in this scope.
+ for (core::int i = 0, core::int i = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
for (int i = 0, i > 10; i++) {}
- ^"; (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).>(10) as{TypeError} core::bool; i = i.{core::num::+}(1)) {
+ ^" as{TypeError} core::int; (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).>(10) as{TypeError} core::bool; i = i.{core::num::+}(1)) {
}
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index 0d7449a..231aa5e 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -63,7 +63,8 @@
"/testcases/.*_part[0-9]*\\.dart$",
"/testcases/.*_lib[0-9]*\\.dart$",
"/testcases/dartino/",
- "/testcases/shaker/"
+ "/testcases/shaker/",
+ "/testcases/expression/"
]
},
@@ -80,7 +81,8 @@
"/testcases/.*_part[0-9]*\\.dart$",
"/testcases/.*_lib[0-9]*\\.dart$",
"/testcases/dartino/",
- "/testcases/shaker/"
+ "/testcases/shaker/",
+ "/testcases/expression/"
]
},
@@ -97,7 +99,8 @@
"/testcases/.*_part[0-9]*\\.dart$",
"/testcases/.*_lib[0-9]*\\.dart$",
"/testcases/dartino/",
- "/testcases/shaker/"
+ "/testcases/shaker/",
+ "/testcases/expression/"
]
},
diff --git a/pkg/front_end/tool/_fasta/abcompile.dart b/pkg/front_end/tool/_fasta/abcompile.dart
index b419d29..fcaf2bd 100644
--- a/pkg/front_end/tool/_fasta/abcompile.dart
+++ b/pkg/front_end/tool/_fasta/abcompile.dart
@@ -156,7 +156,7 @@
}
if (line.startsWith(_summaryTag)) {
String json = line.substring(_summaryTag.length - 2);
- Map<String, dynamic> results = JSON.decode(json);
+ Map<String, dynamic> results = jsonDecode(json);
List<double> elapsedTimes = results['elapsedTimes'];
print('\nElapse times: $elapsedTimes');
if (elapsedTimes.length > 0) {
@@ -183,7 +183,7 @@
stderr.addStream(process.stderr);
StreamSubscription<String> stdOutSubscription;
stdOutSubscription = process.stdout
- .transform(UTF8.decoder)
+ .transform(utf8.decoder)
.transform(new LineSplitter())
.listen(processLine, onDone: () {
stdOutSubscription.cancel();
diff --git a/pkg/front_end/tool/_fasta/bulk_compile.dart b/pkg/front_end/tool/_fasta/bulk_compile.dart
index 7101a1a..fd4e09b 100644
--- a/pkg/front_end/tool/_fasta/bulk_compile.dart
+++ b/pkg/front_end/tool/_fasta/bulk_compile.dart
@@ -4,7 +4,7 @@
import 'dart:async' show Future;
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
import 'package:front_end/src/api_prototype/compiler_options.dart'
show CompilerOptions;
@@ -63,7 +63,7 @@
}
Uri uri = new Uri(scheme: customScheme, host: "", path: path);
MemoryFileSystemEntity entity = options.fileSystem.entityForUri(uri);
- entity.bytes = UTF8.encode(source);
+ entity.bytes = utf8.encode(source);
}
}
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index c69bb9b..1586b35 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -6,7 +6,7 @@
import 'dart:async' show Future, Stream;
-import 'dart:convert' show JSON, LineSplitter, UTF8;
+import 'dart:convert' show jsonDecode, jsonEncode, LineSplitter, utf8;
import 'dart:io' show File, exitCode, stderr, stdin, stdout;
@@ -69,7 +69,7 @@
}
if (summary) {
- var json = JSON.encode(<String, dynamic>{'elapsedTimes': elapsedTimes});
+ var json = jsonEncode(<String, dynamic>{'elapsedTimes': elapsedTimes});
print('\nSummary: $json');
}
}
@@ -85,7 +85,7 @@
batchEntryPoint(List<String> arguments) {
return new BatchCompiler(
- stdin.transform(UTF8.decoder).transform(new LineSplitter()))
+ stdin.transform(utf8.decoder).transform(new LineSplitter()))
.run();
}
@@ -101,7 +101,7 @@
run() async {
await for (String line in lines) {
try {
- if (await batchCompileArguments(JSON.decode(line))) {
+ if (await batchCompileArguments(jsonDecode(line))) {
stdout.writeln(">>> TEST OK");
} else {
stdout.writeln(">>> TEST FAIL");
diff --git a/pkg/front_end/tool/_fasta/log_analyzer.dart b/pkg/front_end/tool/_fasta/log_analyzer.dart
index 029b6d2..c93e916 100644
--- a/pkg/front_end/tool/_fasta/log_analyzer.dart
+++ b/pkg/front_end/tool/_fasta/log_analyzer.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
import 'dart:io';
@@ -16,7 +16,7 @@
}
for (String filename in cl.arguments) {
String json = await new File(filename).readAsString();
- Map<String, dynamic> data = JSON.decode(json) as Map<String, dynamic>;
+ Map<String, dynamic> data = jsonDecode(json) as Map<String, dynamic>;
StringBuffer sb = new StringBuffer();
bool isFirst = true;
for (String field in fields) {
@@ -25,7 +25,7 @@
}
if (field.startsWith("json:")) {
field = field.substring(5);
- sb.write(JSON.encode(data[field]));
+ sb.write(jsonEncode(data[field]));
} else {
sb.write(data[field]);
}
diff --git a/pkg/front_end/tool/_fasta/log_collector.dart b/pkg/front_end/tool/_fasta/log_collector.dart
index b9fa0f6..971cbfe 100644
--- a/pkg/front_end/tool/_fasta/log_collector.dart
+++ b/pkg/front_end/tool/_fasta/log_collector.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:convert' show JSON, UTF8;
+import 'dart:convert' show jsonDecode, utf8;
import 'dart:isolate' show RawReceivePort;
@@ -32,10 +32,10 @@
}
collectLog(DateTime time, HttpRequest request) async {
- String json = await request.transform(UTF8.decoder).join();
+ String json = await request.transform(utf8.decoder).join();
var data;
try {
- data = JSON.decode(json);
+ data = jsonDecode(json);
} on FormatException catch (e) {
print(e);
return badRequest(
diff --git a/pkg/front_end/tool/incremental_perf.dart b/pkg/front_end/tool/incremental_perf.dart
index 1d68942..02a4bb7 100644
--- a/pkg/front_end/tool/incremental_perf.dart
+++ b/pkg/front_end/tool/incremental_perf.dart
@@ -71,7 +71,7 @@
var entryUri = _resolveOverlayUri(options.rest[0]);
var editsUri = Uri.base.resolve(options.rest[1]);
var changeSets =
- parse(JSON.decode(new File.fromUri(editsUri).readAsStringSync()));
+ parse(jsonDecode(new File.fromUri(editsUri).readAsStringSync()));
bool verbose = options["verbose"];
bool verboseCompilation = options["verbose-compilation"];
bool strongMode = options["mode"] == "strong";
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index de480d6..6d4c937 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -642,7 +642,7 @@
}
writeOffset(node.fileOffset);
writeByte(node.flags);
- writeNodeList(node.annotations);
+ writeAnnotationList(node.annotations);
writeLibraryReference(node.targetLibrary);
writeStringReference(node.name ?? '');
writeNodeList(node.combinators);
@@ -665,7 +665,7 @@
if (_metadataSubsections != null) {
_recordNodeOffsetForMetadataMapping(node);
}
- writeNodeList(node.annotations);
+ writeAnnotationList(node.annotations);
writeStringReference(node.partUri);
}
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index 05f7f6f..c781398 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -37,7 +37,7 @@
]
};
- final LibraryIndex _index;
+ final LibraryIndex index;
Library _coreLibrary;
Class _objectClass;
@@ -98,309 +98,308 @@
Library _mirrorsLibrary;
CoreTypes(Component component)
- : _index = new LibraryIndex.coreLibraries(component);
+ : index = new LibraryIndex.coreLibraries(component);
Procedure get asyncErrorWrapperHelperProcedure {
return _asyncErrorWrapperHelperProcedure ??=
- _index.getTopLevelMember('dart:async', '_asyncErrorWrapperHelper');
+ index.getTopLevelMember('dart:async', '_asyncErrorWrapperHelper');
}
Library get asyncLibrary {
- return _asyncLibrary ??= _index.getLibrary('dart:async');
+ return _asyncLibrary ??= index.getLibrary('dart:async');
}
Member get asyncStarStreamControllerAdd {
- return _index.getMember('dart:async', '_AsyncStarStreamController', 'add');
+ return index.getMember('dart:async', '_AsyncStarStreamController', 'add');
}
Member get asyncStarStreamControllerAddError {
- return _index.getMember(
+ return index.getMember(
'dart:async', '_AsyncStarStreamController', 'addError');
}
Member get asyncStarStreamControllerAddStream {
- return _index.getMember(
+ return index.getMember(
'dart:async', '_AsyncStarStreamController', 'addStream');
}
Class get asyncStarStreamControllerClass {
- return _index.getClass('dart:async', '_AsyncStarStreamController');
+ return index.getClass('dart:async', '_AsyncStarStreamController');
}
Member get asyncStarStreamControllerClose {
- return _index.getMember(
- 'dart:async', '_AsyncStarStreamController', 'close');
+ return index.getMember('dart:async', '_AsyncStarStreamController', 'close');
}
Constructor get asyncStarStreamControllerDefaultConstructor {
return _asyncStarStreamControllerDefaultConstructor ??=
- _index.getMember('dart:async', '_AsyncStarStreamController', '');
+ index.getMember('dart:async', '_AsyncStarStreamController', '');
}
Member get asyncStarStreamControllerStream {
- return _index.getMember(
+ return index.getMember(
'dart:async', '_AsyncStarStreamController', 'get:stream');
}
Procedure get asyncStackTraceHelperProcedure {
return _asyncStackTraceHelperProcedure ??=
- _index.getTopLevelMember('dart:async', '_asyncStackTraceHelper');
+ index.getTopLevelMember('dart:async', '_asyncStackTraceHelper');
}
Procedure get asyncThenWrapperHelperProcedure {
return _asyncThenWrapperHelperProcedure ??=
- _index.getTopLevelMember('dart:async', '_asyncThenWrapperHelper');
+ index.getTopLevelMember('dart:async', '_asyncThenWrapperHelper');
}
Procedure get awaitHelperProcedure {
return _awaitHelperProcedure ??=
- _index.getTopLevelMember('dart:async', '_awaitHelper');
+ index.getTopLevelMember('dart:async', '_awaitHelper');
}
Class get boolClass {
- return _boolClass ??= _index.getClass('dart:core', 'bool');
+ return _boolClass ??= index.getClass('dart:core', 'bool');
}
Class get completerClass {
- return _completerClass ??= _index.getClass('dart:async', 'Completer');
+ return _completerClass ??= index.getClass('dart:async', 'Completer');
}
Class get asyncAwaitCompleterClass {
return _asyncAwaitCompleterClass ??=
- _index.getClass('dart:async', '_AsyncAwaitCompleter');
+ index.getClass('dart:async', '_AsyncAwaitCompleter');
}
Procedure get completerSyncConstructor {
return _completerSyncConstructor ??=
- _index.getMember('dart:async', 'Completer', 'sync');
+ index.getMember('dart:async', 'Completer', 'sync');
}
Constructor get asyncAwaitCompleterConstructor {
return _asyncAwaitCompleterConstructor ??=
- _index.getMember('dart:async', '_AsyncAwaitCompleter', '');
+ index.getMember('dart:async', '_AsyncAwaitCompleter', '');
}
Procedure get completerComplete {
return _completerComplete ??=
- _index.getMember('dart:async', 'Completer', 'complete');
+ index.getMember('dart:async', 'Completer', 'complete');
}
Procedure get completerCompleteError {
return _completerCompleteError ??=
- _index.getMember('dart:async', 'Completer', 'completeError');
+ index.getMember('dart:async', 'Completer', 'completeError');
}
Member get completerFuture {
- return _index.getMember('dart:async', 'Completer', 'get:future');
+ return index.getMember('dart:async', 'Completer', 'get:future');
}
Library get coreLibrary {
- return _coreLibrary ??= _index.getLibrary('dart:core');
+ return _coreLibrary ??= index.getLibrary('dart:core');
}
Class get doubleClass {
- return _doubleClass ??= _index.getClass('dart:core', 'double');
+ return _doubleClass ??= index.getClass('dart:core', 'double');
}
Constructor get externalNameDefaultConstructor {
return _externalNameDefaultConstructor ??=
- _index.getMember('dart:_internal', 'ExternalName', '');
+ index.getMember('dart:_internal', 'ExternalName', '');
}
Class get functionClass {
- return _functionClass ??= _index.getClass('dart:core', 'Function');
+ return _functionClass ??= index.getClass('dart:core', 'Function');
}
Class get futureClass {
- return _futureClass ??= _index.getClass('dart:async', 'Future');
+ return _futureClass ??= index.getClass('dart:async', 'Future');
}
Procedure get futureMicrotaskConstructor {
return _futureMicrotaskConstructor ??=
- _index.getMember('dart:async', 'Future', 'microtask');
+ index.getMember('dart:async', 'Future', 'microtask');
}
Class get futureOrClass {
- return _futureOrClass ??= _index.getClass('dart:async', 'FutureOr');
+ return _futureOrClass ??= index.getClass('dart:async', 'FutureOr');
}
Procedure get identicalProcedure {
return _identicalProcedure ??=
- _index.getTopLevelMember('dart:core', 'identical');
+ index.getTopLevelMember('dart:core', 'identical');
}
Class get intClass {
- return _intClass ??= _index.getClass('dart:core', 'int');
+ return _intClass ??= index.getClass('dart:core', 'int');
}
Class get internalSymbolClass {
- return _internalSymbolClass ??= _index.getClass('dart:_internal', 'Symbol');
+ return _internalSymbolClass ??= index.getClass('dart:_internal', 'Symbol');
}
Class get invocationClass {
- return _invocationClass ??= _index.getClass('dart:core', 'Invocation');
+ return _invocationClass ??= index.getClass('dart:core', 'Invocation');
}
Class get invocationMirrorClass {
return _invocationMirrorClass ??=
- _index.getClass('dart:core', '_InvocationMirror');
+ index.getClass('dart:core', '_InvocationMirror');
}
Constructor get invocationMirrorWithTypeConstructor {
return _invocationMirrorWithTypeConstructor ??=
- _index.getMember('dart:core', '_InvocationMirror', '_withType');
+ index.getMember('dart:core', '_InvocationMirror', '_withType');
}
Constructor get invocationMirrorWithoutTypeConstructor {
return _invocationMirrorWithoutTypeConstructor ??=
- _index.getMember('dart:core', '_InvocationMirror', '_withoutType');
+ index.getMember('dart:core', '_InvocationMirror', '_withoutType');
}
Class get iterableClass {
- return _iterableClass ??= _index.getClass('dart:core', 'Iterable');
+ return _iterableClass ??= index.getClass('dart:core', 'Iterable');
}
Class get iteratorClass {
- return _iteratorClass ??= _index.getClass('dart:core', 'Iterator');
+ return _iteratorClass ??= index.getClass('dart:core', 'Iterator');
}
Class get listClass {
- return _listClass ??= _index.getClass('dart:core', 'List');
+ return _listClass ??= index.getClass('dart:core', 'List');
}
Procedure get listFromConstructor {
return _listFromConstructor ??=
- _index.getMember('dart:core', 'List', 'from');
+ index.getMember('dart:core', 'List', 'from');
}
Class get mapClass {
- return _mapClass ??= _index.getClass('dart:core', 'Map');
+ return _mapClass ??= index.getClass('dart:core', 'Map');
}
Procedure get mapUnmodifiable {
return _mapUnmodifiable ??=
- _index.getMember('dart:core', 'Map', 'unmodifiable');
+ index.getMember('dart:core', 'Map', 'unmodifiable');
}
Library get mirrorsLibrary {
- return _mirrorsLibrary ??= _index.tryGetLibrary('dart:mirrors');
+ return _mirrorsLibrary ??= index.tryGetLibrary('dart:mirrors');
}
Class get noSuchMethodErrorClass {
return _noSuchMethodErrorClass ??=
- _index.getClass('dart:core', 'NoSuchMethodError');
+ index.getClass('dart:core', 'NoSuchMethodError');
}
Constructor get noSuchMethodErrorDefaultConstructor {
return _noSuchMethodErrorDefaultConstructor ??=
// TODO(regis): Replace 'withInvocation' with '' after dart2js is fixed.
- _index.getMember('dart:core', 'NoSuchMethodError', 'withInvocation');
+ index.getMember('dart:core', 'NoSuchMethodError', 'withInvocation');
}
Class get nullClass {
- return _nullClass ??= _index.getClass('dart:core', 'Null');
+ return _nullClass ??= index.getClass('dart:core', 'Null');
}
Class get numClass {
- return _numClass ??= _index.getClass('dart:core', 'num');
+ return _numClass ??= index.getClass('dart:core', 'num');
}
Class get objectClass {
- return _objectClass ??= _index.getClass('dart:core', 'Object');
+ return _objectClass ??= index.getClass('dart:core', 'Object');
}
Procedure get objectEquals {
- return _objectEquals ??= _index.getMember('dart:core', 'Object', '==');
+ return _objectEquals ??= index.getMember('dart:core', 'Object', '==');
}
Procedure get printProcedure {
- return _printProcedure ??= _index.getTopLevelMember('dart:core', 'print');
+ return _printProcedure ??= index.getTopLevelMember('dart:core', 'print');
}
Class get stackTraceClass {
- return _stackTraceClass ??= _index.getClass('dart:core', 'StackTrace');
+ return _stackTraceClass ??= index.getClass('dart:core', 'StackTrace');
}
Class get streamClass {
- return _streamClass ??= _index.getClass('dart:async', 'Stream');
+ return _streamClass ??= index.getClass('dart:async', 'Stream');
}
Member get streamIteratorSubscription {
- return _index.getMember('dart:async', '_StreamIterator', '_subscription');
+ return index.getMember('dart:async', '_StreamIterator', '_subscription');
}
Member get streamIteratorCancel {
- return _index.getMember('dart:async', '_StreamIterator', 'cancel');
+ return index.getMember('dart:async', '_StreamIterator', 'cancel');
}
Class get streamIteratorClass {
- return _index.getClass('dart:async', '_StreamIterator');
+ return index.getClass('dart:async', '_StreamIterator');
}
Constructor get streamIteratorDefaultConstructor {
return _streamIteratorDefaultConstructor ??=
- _index.getMember('dart:async', '_StreamIterator', '');
+ index.getMember('dart:async', '_StreamIterator', '');
}
Member get streamIteratorMoveNext {
- return _index.getMember('dart:async', '_StreamIterator', 'moveNext');
+ return index.getMember('dart:async', '_StreamIterator', 'moveNext');
}
Member get streamIteratorCurrent {
- return _index.getMember('dart:async', '_StreamIterator', 'get:current');
+ return index.getMember('dart:async', '_StreamIterator', 'get:current');
}
Class get stringClass {
- return _stringClass ??= _index.getClass('dart:core', 'String');
+ return _stringClass ??= index.getClass('dart:core', 'String');
}
Class get symbolClass {
- return _symbolClass ??= _index.getClass('dart:core', 'Symbol');
+ return _symbolClass ??= index.getClass('dart:core', 'Symbol');
}
Constructor get syncIterableDefaultConstructor {
return _syncIterableDefaultConstructor ??=
- _index.getMember('dart:core', '_SyncIterable', '');
+ index.getMember('dart:core', '_SyncIterable', '');
}
Class get syncIteratorClass {
- return _index.getClass('dart:core', '_SyncIterator');
+ return index.getClass('dart:core', '_SyncIterator');
}
Member get syncIteratorCurrent {
- return _index.getMember('dart:core', '_SyncIterator', '_current');
+ return index.getMember('dart:core', '_SyncIterator', '_current');
}
Member get syncIteratorYieldEachIterable {
- return _index.getMember('dart:core', '_SyncIterator', '_yieldEachIterable');
+ return index.getMember('dart:core', '_SyncIterator', '_yieldEachIterable');
}
Class get typeClass {
- return _typeClass ??= _index.getClass('dart:core', 'Type');
+ return _typeClass ??= index.getClass('dart:core', 'Type');
}
Constructor get constantExpressionErrorDefaultConstructor {
return _constantExpressionErrorDefaultConstructor ??=
- _index.getMember('dart:core', '_ConstantExpressionError', '');
+ index.getMember('dart:core', '_ConstantExpressionError', '');
}
Member get constantExpressionErrorThrow {
return _constantExpressionErrorThrow ??=
- _index.getMember('dart:core', '_ConstantExpressionError', '_throw');
+ index.getMember('dart:core', '_ConstantExpressionError', '_throw');
}
Constructor get duplicatedFieldInitializerErrorDefaultConstructor {
return _duplicatedFieldInitializerErrorDefaultConstructor ??=
- _index.getMember('dart:core', '_DuplicatedFieldInitializerError', '');
+ index.getMember('dart:core', '_DuplicatedFieldInitializerError', '');
}
Constructor get fallThroughErrorUrlAndLineConstructor {
return _fallThroughErrorUrlAndLineConstructor ??=
- _index.getMember('dart:core', 'FallThroughError', '_create');
+ index.getMember('dart:core', 'FallThroughError', '_create');
}
Constructor get compileTimeErrorDefaultConstructor {
return _compileTimeErrorDefaultConstructor ??=
- _index.getMember('dart:core', '_CompileTimeError', '');
+ index.getMember('dart:core', '_CompileTimeError', '');
}
}
diff --git a/pkg/status_file/test/data/co19-dart2js.status b/pkg/status_file/test/data/co19-dart2js.status
index 438316b..26e58ff 100644
--- a/pkg/status_file/test/data/co19-dart2js.status
+++ b/pkg/status_file/test/data/co19-dart2js.status
@@ -1367,6 +1367,7 @@
LayoutTests/fast/table/min-width-html-inline-table_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/table/nested-tables-with-div-offset_t01: RuntimeError # Please triage this failure
LayoutTests/fast/table/padding-height-and-override-height_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/resize-table-cell_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows-except-overlapped_t01: RuntimeError # Please triage this failure
LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows_t01: RuntimeError # Please triage this failure
LayoutTests/fast/table/table-cell-offset-width_t01: RuntimeError # Please triage this failure
diff --git a/pkg/telemetry/test/crash_reporting_test.dart b/pkg/telemetry/test/crash_reporting_test.dart
index c4e812d..a61e1b4 100644
--- a/pkg/telemetry/test/crash_reporting_test.dart
+++ b/pkg/telemetry/test/crash_reporting_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
import 'package:http/http.dart';
import 'package:http/testing.dart';
@@ -31,7 +31,7 @@
await sender.sendReport('test-error', stackTrace: StackTrace.current);
- String body = UTF8.decode(request.bodyBytes);
+ String body = utf8.decode(request.bodyBytes);
expect(body, contains('String')); // error.runtimeType
expect(body, contains(analytics.trackingId));
expect(body, contains('1.0.0'));
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 84a8c4f..026a99e 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -14,7 +14,7 @@
import 'package:front_end/src/api_prototype/compilation_message.dart'
show CompilationMessage, Severity;
import 'package:front_end/src/fasta/severity.dart' show Severity;
-import 'package:kernel/ast.dart' show Component;
+import 'package:kernel/ast.dart' show Component, StaticGet, Field;
import 'package:kernel/core_types.dart' show CoreTypes;
import 'transformations/devirtualization.dart' as devirtualization
@@ -59,6 +59,8 @@
if (strongMode) {
final coreTypes = new CoreTypes(component);
+ _patchVmConstants(coreTypes);
+
// TODO(alexmarkov, dmitryas): Consider doing canonicalization of identical
// mixin applications when creating mixin applications in frontend,
// so all backends (and all transformation passes from the very beginning)
@@ -77,6 +79,21 @@
}
}
+void _patchVmConstants(CoreTypes coreTypes) {
+ // Fix Endian.host to be a const field equal to Endial.little instead of
+ // a final field. VM does not support big-endian architectures at the
+ // moment.
+ // Can't use normal patching process for this because CFE does not
+ // support patching fields.
+ // See http://dartbug.com/32836 for the background.
+ final Field host =
+ coreTypes.index.getMember('dart:typed_data', 'Endian', 'host');
+ host.isConst = true;
+ host.initializer = new StaticGet(
+ coreTypes.index.getMember('dart:typed_data', 'Endian', 'little'))
+ ..parent = host;
+}
+
class ErrorDetector {
final ErrorHandler previousErrorHandler;
bool hasCompilationErrors = false;
diff --git a/runtime/bin/eventhandler_fuchsia.cc b/runtime/bin/eventhandler_fuchsia.cc
index de52abf..4d0804b 100644
--- a/runtime/bin/eventhandler_fuchsia.cc
+++ b/runtime/bin/eventhandler_fuchsia.cc
@@ -340,7 +340,7 @@
msg->id = id;
msg->dart_port = dart_port;
msg->data = data;
- zx_status_t status = zx_port_queue(port_handle_, &pkt, 0);
+ zx_status_t status = zx_port_queue(port_handle_, &pkt, 1);
if (status != ZX_OK) {
// This is a FATAL because the VM won't work at all if we can't send any
// messages to the EventHandler thread.
@@ -511,7 +511,7 @@
millis == kInfinityTimeout
? ZX_TIME_INFINITE
: zx_deadline_after(ZX_MSEC(millis)),
- &pkt, 0);
+ &pkt, 1);
if (status == ZX_ERR_TIMED_OUT) {
handler_impl->HandleTimeout();
} else if (status != ZX_OK) {
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 145e48b..0d475e9 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -1345,8 +1345,8 @@
ASSERT(Dart_IsServiceIsolate(isolate));
// Load embedder specific bits and return. Will not start http server.
if (!VmService::Setup("127.0.0.1", -1, false /* running_precompiled */,
- false /* server dev mode */,
- false /* trace_loading */)) {
+ false /* server dev mode */, false /* trace_loading */,
+ true /* deterministic */)) {
*error = strdup(VmService::GetErrorMessage());
return NULL;
}
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 4e330cf..d8bbc6f 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -473,7 +473,7 @@
if (!VmService::Setup(Options::vm_service_server_ip(),
Options::vm_service_server_port(), skip_library_load,
Options::vm_service_dev_mode(),
- Options::trace_loading())) {
+ Options::trace_loading(), Options::deterministic())) {
*error = strdup(VmService::GetErrorMessage());
return NULL;
}
@@ -801,6 +801,7 @@
{"dart:_builtin", "::", "_loadPort"},
{"dart:_internal", "::", "_printClosure"},
{"dart:vmservice_io", "::", "_autoStart"},
+ {"dart:vmservice_io", "::", "_deterministic"},
{"dart:vmservice_io", "::", "_ip"},
{"dart:vmservice_io", "::", "_isFuchsia"},
{"dart:vmservice_io", "::", "_isWindows"},
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index a002959..df3ec97 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -396,6 +396,11 @@
}
}
+ if (Options::deterministic()) {
+ // Both an embedder and VM flag.
+ vm_options->AddArgument("--deterministic");
+ }
+
Socket::set_short_socket_read(Options::short_socket_read());
Socket::set_short_socket_write(Options::short_socket_write());
#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index 793d3d8..80a4579 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -35,6 +35,7 @@
V(compile_all, compile_all) \
V(parse_all, parse_all) \
V(disable_service_origin_check, vm_service_dev_mode) \
+ V(deterministic, deterministic) \
V(use_blobs, use_blobs) \
V(obfuscate, obfuscate) \
V(trace_loading, trace_loading) \
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc
index 30fb896..43f01ca 100644
--- a/runtime/bin/process_fuchsia.cc
+++ b/runtime/bin/process_fuchsia.cc
@@ -205,7 +205,7 @@
static void SendShutdownMessage() {
zx_port_packet_t pkt;
pkt.key = kShutdownPacketKey;
- zx_status_t status = zx_port_queue(port_, &pkt, 0);
+ zx_status_t status = zx_port_queue(port_, &pkt, 1);
if (status != ZX_OK) {
Log::PrintErr("ExitCodeHandler: zx_port_queue failed: %s\n",
zx_status_get_string(status));
@@ -219,7 +219,7 @@
zx_port_packet_t pkt;
while (true) {
- zx_status_t status = zx_port_wait(port_, ZX_TIME_INFINITE, &pkt, 0);
+ zx_status_t status = zx_port_wait(port_, ZX_TIME_INFINITE, &pkt, 1);
if (status != ZX_OK) {
FATAL1("ExitCodeHandler: zx_port_wait failed: %s\n",
zx_status_get_string(status));
@@ -397,7 +397,7 @@
}
while ((out_tmp != NULL) || (err_tmp != NULL) || (exit_tmp != NULL)) {
zx_port_packet_t pkt;
- status = zx_port_wait(port, ZX_TIME_INFINITE, &pkt, 0);
+ status = zx_port_wait(port, ZX_TIME_INFINITE, &pkt, 1);
if (status != ZX_OK) {
Log::PrintErr("Process::Wait: zx_port_wait failed: %s\n",
zx_status_get_string(status));
diff --git a/runtime/bin/vmservice/loader.dart b/runtime/bin/vmservice/loader.dart
index 20bd3fd..81d9529 100644
--- a/runtime/bin/vmservice/loader.dart
+++ b/runtime/bin/vmservice/loader.dart
@@ -63,6 +63,7 @@
}
bool _traceLoading = false;
+bool _deterministic = false;
// State associated with the isolate that is used for loading.
class IsolateLoaderState extends IsolateEmbedderData {
@@ -137,7 +138,7 @@
// We issue only 16 concurrent calls to File.readAsBytes() to stay within
// platform-specific resource limits (e.g. max open files). The rest go on
// _fileRequestQueue and are processed when we can safely issue them.
- static const int _maxFileRequests = 16;
+ static final int _maxFileRequests = _deterministic ? 1 : 16;
int currentFileRequests = 0;
final List<FileRequest> _fileRequestQueue = new List<FileRequest>();
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 82cf820..621b3f5 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -174,7 +174,8 @@
intptr_t server_port,
bool running_precompiled,
bool dev_mode_server,
- bool trace_loading) {
+ bool trace_loading,
+ bool deterministic) {
Dart_Isolate isolate = Dart_CurrentIsolate();
ASSERT(isolate != NULL);
SetServerAddress("");
@@ -267,6 +268,12 @@
SHUTDOWN_ON_ERROR(result);
}
+ if (deterministic) {
+ result = Dart_SetField(library, DartUtils::NewString("_deterministic"),
+ Dart_True());
+ SHUTDOWN_ON_ERROR(result);
+ }
+
// Get _getWatchSignalInternal from dart:io.
Dart_Handle dart_io_str = Dart_NewStringFromCString(DartUtils::kIOLibURL);
SHUTDOWN_ON_ERROR(dart_io_str);
diff --git a/runtime/bin/vmservice_impl.h b/runtime/bin/vmservice_impl.h
index e9baab4..2dc00d0 100644
--- a/runtime/bin/vmservice_impl.h
+++ b/runtime/bin/vmservice_impl.h
@@ -20,7 +20,8 @@
intptr_t server_port,
bool running_precompiled,
bool dev_mode_server,
- bool trace_loading);
+ bool trace_loading,
+ bool deterministic);
// Error message if startup failed.
static const char* GetErrorMessage();
diff --git a/runtime/lib/bigint_patch.dart b/runtime/lib/bigint_patch.dart
index 5fc7a32..7516712 100644
--- a/runtime/lib/bigint_patch.dart
+++ b/runtime/lib/bigint_patch.dart
@@ -2307,7 +2307,7 @@
var resultBits = new Uint8List(8);
var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
- if (length - 53 > maxDoubleExponent) return double.INFINITY;
+ if (length - 53 > maxDoubleExponent) return double.infinity;
// The most significant bit is for the sign.
if (_isNegative) resultBits[7] = 0x80;
diff --git a/runtime/lib/typed_data_patch.dart b/runtime/lib/typed_data_patch.dart
index 7e4e9cf..83a4f54 100644
--- a/runtime/lib/typed_data_patch.dart
+++ b/runtime/lib/typed_data_patch.dart
@@ -4216,7 +4216,7 @@
_typedData._setUint8(_offset + byteOffset, value);
}
- int getInt16(int byteOffset, [Endianness endian = Endian.big]) {
+ int getInt16(int byteOffset, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 1 >= length) {
throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
}
@@ -4227,7 +4227,7 @@
return _byteSwap16(result).toSigned(16);
}
- void setInt16(int byteOffset, int value, [Endianness endian = Endian.big]) {
+ void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 1 >= length) {
throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
}
@@ -4235,7 +4235,7 @@
identical(endian, Endian.host) ? value : _byteSwap16(value));
}
- int getUint16(int byteOffset, [Endianness endian = Endian.big]) {
+ int getUint16(int byteOffset, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 1 >= length) {
throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
}
@@ -4246,7 +4246,7 @@
return _byteSwap16(result);
}
- void setUint16(int byteOffset, int value, [Endianness endian = Endian.big]) {
+ void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 1 >= length) {
throw new RangeError.range(byteOffset, 0, length - 2, "byteOffset");
}
@@ -4254,7 +4254,7 @@
identical(endian, Endian.host) ? value : _byteSwap16(value));
}
- int getInt32(int byteOffset, [Endianness endian = Endian.big]) {
+ int getInt32(int byteOffset, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 3 >= length) {
throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
}
@@ -4265,7 +4265,7 @@
return _byteSwap32(result).toSigned(32);
}
- void setInt32(int byteOffset, int value, [Endianness endian = Endian.big]) {
+ void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 3 >= length) {
throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
}
@@ -4273,7 +4273,7 @@
identical(endian, Endian.host) ? value : _byteSwap32(value));
}
- int getUint32(int byteOffset, [Endianness endian = Endian.big]) {
+ int getUint32(int byteOffset, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 3 >= length) {
throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
}
@@ -4284,7 +4284,7 @@
return _byteSwap32(result);
}
- void setUint32(int byteOffset, int value, [Endianness endian = Endian.big]) {
+ void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 3 >= length) {
throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
}
@@ -4292,7 +4292,7 @@
identical(endian, Endian.host) ? value : _byteSwap32(value));
}
- int getInt64(int byteOffset, [Endianness endian = Endian.big]) {
+ int getInt64(int byteOffset, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 7 >= length) {
throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
}
@@ -4303,7 +4303,7 @@
return _byteSwap64(result).toSigned(64);
}
- void setInt64(int byteOffset, int value, [Endianness endian = Endian.big]) {
+ void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 7 >= length) {
throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
}
@@ -4311,7 +4311,7 @@
identical(endian, Endian.host) ? value : _byteSwap64(value));
}
- int getUint64(int byteOffset, [Endianness endian = Endian.big]) {
+ int getUint64(int byteOffset, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 7 >= length) {
throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
}
@@ -4322,7 +4322,7 @@
return _byteSwap64(result);
}
- void setUint64(int byteOffset, int value, [Endianness endian = Endian.big]) {
+ void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 7 >= length) {
throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
}
@@ -4330,7 +4330,7 @@
identical(endian, Endian.host) ? value : _byteSwap64(value));
}
- double getFloat32(int byteOffset, [Endianness endian = Endian.big]) {
+ double getFloat32(int byteOffset, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 3 >= length) {
throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
}
@@ -4341,8 +4341,7 @@
return _convF32[0];
}
- void setFloat32(int byteOffset, double value,
- [Endianness endian = Endian.big]) {
+ void setFloat32(int byteOffset, double value, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 3 >= length) {
throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
}
@@ -4354,7 +4353,7 @@
_typedData._setUint32(_offset + byteOffset, _byteSwap32(_convU32[0]));
}
- double getFloat64(int byteOffset, [Endianness endian = Endian.big]) {
+ double getFloat64(int byteOffset, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 7 >= length) {
throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
}
@@ -4365,8 +4364,7 @@
return _convF64[0];
}
- void setFloat64(int byteOffset, double value,
- [Endianness endian = Endian.big]) {
+ void setFloat64(int byteOffset, double value, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 7 >= length) {
throw new RangeError.range(byteOffset, 0, length - 8, "byteOffset");
}
@@ -4378,7 +4376,7 @@
_typedData._setUint64(_offset + byteOffset, _byteSwap64(_convU64[0]));
}
- Float32x4 getFloat32x4(int byteOffset, [Endianness endian = Endian.big]) {
+ Float32x4 getFloat32x4(int byteOffset, [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 3 >= length) {
throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
}
@@ -4387,7 +4385,7 @@
}
void setFloat32x4(int byteOffset, Float32x4 value,
- [Endianness endian = Endian.big]) {
+ [Endian endian = Endian.big]) {
if (byteOffset < 0 || byteOffset + 3 >= length) {
throw new RangeError.range(byteOffset, 0, length - 4, "byteOffset");
}
diff --git a/runtime/observatory/lib/service_common.dart b/runtime/observatory/lib/service_common.dart
index 892ebee..d023f6e 100644
--- a/runtime/observatory/lib/service_common.dart
+++ b/runtime/observatory/lib/service_common.dart
@@ -183,7 +183,7 @@
Map _parseJSON(String message) {
var map;
try {
- map = JSON.decode(message);
+ map = json.decode(message);
} catch (e, st) {
Logger.root.severe('Disconnecting: Error decoding message: $e\n$st');
disconnect(reason: 'Connection saw corrupt JSON message: $e');
@@ -202,8 +202,8 @@
// See format spec. in VMs Service::SendEvent.
int offset = 0;
// Dart2JS workaround (no getUint64). Limit to 4 GB metadata.
- assert(bytes.getUint32(offset, Endianness.BIG_ENDIAN) == 0);
- int metaSize = bytes.getUint32(offset + 4, Endianness.BIG_ENDIAN);
+ assert(bytes.getUint32(offset, Endian.big) == 0);
+ int metaSize = bytes.getUint32(offset + 4, Endian.big);
offset += 8;
var meta = _utf8Decoder.convert(new Uint8List.view(
bytes.buffer, bytes.offsetInBytes + offset, metaSize));
@@ -315,13 +315,13 @@
var message;
// Encode message.
if (target.chrome) {
- message = JSON.encode({
+ message = json.encode({
'id': int.parse(serial),
'method': 'Dart.observatoryQuery',
'params': {'id': serial, 'query': request.method}
});
} else {
- message = JSON.encode(
+ message = json.encode(
{'id': serial, 'method': request.method, 'params': request.params});
}
if (request.method != 'getTagProfile' &&
diff --git a/runtime/observatory/lib/src/app/settings.dart b/runtime/observatory/lib/src/app/settings.dart
index 32339d0..da6d8a8 100644
--- a/runtime/observatory/lib/src/app/settings.dart
+++ b/runtime/observatory/lib/src/app/settings.dart
@@ -10,7 +10,7 @@
/// Associated [value] with [key]. [value] must be JSON encodable.
static void set(String key, dynamic value) {
- _storage[key] = JSON.encode(value);
+ _storage[key] = json.encode(value);
}
/// Get value associated with [key]. Return value will be a JSON encodable
@@ -20,7 +20,7 @@
if (value == null) {
return null;
}
- return JSON.decode(value);
+ return json.decode(value);
}
}
diff --git a/runtime/observatory/lib/src/elements/timeline/dashboard.dart b/runtime/observatory/lib/src/elements/timeline/dashboard.dart
index 3217f0e..bfa7f57 100644
--- a/runtime/observatory/lib/src/elements/timeline/dashboard.dart
+++ b/runtime/observatory/lib/src/elements/timeline/dashboard.dart
@@ -223,7 +223,7 @@
[Map<String, dynamic> params = const <String, dynamic>{}]) async {
var message = {'method': method, 'params': params};
_frame.contentWindow
- .postMessage(JSON.encode(message), window.location.href);
+ .postMessage(json.encode(message), window.location.href);
return null;
}
}
diff --git a/runtime/observatory/lib/src/elements/timeline_page.dart b/runtime/observatory/lib/src/elements/timeline_page.dart
index 8e63126..a751329 100644
--- a/runtime/observatory/lib/src/elements/timeline_page.dart
+++ b/runtime/observatory/lib/src/elements/timeline_page.dart
@@ -204,7 +204,7 @@
[Map<String, dynamic> params = const <String, dynamic>{}]) async {
var message = {'method': method, 'params': params};
_frame.contentWindow
- .postMessage(JSON.encode(message), window.location.href);
+ .postMessage(json.encode(message), window.location.href);
return null;
}
diff --git a/runtime/observatory/lib/src/elements/vm_connect.dart b/runtime/observatory/lib/src/elements/vm_connect.dart
index cdf5fd7..30dd852 100644
--- a/runtime/observatory/lib/src/elements/vm_connect.dart
+++ b/runtime/observatory/lib/src/elements/vm_connect.dart
@@ -165,7 +165,7 @@
var reader = new FileReader();
reader.readAsText(e.files[0]);
reader.onLoad.listen((_) {
- var crashDump = JSON.decode(reader.result);
+ var crashDump = json.decode(reader.result);
_loadDump(crashDump);
});
});
diff --git a/runtime/observatory/lib/src/repositories/settings.dart b/runtime/observatory/lib/src/repositories/settings.dart
index 4121d93..5cfffc0 100644
--- a/runtime/observatory/lib/src/repositories/settings.dart
+++ b/runtime/observatory/lib/src/repositories/settings.dart
@@ -10,7 +10,7 @@
/// Associated [value] with [key]. [value] must be JSON encodable.
static void set(String key, dynamic value) {
- _storage[key] = JSON.encode(value);
+ _storage[key] = json.encode(value);
}
/// Get value associated with [key]. Return value will be a JSON encodable
@@ -20,7 +20,7 @@
if (value == null) {
return null;
}
- return JSON.decode(value);
+ return json.decode(value);
}
}
diff --git a/runtime/observatory/lib/src/sample_profile/sample_profile.dart b/runtime/observatory/lib/src/sample_profile/sample_profile.dart
index a116563..569d4e3 100644
--- a/runtime/observatory/lib/src/sample_profile/sample_profile.dart
+++ b/runtime/observatory/lib/src/sample_profile/sample_profile.dart
@@ -862,7 +862,7 @@
sampleCount = profile['sampleCount'];
samplePeriod = profile['samplePeriod'];
- sampleRate = (Duration.MICROSECONDS_PER_SECOND / samplePeriod);
+ sampleRate = (Duration.microsecondsPerSecond / samplePeriod);
stackDepth = profile['stackDepth'];
timeSpan = profile['timeSpan'];
@@ -1084,10 +1084,10 @@
}
int approximateMillisecondsForCount(count) {
- return (count * samplePeriod) ~/ Duration.MICROSECONDS_PER_MILLISECOND;
+ return (count * samplePeriod) ~/ Duration.microsecondsPerMillisecond;
}
double approximateSecondsForCount(count) {
- return (count * samplePeriod) / Duration.MICROSECONDS_PER_SECOND;
+ return (count * samplePeriod) / Duration.microsecondsPerSecond;
}
}
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 76e3487..a10cfaa 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1261,19 +1261,19 @@
Duration get avgCollectionTime {
final mcs = totalCollectionTimeInSeconds *
- Duration.MICROSECONDS_PER_SECOND /
+ Duration.microsecondsPerSecond /
math.max(collections, 1);
return new Duration(microseconds: mcs.ceil());
}
Duration get totalCollectionTime {
- final mcs = totalCollectionTimeInSeconds * Duration.MICROSECONDS_PER_SECOND;
+ final mcs = totalCollectionTimeInSeconds * Duration.microsecondsPerSecond;
return new Duration(microseconds: mcs.ceil());
}
Duration get avgCollectionPeriod {
final mcs =
- averageCollectionPeriodInMillis * Duration.MICROSECONDS_PER_MILLISECOND;
+ averageCollectionPeriodInMillis * Duration.microsecondsPerMillisecond;
return new Duration(microseconds: mcs.ceil());
}
@@ -2256,8 +2256,8 @@
exceptions = map['_debuggerSettings']['_exceptions'];
}
if (map['bytes'] != null) {
- var bytes = BASE64.decode(map['bytes']);
- bytesAsString = UTF8.decode(bytes);
+ var bytes = base64Decode(map['bytes']);
+ bytesAsString = utf8.decode(bytes);
}
if (map['logRecord'] != null) {
logRecord = map['logRecord'];
@@ -2922,7 +2922,7 @@
}
;
if (map['bytes'] != null) {
- Uint8List bytes = BASE64.decode(map['bytes']);
+ Uint8List bytes = base64Decode(map['bytes']);
switch (map['kind']) {
case "Uint8ClampedList":
typedElements = bytes.buffer.asUint8ClampedList();
diff --git a/runtime/observatory/lib/utils.dart b/runtime/observatory/lib/utils.dart
index f65c1a1..4957014 100644
--- a/runtime/observatory/lib/utils.dart
+++ b/runtime/observatory/lib/utils.dart
@@ -157,19 +157,19 @@
var value = duration.inMicroseconds.abs();
switch (precision) {
case DurationComponent.Days:
- value = (value / Duration.MICROSECONDS_PER_DAY).round();
+ value = (value / Duration.microsecondsPerDay).round();
break;
case DurationComponent.Hours:
- value = (value / Duration.MICROSECONDS_PER_HOUR).round();
+ value = (value / Duration.microsecondsPerHour).round();
break;
case DurationComponent.Minutes:
- value = (value / Duration.MICROSECONDS_PER_MINUTE).round();
+ value = (value / Duration.microsecondsPerMinute).round();
break;
case DurationComponent.Seconds:
- value = (value / Duration.MICROSECONDS_PER_SECOND).round();
+ value = (value / Duration.microsecondsPerSecond).round();
break;
case DurationComponent.Milliseconds:
- value = (value / Duration.MICROSECONDS_PER_MILLISECOND).round();
+ value = (value / Duration.microsecondsPerMillisecond).round();
break;
case DurationComponent.Microseconds:
break;
@@ -186,24 +186,24 @@
}
switch (precision) {
case DurationComponent.Microseconds:
- components.add('${value % Duration.MICROSECONDS_PER_MILLISECOND}μs');
- value = (value / Duration.MICROSECONDS_PER_MILLISECOND).floor();
+ components.add('${value % Duration.microsecondsPerMillisecond}μs');
+ value = (value / Duration.microsecondsPerMillisecond).floor();
if (value != 0) {
continue Milliseconds;
}
break;
Milliseconds:
case DurationComponent.Milliseconds:
- components.add('${value % Duration.MILLISECONDS_PER_SECOND}ms');
- value = (value / Duration.MILLISECONDS_PER_SECOND).floor();
+ components.add('${value % Duration.millisecondsPerSecond}ms');
+ value = (value / Duration.millisecondsPerSecond).floor();
if (value != 0) {
continue Seconds;
}
break;
Seconds:
case DurationComponent.Seconds:
- components.add('${value % Duration.SECONDS_PER_MINUTE}s');
- value = (value / Duration.SECONDS_PER_MINUTE).floor();
+ components.add('${value % Duration.secondsPerMinute}s');
+ value = (value / Duration.secondsPerMinute).floor();
;
if (value != 0) {
continue Minutes;
@@ -211,16 +211,16 @@
break;
Minutes:
case DurationComponent.Minutes:
- components.add('${value % Duration.MINUTES_PER_HOUR}m');
- value = (value / Duration.MINUTES_PER_HOUR).floor();
+ components.add('${value % Duration.minutesPerHour}m');
+ value = (value / Duration.minutesPerHour).floor();
if (value != 0) {
continue Hours;
}
break;
Hours:
case DurationComponent.Hours:
- components.add('${value % Duration.HOURS_PER_DAY}h');
- value = (value / Duration.HOURS_PER_DAY).floor();
+ components.add('${value % Duration.hoursPerDay}h');
+ value = (value / Duration.hoursPerDay).floor();
if (value != 0) {
continue Days;
}
@@ -241,10 +241,10 @@
}
static String formatDurationInSeconds(Duration x) =>
- formatSeconds(x.inMicroseconds / Duration.MICROSECONDS_PER_SECOND);
+ formatSeconds(x.inMicroseconds / Duration.microsecondsPerSecond);
static String formatDurationInMilliseconds(Duration x) =>
- formatMillis(x.inMicroseconds / Duration.MICROSECONDS_PER_MILLISECOND);
+ formatMillis(x.inMicroseconds / Duration.microsecondsPerMillisecond);
static bool runningInJavaScript() => identical(1.0, 1);
@@ -299,7 +299,7 @@
// Already scheduled.
return;
}
- _timer = new Timer(Duration.ZERO, () {
+ _timer = new Timer(Duration.zero, () {
_timer = null;
callback();
});
diff --git a/runtime/observatory/tests/service/crash_dump_test.dart b/runtime/observatory/tests/service/crash_dump_test.dart
index 4d56ccc..2309c94 100644
--- a/runtime/observatory/tests/service/crash_dump_test.dart
+++ b/runtime/observatory/tests/service/crash_dump_test.dart
@@ -25,11 +25,11 @@
print('Received response');
Completer completer = new Completer<String>();
StringBuffer sb = new StringBuffer();
- response.transform(UTF8.decoder).listen((chunk) {
+ response.transform(utf8.decoder).listen((chunk) {
sb.write(chunk);
}, onDone: () => completer.complete(sb.toString()));
var responseString = await completer.future;
- JSON.decode(responseString);
+ json.decode(responseString);
}
];
diff --git a/runtime/observatory/tests/service/dev_fs_http_put_test.dart b/runtime/observatory/tests/service/dev_fs_http_put_test.dart
index 9d7a45b..4ed4172 100644
--- a/runtime/observatory/tests/service/dev_fs_http_put_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_http_put_test.dart
@@ -13,7 +13,7 @@
Future<String> readResponse(HttpClientResponse response) {
var completer = new Completer<String>();
var contents = new StringBuffer();
- response.transform(UTF8.decoder).listen((String data) {
+ response.transform(utf8.decoder).listen((String data) {
contents.write(data);
}, onDone: () => completer.complete(contents.toString()));
return completer.future;
@@ -25,7 +25,7 @@
var fsId = 'test';
var filePath = '/foo/bar.dat';
var fileContents = [0, 1, 2, 3, 4, 5, 6, 255];
- var fileContentsBase64 = BASE64.encode(fileContents);
+ var fileContentsBase64 = base64Encode(fileContents);
var result;
// Create DevFS.
@@ -43,7 +43,7 @@
request.add(GZIP.encode([9]));
HttpClientResponse response = await request.close();
String responseBody = await readResponse(response);
- result = JSON.decode(responseBody);
+ result = jsonDecode(responseBody);
expect(result['result']['type'], equals('Success'));
// Trigger an error by issuing an HTTP PUT.
@@ -53,7 +53,7 @@
request.write(GZIP.encode(fileContents));
response = await request.close();
responseBody = await readResponse(response);
- result = JSON.decode(responseBody);
+ result = jsonDecode(responseBody);
Map error = result['error']['data'];
expect(error, isNotNull);
expect(error['details'].contains("expects the 'path' parameter"), isTrue);
@@ -66,7 +66,7 @@
request.add(GZIP.encode(fileContents));
response = await request.close();
responseBody = await readResponse(response);
- result = JSON.decode(responseBody);
+ result = jsonDecode(responseBody);
expect(result['result']['type'], equals('Success'));
// Close the HTTP client.
diff --git a/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart b/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
index ea8c92f..ed4c886 100644
--- a/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
@@ -13,7 +13,7 @@
Future<String> readResponse(HttpClientResponse response) {
var completer = new Completer<String>();
var contents = new StringBuffer();
- response.transform(UTF8.decoder).listen((String data) {
+ response.transform(utf8.decoder).listen((String data) {
contents.write(data);
}, onDone: () => completer.complete(contents.toString()));
return completer.future;
@@ -24,9 +24,9 @@
(VM vm) async {
var fsId = 'test';
var filePath = '/foo/b\rar.dart';
- var filePathBase64 = BASE64.encode(UTF8.encode(filePath));
+ var filePathBase64 = base64Encode(utf8.encode(filePath));
var fileContents = [0, 1, 2, 3, 4, 5, 6, 255];
- var fileContentsBase64 = BASE64.encode(fileContents);
+ var fileContentsBase64 = base64Encode(fileContents);
var result;
// Create DevFS.
@@ -44,7 +44,7 @@
request.add(GZIP.encode([9]));
HttpClientResponse response = await request.close();
String responseBody = await readResponse(response);
- result = JSON.decode(responseBody);
+ result = jsonDecode(responseBody);
expect(result['result']['type'], equals('Success'));
// Trigger an error by issuing an HTTP PUT.
@@ -54,7 +54,7 @@
request.write(GZIP.encode(fileContents));
response = await request.close();
responseBody = await readResponse(response);
- result = JSON.decode(responseBody);
+ result = jsonDecode(responseBody);
Map error = result['error']['data'];
expect(error, isNotNull);
expect(error['details'].contains("expects the 'path' parameter"), isTrue);
@@ -67,7 +67,7 @@
request.add(GZIP.encode(fileContents));
response = await request.close();
responseBody = await readResponse(response);
- result = JSON.decode(responseBody);
+ result = jsonDecode(responseBody);
expect(result['result']['type'], equals('Success'));
// Close the HTTP client.
diff --git a/runtime/observatory/tests/service/dev_fs_spawn_test.dart b/runtime/observatory/tests/service/dev_fs_spawn_test.dart
index 1ed42cf..9a741fc 100644
--- a/runtime/observatory/tests/service/dev_fs_spawn_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_spawn_test.dart
@@ -102,7 +102,7 @@
// Write three scripts to the fs.
for (int i = 0; i < 3; i++) {
- var fileContents = BASE64.encode(UTF8.encode(scripts[i]));
+ var fileContents = base64Encode(utf8.encode(scripts[i]));
result = await vm.invokeRpcNoUpgrade('_writeDevFSFile', {
'fsName': fsName,
'path': filePaths[i],
diff --git a/runtime/observatory/tests/service/dev_fs_test.dart b/runtime/observatory/tests/service/dev_fs_test.dart
index 2349977..abe80cc 100644
--- a/runtime/observatory/tests/service/dev_fs_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_test.dart
@@ -56,7 +56,7 @@
(VM vm) async {
var fsId = 'banana';
var filePath = '/foo/bar.dat';
- var fileContents = BASE64.encode(UTF8.encode('fileContents'));
+ var fileContents = base64Encode(utf8.encode('fileContents'));
var result;
// Create DevFS.
@@ -119,8 +119,8 @@
result = await vm.invokeRpcNoUpgrade('_writeDevFSFiles', {
'fsName': fsId,
'files': [
- ['/a', BASE64.encode(UTF8.encode('a_contents'))],
- ['/b', BASE64.encode(UTF8.encode('b_contents'))]
+ ['/a', base64Encode(utf8.encode('a_contents'))],
+ ['/b', base64Encode(utf8.encode('b_contents'))]
]
});
expect(result['type'], equals('Success'));
@@ -132,7 +132,7 @@
});
expect(result['type'], equals('FSFile'));
expect(result['fileContents'],
- equals(BASE64.encode(UTF8.encode('b_contents'))));
+ equals(base64Encode(utf8.encode('b_contents'))));
// List all the files in the file system.
result = await vm.invokeRpcNoUpgrade('_listDevFSFiles', {
diff --git a/runtime/observatory/tests/service/dev_fs_uri_test.dart b/runtime/observatory/tests/service/dev_fs_uri_test.dart
index 201ea14..0b6643a 100644
--- a/runtime/observatory/tests/service/dev_fs_uri_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_uri_test.dart
@@ -13,7 +13,7 @@
Future<String> readResponse(HttpClientResponse response) {
var completer = new Completer<String>();
var contents = new StringBuffer();
- response.transform(UTF8.decoder).listen((String data) {
+ response.transform(utf8.decoder).listen((String data) {
contents.write(data);
}, onDone: () => completer.complete(contents.toString()));
return completer.future;
@@ -26,9 +26,9 @@
// NOTE: When using the URI encoding scheme, paths cannot be absolute.
var filePath = 'foo/bar.dat';
var fileUri = Uri.parse(filePath);
- var fileUriBase64 = BASE64.encode(UTF8.encode(fileUri.toString()));
+ var fileUriBase64 = base64Encode(utf8.encode(fileUri.toString()));
var fileContents = [0, 1, 2, 3, 4, 5, 6, 255];
- var fileContentsBase64 = BASE64.encode(fileContents);
+ var fileContentsBase64 = base64Encode(fileContents);
var filePath2 = 'baz/boo.dat';
var fileUri2 = Uri.parse(filePath2);
@@ -49,7 +49,7 @@
request.add(GZIP.encode([9]));
HttpClientResponse response = await request.close();
String responseBody = await readResponse(response);
- result = JSON.decode(responseBody);
+ result = jsonDecode(responseBody);
print(result);
expect(result['result']['type'], equals('Success'));
@@ -60,7 +60,7 @@
request.write(GZIP.encode(fileContents));
response = await request.close();
responseBody = await readResponse(response);
- result = JSON.decode(responseBody);
+ result = jsonDecode(responseBody);
Map error = result['error']['data'];
expect(error, isNotNull);
expect(error['details'].contains("expects the 'path' parameter"), isTrue);
@@ -73,7 +73,7 @@
request.add(GZIP.encode(fileContents));
response = await request.close();
responseBody = await readResponse(response);
- result = JSON.decode(responseBody);
+ result = jsonDecode(responseBody);
expect(result['result']['type'], equals('Success'));
// Close the HTTP client.
diff --git a/runtime/observatory/tests/service/dev_fs_weird_char_test.dart b/runtime/observatory/tests/service/dev_fs_weird_char_test.dart
index 48c15c3..ce99969 100644
--- a/runtime/observatory/tests/service/dev_fs_weird_char_test.dart
+++ b/runtime/observatory/tests/service/dev_fs_weird_char_test.dart
@@ -13,7 +13,7 @@
(VM vm) async {
var fsId = 'test';
var filePath = '/foo/bar?dat';
- var fileContents = BASE64.encode(UTF8.encode('fileContents'));
+ var fileContents = base64Encode(utf8.encode('fileContents'));
var result;
// Create DevFS.
diff --git a/runtime/observatory/tests/service/developer_extension_test.dart b/runtime/observatory/tests/service/developer_extension_test.dart
index 072378e..f128f93 100644
--- a/runtime/observatory/tests/service/developer_extension_test.dart
+++ b/runtime/observatory/tests/service/developer_extension_test.dart
@@ -19,7 +19,7 @@
case 'ext..delay':
Completer c = new Completer();
new Timer(new Duration(seconds: 1), () {
- c.complete(new ServiceExtensionResponse.result(JSON.encode({
+ c.complete(new ServiceExtensionResponse.result(jsonEncode({
'type': '_delayedType',
'method': method,
'parameters': paremeters,
@@ -35,7 +35,7 @@
throw "I always throw!";
case 'ext..success':
return new Future.value(
- new ServiceExtensionResponse.result(JSON.encode({
+ new ServiceExtensionResponse.result(jsonEncode({
'type': '_extensionType',
'method': method,
'parameters': paremeters,
diff --git a/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart b/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
index a6860b9..c467159 100644
--- a/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_asynchronous_invocation_test.dart
@@ -7,7 +7,7 @@
import 'package:unittest/unittest.dart';
import 'test_helper.dart';
import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
import 'dart:async' show Future, Stream, StreamController;
var tests = <IsolateTest>[
@@ -23,10 +23,10 @@
final socket = new StreamController();
// Avoid to manually encode and decode messages from the stream
- Stream<String> stream = socket.stream.map(JSON.encode);
+ Stream<String> stream = socket.stream.map(jsonEncode);
stream.retype<Object>().pipe(_socket);
dynamic _decoder(dynamic obj) {
- return JSON.decode(obj);
+ return jsonDecode(obj);
}
final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/external_service_disappear_test.dart b/runtime/observatory/tests/service/external_service_disappear_test.dart
index 8199de2..9e9931e 100644
--- a/runtime/observatory/tests/service/external_service_disappear_test.dart
+++ b/runtime/observatory/tests/service/external_service_disappear_test.dart
@@ -7,7 +7,7 @@
import 'package:unittest/unittest.dart';
import 'test_helper.dart';
import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
import 'dart:async' show Future, Stream, StreamController;
var tests = <IsolateTest>[
@@ -23,10 +23,10 @@
final socket = new StreamController();
// Avoid to manually encode and decode messages from the stream
- Stream<String> stream = socket.stream.map(JSON.encode);
+ Stream<String> stream = socket.stream.map(jsonEncode);
stream.retype<Object>().pipe(_socket);
dynamic _decoder(dynamic obj) {
- return JSON.decode(obj);
+ return jsonDecode(obj);
}
final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/external_service_notification_invocation_test.dart b/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
index bba191a..2c064af 100644
--- a/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_notification_invocation_test.dart
@@ -7,7 +7,7 @@
import 'package:unittest/unittest.dart';
import 'test_helper.dart';
import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
import 'dart:async' show Future, Stream, StreamController;
var tests = <IsolateTest>[
@@ -26,13 +26,13 @@
final socket_invoker = new StreamController<Map>();
// Avoid to manually encode and decode messages from the stream
- Stream<String> socket_stream = socket.stream.map(JSON.encode);
+ Stream<String> socket_stream = socket.stream.map(jsonEncode);
socket_stream.retype<Object>().pipe(_socket);
Stream<String> socket_invoker_stream =
- socket_invoker.stream.map(JSON.encode);
+ socket_invoker.stream.map(jsonEncode);
socket_invoker_stream.retype<Object>().pipe(_socket_invoker);
dynamic _decoder(dynamic obj) {
- return JSON.decode(obj);
+ return jsonDecode(obj);
}
final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/external_service_registration_test.dart b/runtime/observatory/tests/service/external_service_registration_test.dart
index c0dab2f..083c6d6 100644
--- a/runtime/observatory/tests/service/external_service_registration_test.dart
+++ b/runtime/observatory/tests/service/external_service_registration_test.dart
@@ -7,7 +7,7 @@
import 'package:unittest/unittest.dart';
import 'test_helper.dart';
import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
import 'dart:async' show Future, Stream, StreamController;
var tests = <IsolateTest>[
@@ -26,10 +26,10 @@
final socket = new StreamController();
// Avoid to manually encode and decode messages from the stream
- Stream<String> socket_stream = socket.stream.map(JSON.encode);
+ Stream<String> socket_stream = socket.stream.map(jsonEncode);
socket_stream.retype<Object>().pipe(_socket);
dynamic _decoder(dynamic obj) {
- return JSON.decode(obj);
+ return jsonDecode(obj);
}
final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart b/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
index 74e258c..11d478e 100644
--- a/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
+++ b/runtime/observatory/tests/service/external_service_registration_via_notification_test.dart
@@ -7,7 +7,7 @@
import 'package:unittest/unittest.dart';
import 'test_helper.dart';
import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
import 'dart:async' show Future, Stream, StreamController;
var tests = <IsolateTest>[
@@ -26,10 +26,10 @@
final socket = new StreamController();
// Avoid to manually encode and decode messages from the stream
- Stream<String> stream = socket.stream.map(JSON.encode);
+ Stream<String> stream = socket.stream.map(jsonEncode);
stream.retype<Object>().pipe(_socket);
dynamic _decoder(dynamic obj) {
- return JSON.decode(obj);
+ return jsonDecode(obj);
}
final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart b/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
index 78091e1..43405ad 100644
--- a/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
+++ b/runtime/observatory/tests/service/external_service_synchronous_invocation_test.dart
@@ -7,7 +7,7 @@
import 'package:unittest/unittest.dart';
import 'test_helper.dart';
import 'dart:io' show WebSocket;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonDecode, jsonEncode;
import 'dart:async' show Future, Stream, StreamController;
var tests = <IsolateTest>[
@@ -23,10 +23,10 @@
final socket = new StreamController();
// Avoid to manually encode and decode messages from the stream
- Stream<String> stream = socket.stream.map(JSON.encode);
+ Stream<String> stream = socket.stream.map(jsonEncode);
stream.retype<Object>().pipe(_socket);
dynamic _decoder(dynamic obj) {
- return JSON.decode(obj);
+ return jsonDecode(obj);
}
final client = _socket.map(_decoder).asBroadcastStream();
diff --git a/runtime/observatory/tests/service/file_service_test.dart b/runtime/observatory/tests/service/file_service_test.dart
index 7f372c0..fe9dd6f 100644
--- a/runtime/observatory/tests/service/file_service_test.dart
+++ b/runtime/observatory/tests/service/file_service_test.dart
@@ -27,7 +27,7 @@
Future<ServiceExtensionResponse> cleanup(ignored_a, ignored_b) {
closeDown();
- var result = JSON.encode({'type': 'foobar'});
+ var result = jsonEncode({'type': 'foobar'});
return new Future.value(new ServiceExtensionResponse.result(result));
}
@@ -60,7 +60,7 @@
closeDown();
throw e;
}
- var result = JSON.encode({'type': 'foobar'});
+ var result = jsonEncode({'type': 'foobar'});
return new Future.value(new ServiceExtensionResponse.result(result));
}
diff --git a/runtime/observatory/tests/service/get_object_rpc_test.dart b/runtime/observatory/tests/service/get_object_rpc_test.dart
index 8ac90d2..6e1cb43 100644
--- a/runtime/observatory/tests/service/get_object_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_object_rpc_test.dart
@@ -6,7 +6,7 @@
library get_object_rpc_test;
import 'dart:typed_data';
-import 'dart:convert' show BASE64;
+import 'dart:convert' show base64Decode;
import 'package:observatory/service_io.dart';
import 'package:unittest/unittest.dart';
import 'service_test_common.dart';
@@ -447,7 +447,7 @@
expect(result['offset'], isNull);
expect(result['count'], isNull);
expect(result['bytes'], equals('AwIB'));
- Uint8List bytes = BASE64.decode(result['bytes']);
+ Uint8List bytes = base64Decode(result['bytes']);
expect(bytes.buffer.asUint8List().toString(), equals('[3, 2, 1]'));
},
@@ -473,7 +473,7 @@
expect(result['offset'], isNull);
expect(result['count'], equals(2));
expect(result['bytes'], equals('AwI='));
- Uint8List bytes = BASE64.decode(result['bytes']);
+ Uint8List bytes = base64Decode(result['bytes']);
expect(bytes.buffer.asUint8List().toString(), equals('[3, 2]'));
},
@@ -500,7 +500,7 @@
expect(result['offset'], equals(2));
expect(result['count'], equals(1));
expect(result['bytes'], equals('AQ=='));
- Uint8List bytes = BASE64.decode(result['bytes']);
+ Uint8List bytes = base64Decode(result['bytes']);
expect(bytes.buffer.asUint8List().toString(), equals('[1]'));
},
@@ -550,7 +550,7 @@
expect(result['offset'], isNull);
expect(result['count'], isNull);
expect(result['bytes'], equals('AwAAAAAAAAACAAAAAAAAAAEAAAAAAAAA'));
- Uint8List bytes = BASE64.decode(result['bytes']);
+ Uint8List bytes = base64Decode(result['bytes']);
expect(bytes.buffer.asUint64List().toString(), equals('[3, 2, 1]'));
},
@@ -576,7 +576,7 @@
expect(result['offset'], isNull);
expect(result['count'], equals(2));
expect(result['bytes'], equals('AwAAAAAAAAACAAAAAAAAAA=='));
- Uint8List bytes = BASE64.decode(result['bytes']);
+ Uint8List bytes = base64Decode(result['bytes']);
expect(bytes.buffer.asUint64List().toString(), equals('[3, 2]'));
},
@@ -603,7 +603,7 @@
expect(result['offset'], equals(2));
expect(result['count'], equals(1));
expect(result['bytes'], equals('AQAAAAAAAAA='));
- Uint8List bytes = BASE64.decode(result['bytes']);
+ Uint8List bytes = base64Decode(result['bytes']);
expect(bytes.buffer.asUint64List().toString(), equals('[1]'));
},
diff --git a/runtime/observatory/tests/service/process_service_test.dart b/runtime/observatory/tests/service/process_service_test.dart
index 8a22291..df8556a 100644
--- a/runtime/observatory/tests/service/process_service_test.dart
+++ b/runtime/observatory/tests/service/process_service_test.dart
@@ -33,7 +33,7 @@
Future<ServiceExtensionResponse> cleanup(ignored_a, ignored_b) {
closeDown();
- var result = JSON.encode({'type': 'foobar'});
+ var result = jsonEncode({'type': 'foobar'});
return new Future.value(new ServiceExtensionResponse.result(result));
}
@@ -57,7 +57,7 @@
throw e;
}
- var result = JSON.encode({
+ var result = jsonEncode({
'type': 'foobar',
'pids': [process1.pid, process2.pid, process3.pid]
});
@@ -67,7 +67,7 @@
Future<ServiceExtensionResponse> closeStdin(ignored_a, ignored_b) {
process3.stdin.close();
return process3.exitCode.then<ServiceExtensionResponse>((int exit) {
- var result = JSON.encode({'type': 'foobar'});
+ var result = jsonEncode({'type': 'foobar'});
return new ServiceExtensionResponse.result(result);
});
}
diff --git a/runtime/observatory/tests/service/tcp_socket_closing_service_test.dart b/runtime/observatory/tests/service/tcp_socket_closing_service_test.dart
index c22794e..a995125 100644
--- a/runtime/observatory/tests/service/tcp_socket_closing_service_test.dart
+++ b/runtime/observatory/tests/service/tcp_socket_closing_service_test.dart
@@ -42,7 +42,7 @@
}
});
var client = await io.RawDatagramSocket.bind('127.0.0.1', 0);
- client.send(UTF8.encoder.convert('foobar'),
+ client.send(utf8.encoder.convert('foobar'),
new io.InternetAddress('127.0.0.1'), server.port);
client.close();
diff --git a/runtime/observatory/tests/service/tcp_socket_service_test.dart b/runtime/observatory/tests/service/tcp_socket_service_test.dart
index aef552a..ef80a75 100644
--- a/runtime/observatory/tests/service/tcp_socket_service_test.dart
+++ b/runtime/observatory/tests/service/tcp_socket_service_test.dart
@@ -14,7 +14,7 @@
// to allow us to query them from the other isolate.
var serverSocket = await io.ServerSocket.bind('127.0.0.1', 0);
serverSocket.listen((s) {
- s.transform(UTF8.decoder).listen(print);
+ s.transform(utf8.decoder).listen(print);
s.close();
});
var socket = await io.Socket.connect("127.0.0.1", serverSocket.port);
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 13da4d1..c8a4111 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -223,7 +223,7 @@
var blank;
var first = true;
process.stdout
- .transform(UTF8.decoder)
+ .transform(utf8.decoder)
.transform(new LineSplitter())
.listen((line) {
const kObservatoryListening = 'Observatory listening on ';
@@ -243,7 +243,7 @@
print('>testee>out> $line');
});
process.stderr
- .transform(UTF8.decoder)
+ .transform(utf8.decoder)
.transform(new LineSplitter())
.listen((line) {
print('>testee>err> $line');
diff --git a/runtime/observatory/tests/service/udp_socket_service_test.dart b/runtime/observatory/tests/service/udp_socket_service_test.dart
index d51ca6a..3d40eda 100644
--- a/runtime/observatory/tests/service/udp_socket_service_test.dart
+++ b/runtime/observatory/tests/service/udp_socket_service_test.dart
@@ -18,7 +18,7 @@
}
});
var client = await io.RawDatagramSocket.bind('127.0.0.1', 0);
- client.send(UTF8.encoder.convert('foobar'),
+ client.send(utf8.encoder.convert('foobar'),
new io.InternetAddress('127.0.0.1'), server.port);
}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index e31ec60..a3b0e33 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -18,6 +18,7 @@
#include "vm/symbols.h"
#include "vm/timeline.h"
#include "vm/type_table.h"
+#include "vm/type_testing_stubs.h"
namespace dart {
@@ -589,6 +590,10 @@
}
}
}
+
+ // After resolving, we re-initialize the type testing stub.
+ type.SetTypeTestingStub(
+ Instructions::Handle(TypeTestingStubGenerator::DefaultCodeForType(type)));
}
void ClassFinalizer::FinalizeTypeParameters(const Class& cls,
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index c41dede..03dbd3b 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -97,7 +97,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kClassCid);
intptr_t count = predefined_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawClass* cls = predefined_[i];
intptr_t class_id = cls->ptr()->id_;
@@ -105,7 +105,7 @@
s->AssignRef(cls);
}
count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawClass* cls = objects_[i];
s->AssignRef(cls);
@@ -162,7 +162,7 @@
void ReadAlloc(Deserializer* d) {
predefined_start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
ClassTable* table = d->isolate()->class_table();
for (intptr_t i = 0; i < count; i++) {
intptr_t class_id = d->ReadCid();
@@ -174,7 +174,7 @@
predefined_stop_index_ = d->next_index();
start_index_ = d->next_index();
- count = d->Read<int32_t>();
+ count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Class::InstanceSize()));
}
@@ -298,7 +298,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kUnresolvedClassCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawUnresolvedClass* cls = objects_[i];
s->AssignRef(cls);
@@ -307,7 +307,6 @@
void WriteFill(Serializer* s) {
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
for (intptr_t i = 0; i < count; i++) {
RawUnresolvedClass* cls = objects_[i];
RawObject** from = cls->from();
@@ -332,7 +331,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, UnresolvedClass::InstanceSize()));
@@ -379,11 +378,11 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kTypeArgumentsCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTypeArguments* type_args = objects_[i];
intptr_t length = Smi::Value(type_args->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->AssignRef(type_args);
}
}
@@ -393,7 +392,7 @@
for (intptr_t i = 0; i < count; i++) {
RawTypeArguments* type_args = objects_[i];
intptr_t length = Smi::Value(type_args->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->Write<bool>(type_args->IsCanonical());
intptr_t hash = Smi::Value(type_args->ptr()->hash_);
s->Write<int32_t>(hash);
@@ -417,9 +416,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(old_space,
TypeArguments::InstanceSize(length)));
}
@@ -432,7 +431,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawTypeArguments* type_args =
reinterpret_cast<RawTypeArguments*>(d->Ref(id));
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(type_args, kTypeArgumentsCid,
TypeArguments::InstanceSize(length),
@@ -469,7 +468,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kPatchClassCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawPatchClass* cls = objects_[i];
s->AssignRef(cls);
@@ -505,7 +504,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, PatchClass::InstanceSize()));
@@ -565,7 +564,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kFunctionCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawFunction* func = objects_[i];
s->AssignRef(func);
@@ -615,7 +614,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Function::InstanceSize()));
}
@@ -734,7 +733,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kClosureDataCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawClosureData* data = objects_[i];
s->AssignRef(data);
@@ -767,7 +766,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, ClosureData::InstanceSize()));
@@ -815,7 +814,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kSignatureDataCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawSignatureData* data = objects_[i];
s->AssignRef(data);
@@ -847,7 +846,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, SignatureData::InstanceSize()));
@@ -892,7 +891,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kRedirectionDataCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawRedirectionData* data = objects_[i];
s->AssignRef(data);
@@ -924,7 +923,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, RedirectionData::InstanceSize()));
@@ -999,7 +998,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kFieldCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawField* field = objects_[i];
s->AssignRef(field);
@@ -1071,7 +1070,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Field::InstanceSize()));
}
@@ -1152,7 +1151,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kLiteralTokenCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawLiteralToken* token = objects_[i];
s->AssignRef(token);
@@ -1185,7 +1184,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, LiteralToken::InstanceSize()));
@@ -1230,7 +1229,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kTokenStreamCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTokenStream* stream = objects_[i];
s->AssignRef(stream);
@@ -1262,7 +1261,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, TokenStream::InstanceSize()));
@@ -1306,7 +1305,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kScriptCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawScript* script = objects_[i];
s->AssignRef(script);
@@ -1344,7 +1343,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Script::InstanceSize()));
}
@@ -1398,7 +1397,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kLibraryCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawLibrary* lib = objects_[i];
s->AssignRef(lib);
@@ -1440,7 +1439,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Library::InstanceSize()));
}
@@ -1502,7 +1501,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kNamespaceCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawNamespace* ns = objects_[i];
s->AssignRef(ns);
@@ -1534,7 +1533,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Namespace::InstanceSize()));
}
@@ -1566,10 +1565,6 @@
virtual ~KernelProgramInfoSerializationCluster() {}
void Trace(Serializer* s, RawObject* object) {
- if (s->kind() == Snapshot::kFullAOT) {
- return;
- }
-
RawKernelProgramInfo* info = KernelProgramInfo::RawCast(object);
objects_.Add(info);
@@ -1581,13 +1576,9 @@
}
void WriteAlloc(Serializer* s) {
- if (s->kind() == Snapshot::kFullAOT) {
- return;
- }
-
s->WriteCid(kKernelProgramInfoCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawKernelProgramInfo* info = objects_[i];
s->AssignRef(info);
@@ -1595,10 +1586,6 @@
}
void WriteFill(Serializer* s) {
- if (s->kind() == Snapshot::kFullAOT) {
- return;
- }
-
intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawKernelProgramInfo* info = objects_[i];
@@ -1622,11 +1609,9 @@
virtual ~KernelProgramInfoDeserializationCluster() {}
void ReadAlloc(Deserializer* d) {
- ASSERT(d->kind() != Snapshot::kFullAOT);
-
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, KernelProgramInfo::InstanceSize()));
@@ -1635,8 +1620,6 @@
}
void ReadFill(Deserializer* d) {
- ASSERT(d->kind() != Snapshot::kFullAOT);
-
bool is_vm_object = d->isolate() == Dart::vm_isolate();
for (intptr_t id = start_index_; id < stop_index_; id++) {
@@ -1691,7 +1674,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kCodeCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawCode* code = objects_[i];
s->AssignRef(code);
@@ -1773,7 +1756,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Code::InstanceSize(0)));
}
@@ -1883,11 +1866,11 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kObjectPoolCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawObjectPool* pool = objects_[i];
intptr_t length = pool->ptr()->length_;
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->AssignRef(pool);
}
}
@@ -1897,7 +1880,7 @@
for (intptr_t i = 0; i < count; i++) {
RawObjectPool* pool = objects_[i];
intptr_t length = pool->ptr()->length_;
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
uint8_t* entry_types = pool->ptr()->entry_types();
for (intptr_t j = 0; j < length; j++) {
ObjectPool::EntryType entry_type =
@@ -1950,9 +1933,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
d->AssignRef(
AllocateUninitialized(old_space, ObjectPool::InstanceSize(length)));
}
@@ -1962,7 +1945,7 @@
void ReadFill(Deserializer* d) {
bool is_vm_object = d->isolate() == Dart::vm_isolate();
for (intptr_t id = start_index_; id < stop_index_; id += 1) {
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
RawObjectPool* pool = reinterpret_cast<RawObjectPool*>(d->Ref(id + 0));
Deserializer::InitializeHeader(
pool, kObjectPoolCid, ObjectPool::InstanceSize(length), is_vm_object);
@@ -2013,34 +1996,28 @@
objects_.Add(object);
// A string's hash must already be computed when we write it because it
- // will be loaded into read-only memory.
- if (cid_ == kOneByteStringCid) {
- RawOneByteString* str = static_cast<RawOneByteString*>(object);
- if (String::GetCachedHash(str) == 0) {
- intptr_t hash =
- String::Hash(str->ptr()->data(), Smi::Value(str->ptr()->length_));
- String::SetCachedHash(str, hash);
- }
- ASSERT(String::GetCachedHash(str) != 0);
- } else if (cid_ == kTwoByteStringCid) {
- RawTwoByteString* str = static_cast<RawTwoByteString*>(object);
- if (String::GetCachedHash(str) == 0) {
- intptr_t hash = String::Hash(str->ptr()->data(),
- Smi::Value(str->ptr()->length_) * 2);
- String::SetCachedHash(str, hash);
- }
- ASSERT(String::GetCachedHash(str) != 0);
+ // will be loaded into read-only memory. Extra bytes due to allocation
+ // rounding need to be deterministically set for reliable deduplication in
+ // shared images.
+ if (object->IsVMHeapObject()) {
+ // This object is already read-only.
+ } else {
+ Object::FinalizeReadOnlyObject(object);
}
}
void WriteAlloc(Serializer* s) {
s->WriteCid(cid_);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
+ uint32_t running_offset = 0;
for (intptr_t i = 0; i < count; i++) {
RawObject* object = objects_[i];
- int32_t rodata_offset = s->GetDataOffset(object);
- s->Write<int32_t>(rodata_offset);
+ uint32_t offset = s->GetDataOffset(object);
+ ASSERT(Utils::IsAligned(offset, kObjectAlignment));
+ ASSERT(offset > running_offset);
+ s->WriteUnsigned((offset - running_offset) >> kObjectAlignmentLog2);
+ running_offset = offset;
s->AssignRef(object);
}
}
@@ -2061,10 +2038,11 @@
virtual ~RODataDeserializationCluster() {}
void ReadAlloc(Deserializer* d) {
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
+ uint32_t running_offset = 0;
for (intptr_t i = 0; i < count; i++) {
- int32_t rodata_offset = d->Read<int32_t>();
- d->AssignRef(d->GetObjectAt(rodata_offset));
+ running_offset += d->ReadUnsigned() << kObjectAlignmentLog2;
+ d->AssignRef(d->GetObjectAt(running_offset));
}
}
@@ -2090,11 +2068,11 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kExceptionHandlersCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawExceptionHandlers* handlers = objects_[i];
intptr_t length = handlers->ptr()->num_entries_;
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->AssignRef(handlers);
}
}
@@ -2104,7 +2082,7 @@
for (intptr_t i = 0; i < count; i++) {
RawExceptionHandlers* handlers = objects_[i];
intptr_t length = handlers->ptr()->num_entries_;
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->WriteRef(handlers->ptr()->handled_types_data_);
uint8_t* data = reinterpret_cast<uint8_t*>(handlers->ptr()->data());
@@ -2126,9 +2104,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(
old_space, ExceptionHandlers::InstanceSize(length)));
}
@@ -2141,7 +2119,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawExceptionHandlers* handlers =
reinterpret_cast<RawExceptionHandlers*>(d->Ref(id));
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(handlers, kExceptionHandlersCid,
ExceptionHandlers::InstanceSize(length),
is_vm_object);
@@ -2176,11 +2154,11 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kContextCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawContext* context = objects_[i];
intptr_t length = context->ptr()->num_variables_;
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->AssignRef(context);
}
}
@@ -2190,7 +2168,7 @@
for (intptr_t i = 0; i < count; i++) {
RawContext* context = objects_[i];
intptr_t length = context->ptr()->num_variables_;
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->WriteRef(context->ptr()->parent_);
for (intptr_t j = 0; j < length; j++) {
s->WriteRef(context->ptr()->data()[j]);
@@ -2211,9 +2189,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
d->AssignRef(
AllocateUninitialized(old_space, Context::InstanceSize(length)));
}
@@ -2225,7 +2203,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawContext* context = reinterpret_cast<RawContext*>(d->Ref(id));
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(
context, kContextCid, Context::InstanceSize(length), is_vm_object);
context->ptr()->num_variables_ = length;
@@ -2258,11 +2236,11 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kContextScopeCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawContextScope* scope = objects_[i];
intptr_t length = scope->ptr()->num_variables_;
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->AssignRef(scope);
}
}
@@ -2272,7 +2250,7 @@
for (intptr_t i = 0; i < count; i++) {
RawContextScope* scope = objects_[i];
intptr_t length = scope->ptr()->num_variables_;
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->Write<bool>(scope->ptr()->is_implicit_);
RawObject** from = scope->from();
RawObject** to = scope->to(length);
@@ -2295,9 +2273,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
d->AssignRef(
AllocateUninitialized(old_space, ContextScope::InstanceSize(length)));
}
@@ -2309,7 +2287,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawContextScope* scope = reinterpret_cast<RawContextScope*>(d->Ref(id));
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(scope, kContextScopeCid,
ContextScope::InstanceSize(length),
is_vm_object);
@@ -2344,7 +2322,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kUnlinkedCallCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawUnlinkedCall* unlinked = objects_[i];
s->AssignRef(unlinked);
@@ -2376,7 +2354,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, UnlinkedCall::InstanceSize()));
@@ -2422,7 +2400,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kICDataCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawICData* ic = objects_[i];
s->AssignRef(ic);
@@ -2462,7 +2440,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, ICData::InstanceSize()));
}
@@ -2516,7 +2494,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kMegamorphicCacheCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawMegamorphicCache* cache = objects_[i];
s->AssignRef(cache);
@@ -2549,7 +2527,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, MegamorphicCache::InstanceSize()));
@@ -2592,7 +2570,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kSubtypeTestCacheCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawSubtypeTestCache* cache = objects_[i];
s->AssignRef(cache);
@@ -2620,7 +2598,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, SubtypeTestCache::InstanceSize()));
@@ -2662,7 +2640,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kLanguageErrorCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawLanguageError* error = objects_[i];
s->AssignRef(error);
@@ -2697,7 +2675,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, LanguageError::InstanceSize()));
@@ -2746,7 +2724,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kUnhandledExceptionCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawUnhandledException* exception = objects_[i];
s->AssignRef(exception);
@@ -2778,7 +2756,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, UnhandledException::InstanceSize()));
@@ -2834,7 +2812,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(cid_);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
s->Write<int32_t>(next_field_offset_in_words_);
s->Write<int32_t>(instance_size_in_words_);
@@ -2877,7 +2855,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
next_field_offset_in_words_ = d->Read<int32_t>();
instance_size_in_words_ = d->Read<int32_t>();
intptr_t instance_size =
@@ -2942,7 +2920,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kLibraryPrefixCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawLibraryPrefix* prefix = objects_[i];
s->AssignRef(prefix);
@@ -2977,7 +2955,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, LibraryPrefix::InstanceSize()));
@@ -3015,7 +2993,8 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
class TypeSerializationCluster : public SerializationCluster {
public:
- TypeSerializationCluster() : SerializationCluster("Type") {}
+ explicit TypeSerializationCluster(const TypeTestingStubFinder& ttsf)
+ : SerializationCluster("Type"), type_testing_stubs_(ttsf) {}
virtual ~TypeSerializationCluster() {}
void Trace(Serializer* s, RawObject* object) {
@@ -3046,13 +3025,13 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kTypeCid);
intptr_t count = canonical_objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawType* type = canonical_objects_[i];
s->AssignRef(type);
}
count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawType* type = objects_[i];
s->AssignRef(type);
@@ -3060,6 +3039,8 @@
}
void WriteFill(Serializer* s) {
+ const bool is_vm_isolate = s->isolate() == Dart::vm_isolate();
+
intptr_t count = canonical_objects_.length();
for (intptr_t i = 0; i < count; i++) {
RawType* type = canonical_objects_[i];
@@ -3070,6 +3051,12 @@
}
s->WriteTokenPosition(type->ptr()->token_pos_);
s->Write<int8_t>(type->ptr()->type_state_);
+ if (s->kind() == Snapshot::kFullAOT) {
+ RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
+ type->ptr()->type_test_stub_entry_point_);
+ const int32_t text_offset = s->GetTextOffset(instr, Code::null());
+ s->Write<int32_t>(text_offset);
+ }
}
count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
@@ -3081,31 +3068,51 @@
}
s->WriteTokenPosition(type->ptr()->token_pos_);
s->Write<int8_t>(type->ptr()->type_state_);
+ if (s->kind() == Snapshot::kFullAOT) {
+ RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
+ type->ptr()->type_test_stub_entry_point_);
+ const int32_t text_offset = s->GetTextOffset(instr, Code::null());
+ s->Write<int32_t>(text_offset);
+ }
+ }
+
+ // The dynamic/void objects are not serialized, so we manually send
+ // the type testing stub for it.
+ if (s->kind() == Snapshot::kFullAOT && is_vm_isolate) {
+ RawInstructions* dynamic_instr = type_testing_stubs_.LookupByAddresss(
+ Type::dynamic_type().type_test_stub_entry_point());
+ s->Write<int32_t>(s->GetTextOffset(dynamic_instr, Code::null()));
+
+ RawInstructions* void_instr = type_testing_stubs_.LookupByAddresss(
+ Type::void_type().type_test_stub_entry_point());
+ s->Write<int32_t>(s->GetTextOffset(void_instr, Code::null()));
}
}
private:
GrowableArray<RawType*> canonical_objects_;
GrowableArray<RawType*> objects_;
+ const TypeTestingStubFinder& type_testing_stubs_;
};
#endif // !DART_PRECOMPILED_RUNTIME
class TypeDeserializationCluster : public DeserializationCluster {
public:
- TypeDeserializationCluster() {}
+ TypeDeserializationCluster()
+ : type_(AbstractType::Handle()), instr_(Instructions::Handle()) {}
virtual ~TypeDeserializationCluster() {}
void ReadAlloc(Deserializer* d) {
canonical_start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Type::InstanceSize()));
}
canonical_stop_index_ = d->next_index();
start_index_ = d->next_index();
- count = d->Read<int32_t>();
+ count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Type::InstanceSize()));
}
@@ -3113,13 +3120,13 @@
}
void ReadFill(Deserializer* d) {
- bool is_vm_object = d->isolate() == Dart::vm_isolate();
+ const bool is_vm_isolate = d->isolate() == Dart::vm_isolate();
for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
id++) {
RawType* type = reinterpret_cast<RawType*>(d->Ref(id));
Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
- is_vm_object, true);
+ is_vm_isolate, true);
RawObject** from = type->from();
RawObject** to = type->to();
for (RawObject** p = from; p <= to; p++) {
@@ -3127,12 +3134,18 @@
}
type->ptr()->token_pos_ = d->ReadTokenPosition();
type->ptr()->type_state_ = d->Read<int8_t>();
+ if (d->kind() == Snapshot::kFullAOT) {
+ const int32_t text_offset = d->Read<int32_t>();
+ instr_ = d->GetInstructionsAt(text_offset);
+ type_ = type;
+ type_.SetTypeTestingStub(instr_);
+ }
}
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawType* type = reinterpret_cast<RawType*>(d->Ref(id));
Deserializer::InitializeHeader(type, kTypeCid, Type::InstanceSize(),
- is_vm_object);
+ is_vm_isolate);
RawObject** from = type->from();
RawObject** to = type->to();
for (RawObject** p = from; p <= to; p++) {
@@ -3140,18 +3153,52 @@
}
type->ptr()->token_pos_ = d->ReadTokenPosition();
type->ptr()->type_state_ = d->Read<int8_t>();
+ if (d->kind() == Snapshot::kFullAOT) {
+ const int32_t text_offset = d->Read<int32_t>();
+ instr_ = d->GetInstructionsAt(text_offset);
+ type_ = type;
+ type_.SetTypeTestingStub(instr_);
+ }
+ }
+
+ // The dynamic/void objects are not serialized, so we manually send
+ // the type testing stub for it.
+ if (d->kind() == Snapshot::kFullAOT && is_vm_isolate) {
+ instr_ = d->GetInstructionsAt(d->Read<int32_t>());
+ Type::dynamic_type().SetTypeTestingStub(instr_);
+ instr_ = d->GetInstructionsAt(d->Read<int32_t>());
+ Type::void_type().SetTypeTestingStub(instr_);
+ }
+ }
+
+ void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
+ if (kind != Snapshot::kFullAOT) {
+ for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
+ id++) {
+ type_ ^= refs.At(id);
+ instr_ = TypeTestingStubGenerator::DefaultCodeForType(type_);
+ type_.SetTypeTestingStub(instr_);
+ }
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ type_ ^= refs.At(id);
+ instr_ = TypeTestingStubGenerator::DefaultCodeForType(type_);
+ type_.SetTypeTestingStub(instr_);
+ }
}
}
private:
intptr_t canonical_start_index_;
intptr_t canonical_stop_index_;
+ AbstractType& type_;
+ Instructions& instr_;
};
#if !defined(DART_PRECOMPILED_RUNTIME)
class TypeRefSerializationCluster : public SerializationCluster {
public:
- TypeRefSerializationCluster() : SerializationCluster("TypeRef") {}
+ explicit TypeRefSerializationCluster(const TypeTestingStubFinder& ttsf)
+ : SerializationCluster("TypeRef"), type_testing_stubs_(ttsf) {}
virtual ~TypeRefSerializationCluster() {}
void Trace(Serializer* s, RawObject* object) {
@@ -3168,7 +3215,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kTypeRefCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTypeRef* type = objects_[i];
s->AssignRef(type);
@@ -3184,23 +3231,31 @@
for (RawObject** p = from; p <= to; p++) {
s->WriteRef(*p);
}
+ if (s->kind() == Snapshot::kFullAOT) {
+ RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
+ type->ptr()->type_test_stub_entry_point_);
+ const int32_t text_offset = s->GetTextOffset(instr, Code::null());
+ s->Write<int32_t>(text_offset);
+ }
}
}
private:
GrowableArray<RawTypeRef*> objects_;
+ const TypeTestingStubFinder& type_testing_stubs_;
};
#endif // !DART_PRECOMPILED_RUNTIME
class TypeRefDeserializationCluster : public DeserializationCluster {
public:
- TypeRefDeserializationCluster() {}
+ TypeRefDeserializationCluster()
+ : type_(AbstractType::Handle()), instr_(Instructions::Handle()) {}
virtual ~TypeRefDeserializationCluster() {}
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, TypeRef::InstanceSize()));
}
@@ -3219,14 +3274,26 @@
for (RawObject** p = from; p <= to; p++) {
*p = d->ReadRef();
}
+ if (d->kind() == Snapshot::kFullAOT) {
+ const int32_t text_offset = d->Read<int32_t>();
+ instr_ = d->GetInstructionsAt(text_offset);
+ type_ = type;
+ type_.SetTypeTestingStub(instr_);
+ }
}
}
+
+ private:
+ AbstractType& type_;
+ Instructions& instr_;
};
#if !defined(DART_PRECOMPILED_RUNTIME)
class TypeParameterSerializationCluster : public SerializationCluster {
public:
- TypeParameterSerializationCluster() : SerializationCluster("TypeParameter") {}
+ explicit TypeParameterSerializationCluster(const TypeTestingStubFinder& ttsf)
+ : SerializationCluster("TypeParameter"), type_testing_stubs_(ttsf) {}
+
virtual ~TypeParameterSerializationCluster() {}
void Trace(Serializer* s, RawObject* object) {
@@ -3244,7 +3311,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kTypeParameterCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTypeParameter* type = objects_[i];
s->AssignRef(type);
@@ -3264,23 +3331,31 @@
s->WriteTokenPosition(type->ptr()->token_pos_);
s->Write<int16_t>(type->ptr()->index_);
s->Write<int8_t>(type->ptr()->type_state_);
+ if (s->kind() == Snapshot::kFullAOT) {
+ RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
+ type->ptr()->type_test_stub_entry_point_);
+ const int32_t text_offset = s->GetTextOffset(instr, Code::null());
+ s->Write<int32_t>(text_offset);
+ }
}
}
private:
GrowableArray<RawTypeParameter*> objects_;
+ const TypeTestingStubFinder& type_testing_stubs_;
};
#endif // !DART_PRECOMPILED_RUNTIME
class TypeParameterDeserializationCluster : public DeserializationCluster {
public:
- TypeParameterDeserializationCluster() {}
+ TypeParameterDeserializationCluster()
+ : type_(AbstractType::Handle()), instr_(Instructions::Handle()) {}
virtual ~TypeParameterDeserializationCluster() {}
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, TypeParameter::InstanceSize()));
@@ -3304,8 +3379,28 @@
type->ptr()->token_pos_ = d->ReadTokenPosition();
type->ptr()->index_ = d->Read<int16_t>();
type->ptr()->type_state_ = d->Read<int8_t>();
+ if (d->kind() == Snapshot::kFullAOT) {
+ const int32_t text_offset = d->Read<int32_t>();
+ instr_ = d->GetInstructionsAt(text_offset);
+ type_ = type;
+ type_.SetTypeTestingStub(instr_);
+ }
}
}
+
+ void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
+ if (kind != Snapshot::kFullAOT) {
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ type_ ^= refs.At(id);
+ instr_ = TypeTestingStubGenerator::DefaultCodeForType(type_);
+ type_.SetTypeTestingStub(instr_);
+ }
+ }
+ }
+
+ private:
+ AbstractType& type_;
+ Instructions& instr_;
};
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -3328,7 +3423,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kBoundedTypeCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawBoundedType* type = objects_[i];
s->AssignRef(type);
@@ -3360,7 +3455,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, BoundedType::InstanceSize()));
@@ -3404,7 +3499,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kClosureCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawClosure* closure = objects_[i];
s->AssignRef(closure);
@@ -3437,7 +3532,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Closure::InstanceSize()));
}
@@ -3481,7 +3576,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kMintCid);
- s->Write<int32_t>(smis_.length() + mints_.length());
+ s->WriteUnsigned(smis_.length() + mints_.length());
for (intptr_t i = 0; i < smis_.length(); i++) {
RawSmi* smi = smis_[i];
s->Write<bool>(true);
@@ -3514,7 +3609,7 @@
bool is_vm_object = d->isolate() == Dart::vm_isolate();
start_index_ = d->next_index();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
bool is_canonical = d->Read<bool>();
int64_t value = d->Read<int64_t>();
@@ -3571,7 +3666,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kBigintCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawBigint* bigint = objects_[i];
s->AssignRef(bigint);
@@ -3604,7 +3699,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Bigint::InstanceSize()));
}
@@ -3642,7 +3737,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kDoubleCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawDouble* dbl = objects_[i];
s->AssignRef(dbl);
@@ -3671,7 +3766,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, Double::InstanceSize()));
}
@@ -3712,7 +3807,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kGrowableObjectArrayCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawGrowableObjectArray* array = objects_[i];
s->AssignRef(array);
@@ -3746,7 +3841,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space,
GrowableObjectArray::InstanceSize()));
@@ -3788,11 +3883,11 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(cid_);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTypedData* data = objects_[i];
intptr_t length = Smi::Value(data->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->AssignRef(data);
}
}
@@ -3803,7 +3898,7 @@
for (intptr_t i = 0; i < count; i++) {
RawTypedData* data = objects_[i];
intptr_t length = Smi::Value(data->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->Write<bool>(data->IsCanonical());
uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
s->WriteBytes(cdata, length * element_size);
@@ -3824,10 +3919,10 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
intptr_t element_size = TypedData::ElementSizeInBytes(cid_);
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(
old_space, TypedData::InstanceSize(length * element_size)));
}
@@ -3840,7 +3935,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawTypedData* data = reinterpret_cast<RawTypedData*>(d->Ref(id));
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
intptr_t length_in_bytes = length * element_size;
Deserializer::InitializeHeader(data, cid_,
@@ -3872,7 +3967,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(cid_);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawExternalTypedData* data = objects_[i];
s->AssignRef(data);
@@ -3885,7 +3980,7 @@
for (intptr_t i = 0; i < count; i++) {
RawExternalTypedData* data = objects_[i];
intptr_t length = Smi::Value(data->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data_);
s->WriteBytes(cdata, length * element_size);
}
@@ -3905,7 +4000,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, ExternalTypedData::InstanceSize()));
@@ -3920,7 +4015,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawExternalTypedData* data =
reinterpret_cast<RawExternalTypedData*>(d->Ref(id));
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
Deserializer::InitializeHeader(
data, cid_, ExternalTypedData::InstanceSize(), is_vm_object);
data->ptr()->length_ = Smi::New(length);
@@ -3954,7 +4049,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kStackTraceCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawStackTrace* trace = objects_[i];
s->AssignRef(trace);
@@ -3986,7 +4081,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, StackTrace::InstanceSize()));
@@ -4030,7 +4125,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kRegExpCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawRegExp* regexp = objects_[i];
s->AssignRef(regexp);
@@ -4065,7 +4160,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(AllocateUninitialized(old_space, RegExp::InstanceSize()));
}
@@ -4111,7 +4206,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kWeakPropertyCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawWeakProperty* property = objects_[i];
s->AssignRef(property);
@@ -4143,7 +4238,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, WeakProperty::InstanceSize()));
@@ -4197,7 +4292,7 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kLinkedHashMapCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawLinkedHashMap* map = objects_[i];
s->AssignRef(map);
@@ -4245,7 +4340,7 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
d->AssignRef(
AllocateUninitialized(old_space, LinkedHashMap::InstanceSize()));
@@ -4316,11 +4411,11 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(cid_);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawArray* array = objects_[i];
intptr_t length = Smi::Value(array->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->AssignRef(array);
}
}
@@ -4330,7 +4425,7 @@
for (intptr_t i = 0; i < count; i++) {
RawArray* array = objects_[i];
intptr_t length = Smi::Value(array->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->Write<bool>(array->IsCanonical());
s->WriteRef(array->ptr()->type_arguments_);
for (intptr_t j = 0; j < length; j++) {
@@ -4353,9 +4448,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
d->AssignRef(
AllocateUninitialized(old_space, Array::InstanceSize(length)));
}
@@ -4367,7 +4462,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawArray* array = reinterpret_cast<RawArray*>(d->Ref(id));
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(array, cid_, Array::InstanceSize(length),
is_vm_object, is_canonical);
@@ -4398,11 +4493,11 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kOneByteStringCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawOneByteString* str = objects_[i];
intptr_t length = Smi::Value(str->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->AssignRef(str);
}
}
@@ -4412,7 +4507,7 @@
for (intptr_t i = 0; i < count; i++) {
RawOneByteString* str = objects_[i];
intptr_t length = Smi::Value(str->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->Write<bool>(str->IsCanonical());
intptr_t hash = String::GetCachedHash(str);
s->Write<int32_t>(hash);
@@ -4433,9 +4528,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(old_space,
OneByteString::InstanceSize(length)));
}
@@ -4447,7 +4542,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawOneByteString* str = reinterpret_cast<RawOneByteString*>(d->Ref(id));
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(str, kOneByteStringCid,
OneByteString::InstanceSize(length),
@@ -4475,11 +4570,11 @@
void WriteAlloc(Serializer* s) {
s->WriteCid(kTwoByteStringCid);
intptr_t count = objects_.length();
- s->Write<int32_t>(count);
+ s->WriteUnsigned(count);
for (intptr_t i = 0; i < count; i++) {
RawTwoByteString* str = objects_[i];
intptr_t length = Smi::Value(str->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->AssignRef(str);
}
}
@@ -4489,7 +4584,7 @@
for (intptr_t i = 0; i < count; i++) {
RawTwoByteString* str = objects_[i];
intptr_t length = Smi::Value(str->ptr()->length_);
- s->Write<int32_t>(length);
+ s->WriteUnsigned(length);
s->Write<bool>(str->IsCanonical());
intptr_t hash = String::GetCachedHash(str);
s->Write<int32_t>(hash);
@@ -4510,9 +4605,9 @@
void ReadAlloc(Deserializer* d) {
start_index_ = d->next_index();
PageSpace* old_space = d->heap()->old_space();
- intptr_t count = d->Read<int32_t>();
+ intptr_t count = d->ReadUnsigned();
for (intptr_t i = 0; i < count; i++) {
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
d->AssignRef(AllocateUninitialized(old_space,
TwoByteString::InstanceSize(length)));
}
@@ -4524,7 +4619,7 @@
for (intptr_t id = start_index_; id < stop_index_; id++) {
RawTwoByteString* str = reinterpret_cast<RawTwoByteString*>(d->Ref(id));
- intptr_t length = d->Read<int32_t>();
+ intptr_t length = d->ReadUnsigned();
bool is_canonical = d->Read<bool>();
Deserializer::InitializeHeader(str, kTwoByteStringCid,
TwoByteString::InstanceSize(length),
@@ -4669,11 +4764,11 @@
case kLibraryPrefixCid:
return new (Z) LibraryPrefixSerializationCluster();
case kTypeCid:
- return new (Z) TypeSerializationCluster();
+ return new (Z) TypeSerializationCluster(type_testing_stubs_);
case kTypeRefCid:
- return new (Z) TypeRefSerializationCluster();
+ return new (Z) TypeRefSerializationCluster(type_testing_stubs_);
case kTypeParameterCid:
- return new (Z) TypeParameterSerializationCluster();
+ return new (Z) TypeParameterSerializationCluster(type_testing_stubs_);
case kBoundedTypeCid:
return new (Z) BoundedTypeSerializationCluster();
case kClosureCid:
@@ -4734,7 +4829,7 @@
return offset;
}
-int32_t Serializer::GetDataOffset(RawObject* object) const {
+uint32_t Serializer::GetDataOffset(RawObject* object) const {
return image_writer_->GetDataOffsetFor(object);
}
@@ -4899,9 +4994,9 @@
}
#endif
- Write<int32_t>(num_base_objects_);
- Write<int32_t>(num_objects);
- Write<int32_t>(num_clusters);
+ WriteUnsigned(num_base_objects_);
+ WriteUnsigned(num_objects);
+ WriteUnsigned(num_clusters);
for (intptr_t cid = 1; cid < num_cids_; cid++) {
SerializationCluster* cluster = clusters_by_cid_[cid];
@@ -5063,7 +5158,7 @@
void VisitObject(RawObject* obj) {
if (obj->IsInstructions()) {
uword addr = RawObject::ToAddr(obj);
- int32_t offset = addr - text_base_;
+ uint32_t offset = addr - text_base_;
heap_->SetObjectId(obj, -offset);
}
}
@@ -5340,14 +5435,14 @@
return image_reader_->GetInstructionsAt(offset);
}
-RawObject* Deserializer::GetObjectAt(int32_t offset) const {
+RawObject* Deserializer::GetObjectAt(uint32_t offset) const {
return image_reader_->GetObjectAt(offset);
}
void Deserializer::Prepare() {
- num_base_objects_ = Read<int32_t>();
- num_objects_ = Read<int32_t>();
- num_clusters_ = Read<int32_t>();
+ num_base_objects_ = ReadUnsigned();
+ num_objects_ = ReadUnsigned();
+ num_clusters_ = ReadUnsigned();
clusters_ = new DeserializationCluster*[num_clusters_];
refs_ = Array::New(num_objects_ + 1, Heap::kOld);
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index dd0eb7c..c9e4970 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -15,6 +15,7 @@
#include "vm/heap.h"
#include "vm/object.h"
#include "vm/snapshot.h"
+#include "vm/type_testing_stubs.h"
#include "vm/version.h"
#if defined(DEBUG)
@@ -208,7 +209,7 @@
void Write(T value) {
WriteStream::Raw<sizeof(T), T>::Write(&stream_, value);
}
-
+ void WriteUnsigned(intptr_t value) { stream_.WriteUnsigned(value); }
void WriteBytes(const uint8_t* addr, intptr_t len) {
stream_.WriteBytes(addr, len);
}
@@ -220,7 +221,7 @@
if (id == 0) {
FATAL("Missing ref");
}
- Write<int32_t>(id);
+ WriteUnsigned(id);
return;
}
@@ -241,7 +242,7 @@
}
FATAL("Missing ref");
}
- Write<int32_t>(id);
+ WriteUnsigned(id);
}
void WriteTokenPosition(TokenPosition pos) {
@@ -254,7 +255,7 @@
}
int32_t GetTextOffset(RawInstructions* instr, RawCode* code) const;
- int32_t GetDataOffset(RawObject* object) const;
+ uint32_t GetDataOffset(RawObject* object) const;
intptr_t GetDataSize() const;
intptr_t GetTextSize() const;
@@ -264,6 +265,7 @@
void DumpCombinedCodeStatistics();
private:
+ TypeTestingStubFinder type_testing_stubs_;
Heap* heap_;
Zone* zone_;
Snapshot::Kind kind_;
@@ -312,7 +314,7 @@
T Read() {
return ReadStream::Raw<sizeof(T), T>::Read(&stream_);
}
-
+ intptr_t ReadUnsigned() { return stream_.ReadUnsigned(); }
void ReadBytes(uint8_t* addr, intptr_t len) { stream_.ReadBytes(addr, len); }
const uint8_t* CurrentBufferAddress() const {
@@ -337,10 +339,7 @@
return refs_->ptr()->data()[index];
}
- RawObject* ReadRef() {
- int32_t index = Read<int32_t>();
- return Ref(index);
- }
+ RawObject* ReadRef() { return Ref(ReadUnsigned()); }
TokenPosition ReadTokenPosition() {
return TokenPosition::SnapshotDecode(Read<int32_t>());
@@ -352,7 +351,7 @@
}
RawInstructions* GetInstructionsAt(int32_t offset) const;
- RawObject* GetObjectAt(int32_t offset) const;
+ RawObject* GetObjectAt(uint32_t offset) const;
RawApiError* VerifyVersionAndFeatures(Isolate* isolate);
diff --git a/runtime/vm/code_patcher.cc b/runtime/vm/code_patcher.cc
index 784c9af..ca7cd0e 100644
--- a/runtime/vm/code_patcher.cc
+++ b/runtime/vm/code_patcher.cc
@@ -28,4 +28,15 @@
}
}
+bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size) {
+ uint8_t* bytes = reinterpret_cast<uint8_t*>(addr);
+ for (intptr_t i = 0; i < size; i++) {
+ int16_t val = pattern[i];
+ if ((val >= 0) && (val != bytes[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace dart
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index 8518a74..17ff119 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -102,8 +102,16 @@
NativeFunction target,
const Code& trampoline);
#endif
+
+ static intptr_t GetSubtypeTestCachePoolIndex(uword return_address);
};
+// Beginning from [addr] we compare [size] bytes with [pattern]. All [0..255]
+// values in [pattern] have to match, negative values are skipped.
+//
+// Example pattern: `[0x3d, 0x8b, -1, -1]`.
+bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size);
+
} // namespace dart
#endif // RUNTIME_VM_CODE_PATCHER_H_
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index 8cebf38..4c99d91 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -16,17 +16,6 @@
namespace dart {
-static bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size) {
- uint8_t* bytes = reinterpret_cast<uint8_t*>(addr);
- for (intptr_t i = 0; i < size; i++) {
- int16_t val = pattern[i];
- if ((val >= 0) && (val != bytes[i])) {
- return false;
- }
- }
- return true;
-}
-
intptr_t IndexFromPPLoad(uword start) {
int32_t offset = *reinterpret_cast<int32_t*>(start);
return ObjectPool::IndexFromOffset(offset);
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index f84ed2e..37eea57 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -46,6 +46,7 @@
#include "vm/timeline.h"
#include "vm/timer.h"
#include "vm/type_table.h"
+#include "vm/type_testing_stubs.h"
#include "vm/unicode.h"
#include "vm/version.h"
@@ -273,6 +274,10 @@
ClassFinalizer::SortClasses();
+ // Collects type usage information which allows us to decide when/how to
+ // optimize runtime type tests.
+ TypeUsageInfo type_usage_info(T);
+
// The cid-ranges of subclasses of a class are e.g. used for is/as checks
// as well as other type checks.
HierarchyInfo hierarchy_info(T);
@@ -312,6 +317,10 @@
// Compile newly found targets and add their callees until we reach a
// fixed point.
Iterate();
+
+ // Replace the default type testing stubs installed on [Type]s with new
+ // [Type]-specialized stubs.
+ AttachOptimizedTypeTestingStub();
}
I->set_compilation_allowed(false);
@@ -1858,6 +1867,80 @@
}
}
+void Precompiler::AttachOptimizedTypeTestingStub() {
+ Isolate::Current()->heap()->CollectAllGarbage();
+ GrowableHandlePtrArray<const AbstractType> types(Z, 200);
+ {
+ class TypesCollector : public ObjectVisitor {
+ public:
+ explicit TypesCollector(Zone* zone,
+ GrowableHandlePtrArray<const AbstractType>* types)
+ : type_(AbstractType::Handle(zone)), types_(types) {}
+
+ void VisitObject(RawObject* obj) {
+ if (obj->GetClassId() == kTypeCid || obj->GetClassId() == kTypeRefCid) {
+ type_ ^= obj;
+ types_->Add(type_);
+ }
+ }
+
+ private:
+ AbstractType& type_;
+ GrowableHandlePtrArray<const AbstractType>* types_;
+ };
+
+ HeapIterationScope his(T);
+ TypesCollector visitor(Z, &types);
+
+ // Find all type objects in this isolate.
+ I->heap()->VisitObjects(&visitor);
+
+ // Find all type objects in the vm-isolate.
+ Dart::vm_isolate()->heap()->VisitObjects(&visitor);
+ }
+
+ TypeUsageInfo* type_usage_info = Thread::Current()->type_usage_info();
+
+ // At this point we're not generating any new code, so we build a picture of
+ // which types we might type-test against.
+ type_usage_info->BuildTypeUsageInformation();
+
+ TypeTestingStubGenerator type_testing_stubs;
+ Instructions& instr = Instructions::Handle();
+ for (intptr_t i = 0; i < types.length(); i++) {
+ const AbstractType& type = types.At(i);
+
+ if (!type.IsResolved()) {
+ continue;
+ }
+
+ // [kVectorCid] is excluded because it doesn't have a real class,
+ // corresponding to the class id, in Dart source code.
+ if (type.IsType() && type.type_class_id() == kVectorCid) {
+ continue;
+ }
+
+ if (type.InVMHeap()) {
+ // The only important types in the vm isolate are "dynamic"/"void", which
+ // will get their optimized top-type testing stub installed at creation.
+ continue;
+ }
+
+ if (type.IsResolved() && !type.IsMalformedOrMalbounded()) {
+ if (type_usage_info->IsUsedInTypeTest(type)) {
+ instr = type_testing_stubs.OptimizedCodeForType(type);
+ type.SetTypeTestingStub(instr);
+
+ // Ensure we retain the type.
+ AddType(type);
+ }
+ }
+ }
+
+ ASSERT(Object::dynamic_type().type_test_stub_entry_point() !=
+ StubCode::DefaultTypeTest_entry()->EntryPoint());
+}
+
void Precompiler::DropTypes() {
ObjectStore* object_store = I->object_store();
GrowableObjectArray& retained_types =
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index c54fc75..93e8326 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -373,6 +373,8 @@
void TraceConstFunctions();
void CollectCallbackFields();
+ void AttachOptimizedTypeTestingStub();
+
void TraceForRetainedFunctions();
void DropFunctions();
void DropFields();
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index b4f890a..ab6f811 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -353,6 +353,13 @@
void Bind(Label* label);
void Jump(Label* label) { b(label); }
+ void LoadField(Register dst, FieldAddress address) { ldr(dst, address); }
+
+ void CompareWithFieldValue(Register value, FieldAddress address) {
+ ldr(TMP, address);
+ cmp(value, Operand(TMP));
+ }
+
// Misc. functionality
intptr_t CodeSize() const { return buffer_.Size(); }
intptr_t prologue_offset() const { return prologue_offset_; }
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index cfe69b9..373f848 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -438,6 +438,13 @@
void Bind(Label* label);
void Jump(Label* label) { b(label); }
+ void LoadField(Register dst, FieldAddress address) { ldr(dst, address); }
+
+ void CompareWithFieldValue(Register value, FieldAddress address) {
+ ldr(TMP, address);
+ cmp(value, Operand(TMP));
+ }
+
// Misc. functionality
intptr_t CodeSize() const { return buffer_.Size(); }
intptr_t prologue_offset() const { return prologue_offset_; }
@@ -1506,6 +1513,7 @@
void EnterFrame(intptr_t frame_size);
void LeaveFrame();
+ void Ret() { ret(LR); }
void CheckCodePointer();
void RestoreCodePointer();
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 704550e..24783cb 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -566,6 +566,7 @@
void CompareRegisters(Register a, Register b);
void BranchIf(Condition condition, Label* label) { j(condition, label); }
+ void LoadField(Register dst, FieldAddress address) { movw(dst, address); }
// Issues a move instruction if 'to' is not the same as 'from'.
void MoveRegister(Register to, Register from);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 83a80ff..5b85011 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -651,6 +651,7 @@
}
// Methods for High-level operations and implemented on all architectures.
+ void Ret() { ret(); }
void CompareRegisters(Register a, Register b);
void BranchIf(Condition condition, Label* label) { j(condition, label); }
@@ -799,6 +800,12 @@
void Bind(Label* label);
void Jump(Label* label) { jmp(label); }
+ void LoadField(Register dst, FieldAddress address) { movq(dst, address); }
+
+ void CompareWithFieldValue(Register value, FieldAddress address) {
+ cmpq(value, address);
+ }
+
void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
static bool EmittingComments();
diff --git a/runtime/vm/compiler/assembler/assembler_x64_test.cc b/runtime/vm/compiler/assembler/assembler_x64_test.cc
index a18453c..202a3e1 100644
--- a/runtime/vm/compiler/assembler/assembler_x64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64_test.cc
@@ -3226,7 +3226,7 @@
EXPECT_FLOAT_EQ(-1.0, res, 0.000001f);
EXPECT_DISASSEMBLY_NOT_WINDOWS_ENDS_WITH(
"movups xmm10,[rax]\n"
- "movq r11,[thr+0xf8]\n"
+ "movq r11,[thr+0x...]\n"
"xorpd xmm10,[r11]\n"
"movaps xmm0,xmm10\n"
"pop thr\n"
diff --git a/runtime/vm/compiler/backend/code_statistics.cc b/runtime/vm/compiler/backend/code_statistics.cc
index 7e5cdc5..22df62c 100644
--- a/runtime/vm/compiler/backend/code_statistics.cc
+++ b/runtime/vm/compiler/backend/code_statistics.cc
@@ -108,8 +108,8 @@
}
int CombinedCodeStatistics::CompareEntries(const void* a, const void* b) {
- const intptr_t a_size = static_cast<const Entry*>(a)->bytes;
- const intptr_t b_size = static_cast<const Entry*>(b)->bytes;
+ const intptr_t a_size = (*static_cast<const Entry* const*>(a))->bytes;
+ const intptr_t b_size = (*static_cast<const Entry* const*>(b))->bytes;
if (a_size < b_size) {
return -1;
} else if (a_size > b_size) {
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 0de93d5..5d30eda 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -26,7 +26,6 @@
// Quick access to the current zone and isolate.
#define I (isolate())
#define Z (graph_->zone())
-#define T (graph_->thread())
ConstantPropagator::ConstantPropagator(
FlowGraph* graph,
@@ -1111,8 +1110,7 @@
default:
UNREACHABLE();
}
- const Double& result =
- Double::ZoneHandle(Double::New(result_val, Heap::kOld));
+ const Double& result = Double::ZoneHandle(Double::NewCanonical(result_val));
SetValue(instr, result);
}
}
@@ -1323,7 +1321,6 @@
// instructions, previous pointers, predecessors, etc. after eliminating
// unreachable code. We do not maintain those properties during the
// transformation.
- auto& value = Object::Handle(Z);
for (BlockIterator b = graph_->reverse_postorder_iterator(); !b.Done();
b.Advance()) {
BlockEntryInstr* block = b.Current();
@@ -1401,14 +1398,7 @@
THR_Print("Constant v%" Pd " = %s\n", defn->ssa_temp_index(),
defn->constant_value().ToCString());
}
- value = defn->constant_value().raw();
- if ((value.IsString() || value.IsMint() || value.IsDouble()) &&
- !value.IsCanonical()) {
- const char* error_str = nullptr;
- value = Instance::Cast(value).CheckAndCanonicalize(T, &error_str);
- ASSERT(!value.IsNull() && (error_str == nullptr));
- }
- ConstantInstr* constant = graph_->GetConstant(value);
+ ConstantInstr* constant = graph_->GetConstant(defn->constant_value());
defn->ReplaceUsesWith(constant);
i.RemoveCurrentFromGraph();
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 793a26f..e7b1a69 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -32,6 +32,7 @@
#include "vm/stub_code.h"
#include "vm/symbols.h"
#include "vm/timeline.h"
+#include "vm/type_testing_stubs.h"
namespace dart {
@@ -1232,7 +1233,7 @@
(block == flow_graph().graph_entry()->normal_entry())));
}
-// Allocate a register that is not explicitly blocked.
+// Allocate a register that is not explictly blocked.
static Register AllocateFreeRegister(bool* blocked_registers) {
for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) {
if (!blocked_registers[regno]) {
@@ -1873,29 +1874,14 @@
}
}
-bool FlowGraphCompiler::GenerateSubclassTypeCheck(Register class_id_reg,
+bool FlowGraphCompiler::GenerateSubtypeRangeCheck(Register class_id_reg,
const Class& type_class,
Label* is_subtype) {
HierarchyInfo* hi = Thread::Current()->hierarchy_info();
if (hi != NULL) {
- // We test up to 4 different cid ranges, if we would need to test more in
- // order to get a definite answer we fall back to the old mechanism (namely
- // of going into the subtyping cache)
- static const intptr_t kMaxNumberOfCidRangesToTest = 4;
-
const CidRangeVector& ranges = hi->SubtypeRangesForClass(type_class);
if (ranges.length() <= kMaxNumberOfCidRangesToTest) {
- Label fail;
- int bias = 0;
- for (intptr_t i = 0; i < ranges.length(); ++i) {
- const CidRange& range = ranges[i];
- if (!range.IsIllegalRange()) {
- bias = EmitTestAndCallCheckCid(assembler(), is_subtype, class_id_reg,
- range, bias,
- /*jump_on_miss=*/false);
- }
- }
- __ Bind(&fail);
+ GenerateCidRangesCheck(assembler(), class_id_reg, ranges, is_subtype);
return true;
}
}
@@ -1909,6 +1895,117 @@
return false;
}
+void FlowGraphCompiler::GenerateCidRangesCheck(Assembler* assembler,
+ Register class_id_reg,
+ const CidRangeVector& cid_ranges,
+ Label* inside_range_lbl,
+ Label* outside_range_lbl,
+ bool fall_through_if_inside) {
+ // If there are no valid class ranges, the check will fail. If we are
+ // supposed to fall-through in the positive case, we'll explicitly jump to
+ // the [outside_range_lbl].
+ if (cid_ranges.length() == 1 && cid_ranges[0].IsIllegalRange()) {
+ if (fall_through_if_inside) {
+ assembler->Jump(outside_range_lbl);
+ }
+ return;
+ }
+
+ int bias = 0;
+ for (intptr_t i = 0; i < cid_ranges.length(); ++i) {
+ const CidRange& range = cid_ranges[i];
+ RELEASE_ASSERT(!range.IsIllegalRange());
+ const bool last_round = i == (cid_ranges.length() - 1);
+
+ Label* jump_label = last_round && fall_through_if_inside ? outside_range_lbl
+ : inside_range_lbl;
+ const bool jump_on_miss = last_round && fall_through_if_inside;
+
+ bias = EmitTestAndCallCheckCid(assembler, jump_label, class_id_reg, range,
+ bias, jump_on_miss);
+ }
+}
+
+void FlowGraphCompiler::GenerateAssertAssignableAOT(
+ const AbstractType& dst_type,
+ const String& dst_name,
+ const Register instance_reg,
+ const Register instantiator_type_args_reg,
+ const Register function_type_args_reg,
+ const Register subtype_cache_reg,
+ const Register dst_type_reg,
+ const Register scratch_reg,
+ Label* done) {
+ TypeUsageInfo* type_usage_info = thread()->type_usage_info();
+
+ // If the int type is assignable to [dst_type] we special case it on the
+ // caller side!
+ const Type& int_type = Type::Handle(zone(), Type::IntType());
+ bool is_non_smi = false;
+ if (int_type.IsSubtypeOf(dst_type, NULL, NULL, Heap::kOld)) {
+ __ BranchIfSmi(instance_reg, done);
+ is_non_smi = true;
+ }
+
+ // We can handle certain types very efficiently on the call site (with a
+ // bailout to the normal stub, which will do a runtime call).
+ if (dst_type.IsTypeParameter()) {
+ const TypeParameter& type_param = TypeParameter::Cast(dst_type);
+ const Register kTypeArgumentsReg = type_param.IsClassTypeParameter()
+ ? instantiator_type_args_reg
+ : function_type_args_reg;
+
+ // Check if type arguments are null, i.e. equivalent to vector of dynamic.
+ __ CompareObject(kTypeArgumentsReg, Object::null_object());
+ __ BranchIf(EQUAL, done);
+ __ LoadField(dst_type_reg,
+ FieldAddress(kTypeArgumentsReg, TypeArguments::type_at_offset(
+ type_param.index())));
+ if (type_usage_info != NULL) {
+ type_usage_info->UseTypeInAssertAssignable(dst_type);
+ }
+ } else {
+ HierarchyInfo* hi = Thread::Current()->hierarchy_info();
+ if (hi != NULL) {
+ const Class& type_class = Class::Handle(zone(), dst_type.type_class());
+
+ bool check_handled_at_callsite = false;
+ bool used_cid_range_check = false;
+ const bool can_use_simple_cid_range_test =
+ hi->CanUseSubtypeRangeCheckFor(dst_type);
+ if (can_use_simple_cid_range_test) {
+ const CidRangeVector& ranges = hi->SubtypeRangesForClass(type_class);
+ if (ranges.length() <= kMaxNumberOfCidRangesToTest) {
+ if (is_non_smi) {
+ __ LoadClassId(scratch_reg, instance_reg);
+ } else {
+ __ LoadClassIdMayBeSmi(scratch_reg, instance_reg);
+ }
+ GenerateCidRangesCheck(assembler(), scratch_reg, ranges, done);
+ used_cid_range_check = true;
+ check_handled_at_callsite = true;
+ }
+ }
+
+ if (!used_cid_range_check && can_use_simple_cid_range_test &&
+ IsListClass(type_class)) {
+ __ LoadClassIdMayBeSmi(scratch_reg, instance_reg);
+ GenerateListTypeCheck(scratch_reg, done);
+ used_cid_range_check = true;
+ }
+
+ // If we haven't handled the positive case of the type check on the
+ // call-site, we want an optimized type testing stub and therefore record
+ // it in the [TypeUsageInfo].
+ if (!check_handled_at_callsite) {
+ ASSERT(type_usage_info != NULL);
+ type_usage_info->UseTypeInAssertAssignable(dst_type);
+ }
+ }
+ __ LoadObject(dst_type_reg, dst_type);
+ }
+}
+
#undef __
#endif
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 9a7948f..f61ef7b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -302,6 +302,7 @@
// Accessors.
Assembler* assembler() const { return assembler_; }
const ParsedFunction& parsed_function() const { return parsed_function_; }
+ const Function& function() const { return parsed_function_.function(); }
const GrowableArray<BlockEntryInstr*>& block_order() const {
return block_order_;
}
@@ -363,6 +364,21 @@
const AbstractType& dst_type,
const String& dst_name,
LocationSummary* locs);
+ void GenerateAssertAssignableAOT(TokenPosition token_pos,
+ intptr_t deopt_id,
+ const AbstractType& dst_type,
+ const String& dst_name,
+ LocationSummary* locs);
+
+ void GenerateAssertAssignableAOT(const AbstractType& dst_type,
+ const String& dst_name,
+ const Register instance_reg,
+ const Register instantiator_type_args_reg,
+ const Register function_type_args_reg,
+ const Register subtype_cache_reg,
+ const Register dst_type_reg,
+ const Register scratch_reg,
+ Label* done);
// DBC emits calls very differently from all other architectures due to its
// interpreted nature.
@@ -431,10 +447,25 @@
// Returns true if no further checks are necessary but the code coming after
// the emitted code here is still required do a runtime call (for the negative
// case of throwing an exception).
- bool GenerateSubclassTypeCheck(Register class_id_reg,
+ bool GenerateSubtypeRangeCheck(Register class_id_reg,
const Class& type_class,
Label* is_subtype_lbl);
+ // We test up to 4 different cid ranges, if we would need to test more in
+ // order to get a definite answer we fall back to the old mechanism (namely
+ // of going into the subtyping cache)
+ static const intptr_t kMaxNumberOfCidRangesToTest = 4;
+
+ // If [fall_through_if_inside] is `true`, then [outside_range_lbl] must be
+ // supplied, since it will be jumped to in the last case if the cid is outside
+ // the range.
+ static void GenerateCidRangesCheck(Assembler* assembler,
+ Register class_id_reg,
+ const CidRangeVector& cid_ranges,
+ Label* inside_range_lbl,
+ Label* outside_range_lbl = NULL,
+ bool fall_through_if_inside = false);
+
void EmitOptimizedInstanceCall(const StubEntry& stub_entry,
const ICData& ic_data,
intptr_t deopt_id,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 1917cf9..a27e76c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -381,7 +381,7 @@
// Fast case for cid-range based checks.
// Warning: This code destroys the contents of [kClassIdReg].
- if (GenerateSubclassTypeCheck(kClassIdReg, type_class, is_instance_lbl)) {
+ if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
return false;
}
@@ -641,15 +641,14 @@
!dst_type.IsVoidType()));
const Register kInstantiatorTypeArgumentsReg = R2;
const Register kFunctionTypeArgumentsReg = R1;
- __ PushList((1 << kInstantiatorTypeArgumentsReg) |
- (1 << kFunctionTypeArgumentsReg));
- // A null object is always assignable and is returned as result.
- Label is_assignable, runtime_call;
- __ CompareObject(R0, Object::null_object());
- __ b(&is_assignable, EQ);
// Generate throw new TypeError() if the type is malformed or malbounded.
if (dst_type.IsMalformedOrMalbounded()) {
+ // A null object is always assignable and is returned as result.
+ Label is_assignable;
+ __ CompareObject(R0, Object::null_object());
+ __ b(&is_assignable, EQ);
+
__ PushObject(Object::null_object()); // Make room for the result.
__ Push(R0); // Push the source object.
__ PushObject(dst_name); // Push the name of the destination.
@@ -660,37 +659,92 @@
__ bkpt(0);
__ Bind(&is_assignable); // For a null object.
- __ PopList((1 << kFunctionTypeArgumentsReg) |
- (1 << kInstantiatorTypeArgumentsReg));
return;
}
- // Generate inline type check, linking to runtime call if not assignable.
- SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
- test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
- &runtime_call);
+ if (FLAG_precompiled_mode) {
+ GenerateAssertAssignableAOT(token_pos, deopt_id, dst_type, dst_name, locs);
+ } else {
+ Label is_assignable_fast, is_assignable, runtime_call;
- __ Bind(&runtime_call);
- __ ldm(
- IA, SP,
- (1 << kFunctionTypeArgumentsReg) | (1 << kInstantiatorTypeArgumentsReg));
- __ PushObject(Object::null_object()); // Make room for the result.
- __ Push(R0); // Push the source object.
- __ PushObject(dst_type); // Push the type of the destination.
- __ PushList((1 << kInstantiatorTypeArgumentsReg) |
- (1 << kFunctionTypeArgumentsReg));
- __ PushObject(dst_name); // Push the name of the destination.
- __ LoadUniqueObject(R0, test_cache);
- __ Push(R0);
- GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
- // Pop the parameters supplied to the runtime entry. The result of the
- // type check runtime call is the checked value.
- __ Drop(6);
- __ Pop(R0);
+ // A null object is always assignable and is returned as result.
+ __ CompareObject(R0, Object::null_object());
+ __ b(&is_assignable_fast, EQ);
- __ Bind(&is_assignable);
- __ PopList((1 << kFunctionTypeArgumentsReg) |
- (1 << kInstantiatorTypeArgumentsReg));
+ __ PushList((1 << kInstantiatorTypeArgumentsReg) |
+ (1 << kFunctionTypeArgumentsReg));
+
+ // Generate inline type check, linking to runtime call if not assignable.
+ SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
+ test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
+ &runtime_call);
+
+ __ Bind(&runtime_call);
+ __ ldm(IA, SP,
+ (1 << kFunctionTypeArgumentsReg) |
+ (1 << kInstantiatorTypeArgumentsReg));
+ __ PushObject(Object::null_object()); // Make room for the result.
+ __ Push(R0); // Push the source object.
+ __ PushObject(dst_type); // Push the type of the destination.
+ __ PushList((1 << kInstantiatorTypeArgumentsReg) |
+ (1 << kFunctionTypeArgumentsReg));
+ __ PushObject(dst_name); // Push the name of the destination.
+ __ LoadUniqueObject(R0, test_cache);
+ __ Push(R0);
+ GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+ // Pop the parameters supplied to the runtime entry. The result of the
+ // type check runtime call is the checked value.
+ __ Drop(6);
+ __ Pop(R0);
+ __ Bind(&is_assignable);
+ __ PopList((1 << kFunctionTypeArgumentsReg) |
+ (1 << kInstantiatorTypeArgumentsReg));
+ __ Bind(&is_assignable_fast);
+ }
+}
+
+void FlowGraphCompiler::GenerateAssertAssignableAOT(
+ TokenPosition token_pos,
+ intptr_t deopt_id,
+ const AbstractType& dst_type,
+ const String& dst_name,
+ LocationSummary* locs) {
+ const Register kInstanceReg = R0;
+ const Register kInstantiatorTypeArgumentsReg = R2;
+ const Register kFunctionTypeArgumentsReg = R1;
+
+ const Register kSubtypeTestCacheReg = R3;
+ const Register kDstTypeReg = R8;
+ const Register kScratchReg = R4;
+
+ Label done;
+
+ GenerateAssertAssignableAOT(dst_type, dst_name, kInstanceReg,
+ kInstantiatorTypeArgumentsReg,
+ kFunctionTypeArgumentsReg, kSubtypeTestCacheReg,
+ kDstTypeReg, kScratchReg, &done);
+ // We use 2 consecutive entries in the pool for the subtype cache and the
+ // destination name. The second entry, namely [dst_name] seems to be unused,
+ // but it will be used by the code throwing a TypeError if the type test fails
+ // (see runtime/vm/runtime_entry.cc:TypeCheck). It will use pattern matching
+ // on the call site to find out at which pool index the destination name is
+ // located.
+ const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
+ Object::null_object(), Patchability::kPatchable);
+ const intptr_t sub_type_cache_offset =
+ ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
+ const intptr_t dst_name_index =
+ __ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
+ ASSERT((sub_type_cache_index + 1) == dst_name_index);
+ ASSERT(__ constant_pool_allowed());
+
+ __ LoadField(R9,
+ FieldAddress(kDstTypeReg,
+ AbstractType::type_test_stub_entry_point_offset()));
+ __ ldr(kSubtypeTestCacheReg, Address(PP, sub_type_cache_offset));
+ __ blx(R9);
+ EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ __ Bind(&done);
}
void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
@@ -1195,13 +1249,14 @@
bool jump_on_miss) {
intptr_t cid_start = range.cid_start;
if (range.IsSingleCid()) {
- __ CompareImmediate(class_id_reg, cid_start - bias);
- __ b(label, jump_on_miss ? NE : EQ);
+ __ AddImmediateSetFlags(class_id_reg, class_id_reg, bias - cid_start);
+ __ BranchIf(jump_on_miss ? NOT_ZERO : ZERO, label);
+ bias = cid_start;
} else {
__ AddImmediate(class_id_reg, class_id_reg, bias - cid_start);
- bias = cid_start;
__ CompareImmediate(class_id_reg, range.Extent());
- __ b(label, jump_on_miss ? HI : LS); // Unsigned higher.
+ __ BranchIf(jump_on_miss ? UNSIGNED_GREATER : UNSIGNED_LESS_EQUAL, label);
+ bias = cid_start;
}
return bias;
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index dd22a37..c76e56d 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -367,7 +367,7 @@
// Fast case for cid-range based checks.
// Warning: This code destroys the contents of [kClassIdReg].
- if (GenerateSubclassTypeCheck(kClassIdReg, type_class, is_instance_lbl)) {
+ if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
return false;
}
@@ -622,14 +622,14 @@
!dst_type.IsVoidType()));
const Register kInstantiatorTypeArgumentsReg = R1;
const Register kFunctionTypeArgumentsReg = R2;
- __ PushPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
- // A null object is always assignable and is returned as result.
- Label is_assignable, runtime_call;
- __ CompareObject(R0, Object::null_object());
- __ b(&is_assignable, EQ);
// Generate throw new TypeError() if the type is malformed or malbounded.
if (dst_type.IsMalformedOrMalbounded()) {
+ // A null object is always assignable and is returned as result.
+ Label is_assignable, runtime_call;
+ __ CompareObject(R0, Object::null_object());
+ __ b(&is_assignable, EQ);
+
__ PushObject(Object::null_object()); // Make room for the result.
__ Push(R0); // Push the source object.
__ PushObject(dst_name); // Push the name of the destination.
@@ -640,33 +640,89 @@
__ brk(0);
__ Bind(&is_assignable); // For a null object.
- __ PopPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
return;
}
- // Generate inline type check, linking to runtime call if not assignable.
- SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
- test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
- &runtime_call);
+ if (FLAG_precompiled_mode) {
+ GenerateAssertAssignableAOT(token_pos, deopt_id, dst_type, dst_name, locs);
+ } else {
+ Label is_assignable_fast, is_assignable, runtime_call;
- __ Bind(&runtime_call);
- __ ldp(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg,
- Address(SP, 0 * kWordSize, Address::PairOffset));
- __ PushObject(Object::null_object()); // Make room for the result.
- __ Push(R0); // Push the source object.
- __ PushObject(dst_type); // Push the type of the destination.
- __ PushPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
- __ PushObject(dst_name); // Push the name of the destination.
- __ LoadUniqueObject(R0, test_cache);
- __ Push(R0);
- GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
- // Pop the parameters supplied to the runtime entry. The result of the
- // type check runtime call is the checked value.
- __ Drop(6);
- __ Pop(R0);
+ // A null object is always assignable and is returned as result.
+ __ CompareObject(R0, Object::null_object());
+ __ b(&is_assignable_fast, EQ);
- __ Bind(&is_assignable);
- __ PopPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+ __ PushPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+
+ // Generate inline type check, linking to runtime call if not assignable.
+ SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
+ test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
+ &runtime_call);
+
+ __ Bind(&runtime_call);
+ __ ldp(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg,
+ Address(SP, 0 * kWordSize, Address::PairOffset));
+ __ PushObject(Object::null_object()); // Make room for the result.
+ __ Push(R0); // Push the source object.
+ __ PushObject(dst_type); // Push the type of the destination.
+ __ PushPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+ __ PushObject(dst_name); // Push the name of the destination.
+ __ LoadUniqueObject(R0, test_cache);
+ __ Push(R0);
+ GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+ // Pop the parameters supplied to the runtime entry. The result of the
+ // type check runtime call is the checked value.
+ __ Drop(6);
+ __ Pop(R0);
+ __ Bind(&is_assignable);
+ __ PopPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+ __ Bind(&is_assignable_fast);
+ }
+}
+
+void FlowGraphCompiler::GenerateAssertAssignableAOT(
+ TokenPosition token_pos,
+ intptr_t deopt_id,
+ const AbstractType& dst_type,
+ const String& dst_name,
+ LocationSummary* locs) {
+ const Register kInstanceReg = R0;
+ const Register kInstantiatorTypeArgumentsReg = R1;
+ const Register kFunctionTypeArgumentsReg = R2;
+
+ const Register kSubtypeTestCacheReg = R3;
+ const Register kDstTypeReg = R8;
+ const Register kScratchReg = R4;
+
+ Label done;
+
+ GenerateAssertAssignableAOT(dst_type, dst_name, kInstanceReg,
+ kInstantiatorTypeArgumentsReg,
+ kFunctionTypeArgumentsReg, kSubtypeTestCacheReg,
+ kDstTypeReg, kScratchReg, &done);
+
+ // We use 2 consecutive entries in the pool for the subtype cache and the
+ // destination name. The second entry, namely [dst_name] seems to be unused,
+ // but it will be used by the code throwing a TypeError if the type test fails
+ // (see runtime/vm/runtime_entry.cc:TypeCheck). It will use pattern matching
+ // on the call site to find out at which pool index the destination name is
+ // located.
+ const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
+ Object::null_object(), Patchability::kPatchable);
+ const intptr_t sub_type_cache_offset =
+ ObjectPool::element_offset(sub_type_cache_index);
+ const intptr_t dst_name_index =
+ __ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
+ ASSERT((sub_type_cache_index + 1) == dst_name_index);
+ ASSERT(__ constant_pool_allowed());
+
+ __ LoadField(R9,
+ FieldAddress(kDstTypeReg,
+ AbstractType::type_test_stub_entry_point_offset()));
+ __ ldr(kSubtypeTestCacheReg, Address(PP, sub_type_cache_offset));
+ __ blr(R9);
+ EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ __ Bind(&done);
}
void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
@@ -1146,15 +1202,16 @@
const CidRange& range,
int bias,
bool jump_on_miss) {
- intptr_t cid_start = range.cid_start;
+ const intptr_t cid_start = range.cid_start;
if (range.IsSingleCid()) {
- __ CompareImmediate(class_id_reg, cid_start - bias);
- __ b(label, jump_on_miss ? NE : EQ);
+ __ AddImmediateSetFlags(class_id_reg, class_id_reg, bias - cid_start);
+ __ BranchIf(jump_on_miss ? NOT_EQUAL : EQUAL, label);
+ bias = cid_start;
} else {
__ AddImmediate(class_id_reg, bias - cid_start);
bias = cid_start;
__ CompareImmediate(class_id_reg, range.Extent());
- __ b(label, jump_on_miss ? HI : LS); // Unsigned higher / less-or-equal.
+ __ BranchIf(jump_on_miss ? UNSIGNED_GREATER : UNSIGNED_LESS_EQUAL, label);
}
return bias;
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 712ab2e..0580e5c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -384,7 +384,7 @@
// Fast case for cid-range based checks.
// Warning: This code destroys the contents of [kClassIdReg].
- if (GenerateSubclassTypeCheck(kClassIdReg, type_class, is_instance_lbl)) {
+ if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
return false;
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index d710b8c..4a2c58b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -382,7 +382,7 @@
// Fast case for cid-range based checks.
// Warning: This code destroys the contents of [kClassIdReg].
- if (GenerateSubclassTypeCheck(kClassIdReg, type_class, is_instance_lbl)) {
+ if (GenerateSubtypeRangeCheck(kClassIdReg, type_class, is_instance_lbl)) {
return false;
}
@@ -630,13 +630,17 @@
ASSERT(dst_type.IsMalformedOrMalbounded() ||
(!dst_type.IsDynamicType() && !dst_type.IsObjectType() &&
!dst_type.IsVoidType()));
- // A null object is always assignable and is returned as result.
- Label is_assignable, runtime_call;
- __ CompareObject(RAX, Object::null_object());
- __ j(EQUAL, &is_assignable);
+ const Register kInstantiatorTypeArgumentsReg = RDX;
+ const Register kFunctionTypeArgumentsReg = RCX;
+
+ // A null object is always assignable and is returned as result.
// Generate throw new TypeError() if the type is malformed or malbounded.
if (dst_type.IsMalformedOrMalbounded()) {
+ Label is_assignable;
+ __ CompareObject(RAX, Object::null_object());
+ __ j(EQUAL, &is_assignable);
+
__ PushObject(Object::null_object()); // Make room for the result.
__ pushq(RAX); // Push the source object.
__ PushObject(dst_name); // Push the name of the destination.
@@ -650,28 +654,79 @@
return;
}
- // Generate inline type check, linking to runtime call if not assignable.
- SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
- // The registers RAX, RCX, RDX are preserved across the call.
- test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
- &runtime_call);
+ if (FLAG_precompiled_mode) {
+ GenerateAssertAssignableAOT(token_pos, deopt_id, dst_type, dst_name, locs);
+ } else {
+ Label is_assignable, runtime_call;
- __ Bind(&runtime_call);
- __ PushObject(Object::null_object()); // Make room for the result.
- __ pushq(RAX); // Push the source object.
- __ PushObject(dst_type); // Push the type of the destination.
- __ pushq(RDX); // Instantiator type arguments.
- __ pushq(RCX); // Function type arguments.
- __ PushObject(dst_name); // Push the name of the destination.
- __ LoadUniqueObject(RAX, test_cache);
- __ pushq(RAX);
- GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
- // Pop the parameters supplied to the runtime entry. The result of the
- // type check runtime call is the checked value.
- __ Drop(6);
- __ popq(RAX);
+ // A null object is always assignable and is returned as result.
+ __ CompareObject(RAX, Object::null_object());
+ __ j(EQUAL, &is_assignable);
- __ Bind(&is_assignable);
+ // Generate inline type check, linking to runtime call if not assignable.
+ SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
+ // The registers RAX, RCX, RDX are preserved across the call.
+ test_cache = GenerateInlineInstanceof(token_pos, dst_type, &is_assignable,
+ &runtime_call);
+
+ __ Bind(&runtime_call);
+ __ PushObject(Object::null_object()); // Make room for the result.
+ __ pushq(RAX); // Push the source object.
+ __ PushObject(dst_type); // Push the type of the destination.
+ __ pushq(kInstantiatorTypeArgumentsReg);
+ __ pushq(kFunctionTypeArgumentsReg);
+ __ PushObject(dst_name); // Push the name of the destination.
+ __ LoadUniqueObject(RAX, test_cache);
+ __ pushq(RAX);
+ GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs);
+ // Pop the parameters supplied to the runtime entry. The result of the
+ // type check runtime call is the checked value.
+ __ Drop(6);
+ __ popq(RAX);
+ __ Bind(&is_assignable);
+ }
+}
+
+void FlowGraphCompiler::GenerateAssertAssignableAOT(
+ TokenPosition token_pos,
+ intptr_t deopt_id,
+ const AbstractType& dst_type,
+ const String& dst_name,
+ LocationSummary* locs) {
+ const Register kInstanceReg = RAX;
+ const Register kInstantiatorTypeArgumentsReg = RDX;
+ const Register kFunctionTypeArgumentsReg = RCX;
+
+ Label done;
+
+ const Register subtype_cache_reg = R9;
+ const Register kScratchReg = RBX;
+
+ GenerateAssertAssignableAOT(dst_type, dst_name, kInstanceReg,
+ kInstantiatorTypeArgumentsReg,
+ kFunctionTypeArgumentsReg, subtype_cache_reg,
+ kScratchReg, kScratchReg, &done);
+
+ // We use 2 consecutive entries in the pool for the subtype cache and the
+ // destination name. The second entry, namely [dst_name] seems to be unused,
+ // but it will be used by the code throwing a TypeError if the type test fails
+ // (see runtime/vm/runtime_entry.cc:TypeCheck). It will use pattern matching
+ // on the call site to find out at which pool index the destination name is
+ // located.
+ const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
+ Object::null_object(), Patchability::kPatchable);
+ const intptr_t sub_type_cache_offset =
+ ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
+ const intptr_t dst_name_index =
+ __ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
+ ASSERT((sub_type_cache_index + 1) == dst_name_index);
+ ASSERT(__ constant_pool_allowed());
+
+ __ movq(subtype_cache_reg,
+ Address::AddressBaseImm32(PP, sub_type_cache_offset));
+ __ call(FieldAddress(RBX, AbstractType::type_test_stub_entry_point_offset()));
+ EmitCallsiteMetadata(token_pos, deopt_id, RawPcDescriptors::kOther, locs);
+ __ Bind(&done);
}
void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
@@ -1108,16 +1163,18 @@
const CidRange& range,
int bias,
bool jump_on_miss) {
+ // Note of WARNING: Due to smaller instruction encoding we use the 32-bit
+ // instructions on x64, which means the compare instruction has to be
+ // 32-bit (since the subtraction instruction is as well).
intptr_t cid_start = range.cid_start;
if (range.IsSingleCid()) {
__ cmpl(class_id_reg, Immediate(cid_start - bias));
- __ j(jump_on_miss ? NOT_EQUAL : EQUAL, label);
+ __ BranchIf(jump_on_miss ? NOT_EQUAL : EQUAL, label);
} else {
__ addl(class_id_reg, Immediate(bias - cid_start));
bias = cid_start;
__ cmpl(class_id_reg, Immediate(range.Extent()));
- __ j(jump_on_miss ? ABOVE : BELOW_EQUAL,
- label); // Unsigned higher / lower-or-equal.
+ __ BranchIf(jump_on_miss ? UNSIGNED_GREATER : UNSIGNED_LESS_EQUAL, label);
}
return bias;
}
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 4967657..4f2db6a 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -27,6 +27,7 @@
#include "vm/scopes.h"
#include "vm/stub_code.h"
#include "vm/symbols.h"
+#include "vm/type_testing_stubs.h"
#include "vm/compiler/backend/il_printer.h"
@@ -46,23 +47,28 @@
"Support unboxed double and float32x4 fields.");
DECLARE_FLAG(bool, eliminate_type_checks);
-const CidRangeVector& HierarchyInfo::SubtypeRangesForClass(const Class& klass) {
- ClassTable* table = thread_->isolate()->class_table();
+const CidRangeVector& HierarchyInfo::SubtypeRangesForClass(
+ const Class& klass,
+ bool include_abstract) {
+ ClassTable* table = thread()->isolate()->class_table();
const intptr_t cid_count = table->NumCids();
- if (cid_subtype_ranges_ == NULL) {
- cid_subtype_ranges_ = new CidRangeVector[cid_count];
+ CidRangeVector** cid_ranges =
+ include_abstract ? &cid_subtype_ranges_abstract_ : &cid_subtype_ranges_;
+ if (*cid_ranges == NULL) {
+ *cid_ranges = new CidRangeVector[cid_count];
}
- CidRangeVector& ranges = cid_subtype_ranges_[klass.id()];
+ CidRangeVector& ranges = (*cid_ranges)[klass.id()];
if (ranges.length() == 0) {
- BuildRangesFor(table, &ranges, klass, /*use_subtype_test=*/true);
+ BuildRangesFor(table, &ranges, klass, /*use_subtype_test=*/true,
+ include_abstract);
}
return ranges;
}
const CidRangeVector& HierarchyInfo::SubclassRangesForClass(
const Class& klass) {
- ClassTable* table = thread_->isolate()->class_table();
+ ClassTable* table = thread()->isolate()->class_table();
const intptr_t cid_count = table->NumCids();
if (cid_subclass_ranges_ == NULL) {
cid_subclass_ranges_ = new CidRangeVector[cid_count];
@@ -78,8 +84,9 @@
void HierarchyInfo::BuildRangesFor(ClassTable* table,
CidRangeVector* ranges,
const Class& klass,
- bool use_subtype_test) {
- Zone* zone = thread_->zone();
+ bool use_subtype_test,
+ bool include_abstract) {
+ Zone* zone = thread()->zone();
Class& cls = Class::Handle(zone);
// Only really used if `use_subtype_test == true`.
@@ -92,8 +99,8 @@
for (intptr_t cid = kInstanceCid; cid < cid_count; ++cid) {
// Create local zone because deep hierarchies may allocate lots of handles
// within one iteration of this loop.
- StackZone stack_zone(thread_);
- HANDLESCOPE(thread_);
+ StackZone stack_zone(thread());
+ HANDLESCOPE(thread());
if (!table->HasValidClassAt(cid)) continue;
if (cid == kTypeArgumentsCid) continue;
@@ -101,7 +108,7 @@
if (cid == kDynamicCid) continue;
if (cid == kNullCid) continue;
cls = table->At(cid);
- if (cls.is_abstract()) continue;
+ if (!include_abstract && cls.is_abstract()) continue;
if (cls.is_patch()) continue;
if (cls.IsTopLevel()) continue;
@@ -144,14 +151,26 @@
bool HierarchyInfo::CanUseSubtypeRangeCheckFor(const AbstractType& type) {
ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
- if (!type.IsInstantiated() || type.IsFunctionType() ||
+ if (!type.IsInstantiated() || !type.IsType() || type.IsFunctionType() ||
type.IsDartFunctionType()) {
return false;
}
- Zone* zone = thread_->zone();
+ Zone* zone = thread()->zone();
const Class& type_class = Class::Handle(zone, type.type_class());
+ // The FutureOr<T> type cannot be handled by checking whether the instance is
+ // a subtype of FutureOr and then checking whether the type argument `T`
+ // matches.
+ //
+ // Instead we would need to perform multiple checks:
+ //
+ // instance is Null || instance is T || instance is Future<T>
+ //
+ if (type_class.IsFutureOrClass()) {
+ return false;
+ }
+
// We can use class id range checks only if we don't have to test type
// arguments.
//
@@ -175,7 +194,7 @@
const AbstractType& type) {
ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
- if (type.IsFunctionType() || type.IsDartFunctionType()) {
+ if (!type.IsType() || type.IsFunctionType() || type.IsDartFunctionType()) {
return false;
}
@@ -183,11 +202,23 @@
// [CanUseSubtypeRangeCheckFor], since we handle type parameters in the type
// expression in some cases (see below).
- Zone* zone = thread_->zone();
+ Zone* zone = thread()->zone();
const Class& type_class = Class::Handle(zone, type.type_class());
const intptr_t num_type_parameters = type_class.NumTypeParameters();
const intptr_t num_type_arguments = type_class.NumTypeArguments();
+ // The FutureOr<T> type cannot be handled by checking whether the instance is
+ // a subtype of FutureOr and then checking whether the type argument `T`
+ // matches.
+ //
+ // Instead we would need to perform multiple checks:
+ //
+ // instance is Null || instance is T || instance is Future<T>
+ //
+ if (type_class.IsFutureOrClass()) {
+ return false;
+ }
+
// This function should only be called for generic classes.
ASSERT(type_class.NumTypeParameters() > 0 &&
type.arguments() != TypeArguments::null());
@@ -225,7 +256,8 @@
intptr_t* lower_limit,
intptr_t* upper_limit) {
if (CanUseSubtypeRangeCheckFor(type)) {
- const Class& type_class = Class::Handle(thread_->zone(), type.type_class());
+ const Class& type_class =
+ Class::Handle(thread()->zone(), type.type_class());
const CidRangeVector& ranges = SubtypeRangesForClass(type_class);
if (ranges.length() == 1) {
const CidRange& range = ranges[0];
@@ -3766,6 +3798,14 @@
ArgumentsInfo args_info(type_args_len(), ArgumentCount(), argument_names());
compiler->GenerateStaticCall(deopt_id(), token_pos(), function(), args_info,
locs(), *call_ic_data, rebind_rule_);
+ if (function().IsFactory()) {
+ TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+ if (type_usage_info != nullptr) {
+ const Class& klass = Class::Handle(function().Owner());
+ RegisterTypeArgumentsUse(compiler->function(), type_usage_info, klass,
+ ArgumentAt(0));
+ }
+ }
#else
const Array& arguments_descriptor = Array::Handle(
zone, (ic_data() == NULL) ? GetArgumentsDescriptor()
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index aaed3e0..829a16e 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -37,6 +37,7 @@
class RangeAnalysis;
class RangeBoundary;
class UnboxIntegerInstr;
+class TypeUsageInfo;
// CompileType describes type of the value produced by the definition.
//
@@ -351,23 +352,27 @@
public:
explicit HierarchyInfo(Thread* thread)
: StackResource(thread),
- thread_(thread),
cid_subtype_ranges_(NULL),
+ cid_subtype_ranges_abstract_(NULL),
cid_subclass_ranges_(NULL) {
thread->set_hierarchy_info(this);
}
~HierarchyInfo() {
- thread_->set_hierarchy_info(NULL);
+ thread()->set_hierarchy_info(NULL);
delete[] cid_subtype_ranges_;
cid_subtype_ranges_ = NULL;
+ delete[] cid_subtype_ranges_abstract_;
+ cid_subtype_ranges_abstract_ = NULL;
+
delete[] cid_subclass_ranges_;
cid_subclass_ranges_ = NULL;
}
- const CidRangeVector& SubtypeRangesForClass(const Class& klass);
+ const CidRangeVector& SubtypeRangesForClass(const Class& klass,
+ bool include_abstract = false);
const CidRangeVector& SubclassRangesForClass(const Class& klass);
bool InstanceOfHasClassRange(const AbstractType& type,
@@ -396,10 +401,11 @@
void BuildRangesFor(ClassTable* table,
CidRangeVector* ranges,
const Class& klass,
- bool use_subtype_test);
+ bool use_subtype_test,
+ bool include_abstract = false);
- Thread* thread_;
CidRangeVector* cid_subtype_ranges_;
+ CidRangeVector* cid_subtype_ranges_abstract_;
CidRangeVector* cid_subclass_ranges_;
};
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 01bf389..cd4d8f0 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -22,6 +22,7 @@
#include "vm/stack_frame.h"
#include "vm/stub_code.h"
#include "vm/symbols.h"
+#include "vm/type_testing_stubs.h"
#define __ compiler->assembler()->
#define Z (compiler->zone())
@@ -395,14 +396,55 @@
LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
+ // In AOT mode, we want to prevent spilling of the function/instantiator type
+ // argument vectors, since we preserve them. So we make this a `kNoCall`
+ // summary. Though most other registers can be modified by the type testing
+ // stubs we are calling. To tell the register allocator about it, we reserve
+ // all the other registers as temporary registers.
+ // TODO(http://dartbug.com/32788): Simplify this.
+ const Register kInstanceReg = R0;
+ const Register kInstantiatorTypeArgumentsReg = R2;
+ const Register kFunctionTypeArgumentsReg = R1;
+
+ const intptr_t kNonChangeableInputRegs =
+ (1 << kInstanceReg) | (1 << kInstantiatorTypeArgumentsReg) |
+ (1 << kFunctionTypeArgumentsReg);
+
const intptr_t kNumInputs = 3;
- const intptr_t kNumTemps = 0;
+
+ const intptr_t kNumTemps =
+ FLAG_precompiled_mode ? (Utils::CountOneBits64(kDartAvailableCpuRegs) -
+ Utils::CountOneBits64(kNonChangeableInputRegs))
+ : 0;
+
LocationSummary* summary = new (zone)
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
- summary->set_in(0, Location::RegisterLocation(R0)); // Value.
- summary->set_in(1, Location::RegisterLocation(R2)); // Instant. type args.
- summary->set_in(2, Location::RegisterLocation(R1)); // Function type args.
- summary->set_out(0, Location::RegisterLocation(R0));
+ LocationSummary(zone, kNumInputs, kNumTemps,
+ FLAG_precompiled_mode ? LocationSummary::kCallCalleeSafe
+ : LocationSummary::kCall);
+ summary->set_in(0, Location::RegisterLocation(kInstanceReg)); // Value.
+ summary->set_in(1,
+ Location::RegisterLocation(
+ kInstantiatorTypeArgumentsReg)); // Instant. type args.
+ summary->set_in(2, Location::RegisterLocation(
+ kFunctionTypeArgumentsReg)); // Function type args.
+
+ // TODO(http://dartbug.com/32787): Use Location::SameAsFirstInput() instead,
+ // once register allocator no longer hits assertion.
+ summary->set_out(0, Location::RegisterLocation(kInstanceReg));
+
+ if (FLAG_precompiled_mode) {
+ // Let's reserve all registers except for the input ones.
+ intptr_t next_temp = 0;
+ for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+ const bool is_allocatable = ((1 << i) & kDartAvailableCpuRegs) != 0;
+ const bool is_input = ((1 << i) & kNonChangeableInputRegs) != 0;
+ if (is_allocatable && !is_input) {
+ summary->set_temp(next_temp++,
+ Location::RegisterLocation(static_cast<Register>(i)));
+ }
+ }
+ }
+
return summary;
}
@@ -2391,6 +2433,14 @@
}
void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+ if (type_usage_info != nullptr) {
+ const Class& list_class = Class::Handle(
+ compiler->thread()->isolate()->class_table()->At(kArrayCid));
+ RegisterTypeArgumentsUse(compiler->function(), type_usage_info, list_class,
+ element_type()->definition());
+ }
+
const Register kLengthReg = R2;
const Register kElemTypeReg = R1;
const Register kResultReg = R0;
@@ -6344,6 +6394,13 @@
}
void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (ArgumentCount() == 1) {
+ TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+ if (type_usage_info != nullptr) {
+ RegisterTypeArgumentsUse(compiler->function(), type_usage_info, cls_,
+ ArgumentAt(0));
+ }
+ }
const Code& stub = Code::ZoneHandle(
compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
const StubEntry stub_entry(stub);
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index b2e0a9d..595c61a 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -21,6 +21,7 @@
#include "vm/stack_frame.h"
#include "vm/stub_code.h"
#include "vm/symbols.h"
+#include "vm/type_testing_stubs.h"
#define __ compiler->assembler()->
#define Z (compiler->zone())
@@ -393,14 +394,55 @@
LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
+ // In AOT mode, we want to prevent spilling of the function/instantiator type
+ // argument vectors, since we preserve them. So we make this a `kNoCall`
+ // summary. Though most other registers can be modified by the type testing
+ // stubs we are calling. To tell the register allocator about it, we reserve
+ // all the other registers as temporary registers.
+ // TODO(http://dartbug.com/32788): Simplify this.
+ const Register kInstanceReg = R0;
+ const Register kInstantiatorTypeArgumentsReg = R1;
+ const Register kFunctionTypeArgumentsReg = R2;
+
+ const intptr_t kNonChangeableInputRegs =
+ (1 << kInstanceReg) | (1 << kInstantiatorTypeArgumentsReg) |
+ (1 << kFunctionTypeArgumentsReg);
+
const intptr_t kNumInputs = 3;
- const intptr_t kNumTemps = 0;
+
+ const intptr_t kNumTemps =
+ FLAG_precompiled_mode ? (Utils::CountOneBits64(kDartAvailableCpuRegs) -
+ Utils::CountOneBits64(kNonChangeableInputRegs))
+ : 0;
+
LocationSummary* summary = new (zone)
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
- summary->set_in(0, Location::RegisterLocation(R0)); // Value.
- summary->set_in(1, Location::RegisterLocation(R1)); // Instant. type args.
- summary->set_in(2, Location::RegisterLocation(R2)); // Function type args.
- summary->set_out(0, Location::RegisterLocation(R0));
+ LocationSummary(zone, kNumInputs, kNumTemps,
+ FLAG_precompiled_mode ? LocationSummary::kCallCalleeSafe
+ : LocationSummary::kCall);
+ summary->set_in(0, Location::RegisterLocation(kInstanceReg)); // Value.
+ summary->set_in(1,
+ Location::RegisterLocation(
+ kInstantiatorTypeArgumentsReg)); // Instant. type args.
+ summary->set_in(2, Location::RegisterLocation(
+ kFunctionTypeArgumentsReg)); // Function type args.
+
+ // TODO(http://dartbug.com/32787): Use Location::SameAsFirstInput() instead,
+ // once register allocator no longer hits assertion.
+ summary->set_out(0, Location::RegisterLocation(kInstanceReg));
+
+ if (FLAG_precompiled_mode) {
+ // Let's reserve all registers except for the input ones.
+ intptr_t next_temp = 0;
+ for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+ const bool is_allocatable = ((1 << i) & kDartAvailableCpuRegs) != 0;
+ const bool is_input = ((1 << i) & kNonChangeableInputRegs) != 0;
+ if (is_allocatable && !is_input) {
+ summary->set_temp(next_temp++,
+ Location::RegisterLocation(static_cast<Register>(i)));
+ }
+ }
+ }
+
return summary;
}
@@ -2148,6 +2190,14 @@
}
void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+ if (type_usage_info != nullptr) {
+ const Class& list_class = Class::Handle(
+ compiler->thread()->isolate()->class_table()->At(kArrayCid));
+ RegisterTypeArgumentsUse(compiler->function(), type_usage_info, list_class,
+ element_type()->definition());
+ }
+
const Register kLengthReg = R2;
const Register kElemTypeReg = R1;
const Register kResultReg = R0;
@@ -5552,6 +5602,13 @@
}
void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (ArgumentCount() == 1) {
+ TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+ if (type_usage_info != nullptr) {
+ RegisterTypeArgumentsUse(compiler->function(), type_usage_info, cls_,
+ ArgumentAt(0));
+ }
+ }
const Code& stub = Code::ZoneHandle(
compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
const StubEntry stub_entry(stub);
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index f3109b6..20495f3 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -20,6 +20,7 @@
#include "vm/stack_frame.h"
#include "vm/stub_code.h"
#include "vm/symbols.h"
+#include "vm/type_testing_stubs.h"
#define __ compiler->assembler()->
#define Z (compiler->zone())
@@ -361,14 +362,55 @@
LocationSummary* AssertAssignableInstr::MakeLocationSummary(Zone* zone,
bool opt) const {
+ // In AOT mode, we want to prevent spilling of the function/instantiator type
+ // argument vectors, since we preserve them. So we make this a `kNoCall`
+ // summary. Though most other registers can be modified by the type testing
+ // stubs we are calling. To tell the register allocator about it, we reserve
+ // all the other registers as temporary registers.
+ // TODO(http://dartbug.com/32788): Simplify this.
+ const Register kInstanceReg = RAX;
+ const Register kInstantiatorTypeArgumentsReg = RDX;
+ const Register kFunctionTypeArgumentsReg = RCX;
+
+ const intptr_t kNonChangeableInputRegs =
+ (1 << kInstanceReg) | (1 << kInstantiatorTypeArgumentsReg) |
+ (1 << kFunctionTypeArgumentsReg);
+
const intptr_t kNumInputs = 3;
- const intptr_t kNumTemps = 0;
+
+ const intptr_t kNumTemps =
+ FLAG_precompiled_mode ? (Utils::CountOneBits64(kDartAvailableCpuRegs) -
+ Utils::CountOneBits64(kNonChangeableInputRegs))
+ : 0;
+
LocationSummary* summary = new (zone)
- LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
- summary->set_in(0, Location::RegisterLocation(RAX)); // Value.
- summary->set_in(1, Location::RegisterLocation(RDX)); // Instant. type args.
- summary->set_in(2, Location::RegisterLocation(RCX)); // Function type args.
- summary->set_out(0, Location::RegisterLocation(RAX));
+ LocationSummary(zone, kNumInputs, kNumTemps,
+ FLAG_precompiled_mode ? LocationSummary::kCallCalleeSafe
+ : LocationSummary::kCall);
+ summary->set_in(0, Location::RegisterLocation(kInstanceReg)); // Value.
+ summary->set_in(1,
+ Location::RegisterLocation(
+ kInstantiatorTypeArgumentsReg)); // Instant. type args.
+ summary->set_in(2, Location::RegisterLocation(
+ kFunctionTypeArgumentsReg)); // Function type args.
+
+ // TODO(http://dartbug.com/32787): Use Location::SameAsFirstInput() instead,
+ // once register allocator no longer hits assertion.
+ summary->set_out(0, Location::RegisterLocation(kInstanceReg));
+
+ if (FLAG_precompiled_mode) {
+ // Let's reserve all registers except for the input ones.
+ intptr_t next_temp = 0;
+ for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+ const bool is_allocatable = ((1 << i) & kDartAvailableCpuRegs) != 0;
+ const bool is_input = ((1 << i) & kNonChangeableInputRegs) != 0;
+ if (is_allocatable && !is_input) {
+ summary->set_temp(next_temp++,
+ Location::RegisterLocation(static_cast<Register>(i)));
+ }
+ }
+ }
+
return summary;
}
@@ -2077,6 +2119,14 @@
}
void CreateArrayInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+ if (type_usage_info != nullptr) {
+ const Class& list_class = Class::Handle(
+ compiler->thread()->isolate()->class_table()->At(kArrayCid));
+ RegisterTypeArgumentsUse(compiler->function(), type_usage_info, list_class,
+ element_type()->definition());
+ }
+
// Allocate the array. R10 = length, RBX = element type.
const Register kLengthReg = R10;
const Register kElemTypeReg = RBX;
@@ -5738,6 +5788,13 @@
}
void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ if (ArgumentCount() == 1) {
+ TypeUsageInfo* type_usage_info = compiler->thread()->type_usage_info();
+ if (type_usage_info != nullptr) {
+ RegisterTypeArgumentsUse(compiler->function(), type_usage_info, cls_,
+ ArgumentAt(0));
+ }
+ }
const Code& stub = Code::ZoneHandle(
compiler->zone(), StubCode::GetAllocationStubForClass(cls()));
const StubEntry stub_entry(stub);
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index 9abd019..10d2c09 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -1373,7 +1373,7 @@
// Note that on DBC registers are always essentially spilled so
// we don't need to block anything.
#if !defined(TARGET_ARCH_DBC)
- if (locs->always_calls()) {
+ if (locs->always_calls() && !locs->callee_safe_call()) {
// Expected shape of live range:
//
// i i'
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index 2cf9a45..f6ffbab 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -570,7 +570,8 @@
enum ContainsCall {
kNoCall, // Used registers must be reserved as tmp.
kCall, // Registers have been saved and can be used without reservation.
- kCallOnSlowPath // Used registers must be reserved as tmp.
+ kCallCalleeSafe, // Registers will be saved by the callee.
+ kCallOnSlowPath // Used registers must be reserved as tmp.
};
LocationSummary(Zone* zone,
@@ -651,7 +652,11 @@
}
void SetStackBit(intptr_t index) { stack_bitmap()->Set(index, true); }
- bool always_calls() const { return contains_call_ == kCall; }
+ bool always_calls() const {
+ return contains_call_ == kCall || contains_call_ == kCallCalleeSafe;
+ }
+
+ bool callee_safe_call() const { return contains_call_ == kCallCalleeSafe; }
bool can_call() { return contains_call_ != kNoCall; }
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 684a6c3..a0cb2ef 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -4202,7 +4202,8 @@
if (!target.IsNull() && (target.raw() != parent.raw())) {
DEBUG_ASSERT(Isolate::Current()->HasAttemptedReload());
- if ((target.is_static() != parent.is_static()) || (target.kind() != parent.kind())) {
+ if ((target.is_static() != parent.is_static()) ||
+ (target.kind() != parent.kind())) {
target = Function::null();
}
}
@@ -8327,9 +8328,9 @@
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
- Double& constant = Double::ZoneHandle(
- Z, Double::NewCanonical(
- H.DartString(ReadStringReference()))); // read string reference.
+ Double& constant =
+ Double::ZoneHandle(Z, Double::New(H.DartString(ReadStringReference()),
+ Heap::kOld)); // read string reference.
return Constant(constant);
}
diff --git a/runtime/vm/compiler/method_recognizer.h b/runtime/vm/compiler/method_recognizer.h
index 1203498..afffc77 100644
--- a/runtime/vm/compiler/method_recognizer.h
+++ b/runtime/vm/compiler/method_recognizer.h
@@ -409,24 +409,24 @@
V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 0x62f615e4) \
V(_ByteDataView, setInt8, ByteDataViewSetInt8, 0x6395293e) \
V(_ByteDataView, setUint8, ByteDataViewSetUint8, 0x79979d1f) \
- V(_ByteDataView, setInt16, ByteDataViewSetInt16, 0x57499d9c) \
- V(_ByteDataView, setUint16, ByteDataViewSetUint16, 0x4dd87acb) \
- V(_ByteDataView, setInt32, ByteDataViewSetInt32, 0x57213f62) \
- V(_ByteDataView, setUint32, ByteDataViewSetUint32, 0x5f315c42) \
- V(_ByteDataView, setInt64, ByteDataViewSetInt64, 0x476e7eb8) \
- V(_ByteDataView, setUint64, ByteDataViewSetUint64, 0x6d64f0fa) \
- V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 0x12197195) \
- V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 0x14d20ad7) \
+ V(_ByteDataView, setInt16, ByteDataViewSetInt16, 0x525ec534) \
+ V(_ByteDataView, setUint16, ByteDataViewSetUint16, 0x48eda263) \
+ V(_ByteDataView, setInt32, ByteDataViewSetInt32, 0x523666fa) \
+ V(_ByteDataView, setUint32, ByteDataViewSetUint32, 0x5a4683da) \
+ V(_ByteDataView, setInt64, ByteDataViewSetInt64, 0x4283a650) \
+ V(_ByteDataView, setUint64, ByteDataViewSetUint64, 0x687a1892) \
+ V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 0x7d5784fd) \
+ V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 0x00101e3f) \
V(_ByteDataView, getInt8, ByteDataViewGetInt8, 0x68448b4d) \
V(_ByteDataView, getUint8, ByteDataViewGetUint8, 0x5d68cbf2) \
- V(_ByteDataView, getInt16, ByteDataViewGetInt16, 0x2f4f6115) \
- V(_ByteDataView, getUint16, ByteDataViewGetUint16, 0x10556170) \
- V(_ByteDataView, getInt32, ByteDataViewGetInt32, 0x00435162) \
- V(_ByteDataView, getUint32, ByteDataViewGetUint32, 0x6fd07e56) \
- V(_ByteDataView, getInt64, ByteDataViewGetInt64, 0x3e124984) \
- V(_ByteDataView, getUint64, ByteDataViewGetUint64, 0x2798f8e3) \
- V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 0x77404fe1) \
- V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 0x771585bf) \
+ V(_ByteDataView, getInt16, ByteDataViewGetInt16, 0x691b5ead) \
+ V(_ByteDataView, getUint16, ByteDataViewGetUint16, 0x78b744d8) \
+ V(_ByteDataView, getInt32, ByteDataViewGetInt32, 0x3a0f4efa) \
+ V(_ByteDataView, getUint32, ByteDataViewGetUint32, 0x583261be) \
+ V(_ByteDataView, getInt64, ByteDataViewGetInt64, 0x77de471c) \
+ V(_ByteDataView, getUint64, ByteDataViewGetUint64, 0x0ffadc4b) \
+ V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 0x6a205749) \
+ V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 0x69f58d27) \
V(::, exp, MathExp, 0x32ab9efa) \
V(::, log, MathLog, 0x1ee8f9fc) \
V(::, max, MathMax, 0x377e8889) \
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 8ca2c59..48cc6c3 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -347,7 +347,9 @@
// Platform-independent variants declared for all platforms
EQUAL = EQ,
+ ZERO = EQUAL,
NOT_EQUAL = NE,
+ NOT_ZERO = NOT_EQUAL,
LESS = LT,
LESS_EQUAL = LE,
GREATER_EQUAL = GE,
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 829e3d9..594baf4 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -195,7 +195,9 @@
// Platform-independent variants declared for all platforms
EQUAL = EQ,
+ ZERO = EQUAL,
NOT_EQUAL = NE,
+ NOT_ZERO = NOT_EQUAL,
LESS = LT,
LESS_EQUAL = LE,
GREATER_EQUAL = GE,
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index c003966..fb393bd 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -217,6 +217,7 @@
return strdup("Precompiled runtime requires a precompiled snapshot");
#else
StubCode::InitOnce();
+ Object::FinishInitOnce(vm_isolate_);
// MallocHooks can't be initialized until StubCode has been since stack
// trace generation relies on stub methods that are generated in
// StubCode::InitOnce().
@@ -234,6 +235,7 @@
// Must copy before leaving the zone.
return strdup(error.ToErrorCString());
}
+ Object::FinishInitOnce(vm_isolate_);
#if !defined(PRODUCT)
if (tds.enabled()) {
tds.SetNumArguments(2);
@@ -262,6 +264,7 @@
#else
vm_snapshot_kind_ = Snapshot::kNone;
StubCode::InitOnce();
+ Object::FinishInitOnce(vm_isolate_);
// MallocHooks can't be initialized until StubCode has been since stack
// trace generation relies on stub methods that are generated in
// StubCode::InitOnce().
diff --git a/runtime/vm/handles_impl.h b/runtime/vm/handles_impl.h
index e5b731c..9e2d9f9 100644
--- a/runtime/vm/handles_impl.h
+++ b/runtime/vm/handles_impl.h
@@ -96,7 +96,7 @@
AllocateZoneHandle(Zone* zone) {
#if defined(DEBUG)
Thread* thread = Thread::Current();
- ASSERT(thread->zone() == zone);
+ ASSERT(zone->ContainsNestedZone(thread->zone()));
ASSERT(thread->no_handle_scope_depth() == 0);
#endif // DEBUG
Handles* handles = zone->handles();
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 95a7da0..89186a4 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -12,6 +12,7 @@
#include "vm/object.h"
#include "vm/stub_code.h"
#include "vm/timeline.h"
+#include "vm/type_testing_stubs.h"
namespace dart {
@@ -36,7 +37,7 @@
return offset;
}
-int32_t ImageWriter::GetDataOffsetFor(RawObject* raw_object) {
+uint32_t ImageWriter::GetDataOffsetFor(RawObject* raw_object) {
intptr_t heap_size = raw_object->Size();
intptr_t offset = next_data_offset_;
next_data_offset_ += heap_size;
@@ -239,6 +240,7 @@
Object& owner = Object::Handle(zone);
String& str = String::Handle(zone);
+ TypeTestingStubFinder tts;
for (intptr_t i = 0; i < instructions_.length(); i++) {
const Instructions& insns = *instructions_[i].insns_;
const Code& code = *instructions_[i].code_;
@@ -270,28 +272,41 @@
// 2. Write a label at the entry point.
// Linux's perf uses these labels.
- owner = code.owner();
- if (owner.IsNull()) {
- const char* name = StubCode::NameOfStub(insns.UncheckedEntryPoint());
- assembly_stream_.Print("Precompiled_Stub_%s:\n", name);
- } else if (owner.IsClass()) {
- str = Class::Cast(owner).Name();
- const char* name = str.ToCString();
- EnsureIdentifier(const_cast<char*>(name));
- assembly_stream_.Print("Precompiled_AllocationStub_%s_%" Pd ":\n", name,
- i);
- } else if (owner.IsFunction()) {
- const char* name = Function::Cast(owner).ToQualifiedCString();
- EnsureIdentifier(const_cast<char*>(name));
- assembly_stream_.Print("Precompiled_%s_%" Pd ":\n", name, i);
+ if (code.IsNull()) {
+ const char* name = tts.StubNameFromAddresss(insns.UncheckedEntryPoint());
+ assembly_stream_.Print("Precompiled_%s:\n", name);
} else {
- UNREACHABLE();
+ owner = code.owner();
+ if (owner.IsNull()) {
+ const char* name = StubCode::NameOfStub(insns.UncheckedEntryPoint());
+ if (name != NULL) {
+ assembly_stream_.Print("Precompiled_Stub_%s:\n", name);
+ } else {
+ const char* name =
+ tts.StubNameFromAddresss(insns.UncheckedEntryPoint());
+ assembly_stream_.Print("Precompiled__%s:\n", name);
+ }
+ } else if (owner.IsClass()) {
+ str = Class::Cast(owner).Name();
+ const char* name = str.ToCString();
+ EnsureIdentifier(const_cast<char*>(name));
+ assembly_stream_.Print("Precompiled_AllocationStub_%s_%" Pd ":\n", name,
+ i);
+ } else if (owner.IsFunction()) {
+ const char* name = Function::Cast(owner).ToQualifiedCString();
+ EnsureIdentifier(const_cast<char*>(name));
+ assembly_stream_.Print("Precompiled_%s_%" Pd ":\n", name, i);
+ } else {
+ UNREACHABLE();
+ }
}
#ifdef DART_PRECOMPILER
// Create a label for use by DWARF.
- intptr_t dwarf_index = dwarf_->AddCode(code);
- assembly_stream_.Print(".Lcode%" Pd ":\n", dwarf_index);
+ if (!code.IsNull()) {
+ const intptr_t dwarf_index = dwarf_->AddCode(code);
+ assembly_stream_.Print(".Lcode%" Pd ":\n", dwarf_index);
+ }
#endif
{
@@ -489,7 +504,7 @@
return result;
}
-RawObject* ImageReader::GetObjectAt(int32_t offset) const {
+RawObject* ImageReader::GetObjectAt(uint32_t offset) const {
ASSERT(Utils::IsAligned(offset, kWordSize));
RawObject* result = reinterpret_cast<RawObject*>(
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index ece57a3..5e9fe3d 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -51,7 +51,7 @@
ImageReader(const uint8_t* instructions_buffer, const uint8_t* data_buffer);
RawInstructions* GetInstructionsAt(int32_t offset) const;
- RawObject* GetObjectAt(int32_t offset) const;
+ RawObject* GetObjectAt(uint32_t offset) const;
private:
const uint8_t* instructions_buffer_;
@@ -79,7 +79,7 @@
objects_.Clear();
}
int32_t GetTextOffsetFor(RawInstructions* instructions, RawCode* code);
- int32_t GetDataOffsetFor(RawObject* raw_object);
+ uint32_t GetDataOffsetFor(RawObject* raw_object);
void Write(WriteStream* clustered_stream, bool vm);
intptr_t text_size() const { return next_text_offset_; }
diff --git a/runtime/vm/instructions.h b/runtime/vm/instructions.h
index 0a2e817..e0ec51f 100644
--- a/runtime/vm/instructions.h
+++ b/runtime/vm/instructions.h
@@ -28,6 +28,20 @@
bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj);
+#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
+class TypeTestingStubCallPattern : public ValueObject {
+ public:
+ explicit TypeTestingStubCallPattern(uword pc) : pc_(pc) {}
+
+ intptr_t GetSubtypeTestCachePoolIndex();
+
+ private:
+ const uword pc_;
+};
+
+#endif // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
} // namespace dart
#endif // RUNTIME_VM_INSTRUCTIONS_H_
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index a605542..f62215f 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -285,6 +285,27 @@
return false;
}
+#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
+intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
+ // Calls to the type testing stubs look like:
+ // ldr R3, [PP+idx]
+ // blx R9
+
+ // Ensure the caller of the type testing stub (whose return address is [pc_])
+ // branched via the `blx R9` instruction.
+ ASSERT(*reinterpret_cast<uint32_t*>(pc_ - Instr::kInstrSize) == 0xe12fff39);
+ const uword load_instr_end = pc_ - Instr::kInstrSize;
+
+ Register reg;
+ intptr_t pool_index = -1;
+ InstructionPattern::DecodeLoadWordFromPool(load_instr_end, ®, &pool_index);
+ ASSERT(reg == R3);
+ return pool_index;
+}
+
+#endif // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
} // namespace dart
#endif // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index bfa0a76..f728ffd 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -351,6 +351,27 @@
return bx_lr->InstructionBits() == instruction;
}
+#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
+intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
+ // Calls to the type testing stubs look like:
+ // ldr R3, [PP+idx]
+ // blr R9
+
+ // Ensure the caller of the type testing stub (whose return address is [pc_])
+ // branched via the `blr R9` instruction.
+ ASSERT(*reinterpret_cast<uint32_t*>(pc_ - Instr::kInstrSize) == 0xd63f0120);
+ const uword load_instr_end = pc_ - Instr::kInstrSize;
+
+ Register reg;
+ intptr_t pool_index = -1;
+ InstructionPattern::DecodeLoadWordFromPool(load_instr_end, ®, &pool_index);
+ ASSERT(reg == R3);
+ return pool_index;
+}
+
+#endif // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
} // namespace dart
#endif // defined TARGET_ARCH_ARM64
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index da8a4cb..3c63a75 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -5,6 +5,7 @@
#include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
#if defined(TARGET_ARCH_X64)
+#include "vm/code_patcher.h"
#include "vm/instructions.h"
#include "vm/instructions_x64.h"
@@ -63,6 +64,22 @@
return false;
}
+#if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
+intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
+ const intptr_t kCallPatternSize = 10;
+ static int16_t pattern[kCallPatternSize] = {
+ 0x4d, 0x8b, 0x8f, -1, -1, -1, -1, // movq R9, [PP + offs]
+ 0xff, 0x53, 0x07 // callq [RBX+ 0x7]
+ };
+ const uword start = pc_ - kCallPatternSize;
+ ASSERT(MatchesPattern(start, pattern, kCallPatternSize));
+
+ return IndexFromPPLoad(start + 3);
+}
+
+#endif // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+
} // namespace dart
#endif // defined TARGET_ARCH_X64
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 10a99dc..a297180 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -42,12 +42,14 @@
#include "vm/runtime_entry.h"
#include "vm/scopes.h"
#include "vm/stack_frame.h"
+#include "vm/stub_code.h"
#include "vm/symbols.h"
#include "vm/tags.h"
#include "vm/thread_registry.h"
#include "vm/timeline.h"
#include "vm/timer.h"
#include "vm/type_table.h"
+#include "vm/type_testing_stubs.h"
#include "vm/unicode.h"
#include "vm/weak_code.h"
#include "vm/zone_text_buffer.h"
@@ -999,6 +1001,22 @@
ASSERT(extractor_parameter_names_->IsArray());
}
+void Object::FinishInitOnce(Isolate* isolate) {
+ // The type testing stubs we initialize in AbstractType objects for the
+ // canonical type of kDynamicCid/kVoidCid/kVectorCid need to be set in this
+ // method, which is called after StubCode::InitOnce().
+ Instructions& instr = Instructions::Handle();
+
+ instr = TypeTestingStubGenerator::DefaultCodeForType(*dynamic_type_);
+ dynamic_type_->SetTypeTestingStub(instr);
+
+ instr = TypeTestingStubGenerator::DefaultCodeForType(*void_type_);
+ void_type_->SetTypeTestingStub(instr);
+
+ instr = TypeTestingStubGenerator::DefaultCodeForType(*vector_type_);
+ vector_type_->SetTypeTestingStub(instr);
+}
+
// An object visitor which will mark all visited objects. This is used to
// premark all objects in the vm_isolate_ heap. Also precalculates hash
// codes so that we can get the identity hash code of objects in the read-
@@ -1020,11 +1038,7 @@
if (!obj->IsFreeListElement()) {
ASSERT(obj->IsVMHeapObject());
obj->SetMarkBitUnsynchronized();
- if (obj->IsStringInstance()) {
- RawString* str = reinterpret_cast<RawString*>(obj);
- intptr_t hash = String::Hash(str);
- String::SetCachedHash(str, hash);
- }
+ Object::FinalizeReadOnlyObject(obj);
#if defined(HASH_IN_OBJECT_HEADER)
// These objects end up in the read-only VM isolate which is shared
// between isolates, so we have to prepopulate them with identity hash
@@ -1130,6 +1144,65 @@
}
}
+void Object::FinalizeReadOnlyObject(RawObject* object) {
+ NoSafepointScope no_safepoint;
+ intptr_t cid = object->GetClassId();
+ if (cid == kOneByteStringCid) {
+ RawOneByteString* str = static_cast<RawOneByteString*>(object);
+ if (String::GetCachedHash(str) == 0) {
+ intptr_t hash = String::Hash(str);
+ String::SetCachedHash(str, hash);
+ }
+ intptr_t size = OneByteString::UnroundedSize(str);
+ ASSERT(size <= str->Size());
+ memset(reinterpret_cast<void*>(RawObject::ToAddr(str) + size), 0,
+ str->Size() - size);
+ } else if (cid == kTwoByteStringCid) {
+ RawTwoByteString* str = static_cast<RawTwoByteString*>(object);
+ if (String::GetCachedHash(str) == 0) {
+ intptr_t hash = String::Hash(str);
+ String::SetCachedHash(str, hash);
+ }
+ ASSERT(String::GetCachedHash(str) != 0);
+ intptr_t size = TwoByteString::UnroundedSize(str);
+ ASSERT(size <= str->Size());
+ memset(reinterpret_cast<void*>(RawObject::ToAddr(str) + size), 0,
+ str->Size() - size);
+ } else if (cid == kExternalOneByteStringCid) {
+ RawExternalOneByteString* str =
+ static_cast<RawExternalOneByteString*>(object);
+ if (String::GetCachedHash(str) == 0) {
+ intptr_t hash = String::Hash(str);
+ String::SetCachedHash(str, hash);
+ }
+ } else if (cid == kExternalTwoByteStringCid) {
+ RawExternalTwoByteString* str =
+ static_cast<RawExternalTwoByteString*>(object);
+ if (String::GetCachedHash(str) == 0) {
+ intptr_t hash = String::Hash(str);
+ String::SetCachedHash(str, hash);
+ }
+ } else if (cid == kCodeSourceMapCid) {
+ RawCodeSourceMap* map = CodeSourceMap::RawCast(object);
+ intptr_t size = CodeSourceMap::UnroundedSize(map);
+ ASSERT(size <= map->Size());
+ memset(reinterpret_cast<void*>(RawObject::ToAddr(map) + size), 0,
+ map->Size() - size);
+ } else if (cid == kStackMapCid) {
+ RawStackMap* map = StackMap::RawCast(object);
+ intptr_t size = StackMap::UnroundedSize(map);
+ ASSERT(size <= map->Size());
+ memset(reinterpret_cast<void*>(RawObject::ToAddr(map) + size), 0,
+ map->Size() - size);
+ } else if (cid == kPcDescriptorsCid) {
+ RawPcDescriptors* desc = PcDescriptors::RawCast(object);
+ intptr_t size = PcDescriptors::UnroundedSize(desc);
+ ASSERT(size <= desc->Size());
+ memset(reinterpret_cast<void*>(RawObject::ToAddr(desc) + size), 0,
+ desc->Size() - size);
+ }
+}
+
void Object::set_vm_isolate_snapshot_object_table(const Array& table) {
ASSERT(Isolate::Current() == Dart::vm_isolate());
*vm_isolate_snapshot_object_table_ = table.raw();
@@ -16944,6 +17017,19 @@
return "AbstractType";
}
+void AbstractType::SetTypeTestingStub(const Instructions& instr) const {
+ if (instr.IsNull()) {
+ // This only happens during bootstrapping when creating Type objects before
+ // we have the instructions.
+ ASSERT(type_class_id() == kDynamicCid || type_class_id() == kVoidCid ||
+ type_class_id() == kVectorCid);
+ StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_, 0);
+ } else {
+ StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_,
+ instr.UncheckedEntryPoint());
+ }
+}
+
RawType* Type::NullType() {
return Isolate::Current()->object_store()->null_type();
}
@@ -17852,7 +17938,8 @@
const TypeArguments& arguments,
TokenPosition token_pos,
Heap::Space space) {
- const Type& result = Type::Handle(Type::New(space));
+ Zone* Z = Thread::Current()->zone();
+ const Type& result = Type::Handle(Z, Type::New(space));
if (clazz.IsClass()) {
result.set_type_class(Class::Cast(clazz));
} else {
@@ -17862,6 +17949,9 @@
result.SetHash(0);
result.set_token_pos(token_pos);
result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated);
+
+ result.SetTypeTestingStub(Instructions::Handle(
+ Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
return result.raw();
}
@@ -17888,7 +17978,8 @@
const char* class_name;
if (HasResolvedTypeClass()) {
cls = type_class();
- class_name = String::Handle(zone, cls.Name()).ToCString();
+ const String& name = String::Handle(zone, cls.Name());
+ class_name = name.IsNull() ? "<null>" : name.ToCString();
} else {
class_name = UnresolvedClass::Handle(zone, unresolved_class()).ToCString();
}
@@ -17971,6 +18062,9 @@
space);
ASSERT(!instantiated_ref_type.IsTypeRef());
instantiated_type_ref.set_type(instantiated_ref_type);
+
+ instantiated_type_ref.SetTypeTestingStub(Instructions::Handle(
+ TypeTestingStubGenerator::DefaultCodeForType(instantiated_type_ref)));
return instantiated_type_ref.raw();
}
@@ -18056,8 +18150,12 @@
}
RawTypeRef* TypeRef::New(const AbstractType& type) {
- const TypeRef& result = TypeRef::Handle(TypeRef::New());
+ Zone* Z = Thread::Current()->zone();
+ const TypeRef& result = TypeRef::Handle(Z, TypeRef::New());
result.set_type(type);
+
+ result.SetTypeTestingStub(Instructions::Handle(
+ Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
return result.raw();
}
@@ -18359,7 +18457,8 @@
const AbstractType& bound,
TokenPosition token_pos) {
ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull());
- const TypeParameter& result = TypeParameter::Handle(TypeParameter::New());
+ Zone* Z = Thread::Current()->zone();
+ const TypeParameter& result = TypeParameter::Handle(Z, TypeParameter::New());
result.set_parameterized_class(parameterized_class);
result.set_parameterized_function(parameterized_function);
result.set_index(index);
@@ -18369,6 +18468,9 @@
result.set_token_pos(token_pos);
result.StoreNonPointer(&result.raw_ptr()->type_state_,
RawTypeParameter::kAllocated);
+
+ result.SetTypeTestingStub(Instructions::Handle(
+ Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
return result.raw();
}
@@ -18626,11 +18728,15 @@
RawBoundedType* BoundedType::New(const AbstractType& type,
const AbstractType& bound,
const TypeParameter& type_parameter) {
- const BoundedType& result = BoundedType::Handle(BoundedType::New());
+ Zone* Z = Thread::Current()->zone();
+ const BoundedType& result = BoundedType::Handle(Z, BoundedType::New());
result.set_type(type);
result.set_bound(bound);
result.SetHash(0);
result.set_type_parameter(type_parameter);
+
+ result.SetTypeTestingStub(Instructions::Handle(
+ Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
return result.raw();
}
@@ -18701,9 +18807,13 @@
RawMixinAppType* MixinAppType::New(const AbstractType& super_type,
const Array& mixin_types) {
- const MixinAppType& result = MixinAppType::Handle(MixinAppType::New());
+ Zone* Z = Thread::Current()->zone();
+ const MixinAppType& result = MixinAppType::Handle(Z, MixinAppType::New());
result.set_super_type(super_type);
result.set_mixin_types(mixin_types);
+
+ result.SetTypeTestingStub(Instructions::Handle(
+ Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
return result.raw();
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 0323ff6..de0a01a 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -42,9 +42,10 @@
class Assembler;
class Closure;
class Code;
-class DisassemblyFormatter;
class DeoptInstr;
+class DisassemblyFormatter;
class FinalizablePersistentHandle;
+class HierarchyInfo;
class LocalScope;
class CodeStatistics;
@@ -556,7 +557,9 @@
// Initialize the VM isolate.
static void InitNull(Isolate* isolate);
static void InitOnce(Isolate* isolate);
+ static void FinishInitOnce(Isolate* isolate);
static void FinalizeVMIsolate(Isolate* isolate);
+ static void FinalizeReadOnlyObject(RawObject* object);
// Initialize a new isolate either from a Kernel IR, from source, or from a
// snapshot.
@@ -4354,6 +4357,12 @@
static const intptr_t kBytesPerElement = 1;
static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement;
+ static intptr_t UnroundedSize(RawPcDescriptors* desc) {
+ return UnroundedSize(desc->ptr()->length_);
+ }
+ static intptr_t UnroundedSize(intptr_t len) {
+ return sizeof(RawPcDescriptors) + len;
+ }
static intptr_t InstanceSize() {
ASSERT(sizeof(RawPcDescriptors) ==
OFFSET_OF_RETURNED_VALUE(RawPcDescriptors, data));
@@ -4361,7 +4370,7 @@
}
static intptr_t InstanceSize(intptr_t len) {
ASSERT(0 <= len && len <= kMaxElements);
- return RoundedAllocationSize(sizeof(RawPcDescriptors) + len);
+ return RoundedAllocationSize(UnroundedSize(len));
}
static RawPcDescriptors* New(GrowableArray<uint8_t>* delta_encoded_data);
@@ -4476,6 +4485,12 @@
static const intptr_t kBytesPerElement = 1;
static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement;
+ static intptr_t UnroundedSize(RawCodeSourceMap* map) {
+ return UnroundedSize(map->ptr()->length_);
+ }
+ static intptr_t UnroundedSize(intptr_t len) {
+ return sizeof(RawCodeSourceMap) + len;
+ }
static intptr_t InstanceSize() {
ASSERT(sizeof(RawCodeSourceMap) ==
OFFSET_OF_RETURNED_VALUE(RawCodeSourceMap, data));
@@ -4483,7 +4498,7 @@
}
static intptr_t InstanceSize(intptr_t len) {
ASSERT(0 <= len && len <= kMaxElements);
- return RoundedAllocationSize(sizeof(RawCodeSourceMap) + len);
+ return RoundedAllocationSize(UnroundedSize(len));
}
static RawCodeSourceMap* New(intptr_t length);
@@ -4542,15 +4557,20 @@
static const intptr_t kMaxLengthInBytes = kSmiMax;
+ static intptr_t UnroundedSize(RawStackMap* map) {
+ return UnroundedSize(map->ptr()->length_);
+ }
+ static intptr_t UnroundedSize(intptr_t len) {
+ // The stackmap payload is in an array of bytes.
+ intptr_t payload_size = Utils::RoundUp(len, kBitsPerByte) / kBitsPerByte;
+ return sizeof(RawStackMap) + payload_size;
+ }
static intptr_t InstanceSize() {
ASSERT(sizeof(RawStackMap) == OFFSET_OF_RETURNED_VALUE(RawStackMap, data));
return 0;
}
static intptr_t InstanceSize(intptr_t length) {
- ASSERT(length >= 0);
- // The stackmap payload is in an array of bytes.
- intptr_t payload_size = Utils::RoundUp(length, kBitsPerByte) / kBitsPerByte;
- return RoundedAllocationSize(sizeof(RawStackMap) + payload_size);
+ return RoundedAllocationSize(UnroundedSize(length));
}
static RawStackMap* New(intptr_t pc_offset,
BitmapBuilder* bmap,
@@ -4642,6 +4662,9 @@
}
RawInstructions* instructions() const { return raw_ptr()->instructions_; }
+ static RawInstructions* InstructionsOf(const RawCode* code) {
+ return code->ptr()->instructions_;
+ }
static intptr_t saved_instructions_offset() {
return OFFSET_OF(RawCode, instructions_);
@@ -6115,6 +6138,16 @@
const TypeArguments& instantiator_type_args,
const TypeArguments& function_type_args);
+ static intptr_t type_test_stub_entry_point_offset() {
+ return OFFSET_OF(RawAbstractType, type_test_stub_entry_point_);
+ }
+
+ uword type_test_stub_entry_point() const {
+ return raw_ptr()->type_test_stub_entry_point_;
+ }
+
+ void SetTypeTestingStub(const Instructions& instr) const;
+
private:
// Check the 'is subtype of' or 'is more specific than' relationship.
bool TypeTest(TypeTestKind test_kind,
@@ -6154,6 +6187,12 @@
static intptr_t type_class_id_offset() {
return OFFSET_OF(RawType, type_class_id_);
}
+ static intptr_t arguments_offset() {
+ return OFFSET_OF(RawType, type_class_id_);
+ }
+ static intptr_t type_state_offset() {
+ return OFFSET_OF(RawType, type_state_);
+ }
static intptr_t hash_offset() { return OFFSET_OF(RawType, hash_); }
virtual bool IsFinalized() const {
return (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
@@ -6305,6 +6344,8 @@
// Note that the cycle always involves type arguments.
class TypeRef : public AbstractType {
public:
+ static intptr_t type_offset() { return OFFSET_OF(RawTypeRef, type_); }
+
virtual bool IsFinalized() const {
const AbstractType& ref_type = AbstractType::Handle(type());
return !ref_type.IsNull() && ref_type.IsFinalized();
@@ -7354,12 +7395,17 @@
return OFFSET_OF_RETURNED_VALUE(RawOneByteString, data);
}
+ static intptr_t UnroundedSize(RawOneByteString* str) {
+ return UnroundedSize(Smi::Value(str->ptr()->length_));
+ }
+ static intptr_t UnroundedSize(intptr_t len) {
+ return sizeof(RawOneByteString) + (len * kBytesPerElement);
+ }
static intptr_t InstanceSize() {
ASSERT(sizeof(RawOneByteString) ==
OFFSET_OF_RETURNED_VALUE(RawOneByteString, data));
return 0;
}
-
static intptr_t InstanceSize(intptr_t len) {
ASSERT(sizeof(RawOneByteString) == String::kSizeofRawString);
ASSERT(0 <= len && len <= kMaxElements);
@@ -7369,8 +7415,7 @@
// memory allocated for the raw string.
if (len == 0) return InstanceSize(1);
#endif
- return String::RoundedAllocationSize(sizeof(RawOneByteString) +
- (len * kBytesPerElement));
+ return String::RoundedAllocationSize(UnroundedSize(len));
}
static RawOneByteString* New(intptr_t len, Heap::Space space);
@@ -7498,12 +7543,17 @@
return OFFSET_OF_RETURNED_VALUE(RawTwoByteString, data);
}
+ static intptr_t UnroundedSize(RawTwoByteString* str) {
+ return UnroundedSize(Smi::Value(str->ptr()->length_));
+ }
+ static intptr_t UnroundedSize(intptr_t len) {
+ return sizeof(RawTwoByteString) + (len * kBytesPerElement);
+ }
static intptr_t InstanceSize() {
ASSERT(sizeof(RawTwoByteString) ==
OFFSET_OF_RETURNED_VALUE(RawTwoByteString, data));
return 0;
}
-
static intptr_t InstanceSize(intptr_t len) {
ASSERT(sizeof(RawTwoByteString) == String::kSizeofRawString);
ASSERT(0 <= len && len <= kMaxElements);
@@ -7511,8 +7561,7 @@
// If we don't pad, then the external string object does not fit in the
// memory allocated for the raw string.
if (len == 0) return InstanceSize(1);
- return String::RoundedAllocationSize(sizeof(RawTwoByteString) +
- (len * kBytesPerElement));
+ return String::RoundedAllocationSize(UnroundedSize(len));
}
static RawTwoByteString* New(intptr_t len, Heap::Space space);
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 53b8716..891760f 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -125,6 +125,7 @@
R_(Code, megamorphic_miss_code) \
R_(Function, megamorphic_miss_function) \
RW(Array, obfuscation_map) \
+ RW(GrowableObjectArray, type_testing_stubs) \
RW(GrowableObjectArray, changed_in_last_reload) \
// Please remember the last entry must be referred in the 'to' function below.
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index c82c8cd..de84a19 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1797,11 +1797,13 @@
kFinalizedInstantiated, // Instantiated type ready for use.
kFinalizedUninstantiated, // Uninstantiated type ready for use.
};
+ uword type_test_stub_entry_point_; // Accessed from generated code.
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(AbstractType);
friend class ObjectStore;
+ friend class StubCode;
};
class RawType : public RawAbstractType {
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index e738756..dd41cf1 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -218,6 +218,9 @@
type.set_token_pos(TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
type.set_type_state(reader->Read<int8_t>());
+ // Read the code object for the type testing stub and set its entrypoint.
+ reader->EnqueueTypePostprocessing(type);
+
// Set all the object fields.
READ_OBJECT_FIELDS(type, type.raw()->from(), type.raw()->to(), kAsReference);
@@ -294,6 +297,9 @@
TypeRef& type_ref = TypeRef::ZoneHandle(reader->zone(), TypeRef::New());
reader->AddBackRef(object_id, &type_ref, kIsDeserialized);
+ // Read the code object for the type testing stub and set its entrypoint.
+ reader->EnqueueTypePostprocessing(type_ref);
+
// Set all the object fields.
READ_OBJECT_FIELDS(type_ref, type_ref.raw()->from(), type_ref.raw()->to(),
kAsReference);
@@ -337,6 +343,9 @@
type_parameter.set_index(reader->Read<int16_t>());
type_parameter.set_type_state(reader->Read<int8_t>());
+ // Read the code object for the type testing stub and set its entrypoint.
+ reader->EnqueueTypePostprocessing(type_parameter);
+
// Set all the object fields.
READ_OBJECT_FIELDS(type_parameter, type_parameter.raw()->from(),
type_parameter.raw()->to(), kAsReference);
@@ -392,6 +401,9 @@
BoundedType::ZoneHandle(reader->zone(), BoundedType::New());
reader->AddBackRef(object_id, &bounded_type, kIsDeserialized);
+ // Read the code object for the type testing stub and set its entrypoint.
+ reader->EnqueueTypePostprocessing(bounded_type);
+
// Set all the object fields.
READ_OBJECT_FIELDS(bounded_type, bounded_type.raw()->from(),
bounded_type.raw()->to(), kAsReference);
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 9b99bed..4838da1 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -14,6 +14,7 @@
#include "vm/deopt_instructions.h"
#include "vm/exceptions.h"
#include "vm/flags.h"
+#include "vm/instructions.h"
#include "vm/kernel_isolate.h"
#include "vm/message.h"
#include "vm/message_handler.h"
@@ -665,9 +666,14 @@
TypeArguments::CheckedHandle(zone, arguments.ArgAt(2));
const TypeArguments& function_type_arguments =
TypeArguments::CheckedHandle(zone, arguments.ArgAt(3));
- const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(4));
- const SubtypeTestCache& cache =
- SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(5));
+ String& dst_name = String::Handle(zone);
+ dst_name ^= arguments.ArgAt(4);
+ ASSERT(dst_name.IsNull() || dst_name.IsString());
+
+ SubtypeTestCache& cache = SubtypeTestCache::Handle(zone);
+ cache ^= arguments.ArgAt(5);
+ ASSERT(cache.IsNull() || cache.IsSubtypeTestCache());
+
ASSERT(!dst_type.IsMalformed()); // Already checked in code generator.
ASSERT(!dst_type.IsMalbounded()); // Already checked in code generator.
ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
@@ -700,10 +706,85 @@
ASSERT(isolate->type_checks());
bound_error_message = String::New(bound_error.ToErrorCString());
}
+ if (dst_name.IsNull()) {
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32) && \
+ (defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME))
+ // Grab the [dst_name] from the pool. It's stored at one pool slot after
+ // the subtype-test-cache.
+ DartFrameIterator iterator(thread,
+ StackFrameIterator::kNoCrossThreadIteration);
+ StackFrame* caller_frame = iterator.NextFrame();
+ const Code& caller_code =
+ Code::Handle(zone, caller_frame->LookupDartCode());
+ const ObjectPool& pool =
+ ObjectPool::Handle(zone, caller_code.object_pool());
+ TypeTestingStubCallPattern tts_pattern(caller_frame->pc());
+ const intptr_t stc_pool_idx = tts_pattern.GetSubtypeTestCachePoolIndex();
+ const intptr_t dst_name_idx = stc_pool_idx + 1;
+ dst_name ^= pool.ObjectAt(dst_name_idx);
+#else
+ UNREACHABLE();
+#endif
+ }
+
Exceptions::CreateAndThrowTypeError(location, src_type, dst_type, dst_name,
bound_error_message);
UNREACHABLE();
}
+
+ if (cache.IsNull()) {
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32) && \
+ (defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME))
+
+#if defined(DART_PRECOMPILER)
+ if (FLAG_precompiled_mode) {
+#endif // defined(DART_PRECOMPILER)
+
+ // We lazily create [SubtypeTestCache] for those call sites which actually
+ // need one and will patch the pool entry.
+ DartFrameIterator iterator(thread,
+ StackFrameIterator::kNoCrossThreadIteration);
+ StackFrame* caller_frame = iterator.NextFrame();
+ const Code& caller_code =
+ Code::Handle(zone, caller_frame->LookupDartCode());
+ const ObjectPool& pool =
+ ObjectPool::Handle(zone, caller_code.object_pool());
+ TypeTestingStubCallPattern tts_pattern(caller_frame->pc());
+ const intptr_t stc_pool_idx = tts_pattern.GetSubtypeTestCachePoolIndex();
+
+ // The pool entry must be initialized to `null` when we patch it.
+ ASSERT(pool.ObjectAt(stc_pool_idx) == Object::null());
+ cache = SubtypeTestCache::New();
+ pool.SetObjectAt(stc_pool_idx, cache);
+
+#if defined(DART_PRECOMPILER)
+ }
+#endif // defined(DART_PRECOMPILER)
+
+#else
+ // WARNING: If we ever come here, it's a really bad sign, because it means
+ // that there was a type test, which generated code could not handle but we
+ // have no subtype cache. Which means that this successfully-passing type
+ // check will always go to runtime.
+ //
+ // Currently there is one known case when this happens:
+ //
+ // The [FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest] is
+ // handling type checks against int/num specially: It generates a number of
+ // class-id checks. Unfortunately it handles only normal implementations of
+ // 'int', such as kSmiCid, kMintCid, kBigintCid. It will signal that there
+ // is no subtype-cache necessary on that call site, because all integer
+ // types have been handled.
+ //
+ // -> Though this is not true, due to (from runtime/lib/array_patch.dart):
+ //
+ // class _GrowableArrayMarker implements int { }
+ //
+ // Because of this, we cannot have an `UNREACHABLE()` here, but rather just
+ // have a NOP and return `true`, to signal the type check passed.
+#endif // defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME)
+ }
+
UpdateTypeTestCache(src_instance, dst_type, instantiator_type_arguments,
function_type_arguments, Bool::True(), cache);
arguments.SetReturn(src_instance);
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 1b91df8..447fbf4 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -15,8 +15,10 @@
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/snapshot_ids.h"
+#include "vm/stub_code.h"
#include "vm/symbols.h"
#include "vm/timeline.h"
+#include "vm/type_testing_stubs.h"
#include "vm/version.h"
// We currently only expect the Dart mutator to read snapshots.
@@ -189,6 +191,7 @@
heap_(isolate()->heap()),
old_space_(thread_->isolate()->heap()->old_space()),
cls_(Class::Handle(zone_)),
+ code_(Code::Handle(zone_)),
obj_(Object::Handle(zone_)),
pobj_(PassiveObject::Handle(zone_)),
array_(Array::Handle(zone_)),
@@ -208,6 +211,7 @@
? Object::vm_isolate_snapshot_object_table().Length()
: 0),
backward_references_(backward_refs),
+ types_to_postprocess_(GrowableObjectArray::Handle(zone_)),
objects_to_rehash_(GrowableObjectArray::Handle(zone_)) {}
RawObject* SnapshotReader::ReadObject() {
@@ -215,6 +219,7 @@
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
objects_to_rehash_ = GrowableObjectArray::New(HEAP_SPACE(kind_));
+ types_to_postprocess_ = GrowableObjectArray::New(HEAP_SPACE(kind_));
PassiveObject& obj =
PassiveObject::Handle(zone(), ReadObjectImpl(kAsInlinedObject));
@@ -234,6 +239,7 @@
} else {
result = obj.raw();
}
+ RunDelayedTypePostprocessing();
const Object& ok = Object::Handle(zone_, RunDelayedRehashingOfMaps());
objects_to_rehash_ = GrowableObjectArray::null();
if (!ok.IsNull()) {
@@ -248,6 +254,22 @@
}
}
+void SnapshotReader::EnqueueTypePostprocessing(const AbstractType& type) {
+ types_to_postprocess_.Add(type, HEAP_SPACE(kind_));
+}
+
+void SnapshotReader::RunDelayedTypePostprocessing() {
+ if (types_to_postprocess_.Length() > 0) {
+ AbstractType& type = AbstractType::Handle();
+ Instructions& instr = Instructions::Handle();
+ for (intptr_t i = 0; i < types_to_postprocess_.Length(); ++i) {
+ type ^= types_to_postprocess_.At(i);
+ instr = TypeTestingStubGenerator::DefaultCodeForType(type);
+ type.SetTypeTestingStub(instr);
+ }
+ }
+}
+
void SnapshotReader::EnqueueRehashingOfMap(const LinkedHashMap& map) {
objects_to_rehash_.Add(map, HEAP_SPACE(kind_));
}
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 44cb6db..6dd74d4 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -326,6 +326,7 @@
PassiveObject* PassiveObjectHandle() { return &pobj_; }
Array* ArrayHandle() { return &array_; }
Class* ClassHandle() { return &cls_; }
+ Code* CodeHandle() { return &code_; }
String* StringHandle() { return &str_; }
AbstractType* TypeHandle() { return &type_; }
TypeArguments* TypeArgumentsHandle() { return &type_arguments_; }
@@ -371,6 +372,9 @@
PageSpace* old_space() const { return old_space_; }
private:
+ void EnqueueTypePostprocessing(const AbstractType& type);
+ void RunDelayedTypePostprocessing();
+
void EnqueueRehashingOfMap(const LinkedHashMap& map);
RawObject* RunDelayedRehashingOfMaps();
@@ -434,6 +438,7 @@
Heap* heap_; // Heap of the current isolate.
PageSpace* old_space_; // Old space of the current isolate.
Class& cls_; // Temporary Class handle.
+ Code& code_; // Temporary Code handle.
Object& obj_; // Temporary Object handle.
PassiveObject& pobj_; // Temporary PassiveObject handle.
Array& array_; // Temporary Array handle.
@@ -450,6 +455,7 @@
UnhandledException& error_; // Error handle.
intptr_t max_vm_isolate_object_id_;
ZoneGrowableArray<BackRefNode>* backward_references_;
+ GrowableObjectArray& types_to_postprocess_;
GrowableObjectArray& objects_to_rehash_;
friend class ApiError;
@@ -770,6 +776,8 @@
friend class RawSubtypeTestCache;
friend class RawTokenStream;
friend class RawType;
+ friend class RawTypeRef;
+ friend class RawBoundedType;
friend class RawTypeArguments;
friend class RawTypeParameter;
friend class RawUserTag;
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 9bd84f1..a664808 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -82,14 +82,8 @@
void StubCode::VisitObjectPointers(ObjectPointerVisitor* visitor) {}
bool StubCode::HasBeenInitialized() {
-#if !defined(TARGET_ARCH_DBC)
- // Use JumpToHandler and InvokeDart as canaries.
- const StubEntry* entry_1 = StubCode::JumpToFrame_entry();
- const StubEntry* entry_2 = StubCode::InvokeDartCode_entry();
- return (entry_1 != NULL) && (entry_2 != NULL);
-#else
- return true;
-#endif
+ // Use AsynchronousGapMarker as canary.
+ return StubCode::AsynchronousGapMarker_entry() != NULL;
}
bool StubCode::InInvocationStub(uword pc) {
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 0ef2edc..4fd3d6a 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -67,6 +67,11 @@
V(Subtype1TestCache) \
V(Subtype2TestCache) \
V(Subtype4TestCache) \
+ V(DefaultTypeTest) \
+ V(TopTypeTypeTest) \
+ V(TypeRefTypeTest) \
+ V(UnreachableTypeTest) \
+ V(SlowTypeTest) \
V(CallClosureNoSuchMethod) \
V(FrameAwaitingMaterialization) \
V(AsynchronousGapMarker)
@@ -82,6 +87,11 @@
V(Deoptimize) \
V(DeoptimizeLazyFromReturn) \
V(DeoptimizeLazyFromThrow) \
+ V(DefaultTypeTest) \
+ V(TopTypeTypeTest) \
+ V(TypeRefTypeTest) \
+ V(UnreachableTypeTest) \
+ V(SlowTypeTest) \
V(FrameAwaitingMaterialization) \
V(AsynchronousGapMarker)
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 9b9ca0b..8f51b9f 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
#include "vm/globals.h"
+
#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/compiler/assembler/assembler.h"
@@ -12,11 +13,12 @@
#include "vm/dart_entry.h"
#include "vm/heap.h"
#include "vm/instructions.h"
+#include "vm/isolate.h"
#include "vm/object_store.h"
#include "vm/runtime_entry.h"
#include "vm/stack_frame.h"
-#include "vm/stub_code.h"
#include "vm/tags.h"
+#include "vm/type_testing_stubs.h"
#define __ assembler->
@@ -1726,6 +1728,9 @@
// R2: instantiator type arguments (only if n == 4, can be raw_null).
// R1: function type arguments (only if n == 4, can be raw_null).
// R3: SubtypeTestCache.
+//
+// Preserves R0/R2
+//
// Result in R1: null -> not found, otherwise result (true or false).
static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
ASSERT((n == 1) || (n == 2) || (n == 4));
@@ -1838,6 +1843,206 @@
GenerateSubtypeNTestCacheStub(assembler, 4);
}
+// Used to test whether a given value is of a given type (different variants,
+// all have the same calling convention).
+//
+// Inputs:
+// - R0 : instance to test against.
+// - R2 : instantiator type arguments (if needed).
+// - R1 : function type arguments (if needed).
+//
+// - R3 : subtype test cache.
+//
+// - R8 : type to test against.
+// - R4 : name of destination variable.
+//
+// Preserves R0/R2.
+//
+// Note of warning: The caller will not populate CODE_REG and we have therefore
+// no access to the pool.
+void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
+ Label done;
+
+ const Register kInstanceReg = R0;
+ // Fast case for 'null'.
+ __ CompareObject(kInstanceReg, Object::null_object());
+ __ BranchIf(EQUAL, &done);
+
+ __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+ __ ldr(R9, FieldAddress(CODE_REG, Code::entry_point_offset()));
+ __ bx(R9);
+
+ __ Bind(&done);
+ __ Ret();
+}
+
+void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+ __ Ret();
+}
+
+void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+ const Register kTypeRefReg = R8;
+
+ // We dereference the TypeRef and tail-call to it's type testing stub.
+ __ ldr(kTypeRefReg, FieldAddress(kTypeRefReg, TypeRef::type_offset()));
+ __ ldr(R9, FieldAddress(kTypeRefReg,
+ AbstractType::type_test_stub_entry_point_offset()));
+ __ bx(R9);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const Type& type,
+ const Class& type_class) {
+ const Register kInstanceReg = R0;
+ const Register kClassIdReg = R9;
+
+ BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
+ kInstanceReg, kClassIdReg);
+
+ __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+ __ ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
+ __ bx(TMP);
+}
+
+void TypeTestingStubGenerator::
+ BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
+ HierarchyInfo* hi,
+ const Class& type_class,
+ const TypeArguments& tp,
+ const TypeArguments& ta) {
+ const Register kInstanceReg = R0;
+ const Register kInstanceTypeArguments = NOTFP;
+ const Register kClassIdReg = R9;
+
+ BuildOptimizedSubclassRangeCheckWithTypeArguments(
+ assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
+ kInstanceTypeArguments);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const AbstractType& type_arg,
+ intptr_t type_param_value_offset_i,
+ Label* check_failed) {
+ const Register kInstantiatorTypeArgumentsReg = R2;
+ const Register kFunctionTypeArgumentsReg = R1;
+ const Register kInstanceTypeArguments = NOTFP;
+
+ const Register kClassIdReg = R9;
+ const Register kOwnTypeArgumentValue = TMP;
+
+ BuildOptimizedTypeArgumentValueCheck(
+ assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
+ kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
+ kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
+}
+
+void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+ __ Breakpoint();
+}
+
+void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
+ Label done, call_runtime;
+
+ const Register kInstanceReg = R0;
+ const Register kInstantiatorTypeArgumentsReg = R2;
+ const Register kFunctionTypeArgumentsReg = R1;
+ const Register kDstTypeReg = R8;
+ const Register kSubtypeTestCacheReg = R3;
+
+ __ EnterStubFrame();
+
+#ifdef DEBUG
+ // Guaranteed by caller.
+ Label no_error;
+ __ CompareObject(kInstanceReg, Object::null_object());
+ __ BranchIf(NOT_EQUAL, &no_error);
+ __ Breakpoint();
+ __ Bind(&no_error);
+#endif
+
+ // Need to handle slow cases of [Smi]s here because the
+ // [SubtypeTestCache]-based stubs do not handle [Smi]s.
+ Label non_smi_value;
+ __ BranchIfSmi(kInstanceReg, &call_runtime);
+
+ // If the subtype-cache is null, it needs to be lazily-created by the runtime.
+ __ CompareObject(kSubtypeTestCacheReg, Object::null_object());
+ __ BranchIf(EQUAL, &call_runtime);
+
+ const Register kTmp = NOTFP;
+
+ // If this is not a [Type] object, we'll go to the runtime.
+ Label is_simple, is_instantiated, is_uninstantiated;
+ __ LoadClassId(kTmp, kDstTypeReg);
+ __ cmp(kTmp, Operand(kTypeCid));
+ __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+
+ // Check whether this [Type] is instantiated/uninstantiated.
+ __ ldrb(kTmp, FieldAddress(kDstTypeReg, Type::type_state_offset()));
+ __ cmp(kTmp, Operand(RawType::kFinalizedInstantiated));
+ __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+ // Fall through to &is_instantiated
+
+ const intptr_t kRegsToSave = (1 << kSubtypeTestCacheReg) |
+ (1 << kDstTypeReg) |
+ (1 << kFunctionTypeArgumentsReg);
+
+ __ Bind(&is_instantiated);
+ {
+ __ PushList(kRegsToSave);
+ __ BranchLink(*StubCode::Subtype2TestCache_entry());
+ __ CompareObject(R1, Bool::True());
+ __ PopList(kRegsToSave);
+ __ BranchIf(EQUAL, &done); // Cache said: yes.
+ __ Jump(&call_runtime);
+ }
+
+ __ Bind(&is_uninstantiated);
+ {
+ __ PushList(kRegsToSave);
+ __ BranchLink(*StubCode::Subtype4TestCache_entry());
+ __ CompareObject(R1, Bool::True());
+ __ PopList(kRegsToSave);
+ __ BranchIf(EQUAL, &done); // Cache said: yes.
+ // Fall through to runtime_call
+ }
+
+ __ Bind(&call_runtime);
+
+ // We cannot really ensure here that dynamic/Object never occur here (though
+ // it is guaranteed at dart_precompiled_runtime time). This is because we do
+ // constant evaluation with default stubs and only install optimized versions
+ // before writing out the AOT snapshot. So dynamic/Object will run with
+ // default stub in constant evaluation.
+ __ CompareObject(kDstTypeReg, Type::dynamic_type());
+ __ BranchIf(EQUAL, &done);
+ __ CompareObject(kDstTypeReg, Type::Handle(Type::ObjectType()));
+ __ BranchIf(EQUAL, &done);
+
+ __ PushObject(Object::null_object()); // Make room for result.
+ __ Push(kInstanceReg);
+ __ Push(kDstTypeReg);
+ __ Push(kInstantiatorTypeArgumentsReg);
+ __ Push(kFunctionTypeArgumentsReg);
+ __ PushObject(Object::null_object());
+ __ Push(kSubtypeTestCacheReg);
+ __ CallRuntime(kTypeCheckRuntimeEntry, 6);
+ __ Pop(kSubtypeTestCacheReg);
+ __ Drop(1); // dst_name
+ __ Pop(kFunctionTypeArgumentsReg);
+ __ Pop(kInstantiatorTypeArgumentsReg);
+ __ Pop(kDstTypeReg);
+ __ Pop(kInstanceReg);
+ __ Drop(1); // Discard return value.
+ __ Bind(&done);
+ __ LeaveStubFrame();
+ __ Ret();
+}
+
// Return the current stack pointer address, used to do stack alignment checks.
void StubCode::GenerateGetCStackPointerStub(Assembler* assembler) {
__ mov(R0, Operand(SP));
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index e23bb90..f0354a8 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -16,6 +16,7 @@
#include "vm/stack_frame.h"
#include "vm/stub_code.h"
#include "vm/tags.h"
+#include "vm/type_testing_stubs.h"
#define __ assembler->
@@ -1772,6 +1773,9 @@
// R1: instantiator type arguments (only if n == 4, can be raw_null).
// R2: function type arguments (only if n == 4, can be raw_null).
// R3: SubtypeTestCache.
+//
+// Preserves R0/R2/R8.
+//
// Result in R1: null -> not found, otherwise result (true or false).
static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
ASSERT((n == 1) || (n == 2) || (n == 4));
@@ -1884,6 +1888,213 @@
GenerateSubtypeNTestCacheStub(assembler, 4);
}
+// Used to test whether a given value is of a given type (different variants,
+// all have the same calling convention).
+//
+// Inputs:
+// - R0 : instance to test against.
+// - R2 : instantiator type arguments (if needed).
+// - R1 : function type arguments (if needed).
+//
+// - R3 : subtype test cache.
+//
+// - R8 : type to test against.
+// - R4 : name of destination variable.
+//
+// Preserves R0/R2.
+//
+// Note of warning: The caller will not populate CODE_REG and we have therefore
+// no access to the pool.
+void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
+ Label done;
+
+ const Register kInstanceReg = R0;
+ const Register kDstTypeReg = R8;
+
+ // Fast case for 'null'.
+ __ CompareObject(kInstanceReg, Object::null_object());
+ __ BranchIf(EQUAL, &done);
+
+ // Fast case for 'int'.
+ Label not_smi;
+ __ BranchIfNotSmi(kInstanceReg, ¬_smi);
+ __ CompareObject(kDstTypeReg, Object::ZoneHandle(Type::IntType()));
+ __ BranchIf(EQUAL, &done);
+ __ Bind(¬_smi);
+
+ // Tail call the [SubtypeTestCache]-based implementation.
+ __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+ __ ldr(R9, FieldAddress(CODE_REG, Code::entry_point_offset()));
+ __ br(R9);
+
+ __ Bind(&done);
+ __ Ret();
+}
+
+void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+ __ Ret();
+}
+
+void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+ const Register kTypeRefReg = R8;
+
+ // We dereference the TypeRef and tail-call to it's type testing stub.
+ __ ldr(kTypeRefReg, FieldAddress(kTypeRefReg, TypeRef::type_offset()));
+ __ ldr(R9, FieldAddress(kTypeRefReg,
+ AbstractType::type_test_stub_entry_point_offset()));
+ __ br(R9);
+}
+
+void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+ __ Breakpoint();
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const Type& type,
+ const Class& type_class) {
+ const Register kInstanceReg = R0;
+ const Register kClassIdReg = R9;
+
+ BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
+ kInstanceReg, kClassIdReg);
+
+ __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+ __ ldr(R9, FieldAddress(CODE_REG, Code::entry_point_offset()));
+ __ br(R9);
+}
+
+void TypeTestingStubGenerator::
+ BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
+ HierarchyInfo* hi,
+ const Class& type_class,
+ const TypeArguments& tp,
+ const TypeArguments& ta) {
+ const Register kInstanceReg = R0;
+ const Register kInstanceTypeArguments = R7;
+ const Register kClassIdReg = R9;
+
+ BuildOptimizedSubclassRangeCheckWithTypeArguments(
+ assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
+ kInstanceTypeArguments);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const AbstractType& type_arg,
+ intptr_t type_param_value_offset_i,
+ Label* check_failed) {
+ const Register kInstantiatorTypeArgumentsReg = R1;
+ const Register kFunctionTypeArgumentsReg = R2;
+ const Register kInstanceTypeArguments = R7;
+
+ const Register kClassIdReg = R9;
+ const Register kOwnTypeArgumentValue = TMP;
+
+ BuildOptimizedTypeArgumentValueCheck(
+ assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
+ kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
+ kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
+}
+
+void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
+ Label done, call_runtime;
+
+ const Register kInstanceReg = R0;
+ const Register kInstantiatorTypeArgumentsReg = R1;
+ const Register kFunctionTypeArgumentsReg = R2;
+
+ const Register kSubtypeTestCacheReg = R3;
+ const Register kDstTypeReg = R8;
+
+ __ EnterStubFrame();
+
+#ifdef DEBUG
+ // Guaranteed by caller.
+ Label no_error;
+ __ CompareObject(kInstanceReg, Object::null_object());
+ __ BranchIf(NOT_EQUAL, &no_error);
+ __ Breakpoint();
+ __ Bind(&no_error);
+#endif
+
+ // Need to handle slow cases of [Smi]s here because the
+ // [SubtypeTestCache]-based stubs do not handle [Smi]s.
+ Label non_smi_value;
+ __ BranchIfSmi(kInstanceReg, &call_runtime);
+
+ // If the subtype-cache is null, it needs to be lazily-created by the runtime.
+ __ CompareObject(kSubtypeTestCacheReg, Object::null_object());
+ __ BranchIf(EQUAL, &call_runtime);
+
+ const Register kTmp = R9;
+
+ // If this is not a [Type] object, we'll go to the runtime.
+ Label is_simple, is_instantiated, is_uninstantiated;
+ __ LoadClassId(kTmp, kDstTypeReg);
+ __ cmp(kTmp, Operand(kTypeCid));
+ __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+
+ // Check whether this [Type] is instantiated/uninstantiated.
+ __ ldr(kTmp, FieldAddress(kDstTypeReg, Type::type_state_offset()), kByte);
+ __ cmp(kTmp, Operand(RawType::kFinalizedInstantiated));
+ __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+ // Fall through to &is_instantiated
+
+ __ Bind(&is_instantiated);
+ {
+ __ PushPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+ __ BranchLink(*StubCode::Subtype2TestCache_entry());
+ __ CompareObject(R1, Bool::True());
+ __ PopPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+ __ BranchIf(EQUAL, &done); // Cache said: yes.
+ __ Jump(&call_runtime);
+ }
+
+ __ Bind(&is_uninstantiated);
+ {
+ __ PushPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+ __ BranchLink(*StubCode::Subtype4TestCache_entry());
+ __ CompareObject(R1, Bool::True());
+ __ PopPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+ __ BranchIf(EQUAL, &done); // Cache said: yes.
+ // Fall through to runtime_call
+ }
+
+ __ Bind(&call_runtime);
+
+ // We cannot really ensure here that dynamic/Object never occur here (though
+ // it is guaranteed at dart_precompiled_runtime time). This is because we do
+ // constant evaluation with default stubs and only install optimized versions
+ // before writing out the AOT snapshot. So dynamic/Object will run with
+ // default stub in constant evaluation.
+ __ CompareObject(kDstTypeReg, Type::dynamic_type());
+ __ BranchIf(EQUAL, &done);
+ __ CompareObject(kDstTypeReg, Type::Handle(Type::ObjectType()));
+ __ BranchIf(EQUAL, &done);
+
+ __ PushObject(Object::null_object()); // Make room for result.
+ __ Push(kInstanceReg);
+ __ Push(kDstTypeReg);
+ __ Push(kInstantiatorTypeArgumentsReg);
+ __ Push(kFunctionTypeArgumentsReg);
+ __ PushObject(Object::null_object());
+ __ Push(kSubtypeTestCacheReg);
+ __ CallRuntime(kTypeCheckRuntimeEntry, 6);
+ __ Pop(kSubtypeTestCacheReg);
+ __ Drop(1); // dst_name
+ __ Pop(kFunctionTypeArgumentsReg);
+ __ Pop(kInstantiatorTypeArgumentsReg);
+ __ Pop(kDstTypeReg);
+ __ Pop(kInstanceReg);
+ __ Drop(1); // Discard return value.
+ __ Bind(&done);
+ __ LeaveStubFrame();
+ __ Ret();
+}
+
void StubCode::GenerateGetCStackPointerStub(Assembler* assembler) {
__ mov(R0, CSP);
__ ret();
diff --git a/runtime/vm/stub_code_dbc.cc b/runtime/vm/stub_code_dbc.cc
index 4b7157c..f78a5d1 100644
--- a/runtime/vm/stub_code_dbc.cc
+++ b/runtime/vm/stub_code_dbc.cc
@@ -83,6 +83,31 @@
__ Trap();
}
+// TODO(kustermann): Don't generate this stub.
+void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
+ __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+ __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+ __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+ __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
+ __ Trap();
+}
+
void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
__ Trap();
}
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 9ef1116..a632adf 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1779,6 +1779,31 @@
GenerateSubtypeNTestCacheStub(assembler, 4);
}
+void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
+ // Only used in AOT and therefore not on ia32.
+ __ Breakpoint();
+}
+
+void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+ // Only used in AOT and therefore not on ia32.
+ __ Breakpoint();
+}
+
+void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+ // Only used in AOT and therefore not on ia32.
+ __ Breakpoint();
+}
+
+void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+ // Only used in AOT and therefore not on ia32.
+ __ Breakpoint();
+}
+
+void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
+ // Only used in AOT and therefore not on ia32.
+ __ Breakpoint();
+}
+
// Return the current stack pointer address, used to do stack alignment checks.
// TOS + 0: return address
// Result in EAX.
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 5183d28..fc8e781 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -3,9 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
#include "vm/globals.h"
+
+#include "vm/stub_code.h"
+
#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/assembler/disassembler.h"
#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/dart_entry.h"
@@ -15,8 +19,8 @@
#include "vm/resolver.h"
#include "vm/scavenger.h"
#include "vm/stack_frame.h"
-#include "vm/stub_code.h"
#include "vm/tags.h"
+#include "vm/type_testing_stubs.h"
#define __ assembler->
@@ -1717,7 +1721,7 @@
//
// - TOS + 0: return address.
//
-// Preserves R9/RAX/RCX/RDX.
+// Preserves R9/RAX/RCX/RDX, RBX.
//
// Result in R8: null -> not found, otherwise result (true or false).
static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
@@ -1841,6 +1845,194 @@
GenerateSubtypeNTestCacheStub(assembler, 4);
}
+// Used to test whether a given value is of a given type (different variants,
+// all have the same calling convention).
+//
+// Inputs:
+// - R9 : RawSubtypeTestCache
+// - RAX : instance to test against.
+// - RDX : instantiator type arguments (if needed).
+// - RCX : function type arguments (if needed).
+//
+// - RBX : type to test against.
+// - R10 : name of destination variable.
+//
+// Preserves R9/RAX/RCX/RDX, RBX, R10.
+//
+// Note of warning: The caller will not populate CODE_REG and we have therefore
+// no access to the pool.
+void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
+ Label done;
+
+ const Register kInstanceReg = RAX;
+
+ // Fast case for 'null'.
+ __ CompareObject(kInstanceReg, Object::null_object());
+ __ BranchIf(EQUAL, &done);
+
+ __ movq(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+ __ jmp(FieldAddress(CODE_REG, Code::entry_point_offset()));
+
+ __ Bind(&done);
+ __ Ret();
+}
+
+void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+ __ Ret();
+}
+
+void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+ const Register kTypeRefReg = RBX;
+
+ // We dereference the TypeRef and tail-call to it's type testing stub.
+ __ movq(kTypeRefReg, FieldAddress(kTypeRefReg, TypeRef::type_offset()));
+ __ jmp(FieldAddress(kTypeRefReg,
+ AbstractType::type_test_stub_entry_point_offset()));
+}
+
+void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+ __ Breakpoint();
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const Type& type,
+ const Class& type_class) {
+ const Register kInstanceReg = RAX;
+ const Register kClassIdReg = TMP;
+
+ BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
+ kInstanceReg, kClassIdReg);
+
+ __ movq(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+ __ jmp(FieldAddress(CODE_REG, Code::entry_point_offset()));
+}
+
+void TypeTestingStubGenerator::
+ BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
+ HierarchyInfo* hi,
+ const Class& type_class,
+ const TypeArguments& tp,
+ const TypeArguments& ta) {
+ const Register kInstanceReg = RAX;
+ const Register kInstanceTypeArguments = RSI;
+ const Register kClassIdReg = TMP;
+
+ BuildOptimizedSubclassRangeCheckWithTypeArguments(
+ assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
+ kInstanceTypeArguments);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const AbstractType& type_arg,
+ intptr_t type_param_value_offset_i,
+ Label* check_failed) {
+ const Register kInstanceTypeArguments = RSI;
+ const Register kInstantiatorTypeArgumentsReg = RDX;
+ const Register kFunctionTypeArgumentsReg = RCX;
+
+ const Register kClassIdReg = TMP;
+ const Register kOwnTypeArgumentValue = RDI;
+
+ BuildOptimizedTypeArgumentValueCheck(
+ assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
+ kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
+ kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
+}
+
+void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
+ Label done, call_runtime;
+
+ const Register kInstanceReg = RAX;
+ const Register kInstantiatorTypeArgumentsReg = RDX;
+ const Register kFunctionTypeArgumentsReg = RCX;
+ const Register kDstTypeReg = RBX;
+ const Register kSubtypeTestCacheReg = R9;
+
+ __ EnterStubFrame();
+
+#ifdef DEBUG
+ // Guaranteed by caller.
+ Label no_error;
+ __ CompareObject(kInstanceReg, Object::null_object());
+ __ BranchIf(NOT_EQUAL, &no_error);
+ __ Breakpoint();
+ __ Bind(&no_error);
+#endif
+
+ // Need to handle slow cases of [Smi]s here because the
+ // [SubtypeTestCache]-based stubs do not handle [Smi]s.
+ __ BranchIfSmi(kInstanceReg, &call_runtime);
+
+ // If the subtype-cache is null, it needs to be lazily-created by the runtime.
+ __ CompareObject(kSubtypeTestCacheReg, Object::null_object());
+ __ BranchIf(EQUAL, &call_runtime);
+
+ const Register kTmp = RDI;
+
+ // If this is not a [Type] object, we'll go to the runtime.
+ Label is_simple, is_instantiated, is_uninstantiated;
+ __ LoadClassId(kTmp, kDstTypeReg);
+ __ cmpq(kTmp, Immediate(kTypeCid));
+ __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+
+ // Check whether this [Type] is instantiated/uninstantiated.
+ __ cmpb(FieldAddress(kDstTypeReg, Type::type_state_offset()),
+ Immediate(RawType::kFinalizedInstantiated));
+ __ BranchIf(NOT_EQUAL, &is_uninstantiated);
+ // Fall through to &is_instantiated
+
+ __ Bind(&is_instantiated);
+ {
+ __ Call(*StubCode::Subtype2TestCache_entry());
+ __ CompareObject(R8, Bool::True());
+ __ BranchIf(EQUAL, &done); // Cache said: yes.
+ __ Jump(&call_runtime);
+ }
+
+ __ Bind(&is_uninstantiated);
+ {
+ __ Call(*StubCode::Subtype4TestCache_entry());
+ __ CompareObject(R8, Bool::True());
+ __ BranchIf(EQUAL, &done); // Cache said: yes.
+ // Fall through to runtime_call
+ }
+
+ __ Bind(&call_runtime);
+
+ // We cannot really ensure here that dynamic/Object never occur here (though
+ // it is guaranteed at dart_precompiled_runtime time). This is because we do
+ // constant evaluation with default stubs and only install optimized versions
+ // before writing out the AOT snapshot. So dynamic/Object will run with
+ // default stub in constant evaluation.
+ __ CompareObject(kDstTypeReg, Type::dynamic_type());
+ __ BranchIf(EQUAL, &done);
+ __ CompareObject(kDstTypeReg, Type::Handle(Type::ObjectType()));
+ __ BranchIf(EQUAL, &done);
+
+ __ PushObject(Object::null_object()); // Make room for result.
+ __ pushq(kInstanceReg);
+ __ pushq(kDstTypeReg);
+ __ pushq(kInstantiatorTypeArgumentsReg);
+ __ pushq(kFunctionTypeArgumentsReg);
+ __ PushObject(Object::null_object());
+ __ pushq(kSubtypeTestCacheReg);
+ __ CallRuntime(kTypeCheckRuntimeEntry, 6);
+ __ popq(kSubtypeTestCacheReg);
+ __ Drop(1);
+ __ popq(kFunctionTypeArgumentsReg);
+ __ popq(kInstantiatorTypeArgumentsReg);
+ __ popq(kDstTypeReg);
+ __ popq(kInstanceReg);
+ __ Drop(1); // Discard return value.
+ __ Bind(&done);
+ __ LeaveStubFrame();
+ __ Ret();
+}
+
// Return the current stack pointer address, used to stack alignment
// checks.
// TOS + 0: return address
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index af6c31a..68b4a05 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -93,6 +93,7 @@
stack_overflow_count_(0),
cha_(NULL),
hierarchy_info_(NULL),
+ type_usage_info_(NULL),
deopt_id_(0),
pending_functions_(GrowableObjectArray::null()),
active_exception_(Object::null()),
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 3f98f69..06655b0 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -55,6 +55,7 @@
class TimelineStream;
class TypeArguments;
class TypeParameter;
+class TypeUsageInfo;
class Zone;
#define REUSABLE_HANDLE_LIST(V) \
@@ -97,7 +98,9 @@
V(RawCode*, lazy_deopt_from_return_stub_, \
StubCode::DeoptimizeLazyFromReturn_entry()->code(), NULL) \
V(RawCode*, lazy_deopt_from_throw_stub_, \
- StubCode::DeoptimizeLazyFromThrow_entry()->code(), NULL)
+ StubCode::DeoptimizeLazyFromThrow_entry()->code(), NULL) \
+ V(RawCode*, slow_type_test_stub_, StubCode::SlowTypeTest_entry()->code(), \
+ NULL)
#endif
@@ -353,6 +356,18 @@
hierarchy_info_ = value;
}
+ TypeUsageInfo* type_usage_info() const {
+ ASSERT(isolate_ != NULL);
+ return type_usage_info_;
+ }
+
+ void set_type_usage_info(TypeUsageInfo* value) {
+ ASSERT(isolate_ != NULL);
+ ASSERT((type_usage_info_ == NULL && value != NULL) ||
+ (type_usage_info_ != NULL && value == NULL));
+ type_usage_info_ = value;
+ }
+
int32_t no_callback_scope_depth() const { return no_callback_scope_depth_; }
void IncrementNoCallbackScopeDepth() {
@@ -793,6 +808,7 @@
// Compiler state:
CHA* cha_;
HierarchyInfo* hierarchy_info_;
+ TypeUsageInfo* type_usage_info_;
intptr_t deopt_id_; // Compilation specific counter.
RawGrowableObjectArray* pending_functions_;
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
new file mode 100644
index 0000000..82f55a7
--- /dev/null
+++ b/runtime/vm/type_testing_stubs.cc
@@ -0,0 +1,974 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/type_testing_stubs.h"
+#include "vm/compiler/assembler/disassembler.h"
+#include "vm/compiler/backend/flow_graph_compiler.h"
+#include "vm/compiler/backend/il_printer.h"
+#include "vm/object_store.h"
+
+#define __ assembler->
+
+namespace dart {
+
+DECLARE_FLAG(bool, disassemble_stubs);
+
+TypeTestingStubNamer::TypeTestingStubNamer()
+ : lib_(Library::Handle()),
+ klass_(Class::Handle()),
+ type_(AbstractType::Handle()),
+ type_arguments_(TypeArguments::Handle()),
+ string_(String::Handle()) {}
+
+const char* TypeTestingStubNamer::StubNameForType(
+ const AbstractType& type) const {
+ const uintptr_t address =
+ reinterpret_cast<uintptr_t>(type.raw()) & 0x7fffffff;
+ Zone* Z = Thread::Current()->zone();
+ return OS::SCreate(Z, "TypeTestingStub_%s__%" Pd "", StringifyType(type),
+ address);
+}
+
+const char* TypeTestingStubNamer::StringifyType(
+ const AbstractType& type) const {
+ Zone* Z = Thread::Current()->zone();
+ if (type.IsType() && !type.IsFunctionType()) {
+ const intptr_t cid = Type::Cast(type).type_class_id();
+ ClassTable* class_table = Isolate::Current()->class_table();
+ klass_ = class_table->At(cid);
+ ASSERT(!klass_.IsNull());
+
+ const char* curl = "";
+ lib_ = klass_.library();
+ if (!lib_.IsNull()) {
+ string_ = lib_.url();
+ curl = OS::SCreate(Z, "%s_", string_.ToCString());
+ } else {
+ static intptr_t counter = 0;
+ curl = OS::SCreate(Z, "nolib%" Pd "_", counter++);
+ }
+
+ string_ = klass_.ScrubbedName();
+ ASSERT(!string_.IsNull());
+ const char* concatenated =
+ AssemblerSafeName(OS::SCreate(Z, "%s_%s", curl, string_.ToCString()));
+
+ const intptr_t type_parameters = klass_.NumTypeParameters();
+ if (type.arguments() != TypeArguments::null() && type_parameters > 0) {
+ type_arguments_ = type.arguments();
+ ASSERT(type_arguments_.Length() >= type_parameters);
+ const intptr_t length = type_arguments_.Length();
+ for (intptr_t i = 0; i < type_parameters; ++i) {
+ type_ = type_arguments_.TypeAt(length - type_parameters + i);
+ concatenated =
+ OS::SCreate(Z, "%s__%s", concatenated, StringifyType(type_));
+ }
+ }
+ return concatenated;
+ } else if (type.IsTypeParameter()) {
+ string_ = TypeParameter::Cast(type).name();
+ return AssemblerSafeName(OS::SCreate(Z, "%s", string_.ToCString()));
+ } else if (type.IsTypeRef()) {
+ const Type& dereferenced_type =
+ Type::Handle(Type::RawCast(TypeRef::Cast(type).type()));
+ return OS::SCreate(Z, "TypeRef_%s", StringifyType(dereferenced_type));
+ } else {
+ return AssemblerSafeName(OS::SCreate(Z, "%s", type.ToCString()));
+ }
+}
+
+const char* TypeTestingStubNamer::AssemblerSafeName(char* cname) {
+ char* cursor = cname;
+ while (*cursor != '\0') {
+ char c = *cursor;
+ if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9') || (c == '_'))) {
+ *cursor = '_';
+ }
+ cursor++;
+ }
+ return cname;
+}
+
+RawInstructions* TypeTestingStubGenerator::DefaultCodeForType(
+ const AbstractType& type) {
+ // During bootstrapping we have no access to stubs yet, so we'll just return
+ // `null` and patch these later in `Object::FinishInitOnce()`.
+ if (!StubCode::HasBeenInitialized()) {
+ ASSERT(type.IsType());
+ const intptr_t cid = Type::Cast(type).type_class_id();
+ ASSERT(cid == kDynamicCid || cid == kVoidCid || cid == kVectorCid);
+ return Instructions::null();
+ }
+
+ if (type.raw() == Type::ObjectType() || type.raw() == Type::DynamicType() ||
+ type.raw() == Type::VoidType()) {
+ return Code::InstructionsOf(StubCode::TopTypeTypeTest_entry()->code());
+ }
+
+ if (type.IsTypeRef()) {
+ return Code::InstructionsOf(StubCode::TypeRefTypeTest_entry()->code());
+ }
+
+ if (type.IsType() || type.IsTypeParameter()) {
+ return Code::InstructionsOf(StubCode::DefaultTypeTest_entry()->code());
+ } else {
+ ASSERT(type.IsBoundedType() || type.IsMixinAppType());
+ return Code::InstructionsOf(StubCode::UnreachableTypeTest_entry()->code());
+ }
+}
+
+TypeTestingStubGenerator::TypeTestingStubGenerator()
+ : object_store_(Isolate::Current()->object_store()),
+ array_(GrowableObjectArray::Handle()),
+ instr_(Instructions::Handle()) {}
+
+RawInstructions* TypeTestingStubGenerator::OptimizedCodeForType(
+ const AbstractType& type) {
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+ ASSERT(StubCode::HasBeenInitialized());
+
+ if (type.IsTypeRef()) {
+ return Code::InstructionsOf(StubCode::TypeRefTypeTest_entry()->code());
+ }
+
+ if (type.raw() == Type::ObjectType() || type.raw() == Type::DynamicType()) {
+ return Code::InstructionsOf(StubCode::TopTypeTypeTest_entry()->code());
+ }
+
+ if (type.IsCanonical()) {
+ ASSERT(type.IsResolved());
+ if (type.IsType()) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ // Lazily create the type testing stubs array.
+ array_ = object_store_->type_testing_stubs();
+ if (array_.IsNull()) {
+ array_ = GrowableObjectArray::New(Heap::kOld);
+ object_store_->set_type_testing_stubs(array_);
+ }
+
+ instr_ = TypeTestingStubGenerator::BuildCodeForType(Type::Cast(type));
+ if (!instr_.IsNull()) {
+ array_.Add(type);
+ array_.Add(instr_);
+ } else {
+ // Fall back to default.
+ instr_ =
+ Code::InstructionsOf(StubCode::DefaultTypeTest_entry()->code());
+ }
+#else
+ // In the precompiled runtime we cannot lazily create new optimized type
+ // testing stubs, so if we cannot find one, we'll just return the default
+ // one.
+ instr_ = Code::InstructionsOf(StubCode::DefaultTypeTest_entry()->code());
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ return instr_.raw();
+ }
+ }
+#endif // !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+ return TypeTestingStubGenerator::DefaultCodeForType(type);
+}
+
+TypeTestingStubFinder::TypeTestingStubFinder()
+ : array_(GrowableObjectArray::Handle()),
+ type_(Type::Handle()),
+ code_(Code::Handle()),
+ instr_(Instructions::Handle()) {
+ array_ = Isolate::Current()->object_store()->type_testing_stubs();
+ if (!array_.IsNull()) {
+ SortTableForFastLookup();
+ }
+}
+
+// TODO(kustermann): Use sorting/hashtables to speed this up.
+RawInstructions* TypeTestingStubFinder::LookupByAddresss(
+ uword entry_point) const {
+ // First test the 2 common ones:
+ code_ = StubCode::DefaultTypeTest_entry()->code();
+ if (entry_point == code_.UncheckedEntryPoint()) {
+ return code_.instructions();
+ }
+ code_ = StubCode::TopTypeTypeTest_entry()->code();
+ if (entry_point == code_.UncheckedEntryPoint()) {
+ return code_.instructions();
+ }
+ code_ = StubCode::TypeRefTypeTest_entry()->code();
+ if (entry_point == code_.UncheckedEntryPoint()) {
+ return code_.instructions();
+ }
+ code_ = StubCode::UnreachableTypeTest_entry()->code();
+ if (entry_point == code_.UncheckedEntryPoint()) {
+ return code_.instructions();
+ }
+
+ const intptr_t tuple_idx = LookupInSortedArray(entry_point);
+ return Instructions::RawCast(array_.At(2 * tuple_idx + 1));
+}
+
+const char* TypeTestingStubFinder::StubNameFromAddresss(
+ uword entry_point) const {
+ // First test the 2 common ones:
+ code_ = StubCode::DefaultTypeTest_entry()->code();
+ if (entry_point == code_.UncheckedEntryPoint()) {
+ return "TypeTestingStub_Default";
+ }
+ code_ = StubCode::UnreachableTypeTest_entry()->code();
+ if (entry_point == code_.UncheckedEntryPoint()) {
+ return "TypeTestingStub_Unreachable";
+ }
+
+ const intptr_t tuple_idx = LookupInSortedArray(entry_point);
+ type_ = AbstractType::RawCast(array_.At(2 * tuple_idx));
+ return namer_.StubNameForType(type_);
+}
+
+void TypeTestingStubFinder::SortTableForFastLookup() {
+ struct Sorter {
+ explicit Sorter(const GrowableObjectArray& array)
+ : array_(array),
+ object_(AbstractType::Handle()),
+ object2_(AbstractType::Handle()) {}
+
+ void Sort() {
+ const intptr_t tuples = array_.Length() / 2;
+ InsertionSort(0, tuples - 1);
+ }
+
+ void InsertionSort(intptr_t start, intptr_t end) {
+ for (intptr_t i = start + 1; i <= end; ++i) {
+ intptr_t j = i;
+ while (j > start && Value(j - 1) > Value(j)) {
+ Swap(j - 1, j);
+ j--;
+ }
+ }
+ }
+
+ void Swap(intptr_t i, intptr_t j) {
+ // Swap type.
+ object_ = array_.At(2 * i);
+ object2_ = array_.At(2 * j);
+ array_.SetAt(2 * i, object2_);
+ array_.SetAt(2 * j, object_);
+
+ // Swap instructions.
+ object_ = array_.At(2 * i + 1);
+ object2_ = array_.At(2 * j + 1);
+ array_.SetAt(2 * i + 1, object2_);
+ array_.SetAt(2 * j + 1, object_);
+ }
+
+ uword Value(intptr_t i) {
+ return Instructions::UncheckedEntryPoint(
+ Instructions::RawCast(array_.At(2 * i + 1)));
+ }
+
+ const GrowableObjectArray& array_;
+ Object& object_;
+ Object& object2_;
+ };
+
+ Sorter sorter(array_);
+ sorter.Sort();
+}
+
+intptr_t TypeTestingStubFinder::LookupInSortedArray(uword entry_point) const {
+ intptr_t left = 0;
+ intptr_t right = array_.Length() / 2 - 1;
+
+ while (left <= right) {
+ const intptr_t mid = left + (right - left) / 2;
+ RawInstructions* instr = Instructions::RawCast(array_.At(2 * mid + 1));
+ const uword mid_value = Instructions::UncheckedEntryPoint(instr);
+
+ if (entry_point < mid_value) {
+ right = mid - 1;
+ } else if (mid_value == entry_point) {
+ return mid;
+ } else {
+ left = mid + 1;
+ }
+ }
+
+ // The caller should only call this function if [entry_point] is a real type
+ // testing entrypoint, in which case it must be guaranteed to find it.
+ UNREACHABLE();
+ return NULL;
+}
+
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+RawInstructions* TypeTestingStubGenerator::BuildCodeForType(const Type& type) {
+ HierarchyInfo* hi = Thread::Current()->hierarchy_info();
+ ASSERT(hi != NULL);
+
+ if (!hi->CanUseSubtypeRangeCheckFor(type)) {
+ if (!hi->CanUseGenericSubtypeRangeCheckFor(type)) {
+ return Instructions::null();
+ }
+ }
+
+ const Class& type_class = Class::Handle(type.type_class());
+ ASSERT(!type_class.IsNull());
+
+ // To use the already-defined __ Macro !
+ Assembler assembler;
+ BuildOptimizedTypeTestStub(&assembler, hi, type, type_class);
+
+ const char* name = namer_.StubNameForType(type);
+ const Code& code =
+ Code::Handle(Code::FinalizeCode(name, &assembler, false /* optimized */));
+#ifndef PRODUCT
+ if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
+ LogBlock lb;
+ THR_Print("Code for stub '%s': {\n", name);
+ DisassembleToStdout formatter;
+ code.Disassemble(&formatter);
+ THR_Print("}\n");
+ const ObjectPool& object_pool = ObjectPool::Handle(code.object_pool());
+ object_pool.DebugPrint();
+ }
+#endif // !PRODUCT
+
+ return code.instructions();
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeTestStubFastCases(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const Type& type,
+ const Class& type_class,
+ Register instance_reg,
+ Register class_id_reg) {
+ // These are handled via the TopTypeTypeTestStub!
+ ASSERT(
+ !(type.raw() == Type::ObjectType() || type.raw() == Type::DynamicType()));
+
+ // Fast case for 'int'.
+ if (type.raw() == Type::IntType()) {
+ Label non_smi_value;
+ __ BranchIfNotSmi(instance_reg, &non_smi_value);
+ __ Ret();
+ __ Bind(&non_smi_value);
+ } else if (type.IsDartFunctionType()) {
+ Label continue_checking;
+ __ CompareImmediate(class_id_reg, kClosureCid);
+ __ BranchIf(NOT_EQUAL, &continue_checking);
+ __ Ret();
+ __ Bind(&continue_checking);
+
+ } else {
+ // TODO(kustermann): Make more fast cases, e.g. Type::Number()
+ // is implemented by Smi.
+ }
+
+ // Check the cid ranges which are a subtype of [type].
+ if (hi->CanUseSubtypeRangeCheckFor(type)) {
+ const CidRangeVector& ranges = hi->SubtypeRangesForClass(type_class);
+
+ const Type& int_type = Type::Handle(Type::IntType());
+ const bool smi_is_ok = int_type.IsSubtypeOf(type, NULL, NULL, Heap::kNew);
+
+ BuildOptimizedSubtypeRangeCheck(assembler, ranges, class_id_reg,
+ instance_reg, smi_is_ok);
+ } else {
+ ASSERT(hi->CanUseGenericSubtypeRangeCheckFor(type));
+
+ const intptr_t num_type_parameters = type_class.NumTypeParameters();
+ const intptr_t num_type_arguments = type_class.NumTypeArguments();
+
+ const TypeArguments& tp =
+ TypeArguments::Handle(type_class.type_parameters());
+ ASSERT(tp.Length() == num_type_parameters);
+
+ const TypeArguments& ta = TypeArguments::Handle(type.arguments());
+ ASSERT(ta.Length() == num_type_arguments);
+
+ BuildOptimizedSubclassRangeCheckWithTypeArguments(assembler, hi, type_class,
+ tp, ta);
+ }
+
+ // Fast case for 'null'.
+ Label non_null;
+ __ CompareObject(instance_reg, Object::null_object());
+ __ BranchIf(NOT_EQUAL, &non_null);
+ __ Ret();
+ __ Bind(&non_null);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedSubtypeRangeCheck(
+ Assembler* assembler,
+ const CidRangeVector& ranges,
+ Register class_id_reg,
+ Register instance_reg,
+ bool smi_is_ok) {
+ Label cid_range_failed, is_subtype;
+
+ if (smi_is_ok) {
+ __ LoadClassIdMayBeSmi(class_id_reg, instance_reg);
+ } else {
+ __ BranchIfSmi(instance_reg, &cid_range_failed);
+ __ LoadClassId(class_id_reg, instance_reg);
+ }
+
+ FlowGraphCompiler::GenerateCidRangesCheck(
+ assembler, class_id_reg, ranges, &is_subtype, &cid_range_failed, true);
+ __ Bind(&is_subtype);
+ __ Ret();
+ __ Bind(&cid_range_failed);
+}
+
+void TypeTestingStubGenerator::
+ BuildOptimizedSubclassRangeCheckWithTypeArguments(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const Class& type_class,
+ const TypeArguments& tp,
+ const TypeArguments& ta,
+ const Register class_id_reg,
+ const Register instance_reg,
+ const Register instance_type_args_reg) {
+ // a) First we make a quick sub*class* cid-range check.
+ Label check_failed;
+ ASSERT(!type_class.is_implemented());
+ const CidRangeVector& ranges = hi->SubclassRangesForClass(type_class);
+ BuildOptimizedSubclassRangeCheck(assembler, ranges, class_id_reg,
+ instance_reg, &check_failed);
+ // fall through to continue
+
+ // b) Then we'll load the values for the type parameters.
+ __ LoadField(
+ instance_type_args_reg,
+ FieldAddress(instance_reg, type_class.type_arguments_field_offset()));
+
+ // The kernel frontend should fill in any non-assigned type parameters on
+ // construction with dynamic/Object, so we should never get the null type
+ // argument vector in created instances.
+ //
+ // TODO(kustermann): We could consider not using "null" as type argument
+ // vector representing all-dynamic to avoid this extra check (which will be
+ // uncommon because most Dart code in 2.0 will be strongly typed)!
+ Label process_done;
+ __ CompareObject(instance_type_args_reg, Object::null_object());
+ __ BranchIf(NOT_EQUAL, &process_done);
+ __ Ret();
+ __ Bind(&process_done);
+
+ // c) Then we'll check each value of the type argument.
+ AbstractType& type_arg = AbstractType::Handle();
+
+ const intptr_t num_type_parameters = type_class.NumTypeParameters();
+ const intptr_t num_type_arguments = type_class.NumTypeArguments();
+ for (intptr_t i = 0; i < num_type_parameters; ++i) {
+ const intptr_t type_param_value_offset_i =
+ num_type_arguments - num_type_parameters + i;
+
+ type_arg = ta.TypeAt(type_param_value_offset_i);
+ ASSERT(type_arg.IsTypeParameter() ||
+ hi->CanUseSubtypeRangeCheckFor(type_arg));
+
+ BuildOptimizedTypeArgumentValueCheck(
+ assembler, hi, type_arg, type_param_value_offset_i, &check_failed);
+ }
+ __ Ret();
+
+ // If anything fails.
+ __ Bind(&check_failed);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedSubclassRangeCheck(
+ Assembler* assembler,
+ const CidRangeVector& ranges,
+ Register class_id_reg,
+ Register instance_reg,
+ Label* check_failed) {
+ __ LoadClassIdMayBeSmi(class_id_reg, instance_reg);
+
+ Label is_subtype;
+ FlowGraphCompiler::GenerateCidRangesCheck(assembler, class_id_reg, ranges,
+ &is_subtype, check_failed, true);
+ __ Bind(&is_subtype);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const AbstractType& type_arg,
+ intptr_t type_param_value_offset_i,
+ const Register class_id_reg,
+ const Register instance_type_args_reg,
+ const Register instantiator_type_args_reg,
+ const Register function_type_args_reg,
+ const Register own_type_arg_reg,
+ Label* check_failed) {
+ if (type_arg.raw() != Type::ObjectType() &&
+ type_arg.raw() != Type::DynamicType()) {
+ // TODO(kustermann): Even though it should be safe to use TMP here, we
+ // should avoid using TMP outside the assembler. Try to find a free
+ // register to use here!
+ __ LoadField(
+ TMP,
+ FieldAddress(instance_type_args_reg,
+ TypeArguments::type_at_offset(type_param_value_offset_i)));
+ __ LoadField(class_id_reg, FieldAddress(TMP, Type::type_class_id_offset()));
+
+ if (type_arg.IsTypeParameter()) {
+ const TypeParameter& type_param = TypeParameter::Cast(type_arg);
+ const Register kTypeArgumentsReg = type_param.IsClassTypeParameter()
+ ? instantiator_type_args_reg
+ : function_type_args_reg;
+ __ LoadField(
+ own_type_arg_reg,
+ FieldAddress(kTypeArgumentsReg,
+ TypeArguments::type_at_offset(type_param.index())));
+ __ CompareWithFieldValue(
+ class_id_reg,
+ FieldAddress(own_type_arg_reg, Type::type_class_id_offset()));
+ __ BranchIf(NOT_EQUAL, check_failed);
+ } else {
+ const Class& type_class = Class::Handle(type_arg.type_class());
+ const CidRangeVector& ranges =
+ hi->SubtypeRangesForClass(type_class, /*include_abstract=*/true);
+
+ Label is_subtype;
+ __ SmiUntag(class_id_reg);
+ FlowGraphCompiler::GenerateCidRangesCheck(
+ assembler, class_id_reg, ranges, &is_subtype, check_failed, true);
+ __ Bind(&is_subtype);
+ }
+ }
+}
+
+void RegisterTypeArgumentsUse(const Function& function,
+ TypeUsageInfo* type_usage_info,
+ const Class& klass,
+ Definition* type_arguments) {
+ // The [type_arguments] can, in the general case, be any kind of [Definition]
+ // but generally (in order of expected frequency)
+ //
+ // Case a)
+ // type_arguments <- Constant(#null)
+ // type_arguments <- Constant(#TypeArguments: [ ... ])
+ //
+ // Case b)
+ // type_arguments <- InstantiateTypeArguments(
+ // <type-expr-with-parameters>, ita, fta)
+ //
+ // Case c)
+ // type_arguments <- LoadField(vx)
+ // type_arguments <- LoadField(vx T{_ABC})
+ // type_arguments <- LoadField(vx T{Type: class: '_ABC'})
+ //
+ // Case d, e)
+ // type_arguments <- LoadIndexedUnsafe(rbp[vx + 16]))
+ // type_arguments <- Parameter(0)
+
+ if (ConstantInstr* constant = type_arguments->AsConstant()) {
+ const Object& object = constant->value();
+ ASSERT(object.IsNull() || object.IsTypeArguments());
+ const TypeArguments& type_arguments =
+ TypeArguments::Handle(TypeArguments::RawCast(object.raw()));
+ type_usage_info->UseTypeArgumentsInInstanceCreation(klass, type_arguments);
+ } else if (InstantiateTypeArgumentsInstr* instantiate =
+ type_arguments->AsInstantiateTypeArguments()) {
+ const TypeArguments& ta = instantiate->type_arguments();
+ ASSERT(!ta.IsNull());
+ type_usage_info->UseTypeArgumentsInInstanceCreation(klass, ta);
+ } else if (LoadFieldInstr* load_field = type_arguments->AsLoadField()) {
+ Definition* instance = load_field->instance()->definition();
+ intptr_t cid = instance->Type()->ToNullableCid();
+ if (cid == kDynamicCid) {
+ // This is an approximation: If we only know the type, but not the cid, we
+ // might have a this-dispatch where we know it's either this class or any
+ // subclass.
+ // We try to strengthen this assumption furher down by checking the offset
+ // of the type argument vector, but generally speaking this could be a
+ // false-postive, which is still ok!
+ const AbstractType& type = *instance->Type()->ToAbstractType();
+ if (type.IsType()) {
+ const Class& type_class = Class::Handle(type.type_class());
+ if (type_class.NumTypeArguments() >= klass.NumTypeArguments()) {
+ cid = type_class.id();
+ }
+ }
+ }
+ if (cid != kDynamicCid) {
+ const Class& instance_klass =
+ Class::Handle(Isolate::Current()->class_table()->At(cid));
+ if (instance_klass.IsGeneric() &&
+ instance_klass.type_arguments_field_offset() ==
+ load_field->offset_in_bytes()) {
+ // This is a subset of Case c) above, namely forwarding the type
+ // argument vector.
+ //
+ // We use the declaration type arguments for the instance creation,
+ // which is a non-instantiated, expanded, type arguments vector.
+ const AbstractType& declaration_type =
+ AbstractType::Handle(instance_klass.DeclarationType());
+ TypeArguments& declaration_type_args =
+ TypeArguments::Handle(declaration_type.arguments());
+ type_usage_info->UseTypeArgumentsInInstanceCreation(
+ klass, declaration_type_args);
+ }
+ }
+ } else if (type_arguments->IsParameter() ||
+ type_arguments->IsLoadIndexedUnsafe()) {
+ // This happens in constructors with non-optional/optional parameters
+ // where we forward the type argument vector to object allocation.
+ //
+ // Theoretically this could be a false-positive, which is still ok, but
+ // practically it's guranteed that this is a forward of a type argument
+ // vector passed in by the caller.
+ if (function.IsFactory()) {
+ const Class& enclosing_class = Class::Handle(function.Owner());
+ const AbstractType& declaration_type =
+ AbstractType::Handle(enclosing_class.DeclarationType());
+ TypeArguments& declaration_type_args =
+ TypeArguments::Handle(declaration_type.arguments());
+ type_usage_info->UseTypeArgumentsInInstanceCreation(
+ klass, declaration_type_args);
+ }
+ } else {
+ // It can also be a phi node where the inputs are any of the above.
+ ASSERT(type_arguments->IsPhi());
+ }
+}
+
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+
+#else // !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+
+void RegisterTypeArgumentsUse(const Function& function,
+ TypeUsageInfo* type_usage_info,
+ const Class& klass,
+ Definition* type_arguments) {
+ // We only have a [TypeUsageInfo] object available durin AOT compilation.
+ UNREACHABLE();
+}
+
+#endif // !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+
+#undef __
+
+const TypeArguments& TypeArgumentInstantiator::InstantiateTypeArguments(
+ const Class& klass,
+ const TypeArguments& type_arguments) {
+ const intptr_t len = klass.NumTypeArguments();
+ TypeArguments* instantiated_type_arguments = type_arguments_handles_.Obtain();
+ *instantiated_type_arguments = TypeArguments::New(len);
+ for (intptr_t i = 0; i < len; ++i) {
+ type_ = type_arguments.TypeAt(i);
+ type_ = InstantiateType(type_);
+ instantiated_type_arguments->SetTypeAt(i, type_);
+ ASSERT(type_.IsCanonical() ||
+ (type_.IsTypeRef() &&
+ AbstractType::Handle(TypeRef::Cast(type_).type()).IsCanonical()));
+ }
+ *instantiated_type_arguments =
+ instantiated_type_arguments->Canonicalize(NULL);
+ type_arguments_handles_.Release(instantiated_type_arguments);
+ return *instantiated_type_arguments;
+}
+
+RawAbstractType* TypeArgumentInstantiator::InstantiateType(
+ const AbstractType& type) {
+ if (type.IsTypeParameter()) {
+ const TypeParameter& parameter = TypeParameter::Cast(type);
+ ASSERT(parameter.IsClassTypeParameter());
+ ASSERT(parameter.IsFinalized());
+ if (instantiator_type_arguments_.IsNull()) {
+ return Type::DynamicType();
+ }
+ return instantiator_type_arguments_.TypeAt(parameter.index());
+ } else if (type.IsFunctionType()) {
+ // No support for function types yet.
+ UNREACHABLE();
+ return nullptr;
+ } else if (type.IsTypeRef()) {
+ // No support for recursive types.
+ UNREACHABLE();
+ return nullptr;
+ } else if (type.IsType()) {
+ if (type.IsInstantiated() || type.arguments() == TypeArguments::null()) {
+ return type.raw();
+ }
+
+ const Type& from = Type::Cast(type);
+ klass_ = from.type_class();
+
+ Type* to = type_handles_.Obtain();
+ TypeArguments* to_type_arguments = type_arguments_handles_.Obtain();
+
+ *to_type_arguments = TypeArguments::null();
+ *to = Type::New(klass_, *to_type_arguments, type.token_pos());
+
+ *to_type_arguments = from.arguments();
+ to->set_arguments(InstantiateTypeArguments(klass_, *to_type_arguments));
+ to->SetIsFinalized();
+ *to ^= to->Canonicalize(NULL);
+
+ type_arguments_handles_.Release(to_type_arguments);
+ type_handles_.Release(to);
+
+ return to->raw();
+ }
+ UNREACHABLE();
+ return NULL;
+}
+
+TypeUsageInfo::TypeUsageInfo(Thread* thread)
+ : StackResource(thread),
+ zone_(thread->zone()),
+ finder_(zone_),
+ assert_assignable_types_(),
+ instance_creation_arguments_(
+ new TypeArgumentsSet[thread->isolate()->class_table()->NumCids()]),
+ klass_(Class::Handle(zone_)) {
+ thread->set_type_usage_info(this);
+}
+
+TypeUsageInfo::~TypeUsageInfo() {
+ thread()->set_type_usage_info(NULL);
+ delete[] instance_creation_arguments_;
+}
+
+void TypeUsageInfo::UseTypeInAssertAssignable(const AbstractType& type) {
+ if (!assert_assignable_types_.HasKey(&type)) {
+ AddTypeToSet(&assert_assignable_types_, &type);
+ }
+}
+
+void TypeUsageInfo::UseTypeArgumentsInInstanceCreation(
+ const Class& klass,
+ const TypeArguments& ta) {
+ if (ta.IsNull() || ta.IsCanonical()) {
+ // The Dart VM performs an optimization where it re-uses type argument
+ // vectors if the use-site needs a prefix of an already-existent type
+ // arguments vector.
+ //
+ // For example:
+ //
+ // class Foo<K, V> {
+ // foo() => new Bar<K>();
+ // }
+ //
+ // So the length of the type arguments vector can be longer than the number
+ // of type arguments the class expects.
+ ASSERT(ta.IsNull() || klass.NumTypeArguments() <= ta.Length());
+
+ // If this is a non-instantiated [TypeArguments] object, then it referes to
+ // type parameters. We need to ensure the type parameters in [ta] only
+ // refer to type parameters in the class.
+ if (!ta.IsNull() && !ta.IsInstantiated() &&
+ finder_.FindClass(ta).IsNull()) {
+ return;
+ }
+
+ klass_ = klass.raw();
+ while (klass_.NumTypeArguments() > 0) {
+ const intptr_t cid = klass_.id();
+ TypeArgumentsSet& set = instance_creation_arguments_[cid];
+ if (!set.HasKey(&ta)) {
+ set.Insert(&TypeArguments::ZoneHandle(zone_, ta.raw()));
+ }
+ klass_ = klass_.SuperClass();
+ }
+ }
+}
+
+void TypeUsageInfo::BuildTypeUsageInformation() {
+ ClassTable* class_table = thread()->isolate()->class_table();
+ const intptr_t cid_count = class_table->NumCids();
+
+ // Step 1) Propagate instantiated type argument vectors.
+ PropagateTypeArguments(class_table, cid_count);
+
+ // Step 2) Collect the type parameters we're interested in.
+ TypeParameterSet parameters_tested_against;
+ CollectTypeParametersUsedInAssertAssignable(¶meters_tested_against);
+
+ // Step 2) Add all types which flow into a type parameter we test against to
+ // the set of types tested against.
+ UpdateAssertAssignableTypes(class_table, cid_count,
+ ¶meters_tested_against);
+}
+
+void TypeUsageInfo::PropagateTypeArguments(ClassTable* class_table,
+ intptr_t cid_count) {
+ // See comment in .h file for what this method does.
+
+ Class& klass = Class::Handle(zone_);
+ TypeArguments& temp_type_arguments = TypeArguments::Handle(zone_);
+
+ // We cannot modify a set while we are iterating over it, so we delay the
+ // addition to the set to the point when iteration has finished and use this
+ // list as temporary storage.
+ GrowableObjectArray& delayed_type_argument_set =
+ GrowableObjectArray::Handle(zone_, GrowableObjectArray::New());
+
+ TypeArgumentInstantiator instantiator(zone_);
+
+ const intptr_t kPropgationRounds = 2;
+ for (intptr_t round = 0; round < kPropgationRounds; ++round) {
+ for (intptr_t cid = 0; cid < cid_count; ++cid) {
+ if (!class_table->IsValidIndex(cid) ||
+ !class_table->HasValidClassAt(cid)) {
+ continue;
+ }
+
+ klass = class_table->At(cid);
+ bool null_in_delayed_type_argument_set = false;
+ delayed_type_argument_set.SetLength(0);
+
+ auto it = instance_creation_arguments_[cid].GetIterator();
+ for (const TypeArguments** type_arguments = it.Next();
+ type_arguments != nullptr; type_arguments = it.Next()) {
+ // We have a "type allocation" with "klass<type_arguments[0:N]>".
+ if (!(*type_arguments)->IsNull() &&
+ !(*type_arguments)->IsInstantiated()) {
+ const Class& enclosing_class = finder_.FindClass(**type_arguments);
+ if (!klass.IsNull()) {
+ // We know that "klass<type_arguments[0:N]>" happens inside
+ // [enclosing_class].
+ if (enclosing_class.raw() != klass.raw()) {
+ // Now we try to instantiate [type_arguments] with all the known
+ // instantiator type argument vectors of the [enclosing_class].
+ const intptr_t enclosing_class_cid = enclosing_class.id();
+ TypeArgumentsSet& instantiator_set =
+ instance_creation_arguments_[enclosing_class_cid];
+ auto it2 = instantiator_set.GetIterator();
+ for (const TypeArguments** instantiator_type_arguments =
+ it2.Next();
+ instantiator_type_arguments != nullptr;
+ instantiator_type_arguments = it2.Next()) {
+ // We have also a "type allocation" with
+ // "enclosing_class<instantiator_type_arguments[0:M]>".
+ if ((*instantiator_type_arguments)->IsNull() ||
+ (*instantiator_type_arguments)->IsInstantiated()) {
+ temp_type_arguments = instantiator.Instantiate(
+ klass, **type_arguments, **instantiator_type_arguments);
+ if (temp_type_arguments.IsNull() &&
+ !null_in_delayed_type_argument_set) {
+ null_in_delayed_type_argument_set = true;
+ delayed_type_argument_set.Add(temp_type_arguments);
+ } else {
+ delayed_type_argument_set.Add(temp_type_arguments);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Now we add the [delayed_type_argument_set] elements to the set of
+ // instantiator type arguments of [klass] (and its superclasses).
+ if (delayed_type_argument_set.Length() > 0) {
+ while (klass.NumTypeArguments() > 0) {
+ TypeArgumentsSet& type_argument_set =
+ instance_creation_arguments_[klass.id()];
+ const intptr_t len = delayed_type_argument_set.Length();
+ for (intptr_t i = 0; i < len; ++i) {
+ temp_type_arguments =
+ TypeArguments::RawCast(delayed_type_argument_set.At(i));
+ if (!type_argument_set.HasKey(&temp_type_arguments)) {
+ type_argument_set.Insert(
+ &TypeArguments::ZoneHandle(zone_, temp_type_arguments.raw()));
+ }
+ }
+ klass = klass.SuperClass();
+ }
+ }
+ }
+ }
+}
+
+void TypeUsageInfo::CollectTypeParametersUsedInAssertAssignable(
+ TypeParameterSet* set) {
+ TypeParameter& param = TypeParameter::Handle(zone_);
+ auto it = assert_assignable_types_.GetIterator();
+ for (const AbstractType** type = it.Next(); type != nullptr;
+ type = it.Next()) {
+ AddToSetIfParameter(set, *type, ¶m);
+ }
+}
+
+void TypeUsageInfo::UpdateAssertAssignableTypes(
+ ClassTable* class_table,
+ intptr_t cid_count,
+ TypeParameterSet* parameters_tested_against) {
+ Class& klass = Class::Handle(zone_);
+ TypeParameter& param = TypeParameter::Handle(zone_);
+ TypeArguments& params = TypeArguments::Handle(zone_);
+ AbstractType& type = AbstractType::Handle(zone_);
+
+ // Because Object/dynamic are common values for type parameters, we add them
+ // eagerly and avoid doing it down inside the loop.
+ type = Type::DynamicType();
+ UseTypeInAssertAssignable(type);
+ type = Type::ObjectType();
+ UseTypeInAssertAssignable(type);
+
+ for (intptr_t cid = 0; cid < cid_count; ++cid) {
+ if (!class_table->IsValidIndex(cid) || !class_table->HasValidClassAt(cid)) {
+ continue;
+ }
+ klass = class_table->At(cid);
+ if (klass.NumTypeArguments() <= 0) {
+ continue;
+ }
+
+ const intptr_t num_parameters = klass.NumTypeParameters();
+ params = klass.type_parameters();
+ for (intptr_t i = 0; i < num_parameters; ++i) {
+ param ^= params.TypeAt(i);
+ if (parameters_tested_against->HasKey(¶m)) {
+ TypeArgumentsSet& ta_set = instance_creation_arguments_[cid];
+ auto it = ta_set.GetIterator();
+ for (const TypeArguments** ta = it.Next(); ta != nullptr;
+ ta = it.Next()) {
+ // We only add instantiated types to the set (and dynamic/Object were
+ // already handled above).
+ if (!(*ta)->IsNull()) {
+ type ^= (*ta)->TypeAt(i);
+ if (type.IsInstantiated()) {
+ UseTypeInAssertAssignable(type);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void TypeUsageInfo::AddToSetIfParameter(TypeParameterSet* set,
+ const AbstractType* type,
+ TypeParameter* param) {
+ if (type->IsTypeParameter()) {
+ *param ^= type->raw();
+ if (!param->IsNull() && !set->HasKey(param)) {
+ set->Insert(&TypeParameter::Handle(zone_, param->raw()));
+ }
+ }
+}
+
+void TypeUsageInfo::AddTypeToSet(TypeSet* set, const AbstractType* type) {
+ if (!set->HasKey(type)) {
+ set->Insert(&AbstractType::ZoneHandle(zone_, type->raw()));
+ }
+}
+
+bool TypeUsageInfo::IsUsedInTypeTest(const AbstractType& type) {
+ const AbstractType* dereferenced_type = &type;
+ if (type.IsTypeRef()) {
+ dereferenced_type = &AbstractType::Handle(TypeRef::Cast(type).type());
+ }
+ if (dereferenced_type->IsResolved() && dereferenced_type->IsFinalized()) {
+ return assert_assignable_types_.HasKey(dereferenced_type);
+ }
+ return false;
+}
+
+} // namespace dart
diff --git a/runtime/vm/type_testing_stubs.h b/runtime/vm/type_testing_stubs.h
new file mode 100644
index 0000000..d03b48a
--- /dev/null
+++ b/runtime/vm/type_testing_stubs.h
@@ -0,0 +1,412 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_TYPE_TESTING_STUBS_H_
+#define RUNTIME_VM_TYPE_TESTING_STUBS_H_
+
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/backend/il.h"
+
+namespace dart {
+
+class TypeTestingStubNamer {
+ public:
+ TypeTestingStubNamer();
+
+ // Simple helper for stringinfying a [type] and prefix it with the type
+ // testing
+ //
+ // (only during dart_boostrap).
+ const char* StubNameForType(const AbstractType& type) const;
+
+ private:
+ const char* StringifyType(const AbstractType& type) const;
+ static const char* AssemblerSafeName(char* cname);
+
+ Library& lib_;
+ Class& klass_;
+ AbstractType& type_;
+ TypeArguments& type_arguments_;
+ String& string_;
+};
+
+class TypeTestingStubGenerator {
+ public:
+ // During bootstrapping it will return `null` for a whitelisted set of types,
+ // otherwise it will return a default stub which tail-calls
+ // subtypingtest/runtime code.
+ static RawInstructions* DefaultCodeForType(const AbstractType& type);
+
+ TypeTestingStubGenerator();
+
+ // Creates new stub for [type] (and registers the tuple in object store
+ // array) or returns default stub.
+ RawInstructions* OptimizedCodeForType(const AbstractType& type);
+
+ private:
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ RawInstructions* BuildCodeForType(const Type& type);
+ static void BuildOptimizedTypeTestStub(Assembler* assembler,
+ HierarchyInfo* hi,
+ const Type& type,
+ const Class& type_class);
+
+ static void BuildOptimizedTypeTestStubFastCases(Assembler* assembler,
+ HierarchyInfo* hi,
+ const Type& type,
+ const Class& type_class,
+ Register instance_reg,
+ Register class_id_reg);
+
+ static void BuildOptimizedSubtypeRangeCheck(Assembler* assembler,
+ const CidRangeVector& ranges,
+ Register class_id_reg,
+ Register instance_reg,
+ bool smi_is_ok);
+
+ static void BuildOptimizedSubclassRangeCheckWithTypeArguments(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const Class& type_class,
+ const TypeArguments& type_parameters,
+ const TypeArguments& type_arguments);
+
+ static void BuildOptimizedSubclassRangeCheckWithTypeArguments(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const Class& type_class,
+ const TypeArguments& type_parameters,
+ const TypeArguments& type_arguments,
+ const Register class_id_reg,
+ const Register instance_reg,
+ const Register instance_type_args_reg);
+
+ static void BuildOptimizedSubclassRangeCheck(Assembler* assembler,
+ const CidRangeVector& ranges,
+ Register class_id_reg,
+ Register instance_reg,
+ Label* check_failed);
+
+ static void BuildOptimizedTypeArgumentValueCheck(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const AbstractType& type_arg,
+ intptr_t type_param_value_offset_i,
+ Label* check_failed);
+
+ static void BuildOptimizedTypeArgumentValueCheck(
+ Assembler* assembler,
+ HierarchyInfo* hi,
+ const AbstractType& type_arg,
+ intptr_t type_param_value_offset_i,
+ const Register class_id_reg,
+ const Register instance_type_args_reg,
+ const Register instantiator_type_args_reg,
+ const Register function_type_args_reg,
+ const Register type_arg_reg,
+ Label* check_failed);
+
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+#endif // !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+
+ TypeTestingStubNamer namer_;
+ ObjectStore* object_store_;
+ GrowableObjectArray& array_;
+ Instructions& instr_;
+};
+
+// It is assumed that the caller ensures, while this object lives there is no
+// other access to [Isolate::Current()->object_store()->type_testing_stubs()].
+class TypeTestingStubFinder {
+ public:
+ TypeTestingStubFinder();
+
+ // When serializing an AOT snapshot via our clustered snapshot writer, we
+ // write out references to the [Instructions] object for all the
+ // [AbstractType] objects we encounter.
+ //
+ // This method is used for this mapping of stub entrypoint addresses to the
+ // corresponding [Instructions] object.
+ RawInstructions* LookupByAddresss(uword entry_point) const;
+
+ // When generating an AOT snapshot as an assembly file (i.e. ".S" file) we
+ // need to generate labels for the type testing stubs.
+ //
+ // This method maps stub entrypoint addresses to meaningful names.
+ const char* StubNameFromAddresss(uword entry_point) const;
+
+ private:
+ // Sorts the tuples in [array_] according to entrypoint.
+ void SortTableForFastLookup();
+
+ // Returns the tuple index where [entry_point] was found.
+ intptr_t LookupInSortedArray(uword entry_point) const;
+
+ TypeTestingStubNamer namer_;
+ GrowableObjectArray& array_;
+ AbstractType& type_;
+ Code& code_;
+ Instructions& instr_;
+};
+
+template <typename T>
+class ReusableHandleStack {
+ public:
+ explicit ReusableHandleStack(Zone* zone) : zone_(zone), handles_count_(0) {}
+
+ T* Obtain() {
+ T* handle;
+ if (handles_count_ < handles_.length()) {
+ handle = handles_[handles_count_];
+ } else {
+ handle = &T::ZoneHandle(zone_);
+ handles_.Add(handle);
+ }
+ handles_count_++;
+ return handle;
+ }
+
+ // The released [handle] can be used even after releasing until the next
+ // call to [Obtain].
+ void Release(T* handle) {
+ handles_count_--;
+ ASSERT(handles_count_ >= 0);
+ ASSERT(handles_[handles_count_] == handle);
+ }
+
+ Zone* zone_;
+
+ intptr_t handles_count_;
+ MallocGrowableArray<T*> handles_;
+};
+
+// Attempts to find a [Class] from un-instantiated [TypeArgument] vector to
+// which it's type parameters are referring to.
+//
+// If the given type argument vector contains references to type parameters,
+// this finder will either return a valid class if all of the type parameters
+// come from the same class and returns `null` otherwise.
+//
+// It is safe to use this class inside loops since the implementation uses a
+// [ReusableHandleStack] (which in pratice will only use a handful of handles).
+class TypeArgumentClassFinder {
+ public:
+ explicit TypeArgumentClassFinder(Zone* zone)
+ : klass_(Class::Handle(zone)),
+ type_(AbstractType::Handle(zone)),
+ type_arguments_handles_(zone) {}
+
+ const Class& FindClass(const TypeArguments& ta) {
+ klass_ = Class::null();
+
+ const intptr_t len = ta.Length();
+ for (intptr_t i = 0; i < len; ++i) {
+ type_ = ta.TypeAt(i);
+ if (!FindClassFromType(type_)) {
+ klass_ = Class::null();
+ break;
+ }
+ }
+ return klass_;
+ }
+
+ private:
+ bool FindClassFromType(const AbstractType& type) {
+ if (type.IsTypeParameter()) {
+ const TypeParameter& parameter = TypeParameter::Cast(type);
+ if (!parameter.IsClassTypeParameter()) {
+ return false;
+ }
+ if (klass_.IsNull()) {
+ klass_ = parameter.parameterized_class();
+ } else {
+ // Dart has no support for nested classes.
+ ASSERT(klass_.raw() == parameter.parameterized_class());
+ }
+ return true;
+ } else if (type.IsFunctionType()) {
+ // No support for function types yet.
+ return false;
+ } else if (type.IsTypeRef()) {
+ // No support for recursive types.
+ return false;
+ } else if (type.IsType()) {
+ TypeArguments* type_arguments = type_arguments_handles_.Obtain();
+ *type_arguments = Type::Cast(type).arguments();
+ const intptr_t len = type_arguments->Length();
+ for (intptr_t i = 0; i < len; ++i) {
+ type_ = type_arguments->TypeAt(i);
+ if (!FindClassFromType(type_)) {
+ type_arguments_handles_.Release(type_arguments);
+ return false;
+ }
+ }
+ type_arguments_handles_.Release(type_arguments);
+ return true;
+ } else if (type.IsBoundedType()) {
+ // No support for bounded types.
+ return false;
+ }
+ UNREACHABLE();
+ return false;
+ }
+
+ Class& klass_;
+ AbstractType& type_;
+
+ ReusableHandleStack<TypeArguments> type_arguments_handles_;
+};
+
+// Used for instantiating a [TypeArguments] which contains references to type
+// parameters based on an instantiator [TypeArguments] vector.
+//
+// It is safe to use this class inside loops since the implementation uses a
+// [ReusableHandleStack] (which in pratice will only use a handful of handles).
+class TypeArgumentInstantiator {
+ public:
+ explicit TypeArgumentInstantiator(Zone* zone)
+ : klass_(Class::Handle(zone)),
+ type_(AbstractType::Handle(zone)),
+ instantiator_type_arguments_(TypeArguments::Handle(zone)),
+ type_arguments_handles_(zone),
+ type_handles_(zone) {}
+
+ RawTypeArguments* Instantiate(
+ const Class& klass,
+ const TypeArguments& type_arguments,
+ const TypeArguments& instantiator_type_arguments) {
+ instantiator_type_arguments_ = instantiator_type_arguments.raw();
+ return InstantiateTypeArguments(klass, type_arguments).raw();
+ }
+
+ private:
+ const TypeArguments& InstantiateTypeArguments(
+ const Class& klass,
+ const TypeArguments& type_arguments);
+
+ RawAbstractType* InstantiateType(const AbstractType& type);
+
+ Class& klass_;
+ AbstractType& type_;
+ TypeArguments& instantiator_type_arguments_;
+
+ ReusableHandleStack<TypeArguments> type_arguments_handles_;
+ ReusableHandleStack<Type> type_handles_;
+};
+
+// Collects data on how [Type] objects are used in generated code.
+class TypeUsageInfo : public StackResource {
+ public:
+ explicit TypeUsageInfo(Thread* thread);
+ ~TypeUsageInfo();
+
+ void UseTypeInAssertAssignable(const AbstractType& type);
+ void UseTypeArgumentsInInstanceCreation(const Class& klass,
+ const TypeArguments& ta);
+
+ // Finalize the collected type usage information.
+ void BuildTypeUsageInformation();
+
+ // Query if [type] is very likely used in a type test (can give
+ // false-positives and false-negatives, but tries to make a very good guess)
+ bool IsUsedInTypeTest(const AbstractType& type);
+
+ private:
+ template <typename T>
+ class ObjectSetTrait {
+ public:
+ // Typedefs needed for the DirectChainedHashMap template.
+ typedef const T* Key;
+ typedef const T* Value;
+ typedef const T* Pair;
+
+ static Key KeyOf(Pair kv) { return kv; }
+ static Value ValueOf(Pair kv) { return kv; }
+ static inline intptr_t Hashcode(Key key) { return key->Hash(); }
+ };
+
+ class TypeSetTrait : public ObjectSetTrait<const AbstractType> {
+ public:
+ static inline bool IsKeyEqual(const AbstractType* pair,
+ const AbstractType* key) {
+ return pair->Equals(*key);
+ }
+ };
+
+ class TypeArgumentsSetTrait : public ObjectSetTrait<const TypeArguments> {
+ public:
+ static inline bool IsKeyEqual(const TypeArguments* pair,
+ const TypeArguments* key) {
+ return pair->raw() == key->raw();
+ }
+ };
+
+ class TypeParameterSetTrait : public ObjectSetTrait<const TypeParameter> {
+ public:
+ static inline bool IsKeyEqual(const TypeParameter* pair,
+ const TypeParameter* key) {
+ return pair->raw() == key->raw();
+ }
+ };
+
+ typedef DirectChainedHashMap<TypeSetTrait> TypeSet;
+ typedef DirectChainedHashMap<TypeArgumentsSetTrait> TypeArgumentsSet;
+ typedef DirectChainedHashMap<TypeParameterSetTrait> TypeParameterSet;
+
+ // Runs an (early terminated) fix-point algorithm which propagates type
+ // arguments. For example:
+ //
+ // class Base<X> {}
+ //
+ // class Foo<A, B> extends Base<B> {
+ // foo() => new Map<List<B>, A>();
+ // }
+ //
+ // main() {
+ // new Foo<String, int>();
+ // new Map<double, bool>();
+ // }
+ //
+ // will end up adding new type argument vectors to the per-class instantiator
+ // type argument vector set:
+ //
+ // Foo:
+ // <int, String, int>
+ // Map:
+ // <List<int>, String>
+ // <double, bool>
+ //
+ void PropagateTypeArguments(ClassTable* class_table, intptr_t cid_count);
+
+ // Collects all type parameters we are doing assert assignable checks against.
+ void CollectTypeParametersUsedInAssertAssignable(TypeParameterSet* set);
+
+ // All types which flow into any of the type parameters in [set] will be added
+ // to the set of types we test against.
+ void UpdateAssertAssignableTypes(ClassTable* class_table,
+ intptr_t cid_count,
+ TypeParameterSet* set);
+
+ void AddToSetIfParameter(TypeParameterSet* set,
+ const AbstractType* type,
+ TypeParameter* param);
+ void AddTypeToSet(TypeSet* set, const AbstractType* type);
+
+ Zone* zone_;
+ TypeArgumentClassFinder finder_;
+ TypeSet assert_assignable_types_;
+ TypeArgumentsSet* instance_creation_arguments_;
+
+ Class& klass_;
+};
+
+void RegisterTypeArgumentsUse(const Function& function,
+ TypeUsageInfo* type_usage_info,
+ const Class& klass,
+ Definition* type_arguments);
+
+} // namespace dart
+
+#endif // RUNTIME_VM_TYPE_TESTING_STUBS_H_
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index a4ee4fa..65be0c4 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -341,6 +341,8 @@
"token_position.cc",
"token_position.h",
"type_table.h",
+ "type_testing_stubs.cc",
+ "type_testing_stubs.h",
"unibrow-inl.h",
"unibrow.cc",
"unibrow.h",
diff --git a/runtime/vm/zone.h b/runtime/vm/zone.h
index b65d2df..b892cdc 100644
--- a/runtime/vm/zone.h
+++ b/runtime/vm/zone.h
@@ -75,6 +75,14 @@
Zone* previous() const { return previous_; }
+ bool ContainsNestedZone(Zone* other) const {
+ while (other != NULL) {
+ if (this == other) return true;
+ other = other->previous_;
+ }
+ return false;
+ }
+
private:
Zone();
~Zone(); // Delete all memory associated with the zone.
diff --git a/samples-dev/swarm/UIState.dart b/samples-dev/swarm/UIState.dart
index 461c844..f2e0a9e 100644
--- a/samples-dev/swarm/UIState.dart
+++ b/samples-dev/swarm/UIState.dart
@@ -35,7 +35,7 @@
// the views for this.
window.history.replaceState(null, document.title, '#');
} else if (state != '') {
- loadFromHistory(JSON.decode(state));
+ loadFromHistory(jsonDecode(state));
}
firstEvent = false;
});
@@ -55,7 +55,7 @@
throw 'history tracking not started';
}
- String state = JSON.encode(toHistory());
+ String state = jsonEncode(toHistory());
// TODO(jmesserly): [state] should be an Object, and we should pass it to
// the state parameter instead of as a #hash URL. Right now we're working
diff --git a/samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart b/samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart
index 5a11333..76857782 100644
--- a/samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart
+++ b/samples-dev/swarm/swarm_ui_lib/util/DateUtils.dart
@@ -21,8 +21,7 @@
static const YESTERDAY = 'Yesterday';
- static const MS_IN_WEEK =
- DateTime.DAYS_PER_WEEK * Duration.MILLISECONDS_PER_DAY;
+ static const MS_IN_WEEK = DateTime.daysPerWeek * Duration.millisecondsPerDay;
// TODO(jmesserly): workaround for missing DateTime.fromDate in Dartium
// Remove this once that is implemented. See b/5055106
@@ -153,7 +152,7 @@
final today = new DateTime(now.year, now.month, now.day, 0, 0, 0, 0);
Duration delta = today.difference(then);
- if (delta.inMilliseconds < Duration.MILLISECONDS_PER_DAY) {
+ if (delta.inMilliseconds < Duration.millisecondsPerDay) {
return YESTERDAY;
} else if (delta.inMilliseconds < MS_IN_WEEK) {
return WEEKDAYS[getWeekday(then)];
@@ -175,9 +174,9 @@
static int getWeekday(DateTime dateTime) {
final unixTimeStart = new DateTime(1970, 1, 1, 0, 0, 0, 0);
int msSince1970 = dateTime.difference(unixTimeStart).inMilliseconds;
- int daysSince1970 = msSince1970 ~/ Duration.MILLISECONDS_PER_DAY;
+ int daysSince1970 = msSince1970 ~/ Duration.millisecondsPerDay;
// 1970-1-1 was Thursday
- return ((daysSince1970 + DateTime.THURSDAY) % DateTime.DAYS_PER_WEEK);
+ return ((daysSince1970 + DateTime.thursday) % DateTime.daysPerWeek);
}
/** Formats a time in H:MM A format */
@@ -203,7 +202,7 @@
}
String mm =
- twoDigits(duration.inMinutes.remainder(Duration.MINUTES_PER_HOUR));
+ twoDigits(duration.inMinutes.remainder(Duration.minutesPerHour));
return "${hours}:${mm} ${a}";
}
}
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 1e306bc..1b0f1aa 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -166,19 +166,20 @@
}
}
-Null _kNull(_) => null;
-
@patch
class int {
@patch
static int parse(String source,
{int radix, @deprecated int onError(String source)}) {
- return Primitives.parseInt(source, radix, onError);
+ int value = tryParse(source, radix: radix);
+ if (value != null) return value;
+ if (onError != null) return onError(source);
+ throw new FormatException(source);
}
@patch
static int tryParse(String source, {int radix}) {
- return Primitives.parseInt(source, radix, _kNull);
+ return Primitives.parseInt(source, radix);
}
}
@@ -187,12 +188,15 @@
@patch
static double parse(String source,
[@deprecated double onError(String source)]) {
- return Primitives.parseDouble(source, onError);
+ double value = tryParse(source);
+ if (value != null) return value;
+ if (onError != null) return onError(source);
+ throw new FormatException('Invalid double', source);
}
@patch
static double tryParse(String source) {
- return Primitives.parseDouble(source, _kNull);
+ return Primitives.parseDouble(source);
}
}
@@ -2684,7 +2688,7 @@
var resultBits = new Uint8List(8);
var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
- if (length - 53 > maxDoubleExponent) return double.INFINITY;
+ if (length - 53 > maxDoubleExponent) return double.infinity;
// The most significant bit is for the sign.
if (_isNegative) resultBits[7] = 0x80;
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index d1eae5a..28307ad 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -758,14 +758,7 @@
return JS('int', '#', hash);
}
- @NoInline()
- static int _parseIntError(String source, int handleError(String source)) {
- if (handleError == null) throw new FormatException(source);
- return handleError(source);
- }
-
- static int parseInt(
- String source, int radix, int handleError(String source)) {
+ static int parseInt(String source, int radix) {
checkString(source);
var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
var match = JS('JSExtendableArray|Null', '#.exec(#)', re, source);
@@ -777,7 +770,7 @@
// TODO(sra): It might be that the match failed due to unrecognized U+0085
// spaces. We could replace them with U+0020 spaces and try matching
// again.
- return _parseIntError(source, handleError);
+ return null;
}
String decimalMatch = match[decimalIndex];
if (radix == null) {
@@ -789,7 +782,7 @@
// Cannot fail because we know that the digits are all hex.
return JS('int', r'parseInt(#, 16)', source);
}
- return _parseIntError(source, handleError);
+ return null;
}
if (radix is! int) {
@@ -828,7 +821,7 @@
for (int i = 0; i < digitsPart.length; i++) {
int characterCode = digitsPart.codeUnitAt(i) | 0x20;
if (characterCode > maxCharCode) {
- return _parseIntError(source, handleError);
+ return null;
}
}
}
@@ -837,16 +830,7 @@
return JS('int', r'parseInt(#, #)', source, radix);
}
- @NoInline()
- static double _parseDoubleError(
- String source, double handleError(String source)) {
- if (handleError == null) {
- throw new FormatException('Invalid double', source);
- }
- return handleError(source);
- }
-
- static double parseDouble(String source, double handleError(String source)) {
+ static double parseDouble(String source) {
checkString(source);
// Notice that JS parseFloat accepts garbage at the end of the string.
// Accept only:
@@ -859,7 +843,7 @@
r'/^\s*[+-]?(?:Infinity|NaN|'
r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
source)) {
- return _parseDoubleError(source, handleError);
+ return null;
}
var result = JS('num', r'parseFloat(#)', source);
if (result.isNaN) {
@@ -867,7 +851,7 @@
if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
return result;
}
- return _parseDoubleError(source, handleError);
+ return null;
}
return result;
}
diff --git a/sdk/lib/convert/html_escape.dart b/sdk/lib/convert/html_escape.dart
index befde38..9d6804c 100644
--- a/sdk/lib/convert/html_escape.dart
+++ b/sdk/lib/convert/html_escape.dart
@@ -168,8 +168,8 @@
/**
* Create converter that escapes HTML characters.
*
- * If [mode] is provided as either [HtmlEscapeMode.ATTRIBUTE] or
- * [HtmlEscapeMode.ELEMENT], only the corresponding subset of HTML
+ * If [mode] is provided as either [HtmlEscapeMode.attribute] or
+ * [HtmlEscapeMode.element], only the corresponding subset of HTML
* characters are escaped.
* The default is to escape all HTML characters.
*/
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index 5f57649..f1ceda4 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -328,7 +328,7 @@
String _argumentsAsJson(Map arguments) {
if ((arguments == null) || (arguments.length == 0)) {
- // Fast path no arguments. Avoid calling JSON.encode.
+ // Fast path no arguments. Avoid calling jsonEncode.
return '{}';
}
return json.encode(arguments);
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 012e9ed..971f9a5 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -1254,7 +1254,7 @@
LayoutTests/fast/canvas/webgl/index-validation-verifies-too-many-indices_t01: RuntimeError, Pass # Please triage this flake
LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError, Pass # Please triage this flake
LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError, Pass # Please triage this flake
-LayoutTests/fast/css/font-face-unicode-range-load_t01: Pass, Slow
+LayoutTests/fast/css/font-face-unicode-range-load_t01: Pass, Timeout # It is not slow, but flaky when it times out.
LayoutTests/fast/multicol/newmulticol/balance_t04: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # Please triage this failure
diff --git a/tests/compiler/dart2js/codegen/type_inference3_test.dart b/tests/compiler/dart2js/codegen/type_inference3_test.dart
index 1173171..8cb9a1b 100644
--- a/tests/compiler/dart2js/codegen/type_inference3_test.dart
+++ b/tests/compiler/dart2js/codegen/type_inference3_test.dart
@@ -19,7 +19,8 @@
await compile(TEST_ONE, entry: 'sum', useKernel: useKernel,
check: (String generated) {
RegExp regexp = new RegExp(getNumberTypeCheck('(param1|b)'));
- Expect.isTrue(regexp.hasMatch(generated));
+ Expect.isTrue(
+ regexp.hasMatch(generated), '$regexp not found in:\n$generated');
});
}
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index d090da2..d15d999 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -41,26 +41,6 @@
quarantined/http_test: RuntimeError # not supported with CFE, consider deleting.
rti/rti_emission_test: Pass, Slow
rti/rti_need_test: Pass, Slow
-serialization/analysis1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/analysis3_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/analysis4_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/analysis5_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation0_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation3_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation4_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation5_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/compilation_1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/impact_test: Slow, RuntimeError # Issue 32149
-serialization/library_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/model0_test: Slow, RuntimeError # Issue 32149
-serialization/model1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/model3_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/model4_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/model5_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/model_1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/native_data_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
-serialization/reserialization_test: Slow, RuntimeError # Issue 32149
show_package_warnings_test: RuntimeError # missing errors from the FE
sourcemaps/pub_build_validity_test: Pass, RuntimeError # Investigate: passes locally, but only fails in bots.
sourcemaps/source_mapping_invokes_test: Pass, Slow
@@ -103,7 +83,6 @@
old_frontend/analyze_dart2js_helpers_test: Pass, Slow
old_frontend/duplicate_library_test: Pass, Slow
output_type_test: Pass, Slow
-serialization*: Slow, Pass
sourcemaps/source_map_pub_build_validity_test: Pass, Slow
sourcemaps/stacktrace_test: Pass, Slow
uri_retention_test: Pass, Slow
@@ -111,7 +90,6 @@
[ !$checked ]
end_to_end/exit_code_test: Skip # This tests requires checked mode.
jsinterop/declaration_test: Slow, Pass
-serialization*: Slow, Pass
[ $runtime == chrome || $runtime == ff || $runtime == firefox || $runtime == safari || $jscl ]
*: Skip # dart2js uses #import('dart:io'); and it is not self-hosted (yet).
diff --git a/tests/compiler/dart2js/end_to_end/library_env_test.dart b/tests/compiler/dart2js/end_to_end/library_env_test.dart
index 8c3ae8b..85a4498 100644
--- a/tests/compiler/dart2js/end_to_end/library_env_test.dart
+++ b/tests/compiler/dart2js/end_to_end/library_env_test.dart
@@ -55,7 +55,7 @@
const DummyCompilerInput();
Future<Input> readFromUri(Uri uri,
- {InputKind inputKind: InputKind.utf8}) async {
+ {InputKind inputKind: InputKind.UTF8}) async {
if (uri.toString().endsWith("dart_client.platform")) {
return new Binary(uri, clientPlatform.codeUnits);
} else if (uri.toString().endsWith("dart_server.platform")) {
diff --git a/tests/compiler/dart2js/equivalence/check_functions.dart b/tests/compiler/dart2js/equivalence/check_functions.dart
index 945803a..b06c4ed 100644
--- a/tests/compiler/dart2js/equivalence/check_functions.dart
+++ b/tests/compiler/dart2js/equivalence/check_functions.dart
@@ -23,11 +23,11 @@
import 'package:compiler/src/js_backend/interceptor_data.dart';
import 'package:compiler/src/js_emitter/code_emitter_task.dart';
import 'package:compiler/src/js_emitter/model.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/universe/class_set.dart';
import 'package:compiler/src/universe/world_builder.dart';
import 'package:compiler/src/world.dart';
import 'package:js_ast/js_ast.dart' as js;
+import 'equivalence_helper.dart';
import 'check_helpers.dart';
void checkClosedWorlds(ClosedWorld closedWorld1, ClosedWorld closedWorld2,
@@ -365,33 +365,6 @@
strategy: const CheckStrategy());
}
-void checkAllResolvedAsts(Compiler compiler1, Compiler compiler2,
- {bool verbose: false}) {
- checkLoadedLibraryMembers(compiler1, compiler2, (Element member1) {
- return member1 is ExecutableElement &&
- compiler1.resolution.hasResolvedAst(member1);
- }, checkResolvedAsts, verbose: verbose);
-}
-
-/// Check equivalence of [impact1] and [impact2].
-void checkResolvedAsts(
- Compiler compiler1, Element member1, Compiler compiler2, Element member2,
- {bool verbose: false}) {
- if (!compiler2.serialization.isDeserialized(member2)) {
- return;
- }
- ResolvedAst resolvedAst1 = compiler1.resolution.getResolvedAst(member1);
- ResolvedAst resolvedAst2 = compiler2.serialization.getResolvedAst(member2);
-
- if (resolvedAst1 == null || resolvedAst2 == null) return;
-
- if (verbose) {
- print('Checking resolved asts for $member1 vs $member2');
- }
-
- testResolvedAstEquivalence(resolvedAst1, resolvedAst2, const CheckStrategy());
-}
-
void checkNativeClasses(
Compiler compiler1, Compiler compiler2, TestStrategy strategy) {
Iterable<ClassEntity> nativeClasses1 = compiler1
diff --git a/tests/compiler/dart2js/equivalence/check_helpers.dart b/tests/compiler/dart2js/equivalence/check_helpers.dart
index 9191c01..4a52acc 100644
--- a/tests/compiler/dart2js/equivalence/check_helpers.dart
+++ b/tests/compiler/dart2js/equivalence/check_helpers.dart
@@ -11,9 +11,10 @@
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/resolution_types.dart';
import 'package:compiler/src/elements/types.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
import 'package:expect/expect.dart';
+import 'equivalence_helper.dart';
+
Check currentCheck;
class Check {
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/tests/compiler/dart2js/equivalence/equivalence_helper.dart
similarity index 94%
rename from pkg/compiler/lib/src/serialization/equivalence.dart
rename to tests/compiler/dart2js/equivalence/equivalence_helper.dart
index 486c774..75d497d 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/tests/compiler/dart2js/equivalence/equivalence_helper.dart
@@ -2,35 +2,35 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/// Functions for asserting equivalence across serialization.
+/// Functions for asserting equivalence across different compiler
+/// implementations.
-library dart2js.serialization.equivalence;
+library dart2js.test.equivalence;
-import '../closure.dart';
-import '../common/resolution.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../elements/resolution_types.dart';
-import '../elements/elements.dart';
-import '../elements/entities.dart';
-import '../elements/modelx.dart';
-import '../elements/jumps.dart';
-import '../elements/names.dart';
-import '../elements/types.dart';
-import '../elements/visitor.dart';
-import '../js_backend/backend_serialization.dart'
- show NativeBehaviorSerialization;
-import '../native/native.dart' show NativeBehavior;
-import '../resolution/access_semantics.dart';
-import '../resolution/send_structure.dart';
-import '../resolution/tree_elements.dart';
+import 'package:compiler/src/closure.dart';
+import 'package:compiler/src/common/resolution.dart';
+import 'package:compiler/src/constants/expressions.dart';
+import 'package:compiler/src/constants/values.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/elements/jumps.dart';
+import 'package:compiler/src/elements/modelx.dart';
+import 'package:compiler/src/elements/names.dart';
+import 'package:compiler/src/elements/resolution_types.dart';
+import 'package:compiler/src/elements/types.dart';
+import 'package:compiler/src/elements/visitor.dart';
+import 'package:compiler/src/native/native.dart'
+ show NativeBehavior, SpecialType;
+import 'package:compiler/src/resolution/access_semantics.dart';
+import 'package:compiler/src/resolution/send_structure.dart';
+import 'package:compiler/src/resolution/tree_elements.dart';
+import 'package:compiler/src/tree/nodes.dart';
+import 'package:compiler/src/universe/feature.dart';
+import 'package:compiler/src/universe/selector.dart';
+import 'package:compiler/src/universe/use.dart';
+import 'package:compiler/src/util/util.dart';
+
import 'package:front_end/src/fasta/scanner.dart';
-import '../tree/nodes.dart';
-import '../universe/selector.dart';
-import '../universe/feature.dart';
-import '../universe/use.dart';
-import '../util/util.dart';
-import 'resolved_ast_serialization.dart';
typedef bool Equivalence<E>(E a, E b, {TestStrategy strategy});
@@ -1237,27 +1237,26 @@
a,
b,
'dartTypesReturned',
- NativeBehaviorSerialization.filterDartTypes(a.typesReturned),
- NativeBehaviorSerialization.filterDartTypes(b.typesReturned)) &&
+ NativeBehaviorFilters.filterDartTypes(a.typesReturned),
+ NativeBehaviorFilters.filterDartTypes(b.typesReturned)) &&
strategy.testLists(
a,
b,
'specialTypesReturned',
- NativeBehaviorSerialization.filterSpecialTypes(a.typesReturned),
- NativeBehaviorSerialization.filterSpecialTypes(b.typesReturned)) &&
+ NativeBehaviorFilters.filterSpecialTypes(a.typesReturned),
+ NativeBehaviorFilters.filterSpecialTypes(b.typesReturned)) &&
strategy.testTypeLists(
a,
b,
'dartTypesInstantiated',
- NativeBehaviorSerialization.filterDartTypes(a.typesInstantiated),
- NativeBehaviorSerialization.filterDartTypes(b.typesInstantiated)) &&
+ NativeBehaviorFilters.filterDartTypes(a.typesInstantiated),
+ NativeBehaviorFilters.filterDartTypes(b.typesInstantiated)) &&
strategy.testLists(
a,
b,
'specialTypesInstantiated',
- NativeBehaviorSerialization.filterSpecialTypes(a.typesInstantiated),
- NativeBehaviorSerialization
- .filterSpecialTypes(b.typesInstantiated)) &&
+ NativeBehaviorFilters.filterSpecialTypes(a.typesInstantiated),
+ NativeBehaviorFilters.filterSpecialTypes(b.typesInstantiated)) &&
strategy.test(a, b, 'useGvn', a.useGvn, b.useGvn);
}
@@ -2232,3 +2231,62 @@
metadata1.annotatedElement, metadata2.annotatedElement) &&
areConstantsEquivalent(metadata1.constant, metadata2.constant);
}
+
+class NativeBehaviorFilters {
+ static const int NORMAL_TYPE = 0;
+ static const int THIS_TYPE = 1;
+ static const int SPECIAL_TYPE = 2;
+
+ static int getTypeKind(var type) {
+ if (type is DartType) {
+ // TODO(johnniwinther): Remove this when annotation are no longer resolved
+ // to this-types.
+ if (type is InterfaceType &&
+ type.typeArguments.isNotEmpty &&
+ type.typeArguments.first is TypeVariableType) {
+ return THIS_TYPE;
+ }
+ return NORMAL_TYPE;
+ }
+ return SPECIAL_TYPE;
+ }
+
+ /// Returns a list of the non-this-type [ResolutionDartType]s in [types].
+ static List<ResolutionDartType> filterDartTypes(List types) {
+ return types.where((type) => getTypeKind(type) == NORMAL_TYPE).toList();
+ }
+
+ // TODO(johnniwinther): Remove this when annotation are no longer resolved
+ // to this-types.
+ /// Returns a list of the classes of this-types in [types].
+ static List<Element> filterThisTypes(List types) {
+ return types
+ .where((type) => getTypeKind(type) == THIS_TYPE)
+ .map((type) => type.element)
+ .toList();
+ }
+
+ /// Returns a list of the names of the [SpecialType]s in [types].
+ static List<String> filterSpecialTypes(List types) {
+ return types.where((type) => getTypeKind(type) == SPECIAL_TYPE).map((t) {
+ SpecialType type = t;
+ return type.name;
+ }).toList();
+ }
+}
+
+/// Visitor that computes a node-index mapping.
+class AstIndexComputer extends Visitor {
+ final Map<Node, int> nodeIndices = <Node, int>{};
+ final List<Node> nodeList = <Node>[];
+
+ @override
+ visitNode(Node node) {
+ nodeIndices.putIfAbsent(node, () {
+ // Some nodes (like Modifier and empty NodeList) can be reused.
+ nodeList.add(node);
+ return nodeIndices.length;
+ });
+ node.visitChildren(this);
+ }
+}
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index fad8d47..1ab3749 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -587,6 +587,9 @@
} else {
print('--from kernel (strong mode)-----------------------------------');
List<String> options = [Flags.strongMode]..addAll(testOptions);
+ if (trustTypeAnnotations) {
+ options.add(Flags.omitImplicitChecks);
+ }
MemberAnnotations<IdValue> annotations = expectedMaps[strongMarker];
CompiledData compiledData2 = await computeData(
entryPoint, memorySourceFiles, computeFromKernel,
diff --git a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
index 6fa2be5..5c22fee 100644
--- a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
+++ b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
@@ -10,7 +10,6 @@
import '../type_test_helper.dart';
const List<FunctionTypeData> existentialTypeData = const <FunctionTypeData>[
- // TODO(johnniwinther): Test generic bounds when #31531 is fixed.
const FunctionTypeData('void', 'F1', '<T>(T t)'),
const FunctionTypeData('void', 'F2', '<S>(S s)'),
const FunctionTypeData('void', 'F3', '<U, V>(U u, V v)'),
@@ -31,10 +30,13 @@
factory C3.fact() => C3.gen();
C3.gen();
}
+ class C4 implements C3<C4> {}
void F9<U extends V, V>(U u, V v) {}
F10() {
void local<A extends B, B>(A a, B b) {}
}
+ void F11<Q extends C3<Q>>(Q q) {}
+ void F12<P extends C3<P>>(P p) {}
"""), compileMode: CompileMode.kernel, options: [Flags.strongMode]);
testToString(FunctionType type, String expectedToString) {
@@ -79,6 +81,8 @@
InterfaceType int_ = env['int'];
InterfaceType C1 = instantiate(env.getClass('C1'), []);
InterfaceType C2 = instantiate(env.getClass('C2'), []);
+ ClassEntity C3 = env.getClass('C3');
+ InterfaceType C4 = instantiate(env.getClass('C4'), []);
FunctionType F1 = env.getFieldType('F1');
FunctionType F2 = env.getFieldType('F2');
FunctionType F3 = env.getFieldType('F3');
@@ -89,6 +93,8 @@
FunctionType F8 = env.getFieldType('F8');
FunctionType F9 = env.getMemberType('F9');
FunctionType F10 = env.getClosureType('F10');
+ FunctionType F11 = env.getMemberType('F11');
+ FunctionType F12 = env.getMemberType('F12');
List<FunctionType> all = <FunctionType>[
F1,
@@ -101,6 +107,8 @@
F8,
F9,
F10,
+ F11,
+ F12,
];
testToString(F1, 'void Function<#A>(#A)');
@@ -113,6 +121,8 @@
testToString(F8, '#A Function<#A extends num>(#A)');
testToString(F9, 'void Function<#A extends #B,#B>(#A,#B)');
testToString(F10, 'void Function<#A extends #B,#B>(#A,#B)');
+ testToString(F11, 'void Function<#A extends C3<#A>>(#A)');
+ testToString(F12, 'void Function<#A extends C3<#A>>(#A)');
testBounds(F1, [Object_]);
testBounds(F2, [Object_]);
@@ -124,6 +134,12 @@
testBounds(F8, [num_]);
testBounds(F9, [F9.typeVariables.last, Object_]);
testBounds(F10, [F10.typeVariables.last, Object_]);
+ testBounds(F11, [
+ instantiate(C3, [F11.typeVariables.last])
+ ]);
+ testBounds(F12, [
+ instantiate(C3, [F12.typeVariables.last])
+ ]);
testInstantiate(F1, [C1], 'void Function(C1)');
testInstantiate(F2, [C2], 'void Function(C2)');
@@ -135,6 +151,8 @@
testInstantiate(F8, [int_], 'int Function(int)');
testInstantiate(F9, [int_, num_], 'void Function(int,num)');
testInstantiate(F10, [int_, num_], 'void Function(int,num)');
+ testInstantiate(F11, [C4], 'void Function(C4)');
+ testInstantiate(F12, [C4], 'void Function(C4)');
Map<FunctionType, List<FunctionType>> expectedEquals =
<FunctionType, List<FunctionType>>{
@@ -142,6 +160,8 @@
F2: [F1],
F9: [F10],
F10: [F9],
+ F11: [F12],
+ F12: [F11],
};
Map<FunctionType, List<FunctionType>> expectedSubtype =
@@ -163,8 +183,7 @@
areEqual: true);
testRelations(F1.typeVariables.first, F2.typeVariables.first);
- ClassEntity cls = env.getClass('C3');
- env.elementEnvironment.forEachConstructor(cls,
+ env.elementEnvironment.forEachConstructor(C3,
(ConstructorEntity constructor) {
Expect.equals(
0,
diff --git a/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
new file mode 100644
index 0000000..e938ddb
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/call_method_function_typed_value.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test based on language_2/call_method_function_typed_value_test/04
+
+import "package:expect/expect.dart";
+
+/*ast.element: f:[subclass=JSNumber]*/
+/*kernel.element: f:[subclass=JSNumber]*/
+/*strong.element: f:[subclass=JSInt]*/
+int f(int /*[null|subclass=Object]*/ i) => 2 /*invoke: [exact=JSUInt31]*/ * i;
+
+typedef int IntToInt(int x);
+
+/*element: test:[null]*/
+test(/*[null|subclass=Object]*/ a, /*[subclass=Closure]*/ b) =>
+ Expect.identical(a, b);
+
+/*element: main:[null]*/
+main() {
+ // It is possible to use `.call` on a function-typed value (even though it is
+ // redundant). Similarly, it is possible to tear off `.call` on a
+ // function-typed value (but it is a no-op).
+ IntToInt f2 = f;
+
+ test(f2. /*[subclass=Closure]*/ call, f);
+}
diff --git a/tests/compiler/dart2js/inference/data/closurization_instance.dart b/tests/compiler/dart2js/inference/data/closurization_instance.dart
index 13f52ca..a4b1c5f 100644
--- a/tests/compiler/dart2js/inference/data/closurization_instance.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_instance.dart
@@ -17,19 +17,17 @@
method() => 42;
}
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: closurizedCallToString:[empty]*/
+/*element: closurizedCallToString:[exact=JSString]*/
closurizedCallToString() {
var c = new Class();
var local = c. /*[exact=Class]*/ method;
local. /*invoke: [subclass=Closure]*/ toString();
local();
local
- . /*invoke: [empty]*/
+ . /*invoke: [subclass=Closure]*/
toString();
local.call();
return local
- . /*invoke: [empty]*/
+ . /*invoke: [subclass=Closure]*/
toString();
}
diff --git a/tests/compiler/dart2js/inference/data/closurization_instance_call.dart b/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
index 5a074cd..0c98bcc 100644
--- a/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_instance_call.dart
@@ -21,11 +21,7 @@
method() => 42;
}
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [exact=Class].
-/*ast.element: closurizedCallToString:[exact=JSString]*/
-/*kernel.element: closurizedCallToString:[exact=JSString]*/
-/*strong.element: closurizedCallToString:[empty]*/
+/*element: closurizedCallToString:[exact=JSString]*/
closurizedCallToString() {
var c = new Class();
c.call(); // Make `Class.call` live.
@@ -39,15 +35,15 @@
local();
local
.
- /*ast.invoke: [exact=Class]*/
- /*kernel.invoke: [exact=Class]*/
- /*strong.invoke: [empty]*/
+ /*ast.invoke: [subtype=Function]*/
+ /*kernel.invoke: [subtype=Function]*/
+ /*strong.invoke: [subclass=Closure]*/
toString();
local.call();
return local
.
- /*ast.invoke: [exact=Class]*/
- /*kernel.invoke: [exact=Class]*/
- /*strong.invoke: [empty]*/
+ /*ast.invoke: [subtype=Function]*/
+ /*kernel.invoke: [subtype=Function]*/
+ /*strong.invoke: [subclass=Closure]*/
toString();
}
diff --git a/tests/compiler/dart2js/inference/data/closurization_local_call.dart b/tests/compiler/dart2js/inference/data/closurization_local_call.dart
index 2e2cf0e..25e3bcd 100644
--- a/tests/compiler/dart2js/inference/data/closurization_local_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_local_call.dart
@@ -18,11 +18,7 @@
call() => true;
}
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [exact=Class].
-/*ast.element: closurizedCallToString:[exact=JSString]*/
-/*kernel.element: closurizedCallToString:[exact=JSString]*/
-/*strong.element: closurizedCallToString:[empty]*/
+/*element: closurizedCallToString:[exact=JSString]*/
closurizedCallToString() {
var c = new Class();
c.call(); // Make `Class.call` live.
@@ -36,15 +32,15 @@
local();
local
.
- /*ast.invoke: [exact=Class]*/
- /*kernel.invoke: [exact=Class]*/
- /*strong.invoke: [empty]*/
+ /*ast.invoke: [subtype=Function]*/
+ /*kernel.invoke: [subtype=Function]*/
+ /*strong.invoke: [subclass=Closure]*/
toString();
local.call();
return local
.
- /*ast.invoke: [exact=Class]*/
- /*kernel.invoke: [exact=Class]*/
- /*strong.invoke: [empty]*/
+ /*ast.invoke: [subtype=Function]*/
+ /*kernel.invoke: [subtype=Function]*/
+ /*strong.invoke: [subclass=Closure]*/
toString();
}
diff --git a/tests/compiler/dart2js/inference/data/closurization_static.dart b/tests/compiler/dart2js/inference/data/closurization_static.dart
index e93e641..5ddf338 100644
--- a/tests/compiler/dart2js/inference/data/closurization_static.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_static.dart
@@ -14,18 +14,16 @@
/*element: method:[exact=JSUInt31]*/
method() => 42;
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: closurizedCallToString:[empty]*/
+/*element: closurizedCallToString:[exact=JSString]*/
closurizedCallToString() {
var local = method;
local. /*invoke: [subclass=Closure]*/ toString();
local();
local
- . /*invoke: [empty]*/
+ . /*invoke: [subclass=Closure]*/
toString();
local.call();
return local
- . /*invoke: [empty]*/
+ . /*invoke: [subclass=Closure]*/
toString();
}
diff --git a/tests/compiler/dart2js/inference/data/closurization_static_call.dart b/tests/compiler/dart2js/inference/data/closurization_static_call.dart
index e4efff1..6a28213 100644
--- a/tests/compiler/dart2js/inference/data/closurization_static_call.dart
+++ b/tests/compiler/dart2js/inference/data/closurization_static_call.dart
@@ -21,11 +21,7 @@
call() => true;
}
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [exact=Class].
-/*ast.element: closurizedCallToString:[exact=JSString]*/
-/*kernel.element: closurizedCallToString:[exact=JSString]*/
-/*strong.element: closurizedCallToString:[empty]*/
+/*element: closurizedCallToString:[exact=JSString]*/
closurizedCallToString() {
var c = new Class();
c.call(); // Make `Class.call` live.
@@ -39,15 +35,15 @@
local();
local
.
- /*ast.invoke: [exact=Class]*/
- /*kernel.invoke: [exact=Class]*/
- /*strong.invoke: [empty]*/
+ /*ast.invoke: [subtype=Function]*/
+ /*kernel.invoke: [subtype=Function]*/
+ /*strong.invoke: [subclass=Closure]*/
toString();
local.call();
return local
.
- /*ast.invoke: [exact=Class]*/
- /*kernel.invoke: [exact=Class]*/
- /*strong.invoke: [empty]*/
+ /*ast.invoke: [subtype=Function]*/
+ /*kernel.invoke: [subtype=Function]*/
+ /*strong.invoke: [subclass=Closure]*/
toString();
}
diff --git a/tests/compiler/dart2js/inference/data/local_functions.dart b/tests/compiler/dart2js/inference/data/local_functions.dart
index f6b03f1..478faf2 100644
--- a/tests/compiler/dart2js/inference/data/local_functions.dart
+++ b/tests/compiler/dart2js/inference/data/local_functions.dart
@@ -94,35 +94,29 @@
// Implicit .call on a local variable.
////////////////////////////////////////////////////////////////////////////////
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: closureToString:[empty]*/
+/*element: closureToString:[exact=JSString]*/
closureToString() {
var local = /*[null]*/ () {};
local();
- return local. /*invoke: [empty]*/ toString();
+ return local. /*invoke: [subclass=Closure]*/ toString();
}
////////////////////////////////////////////////////////////////////////////////
// Explicit .call on a local variable.
////////////////////////////////////////////////////////////////////////////////
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: closureCallToString:[empty]*/
+/*element: closureCallToString:[exact=JSString]*/
closureCallToString() {
var local = /*[null]*/ () {};
local.call();
- return local. /*invoke: [empty]*/ toString();
+ return local. /*invoke: [subclass=Closure]*/ toString();
}
////////////////////////////////////////////////////////////////////////////////
// Operator == on the result of a parameter invocation.
////////////////////////////////////////////////////////////////////////////////
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: _callCompare:[empty]*/
+/*element: _callCompare:[subclass=Closure]*/
_callCompare(int /*[subclass=Closure]*/ compare({a, b})) {
compare(a: 0, b: 1) == 0;
return compare;
@@ -145,7 +139,7 @@
method1() {}
}
-/*element: _callClosure:[empty]*/
+/*element: _callClosure:[subclass=Closure]*/
_callClosure(/*[subclass=Closure]*/ f({c})) {
f(c: new Class1()).method1();
return f;
diff --git a/tests/compiler/dart2js/inference/data/local_functions_call.dart b/tests/compiler/dart2js/inference/data/local_functions_call.dart
index 308de0f..586bf73 100644
--- a/tests/compiler/dart2js/inference/data/local_functions_call.dart
+++ b/tests/compiler/dart2js/inference/data/local_functions_call.dart
@@ -15,14 +15,12 @@
// Explicit .call on a local variable.
////////////////////////////////////////////////////////////////////////////////
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: closureCallToString:[empty]*/
+/*element: closureCallToString:[exact=JSString]*/
closureCallToString() {
var local = /*[null]*/ () {};
local.call();
return local
.
- /*invoke: [empty]*/
+ /*invoke: [subclass=Closure]*/
toString();
}
diff --git a/tests/compiler/dart2js/inference/data/locals_notrust.dart b/tests/compiler/dart2js/inference/data/locals_notrust.dart
index bf14080..35f518a 100644
--- a/tests/compiler/dart2js/inference/data/locals_notrust.dart
+++ b/tests/compiler/dart2js/inference/data/locals_notrust.dart
@@ -31,6 +31,7 @@
// function.
////////////////////////////////////////////////////////////////////////////////
+// TODO(johnniwinther): Trust the function type in strong mode.
/*element: _dontTrustFunctions:[exact=JSBool]*/
_dontTrustFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
dynamic c = f(0);
diff --git a/tests/compiler/dart2js/inference/data/locals_trust.dart b/tests/compiler/dart2js/inference/data/locals_trust.dart
index f3dc89b..c179e96 100644
--- a/tests/compiler/dart2js/inference/data/locals_trust.dart
+++ b/tests/compiler/dart2js/inference/data/locals_trust.dart
@@ -10,7 +10,7 @@
////////////////////////////////////////////////////////////////////////////////
// Test that we trust the explicit type of a local with
-// --trust-type-annotations.
+// --trust-type-annotations or --omit-implicit-checks.
////////////////////////////////////////////////////////////////////////////////
/*element: _trustLocals:[exact=JSBool]*/ _trustLocals(
@@ -27,9 +27,10 @@
////////////////////////////////////////////////////////////////////////////////
// Test that we don't trust the type of a function even with
-// --trust-type-annotations.
+// --trust-type-annotations or --omit-implicit-checks.
////////////////////////////////////////////////////////////////////////////////
+// TODO(johnniwinther): Trust the function type in strong mode.
/*element: _dontTrustFunctions:[exact=JSBool]*/
_dontTrustFunctions(int Function(int) /*[null|subclass=Closure]*/ f) {
dynamic c = f(0);
diff --git a/tests/compiler/dart2js/inference/data/parameters_notrust.dart b/tests/compiler/dart2js/inference/data/parameters_notrust.dart
new file mode 100644
index 0000000..41503d2
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/parameters_notrust.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+/*element: main:[null]*/
+main() {
+ dontTrustParameters();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Test that we don't trust the explicit type of a parameter, but do trust
+// the local type of parameters in Dart 2.
+//
+// This means that in both Dart 1 and Dart 2 we infer the parameter type to be
+// either an int or a String. In Dart 1 we don't trust the static type of the
+// parameter within the method, so the return type is inferred to be either an
+// int or a String. In Dart 2 we _do_ trust the static type of the parameter
+// within the method and therefore infer the return type to be an int.
+////////////////////////////////////////////////////////////////////////////////
+
+/*ast.element: _dontTrustParameters:Union([exact=JSString], [exact=JSUInt31])*/
+/*kernel.element: _dontTrustParameters:Union([exact=JSString], [exact=JSUInt31])*/
+/*strong.element: _dontTrustParameters:[exact=JSUInt31]*/
+_dontTrustParameters(int /*Union([exact=JSString], [exact=JSUInt31])*/ i) {
+ return i;
+}
+
+/*element: dontTrustParameters:[null]*/
+dontTrustParameters() {
+ dynamic f = _dontTrustParameters;
+ Expect.equals(0, f(0));
+ Expect.throws(/*[null|subclass=Object]*/ () => f('foo'));
+}
diff --git a/tests/compiler/dart2js/inference/data/parameters_trust.dart b/tests/compiler/dart2js/inference/data/parameters_trust.dart
index a36baa9..3b7ff13 100644
--- a/tests/compiler/dart2js/inference/data/parameters_trust.dart
+++ b/tests/compiler/dart2js/inference/data/parameters_trust.dart
@@ -11,16 +11,11 @@
////////////////////////////////////////////////////////////////////////////////
// Test that we trust the explicit type of a parameter with
-// --trust-type-annotations.
+// --trust-type-annotations or --omit-implicit-checks.
////////////////////////////////////////////////////////////////////////////////
/*element: _trustParameters:[exact=JSUInt31]*/
-_trustParameters(
- int
- /*ast.[exact=JSUInt31]*/
- /*kernel.[exact=JSUInt31]*/
- /*strong.Union([exact=JSString], [exact=JSUInt31])*/
- i) {
+_trustParameters(int /*[exact=JSUInt31]*/ i) {
return i;
}
diff --git a/tests/compiler/dart2js/inference/data/refine_locals.dart b/tests/compiler/dart2js/inference/data/refine_locals.dart
index c7c328c..54a4013 100644
--- a/tests/compiler/dart2js/inference/data/refine_locals.dart
+++ b/tests/compiler/dart2js/inference/data/refine_locals.dart
@@ -178,16 +178,14 @@
// Refine the type of a local variable through a sequence of invocations.
////////////////////////////////////////////////////////////////////////////////
-/*element: _refineToClosureLocal:[empty]*/
+/*element: _refineToClosureLocal:[subclass=Closure]*/
_refineToClosureLocal() {
var f = /*[null]*/ ({/*[exact=JSUInt31]*/ a}) {};
f(a: 0);
return f;
}
-// TODO(johnniwinther): Fix the refined type. Missing call methods in the closed
-// world leads to concluding [empty].
-/*element: _refineToClosureLocalCall:[empty]*/
+/*element: _refineToClosureLocalCall:[subclass=Closure]*/
_refineToClosureLocalCall() {
var f = /*[null]*/ ({/*[exact=JSUInt31]*/ b}) {};
f.call(b: 0);
diff --git a/tests/compiler/dart2js/kernel/arguments.dart b/tests/compiler/dart2js/kernel/arguments.dart
new file mode 100644
index 0000000..11374c0
--- /dev/null
+++ b/tests/compiler/dart2js/kernel/arguments.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.kernel.arguments;
+
+import 'package:compiler/src/filenames.dart';
+
+class Arguments {
+ final String filename;
+ final int start;
+ final int end;
+ final bool verbose;
+
+ const Arguments({this.filename, this.start, this.end, this.verbose: false});
+
+ factory Arguments.from(List<String> arguments) {
+ String filename;
+ int start;
+ int end;
+ for (String arg in arguments) {
+ if (!arg.startsWith('-')) {
+ int index = int.parse(arg, onError: (_) => null);
+ if (index == null) {
+ filename = arg;
+ } else if (start == null) {
+ start = index;
+ } else {
+ end = index;
+ }
+ }
+ }
+ bool verbose = arguments.contains('-v');
+ return new Arguments(
+ filename: filename, start: start, end: end, verbose: verbose);
+ }
+
+ Uri get uri {
+ if (filename != null) {
+ return Uri.base.resolve(nativeToUriPath(filename));
+ }
+ return null;
+ }
+}
diff --git a/tests/compiler/dart2js/kernel/closed_world2_test.dart b/tests/compiler/dart2js/kernel/closed_world2_test.dart
index fe9b70d..d21a95d 100644
--- a/tests/compiler/dart2js/kernel/closed_world2_test.dart
+++ b/tests/compiler/dart2js/kernel/closed_world2_test.dart
@@ -18,14 +18,14 @@
import 'package:compiler/src/js_backend/backend_usage.dart';
import 'package:compiler/src/kernel/element_map.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/universe/world_builder.dart';
import 'package:compiler/src/util/util.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import '../memory_compiler.dart';
-import '../serialization/helper.dart';
import '../equivalence/check_functions.dart';
+import '../equivalence/equivalence_helper.dart';
+import 'arguments.dart';
import 'compiler_helper.dart';
import 'test_helpers.dart';
diff --git a/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart b/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart
index 5dc6689..21dd30e 100644
--- a/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart
+++ b/tests/compiler/dart2js/kernel/closed_world_from_dill_test.dart
@@ -22,10 +22,9 @@
import 'package:expect/expect.dart';
import '../memory_compiler.dart';
import '../equivalence/check_functions.dart';
-import '../serialization/helper.dart';
-import 'test_helpers.dart';
-
+import 'arguments.dart';
import 'compiler_helper.dart';
+import 'test_helpers.dart';
const SOURCE = const {
'main.dart': '''
diff --git a/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart b/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart
index e6e987e..0de692d 100644
--- a/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart
+++ b/tests/compiler/dart2js/kernel/compile_from_dill_test_helper.dart
@@ -17,17 +17,17 @@
import 'package:compiler/src/kernel/element_map.dart';
import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/universe/world_builder.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import '../memory_compiler.dart';
import '../equivalence/check_functions.dart';
import '../equivalence/check_helpers.dart';
-import '../serialization/helper.dart';
-import 'test_helpers.dart';
+import '../equivalence/equivalence_helper.dart';
+import 'arguments.dart';
import 'compiler_helper.dart';
+import 'test_helpers.dart';
class Test {
final Uri uri;
diff --git a/tests/compiler/dart2js/kernel/impact_test.dart b/tests/compiler/dart2js/kernel/impact_test.dart
index 42e37e7..1e21b09 100644
--- a/tests/compiler/dart2js/kernel/impact_test.dart
+++ b/tests/compiler/dart2js/kernel/impact_test.dart
@@ -17,13 +17,13 @@
import 'package:compiler/src/kernel/element_map_impl.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
import 'package:compiler/src/resolution/registry.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/universe/call_structure.dart';
import 'package:compiler/src/universe/feature.dart';
import 'package:compiler/src/universe/use.dart';
import 'package:compiler/src/util/util.dart';
import 'package:expect/expect.dart';
import '../equivalence/check_helpers.dart';
+import '../equivalence/equivalence_helper.dart';
import 'compiler_helper.dart';
import 'test_helpers.dart';
diff --git a/tests/compiler/dart2js/kernel/run_from_dill_test.dart b/tests/compiler/dart2js/kernel/run_from_dill_test.dart
index da6d490..29e526e 100644
--- a/tests/compiler/dart2js/kernel/run_from_dill_test.dart
+++ b/tests/compiler/dart2js/kernel/run_from_dill_test.dart
@@ -10,8 +10,8 @@
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
+import 'arguments.dart';
import 'compiler_helper.dart';
-import '../serialization/helper.dart';
const SOURCE = const {
'main.dart': r'''
diff --git a/tests/compiler/dart2js/kernel/test_helpers.dart b/tests/compiler/dart2js/kernel/test_helpers.dart
index cf49121..3f24c19 100644
--- a/tests/compiler/dart2js/kernel/test_helpers.dart
+++ b/tests/compiler/dart2js/kernel/test_helpers.dart
@@ -15,9 +15,10 @@
import 'package:compiler/src/kernel/element_map_impl.dart';
import 'package:compiler/src/kernel/indexed.dart';
import 'package:compiler/src/kernel/kelements.dart' show KLocalFunction;
-import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/util/util.dart';
+import '../equivalence/equivalence_helper.dart';
+
class KernelEquivalence {
final WorldDeconstructionForTesting testing;
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index a5f6d2e..88dc06c 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -85,7 +85,6 @@
{Map<String, dynamic> memorySourceFiles: const <String, dynamic>{},
Uri entryPoint,
List<Uri> entryPoints,
- List<Uri> resolutionInputs,
CompilerDiagnostics diagnosticHandler,
CompilerOutput outputProvider,
List<String> options: const <String>[],
@@ -100,7 +99,6 @@
}
CompilerImpl compiler = compilerFor(
entryPoint: entryPoint,
- resolutionInputs: resolutionInputs,
memorySourceFiles: memorySourceFiles,
diagnosticHandler: diagnosticHandler,
outputProvider: outputProvider,
@@ -132,7 +130,6 @@
CompilerImpl compilerFor(
{Uri entryPoint,
- List<Uri> resolutionInputs,
Map<String, dynamic> memorySourceFiles: const <String, dynamic>{},
CompilerDiagnostics diagnosticHandler,
CompilerOutput outputProvider,
@@ -185,7 +182,6 @@
CompilerOptions compilerOptions = CompilerOptions.parse(options,
libraryRoot: libraryRoot, platformBinaries: platformBinaries)
..entryPoint = entryPoint
- ..resolutionInputs = resolutionInputs
..packageRoot = packageRoot
..environment = {}
..packageConfig = packageConfig
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 9340024..24a93e7 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -43,7 +43,7 @@
}
Input input;
switch (inputKind) {
- case InputKind.utf8:
+ case InputKind.UTF8:
if (source is String) {
input = new StringSourceFile.fromUri(resourceUri, source);
} else {
@@ -66,6 +66,6 @@
@override
Future<Input> readFromUri(Uri resourceUri,
- {InputKind inputKind: InputKind.utf8}) =>
+ {InputKind inputKind: InputKind.UTF8}) =>
readBytesFromUri(resourceUri, inputKind);
}
diff --git a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
index 4cbd4b9..532dd9e 100644
--- a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
@@ -101,12 +101,14 @@
InterfaceType get enclosingConstructedType =>
_environment.enclosingConstructedType;
+ @override
void reportWarning(
ConstantExpression expression, MessageKind kind, Map arguments) {
errors.add(new EvaluationError(kind, arguments));
_environment.reportWarning(expression, kind, arguments);
}
+ @override
void reportError(
ConstantExpression expression, MessageKind kind, Map arguments) {
errors.add(new EvaluationError(kind, arguments));
@@ -119,6 +121,7 @@
return _environment.evaluateConstructor(constructor, type, evaluate);
}
+ @override
ConstantValue evaluateField(FieldEntity field, ConstantValue evaluate()) {
return _environment.evaluateField(field, evaluate);
}
diff --git a/tests/compiler/dart2js/old_frontend/library_resolution_test.dart b/tests/compiler/dart2js/old_frontend/library_resolution_test.dart
index 190bea2..86250d2 100644
--- a/tests/compiler/dart2js/old_frontend/library_resolution_test.dart
+++ b/tests/compiler/dart2js/old_frontend/library_resolution_test.dart
@@ -56,7 +56,7 @@
if (uri == mock2LibraryUri) {
uri = Uri.parse('memory:mock2.dart');
}
- Input input = await provider.readBytesFromUri(uri, InputKind.utf8);
+ Input input = await provider.readBytesFromUri(uri, InputKind.UTF8);
return input.data;
}
diff --git a/tests/compiler/dart2js/old_frontend/message_span_test.dart b/tests/compiler/dart2js/old_frontend/message_span_test.dart
index 35009d7..6d774bc 100644
--- a/tests/compiler/dart2js/old_frontend/message_span_test.dart
+++ b/tests/compiler/dart2js/old_frontend/message_span_test.dart
@@ -162,7 +162,7 @@
// Remove `filename:line:column:` and message.
String strippedLocationMessage = locationMessage
.substring(locationMessage.indexOf(MARKER) + MARKER.length + 1);
- // Using JSON.encode to add string quotes and backslashes.
+ // Using jsonEncode to add string quotes and backslashes.
String expected = json.encode(
utf8.decode(expectedSpanText.codeUnits, allowMalformed: true));
String actual = json.encode(utf8
diff --git a/tests/compiler/dart2js/serialization/analysis1_test.dart b/tests/compiler/dart2js/serialization/analysis1_test.dart
deleted file mode 100644
index e78f634..0000000
--- a/tests/compiler/dart2js/serialization/analysis1_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.analysis1_test;
-
-import 'analysis_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(1, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/analysis2_test.dart b/tests/compiler/dart2js/serialization/analysis2_test.dart
deleted file mode 100644
index 05c3339..0000000
--- a/tests/compiler/dart2js/serialization/analysis2_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.analysis2_test;
-
-import 'analysis_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(2, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/analysis3_test.dart b/tests/compiler/dart2js/serialization/analysis3_test.dart
deleted file mode 100644
index 84da9d9..0000000
--- a/tests/compiler/dart2js/serialization/analysis3_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.analysis3_test;
-
-import 'analysis_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(3, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/analysis4_test.dart b/tests/compiler/dart2js/serialization/analysis4_test.dart
deleted file mode 100644
index ff5c1ac..0000000
--- a/tests/compiler/dart2js/serialization/analysis4_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.analysis4_test;
-
-import 'analysis_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(4, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/analysis5_test.dart b/tests/compiler/dart2js/serialization/analysis5_test.dart
deleted file mode 100644
index 4e44643..0000000
--- a/tests/compiler/dart2js/serialization/analysis5_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.analysis5_test;
-
-import 'analysis_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(5, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/analysis_test_helper.dart b/tests/compiler/dart2js/serialization/analysis_test_helper.dart
deleted file mode 100644
index 8c48c7c..0000000
--- a/tests/compiler/dart2js/serialization/analysis_test_helper.dart
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_analysis_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/filenames.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-import 'test_data.dart';
-
-/// Number of tests that are not part of the automatic test grouping.
-int SKIP_COUNT = 0;
-
-/// Number of groups that the [TESTS] are split into.
-int SPLIT_COUNT = 5;
-
-main(List<String> args) {
- asyncTest(() async {
- Arguments arguments = new Arguments.from(args);
- SerializedData serializedData =
- await serializeDartCore(arguments: arguments);
- if (arguments.filename != null) {
- Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
- await analyze(entryPoint,
- resolutionInputs: serializedData.toUris(),
- sourceFiles: serializedData.toMemorySourceFiles());
- } else {
- await arguments.forEachTest(serializedData, TESTS, analyze);
- }
- printMeasurementResults();
- });
-}
-
-Future analyze(Uri entryPoint,
- {Map<String, String> sourceFiles: const <String, String>{},
- List<Uri> resolutionInputs,
- int index,
- Test test,
- bool verbose: false}) async {
- String testDescription = test != null ? test.name : '${entryPoint}';
- String id = index != null ? '$index: ' : '';
- String title = '${id}${testDescription}';
- await measure(title, 'analyze', () async {
- DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
- await runCompiler(
- entryPoint: entryPoint,
- resolutionInputs: resolutionInputs,
- memorySourceFiles: sourceFiles,
- options: [Flags.analyzeOnly, Flags.useOldFrontend],
- diagnosticHandler: diagnosticCollector);
- if (test != null) {
- Expect.equals(test.expectedErrorCount, diagnosticCollector.errors.length,
- "Unexpected error count.");
- Expect.equals(test.expectedWarningCount,
- diagnosticCollector.warnings.length, "Unexpected warning count.");
- Expect.equals(test.expectedHintCount, diagnosticCollector.hints.length,
- "Unexpected hint count.");
- Expect.equals(test.expectedInfoCount, diagnosticCollector.infos.length,
- "Unexpected info count.");
- }
- });
-}
diff --git a/tests/compiler/dart2js/serialization/compilation0_test.dart b/tests/compiler/dart2js/serialization/compilation0_test.dart
deleted file mode 100644
index 3e68dd2..0000000
--- a/tests/compiler/dart2js/serialization/compilation0_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation0_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSkipped(0, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation1_test.dart b/tests/compiler/dart2js/serialization/compilation1_test.dart
deleted file mode 100644
index f59e0a0..0000000
--- a/tests/compiler/dart2js/serialization/compilation1_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation1_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(1, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation2_test.dart b/tests/compiler/dart2js/serialization/compilation2_test.dart
deleted file mode 100644
index 1947010..0000000
--- a/tests/compiler/dart2js/serialization/compilation2_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation2_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(2, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation3_test.dart b/tests/compiler/dart2js/serialization/compilation3_test.dart
deleted file mode 100644
index 90bc6ff..0000000
--- a/tests/compiler/dart2js/serialization/compilation3_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation3_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(3, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation4_test.dart b/tests/compiler/dart2js/serialization/compilation4_test.dart
deleted file mode 100644
index 809f62b..0000000
--- a/tests/compiler/dart2js/serialization/compilation4_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation4_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(4, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation5_test.dart b/tests/compiler/dart2js/serialization/compilation5_test.dart
deleted file mode 100644
index 10ce5eb..0000000
--- a/tests/compiler/dart2js/serialization/compilation5_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation5_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(5, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation_1_test.dart b/tests/compiler/dart2js/serialization/compilation_1_test.dart
deleted file mode 100644
index 355cddc..0000000
--- a/tests/compiler/dart2js/serialization/compilation_1_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.compilation_1_test;
-
-import 'compilation_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSkipped(1, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/compilation_test_helper.dart b/tests/compiler/dart2js/serialization/compilation_test_helper.dart
deleted file mode 100644
index f1d22dd..0000000
--- a/tests/compiler/dart2js/serialization/compilation_test_helper.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_compilation_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/compiler_new.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/filenames.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-import 'test_data.dart';
-import '../output_collector.dart';
-
-/// Number of tests that are not part of the automatic test grouping.
-int SKIP_COUNT = 2;
-
-/// Number of groups that the [TESTS] are split into.
-int SPLIT_COUNT = 5;
-
-main(List<String> args) {
- asyncTest(() async {
- Arguments arguments = new Arguments.from(args);
- SerializedData serializedData =
- await serializeDartCore(arguments: arguments);
- if (arguments.filename != null) {
- Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
- SerializationResult result = await serialize(entryPoint,
- memorySourceFiles: serializedData.toMemorySourceFiles(),
- resolutionInputs: serializedData.toUris());
- await compile(entryPoint,
- resolutionInputs: result.serializedData.toUris(),
- sourceFiles: result.serializedData.toMemorySourceFiles());
- } else {
- await arguments.forEachTest(serializedData, TESTS, compile);
- }
- printMeasurementResults();
- });
-}
-
-Future compile(Uri entryPoint,
- {Map<String, String> sourceFiles: const <String, String>{},
- List<Uri> resolutionInputs,
- int index,
- Test test,
- bool verbose: false}) async {
- String testDescription = test != null ? test.name : '${entryPoint}';
- String id = index != null ? '$index: ' : '';
- String title = '${id}${testDescription}';
- OutputCollector outputCollector = new OutputCollector();
- await measure(title, 'compile', () async {
- List<String> options = [Flags.useOldFrontend];
- if (test != null && test.checkedMode) {
- options.add(Flags.enableCheckedMode);
- }
- await runCompiler(
- entryPoint: entryPoint,
- memorySourceFiles: sourceFiles,
- resolutionInputs: resolutionInputs,
- options: options,
- outputProvider: outputCollector);
- });
- if (verbose) {
- print(outputCollector.getOutput('', OutputType.js));
- }
-}
diff --git a/tests/compiler/dart2js/serialization/duplicate_library_test.dart b/tests/compiler/dart2js/serialization/duplicate_library_test.dart
deleted file mode 100644
index 7f8eceb..0000000
--- a/tests/compiler/dart2js/serialization/duplicate_library_test.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.duplicate_libraryc_test;
-
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common/names.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-
-void main(List<String> args) {
- asyncTest(() async {
- SerializedData data =
- await serializeDartCore(arguments: new Arguments.from(args));
- Map<String, String> sourceFiles = data.toMemorySourceFiles();
- List<Uri> resolutionInputs = data.toUris();
- Uri extraUri = Uri.parse('memory:extraUri');
- sourceFiles[extraUri.path] = data.data;
- resolutionInputs.add(extraUri);
-
- DiagnosticCollector collector = new DiagnosticCollector();
- await runCompiler(
- entryPoint: Uris.dart_core,
- memorySourceFiles: sourceFiles,
- resolutionInputs: resolutionInputs,
- diagnosticHandler: collector,
- options: [Flags.analyzeAll, Flags.useOldFrontend]);
- Expect.isTrue(collector.errors.isNotEmpty,
- "Expected duplicate serialized library errors.");
- });
-}
diff --git a/tests/compiler/dart2js/serialization/equivalence_test.dart b/tests/compiler/dart2js/serialization/equivalence_test.dart
deleted file mode 100644
index 027df4e..0000000
--- a/tests/compiler/dart2js/serialization/equivalence_test.dart
+++ /dev/null
@@ -1,855 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions= --no_limit_ints_to_64_bits
-library dart2js.serialization_test;
-
-import 'dart:io';
-import '../memory_compiler.dart';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common.dart';
-import 'package:compiler/src/common/resolution.dart';
-import 'package:compiler/src/constants/constructors.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/diagnostics/invariant.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
-import 'package:compiler/src/elements/visitor.dart';
-import 'package:compiler/src/filenames.dart';
-import 'package:compiler/src/library_loader.dart';
-import 'package:compiler/src/ordered_typeset.dart';
-import 'package:compiler/src/serialization/element_serialization.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
-import 'package:compiler/src/serialization/json_serializer.dart';
-import 'package:compiler/src/serialization/serialization.dart';
-import 'package:expect/expect.dart';
-import '../equivalence/check_helpers.dart';
-
-const TEST_SOURCES = const <String, String>{
- 'main.dart': '''
-import 'library.dart';
-import 'deferred_library.dart' deferred as prefix;
-
-asyncMethod() async {}
-asyncStarMethod() async* {}
-syncStarMethod() sync* {}
-get asyncGetter async {}
-get asyncStarGetter async* {}
-get syncStarGetter sync* {}
-
-genericMethod<T>() {}
-
-class Class1 {
- factory Class1.deferred() = prefix.DeferredClass;
- factory Class1.unresolved() = Unresolved;
-}
-''',
- 'deferred_library.dart': '''
-class DeferredClass {
-}
-
-get getter => 0;
-set setter(_) {}
-get property => 0;
-set property(_) {}
-''',
- 'library.dart': '''
-class Type {}
-''',
-};
-
-main(List<String> arguments) {
- // Ensure that we can print out constant expressions.
- DEBUG_MODE = true;
-
- Uri entryPoint;
- String outPath;
- bool prettyPrint = false;
- for (String arg in arguments) {
- if (arg.startsWith('--')) {
- if (arg.startsWith('--out=')) {
- outPath = arg.substring('--out='.length);
- } else if (arg == '--pretty-print') {
- prettyPrint = true;
- } else {
- print("Unknown option $arg");
- }
- } else {
- if (entryPoint != null) {
- print("Multiple entrypoints is not supported.");
- }
- entryPoint = Uri.base.resolve(nativeToUriPath(arg));
- }
- }
- Map<String, String> sourceFiles = const <String, String>{};
- if (entryPoint == null) {
- entryPoint = Uri.parse('memory:main.dart');
- sourceFiles = TEST_SOURCES;
- }
- asyncTest(() async {
- CompilationResult result = await runCompiler(
- memorySourceFiles: sourceFiles,
- entryPoint: entryPoint,
- options: [
- Flags.analyzeAll,
- Flags.genericMethodSyntax,
- Flags.useOldFrontend
- ]);
- Compiler compiler = result.compiler;
- testSerialization(compiler.libraryLoader.libraries, compiler.reporter,
- compiler.resolution, compiler.libraryLoader,
- outPath: outPath, prettyPrint: prettyPrint);
- Expect.isFalse(
- compiler.reporter.hasReportedError, "Unexpected errors occured.");
- });
-}
-
-void testSerialization(
- Iterable<LibraryElement> libraries1,
- DiagnosticReporter reporter,
- Resolution resolution,
- LibraryProvider libraryProvider,
- {String outPath,
- bool prettyPrint}) {
- Serializer serializer = new Serializer();
- for (LibraryElement library1 in libraries1) {
- serializer.serialize(library1);
- }
- String text = serializer.toText(const JsonSerializationEncoder());
- String outText = text;
- if (prettyPrint) {
- outText = serializer.prettyPrint();
- }
- if (outPath != null) {
- new File(outPath).writeAsStringSync(outText);
- } else if (prettyPrint) {
- print(outText);
- }
-
- Deserializer deserializer = new Deserializer.fromText(
- new DeserializationContext(reporter, resolution, libraryProvider),
- Uri.parse('out1.data'),
- text,
- const JsonSerializationDecoder());
- List<LibraryElement> libraries2 = <LibraryElement>[];
- for (LibraryElement library1 in libraries1) {
- LibraryElement library2 = deserializer.lookupLibrary(library1.canonicalUri);
- if (library2 == null) {
- throw new ArgumentError('No library ${library1.canonicalUri} found.');
- }
- checkLibraryContent('library1', 'library2', 'library', library1, library2);
- libraries2.add(library2);
- }
-
- Serializer serializer2 = new Serializer();
- for (LibraryElement library2 in libraries2) {
- serializer2.serialize(library2);
- }
- String text2 = serializer2.toText(const JsonSerializationEncoder());
-
- Deserializer deserializer3 = new Deserializer.fromText(
- new DeserializationContext(reporter, resolution, libraryProvider),
- Uri.parse('out2.data'),
- text2,
- const JsonSerializationDecoder());
- for (LibraryElement library1 in libraries1) {
- LibraryElement library2 = deserializer.lookupLibrary(library1.canonicalUri);
- if (library2 == null) {
- throw new ArgumentError('No library ${library1.canonicalUri} found.');
- }
- LibraryElement library3 =
- deserializer3.lookupLibrary(library1.canonicalUri);
- if (library3 == null) {
- throw new ArgumentError('No library ${library1.canonicalUri} found.');
- }
- checkLibraryContent('library1', 'library3', 'library', library1, library3);
- checkLibraryContent('library2', 'library3', 'library', library2, library3);
- }
-}
-
-/// Check the equivalence of [library1] and [library2] and their content.
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-checkLibraryContent(Object object1, object2, String property,
- LibraryElement library1, LibraryElement library2) {
- checkElementProperties(object1, object2, property, library1, library2);
-}
-
-/// Check the equivalence of [element1] and [element2] and their properties.
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-checkElementProperties(Object object1, object2, String property,
- Element element1, Element element2) {
- currentCheck =
- new Check(currentCheck, object1, object2, property, element1, element2);
- const ElementPropertyEquivalence().visit(element1, element2);
- currentCheck = currentCheck.parent;
-}
-
-/// Checks the equivalence of [constructor1] and [constructor2].
-void constantConstructorEquivalence(
- ConstantConstructor constructor1, ConstantConstructor constructor2) {
- const ConstantConstructorEquivalence().visit(constructor1, constructor2);
-}
-
-/// Visitor that checks the equivalence of [ConstantConstructor]s.
-class ConstantConstructorEquivalence
- extends ConstantConstructorVisitor<dynamic, ConstantConstructor> {
- const ConstantConstructorEquivalence();
-
- @override
- void visit(
- ConstantConstructor constructor1, ConstantConstructor constructor2) {
- if (identical(constructor1, constructor2)) return;
- check(constructor1, constructor2, 'kind', constructor1.kind,
- constructor2.kind);
- constructor1.accept(this, constructor2);
- }
-
- @override
- visitGenerative(GenerativeConstantConstructor constructor1,
- GenerativeConstantConstructor constructor2) {
- ResolutionInterfaceType type1 = constructor1.type;
- ResolutionInterfaceType type2 = constructor2.type;
- checkTypes(constructor1, constructor2, 'type', type1, type2);
- check(constructor1, constructor2, 'defaultValues.length',
- constructor1.defaultValues.length, constructor2.defaultValues.length);
- constructor1.defaultValues.forEach((k, v) {
- checkConstants(constructor1, constructor2, 'defaultValue[$k]', v,
- constructor2.defaultValues[k]);
- });
- check(constructor1, constructor2, 'fieldMap.length',
- constructor1.fieldMap.length, constructor2.fieldMap.length);
- constructor1.fieldMap.forEach((k1, v1) {
- bool matched = false;
- constructor2.fieldMap.forEach((k2, v2) {
- if (k1.name == k2.name &&
- k1.library.canonicalUri == k2.library.canonicalUri) {
- checkElementIdentities(
- constructor1, constructor2, 'fieldMap[${k1.name}].key', k1, k2);
- checkConstants(
- constructor1, constructor2, 'fieldMap[${k1.name}].value', v1, v2);
- matched = true;
- }
- });
- if (!matched) {
- throw 'Unmatched field $k1 = $v1';
- }
- });
- checkConstants(
- constructor1,
- constructor2,
- 'superConstructorInvocation',
- constructor1.superConstructorInvocation,
- constructor2.superConstructorInvocation);
- }
-
- @override
- visitRedirectingFactory(RedirectingFactoryConstantConstructor constructor1,
- RedirectingFactoryConstantConstructor constructor2) {
- checkConstants(
- constructor1,
- constructor2,
- 'targetConstructorInvocation',
- constructor1.targetConstructorInvocation,
- constructor2.targetConstructorInvocation);
- }
-
- @override
- visitRedirectingGenerative(
- RedirectingGenerativeConstantConstructor constructor1,
- RedirectingGenerativeConstantConstructor constructor2) {
- check(constructor1, constructor2, 'defaultValues.length',
- constructor1.defaultValues.length, constructor2.defaultValues.length);
- constructor1.defaultValues.forEach((k, v) {
- checkConstants(constructor1, constructor2, 'defaultValue[$k]', v,
- constructor2.defaultValues[k]);
- });
- checkConstants(
- constructor1,
- constructor2,
- 'thisConstructorInvocation',
- constructor1.thisConstructorInvocation,
- constructor2.thisConstructorInvocation);
- }
-
- @override
- visitErroneous(ErroneousConstantConstructor constructor1,
- ErroneousConstantConstructor constructor2) {
- throw new UnsupportedError("ConstantConstructorEquivalence.visitErroneous");
- }
-}
-
-/// Check the equivalence of the two lists of elements, [list1] and [list2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-checkElementLists(Object object1, Object object2, String property,
- Iterable<Element> list1, Iterable<Element> list2) {
- checkListEquivalence(
- object1, object2, property, list1, list2, checkElementProperties);
-}
-
-/// Check the equivalence of the two metadata annotations, [metadata1] and
-/// [metadata2].
-///
-/// Uses [object1], [object2] and [property] to provide context for failures.
-checkMetadata(Object object1, Object object2, String property,
- MetadataAnnotation metadata1, MetadataAnnotation metadata2) {
- check(object1, object2, property, metadata1, metadata2,
- areMetadataAnnotationsEquivalent);
-}
-
-/// Visitor that checks for equivalence of [Element] properties.
-class ElementPropertyEquivalence extends BaseElementVisitor<dynamic, Element> {
- const ElementPropertyEquivalence();
-
- void visit(Element element1, Element element2) {
- if (element1 == null && element2 == null) return;
- if (element1 == null || element2 == null) {
- throw currentCheck;
- }
- element1 = element1.declaration;
- element2 = element2.declaration;
- if (element1 == element2) return;
- check(element1, element2, 'kind', element1.kind, element2.kind);
- element1.accept(this, element2);
- check(element1, element2, 'isSynthesized', element1.isSynthesized,
- element2.isSynthesized);
- check(element1, element2, 'isLocal', element1.isLocal, element2.isLocal);
- check(element1, element2, 'isFinal', element1.isFinal, element2.isFinal);
- check(element1, element2, 'isConst', element1.isConst, element2.isConst);
- check(element1, element2, 'isAbstract', element1.isAbstract,
- element2.isAbstract);
- check(element1, element2, 'isStatic', element1.isStatic, element2.isStatic);
- check(element1, element2, 'isTopLevel', element1.isTopLevel,
- element2.isTopLevel);
- check(element1, element2, 'isClassMember', element1.isClassMember,
- element2.isClassMember);
- check(element1, element2, 'isInstanceMember', element1.isInstanceMember,
- element2.isInstanceMember);
- List<MetadataAnnotation> metadata1 = <MetadataAnnotation>[];
- metadata1.addAll(element1.metadata);
- if (element1.isPatched) {
- metadata1.addAll(element1.implementation.metadata);
- }
- List<MetadataAnnotation> metadata2 = <MetadataAnnotation>[];
- metadata2.addAll(element2.metadata);
- if (element2.isPatched) {
- metadata2.addAll(element2.implementation.metadata);
- }
- checkListEquivalence(
- element1, element2, 'metadata', metadata1, metadata2, checkMetadata);
- }
-
- @override
- void visitElement(Element e, Element arg) {
- throw new UnsupportedError("Unsupported element $e");
- }
-
- @override
- void visitLibraryElement(LibraryElement element1, LibraryElement element2) {
- checkElementIdentities(null, null, null, element1, element2);
- check(element1, element2, 'name', element1.name, element2.name);
- check(element1, element2, 'libraryName', element1.libraryName,
- element2.libraryName);
- visitMembers(element1, element2);
- visit(element1.entryCompilationUnit, element2.entryCompilationUnit);
-
- checkElementLists(
- element1,
- element2,
- 'compilationUnits',
- LibrarySerializer.getCompilationUnits(element1),
- LibrarySerializer.getCompilationUnits(element2));
-
- checkElementLists(
- element1,
- element2,
- 'imports',
- LibrarySerializer.getImports(element1),
- LibrarySerializer.getImports(element2));
- checkElementLists(
- element1, element2, 'exports', element1.exports, element2.exports);
-
- List<Element> imported1 = LibrarySerializer.getImportedElements(element1);
- List<Element> imported2 = LibrarySerializer.getImportedElements(element2);
- checkElementListIdentities(
- element1, element2, 'importScope', imported1, imported2);
-
- checkElementListIdentities(
- element1,
- element2,
- 'exportScope',
- LibrarySerializer.getExportedElements(element1),
- LibrarySerializer.getExportedElements(element2));
-
- for (int index = 0; index < imported1.length; index++) {
- checkImportsFor(element1, element2, imported1[index], imported2[index]);
- }
- }
-
- void checkImportsFor(
- Element element1, Element element2, Element import1, Element import2) {
- List<ImportElement> imports1 = element1.library.getImportsFor(import1);
- List<ImportElement> imports2 = element2.library.getImportsFor(import2);
- checkElementListIdentities(element1, element2,
- 'importsFor($import1/$import2)', imports1, imports2);
- }
-
- @override
- void visitCompilationUnitElement(
- CompilationUnitElement element1, CompilationUnitElement element2) {
- checkElementIdentities(
- element1, element2, 'library', element1.library, element2.library);
- check(element1, element2, 'script.resourceUri', element1.script.resourceUri,
- element2.script.resourceUri);
- List<Element> members1 = <Element>[];
- List<Element> members2 = <Element>[];
- element1.forEachLocalMember((Element member) {
- members1.add(member);
- });
- element2.forEachLocalMember((Element member) {
- members2.add(member);
- });
- checkElementListIdentities(
- element1, element2, 'localMembers', members1, members2);
- }
-
- void visitMembers(
- ScopeContainerElement element1, ScopeContainerElement element2) {
- Set<String> names = new Set<String>();
- Iterable<Element> members1 = element1.isLibrary
- ? LibrarySerializer.getMembers(element1)
- : ClassSerializer.getMembers(element1);
- Iterable<Element> members2 = element2.isLibrary
- ? LibrarySerializer.getMembers(element2)
- : ClassSerializer.getMembers(element2);
- for (Element member in members1) {
- names.add(member.name);
- }
- for (Element member in members2) {
- names.add(member.name);
- }
- element1 = element1.implementation;
- element2 = element2.implementation;
- for (String name in names) {
- Element member1 = element1.localLookup(name);
- Element member2 = element2.localLookup(name);
- if (member1 == null) {
- String message =
- 'Missing member for $member2 in\n ${members1.join('\n ')}';
- if (member2.isAbstractField) {
- // TODO(johnniwinther): Ensure abstract fields are handled correctly.
- //print(message);
- continue;
- } else {
- throw message;
- }
- }
- if (member2 == null) {
- String message =
- 'Missing member for $member1 in\n ${members2.join('\n ')}';
- if (member1.isAbstractField) {
- // TODO(johnniwinther): Ensure abstract fields are handled correctly.
- //print(message);
- continue;
- } else {
- throw message;
- }
- }
- currentCheck = new Check(
- currentCheck, element1, element2, 'member:$name', member1, member2);
- visit(member1, member2);
- currentCheck = currentCheck.parent;
- }
- }
-
- @override
- void visitClassElement(ClassElement element1, ClassElement element2) {
- checkElementIdentities(null, null, null, element1, element2);
- check(element1, element2, 'name', element1.name, element2.name);
- if (!element1.isUnnamedMixinApplication) {
- check(element1, element2, 'sourcePosition', element1.sourcePosition,
- element2.sourcePosition);
- } else {
- check(element1, element2, 'sourcePosition.uri',
- element1.sourcePosition.uri, element2.sourcePosition.uri);
- MixinApplicationElement mixin1 = element1;
- MixinApplicationElement mixin2 = element2;
- checkElementIdentities(
- mixin1, mixin2, 'subclass', mixin1.subclass, mixin2.subclass);
- checkTypes(
- mixin1, mixin2, 'mixinType', mixin1.mixinType, mixin2.mixinType);
- }
- checkElementIdentities(
- element1, element2, 'library', element1.library, element2.library);
- checkElementIdentities(element1, element2, 'compilationUnit',
- element1.compilationUnit, element2.compilationUnit);
- checkTypeLists(element1, element2, 'typeVariables', element1.typeVariables,
- element2.typeVariables);
- checkTypes(
- element1, element2, 'thisType', element1.thisType, element2.thisType);
- checkTypes(
- element1, element2, 'rawType', element1.rawType, element2.rawType);
- check(element1, element2, 'isObject', element1.isObject, element2.isObject);
- checkTypeLists(element1, element2, 'typeVariables', element1.typeVariables,
- element2.typeVariables);
- check(element1, element2, 'isAbstract', element1.isAbstract,
- element2.isAbstract);
- check(element1, element2, 'isUnnamedMixinApplication',
- element1.isUnnamedMixinApplication, element2.isUnnamedMixinApplication);
- check(element1, element2, 'isProxy', element1.isProxy, element2.isProxy);
- check(element1, element2, 'isInjected', element1.isInjected,
- element2.isInjected);
- check(element1, element2, 'isEnumClass', element1.isEnumClass,
- element2.isEnumClass);
- if (element1.isEnumClass) {
- EnumClassElement enum1 = element1;
- EnumClassElement enum2 = element2;
- checkElementLists(
- enum1, enum2, 'enumValues', enum1.enumValues, enum2.enumValues);
- }
- if (!element1.isObject) {
- checkTypes(element1, element2, 'supertype', element1.supertype,
- element2.supertype);
- }
- check(element1, element2, 'hierarchyDepth', element1.hierarchyDepth,
- element2.hierarchyDepth);
- checkTypeLists(element1, element2, 'allSupertypes',
- element1.allSupertypes.toList(), element2.allSupertypes.toList());
- OrderedTypeSet typeSet1 = element1.allSupertypesAndSelf;
- OrderedTypeSet typeSet2 = element2.allSupertypesAndSelf;
- checkListEquivalence(element1, element2, 'allSupertypes',
- typeSet1.levelOffsets, typeSet2.levelOffsets, check);
- check(element1, element2, 'allSupertypesAndSelf.levels', typeSet1.levels,
- typeSet2.levels);
- checkTypeLists(element1, element2, 'supertypes',
- typeSet1.supertypes.toList(), typeSet2.supertypes.toList());
- checkTypeLists(element1, element2, 'types', typeSet1.types.toList(),
- typeSet2.types.toList());
-
- checkTypeLists(element1, element2, 'interfaces',
- element1.interfaces.toList(), element2.interfaces.toList());
-
- List<ConstructorElement> getConstructors(ClassElement cls) {
- return cls.implementation.constructors.map((c) => c.declaration).toList();
- }
-
- checkElementLists(element1, element2, 'constructors',
- getConstructors(element1), getConstructors(element2));
-
- checkElementIdentities(
- element1,
- element2,
- 'defaultConstructor',
- element1.lookupDefaultConstructor(),
- element2.lookupDefaultConstructor());
-
- visitMembers(element1, element2);
-
- ClassElement superclass1 = element1.superclass;
- ClassElement superclass2 = element2.superclass;
- while (superclass1 != null && superclass1.isMixinApplication) {
- checkElementProperties(
- element1, element2, 'supermixin', superclass1, superclass2);
- superclass1 = superclass1.superclass;
- superclass2 = superclass2.superclass;
- }
- }
-
- @override
- void visitFieldElement(FieldElement element1, FieldElement element2) {
- checkElementIdentities(null, null, null, element1, element2);
- check(element1, element2, 'name', element1.name, element2.name);
- check(element1, element2, 'sourcePosition', element1.sourcePosition,
- element2.sourcePosition);
- checkTypes(element1, element2, 'type', element1.type, element2.type);
- checkConstants(
- element1, element2, 'constant', element1.constant, element2.constant);
- check(element1, element2, 'isTopLevel', element1.isTopLevel,
- element2.isTopLevel);
- check(element1, element2, 'isStatic', element1.isStatic, element2.isStatic);
- check(element1, element2, 'isInstanceMember', element1.isInstanceMember,
- element2.isInstanceMember);
- check(element1, element2, 'isInjected', element1.isInjected,
- element2.isInjected);
-
- checkElementIdentities(
- element1, element2, 'library', element1.library, element2.library);
- checkElementIdentities(element1, element2, 'compilationUnit',
- element1.compilationUnit, element2.compilationUnit);
- checkElementIdentities(element1, element2, 'enclosingClass',
- element1.enclosingClass, element2.enclosingClass);
- }
-
- @override
- void visitFunctionElement(
- FunctionElement element1, FunctionElement element2) {
- checkElementIdentities(null, null, null, element1, element2);
- check(element1, element2, 'name', element1.name, element2.name);
- check(element1, element2, 'sourcePosition', element1.sourcePosition,
- element2.sourcePosition);
- checkTypes(element1, element2, 'type', element1.type, element2.type);
- checkListEquivalence(element1, element2, 'parameters', element1.parameters,
- element2.parameters, checkElementProperties);
- check(element1, element2, 'isOperator', element1.isOperator,
- element2.isOperator);
- check(element1, element2, 'asyncMarker', element1.asyncMarker,
- element2.asyncMarker);
- check(element1, element2, 'isInjected', element1.isInjected,
- element2.isInjected);
-
- checkElementIdentities(
- element1, element2, 'library', element1.library, element2.library);
- checkElementIdentities(element1, element2, 'compilationUnit',
- element1.compilationUnit, element2.compilationUnit);
- checkElementIdentities(element1, element2, 'enclosingClass',
- element1.enclosingClass, element2.enclosingClass);
-
- check(
- element1,
- element2,
- 'functionSignature.type',
- element1.functionSignature.type,
- element2.functionSignature.type,
- areTypesEquivalent);
- checkElementLists(
- element1,
- element2,
- 'functionSignature.requiredParameters',
- element1.functionSignature.requiredParameters,
- element2.functionSignature.requiredParameters);
- checkElementLists(
- element1,
- element2,
- 'functionSignature.optionalParameters',
- element1.functionSignature.optionalParameters,
- element2.functionSignature.optionalParameters);
- check(
- element1,
- element2,
- 'functionSignature.requiredParameterCount',
- element1.functionSignature.requiredParameterCount,
- element2.functionSignature.requiredParameterCount);
- check(
- element1,
- element2,
- 'functionSignature.optionalParameterCount',
- element1.functionSignature.optionalParameterCount,
- element2.functionSignature.optionalParameterCount);
- check(
- element1,
- element2,
- 'functionSignature.optionalParametersAreNamed',
- element1.functionSignature.optionalParametersAreNamed,
- element2.functionSignature.optionalParametersAreNamed);
- check(
- element1,
- element2,
- 'functionSignature.hasOptionalParameters',
- element1.functionSignature.hasOptionalParameters,
- element2.functionSignature.hasOptionalParameters);
- check(
- element1,
- element2,
- 'functionSignature.parameterCount',
- element1.functionSignature.parameterCount,
- element2.functionSignature.parameterCount);
- checkElementLists(
- element1,
- element2,
- 'functionSignature.orderedOptionalParameters',
- element1.functionSignature.orderedOptionalParameters,
- element2.functionSignature.orderedOptionalParameters);
- checkTypeLists(element1, element2, 'typeVariables', element1.typeVariables,
- element2.typeVariables);
- }
-
- @override
- void visitConstructorElement(
- ConstructorElement element1, ConstructorElement element2) {
- checkElementIdentities(null, null, null, element1, element2);
- checkElementIdentities(element1, element2, 'enclosingClass',
- element1.enclosingClass, element2.enclosingClass);
- check(element1, element2, 'name', element1.name, element2.name);
- if (!element1.isSynthesized) {
- check(element1, element2, 'sourcePosition', element1.sourcePosition,
- element2.sourcePosition);
- } else {
- check(element1, element2, 'sourcePosition.uri',
- element1.sourcePosition.uri, element2.sourcePosition.uri);
- }
- checkListEquivalence(element1, element2, 'parameters', element1.parameters,
- element2.parameters, checkElementProperties);
- checkTypes(element1, element2, 'type', element1.type, element2.type);
- check(element1, element2, 'isExternal', element1.isExternal,
- element2.isExternal);
- if (element1.isConst && !element1.isExternal) {
- constantConstructorEquivalence(
- element1.constantConstructor, element2.constantConstructor);
- }
- check(element1, element2, 'isRedirectingGenerative',
- element1.isRedirectingGenerative, element2.isRedirectingGenerative);
- check(element1, element2, 'isRedirectingFactory',
- element1.isRedirectingFactory, element2.isRedirectingFactory);
- checkElementIdentities(element1, element2, 'effectiveTarget',
- element1.effectiveTarget, element2.effectiveTarget);
- if (element1.isRedirectingFactory) {
- checkElementIdentities(
- element1,
- element2,
- 'immediateRedirectionTarget',
- element1.immediateRedirectionTarget,
- element2.immediateRedirectionTarget);
- checkElementIdentities(
- element1,
- element2,
- 'redirectionDeferredPrefix',
- element1.redirectionDeferredPrefix,
- element2.redirectionDeferredPrefix);
- check(
- element1,
- element2,
- 'isEffectiveTargetMalformed',
- element1.isEffectiveTargetMalformed,
- element2.isEffectiveTargetMalformed);
- }
- checkElementIdentities(element1, element2, 'definingConstructor',
- element1.definingConstructor, element2.definingConstructor);
- check(
- element1,
- element2,
- 'effectiveTargetType',
- element1.computeEffectiveTargetType(element1.enclosingClass.thisType),
- element2.computeEffectiveTargetType(element2.enclosingClass.thisType),
- areTypesEquivalent);
- check(
- element1,
- element2,
- 'effectiveTargetType.raw',
- element1.computeEffectiveTargetType(element1.enclosingClass.rawType),
- element2.computeEffectiveTargetType(element2.enclosingClass.rawType),
- areTypesEquivalent);
- checkElementIdentities(
- element1,
- element2,
- 'immediateRedirectionTarget',
- element1.immediateRedirectionTarget,
- element2.immediateRedirectionTarget);
- checkElementIdentities(element1, element2, 'redirectionDeferredPrefix',
- element1.redirectionDeferredPrefix, element2.redirectionDeferredPrefix);
- check(element1, element2, 'isInjected', element1.isInjected,
- element2.isInjected);
- }
-
- @override
- void visitAbstractFieldElement(
- AbstractFieldElement element1, AbstractFieldElement element2) {
- visit(element1.getter, element2.getter);
- visit(element1.setter, element2.setter);
- }
-
- @override
- void visitTypeVariableElement(
- TypeVariableElement element1, TypeVariableElement element2) {
- checkElementIdentities(null, null, null, element1, element2);
- check(element1, element2, 'name', element1.name, element2.name);
- check(element1, element2, 'sourcePosition', element1.sourcePosition,
- element2.sourcePosition);
- check(element1, element2, 'index', element1.index, element2.index);
- checkTypes(element1, element2, 'type', element1.type, element2.type);
- checkTypes(element1, element2, 'bound', element1.bound, element2.bound);
- }
-
- @override
- void visitTypedefElement(TypedefElement element1, TypedefElement element2) {
- checkElementIdentities(null, null, null, element1, element2);
- check(element1, element2, 'name', element1.name, element2.name);
- check(element1, element2, 'sourcePosition', element1.sourcePosition,
- element2.sourcePosition);
- checkTypes(element1, element2, 'alias', element1.alias, element2.alias);
- checkTypeLists(element1, element2, 'typeVariables', element1.typeVariables,
- element2.typeVariables);
- checkElementIdentities(
- element1, element2, 'library', element1.library, element2.library);
- checkElementIdentities(element1, element2, 'compilationUnit',
- element1.compilationUnit, element2.compilationUnit);
- // TODO(johnniwinther): Check the equivalence of typedef parameters.
- }
-
- @override
- void visitParameterElement(
- ParameterElement element1, ParameterElement element2) {
- checkElementIdentities(null, null, null, element1, element2);
- checkElementIdentities(element1, element2, 'functionDeclaration',
- element1.functionDeclaration, element2.functionDeclaration);
- check(element1, element2, 'name', element1.name, element2.name);
- check(element1, element2, 'sourcePosition', element1.sourcePosition,
- element2.sourcePosition);
- checkTypes(element1, element2, 'type', element1.type, element2.type);
- check(element1, element2, 'isOptional', element1.isOptional,
- element2.isOptional);
- check(element1, element2, 'isNamed', element1.isNamed, element2.isNamed);
- check(element1, element2, 'name', element1.name, element2.name);
- if (element1.isOptional) {
- checkConstants(
- element1, element2, 'constant', element1.constant, element2.constant);
- }
- checkElementIdentities(element1, element2, 'compilationUnit',
- element1.compilationUnit, element2.compilationUnit);
- }
-
- @override
- void visitFieldParameterElement(
- InitializingFormalElement element1, InitializingFormalElement element2) {
- visitParameterElement(element1, element2);
- checkElementIdentities(element1, element2, 'fieldElement',
- element1.fieldElement, element2.fieldElement);
- }
-
- @override
- void visitImportElement(ImportElement element1, ImportElement element2) {
- check(element1, element2, 'uri', element1.uri, element2.uri);
- check(element1, element2, 'isDeferred', element1.isDeferred,
- element2.isDeferred);
- checkElementProperties(
- element1, element2, 'prefix', element1.prefix, element2.prefix);
- checkElementIdentities(element1, element2, 'importedLibrary',
- element1.importedLibrary, element2.importedLibrary);
- }
-
- @override
- void visitExportElement(ExportElement element1, ExportElement element2) {
- check(element1, element2, 'uri', element1.uri, element2.uri);
- checkElementIdentities(element1, element2, 'importedLibrary',
- element1.exportedLibrary, element2.exportedLibrary);
- }
-
- @override
- void visitPrefixElement(PrefixElement element1, PrefixElement element2) {
- check(element1, element2, 'isDeferred', element1.isDeferred,
- element2.isDeferred);
- checkElementIdentities(element1, element2, 'deferredImport',
- element1.deferredImport, element2.deferredImport);
- if (element1.isDeferred) {
- checkElementProperties(element1, element2, 'loadLibrary',
- element1.loadLibrary, element2.loadLibrary);
- }
- element1.forEachLocalMember((Element member1) {
- String name = member1.name;
- Element member2 = element2.lookupLocalMember(name);
- checkElementIdentities(
- element1, element2, 'lookupLocalMember:$name', member1, member2);
- checkImportsFor(element1, element2, member1, member2);
- });
- }
-
- @override
- void visitErroneousElement(
- ErroneousElement element1, ErroneousElement element2) {
- check(element1, element2, 'messageKind', element1.messageKind,
- element2.messageKind);
- }
-}
diff --git a/tests/compiler/dart2js/serialization/helper.dart b/tests/compiler/dart2js/serialization/helper.dart
deleted file mode 100644
index 4770141..0000000
--- a/tests/compiler/dart2js/serialization/helper.dart
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_helper;
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:compiler/compiler_new.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common/names.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/filenames.dart';
-
-import '../memory_compiler.dart';
-import 'test_data.dart';
-
-const String DEFAULT_DATA_FILE_NAME = 'out.data';
-
-class Arguments {
- final String filename;
- final int start;
- final int end;
- final bool loadSerializedData;
- final bool saveSerializedData;
- final String serializedDataFileName;
- final bool verbose;
-
- const Arguments(
- {this.filename,
- this.start,
- this.end,
- this.loadSerializedData: false,
- this.saveSerializedData: false,
- this.serializedDataFileName: DEFAULT_DATA_FILE_NAME,
- this.verbose: false});
-
- factory Arguments.from(List<String> arguments) {
- String filename;
- int start;
- int end;
- for (String arg in arguments) {
- if (!arg.startsWith('-')) {
- int index = int.parse(arg, onError: (_) => null);
- if (index == null) {
- filename = arg;
- } else if (start == null) {
- start = index;
- } else {
- end = index;
- }
- }
- }
- bool verbose = arguments.contains('-v');
- bool loadSerializedData = arguments.contains('-l');
- bool saveSerializedData = arguments.contains('-s');
- if (arguments.contains('--auto')) {
- File file = new File(DEFAULT_DATA_FILE_NAME);
- if (file.existsSync()) {
- loadSerializedData = true;
- } else {
- saveSerializedData = true;
- }
- }
- return new Arguments(
- filename: filename,
- start: start,
- end: end,
- verbose: verbose,
- loadSerializedData: loadSerializedData,
- saveSerializedData: saveSerializedData);
- }
-
- Uri get uri {
- if (filename != null) {
- return Uri.base.resolve(nativeToUriPath(filename));
- }
- return null;
- }
-
- Future forEachTest(SerializedData serializedData, List<Test> tests,
- TestFunction testFunction) async {
- Uri entryPoint = Uri.parse('memory:main.dart');
- int first = start ?? 0;
- int last = end ?? tests.length;
-
- for (int index = first; index < last; index++) {
- Test test = TESTS[index];
- List<SerializedData> dataList =
- await preserializeData(serializedData, test);
- Map<String, String> sourceFiles = <String, String>{};
- sourceFiles.addAll(test.sourceFiles);
- if (test.preserializedSourceFiles != null) {
- sourceFiles.addAll(test.preserializedSourceFiles);
- }
- if (test.unserializedSourceFiles != null) {
- sourceFiles.addAll(test.unserializedSourceFiles);
- }
- List<Uri> resolutionInputs = <Uri>[];
- for (SerializedData data in dataList) {
- data.expandMemorySourceFiles(sourceFiles);
- data.expandUris(resolutionInputs);
- }
- await testFunction(entryPoint,
- sourceFiles: sourceFiles,
- resolutionInputs: resolutionInputs,
- index: index,
- test: test,
- verbose: verbose);
- }
- }
-}
-
-typedef Future TestFunction(Uri entryPoint,
- {Map<String, String> sourceFiles,
- List<Uri> resolutionInputs,
- int index,
- Test test,
- bool verbose});
-
-Future<SerializedData> serializeDartCore(
- {Arguments arguments: const Arguments()}) {
- return measure('dart:core', 'serialize', () async {
- Uri uri = Uri.parse('memory:${arguments.serializedDataFileName}');
- SerializedData serializedData;
- if (arguments.loadSerializedData) {
- File file = new File(arguments.serializedDataFileName);
- if (file.existsSync()) {
- print('Loading data from $file');
- serializedData = new SerializedData(uri, file.readAsStringSync());
- }
- } else {
- SerializationResult result =
- await serialize(Uris.dart_core, dataUri: uri);
- serializedData = result.serializedData;
- }
- if (arguments.saveSerializedData) {
- File file = new File(arguments.serializedDataFileName);
- print('Saving data to $file');
- file.writeAsStringSync(serializedData.data);
- }
- return serializedData;
- });
-}
-
-class SerializationResult {
- final Compiler compiler;
- final SerializedData serializedData;
-
- SerializationResult(this.compiler, this.serializedData);
-}
-
-Future<SerializationResult> serialize(Uri entryPoint,
- {Map<String, String> memorySourceFiles: const <String, String>{},
- List<Uri> resolutionInputs: const <Uri>[],
- Uri dataUri,
- bool deserializeCompilationDataForTesting: false}) async {
- if (dataUri == null) {
- dataUri = Uri.parse('memory:${DEFAULT_DATA_FILE_NAME}');
- }
- OutputCollector outputCollector = new OutputCollector();
- Compiler compiler = compilerFor(
- options: [Flags.resolveOnly, Flags.useOldFrontend],
- memorySourceFiles: memorySourceFiles,
- resolutionInputs: resolutionInputs,
- outputProvider: outputCollector);
- compiler.serialization.deserializeCompilationDataForTesting =
- deserializeCompilationDataForTesting;
- await compiler.run(entryPoint);
- SerializedData serializedData = new SerializedData(
- dataUri, outputCollector.getOutput('', OutputType.serializationData));
- return new SerializationResult(compiler, serializedData);
-}
-
-class SerializedData {
- final Uri uri;
- final String data;
-
- SerializedData(this.uri, this.data) {
- assert(uri != null);
- assert(data != null);
- }
-
- Map<String, String> toMemorySourceFiles([Map<String, String> input]) {
- Map<String, String> sourceFiles = <String, String>{};
- if (input != null) {
- sourceFiles.addAll(input);
- }
- expandMemorySourceFiles(sourceFiles);
- return sourceFiles;
- }
-
- void expandMemorySourceFiles(Map<String, String> sourceFiles) {
- if (uri.scheme == 'memory') {
- sourceFiles[uri.path] = data;
- }
- }
-
- List<Uri> toUris([List<Uri> input]) {
- List<Uri> uris = <Uri>[];
- if (input != null) {
- uris.addAll(input);
- }
- expandUris(uris);
- return uris;
- }
-
- void expandUris(List<Uri> uris) {
- uris.add(uri);
- }
-}
-
-Future<List<SerializedData>> preserializeData(
- SerializedData serializedData, Test test) async {
- if (test == null ||
- test.preserializedSourceFiles == null ||
- test.preserializedSourceFiles.isEmpty) {
- return <SerializedData>[serializedData];
- }
-
- List<Uri> uriList = <Uri>[];
- for (String key in test.preserializedSourceFiles.keys) {
- uriList.add(Uri.parse('memory:$key'));
- }
- Map<String, String> sourceFiles = serializedData.toMemorySourceFiles();
- sourceFiles.addAll(test.preserializedSourceFiles);
- if (test.unserializedSourceFiles != null) {
- sourceFiles.addAll(test.unserializedSourceFiles);
- }
- Uri additionalDataUri = Uri.parse('memory:additional.data');
- SerializedData additionalSerializedData;
- if (test.sourceFiles.isEmpty) {
- SerializationResult result = await serialize(uriList.first,
- memorySourceFiles: sourceFiles,
- resolutionInputs: serializedData.toUris(),
- dataUri: additionalDataUri);
- additionalSerializedData = result.serializedData;
- } else {
- OutputCollector outputCollector = new OutputCollector();
- Compiler compiler = compilerFor(
- entryPoint: test.sourceFiles.isEmpty ? uriList.first : null,
- memorySourceFiles: sourceFiles,
- resolutionInputs: serializedData.toUris(),
- options: [Flags.resolveOnly, Flags.useOldFrontend],
- outputProvider: outputCollector);
- compiler.librariesToAnalyzeWhenRun = uriList;
- await compiler.run(null);
- List<LibraryElement> libraries = <LibraryElement>[];
- for (Uri uri in uriList) {
- libraries.add(compiler.libraryLoader.lookupLibrary(uri));
- }
- additionalSerializedData = new SerializedData(additionalDataUri,
- outputCollector.getOutput('', OutputType.serializationData));
- }
- return <SerializedData>[serializedData, additionalSerializedData];
-}
-
-class MeasurementResult {
- final String title;
- final String taskTitle;
- final int elapsedMilliseconds;
-
- MeasurementResult(this.title, this.taskTitle, this.elapsedMilliseconds);
-}
-
-final List<MeasurementResult> measurementResults = <MeasurementResult>[];
-
-/// Print all store [measurementResults] grouped by title and sorted by
-/// decreasing execution time.
-void printMeasurementResults() {
- Map<String, int> totals = <String, int>{};
-
- for (MeasurementResult result in measurementResults) {
- totals.putIfAbsent(result.title, () => 0);
- totals[result.title] += result.elapsedMilliseconds;
- }
-
- List<String> sorted = totals.keys.toList();
- sorted.sort((a, b) => -totals[a].compareTo(totals[b]));
-
- int paddingLength = '${totals[sorted.first]}'.length;
-
- String pad(int value) {
- String text = '$value';
- return '${' ' * (paddingLength - text.length)}$text';
- }
-
- print('================================================================');
- print('Summary:');
- for (String task in sorted) {
- int time = totals[task];
- print('${pad(time)}ms $task');
- }
-
- measurementResults.clear();
-}
-
-/// Measure execution of [task], print the result and store it in
-/// [measurementResults] for a summary.
-Future measure(String title, String taskTitle, Future task()) async {
- Stopwatch stopwatch = new Stopwatch()..start();
- print('================================================================');
- print('$taskTitle: $title');
- print('----------------------------------------------------------------');
- var result = await task();
- stopwatch.stop();
- int elapsedMilliseconds = stopwatch.elapsedMilliseconds;
- print('$taskTitle: $title: ${elapsedMilliseconds}ms');
- measurementResults
- .add(new MeasurementResult(title, taskTitle, elapsedMilliseconds));
- return result;
-}
diff --git a/tests/compiler/dart2js/serialization/impact_test.dart b/tests/compiler/dart2js/serialization/impact_test.dart
deleted file mode 100644
index 1e5ce1e..0000000
--- a/tests/compiler/dart2js/serialization/impact_test.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions= --no_limit_ints_to_64_bits
-library dart2js.serialization_impact_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/filenames.dart';
-import '../memory_compiler.dart';
-import '../equivalence/check_functions.dart';
-import 'helper.dart';
-
-main(List<String> args) {
- Arguments arguments = new Arguments.from(args);
- asyncTest(() async {
- SerializedData serializedData =
- await serializeDartCore(arguments: arguments);
- if (arguments.filename != null) {
- Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
- await check(serializedData, entryPoint);
- } else {
- Uri entryPoint = Uri.parse('memory:main.dart');
- await check(serializedData, entryPoint,
- sourceFiles: {'main.dart': 'main() {}'}, verbose: arguments.verbose);
- }
- });
-}
-
-Future check(SerializedData serializedData, Uri entryPoint,
- {Map<String, String> sourceFiles: const <String, String>{},
- bool verbose: false}) async {
- Compiler compilerNormal =
- compilerFor(memorySourceFiles: sourceFiles, options: [Flags.analyzeAll]);
- compilerNormal.impactCacheDeleter.retainCachesForTesting = true;
- await compilerNormal.run(entryPoint);
-
- Compiler compilerDeserialized = compilerFor(
- memorySourceFiles: serializedData.toMemorySourceFiles(sourceFiles),
- resolutionInputs: serializedData.toUris(),
- options: [Flags.analyzeAll]);
- compilerDeserialized.impactCacheDeleter.retainCachesForTesting = true;
- await compilerDeserialized.run(entryPoint);
-
- checkAllImpacts(compilerNormal, compilerDeserialized, verbose: verbose);
-}
diff --git a/tests/compiler/dart2js/serialization/library_test.dart b/tests/compiler/dart2js/serialization/library_test.dart
deleted file mode 100644
index 9788562..0000000
--- a/tests/compiler/dart2js/serialization/library_test.dart
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_library_test;
-
-import 'dart:async';
-import 'dart:io';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common/names.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/diagnostics/invariant.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/serialization/json_serializer.dart';
-import 'package:compiler/src/serialization/serialization.dart';
-import 'package:expect/expect.dart';
-import '../equivalence/check_functions.dart';
-import '../memory_compiler.dart';
-import 'equivalence_test.dart';
-import 'helper.dart';
-
-main(List<String> arguments) {
- // Ensure that we can print out constant expressions.
- DEBUG_MODE = true;
-
- Uri entryPoint;
- String outPath;
- int shardCount = 3;
- bool prettyPrint = false;
- for (String arg in arguments) {
- if (arg.startsWith('--')) {
- if (arg.startsWith('--out=')) {
- outPath = arg.substring('--out='.length);
- } else if (arg == '--pretty-print') {
- prettyPrint = true;
- } else if (arg.startsWith('--shards=')) {
- shardCount = int.parse(arg.substring('--shards='.length));
- } else {
- print("Unknown option $arg");
- }
- } else {
- if (entryPoint != null) {
- print("Multiple entrypoints are not supported.");
- }
- entryPoint = Uri.parse(arg);
- }
- }
- if (entryPoint == null) {
- entryPoint = Uris.dart_core;
- }
- asyncTest(() async {
- Compiler compiler =
- await compilerFor(entryPoint: entryPoint, options: [Flags.analyzeAll]);
- compiler.serialization.supportSerialization = true;
- await compiler.run(entryPoint);
- List<SerializedData> data = createData(compiler,
- outPath: outPath, prettyPrint: prettyPrint, shardCount: shardCount);
- await testAnalysis(compiler, data, entryPoint);
- });
-}
-
-List<SerializedData> createData(Compiler compiler,
- {String outPath, bool prettyPrint, int shardCount: 3}) {
- Iterable<LibraryElement> libraries1 = compiler.libraryLoader.libraries;
- if (shardCount < 1 || shardCount > libraries1.length) {
- shardCount = libraries1.length;
- }
- List<List<LibraryElement>> librarySplits = <List<LibraryElement>>[];
- int offset = 0;
- int shardSize = (libraries1.length / shardCount).ceil();
- for (int shard = 0; shard < shardCount; shard++) {
- List<LibraryElement> libraries = <LibraryElement>[];
- for (int index = 0; index < shardSize; index++) {
- if (offset + index < libraries1.length) {
- libraries.add(libraries1.elementAt(offset + index));
- }
- }
- librarySplits.add(libraries);
- offset += shardSize;
- }
- print(librarySplits.join('\n'));
- List<SerializedData> data = <SerializedData>[];
- for (int shard = 0; shard < shardCount; shard++) {
- List<LibraryElement> libraries = librarySplits[shard];
- Serializer serializer = compiler.serialization.createSerializer(libraries);
- String text = serializer.toText(const JsonSerializationEncoder());
- String outText = text;
- if (prettyPrint) {
- outText = serializer.prettyPrint();
- }
- if (outPath != null) {
- String name = outPath;
- String ext = '';
- int dotPos = outPath.lastIndexOf('.');
- if (dotPos != -1) {
- name = outPath.substring(0, dotPos);
- ext = outPath.substring(dotPos);
- }
- new File('$name$shard$ext').writeAsStringSync(outText);
- } else if (prettyPrint) {
- print(outText);
- }
- data.add(new SerializedData(Uri.parse('memory:out$shard.data'), text));
- }
- return data;
-}
-
-Future testAnalysis(
- Compiler compiler1, List<SerializedData> data, Uri entryPoint) async {
- Map<String, String> memorySourceFiles = <String, String>{};
- List<Uri> resolutionInputs = <Uri>[];
- for (int index = 0; index < data.length; index++) {
- SerializedData serializedData = data[index];
- serializedData.expandMemorySourceFiles(memorySourceFiles);
- serializedData.expandUris(resolutionInputs);
- }
- CompilationResult result = await runCompiler(
- entryPoint: entryPoint,
- memorySourceFiles: memorySourceFiles,
- resolutionInputs: resolutionInputs,
- options: [Flags.analyzeAll]);
- Compiler compiler2 = result.compiler;
- for (LibraryElement library1 in compiler1.libraryLoader.libraries) {
- LibraryElement library2 =
- compiler2.libraryLoader.lookupLibrary(library1.canonicalUri);
- if (library2 == null) {
- throw new ArgumentError('No library ${library1.canonicalUri} found.');
- }
- checkLibraryContent('library1', 'library2', 'library', library1, library2);
- checkAllResolvedAsts(compiler1, compiler2);
- checkAllImpacts(compiler1, compiler2);
- }
- Expect.isFalse(compiler2.reporter.hasReportedError, "Unexpected errors");
-}
diff --git a/tests/compiler/dart2js/serialization/members_test.dart b/tests/compiler/dart2js/serialization/members_test.dart
deleted file mode 100644
index 0ef66a6..0000000
--- a/tests/compiler/dart2js/serialization/members_test.dart
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.class_members_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/common/names.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/names.dart';
-import 'package:compiler/src/filenames.dart';
-import 'package:compiler/src/resolution/class_members.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
-import '../equivalence/check_helpers.dart';
-import '../equivalence/check_functions.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-
-main(List<String> args) {
- Arguments arguments = new Arguments.from(args);
- asyncTest(() async {
- SerializedData serializedData =
- await serializeDartCore(arguments: arguments);
- if (arguments.filename != null) {
- Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
- await checkClassMembers(serializedData, entryPoint,
- verbose: arguments.verbose);
- } else {
- await checkClassMembers(serializedData, Uris.dart_core,
- verbose: arguments.verbose);
- }
- });
-}
-
-Future checkClassMembers(SerializedData serializedData, Uri entryPoint,
- {bool verbose: false}) async {
- Compiler compilerNormal = compilerFor(options: [Flags.analyzeAll]);
- await compilerNormal.run(entryPoint);
-
- Compiler compilerDeserialized = compilerFor(
- memorySourceFiles: serializedData.toMemorySourceFiles(),
- resolutionInputs: serializedData.toUris(),
- options: [Flags.analyzeAll]);
- await compilerDeserialized.run(entryPoint);
-
- checkAllMembers(compilerNormal, compilerDeserialized, verbose: true);
-}
-
-void checkAllMembers(Compiler compiler1, Compiler compiler2,
- {bool verbose: false}) {
- checkLoadedLibraryMembers(compiler1, compiler2,
- (Element member1) => member1 is ClassElement, checkMembers,
- verbose: verbose);
-}
-
-/// Check equivalence of members of [class1] and [class2].
-void checkMembers(
- Compiler compiler1, Element _class1, Compiler compiler2, Element _class2,
- {bool verbose: false}) {
- ClassMemberMixin class1 = _class1;
- ClassMemberMixin class2 = _class2;
- if (verbose) {
- print('Checking $class1 vs $class2');
- }
- MembersCreator.computeAllClassMembers(compiler1.resolution, class1);
- MembersCreator.computeAllClassMembers(compiler2.resolution, class2);
-
- check(
- class1,
- class2,
- 'interfaceMemberAreClassMembers',
- class1.interfaceMembersAreClassMembers,
- class2.interfaceMembersAreClassMembers);
- class1.forEachClassMember((Member member1) {
- Name name1 = member1.name;
- Name name2 = convertName(name1, compiler2);
- checkMember(class1, class2, 'classMember:$name1', member1,
- class2.lookupClassMember(name2));
- });
-
- class1.forEachInterfaceMember((MemberSignature member1) {
- Name name1 = member1.name;
- Name name2 = convertName(name1, compiler2);
- checkMemberSignature(class1, class2, 'interfaceMember:$name1', member1,
- class2.lookupInterfaceMember(name2));
- });
-}
-
-Name convertName(Name name, Compiler compiler) {
- if (name.isPrivate) {
- LibraryElement library1 = name.library;
- LibraryElement library2 =
- compiler.libraryLoader.lookupLibrary(library1.canonicalUri);
- if (!areElementsEquivalent(library1, library2)) {
- throw 'Libraries ${library1} and ${library2} are not equivalent';
- }
- name = new Name(name.text, library2, isSetter: name.isSetter);
- }
- return name;
-}
-
-void checkMember(ClassElement class1, ClassElement class2, String property,
- Member member1, Member member2) {
- if (member2 == null) {
- print('$class1 class members:');
- class1.forEachClassMember((m) => print(' ${m.name} $m'));
- print('$class2 class members:');
- class2.forEachClassMember((m) => print(' ${m.name} $m'));
- throw "No member ${member1.name} in $class2 for $property";
- }
- checkMemberSignature(class1, class2, property, member1, member2);
- checkElementIdentities(
- class1, class2, '$property.element', member1.element, member2.element);
- check(class1, class2, '$property.declarer', member1.declarer,
- member2.declarer, areTypesEquivalent);
- check(
- class1, class2, '$property.isStatic', member1.isStatic, member2.isStatic);
- check(class1, class2, '$property.isDeclaredByField',
- member1.isDeclaredByField, member2.isDeclaredByField);
- check(class1, class2, '$property.isAbstract', member1.isAbstract,
- member2.isAbstract);
- if (member1.isAbstract && member1.implementation != null) {
- checkMember(class1, class2, '$property.implementation',
- member1.implementation, member2.implementation);
- }
-}
-
-void checkMemberSignature(ClassElement class1, ClassElement class2,
- String property, MemberSignature member1, MemberSignature member2) {
- if (member2 == null) {
- print('$class1 interface members:');
- class1.forEachInterfaceMember((m) => print(' ${m.name} $m'));
- print('$class2 interface members:');
- class2.forEachInterfaceMember((m) => print(' ${m.name} $m'));
- throw "No member ${member1.name} in $class2 for $property";
- }
- check(class1, class2, '$property.name', member1.name, member2.name,
- areNamesEquivalent);
- check(class1, class2, '$property.type', member1.type, member2.type,
- areTypesEquivalent);
- check(class1, class2, '$property.functionType', member1.functionType,
- member2.functionType, areTypesEquivalent);
- check(
- class1, class2, '$property.isGetter', member1.isGetter, member2.isGetter);
- check(
- class1, class2, '$property.isSetter', member1.isSetter, member2.isSetter);
- check(
- class1, class2, '$property.isMethod', member1.isMethod, member2.isMethod);
-}
diff --git a/tests/compiler/dart2js/serialization/model0_test.dart b/tests/compiler/dart2js/serialization/model0_test.dart
deleted file mode 100644
index 3731bd1..0000000
--- a/tests/compiler/dart2js/serialization/model0_test.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions= --no_limit_ints_to_64_bits
-library dart2js.serialization.model0_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSkipped(0, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model1_test.dart b/tests/compiler/dart2js/serialization/model1_test.dart
deleted file mode 100644
index aec8489..0000000
--- a/tests/compiler/dart2js/serialization/model1_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model1_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(1, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model2_test.dart b/tests/compiler/dart2js/serialization/model2_test.dart
deleted file mode 100644
index 8f02334..0000000
--- a/tests/compiler/dart2js/serialization/model2_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model2_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(2, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model3_test.dart b/tests/compiler/dart2js/serialization/model3_test.dart
deleted file mode 100644
index d3a2ff1..0000000
--- a/tests/compiler/dart2js/serialization/model3_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model3_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(3, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model4_test.dart b/tests/compiler/dart2js/serialization/model4_test.dart
deleted file mode 100644
index 5871fc2..0000000
--- a/tests/compiler/dart2js/serialization/model4_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model4_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(4, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model5_test.dart b/tests/compiler/dart2js/serialization/model5_test.dart
deleted file mode 100644
index 9cf0596..0000000
--- a/tests/compiler/dart2js/serialization/model5_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model5_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSegment(5, test.SPLIT_COUNT, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model_1_test.dart b/tests/compiler/dart2js/serialization/model_1_test.dart
deleted file mode 100644
index e74bd17..0000000
--- a/tests/compiler/dart2js/serialization/model_1_test.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.model_1_test;
-
-import 'model_test_helper.dart' as test;
-import 'test_helper.dart';
-
-main() {
- test.main(testSkipped(1, test.SKIP_COUNT));
-}
diff --git a/tests/compiler/dart2js/serialization/model_test_helper.dart b/tests/compiler/dart2js/serialization/model_test_helper.dart
deleted file mode 100644
index 976b565..0000000
--- a/tests/compiler/dart2js/serialization/model_test_helper.dart
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_model_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:expect/expect.dart';
-import 'package:compiler/src/closure.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/common_elements.dart';
-import 'package:compiler/src/constants/values.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/deferred_load.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:compiler/src/elements/entities.dart';
-import 'package:compiler/src/js_backend/js_backend.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
-import 'package:compiler/src/tree/nodes.dart';
-import 'package:compiler/src/world.dart';
-import '../memory_compiler.dart';
-import '../equivalence/check_helpers.dart';
-import '../equivalence/check_functions.dart';
-import 'helper.dart';
-import 'test_data.dart';
-
-/// Number of tests that are not part of the automatic test grouping.
-int SKIP_COUNT = 2;
-
-/// Number of groups that the [TESTS] are split into.
-int SPLIT_COUNT = 5;
-
-main(List<String> args) {
- asyncTest(() async {
- Arguments arguments = new Arguments.from(args);
- SerializedData serializedData =
- await serializeDartCore(arguments: arguments);
- if (arguments.uri != null) {
- Uri entryPoint = arguments.uri;
- SerializationResult result =
- await measure('${entryPoint}', 'serialize', () {
- return serialize(entryPoint,
- memorySourceFiles: serializedData.toMemorySourceFiles(),
- resolutionInputs: serializedData.toUris(),
- dataUri: Uri.parse('memory:test.data'));
- });
- await checkModels(entryPoint,
- sourceFiles: serializedData
- .toMemorySourceFiles(result.serializedData.toMemorySourceFiles()),
- resolutionInputs:
- serializedData.toUris(result.serializedData.toUris()));
- } else {
- await arguments.forEachTest(serializedData, TESTS, checkModels);
- }
- printMeasurementResults();
- });
-}
-
-Future checkModels(Uri entryPoint,
- {Map<String, String> sourceFiles: const <String, String>{},
- List<Uri> resolutionInputs,
- int index,
- Test test,
- bool verbose: false}) async {
- String testDescription = test != null ? test.name : '${entryPoint}';
- String id = index != null ? '$index: ' : '';
- String title = '${id}${testDescription}';
- Compiler compilerNormal = await measure(title, 'compile normal', () async {
- Compiler compilerNormal = compilerFor(
- memorySourceFiles: sourceFiles,
- options: [Flags.analyzeOnly, Flags.useOldFrontend]);
- compilerNormal.impactCacheDeleter.retainCachesForTesting = true;
- await compilerNormal.run(entryPoint);
- ElementEnvironment elementEnvironment =
- compilerNormal.frontendStrategy.elementEnvironment;
- compilerNormal.closeResolution(elementEnvironment.mainFunction);
- return compilerNormal;
- });
-
- Compiler compilerDeserialized =
- await measure(title, 'compile deserialized', () async {
- Compiler compilerDeserialized = compilerFor(
- memorySourceFiles: sourceFiles,
- resolutionInputs: resolutionInputs,
- options: [Flags.analyzeOnly, Flags.useOldFrontend]);
- compilerDeserialized.impactCacheDeleter.retainCachesForTesting = true;
- await compilerDeserialized.run(entryPoint);
- ElementEnvironment elementEnvironment =
- compilerDeserialized.frontendStrategy.elementEnvironment;
- compilerDeserialized.closeResolution(elementEnvironment.mainFunction);
- return compilerDeserialized;
- });
-
- return measure(title, 'check models', () async {
- checkAllImpacts(compilerNormal, compilerDeserialized, verbose: verbose);
- ClosedWorld closedWorld1 =
- compilerNormal.resolutionWorldBuilder.closedWorldForTesting;
- ClosedWorld closedWorld2 =
- compilerNormal.resolutionWorldBuilder.closedWorldForTesting;
- checkResolutionEnqueuers(
- closedWorld1.backendUsage,
- closedWorld2.backendUsage,
- compilerNormal.enqueuer.resolution,
- compilerDeserialized.enqueuer.resolution,
- verbose: verbose);
- checkClosedWorlds(closedWorld1, closedWorld2,
- // Serialized native data include non-live members.
- allowExtra: true,
- verbose: verbose);
- checkBackendInfo(compilerNormal, compilerDeserialized, verbose: verbose);
- });
-}
-
-void checkBackendInfo(Compiler compilerNormal, Compiler compilerDeserialized,
- {bool verbose: false}) {
- checkSets(
- compilerNormal.enqueuer.resolution.processedEntities,
- compilerDeserialized.enqueuer.resolution.processedEntities,
- "Processed element mismatch",
- areEntitiesEquivalent, onSameElement: (a, b) {
- checkElements(compilerNormal, compilerDeserialized, a, b, verbose: verbose);
- }, verbose: verbose);
- Expect.equals(
- compilerNormal.deferredLoadTask.isProgramSplit,
- compilerDeserialized.deferredLoadTask.isProgramSplit,
- "isProgramSplit mismatch");
-
- Iterable<ConstantValue> constants1 =
- compilerNormal.backend.outputUnitData.constantsForTesting;
- Iterable<ConstantValue> constants2 =
- compilerDeserialized.backend.outputUnitData.constantsForTesting;
- checkSets(
- constants1,
- constants2,
- 'deferredLoadTask._outputUnitForConstants.keys',
- areConstantValuesEquivalent,
- failOnUnfound: false,
- failOnExtra: false,
- onSameElement: (ConstantValue value1, ConstantValue value2) {
- checkOutputUnits(
- compilerNormal,
- compilerDeserialized,
- compilerNormal.backend.outputUnitData.outputUnitForConstant(value1),
- compilerDeserialized.backend.outputUnitData
- .outputUnitForConstant(value2),
- 'for ${value1.toStructuredText()} '
- 'vs ${value2.toStructuredText()}');
- }, onUnfoundElement: (ConstantValue value1) {
- OutputUnit outputUnit1 =
- compilerNormal.backend.outputUnitData.outputUnitForConstant(value1);
- Expect.isTrue(outputUnit1.isMainOutput,
- "Missing deferred constant: ${value1.toStructuredText()}");
- }, onExtraElement: (ConstantValue value2) {
- OutputUnit outputUnit2 = compilerDeserialized.backend.outputUnitData
- .outputUnitForConstant(value2);
- Expect.isTrue(outputUnit2.isMainOutput,
- "Extra deferred constant: ${value2.toStructuredText()}");
- }, elementToString: (a) {
- OutputUnit o1 =
- compilerNormal.backend.outputUnitData.outputUnitForConstant(a);
- OutputUnit o2 =
- compilerDeserialized.backend.outputUnitData.outputUnitForConstant(a);
- return '${a.toStructuredText()} -> ${o1}/${o2}';
- });
-}
-
-void checkElements(
- Compiler compiler1, Compiler compiler2, Element element1, Element element2,
- {bool verbose: false}) {
- if (element1.isAbstract) return;
- if (element1.isFunction ||
- element1.isConstructor ||
- (element1.isField && element1.isInstanceMember)) {
- ClosureTask closureTask1 = compiler1.backendStrategy.closureDataLookup;
- ClosureRepresentationInfo closureData1 =
- closureTask1.getClosureInfoForMember(element1 as MemberElement);
- ClosureTask closureTask2 = compiler2.backendStrategy.closureDataLookup;
- ClosureRepresentationInfo closureData2 =
- closureTask2.getClosureInfoForMember(element2 as MemberElement);
-
- checkElementIdentities(
- closureData1,
- closureData2,
- '$element1.closureEntity',
- closureData1.closureEntity,
- closureData2.closureEntity);
- checkElementIdentities(
- closureData1,
- closureData2,
- '$element1.closureClassEntity',
- closureData1.closureClassEntity,
- closureData2.closureClassEntity);
- checkElementIdentities(closureData1, closureData2, '$element1.callMethod',
- closureData1.callMethod, closureData2.callMethod);
- check(closureData1, closureData2, '$element1.thisLocal',
- closureData1.thisLocal, closureData2.thisLocal, areLocalsEquivalent);
-
- checkElementListIdentities(
- closureData1,
- closureData2,
- "$element1.createdFieldEntities",
- closureData1.createdFieldEntities,
- closureData2.createdFieldEntities);
- check(
- closureData1,
- closureData2,
- '$element1.thisFieldEntity',
- closureData1.thisFieldEntity,
- closureData2.thisFieldEntity,
- areCapturedVariablesEquivalent);
- if (element1 is MemberElement && element2 is MemberElement) {
- MemberElement member1 = element1.implementation;
- MemberElement member2 = element2.implementation;
- checkSets(member1.nestedClosures, member2.nestedClosures,
- "$member1.nestedClosures", areElementsEquivalent, verbose: verbose,
- onSameElement: (a, b) {
- LocalFunctionElement localFunction1 = a.expression;
- LocalFunctionElement localFunction2 = b.expression;
- checkElementIdentities(localFunction1, localFunction2, 'enclosingClass',
- localFunction1.enclosingClass, localFunction2.enclosingClass);
- testResolvedAstEquivalence(localFunction1.resolvedAst,
- localFunction2.resolvedAst, const CheckStrategy());
- });
- }
- }
- JavaScriptBackend backend1 = compiler1.backend;
- JavaScriptBackend backend2 = compiler2.backend;
- if (element1 is MethodElement && element2 is MethodElement) {
- Expect.equals(
- backend1.inlineCache.getCurrentCacheDecisionForTesting(element1),
- backend2.inlineCache.getCurrentCacheDecisionForTesting(element2),
- "Inline cache decision mismatch for $element1 vs $element2");
- }
-
- checkElementOutputUnits(compiler1, compiler2, element1, element2);
-}
-
-bool areLocalsEquivalent(Local a, Local b) => areLocalVariablesEquivalent(a, b);
-
-bool areLocalVariablesEquivalent(LocalVariable a, LocalVariable b) {
- if (a == b) return true;
- if (a == null || b == null) return false;
-
- if (a is Element) {
- return b is Element && areElementsEquivalent(a as Element, b as Element);
- } else {
- return a.runtimeType == b.runtimeType &&
- areElementsEquivalent(a.executableContext, b.executableContext);
- }
-}
-
-bool areCapturedVariablesEquivalent(FieldEntity a, FieldEntity b) {
- if (a == b) return true;
- if (a == null || b == null) return false;
- if (a is ClosureFieldElement && b is ClosureFieldElement) {
- return areElementsEquivalent(a.closureClass, b.closureClass) &&
- areLocalVariablesEquivalent(a.local, b.local);
- } else if (a is BoxFieldElement && b is BoxFieldElement) {
- return areElementsEquivalent(a.variableElement, b.variableElement) &&
- areLocalVariablesEquivalent(a.box, b.box);
- }
- return false;
-}
-
-bool areCapturedScopesEquivalent(CapturedScope a, CapturedScope b) {
- if (a == b) return true;
- if (a == null || b == null) return false;
- if (!areLocalVariablesEquivalent(a.context, b.context)) {
- return false;
- }
- if (!areLocalVariablesEquivalent(a.thisLocal, b.thisLocal)) {
- return false;
- }
- var aBoxed = <LocalVariable, Entity>{};
- a.forEachBoxedVariable((k, v) => aBoxed[k] = v);
- var bBoxed = <LocalVariable, Entity>{};
- b.forEachBoxedVariable((k, v) => bBoxed[k] = v);
- checkMaps(aBoxed, bBoxed, 'CapturedScope.boxedVariables',
- areLocalVariablesEquivalent, areEntitiesEquivalent);
- return true;
-}
-
-String nodeToString(Node node) {
- String text = '$node';
- if (text.length > 40) {
- return '(${node.runtimeType}) ${text.substring(0, 37)}...';
- }
- return '(${node.runtimeType}) $text';
-}
-
-void checkElementOutputUnits(Compiler compiler1, Compiler compiler2,
- Element element1, Element element2) {
- OutputUnit outputUnit1 =
- compiler1.backend.outputUnitData.outputUnitForEntityForTesting(element1);
- OutputUnit outputUnit2 =
- compiler2.backend.outputUnitData.outputUnitForEntityForTesting(element2);
- checkOutputUnits(compiler1, compiler2, outputUnit1, outputUnit2,
- 'for $element1 vs $element2');
-}
-
-void checkOutputUnits(Compiler compiler1, Compiler compiler2,
- OutputUnit outputUnit1, OutputUnit outputUnit2, String message) {
- if (outputUnit1 == null && outputUnit2 == null) return;
- check(outputUnit1, outputUnit2, 'OutputUnit.isMainOutput $message',
- outputUnit1.isMainOutput, outputUnit2.isMainOutput);
- checkSetEquivalence(
- outputUnit1,
- outputUnit2,
- 'OutputUnit.imports $message',
- compiler1.deferredLoadTask.getImportNames(outputUnit1),
- compiler2.deferredLoadTask.getImportNames(outputUnit2),
- (a, b) => areElementsEquivalent(a.declaration, b.declaration));
-}
diff --git a/tests/compiler/dart2js/serialization/native_data_test.dart b/tests/compiler/dart2js/serialization/native_data_test.dart
deleted file mode 100644
index 4d0fbb0..0000000
--- a/tests/compiler/dart2js/serialization/native_data_test.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization.native_data_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/common/names.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/js_backend/native_data.dart';
-import 'package:compiler/src/filenames.dart';
-import 'package:compiler/src/serialization/equivalence.dart';
-import 'package:compiler/src/world.dart';
-import '../equivalence/check_helpers.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-
-main(List<String> args) {
- asyncTest(() async {
- Arguments arguments = new Arguments.from(args);
- Uri uri = Uris.dart_html;
- if (arguments.filename != null) {
- uri = Uri.base.resolve(nativeToUriPath(arguments.filename));
- }
- await checkNativeData(uri, verbose: arguments.verbose);
- });
-}
-
-Future checkNativeData(Uri uri, {bool verbose: false}) async {
- print('------------------------------------------------------------------');
- print('analyze normal: $uri');
- print('------------------------------------------------------------------');
- SerializationResult result = await serialize(uri);
- Compiler compiler1 = result.compiler;
- SerializedData serializedData = result.serializedData;
- var elementEnvironment1 = compiler1.frontendStrategy.elementEnvironment;
- ClosedWorld closedWorld1 =
- compiler1.closeResolution(elementEnvironment1.mainFunction).closedWorld;
-
- print('------------------------------------------------------------------');
- print('analyze deserialized: $uri');
- print('------------------------------------------------------------------');
- Compiler compiler2 = compilerFor(
- memorySourceFiles: serializedData.toMemorySourceFiles(),
- resolutionInputs: serializedData.toUris(),
- options: [Flags.analyzeAll]);
- await compiler2.run(uri);
- var elementEnvironment2 = compiler2.frontendStrategy.elementEnvironment;
- ClosedWorld closedWorld2 =
- compiler2.closeResolution(elementEnvironment2.mainFunction).closedWorld;
-
- NativeBasicDataImpl nativeBasicData1 =
- compiler1.frontendStrategy.nativeBasicData;
- NativeBasicDataImpl nativeBasicData2 =
- compiler2.frontendStrategy.nativeBasicData;
- NativeDataImpl nativeData1 = closedWorld1.nativeData;
- NativeDataImpl nativeData2 = closedWorld2.nativeData;
-
- checkMaps(nativeData1.jsInteropLibraries, nativeData2.jsInteropLibraries,
- "NativeData.jsInteropLibraryNames", areEntitiesEquivalent, equality,
- verbose: verbose);
-
- checkMaps(nativeData1.jsInteropClasses, nativeData2.jsInteropClasses,
- "NativeData.jsInteropClassNames", areEntitiesEquivalent, equality,
- verbose: verbose);
-
- checkMaps(nativeData1.jsInteropMembers, nativeData2.jsInteropMembers,
- "NativeData.jsInteropMemberNames", areEntitiesEquivalent, equality,
- verbose: verbose);
-
- checkMaps(nativeData1.nativeMemberName, nativeData2.nativeMemberName,
- "NativeData.nativeMemberName", areEntitiesEquivalent, equality,
- verbose: verbose);
-
- checkMaps(
- nativeBasicData1.nativeClassTagInfo,
- nativeBasicData2.nativeClassTagInfo,
- "NativeData.nativeClassTagInfo",
- areEntitiesEquivalent,
- equality,
- verbose: verbose);
-
- checkMaps(
- nativeData1.nativeMethodBehavior,
- nativeData2.nativeMethodBehavior,
- "NativeData.nativeMethodBehavior",
- areEntitiesEquivalent,
- testNativeBehavior,
- verbose: verbose);
-
- checkMaps(
- nativeData1.nativeFieldLoadBehavior,
- nativeData2.nativeFieldLoadBehavior,
- "NativeData.nativeFieldLoadBehavior",
- areEntitiesEquivalent,
- testNativeBehavior,
- verbose: verbose);
-
- checkMaps(
- nativeData1.nativeFieldStoreBehavior,
- nativeData2.nativeFieldStoreBehavior,
- "NativeData.nativeFieldStoreBehavior",
- areEntitiesEquivalent,
- testNativeBehavior,
- verbose: verbose);
-}
diff --git a/tests/compiler/dart2js/serialization/reserialization_test.dart b/tests/compiler/dart2js/serialization/reserialization_test.dart
deleted file mode 100644
index 8814e54..0000000
--- a/tests/compiler/dart2js/serialization/reserialization_test.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions= --no_limit_ints_to_64_bits
-library dart2js.reserialization_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/diagnostics/invariant.dart';
-import 'package:compiler/src/elements/elements.dart';
-import 'package:expect/expect.dart';
-import '../equivalence/check_functions.dart';
-import 'helper.dart';
-import 'equivalence_test.dart';
-
-main(List<String> args) {
- // Ensure that we can print out constant expressions.
- DEBUG_MODE = true;
-
- Arguments arguments = new Arguments.from(args);
- Uri entryPoint;
- if (arguments.filename != null) {
- entryPoint = Uri.parse(arguments.filename);
- } else {
- entryPoint = Uri.parse('dart:core');
- }
- asyncTest(() async {
- await testReserialization(entryPoint);
- });
-}
-
-Future testReserialization(Uri entryPoint) async {
- SerializationResult result1 = await serialize(entryPoint);
- Compiler compiler1 = result1.compiler;
- SerializedData serializedData1 = result1.serializedData;
- Iterable<LibraryElement> libraries1 = compiler1.libraryLoader.libraries;
-
- SerializationResult result2 = await serialize(entryPoint,
- memorySourceFiles: serializedData1.toMemorySourceFiles(),
- resolutionInputs: serializedData1.toUris(),
- deserializeCompilationDataForTesting: true);
- Compiler compiler2 = result2.compiler;
- SerializedData serializedData2 = result2.serializedData;
- Iterable<LibraryElement> libraries2 = compiler2.libraryLoader.libraries;
-
- SerializationResult result3 = await serialize(entryPoint,
- memorySourceFiles: serializedData2.toMemorySourceFiles(),
- resolutionInputs: serializedData2.toUris(),
- deserializeCompilationDataForTesting: true);
- Compiler compiler3 = result3.compiler;
- Iterable<LibraryElement> libraries3 = compiler3.libraryLoader.libraries;
-
- for (LibraryElement library1 in libraries1) {
- LibraryElement library2 = libraries2.firstWhere((LibraryElement library2) {
- return library2.canonicalUri == library1.canonicalUri;
- });
- Expect.isNotNull(
- library2, "No library found for ${library1.canonicalUri}.");
- checkLibraryContent('library1', 'library2', 'library', library1, library2);
-
- LibraryElement library3 = libraries3.firstWhere((LibraryElement library3) {
- return library3.canonicalUri == library1.canonicalUri;
- });
- Expect.isNotNull(
- library3, "No library found for ${library1.canonicalUri}.");
- checkLibraryContent('library1', 'library3', 'library', library1, library3);
- }
-
- checkAllResolvedAsts(compiler1, compiler2);
- checkAllResolvedAsts(compiler1, compiler3);
-
- checkAllImpacts(compiler1, compiler2);
- checkAllImpacts(compiler1, compiler3);
-}
diff --git a/tests/compiler/dart2js/serialization/resolved_ast_test.dart b/tests/compiler/dart2js/serialization/resolved_ast_test.dart
deleted file mode 100644
index 7561f73..0000000
--- a/tests/compiler/dart2js/serialization/resolved_ast_test.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// VMOptions= --no_limit_ints_to_64_bits
-library dart2js.serialization_resolved_ast_test;
-
-import 'dart:async';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/compiler.dart';
-import 'package:compiler/src/filenames.dart';
-import '../equivalence/check_functions.dart';
-import '../memory_compiler.dart';
-import 'helper.dart';
-import 'test_data.dart';
-
-main(List<String> args) {
- Arguments arguments = new Arguments.from(args);
- asyncTest(() async {
- SerializedData serializedData =
- await serializeDartCore(arguments: arguments);
- if (arguments.filename != null) {
- Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
- await check(serializedData, entryPoint);
- } else {
- Uri entryPoint = Uri.parse('memory:main.dart');
- // TODO(johnniwinther): Change to test all serialized resolved ast instead
- // only those used in the test.
- Test test = TESTS.first;
- await check(serializedData, entryPoint, test.sourceFiles);
- }
- });
-}
-
-Future check(SerializedData serializedData, Uri entryPoint,
- [Map<String, String> sourceFiles = const <String, String>{}]) async {
- Compiler compilerNormal = compilerFor(
- memorySourceFiles: sourceFiles,
- options: [Flags.analyzeAll, Flags.useOldFrontend]);
- compilerNormal.impactCacheDeleter.retainCachesForTesting = true;
- await compilerNormal.run(entryPoint);
-
- Compiler compilerDeserialized = compilerFor(
- memorySourceFiles: serializedData.toMemorySourceFiles(sourceFiles),
- resolutionInputs: serializedData.toUris(),
- options: [Flags.analyzeAll, Flags.useOldFrontend]);
- compilerDeserialized.impactCacheDeleter.retainCachesForTesting = true;
- await compilerDeserialized.run(entryPoint);
-
- checkAllResolvedAsts(compilerNormal, compilerDeserialized, verbose: true);
-}
diff --git a/tests/compiler/dart2js/serialization/test_data.dart b/tests/compiler/dart2js/serialization/test_data.dart
deleted file mode 100644
index 667ff90..0000000
--- a/tests/compiler/dart2js/serialization/test_data.dart
+++ /dev/null
@@ -1,829 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_test_data;
-
-const List<Test> TESTS = const <Test>[
- // These tests are very long-running and put here first to compile them on
- // their own tests.
- const Test(
- 'Disable tree shaking through reflection',
- const {
- 'main.dart': '''
-import 'dart:mirrors';
-
-main() {
- reflect(null).invoke(#toString, []).reflectee;
-}
-''',
- },
- expectedWarningCount: 1),
-
- const Test('Use of dart:indexed_db', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-import 'dart:indexed_db';
-''',
- }),
-
- // These tests
- const Test('Empty program', const {'main.dart': 'main() {}'}),
-
- const Test(
- 'Hello World', const {'main.dart': 'main() => print("Hello World");'}),
-
- const Test('Too many arguments to print',
- const {'main.dart': 'main() => print("Hello World", 0);'},
- expectedWarningCount: 1, expectedInfoCount: 1),
-
- const Test('Hello World with string interpolation', const {
- 'main.dart': r'''
-main() {
- String text = "Hello World";
- print('$text');
-}'''
- }),
-
- const Test(
- 'Too many arguments to print with string interpolation',
- const {
- 'main.dart': r'''
-main() {
- String text = "Hello World";
- print('$text', text);
-}'''
- },
- expectedWarningCount: 1,
- expectedInfoCount: 1),
-
- const Test('Print main arguments', const {
- 'main.dart': r'''
-main(List<String> arguments) {
- print(arguments);
-}'''
- }),
-
- const Test('For loop on main arguments', const {
- 'main.dart': r'''
-main(List<String> arguments) {
- for (int i = 0; i < arguments.length; i++) {
- print(arguments[i]);
- }
-}'''
- }),
-
- const Test('For-in loop on main arguments', const {
- 'main.dart': r'''
-main(List<String> arguments) {
- for (String argument in arguments) {
- print(argument);
- }
-}'''
- }),
-
- const Test('Simple class', const {
- 'main.dart': r'''
-class Class {}
-main() {
- print(new Class());
-}'''
- }),
-
- const Test(
- 'Simple class implements Function without call method',
- const {
- 'main.dart': r'''
-class Class implements Function {}
-main() {
- print(new Class());
-}'''
- },
- expectedWarningCount: 1),
-
- const Test('Simple class implements Function with call method', const {
- 'main.dart': r'''
-class Class implements Function {
- call() {}
-}
-main() {
- print(new Class()());
-}'''
- }),
-
- const Test('Implement Comparable', const {
- 'main.dart': r'''
-class Class implements Comparable<Class> {
- int compareTo(Class other) => 0;
-}
-main() {
- print(new Class());
-}'''
- }),
-
- const Test(
- 'Implement Comparable with two many type arguments',
- const {
- 'main.dart': r'''
-class Class implements Comparable<Class, Class> {
- int compareTo(other) => 0;
-}
-main() {
- print(new Class());
-}'''
- },
- expectedWarningCount: 1),
-
- const Test(
- 'Implement Comparable with incompatible parameter types',
- const {
- 'main.dart': r'''
-class Class implements Comparable<Class> {
- int compareTo(String other) => 0;
-}
-main() {
- print(new Class().compareTo(null));
-}'''
- },
- expectedWarningCount: 1,
- expectedInfoCount: 1),
-
- const Test(
- 'Implement Comparable with incompatible parameter count',
- const {
- 'main.dart': r'''
-class Class implements Comparable {
- bool compareTo(a, b) => true;
-}
-main() {
- print(new Class().compareTo(null, null));
-}'''
- },
- expectedWarningCount: 1,
- expectedInfoCount: 1),
-
- const Test(
- 'Implement Random and call nextInt directly',
- const {
- 'main.dart': r'''
-import 'dart:math';
-
-class MyRandom implements Random {
- int nextInt(int max) {
- return max.length;
- }
- bool nextBool() => true;
- double nextDouble() => 0.0;
-}
-main() {
- new MyRandom().nextInt(0);
-}'''
- },
- expectedWarningCount: 1,
- expectedInfoCount: 0),
-
- const Test('Implement Random and do not call nextInt', const {
- 'main.dart': r'''
-import 'dart:math';
-
-class MyRandom implements Random {
- int nextInt(int max) {
- return max.length;
- }
- bool nextBool() => true;
- double nextDouble() => 0.0;
-}
-main() {
- new MyRandom();
-}'''
- }),
-
- const Test(
- 'Implement Random and call nextInt through native code',
- const {
- 'main.dart': r'''
-import 'dart:math';
-
-class MyRandom implements Random {
- int nextInt(int max) {
- return max.length;
- }
- bool nextBool() => true;
- double nextDouble() => 0.0;
-}
-main() {
- // Invocation of `MyRandom.nextInt` is only detected knowing the actual
- // implementation class for `List` and the world impact of its `shuffle`
- // method.
- [].shuffle(new MyRandom());
-}'''
- },
- expectedWarningCount: 1,
- expectedInfoCount: 0),
-
- const Test('Handle break and continue', const {
- 'main.dart': '''
-main() {
- loop: for (var a in []) {
- for (var b in []) {
- continue loop;
- }
- break;
- }
-}'''
- }),
-
- const Test('Explicit default constructor', const {
- 'main.dart': '''
-class A {
- A();
-}
-main() => new A();
- ''',
- }),
-
- const Test('Explicit default constructor, preserialized', const {
- 'main.dart': '''
-import 'lib.dart';
-main() => new A();
- ''',
- }, preserializedSourceFiles: const {
- 'lib.dart': '''
-class A {
- A();
-}
-''',
- }),
-
- const Test('Const constructor', const {
- 'main.dart': '''
-class C {
- const C();
-}
-main() => const C();'''
- }),
-
- const Test('Redirecting factory', const {
- 'main.dart': '''
-class C {
- factory C() = Object;
-}
-main() => new C();'''
- }),
-
- const Test('Redirecting factory with optional arguments', const {
- 'main.dart': '''
-abstract class C implements List {
- factory C([_]) = List;
-}
-main() => new C();'''
- }),
-
- const Test('Constructed constant using its default values.', const {
- 'main.dart': '''
-main() => const Duration();
-''',
- }),
-
- const Test('Call forwarding constructor on named mixin application', const {
- 'main.dart': '''
-import 'dart:collection';
-main() => new UnmodifiableListView(null);
-''',
- }),
-
- const Test('Function reference constant', const {
- 'main.dart': '''
-var myIdentical = identical;
-main() => myIdentical;
-''',
- }),
-
- const Test('Super method call', const {
- 'main.dart': '''
-class Foo {
- String toString() => super.toString();
-}
-main() {
- print(new Foo());
-}
-''',
- }),
-
- const Test(
- 'Call forwarding constructor on named mixin application, no args.',
- const {
- 'main.dart': '''
-import 'lib.dart';
-main() => new C();
-''',
- },
- preserializedSourceFiles: const {
- 'lib.dart': '''
-class M {}
-class S {}
-class C = S with M;
-''',
- }),
-
- const Test(
- 'Call forwarding constructor on named mixin application, one arg.',
- const {
- 'main.dart': '''
-import 'lib.dart';
-main() => new C(0);
-''',
- },
- preserializedSourceFiles: const {
- 'lib.dart': '''
-class M {}
-class S {
- S(a);
-}
-class C = S with M;
-''',
- }),
-
- const Test(
- 'Import mirrors, thus checking import paths',
- const {
- 'main.dart': '''
-import 'dart:mirrors';
-main() {}
-''',
- },
- expectedWarningCount: 1),
-
- const Test('Serialized symbol literal', const {
- 'main.dart': '''
-import 'lib.dart';
-main() => m();
-''',
- }, preserializedSourceFiles: const {
- 'lib.dart': '''
-m() => print(#main);
-''',
- }),
-
- const Test('Indirect unserialized library', const {
- 'main.dart': '''
-import 'a.dart';
-main() => foo();
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-import 'memory:b.dart';
-foo() => bar();
-''',
- }, unserializedSourceFiles: const {
- 'b.dart': '''
-import 'memory:a.dart';
-bar() => foo();
-''',
- }),
-
- const Test('Multiple structurally identical mixins', const {
- 'main.dart': '''
-class S {}
-class M {}
-class C1 extends S with M {}
-class C2 extends S with M {}
-main() {
- new C1();
- new C2();
-}
-''',
- }),
-
- const Test('Deferred loading', const {
- 'main.dart': '''
-import 'a.dart' deferred as lib;
-main() {
- lib.foo();
-}
-''',
- 'a.dart': '''
-void foo() {}
-''',
- }),
-
- const Test('fromEnvironment constants', const {
- 'main.dart': '''
-main() => const String.fromEnvironment("foo");
-''',
- }),
-
- const Test('Unused noSuchMethod', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- new A().m();
-}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-class A {
- noSuchMethod(_) => null;
- m();
-}
-''',
- }),
-
- const Test('Malformed types', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- m();
-}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-Unresolved m() {}
-''',
- }),
-
- const Test('Function types for closures', const {
- 'main.dart': '''
-import 'a.dart';
-
-typedef Func();
-
-main(args) {
- (args.isEmpty ? new B() : new C()) is Func;
-}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-class B {
- call(a) {}
-}
-class C {
- call() {}
-}
-''',
- }),
-
- const Test('Double literal in constant constructor', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- const A(1.0);
-}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-class A {
- final field1;
- const A(a) : this.field1 = a + 1.0;
-}
-''',
- }),
-
- const Test('Index set if null', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() => m(null, null, null);
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-m(a, b, c) => a[b] ??= c;
-''',
- }),
-
- const Test('If-null expression in constant constructor', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- const A(1.0);
-}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-class A {
- final field1;
- const A(a) : this.field1 = a ?? 1.0;
-}
-''',
- }),
-
- const Test('Forwarding constructor defined by forwarding constructor', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() => new C();
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-class A {}
-class B {}
-class C {}
-class D = A with B, C;
-''',
- 'b.dart': '''
-''',
- }),
-
- const Test('Deferred prefix loadLibrary', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- test();
-}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-import 'b.dart' deferred as pre;
-test() {
- pre.loadLibrary();
-}
-''',
- 'b.dart': '''
-''',
- }),
-
- const Test(
- 'Deferred without prefix',
- const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- test();
-}
-''',
- },
- preserializedSourceFiles: const {
- 'a.dart': '''
-import 'b.dart' deferred;
-test() {}
-''',
- 'b.dart': '''
-''',
- },
- expectedErrorCount: 1),
-
- const Test(
- 'Deferred with duplicate prefix',
- const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- test();
-}
-''',
- },
- preserializedSourceFiles: const {
- 'a.dart': '''
-import 'b.dart' deferred as pre;
-import 'c.dart' deferred as pre;
-test() {}
-''',
- 'b.dart': '''
-''',
- 'c.dart': '''
-''',
- },
- expectedErrorCount: 1),
-
- const Test('Closure in operator function', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- test();
-}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-class C {
- operator ==(other) => () {};
-}
-
-test() => new C() == null;
-''',
- }),
-
- const Test(
- 'Checked setter',
- const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- test();
-}
-''',
- },
- preserializedSourceFiles: const {
- 'a.dart': '''
-class C {
- set foo(int i) {}
-}
-
-test() => new C().foo = 0;
-''',
- },
- checkedMode: true),
-
- const Test('Deferred access', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- test();
-}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-import 'b.dart' deferred as b;
-
-test() => b.loadLibrary().then((_) => b.test2());
-''',
- 'b.dart': '''
-test2() {}
-''',
- }),
-
- const Test('Deferred access of dart:core', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {
- test();
-}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-import "dart:core" deferred as core;
-
-test() {
- core.loadLibrary().then((_) => null);
-}
-''',
- }),
-
- const Test('Use of dart:indexed_db', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() {}
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-import 'dart:indexed_db';
-''',
- }),
-
- const Test('Deferred static access', const {},
- preserializedSourceFiles: const {
- 'main.dart': '''
-import 'b.dart' deferred as prefix;
-
-main() => prefix.loadLibrary().then((_) => prefix.test2());
-''',
- 'b.dart': '''
-test2() => x;
-var x = const ConstClass(const ConstClass(1));
-class ConstClass {
- final x;
- const ConstClass(this.x);
-}
-''',
- }),
-
- const Test('Multi variable declaration', const {
- 'main.dart': '''
-import 'a.dart';
-
-main() => y;
-''',
- }, preserializedSourceFiles: const {
- 'a.dart': '''
-var x, y = 2;
-''',
- }),
-
- const Test('Double values', const {}, preserializedSourceFiles: const {
- 'main.dart': '''
-const a = 1e+400;
-main() => a;
-''',
- }),
-
- const Test('Erroneous constructor', const {},
- preserializedSourceFiles: const {
- 'main.dart': '''
-main() => new Null();
-'''
- }),
-
- const Test('Metadata on imports', const {}, preserializedSourceFiles: const {
- 'main.dart': '''
-@deprecated
-import 'main.dart';
-
-main() {}
-'''
- }),
-
- const Test('Metadata on exports', const {}, preserializedSourceFiles: const {
- 'main.dart': '''
-@deprecated
-export 'main.dart';
-
-main() {}
-'''
- }),
-
- const Test('Metadata on part tags', const {},
- preserializedSourceFiles: const {
- 'main.dart': '''
-library main;
-
-@deprecated
-part 'a.dart';
-
-main() {}
-'''
- },
- unserializedSourceFiles: const {
- 'a.dart': '''
-part of main;
-'''
- }),
-
- const Test('Metadata on part-of tags', const {},
- preserializedSourceFiles: const {
- 'main.dart': '''
-library main;
-
-part 'a.dart';
-
-main() {}
-'''
- },
- unserializedSourceFiles: const {
- 'a.dart': '''
-@deprecated
-part of main;
-'''
- }),
-
- const Test('Ambiguous elements', const {}, preserializedSourceFiles: const {
- 'main.dart': '''
-import 'a.dart';
-import 'b.dart';
-
-main() => new foo();
-''',
- 'a.dart': '''
-var foo;
-''',
- 'b.dart': '''
-var foo;
-''',
- }),
-
- const Test('html and mirrors', const {},
- preserializedSourceFiles: const {
- 'main.dart': '''
-import 'dart:html';
-import 'dart:mirrors';
-main() {}
-'''
- },
- expectedWarningCount: 1),
-];
-
-class Test {
- final String name;
- final Map sourceFiles;
- final Map preserializedSourceFiles;
- final Map unserializedSourceFiles;
- final int expectedErrorCount;
- final int expectedWarningCount;
- final int expectedHintCount;
- final int expectedInfoCount;
- final bool checkedMode;
-
- const Test(this.name, this.sourceFiles,
- {this.preserializedSourceFiles,
- this.unserializedSourceFiles,
- this.expectedErrorCount: 0,
- this.expectedWarningCount: 0,
- this.expectedHintCount: 0,
- this.expectedInfoCount: 0,
- this.checkedMode: false});
-}
diff --git a/tests/compiler/dart2js/serialization/test_helper.dart b/tests/compiler/dart2js/serialization/test_helper.dart
deleted file mode 100644
index 3b64fa0..0000000
--- a/tests/compiler/dart2js/serialization/test_helper.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.serialization_test_helper;
-
-import 'test_data.dart';
-
-/// Returns the test arguments for testing the [index]th skipped test. The
-/// [skip] count is used to check that [index] is a valid index.
-List<String> testSkipped(int index, int skip) {
- if (index < 0 || index >= skip) {
- throw new ArgumentError('Invalid skip index $index');
- }
- return ['${index}', '${index + 1}'];
-}
-
-/// Return the test arguments for testing the [index]th segment (1-based) of
-/// the [TESTS] split into [count] groups. The first [skip] tests are excluded
-/// from the automatic grouping.
-List<String> testSegment(int index, int count, int skip) {
- if (index < 0 || index > count) {
- throw new ArgumentError('Invalid segment index $index');
- }
-
- String segmentNumber(int i) {
- return '${skip + i * (TESTS.length - skip) ~/ count}';
- }
-
- if (index == 1 && skip != 0) {
- return ['${skip}', segmentNumber(index)];
- } else if (index == count) {
- return [segmentNumber(index - 1)];
- } else {
- return [segmentNumber(index - 1), segmentNumber(index)];
- }
-}
diff --git a/tests/compiler/dart2js_extra/32853_test.dart b/tests/compiler/dart2js_extra/32853_test.dart
new file mode 100644
index 0000000..ccf8dab
--- /dev/null
+++ b/tests/compiler/dart2js_extra/32853_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+// Regression test for issue 32853.
+
+
+int foo<T extends Comparable<T>>(T a, T b) => a.compareTo(b);
+
+main() {
+ int Function<T extends Comparable<T>>(T, T) f = foo;
+ print(f<num>(1, 2));
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index bb4d673..02e2263 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -6,7 +6,6 @@
class_test: Fail
constant_javascript_semantics4_test: Fail, OK
generic_class_is_test: Fail # Issue 32004
-local_function_call_test: RuntimeError # Issue 31879
mirror_printer_test: Pass, Slow # Issue 25940, 16473
mirrors_used_closure_test: Fail # Issue 17939
no_such_method_test: Fail # Wrong Invocation.memberName.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index fe9e13b..80b93c7 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -11,7 +11,6 @@
full_stacktrace2_test: Pass, RuntimeError # Issue 12698
full_stacktrace3_test: Pass, RuntimeError # Issue 12698
library_env_test/has_no_html_support: RuntimeError, OK
-local_function_test: RuntimeError # Issue 31879
vm/*: Skip # Issue 12699
[ $arch == ia32 && $compiler == dart2js && $runtime == d8 ]
diff --git a/tests/language_2/const_cast4_test.dart b/tests/language_2/const_cast4_test.dart
new file mode 100644
index 0000000..cb7a250
--- /dev/null
+++ b/tests/language_2/const_cast4_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Casts in constants correctly substitute type variables.
+
+class A {
+ const A();
+}
+
+class B implements A {
+ const B();
+}
+
+class M<T extends A> {
+ final T a;
+ const M(dynamic t) : a = t; // adds implicit cast `as T`
+}
+
+class N<S extends A> extends M<S> {
+ const N(dynamic t) : super(t);
+}
+
+main() {
+ print(const N<B>(const B()));
+}
diff --git a/tests/language_2/double_identical_test.dart b/tests/language_2/double_identical_test.dart
index 2004e63..16b99fe 100644
--- a/tests/language_2/double_identical_test.dart
+++ b/tests/language_2/double_identical_test.dart
@@ -10,5 +10,5 @@
Expect.isTrue(identical(0.0, 0.0));
Expect.isTrue(identical(1.234E9, 1.234E9));
Expect.isFalse(identical(0.0, -0.0));
- Expect.isTrue(identical(double.NAN, double.NAN));
+ Expect.isTrue(identical(double.nan, double.nan));
}
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index aaf47f0..0ed2de8 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -31,7 +31,6 @@
final_syntax_test/04: Fail # Issue 11124
function_type_parameter2_negative_test: CompileTimeError
function_type_parameter_negative_test: CompileTimeError
-fuzzy_arrows_test/01: MissingCompileTimeError
generic_function_type_as_type_argument_test/01: MissingCompileTimeError # Issue 30929
generic_function_type_as_type_argument_test/02: MissingCompileTimeError # Issue 30929
generic_local_functions_test: CompileTimeError # Issue 28515
@@ -1184,7 +1183,6 @@
mixin_super_2_test/03: MissingCompileTimeError
mixin_supertype_subclass_test/02: MissingCompileTimeError
mixin_supertype_subclass_test/05: MissingCompileTimeError
-mixin_type_parameter_inference_test/11: MissingCompileTimeError # Fuzzy arrow, 32114
multiline_newline_test/01: CompileTimeError
multiline_newline_test/01r: CompileTimeError
multiline_newline_test/02: CompileTimeError
@@ -1411,6 +1409,7 @@
constructor_call_as_function_test: StaticWarning
constructor_duplicate_final_test/03: MissingCompileTimeError
create_unresolved_type_test/01: MissingCompileTimeError
+fuzzy_arrows_test/01: MissingCompileTimeError
generic_constructor_mixin2_test/01: MissingCompileTimeError
generic_constructor_mixin3_test/01: MissingCompileTimeError
generic_constructor_mixin_test/01: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index b53060d..742853a 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -994,10 +994,6 @@
[ $compiler == dart2js && $fasta ]
call_method_as_cast_test/06: RuntimeError
-call_method_function_typed_value_test/02: RuntimeError
-call_method_function_typed_value_test/04: RuntimeError
-call_method_function_typed_value_test/06: RuntimeError
-call_method_function_typed_value_test/08: RuntimeError
call_method_implicit_tear_off_implements_function_test/05: RuntimeError
call_method_implicit_tear_off_implements_function_test/06: RuntimeError
call_method_is_check_test/06: RuntimeError
@@ -1177,7 +1173,7 @@
deferred_regression_22995_test: RuntimeError
deferred_regression_28678_test: RuntimeError
deferred_shadow_load_library_test: RuntimeError
-deferred_shared_and_unshared_classes_test: CompileTimeError
+deferred_shared_and_unshared_classes_test: RuntimeError
deferred_static_seperate_test: RuntimeError
deferred_type_dependency_test/as: RuntimeError
deferred_type_dependency_test/is: RuntimeError
@@ -1254,7 +1250,6 @@
generic_methods_generic_function_result_test/01: MissingCompileTimeError
generic_methods_overriding_test/01: MissingCompileTimeError
generic_methods_recursive_bound_test/02: MissingCompileTimeError
-generic_methods_recursive_bound_test/03: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/metadata_collector.dart': Failed assertion: line 100 pos 12: 'isBound': is not true.
generic_methods_simple_as_expression_test/02: MissingRuntimeError
generic_methods_type_expression_test: RuntimeError
generic_methods_unused_parameter_test: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
@@ -1847,7 +1842,7 @@
deferred_regression_22995_test: RuntimeError
deferred_regression_28678_test: RuntimeError
deferred_shadow_load_library_test: RuntimeError
-deferred_shared_and_unshared_classes_test: CompileTimeError
+deferred_shared_and_unshared_classes_test: RuntimeError
deferred_static_seperate_test: RuntimeError
deferred_type_dependency_test/as: RuntimeError
deferred_type_dependency_test/is: RuntimeError
@@ -1922,7 +1917,6 @@
generic_methods_generic_function_result_test/01: MissingCompileTimeError
generic_methods_overriding_test/01: MissingCompileTimeError
generic_methods_recursive_bound_test/02: MissingCompileTimeError
-generic_methods_recursive_bound_test/03: Crash # NoSuchMethodError: The method 'markSeen' was called on null.
generic_methods_simple_as_expression_test/02: MissingRuntimeError
generic_methods_type_expression_test: RuntimeError
generic_methods_unused_parameter_test: RuntimeError
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 97c9e8d..b259467 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -30,7 +30,6 @@
conflicting_type_variable_and_setter_test: CompileTimeError
const_cast2_test/01: CompileTimeError
const_cast2_test/none: CompileTimeError
-const_evaluation_test/01: RuntimeError # Issue 29920
const_for_in_variable_test/01: MissingCompileTimeError
const_types_test/07: MissingCompileTimeError
const_types_test/08: MissingCompileTimeError
@@ -57,7 +56,6 @@
forwarding_stub_tearoff_generic_test: RuntimeError
forwarding_stub_tearoff_test: CompileTimeError
function_propagation_test: RuntimeError
-fuzzy_arrows_test/01: MissingCompileTimeError
generic_local_functions_test: CompileTimeError
generic_methods_generic_function_parameter_test: CompileTimeError
generic_methods_generic_function_result_test/none: CompileTimeError # Issue #30208
@@ -113,20 +111,16 @@
mixin_supertype_subclass_test/02: MissingCompileTimeError
mixin_supertype_subclass_test/05: MissingCompileTimeError
mixin_type_parameter_inference_previous_mixin_test/01: CompileTimeError
-mixin_type_parameter_inference_previous_mixin_test/02: RuntimeError
-mixin_type_parameter_inference_previous_mixin_test/03: MissingCompileTimeError
+mixin_type_parameter_inference_previous_mixin_test/02: CompileTimeError
mixin_type_parameter_inference_previous_mixin_test/04: MissingCompileTimeError
mixin_type_parameter_inference_previous_mixin_test/05: RuntimeError
mixin_type_parameter_inference_test/01: CompileTimeError
-mixin_type_parameter_inference_test/02: RuntimeError
-mixin_type_parameter_inference_test/03: RuntimeError
-mixin_type_parameter_inference_test/04: MissingCompileTimeError
-mixin_type_parameter_inference_test/05: MissingCompileTimeError
+mixin_type_parameter_inference_test/02: CompileTimeError
+mixin_type_parameter_inference_test/03: CompileTimeError
mixin_type_parameter_inference_test/06: MissingCompileTimeError
mixin_type_parameter_inference_test/07: MissingCompileTimeError
mixin_type_parameter_inference_test/08: RuntimeError
mixin_type_parameter_inference_test/09: RuntimeError
-mixin_type_parameter_inference_test/11: MissingCompileTimeError
mock_writable_final_private_field_test: CompileTimeError # Issue 30848
multiline_newline_test/01: CompileTimeError
multiline_newline_test/01r: CompileTimeError
@@ -137,7 +131,6 @@
multiline_newline_test/none: RuntimeError
multiple_interface_inheritance_test: CompileTimeError # Issue 30552
nested_generic_closure_test: CompileTimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError # Issue 31425
override_inheritance_field_test/04: CompileTimeError
override_inheritance_field_test/06: CompileTimeError
override_inheritance_field_test/26: CompileTimeError
@@ -375,7 +368,6 @@
deferred_inheritance_constraints_test/mixin: MissingCompileTimeError
deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError
deferred_load_library_wrong_args_test/01: CompileTimeError
-deferred_shared_and_unshared_classes_test: CompileTimeError # Issue 31402 Error: A value of type 'dart.core::List<dynamic>' can't be assigned to a variable of type 'dart.core::Iterable<dart.async::Future<dynamic>>'.
double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in ddk
duplicate_export_negative_test: Fail
duplicate_implements_test/01: MissingCompileTimeError
@@ -399,7 +391,6 @@
field_override4_test/02: MissingCompileTimeError
field_override_test/00: MissingCompileTimeError
field_override_test/01: MissingCompileTimeError
-function_call_generic_test: RuntimeError # Issue 32756. Crashes on dsend
function_propagation_test: RuntimeError
function_type_parameter2_negative_test: Fail
function_type_parameter_negative_test: Fail
@@ -555,13 +546,11 @@
mixin_type_parameters_errors_test/03: MissingCompileTimeError
mixin_type_parameters_errors_test/04: MissingCompileTimeError
mixin_type_parameters_errors_test/05: MissingCompileTimeError
-mock_writable_final_field_test: RuntimeError # Expect.listEquals(list length, expected: <1>, actual: <0>) fails: Next element <123>
mock_writable_final_private_field_test: RuntimeError
multiline_newline_test/06: MissingCompileTimeError
multiline_newline_test/06r: MissingCompileTimeError
named_constructor_test/01: MissingCompileTimeError
named_parameters_default_eq_test/02: MissingCompileTimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError # Issue 31425
nsm5_test: MissingCompileTimeError
null2_test: RuntimeError # Issue 32194
null_method_test: RuntimeError # Issue 32194
@@ -712,6 +701,7 @@
compile_time_constant_e_test: RuntimeError # Issue 30876; Expect.identical(expected: <A 3 499 99 100>, actual: <A 3 499 99 100>) fails.
config_import_corelib_test: CompileTimeError
config_import_test: RuntimeError # Expect.equals(expected: <b>, actual: <a>) fails.
+const_evaluation_test/01: RuntimeError # dart:mirrors not supported in DDC
const_list_test: RuntimeError # Expect.equals(expected: <false>, actual: <true>) fails.
const_map4_test: RuntimeError # Expect.equals(expected: <true>, actual: <false>) fails.
const_switch_test/02: RuntimeError # Issue 29920; Expect.equals(expected: <0>, actual: <0.0>) fails.
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 3c1f1a3..ea83e68 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -636,7 +636,6 @@
deferred_load_library_wrong_args_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 30273.
deferred_not_loaded_check_test: RuntimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
deferred_redirecting_factory_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273.
-deferred_shared_and_unshared_classes_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
deferred_static_seperate_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273.
disassemble_test: Pass, Slow
dynamic_prefix_core_test/none: CompileTimeError
@@ -958,7 +957,6 @@
deferred_load_library_wrong_args_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 30273.
deferred_not_loaded_check_test: RuntimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
deferred_redirecting_factory_test: CompileTimeError, Fail, Crash # Issue 23408, KernelVM bug: Deferred loading kernel issue 30273.
-deferred_shared_and_unshared_classes_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
deferred_static_seperate_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273.
deopt_inlined_function_lazy_test: Skip # Incompatible flag: --deoptimize-alot
dynamic_prefix_core_test/none: CompileTimeError
@@ -1209,7 +1207,6 @@
cyclic_typedef_test/10: Crash
cyclic_typedef_test/11: Crash
deferred_load_library_wrong_args_test/01: CompileTimeError
-deferred_shared_and_unshared_classes_test: CompileTimeError
duplicate_implements_test/01: MissingCompileTimeError
duplicate_implements_test/02: MissingCompileTimeError
dynamic_prefix_core_test/none: CompileTimeError
diff --git a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
index ab35197..126c2c0 100644
--- a/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
+++ b/tests/language_2/nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test.dart
@@ -80,7 +80,7 @@
a.test5<int>(1);
(a.test5 as dynamic)<int>(1);
Expect.throwsTypeError(() => (a.test5 as dynamic)<String>("foo"));
- Expect.throwsTypeError(() => (a.test5 as dynamic)<int>(3.0));
+ Expect.throwsTypeError(() => (a.test5 as dynamic)<int>(3.1));
Expect.throwsTypeError(() => a.test6());
Expect.throwsTypeError(() => (a.test6 as dynamic)());
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 220eb6c..45b680a 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -116,7 +116,6 @@
typed_data/typed_data_hierarchy_int64_test: RuntimeError # Issue 10275
[ $compiler == fasta ]
-mirrors/library_imports_bad_metadata_test/01: Crash
mirrors/metadata_allowed_values_test/02: MissingCompileTimeError
mirrors/metadata_allowed_values_test/27: MissingCompileTimeError
mirrors/metadata_constructor_arguments_test/04: MissingCompileTimeError
diff --git a/tests/lib_2/convert/json_test.dart b/tests/lib_2/convert/json_test.dart
index edd89e9..d7be8a0 100644
--- a/tests/lib_2/convert/json_test.dart
+++ b/tests/lib_2/convert/json_test.dart
@@ -170,7 +170,7 @@
testError(integers: "");
// Test for "Initial zero only allowed for zero integer part" moved to
- // json_strict_test.dart because IE's JSON.decode accepts additional initial
+ // json_strict_test.dart because IE's jsonDecode accepts additional initial
// zeros.
// Only minus allowed as sign.
diff --git a/tests/lib_2/convert/utf84_test.dart b/tests/lib_2/convert/utf84_test.dart
index b1a9950..bc1db59 100755
--- a/tests/lib_2/convert/utf84_test.dart
+++ b/tests/lib_2/convert/utf84_test.dart
@@ -626,7 +626,7 @@
String decodeUtf8List(List<int> codeUnits) => utf8.decode(codeUnits);
String decodeUtf8Uint8List(List<int> codeUnits) =>
- UTF8.decode(new Uint8List.fromList(codeUnits));
+ utf8.decode(new Uint8List.fromList(codeUnits));
testUtf8BytesToString(decodeUtf8List);
testUtf8BytesToString(decodeUtf8Uint8List);
@@ -647,7 +647,7 @@
}
void testEncodeToUtf8() {
- List<int> encodeUtf8(String str) => UTF8.encode(str);
+ List<int> encodeUtf8(String str) => utf8.encode(str);
Expect.listEquals(
testEnglishUtf8, encodeUtf8(testEnglishPhrase), "english to utf8");
@@ -681,19 +681,19 @@
Expect.listEquals([0x800], utf8ToRunes([0xe0, 0xa0, 0x80]), "800");
Expect.listEquals([0x10000], utf8ToRunes([0xf0, 0x90, 0x80, 0x80]), "10000");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xf8, 0x88, 0x80, 0x80, 0x80]), "200000");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xfc, 0x84, 0x80, 0x80, 0x80, 0x80]), "4000000");
// boundary conditions: Last possible sequence of a certain length
@@ -701,48 +701,48 @@
Expect.listEquals([0x7ff], utf8ToRunes([0xdf, 0xbf]), "7ff");
Expect.listEquals([0xffff], utf8ToRunes([0xef, 0xbf, 0xbf]), "ffff");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xf7, 0xbf, 0xbf, 0xbf]), "1fffff");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xfb, 0xbf, 0xbf, 0xbf, 0xbf]), "3ffffff");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xfd, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf]), "4000000");
// other boundary conditions
Expect.listEquals([0xd7ff], utf8ToRunes([0xed, 0x9f, 0xbf]), "d7ff");
Expect.listEquals([0xe000], utf8ToRunes([0xee, 0x80, 0x80]), "e000");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xef, 0xbf, 0xbd]), "fffd");
Expect
.listEquals([0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
// unexpected continuation bytes
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0x80]),
+ Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0x80]),
"80 => replacement character");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xbf]),
+ Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xbf]),
"bf => replacement character");
List<int> allContinuationBytes = <int>[];
List<int> matchingReplacementChars = <int>[];
for (int i = 0x80; i < 0xc0; i++) {
allContinuationBytes.add(i);
- matchingReplacementChars.add(UNICODE_REPLACEMENT_CHARACTER_RUNE);
+ matchingReplacementChars.add(unicodeReplacementCharacterRune);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allContinuationBytes),
"80 - bf => replacement character x 64");
@@ -751,7 +751,7 @@
matchingReplacementChars = <int>[];
for (int i = 0xc0; i < 0xe0; i++) {
allFirstTwoByteSeq.addAll([i, 0x20]);
- matchingReplacementChars.addAll([UNICODE_REPLACEMENT_CHARACTER_RUNE, 0x20]);
+ matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstTwoByteSeq),
"c0 - df + space => replacement character + space x 32");
@@ -760,7 +760,7 @@
matchingReplacementChars = <int>[];
for (int i = 0xe0; i < 0xf0; i++) {
allFirstThreeByteSeq.addAll([i, 0x20]);
- matchingReplacementChars.addAll([UNICODE_REPLACEMENT_CHARACTER_RUNE, 0x20]);
+ matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstThreeByteSeq),
"e0 - ef + space => replacement character x 16");
@@ -769,7 +769,7 @@
matchingReplacementChars = <int>[];
for (int i = 0xf0; i < 0xf8; i++) {
allFirstFourByteSeq.addAll([i, 0x20]);
- matchingReplacementChars.addAll([UNICODE_REPLACEMENT_CHARACTER_RUNE, 0x20]);
+ matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstFourByteSeq),
"f0 - f7 + space => replacement character x 8");
@@ -778,7 +778,7 @@
matchingReplacementChars = <int>[];
for (int i = 0xf8; i < 0xfc; i++) {
allFirstFiveByteSeq.addAll([i, 0x20]);
- matchingReplacementChars.addAll([UNICODE_REPLACEMENT_CHARACTER_RUNE, 0x20]);
+ matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstFiveByteSeq),
"f8 - fb + space => replacement character x 4");
@@ -787,91 +787,91 @@
matchingReplacementChars = <int>[];
for (int i = 0xfc; i < 0xfe; i++) {
allFirstSixByteSeq.addAll([i, 0x20]);
- matchingReplacementChars.addAll([UNICODE_REPLACEMENT_CHARACTER_RUNE, 0x20]);
+ matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstSixByteSeq),
"fc - fd + space => replacement character x 2");
// Sequences with last continuation byte missing
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xc2]),
+ Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xc2]),
"2-byte sequence with last byte missing");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xe0, 0x80]), "3-byte sequence with last byte missing");
Expect.listEquals(
- [UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ [unicodeReplacementCharacterRune],
utf8ToRunes([0xf0, 0x80, 0x80]),
"4-byte sequence with last byte missing");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xf8, 0x88, 0x80, 0x80]),
"5-byte sequence with last byte missing");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80]),
"6-byte sequence with last byte missing");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xdf]),
+ Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xdf]),
"2-byte sequence with last byte missing (hi)");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xef, 0xbf]), "3-byte sequence with last byte missing (hi)");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xf7, 0xbf, 0xbf]),
"4-byte sequence with last byte missing (hi)");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xfb, 0xbf, 0xbf, 0xbf]),
"5-byte sequence with last byte missing (hi)");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xfd, 0xbf, 0xbf, 0xbf, 0xbf]),
"6-byte sequence with last byte missing (hi)");
// Concatenation of incomplete sequences
Expect.listEquals(
[
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
],
utf8ToRunes([
0xc2,
@@ -908,82 +908,82 @@
"Concatenation of incomplete sequences");
// Impossible bytes
- Expect.listEquals(
- [UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xfe]), "fe");
- Expect.listEquals(
- [UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xff]), "ff");
+ Expect
+ .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
+ Expect
+ .listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xfe, 0xfe, 0xff, 0xff]), "fe fe ff ff");
// Overlong sequences
Expect.listEquals(
- [UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xc0, 0xaf]), "c0 af");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0xaf]), "c0 af");
+ Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xf8, 0x80, 0x80, 0x80, 0xaf]), "f8 80 80 80 af");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0xaf]), "fc 80 80 80 80 af");
Expect.listEquals(
- [UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xc1, 0xbf]), "c1 bf");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ [unicodeReplacementCharacterRune], utf8ToRunes([0xc1, 0xbf]), "c1 bf");
+ Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xf8, 0x87, 0xbf, 0xbf, 0xbf]), "f8 87 bf bf bf");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xfc, 0x83, 0xbf, 0xbf, 0xbf, 0xbf]), "fc 83 bf bf bf bf");
Expect.listEquals(
- [UNICODE_REPLACEMENT_CHARACTER_RUNE], utf8ToRunes([0xc0, 0x80]), "c0 80");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ [unicodeReplacementCharacterRune], utf8ToRunes([0xc0, 0x80]), "c0 80");
+ Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
- Expect.listEquals([UNICODE_REPLACEMENT_CHARACTER_RUNE],
+ Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xf8, 0x80, 0x80, 0x80, 0x80]), "f8 80 80 80 80");
Expect.listEquals([
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune
], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0x80]), "fc 80 80 80 80 80");
// Other illegal code positions (???)
diff --git a/tests/lib_2/convert/utf85_test.dart b/tests/lib_2/convert/utf85_test.dart
index ecec964..3f287e9 100644
--- a/tests/lib_2/convert/utf85_test.dart
+++ b/tests/lib_2/convert/utf85_test.dart
@@ -9,7 +9,7 @@
main() {
for (int i = 0; i <= 0x10FFFF; i++) {
- if (i == UNICODE_BOM_CHARACTER_RUNE) continue;
+ if (i == unicodeBomCharacterRune) continue;
Expect.equals(
i, utf8.decode(utf8.encode(new String.fromCharCode(i))).runes.first);
}
diff --git a/tests/lib_2/convert/utf8_test.dart b/tests/lib_2/convert/utf8_test.dart
index fc1856b..858c982 100644
--- a/tests/lib_2/convert/utf8_test.dart
+++ b/tests/lib_2/convert/utf8_test.dart
@@ -67,7 +67,7 @@
var typed = new Uint8List.fromList(input);
Expect.throws(() {
- UTF8.decoder.convert(typed);
+ utf8.decoder.convert(typed);
}, (e) => e is FormatException && typed == e.source && offset == e.offset);
}
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index b8926562..1d2d4a3 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -8,7 +8,6 @@
[ $compiler == dartdevk ]
async/slow_consumer_test: CompileTimeError
-collection/list_test: RuntimeError
convert/chunked_conversion1_test: RuntimeError
convert/chunked_conversion_utf82_test: RuntimeError
convert/chunked_conversion_utf86_test: RuntimeError
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index d51d869..cd95ea9 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -136,7 +136,6 @@
mirrors/library_exports_hidden_test: RuntimeError, Crash, CompileTimeError # Issue 31402 (Invocation arguments)
mirrors/library_exports_shown_test: RuntimeError, CompileTimeError # Issue 31402 (Invocation arguments)
mirrors/library_import_deferred_loading_test: RuntimeError # Deferred loading kernel issue 28335.
-mirrors/library_imports_bad_metadata_test/none: Crash
mirrors/library_imports_deferred_test: RuntimeError, CompileTimeError # Issue 31402 (Invocation arguments)
mirrors/library_imports_hidden_test: RuntimeError # Issue 31402 (Invocation arguments)
mirrors/library_imports_metadata_test: RuntimeError # Issue 31402 (Invocation arguments)
@@ -253,7 +252,7 @@
mirrors/instantiate_abstract_class_test: RuntimeError
mirrors/invoke_closurization2_test: RuntimeError
mirrors/invoke_throws_test: RuntimeError
-mirrors/library_imports_bad_metadata_test/none: RuntimeError
+mirrors/library_imports_bad_metadata_test/none: RuntimeError, Crash # Issue 32879
mirrors/metadata_const_map_test: Crash
mirrors/mixin_members_test: RuntimeError
mirrors/null_test: RuntimeError
@@ -332,7 +331,6 @@
[ $compiler == fasta && $strong ]
isolate/isolate_stress_test: CompileTimeError
mirrors/deferred_type_test: CompileTimeError
-mirrors/library_imports_bad_metadata_test/01: Crash
mirrors/metadata_allowed_values_test/02: MissingCompileTimeError
mirrors/metadata_allowed_values_test/27: MissingCompileTimeError
mirrors/metadata_constructor_arguments_test/04: MissingCompileTimeError
@@ -350,7 +348,6 @@
[ $fasta && !$strong ]
isolate/isolate_import_test/01: MissingCompileTimeError
isolate/isolate_stress_test: CompileTimeError
-mirrors/library_imports_bad_metadata_test/01: Crash
mirrors/metadata_allowed_values_test/02: MissingCompileTimeError
mirrors/metadata_allowed_values_test/27: MissingCompileTimeError
mirrors/metadata_constructor_arguments_test/04: MissingCompileTimeError
diff --git a/tests/standalone/verbose_gc_to_bmu_test.dart b/tests/standalone/verbose_gc_to_bmu_test.dart
index 5213d4c..884e139 100644
--- a/tests/standalone/verbose_gc_to_bmu_test.dart
+++ b/tests/standalone/verbose_gc_to_bmu_test.dart
@@ -43,9 +43,9 @@
process.stdin.write(gcLog);
process.stdin.close();
var stdoutStringStream =
- process.stdout.transform(UTF8.decoder).transform(new LineSplitter());
+ process.stdout.transform(utf8.decoder).transform(new LineSplitter());
var stderrStringStream =
- process.stderr.transform(UTF8.decoder).transform(new LineSplitter());
+ process.stderr.transform(utf8.decoder).transform(new LineSplitter());
// Wait for 3 future events: stdout and stderr streams closed, and
// process terminated.
var futures = [];
diff --git a/tests/standalone_2/io/file_test.dart b/tests/standalone_2/io/file_test.dart
index c5229cf..da550d8 100644
--- a/tests/standalone_2/io/file_test.dart
+++ b/tests/standalone_2/io/file_test.dart
@@ -1201,8 +1201,8 @@
text = new File(name).readAsStringSync(encoding: lenientAscii);
// Default replacement character is the Unicode replacement character.
expected = [
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
- UNICODE_REPLACEMENT_CHARACTER_RUNE,
+ unicodeReplacementCharacterRune,
+ unicodeReplacementCharacterRune,
120,
46,
32,
diff --git a/tests/standalone_2/io/file_typed_data_test.dart b/tests/standalone_2/io/file_typed_data_test.dart
index b6efa40..4ef1612 100644
--- a/tests/standalone_2/io/file_typed_data_test.dart
+++ b/tests/standalone_2/io/file_typed_data_test.dart
@@ -14,7 +14,7 @@
void testWriteInt8ListAndView() {
asyncStart();
const int LIST_LENGTH = 8;
- const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int8List.BYTES_PER_ELEMENT;
+ const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int8List.bytesPerElement;
const int VIEW_LENGTH = 4;
Int8List list = new Int8List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
@@ -44,7 +44,7 @@
void testWriteUint8ListAndView() {
asyncStart();
const int LIST_LENGTH = 8;
- const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint8List.BYTES_PER_ELEMENT;
+ const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint8List.bytesPerElement;
const int VIEW_LENGTH = 4;
Uint8List list = new Uint8List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
@@ -104,10 +104,10 @@
void testWriteInt16ListAndView() {
asyncStart();
const int LIST_LENGTH = 8;
- const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int16List.BYTES_PER_ELEMENT;
- const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int16List.BYTES_PER_ELEMENT;
+ const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int16List.bytesPerElement;
+ const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int16List.bytesPerElement;
const int VIEW_LENGTH = 4;
- const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int16List.BYTES_PER_ELEMENT;
+ const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int16List.bytesPerElement;
var list = new Int16List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
@@ -146,10 +146,10 @@
void testWriteUint16ListAndView() {
asyncStart();
const int LIST_LENGTH = 8;
- const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Uint16List.BYTES_PER_ELEMENT;
- const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint16List.BYTES_PER_ELEMENT;
+ const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Uint16List.bytesPerElement;
+ const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint16List.bytesPerElement;
const int VIEW_LENGTH = 4;
- const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint16List.BYTES_PER_ELEMENT;
+ const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint16List.bytesPerElement;
var list = new Uint16List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
@@ -188,10 +188,10 @@
void testWriteInt32ListAndView() {
asyncStart();
const int LIST_LENGTH = 8;
- const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int32List.BYTES_PER_ELEMENT;
- const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int32List.BYTES_PER_ELEMENT;
+ const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int32List.bytesPerElement;
+ const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int32List.bytesPerElement;
const int VIEW_LENGTH = 4;
- const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.BYTES_PER_ELEMENT;
+ const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.bytesPerElement;
var list = new Int32List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
@@ -230,10 +230,10 @@
void testWriteUint32ListAndView() {
asyncStart();
const int LIST_LENGTH = 8;
- const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int32List.BYTES_PER_ELEMENT;
- const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int32List.BYTES_PER_ELEMENT;
+ const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int32List.bytesPerElement;
+ const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int32List.bytesPerElement;
const int VIEW_LENGTH = 4;
- const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.BYTES_PER_ELEMENT;
+ const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int32List.bytesPerElement;
var list = new Uint32List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
@@ -272,10 +272,10 @@
void testWriteInt64ListAndView() {
asyncStart();
const int LIST_LENGTH = 8;
- const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int64List.BYTES_PER_ELEMENT;
- const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int64List.BYTES_PER_ELEMENT;
+ const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Int64List.bytesPerElement;
+ const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Int64List.bytesPerElement;
const int VIEW_LENGTH = 4;
- const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int64List.BYTES_PER_ELEMENT;
+ const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Int64List.bytesPerElement;
var list = new Int64List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
@@ -314,10 +314,10 @@
void testWriteUint64ListAndView() {
asyncStart();
const int LIST_LENGTH = 8;
- const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Uint64List.BYTES_PER_ELEMENT;
- const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint64List.BYTES_PER_ELEMENT;
+ const int LIST_LENGTH_IN_BYTES = LIST_LENGTH * Uint64List.bytesPerElement;
+ const int OFFSET_IN_BYTES_FOR_VIEW = 2 * Uint64List.bytesPerElement;
const int VIEW_LENGTH = 4;
- const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint64List.BYTES_PER_ELEMENT;
+ const int VIEW_LENGTH_IN_BYTES = VIEW_LENGTH * Uint64List.bytesPerElement;
var list = new Uint64List(LIST_LENGTH);
for (int i = 0; i < LIST_LENGTH; i++) list[i] = i;
var view =
diff --git a/tests/standalone_2/io/process_inherit_stdio_test.dart b/tests/standalone_2/io/process_inherit_stdio_test.dart
index 9ca1bf6..375f87e 100644
--- a/tests/standalone_2/io/process_inherit_stdio_test.dart
+++ b/tests/standalone_2/io/process_inherit_stdio_test.dart
@@ -26,7 +26,7 @@
Completer<String> s = new Completer();
future.then((process) {
StringBuffer buf = new StringBuffer();
- process.stdout.transform(UTF8.decoder).listen((data) {
+ process.stdout.transform(utf8.decoder).listen((data) {
buf.write(data);
}, onDone: () {
s.complete(buf.toString());
diff --git a/tests/standalone_2/map_insert_remove_oom_test.dart b/tests/standalone_2/map_insert_remove_oom_test.dart
index 25c1a33..f20126a 100644
--- a/tests/standalone_2/map_insert_remove_oom_test.dart
+++ b/tests/standalone_2/map_insert_remove_oom_test.dart
@@ -2,7 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
-// VMOptions=--old_gen_heap_size=10
+// VMOptions=--old_gen_heap_size=11
+//
+// Notice we set the old gen heap size to 11 MB, which seems to be the minimum
+// (in debug mode) to not cause us run OOM during isolate initialization. The
+// problem here is that we pre-allocate certain exceptions, e.g. NullThrownError
+// during isolate initialization, but if we have an allocation failure before
+// that, we end up running into a recursive allocate/throw loop.
+//
// Test that compaction does occur on repeated add/remove.
main() {
diff --git a/tools/VERSION b/tools/VERSION
index 7f55251..4229ed2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 0
PATCH 0
-PRERELEASE 48
+PRERELEASE 49
PRERELEASE_PATCH 0
diff --git a/tools/apps/update_homebrew/lib/update_homebrew.dart b/tools/apps/update_homebrew/lib/update_homebrew.dart
index 5628c41..477ddb0 100644
--- a/tools/apps/update_homebrew/lib/update_homebrew.dart
+++ b/tools/apps/update_homebrew/lib/update_homebrew.dart
@@ -33,7 +33,7 @@
'channels/$channel/release/$revision/$download.sha256sum',
downloadOptions: DownloadOptions.FullMedia);
- var hashLine = await ASCII.decodeStream(media.stream);
+ var hashLine = await ascii.decodeStream(media.stream);
return new RegExp('[0-9a-fA-F]*').stringMatch(hashLine);
} finally {
client.close();
@@ -49,7 +49,7 @@
'dart-archive', 'channels/$channel/release/$revision/VERSION',
downloadOptions: DownloadOptions.FullMedia);
- var versionObject = await JSON.fuse(ASCII).decoder.bind(media.stream).first;
+ var versionObject = await json.fuse(ascii).decoder.bind(media.stream).first;
return versionObject['version'];
} finally {
client.close();
diff --git a/tools/build.py b/tools/build.py
index df5c045..f22d32d 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -1,14 +1,317 @@
#!/usr/bin/env python
#
-# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
-# This script simply forwards to tools/ninja.py. It is retained simply to avoid
-# breaking various workflows.
-
-import ninja
+import multiprocessing
+import optparse
+import os
+import subprocess
import sys
+import time
+import utils
+
+HOST_OS = utils.GuessOS()
+HOST_CPUS = utils.GuessCpus()
+SCRIPT_DIR = os.path.dirname(sys.argv[0])
+DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
+
+usage = """\
+usage: %%prog [options] [targets]
+
+This script invokes ninja to build Dart.
+"""
+
+
+def BuildOptions():
+ result = optparse.OptionParser(usage=usage)
+ result.add_option("-m", "--mode",
+ help='Build variants (comma-separated).',
+ metavar='[all,debug,release,product]',
+ default='debug')
+ result.add_option("-v", "--verbose",
+ help='Verbose output.',
+ default=False, action="store_true")
+ result.add_option("-a", "--arch",
+ help='Target architectures (comma-separated).',
+ metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
+ 'simarm64,arm64,simdbc,armsimdbc]',
+ default=utils.GuessArchitecture())
+ result.add_option("--os",
+ help='Target OSs (comma-separated).',
+ metavar='[all,host,android]',
+ default='host')
+ result.add_option("-j",
+ type=int,
+ help='Ninja -j option for Goma builds.',
+ metavar=1000,
+ default=1000)
+ result.add_option("--no-start-goma",
+ help="Don't try to start goma",
+ default=False,
+ action='store_true')
+ return result
+
+
+def ProcessOsOption(os_name):
+ if os_name == 'host':
+ return HOST_OS
+ return os_name
+
+
+def ProcessOptions(options, args):
+ if options.arch == 'all':
+ options.arch = 'ia32,x64,simarm,simarm64,simdbc64'
+ if options.mode == 'all':
+ options.mode = 'debug,release,product'
+ if options.os == 'all':
+ options.os = 'host,android'
+ options.mode = options.mode.split(',')
+ options.arch = options.arch.split(',')
+ options.os = options.os.split(',')
+ for mode in options.mode:
+ if not mode in ['debug', 'release', 'product']:
+ print "Unknown mode %s" % mode
+ return False
+ for arch in options.arch:
+ archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
+ 'simarmv5te', 'armv5te', 'simarm64', 'arm64',
+ 'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
+ if not arch in archs:
+ print "Unknown arch %s" % arch
+ return False
+ options.os = [ProcessOsOption(os_name) for os_name in options.os]
+ for os_name in options.os:
+ if not os_name in ['android', 'freebsd', 'linux', 'macos', 'win32']:
+ print "Unknown os %s" % os_name
+ return False
+ if os_name != HOST_OS:
+ if os_name != 'android':
+ print "Unsupported target os %s" % os_name
+ return False
+ if not HOST_OS in ['linux', 'macos']:
+ print ("Cross-compilation to %s is not supported on host os %s."
+ % (os_name, HOST_OS))
+ return False
+ if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64',
+ 'simdbc', 'simdbc64']:
+ print ("Cross-compilation to %s is not supported for architecture %s."
+ % (os_name, arch))
+ return False
+ # We have not yet tweaked the v8 dart build to work with the Android
+ # NDK/SDK, so don't try to build it.
+ if not args:
+ print "For android builds you must specify a target, such as 'runtime'."
+ return False
+ return True
+
+
+def NotifyBuildDone(build_config, success, start):
+ if not success:
+ print "BUILD FAILED"
+
+ sys.stdout.flush()
+
+ # Display a notification if build time exceeded DART_BUILD_NOTIFICATION_DELAY.
+ notification_delay = float(
+ os.getenv('DART_BUILD_NOTIFICATION_DELAY', sys.float_info.max))
+ if (time.time() - start) < notification_delay:
+ return
+
+ if success:
+ message = 'Build succeeded.'
+ else:
+ message = 'Build failed.'
+ title = build_config
+
+ command = None
+ if HOST_OS == 'macos':
+ # Use AppleScript to display a UI non-modal notification.
+ script = 'display notification "%s" with title "%s" sound name "Glass"' % (
+ message, title)
+ command = "osascript -e '%s' &" % script
+ elif HOST_OS == 'linux':
+ if success:
+ icon = 'dialog-information'
+ else:
+ icon = 'dialog-error'
+ command = "notify-send -i '%s' '%s' '%s' &" % (icon, message, title)
+ elif HOST_OS == 'win32':
+ if success:
+ icon = 'info'
+ else:
+ icon = 'error'
+ command = ("powershell -command \""
+ "[reflection.assembly]::loadwithpartialname('System.Windows.Forms')"
+ "| Out-Null;"
+ "[reflection.assembly]::loadwithpartialname('System.Drawing')"
+ "| Out-Null;"
+ "$n = new-object system.windows.forms.notifyicon;"
+ "$n.icon = [system.drawing.systemicons]::information;"
+ "$n.visible = $true;"
+ "$n.showballoontip(%d, '%s', '%s', "
+ "[system.windows.forms.tooltipicon]::%s);\"") % (
+ 5000, # Notification stays on for this many milliseconds
+ message, title, icon)
+
+ if command:
+ # Ignore return code, if this command fails, it doesn't matter.
+ os.system(command)
+
+
+def RunGN(target_os, mode, arch):
+ gn_os = 'host' if target_os == HOST_OS else target_os
+ gn_command = [
+ 'python',
+ os.path.join(DART_ROOT, 'tools', 'gn.py'),
+ '-m', mode,
+ '-a', arch,
+ '--os', gn_os,
+ '-v',
+ ]
+ process = subprocess.Popen(gn_command)
+ process.wait()
+ if process.returncode != 0:
+ print ("Tried to run GN, but it failed. Try running it manually: \n\t$ " +
+ ' '.join(gn_command))
+
+
+def ShouldRunGN(out_dir):
+ return (not os.path.exists(out_dir) or
+ not os.path.isfile(os.path.join(out_dir, 'args.gn')))
+
+
+def UseGoma(out_dir):
+ args_gn = os.path.join(out_dir, 'args.gn')
+ return 'use_goma = true' in open(args_gn, 'r').read()
+
+
+# Try to start goma, but don't bail out if we can't. Instead print an error
+# message, and let the build fail with its own error messages as well.
+goma_started = False
+def EnsureGomaStarted(out_dir):
+ global goma_started
+ if goma_started:
+ return True
+ args_gn_path = os.path.join(out_dir, 'args.gn')
+ goma_dir = None
+ with open(args_gn_path, 'r') as fp:
+ for line in fp:
+ if 'goma_dir' in line:
+ words = line.split()
+ goma_dir = words[2][1:-1] # goma_dir = "/path/to/goma"
+ if not goma_dir:
+ print 'Could not find goma for ' + out_dir
+ return False
+ if not os.path.exists(goma_dir) or not os.path.isdir(goma_dir):
+ print 'Could not find goma at ' + goma_dir
+ return False
+ goma_ctl = os.path.join(goma_dir, 'goma_ctl.py')
+ goma_ctl_command = [
+ 'python',
+ goma_ctl,
+ 'ensure_start',
+ ]
+ process = subprocess.Popen(goma_ctl_command)
+ process.wait()
+ if process.returncode != 0:
+ print ("Tried to run goma_ctl.py, but it failed. Try running it manually: "
+ + "\n\t" + ' '.join(goma_ctl_command))
+ return False
+ goma_started = True
+ return True
+
+
+# Returns a tuple (build_config, command to run, whether goma is used)
+def BuildOneConfig(options, targets, target_os, mode, arch):
+ build_config = utils.GetBuildConf(mode, arch, target_os)
+ out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
+ using_goma = False
+ if ShouldRunGN(out_dir):
+ RunGN(target_os, mode, arch)
+ command = ['ninja', '-C', out_dir]
+ if options.verbose:
+ command += ['-v']
+ if UseGoma(out_dir):
+ if options.no_start_goma or EnsureGomaStarted(out_dir):
+ using_goma = True
+ command += [('-j%s' % str(options.j))]
+ else:
+ # If we couldn't ensure that goma is started, let the build start, but
+ # slowly so we can see any helpful error messages that pop out.
+ command += ['-j1']
+ command += targets
+ return (build_config, command, using_goma)
+
+
+def RunOneBuildCommand(build_config, args):
+ start_time = time.time()
+ print ' '.join(args)
+ process = subprocess.Popen(args, stdin=None)
+ process.wait()
+ if process.returncode != 0:
+ NotifyBuildDone(build_config, success=False, start=start_time)
+ return 1
+ else:
+ NotifyBuildDone(build_config, success=True, start=start_time)
+
+ return 0
+
+
+def RunOneGomaBuildCommand(args):
+ try:
+ print ' '.join(args)
+ process = subprocess.Popen(args, stdin=None)
+ process.wait()
+ print (' '.join(args) + " done.")
+ return process.returncode
+ except KeyboardInterrupt:
+ return 1
+
+
+def Main():
+ starttime = time.time()
+ # Parse the options.
+ parser = BuildOptions()
+ (options, args) = parser.parse_args()
+ if not ProcessOptions(options, args):
+ parser.print_help()
+ return 1
+ # Determine which targets to build. By default we build the "all" target.
+ if len(args) == 0:
+ targets = ['all']
+ else:
+ targets = args
+
+ # Build all targets for each requested configuration.
+ configs = []
+ for target_os in options.os:
+ for mode in options.mode:
+ for arch in options.arch:
+ configs.append(BuildOneConfig(options, targets, target_os, mode, arch))
+
+ # Build regular configs.
+ goma_builds = []
+ for (build_config, args, goma) in configs:
+ if args is None:
+ return 1
+ if goma:
+ goma_builds.append(args)
+ elif RunOneBuildCommand(build_config, args) != 0:
+ return 1
+
+ # Run goma builds in parallel.
+ pool = multiprocessing.Pool(multiprocessing.cpu_count())
+ results = pool.map(RunOneGomaBuildCommand, goma_builds, chunksize=1)
+ for r in results:
+ if r != 0:
+ return 1
+
+ endtime = time.time()
+ print ("The build took %.3f seconds" % (endtime - starttime))
+ return 0
+
if __name__ == '__main__':
- sys.exit(ninja.Main())
+ sys.exit(Main())
diff --git a/tools/gardening/lib/src/buildbucket.dart b/tools/gardening/lib/src/buildbucket.dart
index d2fcc73..ff4db96 100644
--- a/tools/gardening/lib/src/buildbucket.dart
+++ b/tools/gardening/lib/src/buildbucket.dart
@@ -12,14 +12,14 @@
var api = new BuildBucketApi();
var result = api.search("buildset:patch/gerrit/dart-review.googlesource.com/"
"${changeNumber}/${patchset}");
- return result.then(JSON.decode).then(_buildsFromJson);
+ return result.then(jsonDecode).then(_buildsFromJson);
}
/// Get builds from a swarming task with [swarmingTaskId].
Future<List<BuildBucketBuild>> buildsFromSwarmingTaskId(String swarmingTaskId) {
var api = new BuildBucketApi();
var result = api.search("swarming_task_id:$swarmingTaskId");
- return result.then(JSON.decode).then(_buildsFromJson);
+ return result.then(jsonDecode).then(_buildsFromJson);
}
/// Gets builds from a [builder] in descending order.
@@ -32,14 +32,14 @@
fields: "builds(id,tags)",
status: "COMPLETED",
result: "SUCCESS");
- return result.then(JSON.decode).then(_buildsFromJson);
+ return result.then(jsonDecode).then(_buildsFromJson);
}
/// Fetches all builders from a specific [clientBucket].
Future<Iterable<Builder>> fetchBuilders(String clientBucket) async {
BuildBucketApi api = new BuildBucketApi();
String result = await api.builders();
- var json = JSON.decode(result);
+ var json = jsonDecode(result);
var buckets = json["buckets"].where((bucket) {
return bucket["name"] == clientBucket;
});
diff --git a/tools/gardening/lib/src/logdog_rpc.dart b/tools/gardening/lib/src/logdog_rpc.dart
index 06e7766..32f1499 100644
--- a/tools/gardening/lib/src/logdog_rpc.dart
+++ b/tools/gardening/lib/src/logdog_rpc.dart
@@ -17,12 +17,12 @@
scheme: "https", host: LOGDOG_HOST, path: "prpc/logdog.Logs/Get");
var body = {"project": project, "path": path};
return withCache(
- () => _makePostRequest(uri, JSON.encode(body), {
+ () => _makePostRequest(uri, jsonEncode(body), {
HttpHeaders.CONTENT_TYPE: "application/json",
HttpHeaders.ACCEPT: "application/json"
}),
"logdog-get-$path")
- .then(JSON.decode)
+ .then(jsonDecode)
.then((json) {
StringBuffer buffer = new StringBuffer();
json["logs"].forEach((log) {
@@ -41,12 +41,12 @@
scheme: "https", host: LOGDOG_HOST, path: "prpc/logdog.Logs/Query");
var body = {"project": project, "path": path, "maxResults": maxResults};
return withCache(
- () => _makePostRequest(uri, JSON.encode(body), {
+ () => _makePostRequest(uri, jsonEncode(body), {
HttpHeaders.CONTENT_TYPE: "application/json",
HttpHeaders.ACCEPT: "application/json"
}),
"logdog-query-$path")
- .then(JSON.decode)
+ .then(jsonDecode)
.then((json) {
if (json["streams"] == null) {
return <LogdogStream>[];
diff --git a/tools/gardening/lib/src/luci_api.dart b/tools/gardening/lib/src/luci_api.dart
index 2a44833..bf808f0 100644
--- a/tools/gardening/lib/src/luci_api.dart
+++ b/tools/gardening/lib/src/luci_api.dart
@@ -34,7 +34,7 @@
host: CBE_HOST,
path: "/get_master/${client}")),
"cbe")
- .then(JSON.decode);
+ .then(jsonDecode);
}
/// Calling the Milo Api to get latest builds for this bot,
@@ -53,15 +53,15 @@
"includeCurrent": true
};
return withCache(
- () => _makePostRequest(uri, JSON.encode(body), {
+ () => _makePostRequest(uri, jsonEncode(body), {
HttpHeaders.CONTENT_TYPE: "application/json",
HttpHeaders.ACCEPT: "application/json"
}),
'${uri.path}_${botName}_$amount')
- .then(JSON.decode)
+ .then(jsonDecode)
.then((json) {
return json["builds"].map((b) {
- var build = JSON.decode(UTF8.decode(BASE64.decode(b["data"])));
+ var build = jsonDecode(utf8.decode(base64Decode(b["data"])));
return getBuildDetailFromJson(client, botName, build);
}).toList();
});
@@ -77,14 +77,14 @@
path: "prpc/milo.Buildbot/GetBuildbotBuildJSON");
var body = {"master": client, "builder": botName, "buildNum": buildNumber};
return withCache(
- () => _makePostRequest(uri, JSON.encode(body), {
+ () => _makePostRequest(uri, jsonEncode(body), {
HttpHeaders.CONTENT_TYPE: "application/json",
HttpHeaders.ACCEPT: "application/json"
}),
'${uri.path}_${botName}_$buildNumber')
- .then(JSON.decode)
+ .then(jsonDecode)
.then((json) {
- var build = JSON.decode(UTF8.decode(BASE64.decode(json["data"])));
+ var build = jsonDecode(utf8.decode(base64Decode(json["data"])));
return getBuildDetailFromJson(client, botName, build);
});
}
@@ -97,7 +97,7 @@
response.drain();
throw new HttpException(response.reasonPhrase, uri: uri);
}
- return response.transform(UTF8.decoder).join();
+ return response.transform(utf8.decoder).join();
}
/// [_makePostRequest] performs a post request to [uri], where the posted
diff --git a/tools/gardening/lib/src/results/test_result_service.dart b/tools/gardening/lib/src/results/test_result_service.dart
index f6a56d7..9d9326a 100644
--- a/tools/gardening/lib/src/results/test_result_service.dart
+++ b/tools/gardening/lib/src/results/test_result_service.dart
@@ -89,7 +89,7 @@
var cache = createCache ?? standardCache;
return logdog
.get(BUILDER_PROJECT, logName, cache(duration: new Duration(days: 365)))
- .then((json) => new TestResult.fromJson(JSON.decode(json)));
+ .then((json) => new TestResult.fromJson(jsonDecode(json)));
}
/// Gets result logs from logdog streams.
@@ -99,7 +99,7 @@
return Future.wait(streams.map((stream) {
logger.debug('Getting the log ${stream.path}...');
return logdog.get(project, stream.path, cache).then((log) {
- return new TestResult.fromJson(JSON.decode(log));
+ return new TestResult.fromJson(jsonDecode(log));
}).catchError(
errorLogger(logger, "Could not get a log.", new TestResult()));
}));
@@ -221,7 +221,7 @@
Future<TestResult> getFromFile(File file) {
return file
.readAsString()
- .then(JSON.decode)
+ .then(jsonDecode)
.then((json) => new TestResult.fromJson(json));
}
}
diff --git a/tools/gardening/lib/src/util.dart b/tools/gardening/lib/src/util.dart
index d0b44cd..48c3848 100644
--- a/tools/gardening/lib/src/util.dart
+++ b/tools/gardening/lib/src/util.dart
@@ -88,9 +88,9 @@
throw new HttpException(uri, response.statusCode);
}
if (timeout != null) {
- return response.timeout(timeout).transform(UTF8.decoder).join();
+ return response.timeout(timeout).transform(utf8.decoder).join();
} else {
- return response.transform(UTF8.decoder).join();
+ return response.transform(utf8.decoder).join();
}
}
diff --git a/tools/ninja.py b/tools/ninja.py
deleted file mode 100755
index f22d32d..0000000
--- a/tools/ninja.py
+++ /dev/null
@@ -1,317 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import multiprocessing
-import optparse
-import os
-import subprocess
-import sys
-import time
-import utils
-
-HOST_OS = utils.GuessOS()
-HOST_CPUS = utils.GuessCpus()
-SCRIPT_DIR = os.path.dirname(sys.argv[0])
-DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
-
-usage = """\
-usage: %%prog [options] [targets]
-
-This script invokes ninja to build Dart.
-"""
-
-
-def BuildOptions():
- result = optparse.OptionParser(usage=usage)
- result.add_option("-m", "--mode",
- help='Build variants (comma-separated).',
- metavar='[all,debug,release,product]',
- default='debug')
- result.add_option("-v", "--verbose",
- help='Verbose output.',
- default=False, action="store_true")
- result.add_option("-a", "--arch",
- help='Target architectures (comma-separated).',
- metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
- 'simarm64,arm64,simdbc,armsimdbc]',
- default=utils.GuessArchitecture())
- result.add_option("--os",
- help='Target OSs (comma-separated).',
- metavar='[all,host,android]',
- default='host')
- result.add_option("-j",
- type=int,
- help='Ninja -j option for Goma builds.',
- metavar=1000,
- default=1000)
- result.add_option("--no-start-goma",
- help="Don't try to start goma",
- default=False,
- action='store_true')
- return result
-
-
-def ProcessOsOption(os_name):
- if os_name == 'host':
- return HOST_OS
- return os_name
-
-
-def ProcessOptions(options, args):
- if options.arch == 'all':
- options.arch = 'ia32,x64,simarm,simarm64,simdbc64'
- if options.mode == 'all':
- options.mode = 'debug,release,product'
- if options.os == 'all':
- options.os = 'host,android'
- options.mode = options.mode.split(',')
- options.arch = options.arch.split(',')
- options.os = options.os.split(',')
- for mode in options.mode:
- if not mode in ['debug', 'release', 'product']:
- print "Unknown mode %s" % mode
- return False
- for arch in options.arch:
- archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
- 'simarmv5te', 'armv5te', 'simarm64', 'arm64',
- 'simdbc', 'simdbc64', 'armsimdbc', 'armsimdbc64']
- if not arch in archs:
- print "Unknown arch %s" % arch
- return False
- options.os = [ProcessOsOption(os_name) for os_name in options.os]
- for os_name in options.os:
- if not os_name in ['android', 'freebsd', 'linux', 'macos', 'win32']:
- print "Unknown os %s" % os_name
- return False
- if os_name != HOST_OS:
- if os_name != 'android':
- print "Unsupported target os %s" % os_name
- return False
- if not HOST_OS in ['linux', 'macos']:
- print ("Cross-compilation to %s is not supported on host os %s."
- % (os_name, HOST_OS))
- return False
- if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64',
- 'simdbc', 'simdbc64']:
- print ("Cross-compilation to %s is not supported for architecture %s."
- % (os_name, arch))
- return False
- # We have not yet tweaked the v8 dart build to work with the Android
- # NDK/SDK, so don't try to build it.
- if not args:
- print "For android builds you must specify a target, such as 'runtime'."
- return False
- return True
-
-
-def NotifyBuildDone(build_config, success, start):
- if not success:
- print "BUILD FAILED"
-
- sys.stdout.flush()
-
- # Display a notification if build time exceeded DART_BUILD_NOTIFICATION_DELAY.
- notification_delay = float(
- os.getenv('DART_BUILD_NOTIFICATION_DELAY', sys.float_info.max))
- if (time.time() - start) < notification_delay:
- return
-
- if success:
- message = 'Build succeeded.'
- else:
- message = 'Build failed.'
- title = build_config
-
- command = None
- if HOST_OS == 'macos':
- # Use AppleScript to display a UI non-modal notification.
- script = 'display notification "%s" with title "%s" sound name "Glass"' % (
- message, title)
- command = "osascript -e '%s' &" % script
- elif HOST_OS == 'linux':
- if success:
- icon = 'dialog-information'
- else:
- icon = 'dialog-error'
- command = "notify-send -i '%s' '%s' '%s' &" % (icon, message, title)
- elif HOST_OS == 'win32':
- if success:
- icon = 'info'
- else:
- icon = 'error'
- command = ("powershell -command \""
- "[reflection.assembly]::loadwithpartialname('System.Windows.Forms')"
- "| Out-Null;"
- "[reflection.assembly]::loadwithpartialname('System.Drawing')"
- "| Out-Null;"
- "$n = new-object system.windows.forms.notifyicon;"
- "$n.icon = [system.drawing.systemicons]::information;"
- "$n.visible = $true;"
- "$n.showballoontip(%d, '%s', '%s', "
- "[system.windows.forms.tooltipicon]::%s);\"") % (
- 5000, # Notification stays on for this many milliseconds
- message, title, icon)
-
- if command:
- # Ignore return code, if this command fails, it doesn't matter.
- os.system(command)
-
-
-def RunGN(target_os, mode, arch):
- gn_os = 'host' if target_os == HOST_OS else target_os
- gn_command = [
- 'python',
- os.path.join(DART_ROOT, 'tools', 'gn.py'),
- '-m', mode,
- '-a', arch,
- '--os', gn_os,
- '-v',
- ]
- process = subprocess.Popen(gn_command)
- process.wait()
- if process.returncode != 0:
- print ("Tried to run GN, but it failed. Try running it manually: \n\t$ " +
- ' '.join(gn_command))
-
-
-def ShouldRunGN(out_dir):
- return (not os.path.exists(out_dir) or
- not os.path.isfile(os.path.join(out_dir, 'args.gn')))
-
-
-def UseGoma(out_dir):
- args_gn = os.path.join(out_dir, 'args.gn')
- return 'use_goma = true' in open(args_gn, 'r').read()
-
-
-# Try to start goma, but don't bail out if we can't. Instead print an error
-# message, and let the build fail with its own error messages as well.
-goma_started = False
-def EnsureGomaStarted(out_dir):
- global goma_started
- if goma_started:
- return True
- args_gn_path = os.path.join(out_dir, 'args.gn')
- goma_dir = None
- with open(args_gn_path, 'r') as fp:
- for line in fp:
- if 'goma_dir' in line:
- words = line.split()
- goma_dir = words[2][1:-1] # goma_dir = "/path/to/goma"
- if not goma_dir:
- print 'Could not find goma for ' + out_dir
- return False
- if not os.path.exists(goma_dir) or not os.path.isdir(goma_dir):
- print 'Could not find goma at ' + goma_dir
- return False
- goma_ctl = os.path.join(goma_dir, 'goma_ctl.py')
- goma_ctl_command = [
- 'python',
- goma_ctl,
- 'ensure_start',
- ]
- process = subprocess.Popen(goma_ctl_command)
- process.wait()
- if process.returncode != 0:
- print ("Tried to run goma_ctl.py, but it failed. Try running it manually: "
- + "\n\t" + ' '.join(goma_ctl_command))
- return False
- goma_started = True
- return True
-
-
-# Returns a tuple (build_config, command to run, whether goma is used)
-def BuildOneConfig(options, targets, target_os, mode, arch):
- build_config = utils.GetBuildConf(mode, arch, target_os)
- out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
- using_goma = False
- if ShouldRunGN(out_dir):
- RunGN(target_os, mode, arch)
- command = ['ninja', '-C', out_dir]
- if options.verbose:
- command += ['-v']
- if UseGoma(out_dir):
- if options.no_start_goma or EnsureGomaStarted(out_dir):
- using_goma = True
- command += [('-j%s' % str(options.j))]
- else:
- # If we couldn't ensure that goma is started, let the build start, but
- # slowly so we can see any helpful error messages that pop out.
- command += ['-j1']
- command += targets
- return (build_config, command, using_goma)
-
-
-def RunOneBuildCommand(build_config, args):
- start_time = time.time()
- print ' '.join(args)
- process = subprocess.Popen(args, stdin=None)
- process.wait()
- if process.returncode != 0:
- NotifyBuildDone(build_config, success=False, start=start_time)
- return 1
- else:
- NotifyBuildDone(build_config, success=True, start=start_time)
-
- return 0
-
-
-def RunOneGomaBuildCommand(args):
- try:
- print ' '.join(args)
- process = subprocess.Popen(args, stdin=None)
- process.wait()
- print (' '.join(args) + " done.")
- return process.returncode
- except KeyboardInterrupt:
- return 1
-
-
-def Main():
- starttime = time.time()
- # Parse the options.
- parser = BuildOptions()
- (options, args) = parser.parse_args()
- if not ProcessOptions(options, args):
- parser.print_help()
- return 1
- # Determine which targets to build. By default we build the "all" target.
- if len(args) == 0:
- targets = ['all']
- else:
- targets = args
-
- # Build all targets for each requested configuration.
- configs = []
- for target_os in options.os:
- for mode in options.mode:
- for arch in options.arch:
- configs.append(BuildOneConfig(options, targets, target_os, mode, arch))
-
- # Build regular configs.
- goma_builds = []
- for (build_config, args, goma) in configs:
- if args is None:
- return 1
- if goma:
- goma_builds.append(args)
- elif RunOneBuildCommand(build_config, args) != 0:
- return 1
-
- # Run goma builds in parallel.
- pool = multiprocessing.Pool(multiprocessing.cpu_count())
- results = pool.map(RunOneGomaBuildCommand, goma_builds, chunksize=1)
- for r in results:
- if r != 0:
- return 1
-
- endtime = time.time()
- print ("The build took %.3f seconds" % (endtime - starttime))
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(Main())
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart
index f8dd6fc..53f4002 100644
--- a/tools/patch_sdk.dart
+++ b/tools/patch_sdk.dart
@@ -10,7 +10,7 @@
import 'dart:isolate' show RawReceivePort;
import 'dart:async';
import 'dart:math' as math;
-import 'dart:convert' show JSON;
+import 'dart:convert' show jsonEncode;
import 'package:analyzer/analyzer.dart';
import 'package:analyzer/src/generated/sdk.dart';
@@ -148,7 +148,7 @@
await _writeSync(
librariesJson.toFilePath(),
- JSON.encode({
+ jsonEncode({
mode: {"libraries": locations}
}));
diff --git a/tools/status_clean.dart b/tools/status_clean.dart
index 1c47633..1606298 100644
--- a/tools/status_clean.dart
+++ b/tools/status_clean.dart
@@ -5,7 +5,7 @@
library status_clean;
import "dart:async";
-import "dart:convert" show JSON, UTF8;
+import "dart:convert" show json, utf8;
import "dart:io";
import "testing/dart/multitest.dart";
import "testing/dart/status_file_parser.dart";
@@ -388,8 +388,8 @@
.then((HttpClientRequest request) => request.close())
.then((HttpClientResponse response) {
return response
- .transform(UTF8.decoder)
- .transform(JSON.decoder)
+ .transform(utf8.decoder)
+ .transform(json.decoder)
.first
.then((List testResults) {
var setOfActualOutcomes = new Set<Expectation>();
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart
index 17dd98b..7f9adcd 100644
--- a/tools/testing/dart/android.dart
+++ b/tools/testing/dart/android.dart
@@ -5,7 +5,7 @@
library android;
import "dart:async";
-import "dart:convert" show LineSplitter, UTF8;
+import "dart:convert" show LineSplitter, utf8;
import "dart:core";
import "dart:collection";
import "dart:io";
@@ -46,7 +46,7 @@
{String stdin, Duration timeout}) {
Future<String> getOutput(Stream<List<int>> stream) {
return stream
- .transform(UTF8.decoder)
+ .transform(utf8.decoder)
.toList()
.then((data) => data.join(""));
}
@@ -130,7 +130,7 @@
AndroidEmulator._private(this._port, this._adbDevice, this._emulatorProcess) {
Stream<String> getLines(Stream s) {
- return s.transform(UTF8.decoder).transform(new LineSplitter());
+ return s.transform(utf8.decoder).transform(new LineSplitter());
}
getLines(_emulatorProcess.stdout).listen((line) {
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index dd66be3..2489eb3 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -206,7 +206,7 @@
}
stdoutSubscription =
- process.stdout.transform(UTF8.decoder).listen((data) {
+ process.stdout.transform(utf8.decoder).listen((data) {
_addStdout(data);
}, onError: (error) {
// This should _never_ happen, but we really want this in the log
@@ -215,7 +215,7 @@
}, onDone: closeStdout);
stderrSubscription =
- process.stderr.transform(UTF8.decoder).listen((data) {
+ process.stderr.transform(utf8.decoder).listen((data) {
_addStderr(data);
}, onError: (error) {
// This should _never_ happen, but we really want this in the log
@@ -802,7 +802,7 @@
id = _idCounter++;
}
- String toJSON() => JSON.encode({'url': url, 'id': id, 'isHtmlTest': false});
+ String toJSON() => jsonEncode({'url': url, 'id': id, 'isHtmlTest': false});
}
/**
@@ -815,7 +815,7 @@
this.expectedMessages)
: super(url, doneCallback, timeout) {}
- String toJSON() => JSON.encode({
+ String toJSON() => jsonEncode({
'url': url,
'id': id,
'isHtmlTest': true,
@@ -1297,7 +1297,7 @@
errorReportingServer = server;
void errorReportingHandler(HttpRequest request) {
StringBuffer buffer = new StringBuffer();
- request.transform(UTF8.decoder).listen((data) {
+ request.transform(utf8.decoder).listen((data) {
buffer.write(data);
}, onDone: () {
String back = buffer.toString();
@@ -1389,7 +1389,7 @@
void handleReport(HttpRequest request, String browserId, int testId,
{bool isStatusUpdate}) {
StringBuffer buffer = new StringBuffer();
- request.transform(UTF8.decoder).listen((data) {
+ request.transform(utf8.decoder).listen((data) {
buffer.write(data);
}, onDone: () {
String back = buffer.toString();
@@ -1410,7 +1410,7 @@
// If an error occurs while receiving the data from the request stream,
// we don't handle it specially. We can safely ignore it, since the started
// events are not crucial.
- request.transform(UTF8.decoder).listen((data) {
+ request.transform(utf8.decoder).listen((data) {
buffer.write(data);
}, onDone: () {
String back = buffer.toString();
diff --git a/tools/testing/dart/command_output.dart b/tools/testing/dart/command_output.dart
index e342522..9700e6c 100644
--- a/tools/testing/dart/command_output.dart
+++ b/tools/testing/dart/command_output.dart
@@ -330,7 +330,7 @@
}
try {
- var events = JSON.decode(content);
+ var events = jsonDecode(content);
if (events != null) {
validate("Message must be a List", events is List);
diff --git a/tools/testing/dart/configuration.dart b/tools/testing/dart/configuration.dart
index 769e0b7..9071636 100644
--- a/tools/testing/dart/configuration.dart
+++ b/tools/testing/dart/configuration.dart
@@ -275,7 +275,7 @@
try {
var path = new Path("build/win_toolchain.json").toNativePath();
var text = new File(path).readAsStringSync();
- _windowsSdkPath = JSON.decode(text)['win_sdk'] as String;
+ _windowsSdkPath = jsonDecode(text)['win_sdk'] as String;
} on dynamic {
// Ignore errors here. If win_sdk is not found, stack trace dumping
// for timeouts won't work.
diff --git a/tools/testing/dart/html_test.dart b/tools/testing/dart/html_test.dart
index 864a6d2..5c80b01 100644
--- a/tools/testing/dart/html_test.dart
+++ b/tools/testing/dart/html_test.dart
@@ -32,7 +32,7 @@
var match = htmlAnnotation.firstMatch(contents);
if (match == null) return null;
- var annotation = JSON.decode(match[1]);
+ var annotation = jsonDecode(match[1]);
if (annotation is! Map ||
annotation['expectedMessages'] is! List ||
annotation['scripts'] is! List) {
diff --git a/tools/testing/dart/status_reporter.dart b/tools/testing/dart/status_reporter.dart
index 0f33e17..b3d0e27 100644
--- a/tools/testing/dart/status_reporter.dart
+++ b/tools/testing/dart/status_reporter.dart
@@ -164,7 +164,7 @@
var totalIndex = (result.stdout as String).indexOf('JSON:');
var report = (result.stdout as String).substring(totalIndex + 5);
- var map = JSON.decode(report) as Map<String, int>;
+ var map = jsonDecode(report) as Map<String, int>;
if (keys == null) {
keys = map.keys.toList();
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index fb56beb..b3d4c90 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -186,7 +186,7 @@
_sink = new File(TestUtils.testOutcomeFileName)
.openWrite(mode: FileMode.APPEND);
}
- _sink.write("${JSON.encode(record)}\n");
+ _sink.write("${jsonEncode(record)}\n");
}
}
@@ -252,7 +252,7 @@
void allTestsKnown() {
if (jsonOnly) {
print("JSON:");
- print(JSON.encode(summaryReport.values));
+ print(jsonEncode(summaryReport.values));
} else {
summaryReport.printReport();
}
@@ -793,7 +793,7 @@
new File(path.append(TestUtils.resultLogFileName).toNativePath());
file.createSync(recursive: true);
file.writeAsStringSync(
- JSON.encode({'configurations': configurations, 'results': results}));
+ jsonEncode({'configurations': configurations, 'results': results}));
}
}
}
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index b2d8477..c76168e 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -256,13 +256,13 @@
void _checkUtf8(List<int> data) {
try {
- UTF8.decode(data, allowMalformed: false);
+ utf8.decode(data, allowMalformed: false);
} on FormatException {
hasNonUtf8 = true;
- String malformed = UTF8.decode(data, allowMalformed: true);
+ String malformed = utf8.decode(data, allowMalformed: true);
data
..clear()
- ..addAll(UTF8.encode(malformed))
+ ..addAll(utf8.encode(malformed))
..addAll("""
*****************************************************************************
@@ -674,7 +674,7 @@
String _createArgumentsLine(List<String> arguments, int timeout) {
if (_useJson) {
- return "${JSON.encode(arguments)}\n";
+ return "${jsonEncode(arguments)}\n";
} else {
return arguments.join(' ') + '\n';
}
@@ -742,7 +742,7 @@
_process = p;
Stream<String> _stdoutStream =
- _process.stdout.transform(UTF8.decoder).transform(new LineSplitter());
+ _process.stdout.transform(utf8.decoder).transform(new LineSplitter());
_stdoutSubscription = _stdoutStream.listen((String line) {
if (line.startsWith('>>> TEST')) {
_status = line;
@@ -763,7 +763,7 @@
_stdoutSubscription.pause();
Stream<String> _stderrStream =
- _process.stderr.transform(UTF8.decoder).transform(new LineSplitter());
+ _process.stderr.transform(utf8.decoder).transform(new LineSplitter());
_stderrSubscription = _stderrStream.listen((String line) {
if (line.startsWith('>>> EOF STDERR')) {
_stderrSubscription.pause();
@@ -1274,7 +1274,7 @@
if (result.exitCode != 0) break;
}
return createCommandOutput(command, result.exitCode, result.timedOut,
- UTF8.encode('$writer'), [], stopwatch.elapsed, false);
+ utf8.encode('$writer'), [], stopwatch.elapsed, false);
}
BatchRunnerProcess _getBatchRunner(String identifier) {
diff --git a/tools/testing/dart/utils.dart b/tools/testing/dart/utils.dart
index 0e458ba..e9c9175 100644
--- a/tools/testing/dart/utils.dart
+++ b/tools/testing/dart/utils.dart
@@ -181,14 +181,14 @@
}
List<int> encodeUtf8(String string) {
- return UTF8.encode(string);
+ return utf8.encode(string);
}
// TODO(kustermann,ricow): As soon we have a debug log we should log
// invalid utf8-encoded input to the log.
// Currently invalid bytes will be replaced by a replacement character.
String decodeUtf8(List<int> bytes) {
- return UTF8.decode(bytes, allowMalformed: true);
+ return utf8.decode(bytes, allowMalformed: true);
}
/// Given a chunk of UTF-8 output, splits it into lines, normalizes carriage
@@ -217,10 +217,10 @@
return n.toString().padLeft(count, "0");
}
- var minutes = digits(2, duration.inMinutes, Duration.MINUTES_PER_HOUR);
- var seconds = digits(2, duration.inSeconds, Duration.SECONDS_PER_MINUTE);
+ var minutes = digits(2, duration.inMinutes, Duration.minutesPerHour);
+ var seconds = digits(2, duration.inSeconds, Duration.secondsPerMinute);
var millis =
- digits(6, duration.inMilliseconds, Duration.MILLISECONDS_PER_SECOND);
+ digits(6, duration.inMilliseconds, Duration.millisecondsPerSecond);
if (duration.inHours >= 1) {
return "${duration.inHours}:${minutes}:${seconds}s";
diff --git a/utils/dartanalyzer/BUILD.gn b/utils/dartanalyzer/BUILD.gn
index 67415d5..9619512 100644
--- a/utils/dartanalyzer/BUILD.gn
+++ b/utils/dartanalyzer/BUILD.gn
@@ -27,25 +27,11 @@
rebase_path("../../tests/language/first_test.dart"),
]
name = "dartanalyzer"
- cli_files = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../pkg/analyzer_cli"),
- ],
- "list lines")
- inputs = cli_files + analyzer_files
}
aot_assembly("dartanalyzer_aot_assembly") {
main_dart = "../../pkg/analyzer_cli/bin/analyzer.dart"
name = "dartanalyzer"
- cli_files = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../pkg/analyzer_cli"),
- ],
- "list lines")
- inputs = cli_files + analyzer_files
}
# This target is for Goma. It should not be used in the SDK.
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index 6ae3cd9..e9a6160 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -23,7 +23,6 @@
rebase_path("../../pkg/dev_compiler"),
"-o",
"dartdevc.js",
- "--unsafe-force-compile",
rebase_path("../../pkg/dev_compiler/bin/dartdevc.dart"),
]
@@ -31,25 +30,18 @@
":dartdevc_sdk",
]
- inputs = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../pkg/dev_compiler/bin"),
- ],
- "list lines")
- inputs += [ sdk_summary ]
+ inputs = [ sdk_summary ]
}
application_snapshot("dartdevk") {
main_dart = "../../pkg/dev_compiler/bin/dartdevk.dart"
- # TODO(vsm): Train this on real input.
training_args = [
"--dart-sdk-summary",
rebase_path(sdk_dill),
"-o",
"dartdevk.js",
- rebase_path("../../pkg/dev_compiler/test/codegen/sunflower/sunflower.dart"),
+ rebase_path("../../pkg/dev_compiler/bin/dartdevk.dart"),
]
deps = [
@@ -57,13 +49,7 @@
":dartdevc_sdk_kernel_summary",
]
- inputs = exec_script("../../tools/list_dart_files.py",
- [
- "absolute",
- rebase_path("../../pkg/dev_compiler/bin"),
- ],
- "list lines")
- inputs += [ sdk_dill ]
+ inputs = [ sdk_dill ]
}
sdk_lib_files = exec_script("../../tools/list_dart_files.py",
diff --git a/utils/dartdoc/BUILD.gn b/utils/dartdoc/BUILD.gn
index ac302a8..0ba4fe2 100644
--- a/utils/dartdoc/BUILD.gn
+++ b/utils/dartdoc/BUILD.gn
@@ -7,8 +7,4 @@
application_snapshot("dartdoc") {
main_dart = "../../third_party/pkg/dartdoc/bin/dartdoc.dart"
training_args = [ "--help" ]
- inputs = exec_script("../../tools/list_dart_files.py",
- [ "absolute",
- rebase_path("../../third_party/pkg/dartdoc") ],
- "list lines")
}
diff --git a/utils/dartfmt/BUILD.gn b/utils/dartfmt/BUILD.gn
index 7c688a3..566475f 100644
--- a/utils/dartfmt/BUILD.gn
+++ b/utils/dartfmt/BUILD.gn
@@ -7,9 +7,4 @@
application_snapshot("dartfmt") {
main_dart = "../../third_party/pkg_tested/dart_style/bin/format.dart"
training_args = [ "--help" ]
- inputs =
- exec_script("../../tools/list_dart_files.py",
- [ "absolute",
- rebase_path("../../third_party/pkg_tested/dart_style") ],
- "list lines")
}
diff --git a/utils/pub/BUILD.gn b/utils/pub/BUILD.gn
index 33cea34..b2f724c 100644
--- a/utils/pub/BUILD.gn
+++ b/utils/pub/BUILD.gn
@@ -7,12 +7,4 @@
application_snapshot("pub") {
main_dart = "../../third_party/pkg/pub/bin/pub.dart"
training_args = [ "--help" ]
- deps = [
- "../compiler:dart2js_files_stamp",
- ]
- dart2js_gen_dir =
- get_label_info("../compiler:dart2js_files_stamp", "target_gen_dir")
- inputs = [
- "$dart2js_gen_dir/dart2js_files.stamp",
- ]
}