Version 2.0.0-dev.45.0
Merge commit 'cb08bf287de1b987a627ce3a4c3495310a844d86' into dev
diff --git a/.packages b/.packages
index 2b26bb9..68a0766 100644
--- a/.packages
+++ b/.packages
@@ -17,7 +17,6 @@
barback:third_party/pkg/barback/lib
bazel_worker:third_party/pkg/bazel_worker/lib
boolean_selector:third_party/pkg/boolean_selector/lib
-browser:third_party/pkg/browser/lib
charcode:third_party/pkg/charcode/lib
charted:third_party/observatory_pub_packages/packages/charted/lib
cli_util:third_party/pkg/cli_util/lib
@@ -106,7 +105,6 @@
utf:third_party/pkg/utf/lib
vm:pkg/vm/lib
watcher:third_party/pkg/watcher/lib
-# Note: this is pointing to the observatory_pub_packages version of pkg/observe
-web_components:third_party/observatory_pub_packages/packages/web_components/lib
+web_components:third_party/pkg/web_components/lib
web_socket_channel:third_party/pkg/web_socket_channel/lib
yaml:third_party/pkg/yaml/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1006db6..3a214cd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 2.0.0-dev.45.0
+
+### Tool Changes
+
+#### Pub
+
+* Fix a bug where the version solver could crash when resolving a conflict
+ involving pre-release constraints ([issue 1856][pub#1856]).
+
+[pub#1856]: https://github.com/dart-lang/pub/issues/1856
+
## 2.0.0-dev.44.0
### Tool Changes
diff --git a/DEPS b/DEPS
index 3ab4931..fcef030 100644
--- a/DEPS
+++ b/DEPS
@@ -68,7 +68,6 @@
"crypto_tag" : "@2.0.2+1",
"csslib_tag" : "@0.14.1",
"dart2js_info_tag" : "@0.5.5+1",
- "browser_tag" : "@0.10.0+2",
# Note: updates to dart_style have to be coordinated carefully with
# the infrastructure-team so that the internal formatter in
@@ -117,7 +116,7 @@
"pool_tag": "@1.3.4",
"protobuf_tag": "@0.7.1",
"pub_rev": "@4947e0b3cb3ec77e4e8fe0d3141ce4dc60f43256",
- "pub_semver_tag": "@1.3.3",
+ "pub_semver_tag": "@1.3.4",
"quiver_tag": "@5aaa3f58c48608af5b027444d561270b53f15dbf",
"resource_rev":"@af5a5bf65511943398146cf146e466e5f0b95cb9",
"root_certificates_rev": "@16ef64be64c7dfdff2b9f4b910726e635ccc519e",
@@ -143,6 +142,7 @@
"usage_tag": "@3.3.0",
"utf_tag": "@0.9.0+4",
"watcher_tag": "@0.9.7+7",
+ "web_components_rev": "@8f57dac273412a7172c8ade6f361b407e2e4ed02",
"web_socket_channel_tag": "@1.0.7",
"WebCore_rev": "@fb11e887f77919450e497344da570d780e078bc8",
"yaml_tag": "@2.1.13",
@@ -208,9 +208,6 @@
Var("dart_root") + "/third_party/pkg/boolean_selector":
Var("dart_git") + "boolean_selector.git" +
Var("boolean_selector_tag"),
- Var("dart_root") + "/third_party/pkg/browser":
- Var("dart_git") + "browser.git" +
- Var("browser_tag"),
Var("dart_root") + "/third_party/pkg/charcode":
Var("dart_git") + "charcode.git" + Var("charcode_tag"),
Var("dart_root") + "/third_party/pkg/cli_util":
@@ -353,6 +350,9 @@
Var("dart_git") + "utf.git" + Var("utf_tag"),
Var("dart_root") + "/third_party/pkg/watcher":
Var("dart_git") + "watcher.git" + Var("watcher_tag"),
+ Var("dart_root") + "/third_party/pkg/web_components":
+ Var("dart_git") + "web-components.git" +
+ Var("web_components_rev"),
Var("dart_root") + "/third_party/pkg/web_socket_channel":
Var("dart_git") + "web_socket_channel.git" +
Var("web_socket_channel_tag"),
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
index 593de24..8239f37 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -68,13 +68,6 @@
}
@override
- visitConstructorElement(ConstructorElement element) {
- if (element.context.analysisOptions.previewDart2) {
- _addSuggestion(element);
- }
- }
-
- @override
visitFieldElement(FieldElement element) {
if (element.isStatic) {
_addSuggestion(element);
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 15b3600..d7b5b78 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -1676,9 +1676,7 @@
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addReplacement(range.node(widgetExpr), (DartEditBuilder builder) {
- if (!driver.analysisOptions.previewDart2) {
- builder.write('new ');
- }
+ builder.write('new ');
if (parentClassElement == null) {
builder.addSimpleLinkedEdit('WIDGET', 'widget');
} else {
@@ -1757,9 +1755,7 @@
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addReplacement(selectedRange, (DartEditBuilder builder) {
- if (!driver.analysisOptions.previewDart2) {
- builder.write('new ');
- }
+ builder.write('new ');
builder.writeType(parentClassElement.type);
builder.write('(');
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index d4029b3..4a2270c 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -732,17 +732,21 @@
<String>["1+fooConst", "1-fooNotConst", "1-bar"],
failingTests: '1');
- buildTests('testCompletion_annotation_type', '''
+ buildTests(
+ 'testCompletion_annotation_type',
+ '''
class AAA {
const AAA({int a, int b});
const AAA.nnn(int c, int d);
}
@AAA!1
main() {
-}''', <String>[
- "1+AAA" /*":" + ProposalKind.CONSTRUCTOR*/,
- "1+AAA.nnn" /*":" + ProposalKind.CONSTRUCTOR*/
- ]);
+}''',
+ <String>[
+ "1+AAA" /*":" + ProposalKind.CONSTRUCTOR*/,
+ "1+AAA.nnn" /*":" + ProposalKind.CONSTRUCTOR*/
+ ],
+ failingTests: '1');
buildTests('testCompletion_annotation_type_inClass_withoutMember', '''
class AAA {
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 07c23fa..078a2bb 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -619,11 +619,8 @@
assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
elementKind: ElementKind.CLASS);
- // Both constructors - default and named, are suggested.
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
- elementKind: ElementKind.CONSTRUCTOR);
- assertHasResult(CompletionSuggestionKind.INVOCATION, 'A.named',
- elementKind: ElementKind.CONSTRUCTOR);
+ // No constructors suggested.
+ assertNoResult('A.named');
}
test_local_named_constructor() {
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 41feab8..a72473f 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -2449,12 +2449,12 @@
await computeSuggestions();
assertSuggestClass('A');
- assertSuggestConstructor('A.a1');
- assertSuggestConstructor('A.a2');
+ assertNotSuggested('A.a1');
+ assertNotSuggested('A.a2');
assertSuggestClass('B');
- assertSuggestConstructor('B.b1');
- assertSuggestConstructor('B.b2');
+ assertNotSuggested('B.b1');
+ assertNotSuggested('B.b2');
}
test_ImportDirective_dart() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
index 2987710..8aebb55 100644
--- a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -114,8 +114,8 @@
''');
await computeSuggestions();
- assertSuggestConstructor('foo', elementName: 'foo');
- assertSuggestConstructor('bar', elementName: 'bar');
+ assertNotSuggested('foo');
+ assertNotSuggested('bar');
}
test_keyword() async {
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 7567e4b..cb974b3 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -3541,7 +3541,7 @@
import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
- return /*caret*/Container();
+ return /*caret*/new Container();
}
}
''');
@@ -3550,7 +3550,7 @@
import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
- return /*caret*/Center(child: Container());
+ return /*caret*/new Center(child: new Container());
}
}
''');
@@ -3677,7 +3677,7 @@
main() {
return Container(
- child: /*caret*/Text('aaa'),
+ child: /*caret*/new Text('aaa'),
);
}
''');
@@ -3687,9 +3687,9 @@
main() {
return Container(
- child: /*caret*/Column(
+ child: /*caret*/new Column(
children: <Widget>[
- Text('aaa'),
+ new Text('aaa'),
],
),
);
diff --git a/pkg/analyzer/lib/dart/analysis/analysis_context.dart b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
index a075b09..e24bfc8 100644
--- a/pkg/analyzer/lib/dart/analysis/analysis_context.dart
+++ b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
@@ -1,7 +1,4 @@
-// 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/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
@@ -10,10 +7,10 @@
* analyzed.
*
* The body of code is represented as a collection of files and directories, as
- * defined by the list of [includedPaths]. If the list of included paths
+ * defined by the list of included paths. If the list of included paths
* contains one or more directories, then zero or more files or directories
* within the included directories can be excluded from analysis, as defined by
- * the list of [excludedPaths].
+ * the list of excluded paths.
*
* Clients may not extend, implement or mix-in this class.
*/
@@ -24,6 +21,11 @@
AnalysisOptions get analysisOptions;
/**
+ * Return the context root from which this context was created.
+ */
+ ContextRoot get contextRoot;
+
+ /**
* Return the currently active analysis session.
*/
AnalysisSession get currentSession;
@@ -31,7 +33,10 @@
/**
* A list of the absolute, normalized paths of files and directories that
* will not be analyzed.
+ *
+ * Deprecated: Use `contextRoot.excludedPaths`.
*/
+ @deprecated
List<String> get excludedPaths;
/**
@@ -41,7 +46,10 @@
* the list represents a directory, then all of the files contained in that
* directory, either directly or indirectly, and that are not explicitly
* excluded by the list of [excludedPaths] will be analyzed.
+ *
+ * Deprecated: Use `contextRoot.includedPaths`.
*/
+ @deprecated
List<String> get includedPaths;
/**
@@ -49,7 +57,10 @@
* contained in this context. These are all of the files that are included
* directly or indirectly by one or more of the [includedPaths] and that are
* not excluded by any of the [excludedPaths].
+ *
+ * Deprecated: Use `contextRoot.analyzedFiles`.
*/
+ @deprecated
Iterable<String> analyzedFiles();
/**
@@ -58,6 +69,9 @@
* either the same as or contained in one of the [includedPaths] and, if it is
* is contained in one of the [includedPaths], is not the same as or contained
* in one of the [excludedPaths].
+ *
+ * Deprecated: Use `contextRoot.isAnalyzed`.
*/
+ @deprecated
bool isAnalyzed(String path);
}
diff --git a/pkg/analyzer/lib/dart/analysis/context_root.dart b/pkg/analyzer/lib/dart/analysis/context_root.dart
index f710dbd..a8998fe 100644
--- a/pkg/analyzer/lib/dart/analysis/context_root.dart
+++ b/pkg/analyzer/lib/dart/analysis/context_root.dart
@@ -51,7 +51,32 @@
File get packagesFile;
/**
+ * The resource provider used to access the file system.
+ */
+ ResourceProvider get resourceProvider;
+
+ /**
* The root directory containing the files to be analyzed.
*/
Folder get root;
+
+ /**
+ * Return the absolute, normalized paths of all of the files that are
+ * contained in this context. These are all of the files that are included
+ * directly or indirectly by one or more of the [includedPaths] and that are
+ * not excluded by any of the [excludedPaths].
+ *
+ * Note that the list is not filtered based on the file suffix, so non-Dart
+ * files can be returned.
+ */
+ Iterable<String> analyzedFiles();
+
+ /**
+ * Return `true` if the file or directory with the given [path] will be
+ * analyzed in this context. A file (or directory) will be analyzed if it is
+ * either the same as or contained in one of the [includedPaths] and, if it is
+ * contained in one of the [includedPaths], is not the same as or contained
+ * in one of the [excludedPaths].
+ */
+ bool isAnalyzed(String path);
}
diff --git a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
index 034c337..00b8201 100644
--- a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
+++ b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
@@ -41,7 +41,7 @@
*/
const AnalysisOptionsErrorCode(String name, String message,
{String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
@@ -140,7 +140,7 @@
*/
const AnalysisOptionsWarningCode(String name, String message,
{String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
@@ -178,7 +178,7 @@
*/
const AnalysisOptionsHintCode(String name, String message,
{String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index e9fbaa9..2f3fc05 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -109,9 +109,7 @@
new old.ContextRoot(root.root.path, root.excludedPaths.toList());
AnalysisDriver driver = builder.buildDriver(contextRoot);
DriverBasedAnalysisContext context =
- new DriverBasedAnalysisContext(resourceProvider, driver);
- context.includedPaths = root.includedPaths.toList();
- context.excludedPaths = root.excludedPaths.toList();
+ new DriverBasedAnalysisContext(resourceProvider, root, driver);
contextList.add(context);
}
return contextList;
@@ -173,7 +171,7 @@
}
List<ContextRoot> roots = <ContextRoot>[];
for (Folder folder in includedFolders) {
- ContextRootImpl root = new ContextRootImpl(folder);
+ ContextRootImpl root = new ContextRootImpl(resourceProvider, folder);
root.packagesFile = defaultPackagesFile ?? _findPackagesFile(folder);
root.optionsFile = defaultOptionsFile ?? _findOptionsFile(folder);
root.included.add(folder);
@@ -185,7 +183,7 @@
for (File file in includedFiles) {
Folder parent = file.parent;
ContextRoot root = rootMap.putIfAbsent(parent, () {
- ContextRootImpl root = new ContextRootImpl(parent);
+ ContextRootImpl root = new ContextRootImpl(resourceProvider, parent);
root.packagesFile = defaultPackagesFile ?? _findPackagesFile(parent);
root.optionsFile = defaultOptionsFile ?? _findOptionsFile(parent);
roots.add(root);
@@ -245,7 +243,7 @@
if (packagesFile != null) {
localPackagesFile = packagesFile;
}
- ContextRootImpl root = new ContextRootImpl(folder);
+ ContextRootImpl root = new ContextRootImpl(resourceProvider, folder);
root.packagesFile = localPackagesFile ?? containingRoot.packagesFile;
root.optionsFile = localOptionsFile ?? containingRoot.optionsFile;
root.included.add(folder);
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_root.dart b/pkg/analyzer/lib/src/dart/analysis/context_root.dart
index 607c9d2..0d3a082 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_root.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_root.dart
@@ -4,12 +4,16 @@
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:path/path.dart';
/**
* An implementation of a context root.
*/
class ContextRootImpl implements ContextRoot {
@override
+ final ResourceProvider resourceProvider;
+
+ @override
final Folder root;
@override
@@ -27,7 +31,7 @@
/**
* Initialize a newly created context root.
*/
- ContextRootImpl(this.root);
+ ContextRootImpl(this.resourceProvider, this.root);
@override
Iterable<String> get excludedPaths =>
@@ -44,4 +48,90 @@
bool operator ==(Object other) {
return other is ContextRoot && root.path == other.root.path;
}
+
+ @override
+ Iterable<String> analyzedFiles() sync* {
+ for (String path in includedPaths) {
+ if (!_isExcluded(path)) {
+ Resource resource = resourceProvider.getResource(path);
+ if (resource is File) {
+ yield path;
+ } else if (resource is Folder) {
+ yield* _includedFilesInFolder(resource);
+ } else {
+ Type type = resource.runtimeType;
+ throw new StateError('Unknown resource at path "$path" ($type)');
+ }
+ }
+ }
+ }
+
+ @override
+ bool isAnalyzed(String path) {
+ return _isIncluded(path) && !_isExcluded(path);
+ }
+
+ /**
+ * Return the absolute paths of all of the files that are included in the
+ * given [folder].
+ */
+ Iterable<String> _includedFilesInFolder(Folder folder) sync* {
+ for (Resource resource in folder.getChildren()) {
+ String path = resource.path;
+ if (!_isExcluded(path)) {
+ if (resource is File) {
+ yield path;
+ } else if (resource is Folder) {
+ yield* _includedFilesInFolder(resource);
+ } else {
+ Type type = resource.runtimeType;
+ throw new StateError('Unknown resource at path "$path" ($type)');
+ }
+ }
+ }
+ }
+
+ /**
+ * Return `true` if the given [path] is either the same as or inside of one of
+ * the [excludedPaths].
+ */
+ bool _isExcluded(String path) {
+ Context context = resourceProvider.pathContext;
+ String name = context.basename(path);
+ if (name.startsWith('.') ||
+ (name == 'packages' && resourceProvider.getResource(path) is Folder)) {
+ return true;
+ }
+ for (String excludedPath in excludedPaths) {
+ if (context.isAbsolute(excludedPath)) {
+ if (context.isWithin(excludedPath, path)) {
+ return true;
+ }
+ } else {
+ // The documentation claims that [excludedPaths] only contains absolute
+ // paths, so we shouldn't be able to reach this point.
+ for (String includedPath in includedPaths) {
+ if (context.isWithin(
+ context.join(includedPath, excludedPath), path)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return `true` if the given [path] is either the same as or inside of one of
+ * the [includedPaths].
+ */
+ bool _isIncluded(String path) {
+ Context context = resourceProvider.pathContext;
+ for (String includedPath in includedPaths) {
+ if (context.isWithin(includedPath, path)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index c3e188f..b596dca 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -95,7 +95,7 @@
/**
* The version of data format, should be incremented on every format change.
*/
- static const int DATA_VERSION = 54;
+ static const int DATA_VERSION = 55;
/**
* The number of exception contexts allowed to write. Once this field is
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
index 558b2a1..f96d909 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
@@ -3,11 +3,11 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/analysis_context.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' hide AnalysisResult;
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptions;
-import 'package:path/src/context.dart';
/**
* An analysis context whose implementation is based on an analysis driver.
@@ -18,22 +18,20 @@
*/
final ResourceProvider resourceProvider;
+ @override
+ final ContextRoot contextRoot;
+
/**
* The driver on which this context is based.
*/
final AnalysisDriver driver;
- @override
- List<String> includedPaths;
-
- @override
- List<String> excludedPaths;
-
/**
* Initialize a newly created context that uses the given [resourceProvider]
* to access the file system and that is based on the given analysis [driver].
*/
- DriverBasedAnalysisContext(this.resourceProvider, this.driver);
+ DriverBasedAnalysisContext(
+ this.resourceProvider, this.contextRoot, this.driver);
@override
AnalysisOptions get analysisOptions => driver.analysisOptions;
@@ -41,89 +39,23 @@
@override
AnalysisSession get currentSession => driver.currentSession;
+ @deprecated
@override
- Iterable<String> analyzedFiles() sync* {
- for (String path in includedPaths) {
- if (!_isExcluded(path)) {
- Resource resource = resourceProvider.getResource(path);
- if (resource is File) {
- yield path;
- } else if (resource is Folder) {
- yield* _includedFilesInFolder(resource);
- } else {
- Type type = resource.runtimeType;
- throw new StateError('Unknown resource at path "$path" ($type)');
- }
- }
- }
+ List<String> get excludedPaths => contextRoot.excludedPaths.toList();
+
+ @deprecated
+ @override
+ List<String> get includedPaths => contextRoot.includedPaths.toList();
+
+ @deprecated
+ @override
+ Iterable<String> analyzedFiles() {
+ return contextRoot.analyzedFiles();
}
+ @deprecated
@override
bool isAnalyzed(String path) {
- return _isIncluded(path) && !_isExcluded(path);
- }
-
- /**
- * Return the absolute paths of all of the files that are included in the
- * given [folder].
- */
- Iterable<String> _includedFilesInFolder(Folder folder) sync* {
- for (Resource resource in folder.getChildren()) {
- String path = resource.path;
- if (!_isExcluded(path)) {
- if (resource is File) {
- yield path;
- } else if (resource is Folder) {
- yield* _includedFilesInFolder(resource);
- } else {
- Type type = resource.runtimeType;
- throw new StateError('Unknown resource at path "$path" ($type)');
- }
- }
- }
- }
-
- /**
- * Return `true` if the given [path] is either the same as or inside of one of
- * the [excludedPaths].
- */
- bool _isExcluded(String path) {
- Context context = resourceProvider.pathContext;
- String name = context.basename(path);
- if (name.startsWith('.') ||
- (name == 'packages' && resourceProvider.getResource(path) is Folder)) {
- return true;
- }
- for (String excludedPath in excludedPaths) {
- if (context.isAbsolute(excludedPath)) {
- if (context.isWithin(excludedPath, path)) {
- return true;
- }
- } else {
- // The documentation claims that [excludedPaths] only contains absolute
- // paths, so we shouldn't be able to reach this point.
- for (String includedPath in includedPaths) {
- if (context.isWithin(
- context.join(includedPath, excludedPath), path)) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- /**
- * Return `true` if the given [path] is either the same as or inside of one of
- * the [includedPaths].
- */
- bool _isIncluded(String path) {
- Context context = resourceProvider.pathContext;
- for (String includedPath in includedPaths) {
- if (context.isWithin(includedPath, path)) {
- return true;
- }
- }
- return false;
+ return contextRoot.isAnalyzed(path);
}
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index bc02210..93b51a3 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -534,7 +534,6 @@
ErrorReporter libraryErrorReporter = _getErrorReporter(_library);
LibraryIdentifier libraryNameNode = null;
- bool hasPartDirective = false;
var seenPartSources = new Set<Source>();
var directivesToResolve = <Directive>[];
int partIndex = 0;
@@ -571,7 +570,6 @@
}
}
} else if (directive is PartDirective) {
- hasPartDirective = true;
StringLiteral partUri = directive.uri;
FileState partFile = _library.partedFiles[partIndex];
@@ -632,12 +630,8 @@
}
}
- if (hasPartDirective &&
- libraryNameNode == null &&
- !_context.analysisOptions.enableUriInPartOf) {
- libraryErrorReporter.reportErrorForOffset(
- ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART, 0, 0);
- }
+ // TODO(brianwilkerson) Report the error
+ // ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART
//
// Resolve the relevant directives to the library element.
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 188ac1d..8fa0d0b 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -203,7 +203,7 @@
@override
MethodElement lookUpConcreteMethod(
String methodName, LibraryElement library) =>
- _first(_implementationsOfMethod(methodName).where(
+ _first(getImplementationsOfMethod(this, methodName).where(
(MethodElement method) =>
!method.isAbstract && method.isAccessibleIn(library)));
@@ -225,7 +225,7 @@
@override
MethodElement lookUpInheritedConcreteMethod(
String methodName, LibraryElement library) =>
- _first(_implementationsOfMethod(methodName).where(
+ _first(getImplementationsOfMethod(this, methodName).where(
(MethodElement method) =>
!method.isAbstract &&
method.isAccessibleIn(library) &&
@@ -243,15 +243,14 @@
@override
MethodElement lookUpInheritedMethod(
String methodName, LibraryElement library) =>
- _first(_implementationsOfMethod(methodName).where(
+ _first(getImplementationsOfMethod(this, methodName).where(
(MethodElement method) =>
method.isAccessibleIn(library) &&
method.enclosingElement != this));
@override
MethodElement lookUpMethod(String methodName, LibraryElement library) =>
- _first(_implementationsOfMethod(methodName)
- .where((MethodElement method) => method.isAccessibleIn(library)));
+ lookUpMethodInClass(this, methodName, library);
@override
PropertyAccessorElement lookUpSetter(
@@ -267,17 +266,6 @@
}
/**
- * Return the first element from the given [iterable], or `null` if the
- * iterable is empty.
- */
- E _first<E>(Iterable<E> iterable) {
- if (iterable.isEmpty) {
- return null;
- }
- return iterable.first;
- }
-
- /**
* Return an iterable containing all of the implementations of a getter with
* the given [getterName] that are defined in this class any any superclass of
* this class (but not in interfaces).
@@ -310,37 +298,6 @@
}
/**
- * Return an iterable containing all of the implementations of a method with
- * the given [methodName] that are defined in this class any any superclass of
- * this class (but not in interfaces).
- *
- * The methods that are returned are not filtered in any way. In particular,
- * they can include methods that are not visible in some context. Clients must
- * perform any necessary filtering.
- *
- * The methods are returned based on the depth of their defining class; if
- * this class contains a definition of the method it will occur first, if
- * Object contains a definition of the method it will occur last.
- */
- Iterable<MethodElement> _implementationsOfMethod(String methodName) sync* {
- ClassElement classElement = this;
- HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
- while (classElement != null && visitedClasses.add(classElement)) {
- MethodElement method = classElement.getMethod(methodName);
- if (method != null) {
- yield method;
- }
- for (InterfaceType mixin in classElement.mixins.reversed) {
- method = mixin.element?.getMethod(methodName);
- if (method != null) {
- yield method;
- }
- }
- classElement = classElement.supertype?.element;
- }
- }
-
- /**
* Return an iterable containing all of the implementations of a setter with
* the given [setterName] that are defined in this class any any superclass of
* this class (but not in interfaces).
@@ -384,6 +341,37 @@
return classElement as AbstractClassElementImpl;
}
+ /**
+ * Return an iterable containing all of the implementations of a method with
+ * the given [methodName] that are defined in this class any any superclass of
+ * this class (but not in interfaces).
+ *
+ * The methods that are returned are not filtered in any way. In particular,
+ * they can include methods that are not visible in some context. Clients must
+ * perform any necessary filtering.
+ *
+ * The methods are returned based on the depth of their defining class; if
+ * this class contains a definition of the method it will occur first, if
+ * Object contains a definition of the method it will occur last.
+ */
+ static Iterable<MethodElement> getImplementationsOfMethod(
+ ClassElement classElement, String methodName) sync* {
+ HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+ while (classElement != null && visitedClasses.add(classElement)) {
+ MethodElement method = classElement.getMethod(methodName);
+ if (method != null) {
+ yield method;
+ }
+ for (InterfaceType mixin in classElement.mixins.reversed) {
+ method = mixin.element?.getMethod(methodName);
+ if (method != null) {
+ yield method;
+ }
+ }
+ classElement = classElement.supertype?.element;
+ }
+ }
+
static PropertyAccessorElement getSetterFromAccessors(
String setterName, List<PropertyAccessorElement> accessors) {
// TODO (jwren) revisit- should we append '=' here or require clients to
@@ -399,6 +387,23 @@
}
return null;
}
+
+ static MethodElement lookUpMethodInClass(
+ ClassElement classElement, String methodName, LibraryElement library) {
+ return _first(getImplementationsOfMethod(classElement, methodName)
+ .where((MethodElement method) => method.isAccessibleIn(library)));
+ }
+
+ /**
+ * Return the first element from the given [iterable], or `null` if the
+ * iterable is empty.
+ */
+ static E _first<E>(Iterable<E> iterable) {
+ if (iterable.isEmpty) {
+ return null;
+ }
+ return iterable.first;
+ }
}
/**
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 5b1ae8c..8d2ab0f 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -703,7 +703,7 @@
* given [correction] template.
*/
const HintCode(String name, String message, {String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorType.HINT.severity;
diff --git a/pkg/analyzer/lib/src/dart/error/lint_codes.dart b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
index 9fc7d8f..11da461e0 100644
--- a/pkg/analyzer/lib/src/dart/error/lint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
@@ -15,7 +15,7 @@
*/
class LintCode extends ErrorCode {
const LintCode(String name, String message, {String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 87d69d3..f794006 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -970,7 +970,7 @@
* given [correction] template.
*/
const ParserErrorCode(String name, String message, {String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analyzer/lib/src/dart/error/todo_codes.dart b/pkg/analyzer/lib/src/dart/error/todo_codes.dart
index 3980f57..e214e9d 100644
--- a/pkg/analyzer/lib/src/dart/error/todo_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/todo_codes.dart
@@ -35,7 +35,7 @@
/**
* Initialize a newly created error code to have the given [name].
*/
- const TodoCode(String name) : super(name, "{0}");
+ const TodoCode(String name) : super.temporary(name, "{0}");
@override
ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 77853fc..9e84278 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -153,7 +153,7 @@
*/
const CheckedModeCompileTimeErrorCode(String name, String message,
{String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity =>
@@ -2582,7 +2582,7 @@
*/
const CompileTimeErrorCode(String name, String message,
{String correction, bool isUnresolvedIdentifier: false})
- : super(name, message,
+ : super.temporary(name, message,
correction: correction,
isUnresolvedIdentifier: isUnresolvedIdentifier);
@@ -3241,7 +3241,7 @@
*/
const StaticTypeWarningCode(String name, String message,
{String correction, bool isUnresolvedIdentifier: false})
- : super(name, message,
+ : super.temporary(name, message,
correction: correction,
isUnresolvedIdentifier: isUnresolvedIdentifier);
@@ -4731,7 +4731,7 @@
{String correction,
this.isStrongModeError = true,
bool isUnresolvedIdentifier: false})
- : super(name, message,
+ : super.temporary(name, message,
correction: correction,
isUnresolvedIdentifier: isUnresolvedIdentifier);
@@ -5053,7 +5053,7 @@
const StrongModeCode(ErrorType type, String name, String message,
{String correction})
: type = type,
- super('STRONG_MODE_$name', message, correction: correction);
+ super.temporary('STRONG_MODE_$name', message, correction: correction);
@override
ErrorSeverity get errorSeverity => type.severity;
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 408b911..1b56f66 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -1058,19 +1058,8 @@
exitLocalScope();
exitContinueTarget();
exitBreakTarget();
- if (variableOrDeclaration is SimpleIdentifier) {
- push(ast.forEachStatementWithReference(
- awaitToken,
- forToken,
- leftParenthesis,
- variableOrDeclaration,
- inKeyword,
- iterator,
- leftParenthesis?.endGroup,
- body));
- } else {
- var statement = variableOrDeclaration as VariableDeclarationStatement;
- VariableDeclarationList variableList = statement.variables;
+ if (variableOrDeclaration is VariableDeclarationStatement) {
+ VariableDeclarationList variableList = variableOrDeclaration.variables;
push(ast.forEachStatementWithDeclaration(
awaitToken,
forToken,
@@ -1080,7 +1069,27 @@
variableList.metadata,
variableList.keyword,
variableList.type,
- variableList.variables.single.name),
+ variableList.variables.first.name),
+ inKeyword,
+ iterator,
+ leftParenthesis?.endGroup,
+ body));
+ } else {
+ if (variableOrDeclaration is! SimpleIdentifier) {
+ // Parser has already reported the error.
+ if (!leftParenthesis.next.isIdentifier) {
+ parser.rewriter.insertTokenAfter(
+ leftParenthesis,
+ new SyntheticStringToken(
+ TokenType.IDENTIFIER, '', leftParenthesis.next.charOffset));
+ }
+ variableOrDeclaration = ast.simpleIdentifier(leftParenthesis.next);
+ }
+ push(ast.forEachStatementWithReference(
+ awaitToken,
+ forToken,
+ leftParenthesis,
+ variableOrDeclaration,
inKeyword,
iterator,
leftParenthesis?.endGroup,
@@ -2093,17 +2102,22 @@
@override
void endNamedFunctionExpression(Token endToken) {
- // TODO(scheglov): The logEvent() invocation is commented because it
- // spams to the console. We already know that these test fail, uncomment
- // when you are working on fixing them.
-// logEvent("NamedFunctionExpression");
- unhandled("NamedFunctionExpression", "$runtimeType", -1, uri);
+ debugEvent("NamedFunctionExpression");
+ FunctionBody body = pop();
+ if (isFullAst) {
+ pop(); // constructor initializers
+ pop(); // separator before constructor initializers
+ }
+ FormalParameterList parameters = pop();
+ pop(); // name
+ pop(); // returnType
+ TypeParameterList typeParameters = pop();
+ push(ast.functionExpression(typeParameters, parameters, body));
}
@override
void endLocalFunctionDeclaration(Token token) {
debugEvent("LocalFunctionDeclaration");
-
FunctionBody body = pop();
if (isFullAst) {
pop(); // constructor initializers
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 8fe08ec..836f94c 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -384,6 +384,10 @@
errorReporter?.reportErrorForOffset(
ScannerErrorCode.MISSING_DIGIT, offset, length);
return;
+ case "MISSING_ENUM_BODY":
+ errorReporter?.reportErrorForOffset(
+ ParserErrorCode.MISSING_ENUM_BODY, offset, length);
+ return;
case "MISSING_FUNCTION_BODY":
errorReporter?.reportErrorForOffset(
ParserErrorCode.MISSING_FUNCTION_BODY, offset, length);
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index ddb19d7..ad983e9 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1236,6 +1236,7 @@
/**
* Return `true` to enable the use of URIs in part-of directives.
*/
+ @deprecated
bool get enableUriInPartOf;
/**
@@ -1419,9 +1420,6 @@
List<String> _excludePatterns;
@override
- bool enableUriInPartOf = true;
-
- @override
bool generateImplicitErrors = true;
@override
@@ -1605,6 +1603,13 @@
@deprecated
void set enableInitializingFormalAccess(bool enable) {}
+ @deprecated
+ @override
+ bool get enableUriInPartOf => true;
+
+ @deprecated
+ void set enableUriInPartOf(bool enable) {}
+
@override
List<ErrorProcessor> get errorProcessors =>
_errorProcessors ??= const <ErrorProcessor>[];
@@ -1648,7 +1653,6 @@
buffer.addBool(declarationCasts);
buffer.addBool(enableLazyAssignmentOperators);
buffer.addBool(enableSuperMixins);
- buffer.addBool(enableUriInPartOf);
buffer.addBool(implicitCasts);
buffer.addBool(implicitDynamic);
buffer.addBool(strongMode);
@@ -1696,7 +1700,6 @@
enableLazyAssignmentOperators = false;
enableSuperMixins = false;
enableTiming = false;
- enableUriInPartOf = true;
_errorProcessors = null;
_excludePatterns = null;
generateImplicitErrors = true;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index fe9f7fe..b7b109d 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -216,12 +216,6 @@
bool _enableOptionalNewAndConst = false;
/**
- * A flag indicating whether the parser is to allow URI's in part-of
- * directives.
- */
- bool _enableUriInPartOf = true;
-
- /**
* A flag indicating whether parser is to parse function bodies.
*/
bool _parseFunctionBodies = true;
@@ -351,15 +345,15 @@
/**
* Return `true` if the parser is to allow URI's in part-of directives.
*/
- bool get enableUriInPartOf => _enableUriInPartOf;
+ @deprecated
+ bool get enableUriInPartOf => true;
/**
* Set whether the parser is to allow URI's in part-of directives to the given
* [enable] flag.
*/
- void set enableUriInPartOf(bool enable) {
- _enableUriInPartOf = enable;
- }
+ @deprecated
+ void set enableUriInPartOf(bool enable) {}
/**
* Return `true` if the current token is the first token of a return type that
@@ -7444,7 +7438,7 @@
Directive _parsePartOfDirective(CommentAndMetadata commentAndMetadata) {
Token partKeyword = getAndAdvance();
Token ofKeyword = getAndAdvance();
- if (enableUriInPartOf && _matches(TokenType.STRING)) {
+ if (_matches(TokenType.STRING)) {
StringLiteral libraryUri = _parseUri();
Token semicolon = _expect(TokenType.SEMICOLON);
return astFactory.partOfDirective(
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 824a7ee..529103f 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -4880,7 +4880,7 @@
* given [correction] template.
*/
const ResolverErrorCode(String name, String message, {String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => type.severity;
diff --git a/pkg/analyzer/lib/src/html/error/html_codes.dart b/pkg/analyzer/lib/src/html/error/html_codes.dart
index 9644fb1..f62a756 100644
--- a/pkg/analyzer/lib/src/html/error/html_codes.dart
+++ b/pkg/analyzer/lib/src/html/error/html_codes.dart
@@ -29,7 +29,7 @@
* given [correction] template.
*/
const HtmlErrorCode(String name, String message, {String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
@@ -72,7 +72,7 @@
* given [correction] template.
*/
const HtmlWarningCode(String name, String message, {String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
index 133d6dd..d4d4c2d 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
@@ -88,7 +88,7 @@
* and [correction].
*/
const PubspecWarningCode(String name, String message, {String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index dd3ff8a..7554f34 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -527,6 +527,12 @@
void link(CompilationUnitElementInBuildUnit compilationUnit);
@override
+ MethodElement lookUpMethod(String methodName, LibraryElement library) {
+ return AbstractClassElementImpl.lookUpMethodInClass(
+ this, methodName, library);
+ }
+
+ @override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 3fed1de..f2e8703 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -1507,7 +1507,6 @@
//
LibraryIdentifier libraryNameNode = null;
String partsLibraryName = _UNKNOWN_LIBRARY_NAME;
- bool hasPartDirective = false;
Set<Source> seenPartSources = new Set<Source>();
FunctionElement entryPoint =
_findEntryPoint(definingCompilationUnitElement);
@@ -1524,7 +1523,6 @@
} else if (directive is PartDirective) {
StringLiteral partUri = directive.uri;
Source partSource = directive.uriSource;
- hasPartDirective = true;
CompilationUnit partUnit = partUnitMap[partSource];
if (partUnit != null) {
CompilationUnitElementImpl partElement = partUnit.element;
@@ -1594,12 +1592,8 @@
}
}
}
- if (hasPartDirective &&
- libraryNameNode == null &&
- !context.analysisOptions.enableUriInPartOf) {
- errors.add(new AnalysisError(librarySource, 0, 0,
- ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART));
- }
+ // TODO(brianwilkerson) Report the error
+ // ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART
//
// Create and populate the library element.
//
@@ -3769,7 +3763,6 @@
options.analyzeFunctionBodiesPredicate(_source);
parser.parseGenericMethodComments = options.strongMode;
parser.enableOptionalNewAndConst = options.previewDart2;
- parser.enableUriInPartOf = options.enableUriInPartOf;
CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
unit.lineInfo = lineInfo;
diff --git a/pkg/analyzer/lib/src/task/yaml.dart b/pkg/analyzer/lib/src/task/yaml.dart
index acbb550..4024039 100644
--- a/pkg/analyzer/lib/src/task/yaml.dart
+++ b/pkg/analyzer/lib/src/task/yaml.dart
@@ -145,7 +145,7 @@
* given [correction] template.
*/
const YamlErrorCode(String name, String message, {String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index f2196eb..59dd90c 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -44,7 +44,6 @@
modifiedOptions.enableLazyAssignmentOperators = true;
modifiedOptions.enableSuperMixins = true;
modifiedOptions.enableTiming = true;
- modifiedOptions.enableUriInPartOf = true;
modifiedOptions.errorProcessors = [null];
modifiedOptions.excludePatterns = ['a'];
modifiedOptions.generateImplicitErrors = false;
@@ -69,7 +68,6 @@
defaultOptions.enableLazyAssignmentOperators);
expect(modifiedOptions.enableSuperMixins, defaultOptions.enableSuperMixins);
expect(modifiedOptions.enableTiming, defaultOptions.enableTiming);
- expect(modifiedOptions.enableUriInPartOf, defaultOptions.enableUriInPartOf);
expect(modifiedOptions.errorProcessors, defaultOptions.errorProcessors);
expect(modifiedOptions.excludePatterns, defaultOptions.excludePatterns);
expect(modifiedOptions.generateImplicitErrors,
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index fe720a6..f9ad390 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -472,38 +472,6 @@
@override
@failingTest
- void test_missingAssignableSelector_identifiersAssigned() {
- // TODO(brianwilkerson) Does not recover.
- // Expected: true
- // Actual: <false>
- //
- // package:test expect
- // test/generated/parser_fasta_test.dart 3439:5 ParserProxy._run
- super.test_missingAssignableSelector_identifiersAssigned();
- }
-
- @override
- @failingTest
- void test_missingAssignableSelector_superPropertyAccessAssigned() {
- // TODO(brianwilkerson) Does not recover.
- // Expected: true
- // Actual: <false>
- //
- // package:test expect
- // test/generated/parser_fasta_test.dart 3488:5 ParserProxy._run
- super.test_missingAssignableSelector_superPropertyAccessAssigned();
- }
-
- @override
- @failingTest
- void test_missingEnumBody() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.MISSING_ENUM_BODY, found 0
- super.test_missingEnumBody();
- }
-
- @override
- @failingTest
void test_missingExpressionInThrow() {
// TODO(brianwilkerson) Does not recover.
// type 'RethrowExpressionImpl' is not a subtype of type 'ThrowExpression' of 'expression' where
@@ -516,19 +484,6 @@
@override
@failingTest
- void test_missingFunctionBody_invalid() {
- // TODO(brianwilkerson) Does not recover.
- // Expected: an object with length of <1>
- // Actual: <Instance of 'Stack'>
- // Which: has length of <0>
- //
- // package:test expect
- // test/generated/parser_fasta_test.dart 3506:7 ParserProxy._run
- super.test_missingFunctionBody_invalid();
- }
-
- @override
- @failingTest
void test_missingFunctionParameters_topLevel_void_block() {
// TODO(brianwilkerson) Wrong errors:
// Expected 1 errors of type ParserErrorCode.MISSING_FUNCTION_PARAMETERS, found 0
@@ -545,83 +500,6 @@
@override
@failingTest
- void test_missingIdentifier_beforeClosingCurly() {
- // TODO(brianwilkerson) Does not recover.
- // Expected: an object with length of <1>
- // Actual: <Instance of 'Stack'>
- // Which: has length of <2>
- //
- // package:test expect
- // test/generated/parser_fasta_test.dart 3547:7 ParserProxy._run
- super.test_missingIdentifier_beforeClosingCurly();
- }
-
- @override
- @failingTest
- void test_missingVariableInForEach() {
- // TODO(brianwilkerson) Does not recover.
- // type 'BinaryExpressionImpl' is not a subtype of type 'VariableDeclarationStatement' in type cast where
- // BinaryExpressionImpl is from package:analyzer/src/dart/ast/ast.dart
- // VariableDeclarationStatement is from package:analyzer/dart/ast/ast.dart
- //
- // dart:core Object._as
- // package:analyzer/src/fasta/ast_builder.dart 797:45 AstBuilder.endForIn
- // test/generated/parser_fasta_listener.dart 751:14 ForwardingTestListener.endForIn
- // package:front_end/src/fasta/parser/parser.dart 3755:14 Parser.parseForInRest
- // package:front_end/src/fasta/parser/parser.dart 3695:14 Parser.parseForStatement
- // package:front_end/src/fasta/parser/parser.dart 2745:14 Parser.parseStatementX
- // package:front_end/src/fasta/parser/parser.dart 2722:20 Parser.parseStatement
- // test/generated/parser_fasta_test.dart 3671:39 ParserProxy._run
- super.test_missingVariableInForEach();
- }
-
- @override
- @failingTest
- void test_mixin_application_lacks_with_clause() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.EXPECTED_TOKEN, found 0
- super.test_mixin_application_lacks_with_clause();
- }
-
- @override
- @failingTest
- void test_multipleVariablesInForEach() {
- // TODO(brianwilkerson) Does not recover.
- // Bad state: Too many elements
- // dart:collection Object&ListMixin.single
- // package:analyzer/src/fasta/ast_builder.dart 808:38 AstBuilder.endForIn
- // test/generated/parser_fasta_listener.dart 751:14 ForwardingTestListener.endForIn
- // package:front_end/src/fasta/parser/parser.dart 3755:14 Parser.parseForInRest
- // package:front_end/src/fasta/parser/parser.dart 3695:14 Parser.parseForStatement
- // package:front_end/src/fasta/parser/parser.dart 2745:14 Parser.parseStatementX
- // package:front_end/src/fasta/parser/parser.dart 2722:20 Parser.parseStatement
- // test/generated/parser_fasta_test.dart 3702:39 ParserProxy._run
- super.test_multipleVariablesInForEach();
- }
-
- @override
- @failingTest
- void test_namedFunctionExpression() {
- // TODO(brianwilkerson) Does not recover.
- // Internal problem: Compiler cannot run without a compiler context.
- // Tip: Are calls to the compiler wrapped in CompilerContext.runInContext?
- // package:front_end/src/fasta/compiler_context.dart 81:7 CompilerContext.current
- // package:front_end/src/fasta/problems.dart 29:25 internalProblem
- // package:front_end/src/fasta/problems.dart 41:10 unhandled
- // package:front_end/src/fasta/source/stack_listener.dart 126:5 StackListener.logEvent
- // package:analyzer/src/fasta/ast_builder.dart 1548:5 AstBuilder.endNamedFunctionExpression
- // test/generated/parser_fasta_listener.dart 938:14 ForwardingTestListener.endNamedFunctionExpression
- // package:front_end/src/fasta/parser/parser.dart 2520:16 Parser.parseNamedFunctionRest
- // package:front_end/src/fasta/parser/parser.dart 1379:16 Parser.parseType
- // package:front_end/src/fasta/parser/parser.dart 3365:14 Parser.parseSendOrFunctionLiteral
- // package:front_end/src/fasta/parser/parser.dart 3127:14 Parser.parsePrimary
- // test/generated/parser_fasta_test.dart 3320:31 FastaParserTestCase.parsePrimaryExpression.<fn>.<fn>
- // test/generated/parser_fasta_test.dart 3702:39 ParserProxy._run
- super.test_namedFunctionExpression();
- }
-
- @override
- @failingTest
void test_nonConstructorFactory_field() {
// TODO(brianwilkerson) Does not recover.
// Internal problem: Compiler cannot run without a compiler context.
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index ef46fe2..dc7803d 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -4291,7 +4291,7 @@
}
void test_missingAssignableSelector_identifiersAssigned() {
- parseExpression("x.y = y;");
+ parseExpression("x.y = y;", expectedEndOffset: 7);
}
void test_missingAssignableSelector_prefix_minusMinus_literal() {
@@ -4324,7 +4324,7 @@
}
void test_missingAssignableSelector_superPropertyAccessAssigned() {
- parseExpression("super.x = x;");
+ parseExpression("super.x = x;", expectedEndOffset: 11);
}
void test_missingCatchOrFinally() {
@@ -4373,13 +4373,21 @@
}
void test_missingEnumBody() {
- createParser('enum E;');
+ createParser('enum E;', expectedEndOffset: 6);
EnumDeclaration declaration = parseFullCompilationUnitMember();
expectNotNullIfNoErrors(declaration);
listener
.assertErrors([expectedError(ParserErrorCode.MISSING_ENUM_BODY, 6, 1)]);
}
+ void test_missingEnumComma() {
+ createParser('enum E {one two}');
+ EnumDeclaration declaration = parseFullCompilationUnitMember();
+ expectNotNullIfNoErrors(declaration);
+ listener
+ .assertErrors([expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 3)]);
+ }
+
void test_missingExpressionInThrow() {
ThrowExpression expression =
(parseStatement('throw;') as ExpressionStatement).expression;
@@ -4475,13 +4483,19 @@
}
void test_missingIdentifier_beforeClosingCurly() {
- createParser('int}');
+ createParser('int}', expectedEndOffset: 3);
ClassMember member = parser.parseClassMember('C');
expectNotNullIfNoErrors(member);
- listener.assertErrors([
- expectedError(ParserErrorCode.MISSING_IDENTIFIER, 3, 1),
- expectedError(ParserErrorCode.EXPECTED_TOKEN, 4, 1)
- ]);
+ listener.assertErrors(usingFastaParser
+ ? [
+ expectedError(
+ ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 0, 3),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 3, 1)
+ ]
+ : [
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 3, 1),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 4, 1)
+ ]);
}
void test_missingIdentifier_inEnum() {
@@ -4745,8 +4759,9 @@
void test_missingVariableInForEach() {
Statement statement = parseStatement('for (a < b in foo) {}');
expectNotNullIfNoErrors(statement);
- listener.assertErrors(
- [expectedError(ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH, 5, 5)]);
+ listener.assertErrors(usingFastaParser
+ ? [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 1)]
+ : [expectedError(ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH, 5, 5)]);
}
void test_mixedParameterGroups_namedPositional() {
@@ -4822,8 +4837,11 @@
void test_multipleVariablesInForEach() {
Statement statement = parseStatement('for (int a, b in foo) {}');
expectNotNullIfNoErrors(statement);
- listener.assertErrors(
- [expectedError(ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, 12, 1)]);
+ listener.assertErrors(usingFastaParser
+ ? [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 10, 1)]
+ : [
+ expectedError(ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, 12, 1)
+ ]);
}
void test_multipleWithClauses() {
@@ -4831,13 +4849,22 @@
errors: [expectedError(ParserErrorCode.MULTIPLE_WITH_CLAUSES, 25, 4)]);
}
- @failingTest
void test_namedFunctionExpression() {
- Expression expression = parsePrimaryExpression('f() {}');
- expectNotNullIfNoErrors(expression);
- listener.assertErrors(
- [expectedError(ParserErrorCode.NAMED_FUNCTION_EXPRESSION, 0, 1)]);
- expect(expression, new isInstanceOf<FunctionExpression>());
+ Expression expression;
+ if (usingFastaParser) {
+ createParser('f() {}');
+ expression = parser.parsePrimaryExpression();
+ listener.assertErrors(
+ [expectedError(ParserErrorCode.NAMED_FUNCTION_EXPRESSION, 0, 1)]);
+ expect(expression, new isInstanceOf<FunctionExpression>());
+ } else {
+ expression = parsePrimaryExpression('f() {}');
+ expectNotNullIfNoErrors(expression);
+ // Should generate an error.
+ //listener.assertErrors(
+ // [expectedError(ParserErrorCode.NAMED_FUNCTION_EXPRESSION, 0, 1)]);
+ //expect(expression, new isInstanceOf<FunctionExpression>());
+ }
}
void test_namedParameterOutsideGroup() {
@@ -5415,15 +5442,7 @@
void test_unexpectedToken_returnInExpressionFunctionBody() {
parseCompilationUnit("f() => return null;",
- errors: usingFastaParser
- ? [
- expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 6),
- expectedError(ParserErrorCode.EXPECTED_TOKEN, 14, 4),
- expectedError(
- ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 14, 4),
- expectedError(ParserErrorCode.MISSING_IDENTIFIER, 14, 4)
- ]
- : [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 6)]);
+ errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 6)]);
}
void test_unexpectedToken_semicolonBetweenClassMembers() {
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 484eb63..dea470e 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -733,19 +733,16 @@
expect(errors, hasLength(0));
}
+ @failingTest
void test_computeErrors_dart_part() {
Source librarySource =
addSource("/lib.dart", "library lib; part 'part.dart';");
Source partSource = addSource("/part.dart", "part of 'lib';");
context.parseCompilationUnit(librarySource);
List<AnalysisError> errors = context.computeErrors(partSource);
- if (context.analysisOptions.enableUriInPartOf) {
- // TODO(28522)
- // Should report that 'lib' isn't the correct URI.
- } else {
- expect(errors, isNotNull);
- expect(errors.length > 0, isTrue);
- }
+ expect(errors, isNotNull);
+ // TODO(28522)
+ fail("Should report that 'lib' isn't the correct URI.");
}
void test_computeErrors_dart_some() {
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index cb6b92c..fff1a3c 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -105,7 +105,6 @@
AnalysisOptionsImpl createAnalysisOptions() => new AnalysisOptionsImpl()
..strongMode = true
- ..enableUriInPartOf = true
..useFastaParser = useCFE;
int findOffset(String search) {
diff --git a/pkg/analyzer/test/src/dart/analysis/context_root_test.dart b/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
new file mode 100644
index 0000000..9f15523
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
@@ -0,0 +1,78 @@
+// 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/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/dart/analysis/context_root.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ContextRootTest);
+ });
+}
+
+@reflectiveTest
+class ContextRootTest {
+ MemoryResourceProvider provider = new MemoryResourceProvider();
+ String rootPath;
+ Folder rootFolder;
+ ContextRootImpl contextRoot;
+
+ void setUp() {
+ rootPath = provider.convertPath('/test/root');
+ rootFolder = provider.newFolder(rootPath);
+ contextRoot = new ContextRootImpl(provider, rootFolder);
+ contextRoot.included.add(rootFolder);
+ }
+
+ test_analyzedFiles() {
+ String optionsPath =
+ provider.convertPath('/test/root/analysis_options.yaml');
+ String readmePath = provider.convertPath('/test/root/README.md');
+ String aPath = provider.convertPath('/test/root/lib/a.dart');
+ String bPath = provider.convertPath('/test/root/lib/src/b.dart');
+ String excludePath = provider.convertPath('/test/root/exclude');
+ String cPath = provider.convertPath('/test/root/exclude/c.dart');
+
+ provider.newFile(optionsPath, '');
+ provider.newFile(readmePath, '');
+ provider.newFile(aPath, '');
+ provider.newFile(bPath, '');
+ provider.newFile(cPath, '');
+ contextRoot.excluded.add(provider.newFolder(excludePath));
+
+ expect(contextRoot.analyzedFiles(),
+ unorderedEquals([optionsPath, readmePath, aPath, bPath]));
+ }
+
+ test_isAnalyzed_explicitlyExcluded() {
+ String excludePath = provider.convertPath('/test/root/exclude');
+ String filePath = provider.convertPath('/test/root/exclude/root.dart');
+ contextRoot.excluded.add(provider.newFolder(excludePath));
+ expect(contextRoot.isAnalyzed(filePath), isFalse);
+ }
+
+ test_isAnalyzed_implicitlyExcluded_dot_analysisOptions() {
+ String filePath = provider.convertPath('/test/root/lib/.analysis_options');
+ expect(contextRoot.isAnalyzed(filePath), isFalse);
+ }
+
+ test_isAnalyzed_implicitlyExcluded_dot_packages() {
+ String filePath = provider.convertPath('/test/root/lib/.packages');
+ expect(contextRoot.isAnalyzed(filePath), isFalse);
+ }
+
+ test_isAnalyzed_implicitlyExcluded_packages() {
+ String folderPath = provider.convertPath('/test/root/lib/packages');
+ provider.newFolder(folderPath);
+ expect(contextRoot.isAnalyzed(folderPath), isFalse);
+ }
+
+ test_isAnalyzed_included() {
+ String filePath = provider.convertPath('/test/root/lib/root.dart');
+ expect(contextRoot.isAnalyzed(filePath), isTrue);
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
index 19c8d39..19ca54e 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
@@ -12,7 +12,6 @@
// TODO(scheglov): Restore similar test coverage when the front-end API
// allows it. See https://github.com/dart-lang/sdk/issues/32258.
// defineReflectiveTests(AnalysisDriverTest_Kernel);
- // defineReflectiveTests(AnalysisDriverResolutionTest_Kernel);
});
}
@@ -30,19 +29,6 @@
}
@reflectiveTest
-class AnalysisDriverResolutionTest_Kernel extends AnalysisDriverResolutionTest {
- @override
- bool get useCFE => true;
-
- @override
- @failingTest
- @FastaProblem('https://github.com/dart-lang/sdk/issues/31605')
- test_constructor_redirected_generic() async {
- await super.test_constructor_redirected_generic();
- }
-}
-
-@reflectiveTest
class AnalysisDriverTest_Kernel extends AnalysisDriverTest {
@override
bool get useCFE => true;
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
new file mode 100644
index 0000000..66a1bb0
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
@@ -0,0 +1,37 @@
+// 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 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution_test.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ // TODO(scheglov): Restore similar test coverage when the front-end API
+ // allows it. See https://github.com/dart-lang/sdk/issues/32258.
+ // defineReflectiveTests(AnalysisDriverResolutionTest_Kernel);
+ });
+}
+
+/// Tests marked with this annotations fail because we either have not triaged
+/// them, or know that this is an analyzer problem.
+const potentialAnalyzerProblem = const Object();
+
+@reflectiveTest
+class AnalysisDriverResolutionTest_Kernel extends AnalysisDriverResolutionTest {
+ @override
+ bool get useCFE => true;
+
+ @override
+ @failingTest
+ @FastaProblem('https://github.com/dart-lang/sdk/issues/31605')
+ test_constructor_redirected_generic() async {
+ await super.test_constructor_redirected_generic();
+ }
+}
+
+/// Tests marked with this annotation fail because of a Fasta problem.
+class FastaProblem {
+ const FastaProblem(String issueUri);
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
new file mode 100644
index 0000000..dc7cb05
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -0,0 +1,5714 @@
+// 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/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../utils.dart';
+import 'base.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisDriverResolutionTest);
+ });
+}
+
+Matcher isUndefinedType = new isInstanceOf<UndefinedTypeImpl>();
+
+/**
+ * Integration tests for resolution.
+ */
+@reflectiveTest
+class AnalysisDriverResolutionTest extends BaseAnalysisDriverTest {
+ test_adjacentStrings() async {
+ String content = r'''
+void main() {
+ 'aaa' 'bbb' 'ccc';
+}
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ ExpressionStatement statement = statements[0];
+ AdjacentStrings expression = statement.expression;
+ expect(expression.staticType, typeProvider.stringType);
+ expect(expression.strings, hasLength(3));
+
+ StringLiteral literal_1 = expression.strings[0];
+ expect(literal_1.staticType, typeProvider.stringType);
+
+ StringLiteral literal_2 = expression.strings[1];
+ expect(literal_2.staticType, typeProvider.stringType);
+
+ StringLiteral literal_3 = expression.strings[2];
+ expect(literal_3.staticType, typeProvider.stringType);
+ }
+
+ test_annotation() async {
+ String content = r'''
+const myAnnotation = 1;
+
+@myAnnotation
+class C {
+ @myAnnotation
+ int field1 = 2, field2 = 3;
+
+ @myAnnotation
+ C() {}
+
+ @myAnnotation
+ void method() {}
+}
+
+@myAnnotation
+int topLevelVariable1 = 4, topLevelVariable2 = 5;
+
+@myAnnotation
+void topLevelFunction() {}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ TopLevelVariableDeclaration myDeclaration = result.unit.declarations[0];
+ VariableDeclaration myVariable = myDeclaration.variables.variables[0];
+ TopLevelVariableElement myElement = myVariable.element;
+
+ void assertMyAnnotation(AnnotatedNode node) {
+ Annotation annotation = node.metadata[0];
+ expect(annotation.element, same(myElement.getter));
+
+ SimpleIdentifier identifier_1 = annotation.name;
+ expect(identifier_1.staticElement, same(myElement.getter));
+ expect(identifier_1.staticType, typeProvider.intType);
+ }
+
+ {
+ ClassDeclaration classNode = result.unit.declarations[1];
+ assertMyAnnotation(classNode);
+
+ {
+ FieldDeclaration node = classNode.members[0];
+ assertMyAnnotation(node);
+ }
+
+ {
+ ConstructorDeclaration node = classNode.members[1];
+ assertMyAnnotation(node);
+ }
+
+ {
+ MethodDeclaration node = classNode.members[2];
+ assertMyAnnotation(node);
+ }
+ }
+
+ {
+ TopLevelVariableDeclaration node = result.unit.declarations[2];
+ assertMyAnnotation(node);
+ }
+
+ {
+ FunctionDeclaration node = result.unit.declarations[3];
+ assertMyAnnotation(node);
+ }
+ }
+
+ test_annotation_constructor_withNestedConstructorInvocation() async {
+ addTestFile('''
+class C {
+ const C();
+}
+class D {
+ final C c;
+ const D(this.c);
+}
+@D(const C())
+f() {}
+''');
+ var result = await driver.getResult(testFile);
+ var elementC = AstFinder.getClass(result.unit, 'C').element;
+ var constructorC = elementC.constructors[0];
+ var elementD = AstFinder.getClass(result.unit, 'D').element;
+ var constructorD = elementD.constructors[0];
+ var atD = AstFinder.getTopLevelFunction(result.unit, 'f').metadata[0];
+ InstanceCreationExpression constC = atD.arguments.arguments[0];
+
+ expect(atD.name.staticElement, elementD);
+ expect(atD.element, constructorD);
+
+ expect(constC.staticElement, constructorC);
+ expect(constC.staticType, elementC.type);
+
+ expect(constC.constructorName.staticElement, constructorC);
+ expect(constC.constructorName.type.type, elementC.type);
+ }
+
+ test_annotation_kind_reference() async {
+ String content = r'''
+const annotation_1 = 1;
+const annotation_2 = 1;
+@annotation_1
+@annotation_2
+void main() {
+ print(42);
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ TopLevelVariableDeclaration declaration_1 = result.unit.declarations[0];
+ VariableDeclaration variable_1 = declaration_1.variables.variables[0];
+ TopLevelVariableElement element_1 = variable_1.element;
+
+ TopLevelVariableDeclaration declaration_2 = result.unit.declarations[1];
+ VariableDeclaration variable_2 = declaration_2.variables.variables[0];
+ TopLevelVariableElement element_2 = variable_2.element;
+
+ FunctionDeclaration main = result.unit.declarations[2];
+
+ Annotation annotation_1 = main.metadata[0];
+ expect(annotation_1.element, same(element_1.getter));
+
+ SimpleIdentifier identifier_1 = annotation_1.name;
+ expect(identifier_1.staticElement, same(element_1.getter));
+ expect(identifier_1.staticType, typeProvider.intType);
+
+ Annotation annotation_2 = main.metadata[1];
+ expect(annotation_2.element, same(element_2.getter));
+
+ SimpleIdentifier identifier_2 = annotation_2.name;
+ expect(identifier_2.staticElement, same(element_2.getter));
+ expect(identifier_2.staticType, typeProvider.intType);
+ }
+
+ test_annotation_prefixed_classConstructor() async {
+ var a = _p('/test/lib/a.dart');
+ provider.newFile(a, r'''
+class A {
+ const A(int a, {int b});
+}
+''');
+ addTestFile(r'''
+import 'a.dart' as p;
+
+@p.A(1, b: 2)
+main() {}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+
+ ImportElement aImport = unit.element.library.imports[0];
+ PrefixElement aPrefix = aImport.prefix;
+ LibraryElement aLibrary = aImport.importedLibrary;
+
+ CompilationUnitElement aUnitElement = aLibrary.definingCompilationUnit;
+ ClassElement aClass = aUnitElement.getType('A');
+ ConstructorElement constructor = aClass.unnamedConstructor;
+
+ Annotation annotation = unit.declarations[0].metadata.single;
+ expect(annotation.element, same(constructor));
+ PrefixedIdentifier prefixed = annotation.name;
+
+ expect(prefixed.prefix.staticElement, same(aPrefix));
+ expect(prefixed.prefix.staticType, isNull);
+
+ expect(prefixed.identifier.staticElement, same(aClass));
+ expect(prefixed.prefix.staticType, isNull);
+
+ expect(annotation.constructorName, isNull);
+
+ var arguments = annotation.arguments.arguments;
+ var parameters = constructor.parameters;
+ _assertArgumentToParameter(arguments[0], parameters[0]);
+ _assertArgumentToParameter(arguments[1], parameters[1]);
+ }
+
+ test_annotation_prefixed_classConstructorNamed() async {
+ var a = _p('/test/lib/a.dart');
+ provider.newFile(a, r'''
+class A {
+ const A.named(int a, {int b});
+}
+''');
+ addTestFile(r'''
+import 'a.dart' as p;
+
+@p.A.named(1, b: 2)
+main() {}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+
+ ImportElement aImport = unit.element.library.imports[0];
+ PrefixElement aPrefix = aImport.prefix;
+ LibraryElement aLibrary = aImport.importedLibrary;
+
+ CompilationUnitElement aUnitElement = aLibrary.definingCompilationUnit;
+ ClassElement aClass = aUnitElement.getType('A');
+ ConstructorElement constructor = aClass.getNamedConstructor('named');
+
+ Annotation annotation = unit.declarations[0].metadata.single;
+ expect(annotation.element, same(constructor));
+ PrefixedIdentifier prefixed = annotation.name;
+
+ expect(prefixed.prefix.staticElement, same(aPrefix));
+ expect(prefixed.prefix.staticType, isNull);
+
+ expect(prefixed.identifier.staticElement, same(aClass));
+ expect(prefixed.prefix.staticType, isNull);
+
+ SimpleIdentifier constructorName = annotation.constructorName;
+ expect(constructorName.staticElement, same(constructor));
+ expect(constructorName.staticType.toString(), '(int, {b: int}) → A');
+
+ var arguments = annotation.arguments.arguments;
+ var parameters = constructor.parameters;
+ _assertArgumentToParameter(arguments[0], parameters[0]);
+ _assertArgumentToParameter(arguments[1], parameters[1]);
+ }
+
+ test_annotation_prefixed_classField() async {
+ var a = _p('/test/lib/a.dart');
+ provider.newFile(a, r'''
+class A {
+ static const a = 1;
+}
+''');
+ addTestFile(r'''
+import 'a.dart' as p;
+
+@p.A.a
+main() {}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ImportElement aImport = unit.element.library.imports[0];
+ PrefixElement aPrefix = aImport.prefix;
+ LibraryElement aLibrary = aImport.importedLibrary;
+
+ CompilationUnitElement aUnitElement = aLibrary.definingCompilationUnit;
+ ClassElement aClass = aUnitElement.getType('A');
+ var aGetter = aClass.getField('a').getter;
+
+ Annotation annotation = unit.declarations[0].metadata.single;
+ expect(annotation.element, same(aGetter));
+ PrefixedIdentifier prefixed = annotation.name;
+
+ expect(prefixed.prefix.staticElement, same(aPrefix));
+ expect(prefixed.prefix.staticType, isNull);
+
+ expect(prefixed.identifier.staticElement, same(aClass));
+ expect(prefixed.prefix.staticType, isNull);
+
+ expect(annotation.constructorName.staticElement, aGetter);
+ expect(annotation.constructorName.staticType, typeProvider.intType);
+
+ expect(annotation.arguments, isNull);
+ }
+
+ test_annotation_prefixed_topLevelVariable() async {
+ var a = _p('/test/lib/a.dart');
+ provider.newFile(a, r'''
+const topAnnotation = 1;
+''');
+ addTestFile(r'''
+import 'a.dart' as p;
+
+@p.topAnnotation
+main() {}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+
+ ImportElement aImport = unit.element.library.imports[0];
+ PrefixElement aPrefix = aImport.prefix;
+ LibraryElement aLibrary = aImport.importedLibrary;
+
+ CompilationUnitElement aUnitElement = aLibrary.definingCompilationUnit;
+ var topAnnotation = aUnitElement.topLevelVariables[0].getter;
+
+ Annotation annotation = unit.declarations[0].metadata.single;
+ expect(annotation.element, same(topAnnotation));
+ PrefixedIdentifier prefixed = annotation.name;
+
+ expect(prefixed.prefix.staticElement, same(aPrefix));
+ expect(prefixed.prefix.staticType, isNull);
+
+ expect(prefixed.identifier.staticElement, same(topAnnotation));
+ expect(prefixed.prefix.staticType, isNull);
+
+ expect(annotation.constructorName, isNull);
+ expect(annotation.arguments, isNull);
+ }
+
+ test_asExpression() async {
+ String content = r'''
+void main() {
+ num v = 42;
+ v as int;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.path, testFile);
+ expect(result.errors, isEmpty);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ NodeList<Statement> statements = _getMainStatements(result);
+
+ // num v = 42;
+ VariableElement vElement;
+ {
+ VariableDeclarationStatement statement = statements[0];
+ vElement = statement.variables.variables[0].name.staticElement;
+ expect(vElement.type, typeProvider.numType);
+ }
+
+ // v as int;
+ {
+ ExpressionStatement statement = statements[1];
+ AsExpression asExpression = statement.expression;
+ expect(asExpression.staticType, typeProvider.intType);
+
+ SimpleIdentifier target = asExpression.expression;
+ expect(target.staticElement, vElement);
+ expect(target.staticType, typeProvider.numType);
+
+ TypeName intName = asExpression.type;
+ expect(intName.name.staticElement, typeProvider.intType.element);
+ expect(intName.name.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_compound_indexExpression() async {
+ String content = r'''
+main() {
+ var items = <num>[1, 2, 3];
+ items[0] += 4;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+
+ var typeProvider = unit.element.context.typeProvider;
+ InterfaceType numType = typeProvider.numType;
+ InterfaceType intType = typeProvider.intType;
+ InterfaceType listType = typeProvider.listType;
+ InterfaceType listNumType = listType.instantiate([numType]);
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement itemsElement;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ VariableDeclaration itemsNode = statement.variables.variables[0];
+ itemsElement = itemsNode.element;
+ expect(itemsElement.type, listNumType);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.operator.type, TokenType.PLUS_EQ);
+ expect(assignment.staticElement, isNotNull);
+ expect(assignment.staticElement.name, '+');
+ expect(assignment.staticType, typeProvider.numType); // num + int = num
+
+ IndexExpression indexExpression = assignment.leftHandSide;
+ expect(indexExpression.staticType, numType);
+ expect(indexExpression.index.staticType, intType);
+
+ MethodMember actualElement = indexExpression.staticElement;
+ MethodMember expectedElement = listNumType.getMethod('[]=');
+ expect(actualElement.name, '[]=');
+ expect(actualElement.baseElement, same(expectedElement.baseElement));
+ expect(actualElement.returnType, VoidTypeImpl.instance);
+ expect(actualElement.parameters[0].type, intType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_compound_local() async {
+ String content = r'''
+main() {
+ num v = 0;
+ v += 3;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement v;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ v = statement.variables.variables[0].element;
+ expect(v.type, typeProvider.numType);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.operator.type, TokenType.PLUS_EQ);
+ expect(assignment.staticElement, isNotNull);
+ expect(assignment.staticElement.name, '+');
+ expect(assignment.staticType, typeProvider.numType); // num + int = num
+
+ SimpleIdentifier left = assignment.leftHandSide;
+ expect(left.staticElement, same(v));
+ expect(left.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_compound_prefixedIdentifier() async {
+ String content = r'''
+main() {
+ var c = new C();
+ c.f += 2;
+}
+class C {
+ num f;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cClassDeclaration = unit.declarations[1];
+ ClassElement cClassElement = cClassDeclaration.element;
+ FieldElement fElement = cClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement c;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ c = statement.variables.variables[0].element;
+ expect(c.type, cClassElement.type);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.operator.type, TokenType.PLUS_EQ);
+ expect(assignment.staticElement, isNotNull);
+ expect(assignment.staticElement.name, '+');
+ expect(assignment.staticType, typeProvider.numType); // num + int = num
+
+ PrefixedIdentifier left = assignment.leftHandSide;
+ expect(left.staticElement, same(fElement.setter));
+ expect(left.staticType, typeProvider.numType);
+
+ expect(left.prefix.staticElement, c);
+ expect(left.prefix.staticType, cClassElement.type);
+
+ expect(left.identifier.staticElement, same(fElement.setter));
+ expect(left.identifier.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_compound_propertyAccess() async {
+ String content = r'''
+main() {
+ new C().f += 2;
+}
+class C {
+ num f;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cClassDeclaration = unit.declarations[1];
+ ClassElement cClassElement = cClassDeclaration.element;
+ FieldElement fElement = cClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.operator.type, TokenType.PLUS_EQ);
+ expect(assignment.staticElement, isNotNull);
+ expect(assignment.staticElement.name, '+');
+ expect(assignment.staticType, typeProvider.numType); // num + int = num
+
+ PropertyAccess left = assignment.leftHandSide;
+ expect(left.staticType, typeProvider.numType);
+
+ InstanceCreationExpression newC = left.target;
+ expect(newC.staticElement, cClassElement.unnamedConstructor);
+
+ expect(left.propertyName.staticElement, same(fElement.setter));
+ expect(left.propertyName.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_nullAware_local() async {
+ String content = r'''
+main() {
+ String v;
+ v ??= 'test';
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement v;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ v = statement.variables.variables[0].element;
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.operator.type, TokenType.QUESTION_QUESTION_EQ);
+ expect(assignment.staticElement, isNull);
+ expect(assignment.staticType, typeProvider.stringType);
+
+ SimpleIdentifier left = assignment.leftHandSide;
+ expect(left.staticElement, same(v));
+ expect(left.staticType, typeProvider.stringType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.stringType);
+ }
+ }
+
+ test_assignmentExpression_propertyAccess_forwardingStub() async {
+ String content = r'''
+class A {
+ int f;
+}
+abstract class I<T> {
+ T f;
+}
+class B extends A implements I<int> {}
+main() {
+ new B().f = 1;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration aNode = unit.declarations[0];
+ ClassElement aElement = aNode.element;
+ FieldElement fElement = aElement.getField('f');
+
+ ClassDeclaration bNode = unit.declarations[2];
+ ClassElement bElement = bNode.element;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+ ExpressionStatement statement = mainStatements[0];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.staticType, typeProvider.intType);
+
+ PropertyAccess left = assignment.leftHandSide;
+ expect(left.staticType, typeProvider.intType);
+
+ InstanceCreationExpression newB = left.target;
+ expect(newB.staticElement, bElement.unnamedConstructor);
+
+ expect(left.propertyName.staticElement, same(fElement.setter));
+ expect(left.propertyName.staticType, typeProvider.intType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+
+ test_assignmentExpression_simple_indexExpression() async {
+ String content = r'''
+main() {
+ var items = <int>[1, 2, 3];
+ items[0] = 4;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+
+ var typeProvider = unit.element.context.typeProvider;
+ InterfaceType intType = typeProvider.intType;
+ InterfaceType listType = typeProvider.listType;
+ InterfaceType listIntType = listType.instantiate([intType]);
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement itemsElement;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ VariableDeclaration itemsNode = statement.variables.variables[0];
+ itemsElement = itemsNode.element;
+ expect(itemsElement.type, listIntType);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.operator.type, TokenType.EQ);
+ expect(assignment.staticElement, isNull);
+ expect(assignment.staticType, typeProvider.intType);
+
+ IndexExpression indexExpression = assignment.leftHandSide;
+ expect(indexExpression.staticType, intType);
+ expect(indexExpression.index.staticType, intType);
+
+ MethodMember actualElement = indexExpression.staticElement;
+ MethodMember expectedElement = listIntType.getMethod('[]=');
+ expect(actualElement.name, '[]=');
+ expect(actualElement.baseElement, same(expectedElement.baseElement));
+ expect(actualElement.returnType, VoidTypeImpl.instance);
+ expect(actualElement.parameters[0].type, intType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_simple_instanceField_unqualified() async {
+ String content = r'''
+class C {
+ num f = 0;
+ foo() {
+ f = 2;
+ }
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cDeclaration = unit.declarations[0];
+ FieldElement fElement = cDeclaration.element.fields[0];
+
+ MethodDeclaration fooDeclaration = cDeclaration.members[1];
+ BlockFunctionBody fooBody = fooDeclaration.body;
+
+ {
+ ExpressionStatement statement = fooBody.block.statements[0];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.operator.type, TokenType.EQ);
+ expect(assignment.staticElement, isNull);
+ expect(assignment.staticType, typeProvider.intType);
+
+ SimpleIdentifier left = assignment.leftHandSide;
+ expect(left.staticElement, same(fElement.setter));
+ expect(left.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_simple_local() async {
+ String content = r'''
+main() {
+ num v = 0;
+ v = 2;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement v;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ v = statement.variables.variables[0].element;
+ expect(v.type, typeProvider.numType);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.operator.type, TokenType.EQ);
+ expect(assignment.staticElement, isNull);
+ expect(assignment.staticType, typeProvider.intType);
+
+ SimpleIdentifier left = assignment.leftHandSide;
+ expect(left.staticElement, same(v));
+ expect(left.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_simple_prefixedIdentifier() async {
+ String content = r'''
+main() {
+ var c = new C();
+ c.f = 2;
+}
+class C {
+ num f;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cClassDeclaration = unit.declarations[1];
+ ClassElement cClassElement = cClassDeclaration.element;
+ FieldElement fElement = cClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement c;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ c = statement.variables.variables[0].element;
+ expect(c.type, cClassElement.type);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.staticType, typeProvider.intType);
+
+ PrefixedIdentifier left = assignment.leftHandSide;
+ expect(left.staticElement, same(fElement.setter));
+ expect(left.staticType, typeProvider.numType);
+
+ expect(left.prefix.staticElement, c);
+ expect(left.prefix.staticType, cClassElement.type);
+
+ expect(left.identifier.staticElement, same(fElement.setter));
+ expect(left.identifier.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_simple_prefixedIdentifier_staticField() async {
+ String content = r'''
+main() {
+ C.f = 2;
+}
+class C {
+ static num f;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cClassDeclaration = unit.declarations[1];
+ ClassElement cClassElement = cClassDeclaration.element;
+ FieldElement fElement = cClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.staticType, typeProvider.intType);
+
+ PrefixedIdentifier left = assignment.leftHandSide;
+ expect(left.staticElement, same(fElement.setter));
+ expect(left.staticType, typeProvider.numType);
+
+ expect(left.prefix.staticElement, cClassElement);
+ expect(left.prefix.staticType, cClassElement.type);
+
+ expect(left.identifier.staticElement, same(fElement.setter));
+ expect(left.identifier.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_simple_propertyAccess() async {
+ String content = r'''
+main() {
+ new C().f = 2;
+}
+class C {
+ num f;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cClassDeclaration = unit.declarations[1];
+ ClassElement cClassElement = cClassDeclaration.element;
+ FieldElement fElement = cClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.staticType, typeProvider.intType);
+
+ PropertyAccess left = assignment.leftHandSide;
+ expect(left.staticType, typeProvider.numType);
+
+ InstanceCreationExpression newC = left.target;
+ expect(newC.staticElement, cClassElement.unnamedConstructor);
+
+ expect(left.propertyName.staticElement, same(fElement.setter));
+ expect(left.propertyName.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_simple_propertyAccess_chained() async {
+ String content = r'''
+main() {
+ var a = new A();
+ a.b.f = 2;
+}
+class A {
+ B b;
+}
+class B {
+ num f;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration aClassDeclaration = unit.declarations[1];
+ ClassElement aClassElement = aClassDeclaration.element;
+ FieldElement bElement = aClassElement.getField('b');
+
+ ClassDeclaration bClassDeclaration = unit.declarations[2];
+ ClassElement bClassElement = bClassDeclaration.element;
+ FieldElement fElement = bClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement a;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ a = statement.variables.variables[0].element;
+ expect(a.type, aClassElement.type);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.staticType, typeProvider.intType);
+
+ PropertyAccess fAccess = assignment.leftHandSide;
+ expect(fAccess.propertyName.name, 'f');
+ expect(fAccess.propertyName.staticElement, same(fElement.setter));
+ expect(fAccess.propertyName.staticType, typeProvider.numType);
+
+ PrefixedIdentifier bAccess = fAccess.target;
+ expect(bAccess.identifier.name, 'b');
+ expect(bAccess.identifier.staticElement, same(bElement.getter));
+ expect(bAccess.identifier.staticType, bClassElement.type);
+
+ SimpleIdentifier aIdentifier = bAccess.prefix;
+ expect(aIdentifier.name, 'a');
+ expect(aIdentifier.staticElement, a);
+ expect(aIdentifier.staticType, aClassElement.type);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_simple_propertyAccess_setter() async {
+ String content = r'''
+main() {
+ new C().f = 2;
+}
+class C {
+ void set f(num _) {}
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cClassDeclaration = unit.declarations[1];
+ ClassElement cClassElement = cClassDeclaration.element;
+ FieldElement fElement = cClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.staticType, typeProvider.intType);
+
+ PropertyAccess left = assignment.leftHandSide;
+ expect(left.staticType, typeProvider.numType);
+
+ InstanceCreationExpression newC = left.target;
+ expect(newC.staticElement, cClassElement.unnamedConstructor);
+
+ expect(left.propertyName.staticElement, same(fElement.setter));
+ expect(left.propertyName.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_simple_staticField_unqualified() async {
+ String content = r'''
+class C {
+ static num f = 0;
+ foo() {
+ f = 2;
+ }
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cDeclaration = unit.declarations[0];
+ FieldElement fElement = cDeclaration.element.fields[0];
+
+ MethodDeclaration fooDeclaration = cDeclaration.members[1];
+ BlockFunctionBody fooBody = fooDeclaration.body;
+
+ {
+ ExpressionStatement statement = fooBody.block.statements[0];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.operator.type, TokenType.EQ);
+ expect(assignment.staticElement, isNull);
+ expect(assignment.staticType, typeProvider.intType);
+
+ SimpleIdentifier left = assignment.leftHandSide;
+ expect(left.staticElement, same(fElement.setter));
+ expect(left.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_assignmentExpression_simple_topLevelVariable() async {
+ String content = r'''
+main() {
+ v = 2;
+}
+num v = 0;
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ TopLevelVariableElement v;
+ {
+ TopLevelVariableDeclaration declaration = unit.declarations[1];
+ v = declaration.variables.variables[0].element;
+ expect(v.type, typeProvider.numType);
+ }
+
+ List<Statement> mainStatements = _getMainStatements(result);
+ {
+ ExpressionStatement statement = mainStatements[0];
+
+ AssignmentExpression assignment = statement.expression;
+ expect(assignment.operator.type, TokenType.EQ);
+ expect(assignment.staticElement, isNull);
+ expect(assignment.staticType, typeProvider.intType);
+
+ SimpleIdentifier left = assignment.leftHandSide;
+ expect(left.staticElement, same(v.setter));
+ expect(left.staticType, typeProvider.numType);
+
+ Expression right = assignment.rightHandSide;
+ expect(right.staticType, typeProvider.intType);
+ }
+ }
+
+ test_binaryExpression() async {
+ String content = r'''
+main() {
+ var v = 1 + 2;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableDeclarationStatement statement = mainStatements[0];
+ VariableDeclaration vNode = statement.variables.variables[0];
+ VariableElement vElement = vNode.element;
+ expect(vElement.type, typeProvider.intType);
+
+ BinaryExpression value = vNode.initializer;
+ expect(value.leftOperand.staticType, typeProvider.intType);
+ expect(value.rightOperand.staticType, typeProvider.intType);
+ expect(value.staticElement.name, '+');
+ expect(value.staticType, typeProvider.intType);
+ }
+
+ test_binaryExpression_ifNull() async {
+ String content = r'''
+main() {
+ 1.2 ?? 3;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ ExpressionStatement statement = mainStatements[0];
+ BinaryExpression binary = statement.expression;
+ expect(binary.operator.type, TokenType.QUESTION_QUESTION);
+ expect(binary.staticElement, isNull);
+ expect(binary.staticType, typeProvider.numType);
+
+ expect(binary.leftOperand.staticType, typeProvider.doubleType);
+ expect(binary.rightOperand.staticType, typeProvider.intType);
+ }
+
+ test_binaryExpression_logical() async {
+ addTestFile(r'''
+main() {
+ true && true;
+ true || true;
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = statements[0];
+ BinaryExpression binaryExpression = statement.expression;
+ expect(binaryExpression.staticElement, isNull);
+ expect(binaryExpression.staticType, typeProvider.boolType);
+ }
+
+ {
+ ExpressionStatement statement = statements[1];
+ BinaryExpression binaryExpression = statement.expression;
+ expect(binaryExpression.staticElement, isNull);
+ expect(binaryExpression.staticType, typeProvider.boolType);
+ }
+ }
+
+ test_binaryExpression_notEqual() async {
+ String content = r'''
+main() {
+ 1 != 2;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+ ExpressionStatement statement = statements[0];
+ BinaryExpression expression = statement.expression;
+ expect(expression.operator.type, TokenType.BANG_EQ);
+ expect(expression.leftOperand.staticType, typeProvider.intType);
+ expect(expression.rightOperand.staticType, typeProvider.intType);
+ expect(expression.staticElement.name, '==');
+ expect(expression.staticType, typeProvider.boolType);
+ }
+
+ test_cascadeExpression() async {
+ String content = r'''
+void main() {
+ new A()..a()..b();
+}
+class A {
+ void a() {}
+ void b() {}
+}
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+
+ List<Statement> statements = _getMainStatements(result);
+
+ ExpressionStatement statement = statements[0];
+ CascadeExpression expression = statement.expression;
+ expect(expression.target.staticType, isNotNull);
+ NodeList<Expression> sections = expression.cascadeSections;
+
+ MethodInvocation a = sections[0];
+ expect(a.methodName.staticElement, isNotNull);
+ expect(a.staticType, isNotNull);
+
+ MethodInvocation b = sections[1];
+ expect(b.methodName.staticElement, isNotNull);
+ expect(b.staticType, isNotNull);
+ }
+
+ test_closure() async {
+ addTestFile(r'''
+main() {
+ var items = <int>[1, 2, 3];
+ items.forEach((item) {
+ item;
+ });
+ items.forEach((item) {
+ item;
+ });
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ FunctionDeclaration mainDeclaration = result.unit.declarations[0];
+ FunctionElement mainElement = mainDeclaration.element;
+ BlockFunctionBody mainBody = mainDeclaration.functionExpression.body;
+ List<Statement> mainStatements = mainBody.block.statements;
+
+ VariableDeclarationStatement itemsStatement = mainStatements[0];
+ var itemsElement = itemsStatement.variables.variables[0].element;
+
+ // First closure.
+ ParameterElement itemElement1;
+ {
+ ExpressionStatement forStatement = mainStatements[1];
+ MethodInvocation forInvocation = forStatement.expression;
+
+ SimpleIdentifier forTarget = forInvocation.target;
+ expect(forTarget.staticElement, itemsElement);
+
+ var closureTypeStr = '(int) → Null';
+ FunctionExpression closure = forInvocation.argumentList.arguments[0];
+
+ FunctionElementImpl closureElement = closure.element;
+ expect(closureElement.enclosingElement, same(mainElement));
+
+ ParameterElement itemElement = closureElement.parameters[0];
+ itemElement1 = itemElement;
+
+ expect(closureElement.returnType, typeProvider.nullType);
+ expect(closureElement.type.element, same(closureElement));
+ expect(closureElement.type.toString(), closureTypeStr);
+ expect(closure.staticType, same(closureElement.type));
+
+ List<FormalParameter> closureParameters = closure.parameters.parameters;
+ expect(closureParameters, hasLength(1));
+
+ SimpleFormalParameter itemNode = closureParameters[0];
+ _assertSimpleParameter(itemNode, itemElement,
+ name: 'item',
+ offset: 56,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.intType);
+
+ BlockFunctionBody closureBody = closure.body;
+ List<Statement> closureStatements = closureBody.block.statements;
+
+ ExpressionStatement itemStatement = closureStatements[0];
+ SimpleIdentifier itemIdentifier = itemStatement.expression;
+ expect(itemIdentifier.staticElement, itemElement);
+ expect(itemIdentifier.staticType, typeProvider.intType);
+ }
+
+ // Second closure, same names, different elements.
+ {
+ ExpressionStatement forStatement = mainStatements[2];
+ MethodInvocation forInvocation = forStatement.expression;
+
+ SimpleIdentifier forTarget = forInvocation.target;
+ expect(forTarget.staticElement, itemsElement);
+
+ var closureTypeStr = '(int) → Null';
+ FunctionExpression closure = forInvocation.argumentList.arguments[0];
+
+ FunctionElementImpl closureElement = closure.element;
+ expect(closureElement.enclosingElement, same(mainElement));
+
+ ParameterElement itemElement = closureElement.parameters[0];
+ expect(itemElement, isNot(same(itemElement1)));
+
+ expect(closureElement.returnType, typeProvider.nullType);
+ expect(closureElement.type.element, same(closureElement));
+ expect(closureElement.type.toString(), closureTypeStr);
+ expect(closure.staticType, same(closureElement.type));
+
+ List<FormalParameter> closureParameters = closure.parameters.parameters;
+ expect(closureParameters, hasLength(1));
+
+ SimpleFormalParameter itemNode = closureParameters[0];
+ _assertSimpleParameter(itemNode, itemElement,
+ name: 'item',
+ offset: 97,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.intType);
+
+ BlockFunctionBody closureBody = closure.body;
+ List<Statement> closureStatements = closureBody.block.statements;
+
+ ExpressionStatement itemStatement = closureStatements[0];
+ SimpleIdentifier itemIdentifier = itemStatement.expression;
+ expect(itemIdentifier.staticElement, itemElement);
+ expect(itemIdentifier.staticType, typeProvider.intType);
+ }
+ }
+
+ test_conditionalExpression() async {
+ String content = r'''
+void main() {
+ true ? 1 : 2.3;
+}
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ ExpressionStatement statement = statements[0];
+ ConditionalExpression expression = statement.expression;
+ expect(expression.staticType, typeProvider.numType);
+ expect(expression.condition.staticType, typeProvider.boolType);
+ expect(expression.thenExpression.staticType, typeProvider.intType);
+ expect(expression.elseExpression.staticType, typeProvider.doubleType);
+ }
+
+ test_constructor_context() async {
+ addTestFile(r'''
+class C {
+ C(int p) {
+ p;
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration cNode = result.unit.declarations[0];
+
+ ConstructorDeclaration constructorNode = cNode.members[0];
+ ParameterElement pElement = constructorNode.element.parameters[0];
+
+ BlockFunctionBody constructorBody = constructorNode.body;
+ ExpressionStatement pStatement = constructorBody.block.statements[0];
+
+ SimpleIdentifier pIdentifier = pStatement.expression;
+ expect(pIdentifier.staticElement, same(pElement));
+ expect(pIdentifier.staticType, typeProvider.intType);
+ }
+
+ test_constructor_initializer_field() async {
+ addTestFile(r'''
+class C {
+ int f;
+ C(int p) : f = p {
+ f;
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ ClassDeclaration cNode = result.unit.declarations[0];
+ ClassElement cElement = cNode.element;
+ FieldElement fElement = cElement.getField('f');
+
+ ConstructorDeclaration constructorNode = cNode.members[1];
+ ParameterElement pParameterElement = constructorNode.element.parameters[0];
+
+ {
+ ConstructorFieldInitializer initializer = constructorNode.initializers[0];
+ expect(initializer.fieldName.staticElement, same(fElement));
+
+ SimpleIdentifier expression = initializer.expression;
+ expect(expression.staticElement, same(pParameterElement));
+ }
+ }
+
+ test_constructor_initializer_super() async {
+ addTestFile(r'''
+class A {
+ A(int a);
+ A.named(int a, {int b});
+}
+class B extends A {
+ B.one(int p) : super(p + 1);
+ B.two(int p) : super.named(p + 1, b: p + 2);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ ClassDeclaration aNode = result.unit.declarations[0];
+ ClassElement aElement = aNode.element;
+
+ ClassDeclaration bNode = result.unit.declarations[1];
+
+ {
+ ConstructorDeclaration constructor = bNode.members[0];
+ SuperConstructorInvocation initializer = constructor.initializers[0];
+ expect(initializer.staticElement, same(aElement.unnamedConstructor));
+ expect(initializer.constructorName, isNull);
+ }
+
+ {
+ var namedConstructor = aElement.getNamedConstructor('named');
+
+ ConstructorDeclaration constructor = bNode.members[1];
+ SuperConstructorInvocation initializer = constructor.initializers[0];
+ expect(initializer.staticElement, same(namedConstructor));
+
+ var constructorName = initializer.constructorName;
+ expect(constructorName.staticElement, same(namedConstructor));
+ expect(constructorName.staticType, isNull);
+
+ List<Expression> arguments = initializer.argumentList.arguments;
+ _assertArgumentToParameter(arguments[0], namedConstructor.parameters[0]);
+ _assertArgumentToParameter(arguments[1], namedConstructor.parameters[1]);
+ }
+ }
+
+ test_constructor_initializer_this() async {
+ addTestFile(r'''
+class C {
+ C(int a, [int b]);
+ C.named(int a, {int b});
+ C.one(int p) : this(1, 2);
+ C.two(int p) : this.named(3, b: 4);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ ClassDeclaration cNode = result.unit.declarations[0];
+ ClassElement cElement = cNode.element;
+
+ {
+ var unnamedConstructor = cElement.constructors[0];
+
+ ConstructorDeclaration constructor = cNode.members[2];
+ RedirectingConstructorInvocation initializer =
+ constructor.initializers[0];
+ expect(initializer.staticElement, same(unnamedConstructor));
+ expect(initializer.constructorName, isNull);
+
+ List<Expression> arguments = initializer.argumentList.arguments;
+ _assertArgumentToParameter(
+ arguments[0], unnamedConstructor.parameters[0]);
+ _assertArgumentToParameter(
+ arguments[1], unnamedConstructor.parameters[1]);
+ }
+
+ {
+ var namedConstructor = cElement.constructors[1];
+
+ ConstructorDeclaration constructor = cNode.members[3];
+ RedirectingConstructorInvocation initializer =
+ constructor.initializers[0];
+ expect(initializer.staticElement, same(namedConstructor));
+
+ var constructorName = initializer.constructorName;
+ expect(constructorName.staticElement, same(namedConstructor));
+ expect(constructorName.staticType, isNull);
+
+ List<Expression> arguments = initializer.argumentList.arguments;
+ _assertArgumentToParameter(arguments[0], namedConstructor.parameters[0]);
+ _assertArgumentToParameter(arguments[1], namedConstructor.parameters[1]);
+ }
+ }
+
+ test_constructor_redirected() async {
+ addTestFile(r'''
+class A implements B {
+ A(int a);
+ A.named(double a);
+}
+class B {
+ factory B.one(int b) = A;
+ factory B.two(double b) = A.named;
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.errors, isEmpty);
+
+ ClassDeclaration aNode = result.unit.declarations[0];
+ ClassElement aElement = aNode.element;
+
+ ClassDeclaration bNode = result.unit.declarations[1];
+
+ {
+ ConstructorElement aUnnamed = aElement.constructors[0];
+
+ ConstructorDeclaration constructor = bNode.members[0];
+ ConstructorElement element = constructor.element;
+ expect(element.redirectedConstructor, same(aUnnamed));
+
+ var constructorName = constructor.redirectedConstructor;
+ expect(constructorName.staticElement, same(aUnnamed));
+
+ TypeName typeName = constructorName.type;
+ expect(typeName.type, aElement.type);
+
+ SimpleIdentifier identifier = typeName.name;
+ expect(identifier.staticElement, same(aElement));
+ expect(identifier.staticType, aElement.type);
+
+ expect(constructorName.name, isNull);
+ }
+
+ {
+ ConstructorElement aNamed = aElement.constructors[1];
+
+ ConstructorDeclaration constructor = bNode.members[1];
+ ConstructorElement element = constructor.element;
+ expect(element.redirectedConstructor, same(aNamed));
+
+ var constructorName = constructor.redirectedConstructor;
+ expect(constructorName.staticElement, same(aNamed));
+
+ TypeName typeName = constructorName.type;
+ expect(typeName.type, aElement.type);
+
+ SimpleIdentifier identifier = typeName.name;
+ expect(identifier.staticElement, same(aElement));
+ expect(identifier.staticType, aElement.type);
+
+ expect(constructorName.name.staticElement, aNamed);
+ expect(constructorName.name.staticType, isNull);
+ }
+ }
+
+ test_constructor_redirected_generic() async {
+ addTestFile(r'''
+class A<T> implements B<T> {
+ A(int a);
+ A.named(double a);
+}
+class B<U> {
+ factory B.one(int b) = A<U>;
+ factory B.two(double b) = A<U>.named;
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.errors, isEmpty);
+
+ ClassDeclaration aNode = result.unit.declarations[0];
+ ClassElement aElement = aNode.element;
+
+ ClassDeclaration bNode = result.unit.declarations[1];
+ TypeParameterType uType = bNode.element.typeParameters[0].type;
+ InterfaceType auType = aElement.type.instantiate([uType]);
+
+ {
+ ConstructorElement expectedElement = aElement.constructors[0];
+
+ ConstructorDeclaration constructor = bNode.members[0];
+ ConstructorElement element = constructor.element;
+
+ ConstructorMember actualMember = element.redirectedConstructor;
+ expect(actualMember.baseElement, same(expectedElement));
+ expect(actualMember.definingType, auType);
+
+ var constructorName = constructor.redirectedConstructor;
+ expect(constructorName.staticElement, same(actualMember));
+
+ TypeName typeName = constructorName.type;
+ expect(typeName.type, auType);
+
+ SimpleIdentifier identifier = typeName.name;
+ expect(identifier.staticElement, same(aElement));
+ expect(identifier.staticType, auType);
+
+ expect(constructorName.name, isNull);
+ }
+
+ {
+ ConstructorElement expectedElement = aElement.constructors[1];
+
+ ConstructorDeclaration constructor = bNode.members[1];
+ ConstructorElement element = constructor.element;
+
+ ConstructorMember actualMember = element.redirectedConstructor;
+ expect(actualMember.baseElement, same(expectedElement));
+ expect(actualMember.definingType, auType);
+
+ var constructorName = constructor.redirectedConstructor;
+ expect(constructorName.staticElement, same(actualMember));
+
+ TypeName typeName = constructorName.type;
+ expect(typeName.type, auType);
+
+ SimpleIdentifier identifier = typeName.name;
+ expect(identifier.staticElement, same(aElement));
+ expect(identifier.staticType, auType);
+
+ expect(constructorName.name.staticElement, same(actualMember));
+ expect(constructorName.name.staticType, isNull);
+ }
+ }
+
+ test_enum_toString() async {
+ addTestFile(r'''
+enum MyEnum { A, B, C }
+main(MyEnum e) {
+ e.toString();
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ EnumDeclaration enumNode = result.unit.declarations[0];
+ ClassElement enumElement = enumNode.element;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ expect(invocation.staticInvokeType.toString(), '() → String');
+
+ MethodElement methodElement = invocation.methodName.staticElement;
+ expect(methodElement.name, 'toString');
+ expect(methodElement.enclosingElement, same(enumElement));
+ }
+
+ test_error_unresolvedTypeAnnotation() async {
+ String content = r'''
+main() {
+ Foo<int> v = null;
+}
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ var statements = _getMainStatements(result);
+
+ VariableDeclarationStatement statement = statements[0];
+
+ TypeName typeName = statement.variables.type;
+ expect(typeName.type, isUndefinedType);
+ if (useCFE) {
+ expect(typeName.typeArguments.arguments[0].type, isUndefinedType);
+ } else {
+ expect(typeName.typeArguments.arguments[0].type, typeProvider.intType);
+ }
+
+ VariableDeclaration vNode = statement.variables.variables[0];
+ expect(vNode.name.staticType, isUndefinedType);
+ expect(vNode.element.type, isUndefinedType);
+ }
+
+ test_field_context() async {
+ addTestFile(r'''
+class C<T> {
+ var f = <T>[];
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration cNode = result.unit.declarations[0];
+ var tElement = cNode.element.typeParameters[0];
+
+ FieldDeclaration fDeclaration = cNode.members[0];
+ VariableDeclaration fNode = fDeclaration.fields.variables[0];
+ FieldElement fElement = fNode.element;
+ expect(fElement.type, typeProvider.listType.instantiate([tElement.type]));
+ }
+
+ test_formalParameter_functionTyped() async {
+ addTestFile(r'''
+class A {
+ A(String p(int a));
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration clazz = result.unit.declarations[0];
+ ConstructorDeclaration constructor = clazz.members[0];
+ List<FormalParameter> parameters = constructor.parameters.parameters;
+
+ FunctionTypedFormalParameter p = parameters[0];
+ expect(p.element, same(constructor.element.parameters[0]));
+
+ {
+ FunctionType type = p.identifier.staticType;
+ expect(type.returnType, typeProvider.stringType);
+
+ expect(type.parameters, hasLength(1));
+ expect(type.parameters[0].type, typeProvider.intType);
+ }
+
+ _assertTypeNameSimple(p.returnType, typeProvider.stringType);
+
+ {
+ SimpleFormalParameter a = p.parameters.parameters[0];
+ _assertTypeNameSimple(a.type, typeProvider.intType);
+ expect(a.identifier.staticType, typeProvider.intType);
+ }
+ }
+
+ test_formalParameter_functionTyped_fieldFormal_typed() async {
+ // TODO(scheglov) Add "untyped" version with precise type in field.
+ addTestFile(r'''
+class A {
+ Function f;
+ A(String this.f(int a));
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration clazz = result.unit.declarations[0];
+
+ FieldDeclaration fDeclaration = clazz.members[0];
+ VariableDeclaration fNode = fDeclaration.fields.variables[0];
+ FieldElement fElement = fNode.element;
+
+ ConstructorDeclaration constructor = clazz.members[1];
+
+ FieldFormalParameterElement pElement = constructor.element.parameters[0];
+ expect(pElement.field, same(fElement));
+
+ List<FormalParameter> parameters = constructor.parameters.parameters;
+ FieldFormalParameter p = parameters[0];
+ expect(p.element, same(pElement));
+
+ expect(p.identifier.staticElement, same(pElement));
+ expect(p.identifier.staticType.toString(), '(int) → String');
+
+ {
+ FunctionType type = p.identifier.staticType;
+ expect(type.returnType, typeProvider.stringType);
+
+ expect(type.parameters, hasLength(1));
+ expect(type.parameters[0].type, typeProvider.intType);
+ }
+
+ _assertTypeNameSimple(p.type, typeProvider.stringType);
+
+ {
+ SimpleFormalParameter a = p.parameters.parameters[0];
+ _assertTypeNameSimple(a.type, typeProvider.intType);
+ expect(a.identifier.staticType, typeProvider.intType);
+ }
+ }
+
+ test_formalParameter_simple_fieldFormal() async {
+ addTestFile(r'''
+class A {
+ int f;
+ A(this.f);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration clazz = result.unit.declarations[0];
+
+ FieldDeclaration fDeclaration = clazz.members[0];
+ VariableDeclaration fNode = fDeclaration.fields.variables[0];
+ FieldElement fElement = fNode.element;
+
+ ConstructorDeclaration constructor = clazz.members[1];
+ List<FormalParameter> parameters = constructor.parameters.parameters;
+
+ FieldFormalParameterElement parameterElement =
+ constructor.element.parameters[0];
+ expect(parameterElement.field, same(fElement));
+
+ FieldFormalParameter parameterNode = parameters[0];
+ expect(parameterNode.type, isNull);
+ expect(parameterNode.element, same(parameterElement));
+
+ expect(parameterNode.identifier.staticElement, same(parameterElement));
+ expect(parameterNode.identifier.staticType, typeProvider.intType);
+ }
+
+ test_formalParameter_simple_fieldFormal_typed() async {
+ addTestFile(r'''
+class A {
+ int f;
+ A(int this.f);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration clazz = result.unit.declarations[0];
+
+ FieldDeclaration fDeclaration = clazz.members[0];
+ VariableDeclaration fNode = fDeclaration.fields.variables[0];
+ FieldElement fElement = fNode.element;
+
+ ConstructorDeclaration constructor = clazz.members[1];
+ List<FormalParameter> parameters = constructor.parameters.parameters;
+
+ FieldFormalParameterElement parameterElement =
+ constructor.element.parameters[0];
+ expect(parameterElement.field, same(fElement));
+
+ FieldFormalParameter parameterNode = parameters[0];
+ _assertTypeNameSimple(parameterNode.type, typeProvider.intType);
+ expect(parameterNode.element, same(parameterElement));
+
+ expect(parameterNode.identifier.staticElement, same(parameterElement));
+ expect(parameterNode.identifier.staticType, typeProvider.intType);
+ }
+
+ test_forwardingStub_class() async {
+ addTestFile(r'''
+class A<T> {
+ void m(T t) {}
+}
+class B extends A<int> {}
+main(B b) {
+ b.m(1);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ ClassDeclaration aNode = result.unit.declarations[0];
+ ClassElement eElement = aNode.element;
+ MethodElement mElement = eElement.getMethod('m');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ expect(invocation.staticInvokeType.toString(), '(int) → void');
+ if (useCFE) {
+ expect(invocation.methodName.staticElement, same(mElement));
+ }
+ }
+
+ test_functionExpressionInvocation() async {
+ addTestFile(r'''
+typedef Foo<S> = S Function<T>(T x);
+void main(f) {
+ (f as Foo<int>)<String>('hello');
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ ExpressionStatement statement = statements[0];
+ FunctionExpressionInvocation invocation = statement.expression;
+
+ expect(invocation.staticElement, isNull);
+ expect(invocation.staticInvokeType.toString(), '(String) → int');
+ expect(invocation.staticType, typeProvider.intType);
+
+ List<TypeAnnotation> typeArguments = invocation.typeArguments.arguments;
+ expect(typeArguments, hasLength(1));
+ _assertTypeNameSimple(typeArguments[0], typeProvider.stringType);
+ }
+
+ test_indexExpression() async {
+ String content = r'''
+main() {
+ var items = <int>[1, 2, 3];
+ items[0];
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+
+ var typeProvider = unit.element.context.typeProvider;
+ InterfaceType intType = typeProvider.intType;
+ InterfaceType listType = typeProvider.listType;
+ InterfaceType listIntType = listType.instantiate([intType]);
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement itemsElement;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ VariableDeclaration itemsNode = statement.variables.variables[0];
+ itemsElement = itemsNode.element;
+ expect(itemsElement.type, listIntType);
+ }
+
+ ExpressionStatement statement = mainStatements[1];
+ IndexExpression indexExpression = statement.expression;
+ expect(indexExpression.staticType, intType);
+
+ MethodMember actualElement = indexExpression.staticElement;
+ MethodMember expectedElement = listIntType.getMethod('[]');
+ expect(actualElement.name, '[]');
+ expect(actualElement.baseElement, same(expectedElement.baseElement));
+ expect(actualElement.returnType, intType);
+ expect(actualElement.parameters[0].type, intType);
+ }
+
+ test_instanceCreation_factory() async {
+ String content = r'''
+class C {
+ factory C() => null;
+ factory C.named() => null;
+}
+var a = new C();
+var b = new C.named();
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+
+ ClassDeclaration cNode = unit.declarations[0];
+ ClassElement cElement = cNode.element;
+ ConstructorElement defaultConstructor = cElement.constructors[0];
+ ConstructorElement namedConstructor = cElement.constructors[1];
+
+ {
+ TopLevelVariableDeclaration aDeclaration = unit.declarations[1];
+ VariableDeclaration aNode = aDeclaration.variables.variables[0];
+ InstanceCreationExpression value = aNode.initializer;
+ expect(value.staticElement, defaultConstructor);
+ expect(value.staticType, cElement.type);
+
+ TypeName typeName = value.constructorName.type;
+ expect(typeName.typeArguments, isNull);
+
+ Identifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, cElement);
+ expect(typeIdentifier.staticType, cElement.type);
+
+ expect(value.constructorName.name, isNull);
+ }
+
+ {
+ TopLevelVariableDeclaration bDeclaration = unit.declarations[2];
+ VariableDeclaration bNode = bDeclaration.variables.variables[0];
+ InstanceCreationExpression value = bNode.initializer;
+ expect(value.staticElement, namedConstructor);
+ expect(value.staticType, cElement.type);
+
+ TypeName typeName = value.constructorName.type;
+ expect(typeName.typeArguments, isNull);
+
+ SimpleIdentifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, cElement);
+ expect(typeIdentifier.staticType, cElement.type);
+
+ SimpleIdentifier constructorName = value.constructorName.name;
+ expect(constructorName.staticElement, namedConstructor);
+ expect(constructorName.staticType, isNull);
+ }
+ }
+
+ test_instanceCreation_namedArgument() async {
+ addTestFile(r'''
+class X {
+ X(int a, {bool b, double c});
+}
+var v = new X(1, b: true, c: 3.0);
+''');
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+
+ ClassDeclaration xNode = unit.declarations[0];
+ ClassElement xElement = xNode.element;
+ ConstructorElement constructorElement = xElement.constructors[0];
+
+ TopLevelVariableDeclaration vDeclaration = unit.declarations[1];
+ VariableDeclaration vNode = vDeclaration.variables.variables[0];
+
+ InstanceCreationExpression creation = vNode.initializer;
+ List<Expression> arguments = creation.argumentList.arguments;
+ expect(creation.staticElement, constructorElement);
+ expect(creation.staticType, xElement.type);
+
+ TypeName typeName = creation.constructorName.type;
+ expect(typeName.typeArguments, isNull);
+
+ Identifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, xElement);
+ expect(typeIdentifier.staticType, xElement.type);
+
+ expect(creation.constructorName.name, isNull);
+
+ _assertArgumentToParameter(arguments[0], constructorElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], constructorElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], constructorElement.parameters[2]);
+ }
+
+ test_instanceCreation_noTypeArguments() async {
+ String content = r'''
+class C {
+ C(int p);
+ C.named(int p);
+}
+var a = new C(1);
+var b = new C.named(2);
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+
+ ClassDeclaration cNode = unit.declarations[0];
+ ClassElement cElement = cNode.element;
+ ConstructorElement defaultConstructor = cElement.constructors[0];
+ ConstructorElement namedConstructor = cElement.constructors[1];
+
+ {
+ TopLevelVariableDeclaration aDeclaration = unit.declarations[1];
+ VariableDeclaration aNode = aDeclaration.variables.variables[0];
+ InstanceCreationExpression value = aNode.initializer;
+ expect(value.staticElement, defaultConstructor);
+ expect(value.staticType, cElement.type);
+
+ TypeName typeName = value.constructorName.type;
+ expect(typeName.typeArguments, isNull);
+
+ Identifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, cElement);
+ expect(typeIdentifier.staticType, cElement.type);
+
+ expect(value.constructorName.name, isNull);
+
+ Expression argument = value.argumentList.arguments[0];
+ _assertArgumentToParameter(argument, defaultConstructor.parameters[0]);
+ }
+
+ {
+ TopLevelVariableDeclaration bDeclaration = unit.declarations[2];
+ VariableDeclaration bNode = bDeclaration.variables.variables[0];
+ InstanceCreationExpression value = bNode.initializer;
+ expect(value.staticElement, namedConstructor);
+ expect(value.staticType, cElement.type);
+
+ TypeName typeName = value.constructorName.type;
+ expect(typeName.typeArguments, isNull);
+
+ SimpleIdentifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, cElement);
+ expect(typeIdentifier.staticType, cElement.type);
+
+ SimpleIdentifier constructorName = value.constructorName.name;
+ expect(constructorName.staticElement, namedConstructor);
+ expect(constructorName.staticType, isNull);
+
+ Expression argument = value.argumentList.arguments[0];
+ _assertArgumentToParameter(argument, namedConstructor.parameters[0]);
+ }
+ }
+
+ test_instanceCreation_prefixed() async {
+ var a = _p('/test/lib/a.dart');
+ provider.newFile(a, r'''
+class C<T> {
+ C(T p);
+ C.named(T p);
+}
+''');
+ addTestFile(r'''
+import 'a.dart' as p;
+main() {
+ new p.C(0);
+ new p.C.named(1.2);
+ new p.C<bool>.named(false);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ImportElement aImport = unit.element.library.imports[0];
+ LibraryElement aLibrary = aImport.importedLibrary;
+
+ ClassElement cElement = aLibrary.getType('C');
+ ConstructorElement defaultConstructor = cElement.constructors[0];
+ ConstructorElement namedConstructor = cElement.constructors[1];
+ InterfaceType cType = cElement.type;
+ var cTypeDynamic = cType.instantiate([DynamicTypeImpl.instance]);
+
+ var statements = _getMainStatements(result);
+ {
+ var cTypeInt = cType.instantiate([typeProvider.intType]);
+
+ ExpressionStatement statement = statements[0];
+ InstanceCreationExpression creation = statement.expression;
+ expect(creation.staticElement, defaultConstructor);
+ expect(creation.staticType, cTypeInt);
+
+ TypeName typeName = creation.constructorName.type;
+ expect(typeName.typeArguments, isNull);
+
+ PrefixedIdentifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, same(cElement));
+ if (useCFE) {
+ expect(typeIdentifier.staticType, cTypeInt);
+ } else {
+ expect(typeIdentifier.staticType, cTypeDynamic);
+ }
+
+ SimpleIdentifier typePrefix = typeIdentifier.prefix;
+ expect(typePrefix.name, 'p');
+ expect(typePrefix.staticElement, same(aImport.prefix));
+ expect(typePrefix.staticType, isNull);
+
+ expect(typeIdentifier.identifier.staticElement, same(cElement));
+
+ expect(creation.constructorName.name, isNull);
+ }
+
+ {
+ var cTypeDouble = cType.instantiate([typeProvider.doubleType]);
+
+ ExpressionStatement statement = statements[1];
+ InstanceCreationExpression creation = statement.expression;
+ expect(creation.staticElement, namedConstructor);
+ expect(creation.staticType, cTypeDouble);
+
+ TypeName typeName = creation.constructorName.type;
+ expect(typeName.typeArguments, isNull);
+
+ PrefixedIdentifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, cElement);
+ if (useCFE) {
+ expect(typeIdentifier.staticType, cTypeDouble);
+ } else {
+ expect(typeIdentifier.staticType, cTypeDynamic);
+ }
+
+ SimpleIdentifier typePrefix = typeIdentifier.prefix;
+ expect(typePrefix.name, 'p');
+ expect(typePrefix.staticElement, same(aImport.prefix));
+ expect(typePrefix.staticType, isNull);
+
+ expect(typeIdentifier.identifier.staticElement, same(cElement));
+
+ SimpleIdentifier constructorName = creation.constructorName.name;
+ expect(constructorName.staticElement, namedConstructor);
+ expect(constructorName.staticType, isNull);
+ }
+
+ {
+ var cTypeBool = cType.instantiate([typeProvider.boolType]);
+
+ ExpressionStatement statement = statements[2];
+ InstanceCreationExpression creation = statement.expression;
+ expect(creation.staticElement, namedConstructor);
+ expect(creation.staticType, cTypeBool);
+
+ TypeName typeName = creation.constructorName.type;
+ expect(typeName.typeArguments.arguments, hasLength(1));
+ _assertTypeNameSimple(
+ typeName.typeArguments.arguments[0], typeProvider.boolType);
+
+ PrefixedIdentifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, cElement);
+ expect(typeIdentifier.staticType, cTypeBool);
+
+ SimpleIdentifier typePrefix = typeIdentifier.prefix;
+ expect(typePrefix.name, 'p');
+ expect(typePrefix.staticElement, same(aImport.prefix));
+ expect(typePrefix.staticType, isNull);
+
+ expect(typeIdentifier.identifier.staticElement, same(cElement));
+
+ SimpleIdentifier constructorName = creation.constructorName.name;
+ expect(constructorName.staticElement, namedConstructor);
+ expect(constructorName.staticType, isNull);
+ }
+ }
+
+ test_instanceCreation_withTypeArguments() async {
+ String content = r'''
+class C<K, V> {
+ C(K k, V v);
+ C.named(K k, V v);
+}
+var a = new C<int, double>(1, 2.3);
+var b = new C<num, String>.named(4, 'five');
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cNode = unit.declarations[0];
+ ClassElement cElement = cNode.element;
+ ConstructorElement defaultConstructor = cElement.constructors[0];
+ ConstructorElement namedConstructor = cElement.constructors[1];
+
+ {
+ TopLevelVariableDeclaration aDeclaration = unit.declarations[1];
+ VariableDeclaration aNode = aDeclaration.variables.variables[0];
+
+ InstanceCreationExpression value = aNode.initializer;
+ InterfaceType instantiatedType = cElement.type
+ .instantiate([typeProvider.intType, typeProvider.doubleType]);
+
+ expect(value.staticElement, defaultConstructor);
+ expect(value.staticType, instantiatedType);
+
+ TypeName typeName = value.constructorName.type;
+
+ Identifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, cElement);
+ expect(typeIdentifier.staticType, instantiatedType);
+
+ TypeName typeArgument1 = typeName.typeArguments.arguments[0];
+ expect(typeArgument1.type, typeProvider.intType);
+ expect(typeArgument1.name.staticType, typeProvider.intType);
+ expect(typeArgument1.name.staticElement, typeProvider.intType.element);
+
+ TypeName typeArgument2 = typeName.typeArguments.arguments[1];
+ expect(typeArgument2.type, typeProvider.doubleType);
+ expect(typeArgument2.name.staticType, typeProvider.doubleType);
+ expect(typeArgument2.name.staticElement, typeProvider.doubleType.element);
+
+ expect(value.constructorName.name, isNull);
+
+ Expression argument = value.argumentList.arguments[0];
+ _assertArgumentToParameter(argument, defaultConstructor.parameters[0]);
+ }
+
+ {
+ TopLevelVariableDeclaration bDeclaration = unit.declarations[2];
+ VariableDeclaration bNode = bDeclaration.variables.variables[0];
+
+ InstanceCreationExpression value = bNode.initializer;
+ InterfaceType instantiatedType = cElement.type
+ .instantiate([typeProvider.numType, typeProvider.stringType]);
+
+ expect(value.staticElement, namedConstructor);
+ expect(value.staticType, instantiatedType);
+
+ TypeName typeName = value.constructorName.type;
+
+ SimpleIdentifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, cElement);
+ expect(typeIdentifier.staticType, instantiatedType);
+
+ TypeName typeArgument1 = typeName.typeArguments.arguments[0];
+ expect(typeArgument1.type, typeProvider.numType);
+ expect(typeArgument1.name.staticType, typeProvider.numType);
+ expect(typeArgument1.name.staticElement, typeProvider.numType.element);
+
+ TypeName typeArgument2 = typeName.typeArguments.arguments[1];
+ expect(typeArgument2.type, typeProvider.stringType);
+ expect(typeArgument2.name.staticType, typeProvider.stringType);
+ expect(typeArgument2.name.staticElement, typeProvider.stringType.element);
+
+ SimpleIdentifier constructorName = value.constructorName.name;
+ expect(constructorName.staticElement, namedConstructor);
+ expect(constructorName.staticType, isNull);
+
+ Expression argument = value.argumentList.arguments[0];
+ _assertArgumentToParameter(argument, namedConstructor.parameters[0]);
+ }
+ }
+
+ test_isExpression() async {
+ String content = r'''
+void main() {
+ var v = 42;
+ v is num;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.path, testFile);
+ expect(result.errors, isEmpty);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ NodeList<Statement> statements = _getMainStatements(result);
+
+ // var v = 42;
+ VariableElement vElement;
+ {
+ VariableDeclarationStatement statement = statements[0];
+ vElement = statement.variables.variables[0].name.staticElement;
+ }
+
+ // v is num;
+ {
+ ExpressionStatement statement = statements[1];
+ IsExpression isExpression = statement.expression;
+ expect(isExpression.notOperator, isNull);
+ expect(isExpression.staticType, typeProvider.boolType);
+
+ SimpleIdentifier target = isExpression.expression;
+ expect(target.staticElement, vElement);
+ expect(target.staticType, typeProvider.intType);
+
+ TypeName numName = isExpression.type;
+ expect(numName.name.staticElement, typeProvider.numType.element);
+ expect(numName.name.staticType, typeProvider.numType);
+ }
+ }
+
+ test_isExpression_not() async {
+ String content = r'''
+void main() {
+ var v = 42;
+ v is! num;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.path, testFile);
+ expect(result.errors, isEmpty);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ NodeList<Statement> statements = _getMainStatements(result);
+
+ // var v = 42;
+ VariableElement vElement;
+ {
+ VariableDeclarationStatement statement = statements[0];
+ vElement = statement.variables.variables[0].name.staticElement;
+ }
+
+ // v is! num;
+ {
+ ExpressionStatement statement = statements[1];
+ IsExpression isExpression = statement.expression;
+ expect(isExpression.notOperator, isNotNull);
+ expect(isExpression.staticType, typeProvider.boolType);
+
+ SimpleIdentifier target = isExpression.expression;
+ expect(target.staticElement, vElement);
+ expect(target.staticType, typeProvider.intType);
+
+ TypeName numName = isExpression.type;
+ expect(numName.name.staticElement, typeProvider.numType.element);
+ expect(numName.name.staticType, typeProvider.numType);
+ }
+ }
+
+ test_label_while() async {
+ addTestFile(r'''
+main() {
+ myLabel:
+ while (true) {
+ continue myLabel;
+ break myLabel;
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ List<Statement> statements = _getMainStatements(result);
+
+ LabeledStatement statement = statements[0];
+
+ Label label = statement.labels.single;
+ LabelElement labelElement = label.label.staticElement;
+
+ WhileStatement whileStatement = statement.statement;
+ Block whileBlock = whileStatement.body;
+
+ ContinueStatement continueStatement = whileBlock.statements[0];
+ expect(continueStatement.label.staticElement, same(labelElement));
+ expect(continueStatement.label.staticType, isNull);
+
+ BreakStatement breakStatement = whileBlock.statements[1];
+ expect(breakStatement.label.staticElement, same(labelElement));
+ expect(breakStatement.label.staticType, isNull);
+ }
+
+ test_local_function() async {
+ addTestFile(r'''
+void main() {
+ double f(int a, String b) {}
+ var v = f(1, '2');
+}
+''');
+ String fTypeString = '(int, String) → double';
+
+ AnalysisResult result = await driver.getResult(testFile);
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ InterfaceType doubleType = typeProvider.doubleType;
+
+ FunctionDeclarationStatement fStatement = mainStatements[0];
+ FunctionDeclaration fNode = fStatement.functionDeclaration;
+ FunctionExpression fExpression = fNode.functionExpression;
+ FunctionElement fElement = fNode.element;
+ expect(fElement, isNotNull);
+ expect(fElement.type.toString(), fTypeString);
+
+ expect(fNode.name.staticElement, same(fElement));
+ expect(fNode.name.staticType, fElement.type);
+
+ TypeName fReturnTypeNode = fNode.returnType;
+ expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
+ expect(fReturnTypeNode.type, doubleType);
+
+ expect(fExpression.element, same(fElement));
+
+ {
+ List<ParameterElement> elements = fElement.parameters;
+ expect(elements, hasLength(2));
+
+ List<FormalParameter> nodes = fExpression.parameters.parameters;
+ expect(nodes, hasLength(2));
+
+ _assertSimpleParameter(nodes[0], elements[0],
+ name: 'a',
+ offset: 29,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.intType);
+
+ _assertSimpleParameter(nodes[1], elements[1],
+ name: 'b',
+ offset: 39,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.stringType);
+ }
+
+ VariableDeclarationStatement vStatement = mainStatements[1];
+ VariableDeclaration vDeclaration = vStatement.variables.variables[0];
+ expect(vDeclaration.element.type, same(doubleType));
+
+ MethodInvocation fInvocation = vDeclaration.initializer;
+ expect(fInvocation.methodName.staticElement, same(fElement));
+ expect(fInvocation.methodName.staticType.toString(), fTypeString);
+ expect(fInvocation.staticType, same(doubleType));
+ expect(fInvocation.staticInvokeType.toString(), fTypeString);
+ }
+
+ test_local_function_generic() async {
+ addTestFile(r'''
+void main() {
+ T f<T, U>(T a, U b) {}
+ var v = f(1, '2');
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ FunctionDeclarationStatement fStatement = mainStatements[0];
+ FunctionDeclaration fNode = fStatement.functionDeclaration;
+ FunctionExpression fExpression = fNode.functionExpression;
+ FunctionElement fElement = fNode.element;
+
+ TypeParameterElement tElement = fElement.typeParameters[0];
+ TypeParameterElement uElement = fElement.typeParameters[1];
+
+ {
+ var fTypeParameters = fExpression.typeParameters.typeParameters;
+ expect(fTypeParameters, hasLength(2));
+
+ TypeParameter tNode = fTypeParameters[0];
+ expect(tNode.element, same(tElement));
+ expect(tNode.name.staticElement, same(tElement));
+ expect(tNode.name.staticType, typeProvider.typeType);
+
+ TypeParameter uNode = fTypeParameters[1];
+ expect(uNode.element, same(uElement));
+ expect(uNode.name.staticElement, same(uElement));
+ expect(uNode.name.staticType, typeProvider.typeType);
+ }
+
+ expect(fElement, isNotNull);
+ expect(fElement.type.toString(), '<T,U>(T, U) → T');
+
+ expect(fNode.name.staticElement, same(fElement));
+ expect(fNode.name.staticType, fElement.type);
+
+ TypeName fReturnTypeNode = fNode.returnType;
+ expect(fReturnTypeNode.name.staticElement, same(tElement));
+ expect(fReturnTypeNode.type, tElement.type);
+
+ expect(fExpression.element, same(fElement));
+
+ {
+ List<ParameterElement> elements = fElement.parameters;
+ expect(elements, hasLength(2));
+
+ List<FormalParameter> nodes = fExpression.parameters.parameters;
+ expect(nodes, hasLength(2));
+
+ _assertSimpleParameter(nodes[0], elements[0],
+ name: 'a',
+ offset: 28,
+ kind: ParameterKind.REQUIRED,
+ type: tElement.type);
+
+ _assertSimpleParameter(nodes[1], elements[1],
+ name: 'b',
+ offset: 33,
+ kind: ParameterKind.REQUIRED,
+ type: uElement.type);
+ }
+
+ VariableDeclarationStatement vStatement = mainStatements[1];
+ VariableDeclaration vDeclaration = vStatement.variables.variables[0];
+ expect(vDeclaration.element.type, typeProvider.intType);
+
+ MethodInvocation fInvocation = vDeclaration.initializer;
+ expect(fInvocation.methodName.staticElement, same(fElement));
+ expect(fInvocation.staticType, typeProvider.intType);
+ // TODO(scheglov) We don't support invoke types well.
+// if (useCFE) {
+// String fInstantiatedType = '(int, String) → int';
+// expect(fInvocation.methodName.staticType.toString(), fInstantiatedType);
+// expect(fInvocation.staticInvokeType.toString(), fInstantiatedType);
+// }
+ }
+
+ test_local_function_namedParameters() async {
+ addTestFile(r'''
+void main() {
+ double f(int a, {String b, bool c: false}) {}
+ f(1, b: '2', c: true);
+}
+''');
+ String fTypeString = '(int, {b: String, c: bool}) → double';
+
+ AnalysisResult result = await driver.getResult(testFile);
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ InterfaceType doubleType = typeProvider.doubleType;
+
+ FunctionDeclarationStatement fStatement = mainStatements[0];
+ FunctionDeclaration fNode = fStatement.functionDeclaration;
+ FunctionExpression fExpression = fNode.functionExpression;
+ FunctionElement fElement = fNode.element;
+ expect(fElement, isNotNull);
+ expect(fElement.type.toString(), fTypeString);
+
+ expect(fNode.name.staticElement, same(fElement));
+ expect(fNode.name.staticType, fElement.type);
+
+ TypeName fReturnTypeNode = fNode.returnType;
+ expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
+ expect(fReturnTypeNode.type, doubleType);
+
+ expect(fExpression.element, same(fElement));
+
+ {
+ List<ParameterElement> elements = fElement.parameters;
+ expect(elements, hasLength(3));
+
+ List<FormalParameter> nodes = fExpression.parameters.parameters;
+ expect(nodes, hasLength(3));
+
+ _assertSimpleParameter(nodes[0], elements[0],
+ name: 'a',
+ offset: 29,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.intType);
+
+ _assertDefaultParameter(nodes[1], elements[1],
+ name: 'b',
+ offset: 40,
+ kind: ParameterKind.NAMED,
+ type: typeProvider.stringType);
+
+ _assertDefaultParameter(nodes[2], elements[2],
+ name: 'c',
+ offset: 48,
+ kind: ParameterKind.NAMED,
+ type: typeProvider.boolType);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+ MethodInvocation invocation = statement.expression;
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
+ }
+ }
+
+ test_local_function_noReturnType() async {
+ addTestFile(r'''
+void main() {
+ f() {}
+}
+''');
+
+ AnalysisResult result = await driver.getResult(testFile);
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ FunctionDeclarationStatement fStatement = mainStatements[0];
+ FunctionDeclaration fNode = fStatement.functionDeclaration;
+ FunctionExpression fExpression = fNode.functionExpression;
+ FunctionElement fElement = fNode.element;
+
+ expect(fNode.returnType, isNull);
+ expect(fElement, isNotNull);
+ expect(fElement.type.toString(), '() → Null');
+
+ expect(fNode.name.staticElement, same(fElement));
+ expect(fNode.name.staticType, fElement.type);
+
+ expect(fExpression.element, same(fElement));
+ }
+
+ test_local_function_optionalParameters() async {
+ addTestFile(r'''
+void main() {
+ double f(int a, [String b, bool c]) {}
+ var v = f(1, '2', true);
+}
+''');
+ String fTypeString = '(int, [String, bool]) → double';
+
+ AnalysisResult result = await driver.getResult(testFile);
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ InterfaceType doubleType = typeProvider.doubleType;
+
+ FunctionDeclarationStatement fStatement = mainStatements[0];
+ FunctionDeclaration fNode = fStatement.functionDeclaration;
+ FunctionExpression fExpression = fNode.functionExpression;
+ FunctionElement fElement = fNode.element;
+ expect(fElement, isNotNull);
+ expect(fElement.type.toString(), fTypeString);
+
+ expect(fNode.name.staticElement, same(fElement));
+ expect(fNode.name.staticType, fElement.type);
+
+ TypeName fReturnTypeNode = fNode.returnType;
+ expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
+ expect(fReturnTypeNode.type, doubleType);
+
+ expect(fExpression.element, same(fElement));
+
+ {
+ List<ParameterElement> elements = fElement.parameters;
+ expect(elements, hasLength(3));
+
+ List<FormalParameter> nodes = fExpression.parameters.parameters;
+ expect(nodes, hasLength(3));
+
+ _assertSimpleParameter(nodes[0], elements[0],
+ name: 'a',
+ offset: 29,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.intType);
+
+ _assertDefaultParameter(nodes[1], elements[1],
+ name: 'b',
+ offset: 40,
+ kind: ParameterKind.POSITIONAL,
+ type: typeProvider.stringType);
+
+ _assertDefaultParameter(nodes[2], elements[2],
+ name: 'c',
+ offset: 48,
+ kind: ParameterKind.POSITIONAL,
+ type: typeProvider.boolType);
+ }
+
+ {
+ VariableDeclarationStatement statement = mainStatements[1];
+ VariableDeclaration declaration = statement.variables.variables[0];
+ expect(declaration.element.type, same(doubleType));
+
+ MethodInvocation invocation = declaration.initializer;
+ expect(invocation.methodName.staticElement, same(fElement));
+ expect(invocation.methodName.staticType.toString(), fTypeString);
+ expect(invocation.staticType, same(doubleType));
+ expect(invocation.staticInvokeType.toString(), fTypeString);
+
+ List<Expression> arguments = invocation.argumentList.arguments;
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
+ }
+ }
+
+ test_local_parameter() async {
+ String content = r'''
+void main(int p) {
+ p;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.path, testFile);
+ expect(result.errors, isEmpty);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ InterfaceType intType = typeProvider.intType;
+
+ FunctionDeclaration main = result.unit.declarations[0];
+ List<Statement> statements = _getMainStatements(result);
+
+ // (int p)
+ VariableElement pElement = main.element.parameters[0];
+ expect(pElement.type, intType);
+
+ // p;
+ {
+ ExpressionStatement statement = statements[0];
+ SimpleIdentifier identifier = statement.expression;
+ expect(identifier.staticElement, pElement);
+ expect(identifier.staticType, intType);
+ }
+ }
+
+ test_local_parameter_ofLocalFunction() async {
+ addTestFile(r'''
+void main() {
+ void f(int a) {
+ a;
+ void g(double b) {
+ b;
+ }
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ // f(int a) {}
+ FunctionDeclarationStatement fStatement = mainStatements[0];
+ FunctionDeclaration fNode = fStatement.functionDeclaration;
+ FunctionExpression fExpression = fNode.functionExpression;
+ FunctionElement fElement = fNode.element;
+ ParameterElement aElement = fElement.parameters[0];
+ _assertSimpleParameter(fExpression.parameters.parameters[0], aElement,
+ name: 'a',
+ offset: 27,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.intType);
+
+ BlockFunctionBody fBody = fExpression.body;
+ List<Statement> fStatements = fBody.block.statements;
+
+ // a;
+ ExpressionStatement aStatement = fStatements[0];
+ SimpleIdentifier aNode = aStatement.expression;
+ expect(aNode.staticElement, same(aElement));
+ expect(aNode.staticType, typeProvider.intType);
+
+ // g(double b) {}
+ FunctionDeclarationStatement gStatement = fStatements[1];
+ FunctionDeclaration gNode = gStatement.functionDeclaration;
+ FunctionExpression gExpression = gNode.functionExpression;
+ FunctionElement gElement = gNode.element;
+ ParameterElement bElement = gElement.parameters[0];
+ _assertSimpleParameter(gExpression.parameters.parameters[0], bElement,
+ name: 'b',
+ offset: 57,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.doubleType);
+
+ BlockFunctionBody gBody = gExpression.body;
+ List<Statement> gStatements = gBody.block.statements;
+
+ // b;
+ ExpressionStatement bStatement = gStatements[0];
+ SimpleIdentifier bNode = bStatement.expression;
+ expect(bNode.staticElement, same(bElement));
+ expect(bNode.staticType, typeProvider.doubleType);
+ }
+
+ test_local_variable() async {
+ addTestFile(r'''
+void main() {
+ var v = 42;
+ v;
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.path, testFile);
+ expect(result.errors, isEmpty);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ InterfaceType intType = typeProvider.intType;
+
+ FunctionDeclaration main = result.unit.declarations[0];
+ expect(main.element, isNotNull);
+ expect(main.name.staticElement, isNotNull);
+ expect(main.name.staticType.toString(), '() → void');
+
+ BlockFunctionBody body = main.functionExpression.body;
+ NodeList<Statement> statements = body.block.statements;
+
+ // var v = 42;
+ VariableElement vElement;
+ {
+ VariableDeclarationStatement statement = statements[0];
+ VariableDeclaration vNode = statement.variables.variables[0];
+ expect(vNode.name.staticType, intType);
+ expect(vNode.initializer.staticType, intType);
+
+ vElement = vNode.name.staticElement;
+ expect(vElement, isNotNull);
+ expect(vElement.type, isNotNull);
+ expect(vElement.type, intType);
+ }
+
+ // v;
+ {
+ ExpressionStatement statement = statements[1];
+ SimpleIdentifier identifier = statement.expression;
+ expect(identifier.staticElement, same(vElement));
+ expect(identifier.staticType, intType);
+ }
+ }
+
+ test_local_variable_forIn_identifier_field() async {
+ addTestFile(r'''
+class C {
+ num v;
+ void foo() {
+ for (v in <int>[]) {
+ v;
+ }
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cDeclaration = unit.declarations[0];
+
+ FieldDeclaration vDeclaration = cDeclaration.members[0];
+ VariableDeclaration vNode = vDeclaration.fields.variables[0];
+ FieldElement vElement = vNode.element;
+ expect(vElement.type, typeProvider.numType);
+
+ MethodDeclaration fooDeclaration = cDeclaration.members[1];
+ BlockFunctionBody fooBody = fooDeclaration.body;
+ List<Statement> statements = fooBody.block.statements;
+
+ ForEachStatement forEachStatement = statements[0];
+ Block forBlock = forEachStatement.body;
+
+ expect(forEachStatement.loopVariable, isNull);
+
+ SimpleIdentifier vInFor = forEachStatement.identifier;
+ expect(vInFor.staticElement, same(vElement.setter));
+ expect(vInFor.staticType, typeProvider.numType);
+
+ ExpressionStatement statement = forBlock.statements[0];
+ SimpleIdentifier identifier = statement.expression;
+ expect(identifier.staticElement, same(vElement.getter));
+ expect(identifier.staticType, typeProvider.numType);
+ }
+
+ test_local_variable_forIn_identifier_localVariable() async {
+ addTestFile(r'''
+void main() {
+ num v;
+ for (v in <int>[]) {
+ v;
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ VariableDeclarationStatement vStatement = statements[0];
+ VariableDeclaration vNode = vStatement.variables.variables[0];
+ LocalVariableElement vElement = vNode.element;
+ expect(vElement.type, typeProvider.numType);
+
+ ForEachStatement forEachStatement = statements[1];
+ Block forBlock = forEachStatement.body;
+
+ expect(forEachStatement.loopVariable, isNull);
+
+ SimpleIdentifier vInFor = forEachStatement.identifier;
+ expect(vInFor.staticElement, vElement);
+ expect(vInFor.staticType, typeProvider.numType);
+
+ ExpressionStatement statement = forBlock.statements[0];
+ SimpleIdentifier identifier = statement.expression;
+ expect(identifier.staticElement, same(vElement));
+ expect(identifier.staticType, typeProvider.numType);
+ }
+
+ test_local_variable_forIn_identifier_topLevelVariable() async {
+ addTestFile(r'''
+void main() {
+ for (v in <int>[]) {
+ v;
+ }
+}
+num v;
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ TopLevelVariableDeclaration vDeclaration = unit.declarations[1];
+ VariableDeclaration vNode = vDeclaration.variables.variables[0];
+ TopLevelVariableElement vElement = vNode.element;
+ expect(vElement.type, typeProvider.numType);
+
+ ForEachStatement forEachStatement = statements[0];
+ Block forBlock = forEachStatement.body;
+
+ expect(forEachStatement.loopVariable, isNull);
+
+ SimpleIdentifier vInFor = forEachStatement.identifier;
+ expect(vInFor.staticElement, same(vElement.setter));
+ expect(vInFor.staticType, typeProvider.numType);
+
+ ExpressionStatement statement = forBlock.statements[0];
+ SimpleIdentifier identifier = statement.expression;
+ expect(identifier.staticElement, same(vElement.getter));
+ expect(identifier.staticType, typeProvider.numType);
+ }
+
+ test_local_variable_forIn_loopVariable() async {
+ addTestFile(r'''
+void main() {
+ for (var v in <int>[]) {
+ v;
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ ForEachStatement forEachStatement = statements[0];
+ Block forBlock = forEachStatement.body;
+
+ DeclaredIdentifier vNode = forEachStatement.loopVariable;
+ LocalVariableElement vElement = vNode.element;
+ expect(vElement.type, typeProvider.intType);
+
+ expect(vNode.identifier.staticElement, vElement);
+ expect(vNode.identifier.staticType, typeProvider.intType);
+
+ ExpressionStatement statement = forBlock.statements[0];
+ SimpleIdentifier identifier = statement.expression;
+ expect(identifier.staticElement, vElement);
+ expect(identifier.staticType, typeProvider.intType);
+ }
+
+ test_local_variable_forIn_loopVariable_explicitType() async {
+ addTestFile(r'''
+void main() {
+ for (num v in <int>[]) {
+ v;
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ ForEachStatement forEachStatement = statements[0];
+ Block forBlock = forEachStatement.body;
+
+ DeclaredIdentifier vNode = forEachStatement.loopVariable;
+ LocalVariableElement vElement = vNode.element;
+ expect(vElement.type, typeProvider.numType);
+
+ TypeName vTypeName = vNode.type;
+ expect(vTypeName.type, typeProvider.numType);
+
+ SimpleIdentifier vTypeIdentifier = vTypeName.name;
+ expect(vTypeIdentifier.staticElement, typeProvider.numType.element);
+ expect(vTypeIdentifier.staticType, typeProvider.numType);
+
+ expect(vNode.identifier.staticElement, vElement);
+ expect(vNode.identifier.staticType, typeProvider.numType);
+
+ ExpressionStatement statement = forBlock.statements[0];
+ SimpleIdentifier identifier = statement.expression;
+ expect(identifier.staticElement, vElement);
+ expect(identifier.staticType, typeProvider.numType);
+ }
+
+ test_local_variable_multiple() async {
+ addTestFile(r'''
+void main() {
+ var a = 1, b = 2.3;
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ VariableDeclarationStatement declarationStatement = statements[0];
+
+ VariableDeclaration aNode = declarationStatement.variables.variables[0];
+ LocalVariableElement aElement = aNode.element;
+ expect(aElement.type, typeProvider.intType);
+
+ VariableDeclaration bNode = declarationStatement.variables.variables[1];
+ LocalVariableElement bElement = bNode.element;
+ expect(bElement.type, typeProvider.doubleType);
+ }
+
+ test_local_variable_ofLocalFunction() async {
+ addTestFile(r'''
+void main() {
+ void f() {
+ int a;
+ a;
+ void g() {
+ double b;
+ a;
+ b;
+ }
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ // f() {}
+ FunctionDeclarationStatement fStatement = mainStatements[0];
+ FunctionDeclaration fNode = fStatement.functionDeclaration;
+ BlockFunctionBody fBody = fNode.functionExpression.body;
+ List<Statement> fStatements = fBody.block.statements;
+
+ // int a;
+ VariableDeclarationStatement aDeclaration = fStatements[0];
+ VariableElement aElement = aDeclaration.variables.variables[0].element;
+
+ // a;
+ {
+ ExpressionStatement aStatement = fStatements[1];
+ SimpleIdentifier aNode = aStatement.expression;
+ expect(aNode.staticElement, same(aElement));
+ expect(aNode.staticType, typeProvider.intType);
+ }
+
+ // g(double b) {}
+ FunctionDeclarationStatement gStatement = fStatements[2];
+ FunctionDeclaration gNode = gStatement.functionDeclaration;
+ BlockFunctionBody gBody = gNode.functionExpression.body;
+ List<Statement> gStatements = gBody.block.statements;
+
+ // double b;
+ VariableDeclarationStatement bDeclaration = gStatements[0];
+ VariableElement bElement = bDeclaration.variables.variables[0].element;
+
+ // a;
+ {
+ ExpressionStatement aStatement = gStatements[1];
+ SimpleIdentifier aNode = aStatement.expression;
+ expect(aNode.staticElement, same(aElement));
+ expect(aNode.staticType, typeProvider.intType);
+ }
+
+ // b;
+ {
+ ExpressionStatement bStatement = gStatements[2];
+ SimpleIdentifier bNode = bStatement.expression;
+ expect(bNode.staticElement, same(bElement));
+ expect(bNode.staticType, typeProvider.doubleType);
+ }
+ }
+
+ test_mapLiteral() async {
+ addTestFile(r'''
+void main() {
+ <int, double>{};
+ const <bool, String>{};
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ var statements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = statements[0];
+ MapLiteral mapLiteral = statement.expression;
+ expect(
+ mapLiteral.staticType,
+ typeProvider.mapType
+ .instantiate([typeProvider.intType, typeProvider.doubleType]));
+ }
+
+ {
+ ExpressionStatement statement = statements[1];
+ MapLiteral mapLiteral = statement.expression;
+ expect(
+ mapLiteral.staticType,
+ typeProvider.mapType
+ .instantiate([typeProvider.boolType, typeProvider.stringType]));
+ }
+ }
+
+ test_method_namedParameters() async {
+ addTestFile(r'''
+class C {
+ double f(int a, {String b, bool c: false}) {}
+}
+void g(C c) {
+ c.f(1, b: '2', c: true);
+}
+''');
+ String fTypeString = '(int, {b: String, c: bool}) → double';
+
+ AnalysisResult result = await driver.getResult(testFile);
+ ClassDeclaration classDeclaration = result.unit.declarations[0];
+ MethodDeclaration methodDeclaration = classDeclaration.members[0];
+ MethodElement methodElement = methodDeclaration.element;
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ InterfaceType doubleType = typeProvider.doubleType;
+
+ expect(methodElement, isNotNull);
+ expect(methodElement.type.toString(), fTypeString);
+
+ expect(methodDeclaration.name.staticElement, same(methodElement));
+ expect(methodDeclaration.name.staticType, methodElement.type);
+
+ TypeName fReturnTypeNode = methodDeclaration.returnType;
+ expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
+ expect(fReturnTypeNode.type, doubleType);
+ //
+ // Validate the parameters at the declaration site.
+ //
+ List<ParameterElement> elements = methodElement.parameters;
+ expect(elements, hasLength(3));
+
+ List<FormalParameter> nodes = methodDeclaration.parameters.parameters;
+ expect(nodes, hasLength(3));
+
+ _assertSimpleParameter(nodes[0], elements[0],
+ name: 'a',
+ offset: 25,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.intType);
+
+ _assertDefaultParameter(nodes[1], elements[1],
+ name: 'b',
+ offset: 36,
+ kind: ParameterKind.NAMED,
+ type: typeProvider.stringType);
+
+ _assertDefaultParameter(nodes[2], elements[2],
+ name: 'c',
+ offset: 44,
+ kind: ParameterKind.NAMED,
+ type: typeProvider.boolType);
+ //
+ // Validate the arguments at the call site.
+ //
+ FunctionDeclaration functionDeclaration = result.unit.declarations[1];
+ BlockFunctionBody body = functionDeclaration.functionExpression.body;
+ ExpressionStatement statement = body.block.statements[0];
+ MethodInvocation invocation = statement.expression;
+
+ List<Expression> arguments = invocation.argumentList.arguments;
+ _assertArgumentToParameter(arguments[0], methodElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], methodElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], methodElement.parameters[2]);
+ }
+
+ test_methodInvocation_explicitCall_classTarget() async {
+ addTestFile(r'''
+class C {
+ double call(int p) => 0.0;
+}
+main() {
+ new C().call(0);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.errors, isEmpty);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration cNode = result.unit.declarations[0];
+ ClassElement cElement = cNode.element;
+ MethodElement callElement = cElement.methods[0];
+
+ List<Statement> statements = _getMainStatements(result);
+
+ ExpressionStatement statement = statements[0];
+ MethodInvocation invocation = statement.expression;
+
+ expect(invocation.staticType, typeProvider.doubleType);
+ expect(invocation.staticInvokeType.toString(), '(int) → double');
+
+ SimpleIdentifier methodName = invocation.methodName;
+ expect(methodName.staticElement, same(callElement));
+ expect(methodName.staticType.toString(), '(int) → double');
+ }
+
+ test_methodInvocation_explicitCall_functionTarget() async {
+ addTestFile(r'''
+main(double computation(int p)) {
+ computation.call(1);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.errors, isEmpty);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ FunctionDeclaration main = result.unit.declarations[0];
+ FunctionElement mainElement = main.element;
+ ParameterElement parameter = mainElement.parameters[0];
+
+ BlockFunctionBody mainBody = main.functionExpression.body;
+ List<Statement> statements = mainBody.block.statements;
+
+ ExpressionStatement statement = statements[0];
+ MethodInvocation invocation = statement.expression;
+
+ expect(invocation.staticType, typeProvider.doubleType);
+ expect(invocation.staticInvokeType.toString(), '(int) → double');
+
+ SimpleIdentifier target = invocation.target;
+ expect(target.staticElement, same(parameter));
+ expect(target.staticType.toString(), '(int) → double');
+
+ SimpleIdentifier methodName = invocation.methodName;
+ if (useCFE) {
+ expect(methodName.staticElement, isNull);
+ expect(methodName.staticType, isNull);
+ } else {
+ expect(methodName.staticElement, same(parameter));
+ expect(methodName.staticType, parameter.type);
+ }
+ }
+
+ test_methodInvocation_instanceMethod_forwardingStub() async {
+ addTestFile(r'''
+class A {
+ void foo(int x) {}
+}
+abstract class I<T> {
+ void foo(T x);
+}
+class B extends A implements I<int> {}
+main(B b) {
+ b.foo(1);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ ClassDeclaration aNode = result.unit.declarations[0];
+ MethodDeclaration fooNode = aNode.members[0];
+ MethodElement fooElement = fooNode.element;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ expect(invocation.methodName.staticElement, same(fooElement));
+
+ var invokeTypeStr = '(int) → void';
+ expect(invocation.staticType.toString(), 'void');
+ expect(invocation.staticInvokeType.toString(), invokeTypeStr);
+ }
+
+ test_methodInvocation_instanceMethod_genericClass() async {
+ addTestFile(r'''
+main() {
+ new C<int, double>().m(1);
+}
+class C<T, U> {
+ void m(T p) {}
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ ClassDeclaration cNode = result.unit.declarations[1];
+ MethodDeclaration mNode = cNode.members[0];
+ MethodElement mElement = mNode.element;
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ var invokeTypeStr = '(int) → void';
+ expect(invocation.staticType.toString(), 'void');
+ expect(invocation.staticInvokeType.toString(), invokeTypeStr);
+ if (useCFE) {
+ expect(invocation.methodName.staticElement, same(mElement));
+ expect(invocation.methodName.staticType.toString(), invokeTypeStr);
+ } else {
+ expect(invocation.staticInvokeType.element, same(mElement));
+ }
+
+ _assertArgumentToParameter(arguments[0], mElement.parameters[0]);
+ }
+ }
+
+ test_methodInvocation_instanceMethod_genericClass_genericMethod() async {
+ addTestFile(r'''
+main() {
+ new C<int>().m(1, 2.3);
+}
+class C<T> {
+ Map<T, U> m<U>(T a, U b) => null;
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ ClassDeclaration cNode = result.unit.declarations[1];
+ MethodDeclaration mNode = cNode.members[0];
+ MethodElement mElement = mNode.element;
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ var invokeTypeStr = '(int, double) → Map<int, double>';
+ expect(invocation.staticType.toString(), 'Map<int, double>');
+ expect(invocation.staticInvokeType.toString(), invokeTypeStr);
+ if (useCFE) {
+ expect(invocation.methodName.staticElement, same(mElement));
+ expect(invocation.methodName.staticType.toString(), invokeTypeStr);
+ }
+
+ if (useCFE) {
+ expect(arguments[0].staticParameterElement, isNull);
+ expect(arguments[1].staticParameterElement, isNull);
+ } else {
+ Expression aArgument = arguments[0];
+ ParameterMember aArgumentParameter = aArgument.staticParameterElement;
+ ParameterElement aElement = mElement.parameters[0];
+ expect(aArgumentParameter.type, typeProvider.intType);
+ expect(aArgumentParameter.baseElement, same(aElement));
+
+ Expression bArgument = arguments[1];
+ ParameterMember bArgumentParameter = bArgument.staticParameterElement;
+ expect(bArgumentParameter.type, typeProvider.doubleType);
+ }
+ }
+ }
+
+ test_methodInvocation_namedArgument() async {
+ addTestFile(r'''
+void main() {
+ foo(1, b: true, c: 3.0);
+}
+void foo(int a, {bool b, double c}) {}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ FunctionDeclaration foo = result.unit.declarations[1];
+ ExecutableElement fooElement = foo.element;
+
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ _assertArgumentToParameter(arguments[0], fooElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], fooElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], fooElement.parameters[2]);
+ }
+
+ test_methodInvocation_notFunction_field_dynamic() async {
+ addTestFile(r'''
+class C {
+ dynamic f;
+ foo() {
+ f(1);
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ ClassDeclaration cDeclaration = result.unit.declarations[0];
+
+ FieldDeclaration fDeclaration = cDeclaration.members[0];
+ VariableDeclaration fNode = fDeclaration.fields.variables[0];
+ FieldElement fElement = fNode.element;
+
+ MethodDeclaration fooDeclaration = cDeclaration.members[1];
+ BlockFunctionBody fooBody = fooDeclaration.body;
+ List<Statement> fooStatements = fooBody.block.statements;
+
+ ExpressionStatement statement = fooStatements[0];
+ MethodInvocation invocation = statement.expression;
+ expect(invocation.methodName.staticElement, same(fElement.getter));
+ if (useCFE) {
+ _assertDynamicFunctionType(invocation.staticInvokeType);
+ } else {
+ expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
+ }
+ expect(invocation.staticType, DynamicTypeImpl.instance);
+
+ List<Expression> arguments = invocation.argumentList.arguments;
+ expect(arguments[0].staticParameterElement, isNull);
+ }
+
+ test_methodInvocation_notFunction_getter_dynamic() async {
+ addTestFile(r'''
+class C {
+ get f => null;
+ foo() {
+ f(1);
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ ClassDeclaration cDeclaration = result.unit.declarations[0];
+
+ MethodDeclaration fDeclaration = cDeclaration.members[0];
+ PropertyAccessorElement fElement = fDeclaration.element;
+
+ MethodDeclaration fooDeclaration = cDeclaration.members[1];
+ BlockFunctionBody fooBody = fooDeclaration.body;
+ List<Statement> fooStatements = fooBody.block.statements;
+
+ ExpressionStatement statement = fooStatements[0];
+ MethodInvocation invocation = statement.expression;
+ expect(invocation.methodName.staticElement, same(fElement));
+ if (useCFE) {
+ _assertDynamicFunctionType(invocation.staticInvokeType);
+ } else {
+ expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
+ }
+ expect(invocation.staticType, DynamicTypeImpl.instance);
+
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ Expression argument = arguments[0];
+ expect(argument.staticParameterElement, isNull);
+ }
+
+ test_methodInvocation_notFunction_getter_typedef() async {
+ addTestFile(r'''
+typedef String Fun(int a, {int b});
+class C {
+ Fun get f => null;
+ foo() {
+ f(1, b: 2);
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ FunctionTypeAlias funDeclaration = result.unit.declarations[0];
+ FunctionTypeAliasElement funElement = funDeclaration.element;
+
+ ClassDeclaration cDeclaration = result.unit.declarations[1];
+
+ MethodDeclaration fDeclaration = cDeclaration.members[0];
+ PropertyAccessorElement fElement = fDeclaration.element;
+
+ MethodDeclaration fooDeclaration = cDeclaration.members[1];
+ BlockFunctionBody fooBody = fooDeclaration.body;
+ List<Statement> fooStatements = fooBody.block.statements;
+
+ ExpressionStatement statement = fooStatements[0];
+ MethodInvocation invocation = statement.expression;
+ expect(invocation.methodName.staticElement, same(fElement));
+ expect(invocation.staticInvokeType.toString(), '(int, {b: int}) → String');
+ expect(invocation.staticType, typeProvider.stringType);
+
+ List<Expression> arguments = invocation.argumentList.arguments;
+ _assertArgumentToParameter(arguments[0], funElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], funElement.parameters[1]);
+ }
+
+ test_methodInvocation_notFunction_local_dynamic() async {
+ addTestFile(r'''
+main(f) {
+ f(1);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ FunctionDeclaration mainDeclaration = result.unit.declarations[0];
+ FunctionExpression mainFunction = mainDeclaration.functionExpression;
+ ParameterElement fElement = mainFunction.parameters.parameters[0].element;
+
+ BlockFunctionBody mainBody = mainFunction.body;
+ List<Statement> mainStatements = mainBody.block.statements;
+
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ expect(invocation.methodName.staticElement, same(fElement));
+ _assertDynamicFunctionType(invocation.staticInvokeType);
+ expect(invocation.staticType, DynamicTypeImpl.instance);
+
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ Expression argument = arguments[0];
+ expect(argument.staticParameterElement, isNull);
+ }
+
+ test_methodInvocation_notFunction_local_functionTyped() async {
+ addTestFile(r'''
+main(String f(int a)) {
+ f(1);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ FunctionDeclaration mainDeclaration = result.unit.declarations[0];
+ FunctionExpression mainFunction = mainDeclaration.functionExpression;
+ ParameterElement fElement = mainFunction.parameters.parameters[0].element;
+
+ BlockFunctionBody mainBody = mainFunction.body;
+ List<Statement> mainStatements = mainBody.block.statements;
+
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ expect(invocation.methodName.staticElement, same(fElement));
+ expect(invocation.staticInvokeType.toString(), '(int) → String');
+ expect(invocation.staticType, typeProvider.stringType);
+
+ List<Expression> arguments = invocation.argumentList.arguments;
+ _assertArgumentToParameter(
+ arguments[0], (fElement.type as FunctionType).parameters[0]);
+ }
+
+ test_methodInvocation_notFunction_topLevelVariable_dynamic() async {
+ addTestFile(r'''
+dynamic f;
+main() {
+ f(1);
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ TopLevelVariableDeclaration fDeclaration = result.unit.declarations[0];
+ VariableDeclaration fNode = fDeclaration.variables.variables[0];
+ TopLevelVariableElement fElement = fNode.element;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ expect(invocation.methodName.staticElement, same(fElement.getter));
+ _assertDynamicFunctionType(invocation.staticInvokeType);
+ expect(invocation.staticType, DynamicTypeImpl.instance);
+
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ Expression argument = arguments[0];
+ expect(argument.staticParameterElement, isNull);
+ }
+
+ test_methodInvocation_staticMethod() async {
+ addTestFile(r'''
+main() {
+ C.m(1);
+}
+class C {
+ static void m(int p) {}
+ void foo() {
+ m(2);
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ ClassDeclaration cNode = result.unit.declarations[1];
+ ClassElement cElement = cNode.element;
+ MethodDeclaration mNode = cNode.members[0];
+ MethodElement mElement = mNode.element;
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ SimpleIdentifier target = invocation.target;
+ expect(target.staticElement, same(cElement));
+ expect(target.staticType, same(cElement.type));
+
+ var invokeTypeStr = '(int) → void';
+ expect(invocation.staticType.toString(), 'void');
+ expect(invocation.staticInvokeType.toString(), invokeTypeStr);
+ if (!useCFE) {
+ expect(invocation.staticInvokeType.element, same(mElement));
+ }
+ expect(invocation.methodName.staticElement, same(mElement));
+ expect(invocation.methodName.staticType.toString(), invokeTypeStr);
+
+ Expression argument = arguments[0];
+ _assertArgumentToParameter(argument, mElement.parameters[0]);
+ }
+
+ {
+ MethodDeclaration fooNode = cNode.members[1];
+ BlockFunctionBody fooBody = fooNode.body;
+ List<Statement> statements = fooBody.block.statements;
+
+ ExpressionStatement statement = statements[0];
+ MethodInvocation invocation = statement.expression;
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ expect(invocation.target, isNull);
+
+ var invokeTypeStr = '(int) → void';
+ expect(invocation.staticType.toString(), 'void');
+ expect(invocation.staticInvokeType.toString(), invokeTypeStr);
+ if (!useCFE) {
+ expect(invocation.staticInvokeType.element, same(mElement));
+ }
+ expect(invocation.methodName.staticElement, same(mElement));
+ expect(invocation.methodName.staticType.toString(), invokeTypeStr);
+
+ Expression argument = arguments[0];
+ _assertArgumentToParameter(argument, mElement.parameters[0]);
+ }
+ }
+
+ test_methodInvocation_staticMethod_contextTypeParameter() async {
+ addTestFile(r'''
+class C<T> {
+ static E foo<E>(C<E> c) => null;
+ void bar() {
+ foo(this);
+ }
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+
+ ClassDeclaration cNode = result.unit.declarations[0];
+ TypeParameterElement tElement = cNode.element.typeParameters[0];
+
+ MethodDeclaration barNode = cNode.members[1];
+ BlockFunctionBody barBody = barNode.body;
+ ExpressionStatement fooStatement = barBody.block.statements[0];
+ MethodInvocation fooInvocation = fooStatement.expression;
+ expect(fooInvocation.staticInvokeType.toString(), '(C<T>) → T');
+ expect(fooInvocation.staticType.toString(), 'T');
+ expect(fooInvocation.staticType.element, same(tElement));
+ }
+
+ test_methodInvocation_topLevelFunction() async {
+ addTestFile(r'''
+void main() {
+ f(1, '2');
+}
+double f(int a, String b) {}
+''');
+ String fTypeString = '(int, String) → double';
+
+ AnalysisResult result = await driver.getResult(testFile);
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ InterfaceType doubleType = typeProvider.doubleType;
+
+ FunctionDeclaration fNode = result.unit.declarations[1];
+ FunctionElement fElement = fNode.element;
+
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ expect(invocation.methodName.staticElement, same(fElement));
+ expect(invocation.methodName.staticType.toString(), fTypeString);
+ expect(invocation.staticType, same(doubleType));
+ expect(invocation.staticInvokeType.toString(), fTypeString);
+
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
+ }
+
+ test_methodInvocation_topLevelFunction_generic() async {
+ addTestFile(r'''
+void main() {
+ f<bool, String>(true, 'str');
+ f(1, 2.3);
+}
+void f<T, U>(T a, U b) {}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ FunctionDeclaration fNode = result.unit.declarations[1];
+ FunctionElement fElement = fNode.element;
+
+ // f<bool, String>(true, 'str');
+ {
+ String fTypeString = '(bool, String) → void';
+ ExpressionStatement statement = mainStatements[0];
+ MethodInvocation invocation = statement.expression;
+
+ List<TypeAnnotation> typeArguments = invocation.typeArguments.arguments;
+ expect(typeArguments, hasLength(2));
+ {
+ TypeName typeArgument = typeArguments[0];
+ InterfaceType boolType = typeProvider.boolType;
+ expect(typeArgument.type, boolType);
+ expect(typeArgument.name.staticElement, boolType.element);
+ expect(typeArgument.name.staticType, boolType);
+ }
+ {
+ TypeName typeArgument = typeArguments[1];
+ InterfaceType stringType = typeProvider.stringType;
+ expect(typeArgument.type, stringType);
+ expect(typeArgument.name.staticElement, stringType.element);
+ expect(typeArgument.name.staticType, stringType);
+ }
+
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ expect(invocation.methodName.staticElement, same(fElement));
+ if (useCFE) {
+ expect(invocation.methodName.staticType.toString(), fTypeString);
+ }
+ expect(invocation.staticType, VoidTypeImpl.instance);
+ expect(invocation.staticInvokeType.toString(), fTypeString);
+
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0],
+ parameterMemberType: typeProvider.boolType);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1],
+ parameterMemberType: typeProvider.stringType);
+ }
+
+ // f(1, 2.3);
+ {
+ String fTypeString = '(int, double) → void';
+ ExpressionStatement statement = mainStatements[1];
+ MethodInvocation invocation = statement.expression;
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ expect(invocation.methodName.staticElement, same(fElement));
+ if (useCFE) {
+ expect(invocation.methodName.staticType.toString(), fTypeString);
+ }
+ expect(invocation.staticType, VoidTypeImpl.instance);
+ expect(invocation.staticInvokeType.toString(), fTypeString);
+
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0],
+ parameterMemberType: typeProvider.intType);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1],
+ parameterMemberType: typeProvider.doubleType);
+ }
+ }
+
+ test_postfixExpression_local() async {
+ String content = r'''
+main() {
+ int v = 0;
+ v++;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement v;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ v = statement.variables.variables[0].element;
+ expect(v.type, typeProvider.intType);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ PostfixExpression postfix = statement.expression;
+ expect(postfix.operator.type, TokenType.PLUS_PLUS);
+ expect(postfix.staticElement.name, '+');
+ expect(postfix.staticType, typeProvider.intType);
+
+ SimpleIdentifier operand = postfix.operand;
+ expect(operand.staticElement, same(v));
+ expect(operand.staticType, typeProvider.intType);
+ }
+ }
+
+ test_postfixExpression_propertyAccess() async {
+ String content = r'''
+main() {
+ new C().f++;
+}
+class C {
+ int f;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cClassDeclaration = unit.declarations[1];
+ ClassElement cClassElement = cClassDeclaration.element;
+ FieldElement fElement = cClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+
+ PostfixExpression postfix = statement.expression;
+ expect(postfix.operator.type, TokenType.PLUS_PLUS);
+ expect(postfix.staticElement.name, '+');
+ expect(postfix.staticType, typeProvider.intType);
+
+ PropertyAccess propertyAccess = postfix.operand;
+ expect(propertyAccess.staticType, typeProvider.intType);
+
+ SimpleIdentifier propertyName = propertyAccess.propertyName;
+ expect(propertyName.staticElement, same(fElement.setter));
+ expect(propertyName.staticType, typeProvider.intType);
+ }
+ }
+
+ test_prefixedIdentifier_classInstance_instanceField() async {
+ String content = r'''
+main() {
+ var c = new C();
+ c.f;
+}
+class C {
+ int f;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ ClassDeclaration cDeclaration = result.unit.declarations[1];
+ ClassElement cElement = cDeclaration.element;
+ FieldElement fElement = cElement.fields[0];
+
+ VariableDeclarationStatement cStatement = statements[0];
+ VariableElement vElement = cStatement.variables.variables[0].element;
+
+ ExpressionStatement statement = statements[1];
+ PrefixedIdentifier prefixed = statement.expression;
+
+ SimpleIdentifier prefix = prefixed.prefix;
+ expect(prefix.staticElement, same(vElement));
+ expect(prefix.staticType, cElement.type);
+
+ SimpleIdentifier identifier = prefixed.identifier;
+ expect(identifier.staticElement, same(fElement.getter));
+ expect(identifier.staticType, typeProvider.intType);
+ }
+
+ test_prefixedIdentifier_className_staticField() async {
+ String content = r'''
+main() {
+ C.f;
+}
+class C {
+ static f = 0;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ ClassDeclaration cDeclaration = result.unit.declarations[1];
+ ClassElement cElement = cDeclaration.element;
+ FieldElement fElement = cElement.fields[0];
+
+ ExpressionStatement statement = statements[0];
+ PrefixedIdentifier prefixed = statement.expression;
+
+ SimpleIdentifier prefix = prefixed.prefix;
+ expect(prefix.staticElement, same(cElement));
+ expect(prefix.staticType, cElement.type);
+
+ SimpleIdentifier identifier = prefixed.identifier;
+ expect(identifier.staticElement, same(fElement.getter));
+ expect(identifier.staticType, typeProvider.intType);
+ }
+
+ test_prefixedIdentifier_explicitCall() async {
+ addTestFile(r'''
+main(double computation(int p)) {
+ computation.call;
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.errors, isEmpty);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ FunctionDeclaration main = result.unit.declarations[0];
+ FunctionElement mainElement = main.element;
+ ParameterElement parameter = mainElement.parameters[0];
+
+ BlockFunctionBody mainBody = main.functionExpression.body;
+ List<Statement> statements = mainBody.block.statements;
+
+ ExpressionStatement statement = statements[0];
+ PrefixedIdentifier prefixed = statement.expression;
+
+ expect(prefixed.prefix.staticElement, same(parameter));
+ expect(prefixed.prefix.staticType.toString(), '(int) → double');
+
+ SimpleIdentifier methodName = prefixed.identifier;
+ expect(methodName.staticElement, isNull);
+ if (useCFE) {
+ expect(methodName.staticType, isNull);
+ } else {
+ expect(methodName.staticType, typeProvider.dynamicType);
+ }
+ }
+
+ test_prefixedIdentifier_importPrefix_className() async {
+ var libPath = _p('/test/lib/lib.dart');
+ provider.newFile(libPath, '''
+class MyClass {}
+typedef void MyFunctionTypeAlias();
+int myTopVariable;
+int myTopFunction() => 0;
+int get myGetter => 0;
+void set mySetter(int _) {}
+''');
+ addTestFile(r'''
+import 'lib.dart' as my;
+main() {
+ my.MyClass;
+ my.MyFunctionTypeAlias;
+ my.myTopVariable;
+ my.myTopFunction;
+ my.myTopFunction();
+ my.myGetter;
+ my.mySetter = 0;
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ // TODO(scheglov) Uncomment and fix "unused imports" hint.
+// expect(result.errors, isEmpty);
+
+ var unitElement = result.unit.element;
+ ImportElement myImport = unitElement.library.imports[0];
+ PrefixElement myPrefix = myImport.prefix;
+ var typeProvider = unitElement.context.typeProvider;
+
+ var myLibrary = myImport.importedLibrary;
+ var myUnit = myLibrary.definingCompilationUnit;
+ var myClass = myUnit.types.single;
+ var myFunctionTypeAlias = myUnit.functionTypeAliases.single;
+ var myTopVariable = myUnit.topLevelVariables[0];
+ var myTopFunction = myUnit.functions.single;
+ var myGetter = myUnit.topLevelVariables[1].getter;
+ var mySetter = myUnit.topLevelVariables[2].setter;
+ expect(myTopVariable.name, 'myTopVariable');
+ expect(myGetter.displayName, 'myGetter');
+ expect(mySetter.displayName, 'mySetter');
+
+ List<Statement> statements = _getMainStatements(result);
+
+ void assertPrefix(SimpleIdentifier identifier) {
+ expect(identifier.staticElement, same(myPrefix));
+ expect(identifier.staticType, isNull);
+ }
+
+ void assertPrefixedIdentifier(
+ int statementIndex, Element expectedElement, DartType expectedType) {
+ ExpressionStatement statement = statements[statementIndex];
+ PrefixedIdentifier prefixed = statement.expression;
+ assertPrefix(prefixed.prefix);
+
+ expect(prefixed.identifier.staticElement, same(expectedElement));
+ expect(prefixed.identifier.staticType, expectedType);
+ }
+
+ assertPrefixedIdentifier(0, myClass, typeProvider.typeType);
+ assertPrefixedIdentifier(1, myFunctionTypeAlias, typeProvider.typeType);
+ assertPrefixedIdentifier(2, myTopVariable.getter, typeProvider.intType);
+
+ {
+ ExpressionStatement statement = statements[3];
+ PrefixedIdentifier prefixed = statement.expression;
+ assertPrefix(prefixed.prefix);
+
+ expect(prefixed.identifier.staticElement, same(myTopFunction));
+ expect(prefixed.identifier.staticType, isNotNull);
+ }
+
+ {
+ ExpressionStatement statement = statements[4];
+ MethodInvocation invocation = statement.expression;
+ assertPrefix(invocation.target);
+
+ expect(invocation.methodName.staticElement, same(myTopFunction));
+ expect(invocation.methodName.staticType, isNotNull);
+ }
+
+ assertPrefixedIdentifier(5, myGetter, typeProvider.intType);
+
+ {
+ ExpressionStatement statement = statements[6];
+ AssignmentExpression assignment = statement.expression;
+ PrefixedIdentifier left = assignment.leftHandSide;
+ assertPrefix(left.prefix);
+
+ expect(left.identifier.staticElement, same(mySetter));
+ expect(left.identifier.staticType, typeProvider.intType);
+ }
+ }
+
+ test_prefixExpression_local() async {
+ String content = r'''
+main() {
+ int v = 0;
+ ++v;
+ ~v;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement v;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ v = statement.variables.variables[0].element;
+ expect(v.type, typeProvider.intType);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ PrefixExpression prefix = statement.expression;
+ expect(prefix.operator.type, TokenType.PLUS_PLUS);
+ expect(prefix.staticElement.name, '+');
+ expect(prefix.staticType, typeProvider.intType);
+
+ SimpleIdentifier operand = prefix.operand;
+ expect(operand.staticElement, same(v));
+ expect(operand.staticType, typeProvider.intType);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[2];
+
+ PrefixExpression prefix = statement.expression;
+ expect(prefix.operator.type, TokenType.TILDE);
+ expect(prefix.staticElement.name, '~');
+ expect(prefix.staticType, typeProvider.intType);
+
+ SimpleIdentifier operand = prefix.operand;
+ expect(operand.staticElement, same(v));
+ expect(operand.staticType, typeProvider.intType);
+ }
+ }
+
+ test_prefixExpression_local_not() async {
+ String content = r'''
+main() {
+ bool v = true;
+ !v;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ VariableElement v;
+ {
+ VariableDeclarationStatement statement = mainStatements[0];
+ v = statement.variables.variables[0].element;
+ expect(v.type, typeProvider.boolType);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ PrefixExpression prefix = statement.expression;
+ expect(prefix.operator.type, TokenType.BANG);
+ expect(prefix.staticElement, isNull);
+ expect(prefix.staticType, typeProvider.boolType);
+
+ SimpleIdentifier operand = prefix.operand;
+ expect(operand.staticElement, same(v));
+ expect(operand.staticType, typeProvider.boolType);
+ }
+ }
+
+ test_prefixExpression_propertyAccess() async {
+ String content = r'''
+main() {
+ ++new C().f;
+ ~new C().f;
+}
+class C {
+ int f;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cClassDeclaration = unit.declarations[1];
+ ClassElement cClassElement = cClassDeclaration.element;
+ FieldElement fElement = cClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+
+ PrefixExpression prefix = statement.expression;
+ expect(prefix.operator.type, TokenType.PLUS_PLUS);
+ expect(prefix.staticElement.name, '+');
+ expect(prefix.staticType, typeProvider.intType);
+
+ PropertyAccess propertyAccess = prefix.operand;
+ expect(propertyAccess.staticType, typeProvider.intType);
+
+ SimpleIdentifier propertyName = propertyAccess.propertyName;
+ expect(propertyName.staticElement, same(fElement.setter));
+ expect(propertyName.staticType, typeProvider.intType);
+ }
+
+ {
+ ExpressionStatement statement = mainStatements[1];
+
+ PrefixExpression prefix = statement.expression;
+ expect(prefix.operator.type, TokenType.TILDE);
+ expect(prefix.staticElement.name, '~');
+ expect(prefix.staticType, typeProvider.intType);
+
+ PropertyAccess propertyAccess = prefix.operand;
+ expect(propertyAccess.staticType, typeProvider.intType);
+
+ SimpleIdentifier propertyName = propertyAccess.propertyName;
+ expect(propertyName.staticElement, same(fElement.getter));
+ expect(propertyName.staticType, typeProvider.intType);
+ }
+ }
+
+ test_propertyAccess_field() async {
+ String content = r'''
+main() {
+ new C().f;
+}
+class C {
+ int f;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cClassDeclaration = unit.declarations[1];
+ ClassElement cClassElement = cClassDeclaration.element;
+ FieldElement fElement = cClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+ PropertyAccess access = statement.expression;
+ expect(access.staticType, typeProvider.intType);
+
+ InstanceCreationExpression newC = access.target;
+ expect(newC.staticElement, cClassElement.unnamedConstructor);
+ expect(newC.staticType, cClassElement.type);
+
+ expect(access.propertyName.staticElement, same(fElement.getter));
+ expect(access.propertyName.staticType, typeProvider.intType);
+ }
+ }
+
+ test_propertyAccess_getter() async {
+ String content = r'''
+main() {
+ new C().f;
+}
+class C {
+ int get f => 0;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ ClassDeclaration cClassDeclaration = unit.declarations[1];
+ ClassElement cClassElement = cClassDeclaration.element;
+ FieldElement fElement = cClassElement.getField('f');
+
+ List<Statement> mainStatements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = mainStatements[0];
+ PropertyAccess access = statement.expression;
+ expect(access.staticType, typeProvider.intType);
+
+ InstanceCreationExpression newC = access.target;
+ expect(newC.staticElement, cClassElement.unnamedConstructor);
+ expect(newC.staticType, cClassElement.type);
+
+ expect(access.propertyName.staticElement, same(fElement.getter));
+ expect(access.propertyName.staticType, typeProvider.intType);
+ }
+ }
+
+ test_stringInterpolation() async {
+ String content = r'''
+void main() {
+ var v = 42;
+ '$v$v $v';
+ ' ${v + 1} ';
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.path, testFile);
+ expect(result.errors, isEmpty);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ FunctionDeclaration main = result.unit.declarations[0];
+ expect(main.element, isNotNull);
+ expect(main.name.staticElement, isNotNull);
+ expect(main.name.staticType.toString(), '() → void');
+
+ BlockFunctionBody body = main.functionExpression.body;
+ NodeList<Statement> statements = body.block.statements;
+
+ // var v = 42;
+ VariableElement vElement;
+ {
+ VariableDeclarationStatement statement = statements[0];
+ vElement = statement.variables.variables[0].name.staticElement;
+ }
+
+ {
+ ExpressionStatement statement = statements[1];
+ StringInterpolation interpolation = statement.expression;
+
+ InterpolationExpression element_1 = interpolation.elements[1];
+ SimpleIdentifier expression_1 = element_1.expression;
+ expect(expression_1.staticElement, same(vElement));
+ expect(expression_1.staticType, typeProvider.intType);
+
+ InterpolationExpression element_3 = interpolation.elements[3];
+ SimpleIdentifier expression_3 = element_3.expression;
+ expect(expression_3.staticElement, same(vElement));
+ expect(expression_3.staticType, typeProvider.intType);
+
+ InterpolationExpression element_5 = interpolation.elements[5];
+ SimpleIdentifier expression_5 = element_5.expression;
+ expect(expression_5.staticElement, same(vElement));
+ expect(expression_5.staticType, typeProvider.intType);
+ }
+
+ {
+ ExpressionStatement statement = statements[2];
+ StringInterpolation interpolation = statement.expression;
+
+ InterpolationExpression element_1 = interpolation.elements[1];
+ BinaryExpression expression = element_1.expression;
+ expect(expression.staticType, typeProvider.intType);
+
+ SimpleIdentifier left = expression.leftOperand;
+ expect(left.staticElement, same(vElement));
+ expect(left.staticType, typeProvider.intType);
+ }
+ }
+
+ test_stringInterpolation_multiLine_emptyBeforeAfter() async {
+ addTestFile(r"""
+void main() {
+ var v = 42;
+ '''$v''';
+}
+""");
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.errors, isEmpty);
+ }
+
+ test_super() async {
+ String content = r'''
+class A {
+ void method(int p) {}
+ int get getter => 0;
+ void set setter(int p) {}
+ int operator+(int p) => 0;
+}
+class B extends A {
+ void test() {
+ method(1);
+ super.method(2);
+ getter;
+ super.getter;
+ setter = 3;
+ super.setter = 4;
+ this + 5;
+ }
+}
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration aNode = result.unit.declarations[0];
+ ClassDeclaration bNode = result.unit.declarations[1];
+
+ MethodElement methodElement = aNode.members[0].element;
+ PropertyAccessorElement getterElement = aNode.members[1].element;
+ PropertyAccessorElement setterElement = aNode.members[2].element;
+ MethodElement operatorElement = aNode.members[3].element;
+
+ MethodDeclaration testNode = bNode.members[0];
+ BlockFunctionBody testBody = testNode.body;
+ List<Statement> testStatements = testBody.block.statements;
+
+ // method(1);
+ {
+ ExpressionStatement statement = testStatements[0];
+ MethodInvocation invocation = statement.expression;
+
+ expect(invocation.target, isNull);
+
+ expect(invocation.methodName.staticElement, same(methodElement));
+ }
+
+ // super.method(2);
+ {
+ ExpressionStatement statement = testStatements[1];
+ MethodInvocation invocation = statement.expression;
+
+ SuperExpression target = invocation.target;
+ expect(target.staticType, bNode.element.type); // raw
+
+ expect(invocation.methodName.staticElement, same(methodElement));
+ }
+
+ // getter;
+ {
+ ExpressionStatement statement = testStatements[2];
+ SimpleIdentifier identifier = statement.expression;
+
+ expect(identifier.staticElement, same(getterElement));
+ expect(identifier.staticType, same(typeProvider.intType));
+ }
+
+ // super.getter;
+ {
+ ExpressionStatement statement = testStatements[3];
+ PropertyAccess propertyAccess = statement.expression;
+ expect(propertyAccess.staticType, same(typeProvider.intType));
+
+ SuperExpression target = propertyAccess.target;
+ expect(target.staticType, bNode.element.type); // raw
+
+ expect(propertyAccess.propertyName.staticElement, same(getterElement));
+ expect(
+ propertyAccess.propertyName.staticType, same(typeProvider.intType));
+ }
+
+ // setter = 3;
+ {
+ ExpressionStatement statement = testStatements[4];
+ AssignmentExpression assignment = statement.expression;
+
+ SimpleIdentifier identifier = assignment.leftHandSide;
+ expect(identifier.staticElement, same(setterElement));
+ expect(identifier.staticType, same(typeProvider.intType));
+ }
+
+ // this.setter = 4;
+ {
+ ExpressionStatement statement = testStatements[5];
+ AssignmentExpression assignment = statement.expression;
+
+ PropertyAccess propertyAccess = assignment.leftHandSide;
+
+ SuperExpression target = propertyAccess.target;
+ expect(target.staticType, bNode.element.type); // raw
+
+ expect(propertyAccess.propertyName.staticElement, same(setterElement));
+ expect(
+ propertyAccess.propertyName.staticType, same(typeProvider.intType));
+ }
+
+ // super + 5;
+ {
+ ExpressionStatement statement = testStatements[6];
+ BinaryExpression binary = statement.expression;
+
+ ThisExpression target = binary.leftOperand;
+ expect(target.staticType, bNode.element.type); // raw
+
+ expect(binary.staticElement, same(operatorElement));
+ expect(binary.staticType, typeProvider.intType);
+ }
+ }
+
+ test_this() async {
+ String content = r'''
+class A {
+ void method(int p) {}
+ int get getter => 0;
+ void set setter(int p) {}
+ int operator+(int p) => 0;
+ void test() {
+ method(1);
+ this.method(2);
+ getter;
+ this.getter;
+ setter = 3;
+ this.setter = 4;
+ this + 5;
+ }
+}
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration aNode = result.unit.declarations[0];
+
+ MethodElement methodElement = aNode.members[0].element;
+ PropertyAccessorElement getterElement = aNode.members[1].element;
+ PropertyAccessorElement setterElement = aNode.members[2].element;
+ MethodElement operatorElement = aNode.members[3].element;
+
+ MethodDeclaration testNode = aNode.members[4];
+ BlockFunctionBody testBody = testNode.body;
+ List<Statement> testStatements = testBody.block.statements;
+
+ // method(1);
+ {
+ ExpressionStatement statement = testStatements[0];
+ MethodInvocation invocation = statement.expression;
+
+ expect(invocation.target, isNull);
+
+ expect(invocation.methodName.staticElement, same(methodElement));
+ }
+
+ // this.method(2);
+ {
+ ExpressionStatement statement = testStatements[1];
+ MethodInvocation invocation = statement.expression;
+
+ ThisExpression target = invocation.target;
+ expect(target.staticType, aNode.element.type); // raw
+
+ expect(invocation.methodName.staticElement, same(methodElement));
+ }
+
+ // getter;
+ {
+ ExpressionStatement statement = testStatements[2];
+ SimpleIdentifier identifier = statement.expression;
+
+ expect(identifier.staticElement, same(getterElement));
+ expect(identifier.staticType, typeProvider.intType);
+ }
+
+ // this.getter;
+ {
+ ExpressionStatement statement = testStatements[3];
+ PropertyAccess propertyAccess = statement.expression;
+ expect(propertyAccess.staticType, typeProvider.intType);
+
+ ThisExpression target = propertyAccess.target;
+ expect(target.staticType, aNode.element.type); // raw
+
+ expect(propertyAccess.propertyName.staticElement, same(getterElement));
+ expect(propertyAccess.propertyName.staticType, typeProvider.intType);
+ }
+
+ // setter = 3;
+ {
+ ExpressionStatement statement = testStatements[4];
+ AssignmentExpression assignment = statement.expression;
+
+ SimpleIdentifier identifier = assignment.leftHandSide;
+ expect(identifier.staticElement, same(setterElement));
+ expect(identifier.staticType, typeProvider.intType);
+ }
+
+ // this.setter = 4;
+ {
+ ExpressionStatement statement = testStatements[5];
+ AssignmentExpression assignment = statement.expression;
+
+ PropertyAccess propertyAccess = assignment.leftHandSide;
+
+ ThisExpression target = propertyAccess.target;
+ expect(target.staticType, aNode.element.type); // raw
+
+ expect(propertyAccess.propertyName.staticElement, same(setterElement));
+ expect(propertyAccess.propertyName.staticType, typeProvider.intType);
+ }
+
+ // this + 5;
+ {
+ ExpressionStatement statement = testStatements[6];
+ BinaryExpression binary = statement.expression;
+
+ ThisExpression target = binary.leftOperand;
+ expect(target.staticType, aNode.element.type); // raw
+
+ expect(binary.staticElement, same(operatorElement));
+ expect(binary.staticType, typeProvider.intType);
+ }
+ }
+
+ test_top_class() async {
+ String content = r'''
+class A<T> {}
+class B<T> {}
+class C<T> {}
+class D extends A<bool> with B<int> implements C<double> {}
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration aNode = result.unit.declarations[0];
+ ClassElement aElement = aNode.element;
+
+ ClassDeclaration bNode = result.unit.declarations[1];
+ ClassElement bElement = bNode.element;
+
+ ClassDeclaration cNode = result.unit.declarations[2];
+ ClassElement cElement = cNode.element;
+
+ ClassDeclaration dNode = result.unit.declarations[3];
+ Element dElement = dNode.element;
+
+ SimpleIdentifier dName = dNode.name;
+ expect(dName.staticElement, same(dElement));
+ expect(dName.staticType, typeProvider.typeType);
+
+ {
+ var aRawType = aElement.type;
+ var expectedType = aRawType.instantiate([typeProvider.boolType]);
+
+ TypeName superClass = dNode.extendsClause.superclass;
+ expect(superClass.type, expectedType);
+
+ SimpleIdentifier identifier = superClass.name;
+ expect(identifier.staticElement, aElement);
+ expect(identifier.staticType, expectedType);
+ }
+
+ {
+ var bRawType = bElement.type;
+ var expectedType = bRawType.instantiate([typeProvider.intType]);
+
+ TypeName mixinType = dNode.withClause.mixinTypes[0];
+ expect(mixinType.type, expectedType);
+
+ SimpleIdentifier identifier = mixinType.name;
+ expect(identifier.staticElement, bElement);
+ expect(identifier.staticType, expectedType);
+ }
+
+ {
+ var cRawType = cElement.type;
+ var expectedType = cRawType.instantiate([typeProvider.doubleType]);
+
+ TypeName implementedType = dNode.implementsClause.interfaces[0];
+ expect(implementedType.type, expectedType);
+
+ SimpleIdentifier identifier = implementedType.name;
+ expect(identifier.staticElement, cElement);
+ expect(identifier.staticType, expectedType);
+ }
+ }
+
+ test_top_class_constructor_parameter_defaultValue() async {
+ String content = r'''
+class C {
+ double f;
+ C([int a: 1 + 2]) : f = 3.4;
+}
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration cNode = result.unit.declarations[0];
+ ClassElement cElement = cNode.element;
+
+ ConstructorDeclaration constructorNode = cNode.members[1];
+
+ DefaultFormalParameter aNode = constructorNode.parameters.parameters[0];
+ _assertDefaultParameter(aNode, cElement.unnamedConstructor.parameters[0],
+ name: 'a',
+ offset: 31,
+ kind: ParameterKind.POSITIONAL,
+ type: typeProvider.intType);
+
+ BinaryExpression binary = aNode.defaultValue;
+ expect(binary.staticElement, isNotNull);
+ expect(binary.staticType, typeProvider.intType);
+ expect(binary.leftOperand.staticType, typeProvider.intType);
+ expect(binary.rightOperand.staticType, typeProvider.intType);
+ }
+
+ test_top_classTypeAlias() async {
+ String content = r'''
+class A<T> {}
+class B<T> {}
+class C<T> {}
+class D = A<bool> with B<int> implements C<double>;
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ ClassDeclaration aNode = result.unit.declarations[0];
+ ClassElement aElement = aNode.element;
+
+ ClassDeclaration bNode = result.unit.declarations[1];
+ ClassElement bElement = bNode.element;
+
+ ClassDeclaration cNode = result.unit.declarations[2];
+ ClassElement cElement = cNode.element;
+
+ ClassTypeAlias dNode = result.unit.declarations[3];
+ Element dElement = dNode.element;
+
+ SimpleIdentifier dName = dNode.name;
+ expect(dName.staticElement, same(dElement));
+ expect(dName.staticType, typeProvider.typeType);
+
+ {
+ var aRawType = aElement.type;
+ var expectedType = aRawType.instantiate([typeProvider.boolType]);
+
+ TypeName superClass = dNode.superclass;
+ expect(superClass.type, expectedType);
+
+ SimpleIdentifier identifier = superClass.name;
+ expect(identifier.staticElement, same(aElement));
+ expect(identifier.staticType, expectedType);
+ }
+
+ {
+ var bRawType = bElement.type;
+ var expectedType = bRawType.instantiate([typeProvider.intType]);
+
+ TypeName mixinType = dNode.withClause.mixinTypes[0];
+ expect(mixinType.type, expectedType);
+
+ SimpleIdentifier identifier = mixinType.name;
+ expect(identifier.staticElement, same(bElement));
+ expect(identifier.staticType, expectedType);
+ }
+
+ {
+ var cRawType = cElement.type;
+ var expectedType = cRawType.instantiate([typeProvider.doubleType]);
+
+ TypeName interfaceType = dNode.implementsClause.interfaces[0];
+ expect(interfaceType.type, expectedType);
+
+ SimpleIdentifier identifier = interfaceType.name;
+ expect(identifier.staticElement, same(cElement));
+ expect(identifier.staticType, expectedType);
+ }
+ }
+
+ test_top_enum() async {
+ String content = r'''
+enum MyEnum {
+ A, B
+}
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+ var typeProvider = result.unit.element.context.typeProvider;
+
+ EnumDeclaration enumNode = result.unit.declarations[0];
+ ClassElement enumElement = enumNode.element;
+
+ SimpleIdentifier dName = enumNode.name;
+ expect(dName.staticElement, same(enumElement));
+ if (useCFE) {
+ expect(dName.staticType, typeProvider.typeType);
+ }
+
+ {
+ var aElement = enumElement.getField('A');
+ var aNode = enumNode.constants[0];
+ expect(aNode.element, same(aElement));
+ expect(aNode.name.staticElement, same(aElement));
+ expect(aNode.name.staticType, same(enumElement.type));
+ }
+
+ {
+ var bElement = enumElement.getField('B');
+ var bNode = enumNode.constants[1];
+ expect(bNode.element, same(bElement));
+ expect(bNode.name.staticElement, same(bElement));
+ expect(bNode.name.staticType, same(enumElement.type));
+ }
+ }
+
+ test_top_executables_class() async {
+ String content = r'''
+class C {
+ C(int p);
+ C.named(int p);
+
+ int publicMethod(double p) => 0;
+ int get publicGetter => 0;
+ void set publicSetter(double p) {}
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.path, testFile);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ InterfaceType typeType = typeProvider.typeType;
+ InterfaceType doubleType = typeProvider.doubleType;
+ InterfaceType intType = typeProvider.intType;
+ ClassElement doubleElement = doubleType.element;
+ ClassElement intElement = intType.element;
+
+ ClassDeclaration cNode = result.unit.declarations[0];
+ ClassElement cElement = cNode.element;
+
+ // The class name identifier.
+ expect(cNode.name.staticElement, same(cElement));
+ expect(cNode.name.staticType, typeType);
+
+ // unnamed constructor
+ {
+ ConstructorDeclaration node = cNode.members[0];
+ expect(node.element, isNotNull);
+ expect(node.element.type.toString(), '(int) → C');
+ expect(node.returnType.staticElement, same(cElement));
+ expect(node.returnType.staticType, typeType);
+ expect(node.name, isNull);
+ }
+
+ // named constructor
+ {
+ ConstructorDeclaration node = cNode.members[1];
+ expect(node.element, isNotNull);
+ expect(node.element.type.toString(), '(int) → C');
+ expect(node.returnType.staticElement, same(cElement));
+ expect(node.returnType.staticType, typeType);
+ expect(node.name.staticElement, same(node.element));
+ expect(node.name.staticType.toString(), '(int) → C');
+ }
+
+ // publicMethod()
+ {
+ MethodDeclaration node = cNode.members[2];
+ expect(node.element, isNotNull);
+ expect(node.element.type.toString(), '(double) → int');
+
+ // method return type
+ TypeName returnType = node.returnType;
+ SimpleIdentifier returnTypeName = returnType.name;
+ expect(returnType.type, intType);
+ expect(returnTypeName.staticElement, intElement);
+ expect(returnTypeName.staticType, intType);
+
+ // method name
+ expect(node.name.staticElement, same(node.element));
+ expect(node.name.staticType, same(node.element.type));
+
+ // method parameter
+ {
+ SimpleFormalParameter pNode = node.parameters.parameters[0];
+ expect(pNode.element, isNotNull);
+ expect(pNode.element.type, doubleType);
+
+ TypeName pType = pNode.type;
+ expect(pType.name.staticElement, doubleElement);
+ expect(pType.name.staticType, doubleType);
+
+ expect(pNode.identifier.staticElement, pNode.element);
+ expect(pNode.identifier.staticType, doubleType);
+ }
+ }
+
+ // publicGetter()
+ {
+ MethodDeclaration node = cNode.members[3];
+ expect(node.element, isNotNull);
+ expect(node.element.type.toString(), '() → int');
+
+ // getter return type
+ TypeName returnType = node.returnType;
+ SimpleIdentifier returnTypeName = returnType.name;
+ expect(returnType.type, intType);
+ expect(returnTypeName.staticElement, intElement);
+ expect(returnTypeName.staticType, intType);
+
+ // getter name
+ expect(node.name.staticElement, same(node.element));
+ expect(node.name.staticType, intType);
+ }
+
+ // publicSetter()
+ {
+ MethodDeclaration node = cNode.members[4];
+ expect(node.element, isNotNull);
+ expect(node.element.type.toString(), '(double) → void');
+
+ // setter return type
+ TypeName returnType = node.returnType;
+ SimpleIdentifier returnTypeName = returnType.name;
+ expect(returnType.type, VoidTypeImpl.instance);
+ expect(returnTypeName.staticElement, isNull);
+ expect(returnTypeName.staticType, VoidTypeImpl.instance);
+
+ // setter name
+ expect(node.name.staticElement, same(node.element));
+ expect(node.name.staticType, doubleType);
+
+ // setter parameter
+ {
+ SimpleFormalParameter pNode = node.parameters.parameters[0];
+ expect(pNode.element, isNotNull);
+ expect(pNode.element.type, doubleType);
+
+ TypeName pType = pNode.type;
+ expect(pType.name.staticElement, doubleElement);
+ expect(pType.name.staticType, doubleType);
+
+ expect(pNode.identifier.staticElement, pNode.element);
+ expect(pNode.identifier.staticType, doubleType);
+ }
+ }
+ }
+
+ test_top_executables_top() async {
+ String content = r'''
+int topFunction(double p) => 0;
+int get topGetter => 0;
+void set topSetter(double p) {}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ expect(result.path, testFile);
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ InterfaceType doubleType = typeProvider.doubleType;
+ InterfaceType intType = typeProvider.intType;
+ ClassElement doubleElement = doubleType.element;
+ ClassElement intElement = intType.element;
+
+ // topFunction()
+ {
+ FunctionDeclaration node = result.unit.declarations[0];
+ expect(node.element, isNotNull);
+ expect(node.element.type.toString(), '(double) → int');
+
+ // function return type
+ TypeName returnType = node.returnType;
+ SimpleIdentifier returnTypeName = returnType.name;
+ expect(returnType.type, intType);
+ expect(returnTypeName.staticElement, intElement);
+ expect(returnTypeName.staticType, intType);
+
+ // function name
+ expect(node.name.staticElement, same(node.element));
+ expect(node.name.staticType, same(node.element.type));
+
+ // function parameter
+ {
+ SimpleFormalParameter pNode =
+ node.functionExpression.parameters.parameters[0];
+ expect(pNode.element, isNotNull);
+ expect(pNode.element.type, doubleType);
+
+ TypeName pType = pNode.type;
+ expect(pType.name.staticElement, doubleElement);
+ expect(pType.name.staticType, doubleType);
+
+ expect(pNode.identifier.staticElement, pNode.element);
+ expect(pNode.identifier.staticType, doubleType);
+ }
+ }
+
+ // topGetter()
+ {
+ FunctionDeclaration node = result.unit.declarations[1];
+ expect(node.element, isNotNull);
+ expect(node.element.type.toString(), '() → int');
+
+ // getter return type
+ TypeName returnType = node.returnType;
+ SimpleIdentifier returnTypeName = returnType.name;
+ expect(returnType.type, intType);
+ expect(returnTypeName.staticElement, intElement);
+ expect(returnTypeName.staticType, intType);
+
+ // getter name
+ expect(node.name.staticElement, same(node.element));
+ expect(node.name.staticType, intType);
+ }
+
+ // topSetter()
+ {
+ FunctionDeclaration node = result.unit.declarations[2];
+ expect(node.element, isNotNull);
+ expect(node.element.type.toString(), '(double) → void');
+
+ // setter return type
+ TypeName returnType = node.returnType;
+ SimpleIdentifier returnTypeName = returnType.name;
+ expect(returnType.type, VoidTypeImpl.instance);
+ expect(returnTypeName.staticElement, isNull);
+ expect(returnTypeName.staticType, VoidTypeImpl.instance);
+
+ // setter name
+ expect(node.name.staticElement, same(node.element));
+ expect(node.name.staticType, doubleType);
+
+ // setter parameter
+ {
+ SimpleFormalParameter pNode =
+ node.functionExpression.parameters.parameters[0];
+ expect(pNode.element, isNotNull);
+ expect(pNode.element.type, doubleType);
+
+ TypeName pType = pNode.type;
+ expect(pType.name.staticElement, doubleElement);
+ expect(pType.name.staticType, doubleType);
+
+ expect(pNode.identifier.staticElement, pNode.element);
+ expect(pNode.identifier.staticType, doubleType);
+ }
+ }
+ }
+
+ test_top_field_class() async {
+ String content = r'''
+class C<T> {
+ var a = 1;
+ T b;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ CompilationUnitElement unitElement = unit.element;
+ var typeProvider = unitElement.context.typeProvider;
+
+ ClassDeclaration cNode = unit.declarations[0];
+ ClassElement cElement = cNode.element;
+ TypeParameterElement tElement = cElement.typeParameters[0];
+ expect(cElement, same(unitElement.types[0]));
+
+ {
+ FieldElement aElement = cElement.getField('a');
+ FieldDeclaration aDeclaration = cNode.members[0];
+ VariableDeclaration aNode = aDeclaration.fields.variables[0];
+ expect(aNode.element, same(aElement));
+ expect(aElement.type, typeProvider.intType);
+ expect(aNode.name.staticElement, same(aElement));
+ expect(aNode.name.staticType, same(aElement.type));
+
+ Expression aValue = aNode.initializer;
+ expect(aValue.staticType, typeProvider.intType);
+ }
+
+ {
+ FieldElement bElement = cElement.getField('b');
+ FieldDeclaration bDeclaration = cNode.members[1];
+
+ TypeName typeName = bDeclaration.fields.type;
+ SimpleIdentifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, same(tElement));
+ expect(typeIdentifier.staticType, same(tElement.type));
+
+ VariableDeclaration bNode = bDeclaration.fields.variables[0];
+ expect(bNode.element, same(bElement));
+ expect(bElement.type, tElement.type);
+ expect(bNode.name.staticElement, same(bElement));
+ expect(bNode.name.staticType, same(bElement.type));
+ }
+ }
+
+ test_top_field_class_multiple() async {
+ String content = r'''
+class C {
+ var a = 1, b = 2.3;
+}
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ CompilationUnitElement unitElement = unit.element;
+ var typeProvider = unitElement.context.typeProvider;
+
+ ClassDeclaration cNode = unit.declarations[0];
+ ClassElement cElement = cNode.element;
+
+ FieldDeclaration fieldDeclaration = cNode.members[0];
+
+ {
+ FieldElement aElement = cElement.getField('a');
+
+ VariableDeclaration aNode = fieldDeclaration.fields.variables[0];
+ expect(aNode.element, same(aElement));
+ expect(aElement.type, typeProvider.intType);
+
+ expect(aNode.name.staticElement, same(aElement));
+ expect(aNode.name.staticType, same(aElement.type));
+
+ Expression aValue = aNode.initializer;
+ expect(aValue.staticType, typeProvider.intType);
+ }
+
+ {
+ FieldElement bElement = cElement.getField('b');
+
+ VariableDeclaration bNode = fieldDeclaration.fields.variables[1];
+ expect(bNode.element, same(bElement));
+ expect(bElement.type, typeProvider.doubleType);
+
+ expect(bNode.name.staticElement, same(bElement));
+ expect(bNode.name.staticType, same(bElement.type));
+
+ Expression aValue = bNode.initializer;
+ expect(aValue.staticType, typeProvider.doubleType);
+ }
+ }
+
+ test_top_field_top() async {
+ String content = r'''
+var a = 1;
+double b = 2.3;
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ CompilationUnitElement unitElement = unit.element;
+ var typeProvider = unitElement.context.typeProvider;
+
+ {
+ TopLevelVariableDeclaration aDeclaration = unit.declarations[0];
+ VariableDeclaration aNode = aDeclaration.variables.variables[0];
+ TopLevelVariableElement aElement = aNode.element;
+ expect(aElement, same(unitElement.topLevelVariables[0]));
+ expect(aElement.type, typeProvider.intType);
+ expect(aNode.name.staticElement, same(aElement));
+ expect(aNode.name.staticType, same(aElement.type));
+
+ Expression aValue = aNode.initializer;
+ expect(aValue.staticType, typeProvider.intType);
+ }
+
+ {
+ TopLevelVariableDeclaration bDeclaration = unit.declarations[1];
+
+ VariableDeclaration bNode = bDeclaration.variables.variables[0];
+ TopLevelVariableElement bElement = bNode.element;
+ expect(bElement, same(unitElement.topLevelVariables[1]));
+ expect(bElement.type, typeProvider.doubleType);
+
+ TypeName typeName = bDeclaration.variables.type;
+ _assertTypeNameSimple(typeName, typeProvider.doubleType);
+
+ expect(bNode.name.staticElement, same(bElement));
+ expect(bNode.name.staticType, same(bElement.type));
+
+ Expression aValue = bNode.initializer;
+ expect(aValue.staticType, typeProvider.doubleType);
+ }
+ }
+
+ test_top_field_top_multiple() async {
+ String content = r'''
+var a = 1, b = 2.3;
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ CompilationUnitElement unitElement = unit.element;
+ var typeProvider = unitElement.context.typeProvider;
+
+ TopLevelVariableDeclaration variableDeclaration = unit.declarations[0];
+ expect(variableDeclaration.variables.type, isNull);
+
+ {
+ VariableDeclaration aNode = variableDeclaration.variables.variables[0];
+ TopLevelVariableElement aElement = aNode.element;
+ expect(aElement, same(unitElement.topLevelVariables[0]));
+ expect(aElement.type, typeProvider.intType);
+
+ expect(aNode.name.staticElement, same(aElement));
+ expect(aNode.name.staticType, aElement.type);
+
+ Expression aValue = aNode.initializer;
+ expect(aValue.staticType, typeProvider.intType);
+ }
+
+ {
+ VariableDeclaration bNode = variableDeclaration.variables.variables[1];
+ TopLevelVariableElement bElement = bNode.element;
+ expect(bElement, same(unitElement.topLevelVariables[1]));
+ expect(bElement.type, typeProvider.doubleType);
+
+ expect(bNode.name.staticElement, same(bElement));
+ expect(bNode.name.staticType, bElement.type);
+
+ Expression aValue = bNode.initializer;
+ expect(aValue.staticType, typeProvider.doubleType);
+ }
+ }
+
+ test_top_function_namedParameters() async {
+ addTestFile(r'''
+double f(int a, {String b, bool c: 1 == 2}) {}
+void main() {
+ f(1, b: '2', c: true);
+}
+''');
+ String fTypeString = '(int, {b: String, c: bool}) → double';
+
+ AnalysisResult result = await driver.getResult(testFile);
+ FunctionDeclaration fDeclaration = result.unit.declarations[0];
+ FunctionElement fElement = fDeclaration.element;
+
+ var typeProvider = result.unit.element.context.typeProvider;
+ InterfaceType doubleType = typeProvider.doubleType;
+
+ expect(fElement, isNotNull);
+ expect(fElement.type.toString(), fTypeString);
+
+ expect(fDeclaration.name.staticElement, same(fElement));
+ expect(fDeclaration.name.staticType, fElement.type);
+
+ TypeName fReturnTypeNode = fDeclaration.returnType;
+ expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
+ expect(fReturnTypeNode.type, doubleType);
+ //
+ // Validate the parameters at the declaration site.
+ //
+ List<ParameterElement> elements = fElement.parameters;
+ expect(elements, hasLength(3));
+
+ List<FormalParameter> nodes =
+ fDeclaration.functionExpression.parameters.parameters;
+ expect(nodes, hasLength(3));
+
+ _assertSimpleParameter(nodes[0], elements[0],
+ name: 'a',
+ offset: 13,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.intType);
+
+ DefaultFormalParameter bNode = nodes[1];
+ _assertDefaultParameter(bNode, elements[1],
+ name: 'b',
+ offset: 24,
+ kind: ParameterKind.NAMED,
+ type: typeProvider.stringType);
+ expect(bNode.defaultValue, isNull);
+
+ DefaultFormalParameter cNode = nodes[2];
+ _assertDefaultParameter(cNode, elements[2],
+ name: 'c',
+ offset: 32,
+ kind: ParameterKind.NAMED,
+ type: typeProvider.boolType);
+ {
+ BinaryExpression defaultValue = cNode.defaultValue;
+ expect(defaultValue.staticElement, isNotNull);
+ expect(defaultValue.staticType, typeProvider.boolType);
+ }
+
+ //
+ // Validate the arguments at the call site.
+ //
+ FunctionDeclaration mainDeclaration = result.unit.declarations[1];
+ BlockFunctionBody body = mainDeclaration.functionExpression.body;
+ ExpressionStatement statement = body.block.statements[0];
+ MethodInvocation invocation = statement.expression;
+ List<Expression> arguments = invocation.argumentList.arguments;
+
+ _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+ _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
+ _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
+ }
+
+ test_top_functionTypeAlias() async {
+ String content = r'''
+typedef int F<T>(bool a, T b);
+''';
+ addTestFile(content);
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ CompilationUnitElement unitElement = unit.element;
+ var typeProvider = unitElement.context.typeProvider;
+
+ FunctionTypeAlias alias = unit.declarations[0];
+ FunctionTypeAliasElement aliasElement = alias.element;
+ expect(aliasElement, same(unitElement.functionTypeAliases[0]));
+ expect(aliasElement.returnType, typeProvider.intType);
+
+ _assertTypeNameSimple(alias.returnType, typeProvider.intType);
+
+ _assertSimpleParameter(
+ alias.parameters.parameters[0], aliasElement.parameters[0],
+ name: 'a',
+ offset: 22,
+ kind: ParameterKind.REQUIRED,
+ type: typeProvider.boolType);
+
+ _assertSimpleParameter(
+ alias.parameters.parameters[1], aliasElement.parameters[1],
+ name: 'b',
+ offset: 27,
+ kind: ParameterKind.REQUIRED,
+ type: aliasElement.typeParameters[0].type);
+ }
+
+ test_top_typeParameter() async {
+ String content = r'''
+class A {}
+class C<T extends A, U extends List<A>, V> {}
+''';
+ addTestFile(content);
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ CompilationUnitElement unitElement = unit.element;
+ var typeProvider = unitElement.context.typeProvider;
+
+ ClassDeclaration aNode = unit.declarations[0];
+ ClassElement aElement = aNode.element;
+ expect(aElement, same(unitElement.types[0]));
+
+ ClassDeclaration cNode = unit.declarations[1];
+ ClassElement cElement = cNode.element;
+ expect(cElement, same(unitElement.types[1]));
+
+ {
+ TypeParameter tNode = cNode.typeParameters.typeParameters[0];
+ expect(tNode.element, same(cElement.typeParameters[0]));
+
+ TypeName bound = tNode.bound;
+ expect(bound.type, aElement.type);
+
+ SimpleIdentifier boundIdentifier = bound.name;
+ expect(boundIdentifier.staticElement, same(aElement));
+ expect(boundIdentifier.staticType, aElement.type);
+ }
+
+ {
+ var listElement = typeProvider.listType.element;
+ var listOfA = typeProvider.listType.instantiate([aElement.type]);
+
+ TypeParameter uNode = cNode.typeParameters.typeParameters[1];
+ expect(uNode.element, same(cElement.typeParameters[1]));
+
+ TypeName bound = uNode.bound;
+ expect(bound.type, listOfA);
+
+ SimpleIdentifier listIdentifier = bound.name;
+ expect(listIdentifier.staticElement, same(listElement));
+ expect(listIdentifier.staticType, listOfA);
+
+ TypeName aTypeName = bound.typeArguments.arguments[0];
+ expect(aTypeName.type, aElement.type);
+
+ SimpleIdentifier aIdentifier = aTypeName.name;
+ expect(aIdentifier.staticElement, same(aElement));
+ expect(aIdentifier.staticType, aElement.type);
+ }
+
+ {
+ TypeParameter vNode = cNode.typeParameters.typeParameters[2];
+ expect(vNode.element, same(cElement.typeParameters[2]));
+ expect(vNode.bound, isNull);
+ }
+ }
+
+ test_tryCatch() async {
+ addTestFile(r'''
+void main() {
+ try {} catch (e, st) {
+ e;
+ st;
+ }
+ try {} on int catch (e, st) {
+ e;
+ st;
+ }
+ try {} catch (e) {
+ e;
+ }
+ try {} on int catch (e) {
+ e;
+ }
+ try {} on int {}
+}
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ List<Statement> statements = _getMainStatements(result);
+
+ // catch (e, st)
+ {
+ TryStatement statement = statements[0];
+ CatchClause catchClause = statement.catchClauses[0];
+ expect(catchClause.exceptionType, isNull);
+
+ SimpleIdentifier exceptionNode = catchClause.exceptionParameter;
+ LocalVariableElement exceptionElement = exceptionNode.staticElement;
+ expect(exceptionElement.type, DynamicTypeImpl.instance);
+
+ SimpleIdentifier stackNode = catchClause.stackTraceParameter;
+ LocalVariableElement stackElement = stackNode.staticElement;
+ expect(stackElement.type, typeProvider.stackTraceType);
+
+ List<Statement> catchStatements = catchClause.body.statements;
+
+ ExpressionStatement exceptionStatement = catchStatements[0];
+ SimpleIdentifier exceptionIdentifier = exceptionStatement.expression;
+ expect(exceptionIdentifier.staticElement, same(exceptionElement));
+ expect(exceptionIdentifier.staticType, DynamicTypeImpl.instance);
+
+ ExpressionStatement stackStatement = catchStatements[1];
+ SimpleIdentifier stackIdentifier = stackStatement.expression;
+ expect(stackIdentifier.staticElement, same(stackElement));
+ expect(stackIdentifier.staticType, typeProvider.stackTraceType);
+ }
+
+ // on int catch (e, st)
+ {
+ TryStatement statement = statements[1];
+ CatchClause catchClause = statement.catchClauses[0];
+ _assertTypeNameSimple(catchClause.exceptionType, typeProvider.intType);
+
+ SimpleIdentifier exceptionNode = catchClause.exceptionParameter;
+ LocalVariableElement exceptionElement = exceptionNode.staticElement;
+ expect(exceptionElement.type, typeProvider.intType);
+
+ SimpleIdentifier stackNode = catchClause.stackTraceParameter;
+ LocalVariableElement stackElement = stackNode.staticElement;
+ expect(stackElement.type, typeProvider.stackTraceType);
+
+ List<Statement> catchStatements = catchClause.body.statements;
+
+ ExpressionStatement exceptionStatement = catchStatements[0];
+ SimpleIdentifier exceptionIdentifier = exceptionStatement.expression;
+ expect(exceptionIdentifier.staticElement, same(exceptionElement));
+ expect(exceptionIdentifier.staticType, typeProvider.intType);
+
+ ExpressionStatement stackStatement = catchStatements[1];
+ SimpleIdentifier stackIdentifier = stackStatement.expression;
+ expect(stackIdentifier.staticElement, same(stackElement));
+ expect(stackIdentifier.staticType, typeProvider.stackTraceType);
+ }
+
+ // catch (e)
+ {
+ TryStatement statement = statements[2];
+ CatchClause catchClause = statement.catchClauses[0];
+ expect(catchClause.exceptionType, isNull);
+ expect(catchClause.stackTraceParameter, isNull);
+
+ SimpleIdentifier exceptionNode = catchClause.exceptionParameter;
+ LocalVariableElement exceptionElement = exceptionNode.staticElement;
+ expect(exceptionElement.type, DynamicTypeImpl.instance);
+ }
+
+ // on int catch (e)
+ {
+ TryStatement statement = statements[3];
+ CatchClause catchClause = statement.catchClauses[0];
+ _assertTypeNameSimple(catchClause.exceptionType, typeProvider.intType);
+ expect(catchClause.stackTraceParameter, isNull);
+
+ SimpleIdentifier exceptionNode = catchClause.exceptionParameter;
+ LocalVariableElement exceptionElement = exceptionNode.staticElement;
+ expect(exceptionElement.type, typeProvider.intType);
+ }
+
+ // on int catch (e)
+ {
+ TryStatement statement = statements[4];
+ CatchClause catchClause = statement.catchClauses[0];
+ _assertTypeNameSimple(catchClause.exceptionType, typeProvider.intType);
+ expect(catchClause.exceptionParameter, isNull);
+ expect(catchClause.stackTraceParameter, isNull);
+ }
+ }
+
+ test_type_functionTypeAlias() async {
+ addTestFile(r'''
+typedef T F<T>(bool a);
+class C {
+ F<int> f;
+}
+''');
+
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ CompilationUnitElement unitElement = unit.element;
+ var typeProvider = unitElement.context.typeProvider;
+
+ FunctionTypeAlias alias = unit.declarations[0];
+ GenericTypeAliasElement aliasElement = alias.element;
+ FunctionType aliasType = aliasElement.type;
+
+ ClassDeclaration cNode = unit.declarations[1];
+
+ FieldDeclaration fDeclaration = cNode.members[0];
+ FunctionType instantiatedAliasType =
+ aliasType.instantiate([typeProvider.intType]);
+
+ TypeName typeName = fDeclaration.fields.type;
+ expect(typeName.type, instantiatedAliasType);
+
+ SimpleIdentifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, same(aliasElement));
+ expect(typeIdentifier.staticType, instantiatedAliasType);
+
+ List<TypeAnnotation> typeArguments = typeName.typeArguments.arguments;
+ expect(typeArguments, hasLength(1));
+ _assertTypeNameSimple(typeArguments[0], typeProvider.intType);
+ }
+
+ test_typeAnnotation_prefixed() async {
+ var a = _p('/test/lib/a.dart');
+ var b = _p('/test/lib/b.dart');
+ var c = _p('/test/lib/c.dart');
+ provider.newFile(a, 'class A {}');
+ provider.newFile(b, "export 'a.dart';");
+ provider.newFile(c, "export 'a.dart';");
+ addTestFile(r'''
+import 'b.dart' as b;
+import 'c.dart' as c;
+b.A a1;
+c.A a2;
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+
+ ImportElement bImport = unit.element.library.imports[0];
+ ImportElement cImport = unit.element.library.imports[1];
+
+ LibraryElement bLibrary = bImport.importedLibrary;
+ LibraryElement aLibrary = bLibrary.exports[0].exportedLibrary;
+ ClassElement aClass = aLibrary.getType('A');
+
+ {
+ TopLevelVariableDeclaration declaration = unit.declarations[0];
+ TypeName typeName = declaration.variables.type;
+
+ PrefixedIdentifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, aClass);
+
+ expect(typeIdentifier.prefix.name, 'b');
+ expect(typeIdentifier.prefix.staticElement, same(bImport.prefix));
+
+ expect(typeIdentifier.identifier.staticElement, aClass);
+ }
+
+ {
+ TopLevelVariableDeclaration declaration = unit.declarations[1];
+ TypeName typeName = declaration.variables.type;
+
+ PrefixedIdentifier typeIdentifier = typeName.name;
+ expect(typeIdentifier.staticElement, aClass);
+
+ expect(typeIdentifier.prefix.name, 'c');
+ expect(typeIdentifier.prefix.staticElement, same(cImport.prefix));
+
+ expect(typeIdentifier.identifier.staticElement, aClass);
+ }
+ }
+
+ test_typeLiteral() async {
+ addTestFile(r'''
+void main() {
+ int;
+ F;
+}
+typedef void F(int p);
+''');
+ AnalysisResult result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ var typeProvider = unit.element.context.typeProvider;
+
+ FunctionTypeAlias fNode = unit.declarations[1];
+ FunctionTypeAliasElement fElement = fNode.element;
+
+ var statements = _getMainStatements(result);
+
+ {
+ ExpressionStatement statement = statements[0];
+ SimpleIdentifier identifier = statement.expression;
+ expect(identifier.staticElement, same(typeProvider.intType.element));
+ expect(identifier.staticType, typeProvider.typeType);
+ }
+
+ {
+ ExpressionStatement statement = statements[1];
+ SimpleIdentifier identifier = statement.expression;
+ expect(identifier.staticElement, same(fElement));
+ expect(identifier.staticType, typeProvider.typeType);
+ }
+ }
+
+ /// Assert that the [argument] is associated with the [expectedParameter],
+ /// if [useCFE] is `null`. If the [argument] is a [NamedExpression],
+ /// the name must be resolved to the parameter in both cases.
+ void _assertArgumentToParameter(
+ Expression argument, ParameterElement expectedParameter,
+ {DartType parameterMemberType}) {
+ ParameterElement actualParameter = argument.staticParameterElement;
+ if (useCFE) {
+ expect(actualParameter, isNull);
+ if (argument is NamedExpression) {
+ SimpleIdentifier name = argument.name.label;
+ expect(name.staticElement, same(expectedParameter));
+ }
+ } else {
+ ParameterElement baseActualParameter;
+ if (actualParameter is ParameterMember) {
+ if (parameterMemberType != null) {
+ expect(actualParameter.type, parameterMemberType);
+ }
+ baseActualParameter = actualParameter.baseElement;
+ // Unwrap ParameterMember one more time.
+ // By some reason we wrap in twice.
+ if (baseActualParameter is ParameterMember) {
+ ParameterMember member = baseActualParameter;
+ baseActualParameter = member.baseElement;
+ }
+ } else {
+ baseActualParameter = actualParameter;
+ }
+ expect(baseActualParameter, same(expectedParameter));
+ if (argument is NamedExpression) {
+ SimpleIdentifier name = argument.name.label;
+ expect(name.staticElement, same(actualParameter));
+ }
+ }
+ }
+
+ void _assertDefaultParameter(
+ DefaultFormalParameter node, ParameterElement element,
+ {String name, int offset, ParameterKind kind, DartType type}) {
+ expect(node, isNotNull);
+ NormalFormalParameter normalNode = node.parameter;
+ _assertSimpleParameter(normalNode, element,
+ name: name, offset: offset, kind: kind, type: type);
+ }
+
+ /// Assert that the [type] is a function type `() -> dynamic`.
+ void _assertDynamicFunctionType(DartType type) {
+ if (useCFE) {
+ expect(type.toString(), '() → dynamic');
+ } else {
+ expect(type, DynamicTypeImpl.instance);
+ }
+ }
+
+ void _assertParameterElement(ParameterElement element,
+ {String name, int offset, ParameterKind kind, DartType type}) {
+ expect(element, isNotNull);
+ expect(name, isNotNull);
+ expect(offset, isNotNull);
+ expect(kind, isNotNull);
+ expect(type, isNotNull);
+ expect(element.name, name);
+ expect(element.nameOffset, offset);
+ // ignore: deprecated_member_use
+ expect(element.parameterKind, kind);
+ expect(element.type, type);
+ }
+
+ void _assertSimpleParameter(
+ SimpleFormalParameter node, ParameterElement element,
+ {String name, int offset, ParameterKind kind, DartType type}) {
+ _assertParameterElement(element,
+ name: name, offset: offset, kind: kind, type: type);
+
+ expect(node, isNotNull);
+ expect(node.element, same(element));
+ expect(node.identifier.staticElement, same(element));
+
+ TypeName typeName = node.type;
+ if (typeName != null) {
+ expect(typeName.type, same(type));
+ expect(typeName.name.staticElement, same(type.element));
+ }
+ }
+
+ void _assertTypeNameSimple(TypeName typeName, DartType type) {
+ expect(typeName.type, type);
+
+ SimpleIdentifier identifier = typeName.name;
+ expect(identifier.staticElement, same(type.element));
+ expect(identifier.staticType, type);
+ }
+
+ List<Statement> _getMainStatements(AnalysisResult result) {
+ for (var declaration in result.unit.declarations) {
+ if (declaration is FunctionDeclaration &&
+ declaration.name.name == 'main') {
+ BlockFunctionBody body = declaration.functionExpression.body;
+ return body.block.statements;
+ }
+ }
+ fail('Not found main() in ${result.unit}');
+ }
+
+ /**
+ * Return the [provider] specific path for the given Posix [path].
+ */
+ String _p(String path) => provider.convertPath(path);
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 887b208..50be7e7 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -6,7 +6,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
-import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
@@ -18,14 +17,11 @@
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
import 'package:analyzer/src/dart/constant/evaluation.dart';
import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/resolver.dart' show ResolverErrorCode;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
@@ -41,13 +37,10 @@
defineReflectiveSuite(() {
defineReflectiveTests(AnalysisDriverSchedulerTest);
defineReflectiveTests(AnalysisDriverTest);
- defineReflectiveTests(AnalysisDriverResolutionTest);
defineReflectiveTests(CacheAllAnalysisDriverTest);
});
}
-Matcher isUndefinedType = new isInstanceOf<UndefinedTypeImpl>();
-
/**
* Returns a [Future] that completes after pumping the event queue [times]
* times. By default, this should pump the event queue enough times to allow
@@ -62,5694 +55,6 @@
return new Future.delayed(Duration.zero, () => pumpEventQueue(times - 1));
}
-/**
- * Integration tests for resolution.
- */
-@reflectiveTest
-class AnalysisDriverResolutionTest extends BaseAnalysisDriverTest {
- test_adjacentStrings() async {
- String content = r'''
-void main() {
- 'aaa' 'bbb' 'ccc';
-}
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- ExpressionStatement statement = statements[0];
- AdjacentStrings expression = statement.expression;
- expect(expression.staticType, typeProvider.stringType);
- expect(expression.strings, hasLength(3));
-
- StringLiteral literal_1 = expression.strings[0];
- expect(literal_1.staticType, typeProvider.stringType);
-
- StringLiteral literal_2 = expression.strings[1];
- expect(literal_2.staticType, typeProvider.stringType);
-
- StringLiteral literal_3 = expression.strings[2];
- expect(literal_3.staticType, typeProvider.stringType);
- }
-
- test_annotation() async {
- String content = r'''
-const myAnnotation = 1;
-
-@myAnnotation
-class C {
- @myAnnotation
- int field1 = 2, field2 = 3;
-
- @myAnnotation
- C() {}
-
- @myAnnotation
- void method() {}
-}
-
-@myAnnotation
-int topLevelVariable1 = 4, topLevelVariable2 = 5;
-
-@myAnnotation
-void topLevelFunction() {}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- TopLevelVariableDeclaration myDeclaration = result.unit.declarations[0];
- VariableDeclaration myVariable = myDeclaration.variables.variables[0];
- TopLevelVariableElement myElement = myVariable.element;
-
- void assertMyAnnotation(AnnotatedNode node) {
- Annotation annotation = node.metadata[0];
- expect(annotation.element, same(myElement.getter));
-
- SimpleIdentifier identifier_1 = annotation.name;
- expect(identifier_1.staticElement, same(myElement.getter));
- expect(identifier_1.staticType, typeProvider.intType);
- }
-
- {
- ClassDeclaration classNode = result.unit.declarations[1];
- assertMyAnnotation(classNode);
-
- {
- FieldDeclaration node = classNode.members[0];
- assertMyAnnotation(node);
- }
-
- {
- ConstructorDeclaration node = classNode.members[1];
- assertMyAnnotation(node);
- }
-
- {
- MethodDeclaration node = classNode.members[2];
- assertMyAnnotation(node);
- }
- }
-
- {
- TopLevelVariableDeclaration node = result.unit.declarations[2];
- assertMyAnnotation(node);
- }
-
- {
- FunctionDeclaration node = result.unit.declarations[3];
- assertMyAnnotation(node);
- }
- }
-
- test_annotation_constructor_withNestedConstructorInvocation() async {
- addTestFile('''
-class C {
- const C();
-}
-class D {
- final C c;
- const D(this.c);
-}
-@D(const C())
-f() {}
-''');
- var result = await driver.getResult(testFile);
- var elementC = AstFinder.getClass(result.unit, 'C').element;
- var constructorC = elementC.constructors[0];
- var elementD = AstFinder.getClass(result.unit, 'D').element;
- var constructorD = elementD.constructors[0];
- var atD = AstFinder.getTopLevelFunction(result.unit, 'f').metadata[0];
- InstanceCreationExpression constC = atD.arguments.arguments[0];
-
- expect(atD.name.staticElement, elementD);
- expect(atD.element, constructorD);
-
- expect(constC.staticElement, constructorC);
- expect(constC.staticType, elementC.type);
-
- expect(constC.constructorName.staticElement, constructorC);
- expect(constC.constructorName.type.type, elementC.type);
- }
-
- test_annotation_kind_reference() async {
- String content = r'''
-const annotation_1 = 1;
-const annotation_2 = 1;
-@annotation_1
-@annotation_2
-void main() {
- print(42);
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- TopLevelVariableDeclaration declaration_1 = result.unit.declarations[0];
- VariableDeclaration variable_1 = declaration_1.variables.variables[0];
- TopLevelVariableElement element_1 = variable_1.element;
-
- TopLevelVariableDeclaration declaration_2 = result.unit.declarations[1];
- VariableDeclaration variable_2 = declaration_2.variables.variables[0];
- TopLevelVariableElement element_2 = variable_2.element;
-
- FunctionDeclaration main = result.unit.declarations[2];
-
- Annotation annotation_1 = main.metadata[0];
- expect(annotation_1.element, same(element_1.getter));
-
- SimpleIdentifier identifier_1 = annotation_1.name;
- expect(identifier_1.staticElement, same(element_1.getter));
- expect(identifier_1.staticType, typeProvider.intType);
-
- Annotation annotation_2 = main.metadata[1];
- expect(annotation_2.element, same(element_2.getter));
-
- SimpleIdentifier identifier_2 = annotation_2.name;
- expect(identifier_2.staticElement, same(element_2.getter));
- expect(identifier_2.staticType, typeProvider.intType);
- }
-
- test_annotation_prefixed_classConstructor() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
-class A {
- const A(int a, {int b});
-}
-''');
- addTestFile(r'''
-import 'a.dart' as p;
-
-@p.A(1, b: 2)
-main() {}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
-
- ImportElement aImport = unit.element.library.imports[0];
- PrefixElement aPrefix = aImport.prefix;
- LibraryElement aLibrary = aImport.importedLibrary;
-
- CompilationUnitElement aUnitElement = aLibrary.definingCompilationUnit;
- ClassElement aClass = aUnitElement.getType('A');
- ConstructorElement constructor = aClass.unnamedConstructor;
-
- Annotation annotation = unit.declarations[0].metadata.single;
- expect(annotation.element, same(constructor));
- PrefixedIdentifier prefixed = annotation.name;
-
- expect(prefixed.prefix.staticElement, same(aPrefix));
- expect(prefixed.prefix.staticType, isNull);
-
- expect(prefixed.identifier.staticElement, same(aClass));
- expect(prefixed.prefix.staticType, isNull);
-
- expect(annotation.constructorName, isNull);
-
- var arguments = annotation.arguments.arguments;
- var parameters = constructor.parameters;
- _assertArgumentToParameter(arguments[0], parameters[0]);
- _assertArgumentToParameter(arguments[1], parameters[1]);
- }
-
- test_annotation_prefixed_classConstructorNamed() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
-class A {
- const A.named(int a, {int b});
-}
-''');
- addTestFile(r'''
-import 'a.dart' as p;
-
-@p.A.named(1, b: 2)
-main() {}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
-
- ImportElement aImport = unit.element.library.imports[0];
- PrefixElement aPrefix = aImport.prefix;
- LibraryElement aLibrary = aImport.importedLibrary;
-
- CompilationUnitElement aUnitElement = aLibrary.definingCompilationUnit;
- ClassElement aClass = aUnitElement.getType('A');
- ConstructorElement constructor = aClass.getNamedConstructor('named');
-
- Annotation annotation = unit.declarations[0].metadata.single;
- expect(annotation.element, same(constructor));
- PrefixedIdentifier prefixed = annotation.name;
-
- expect(prefixed.prefix.staticElement, same(aPrefix));
- expect(prefixed.prefix.staticType, isNull);
-
- expect(prefixed.identifier.staticElement, same(aClass));
- expect(prefixed.prefix.staticType, isNull);
-
- SimpleIdentifier constructorName = annotation.constructorName;
- expect(constructorName.staticElement, same(constructor));
- expect(constructorName.staticType.toString(), '(int, {b: int}) → A');
-
- var arguments = annotation.arguments.arguments;
- var parameters = constructor.parameters;
- _assertArgumentToParameter(arguments[0], parameters[0]);
- _assertArgumentToParameter(arguments[1], parameters[1]);
- }
-
- test_annotation_prefixed_classField() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
-class A {
- static const a = 1;
-}
-''');
- addTestFile(r'''
-import 'a.dart' as p;
-
-@p.A.a
-main() {}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ImportElement aImport = unit.element.library.imports[0];
- PrefixElement aPrefix = aImport.prefix;
- LibraryElement aLibrary = aImport.importedLibrary;
-
- CompilationUnitElement aUnitElement = aLibrary.definingCompilationUnit;
- ClassElement aClass = aUnitElement.getType('A');
- var aGetter = aClass.getField('a').getter;
-
- Annotation annotation = unit.declarations[0].metadata.single;
- expect(annotation.element, same(aGetter));
- PrefixedIdentifier prefixed = annotation.name;
-
- expect(prefixed.prefix.staticElement, same(aPrefix));
- expect(prefixed.prefix.staticType, isNull);
-
- expect(prefixed.identifier.staticElement, same(aClass));
- expect(prefixed.prefix.staticType, isNull);
-
- expect(annotation.constructorName.staticElement, aGetter);
- expect(annotation.constructorName.staticType, typeProvider.intType);
-
- expect(annotation.arguments, isNull);
- }
-
- test_annotation_prefixed_topLevelVariable() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
-const topAnnotation = 1;
-''');
- addTestFile(r'''
-import 'a.dart' as p;
-
-@p.topAnnotation
-main() {}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
-
- ImportElement aImport = unit.element.library.imports[0];
- PrefixElement aPrefix = aImport.prefix;
- LibraryElement aLibrary = aImport.importedLibrary;
-
- CompilationUnitElement aUnitElement = aLibrary.definingCompilationUnit;
- var topAnnotation = aUnitElement.topLevelVariables[0].getter;
-
- Annotation annotation = unit.declarations[0].metadata.single;
- expect(annotation.element, same(topAnnotation));
- PrefixedIdentifier prefixed = annotation.name;
-
- expect(prefixed.prefix.staticElement, same(aPrefix));
- expect(prefixed.prefix.staticType, isNull);
-
- expect(prefixed.identifier.staticElement, same(topAnnotation));
- expect(prefixed.prefix.staticType, isNull);
-
- expect(annotation.constructorName, isNull);
- expect(annotation.arguments, isNull);
- }
-
- test_asExpression() async {
- String content = r'''
-void main() {
- num v = 42;
- v as int;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.path, testFile);
- expect(result.errors, isEmpty);
-
- var typeProvider = result.unit.element.context.typeProvider;
- NodeList<Statement> statements = _getMainStatements(result);
-
- // num v = 42;
- VariableElement vElement;
- {
- VariableDeclarationStatement statement = statements[0];
- vElement = statement.variables.variables[0].name.staticElement;
- expect(vElement.type, typeProvider.numType);
- }
-
- // v as int;
- {
- ExpressionStatement statement = statements[1];
- AsExpression asExpression = statement.expression;
- expect(asExpression.staticType, typeProvider.intType);
-
- SimpleIdentifier target = asExpression.expression;
- expect(target.staticElement, vElement);
- expect(target.staticType, typeProvider.numType);
-
- TypeName intName = asExpression.type;
- expect(intName.name.staticElement, typeProvider.intType.element);
- expect(intName.name.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_compound_indexExpression() async {
- String content = r'''
-main() {
- var items = <num>[1, 2, 3];
- items[0] += 4;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
-
- var typeProvider = unit.element.context.typeProvider;
- InterfaceType numType = typeProvider.numType;
- InterfaceType intType = typeProvider.intType;
- InterfaceType listType = typeProvider.listType;
- InterfaceType listNumType = listType.instantiate([numType]);
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement itemsElement;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- VariableDeclaration itemsNode = statement.variables.variables[0];
- itemsElement = itemsNode.element;
- expect(itemsElement.type, listNumType);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.operator.type, TokenType.PLUS_EQ);
- expect(assignment.staticElement, isNotNull);
- expect(assignment.staticElement.name, '+');
- expect(assignment.staticType, typeProvider.numType); // num + int = num
-
- IndexExpression indexExpression = assignment.leftHandSide;
- expect(indexExpression.staticType, numType);
- expect(indexExpression.index.staticType, intType);
-
- MethodMember actualElement = indexExpression.staticElement;
- MethodMember expectedElement = listNumType.getMethod('[]=');
- expect(actualElement.name, '[]=');
- expect(actualElement.baseElement, same(expectedElement.baseElement));
- expect(actualElement.returnType, VoidTypeImpl.instance);
- expect(actualElement.parameters[0].type, intType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_compound_local() async {
- String content = r'''
-main() {
- num v = 0;
- v += 3;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement v;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- v = statement.variables.variables[0].element;
- expect(v.type, typeProvider.numType);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.operator.type, TokenType.PLUS_EQ);
- expect(assignment.staticElement, isNotNull);
- expect(assignment.staticElement.name, '+');
- expect(assignment.staticType, typeProvider.numType); // num + int = num
-
- SimpleIdentifier left = assignment.leftHandSide;
- expect(left.staticElement, same(v));
- expect(left.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_compound_prefixedIdentifier() async {
- String content = r'''
-main() {
- var c = new C();
- c.f += 2;
-}
-class C {
- num f;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cClassDeclaration = unit.declarations[1];
- ClassElement cClassElement = cClassDeclaration.element;
- FieldElement fElement = cClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement c;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- c = statement.variables.variables[0].element;
- expect(c.type, cClassElement.type);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.operator.type, TokenType.PLUS_EQ);
- expect(assignment.staticElement, isNotNull);
- expect(assignment.staticElement.name, '+');
- expect(assignment.staticType, typeProvider.numType); // num + int = num
-
- PrefixedIdentifier left = assignment.leftHandSide;
- expect(left.staticElement, same(fElement.setter));
- expect(left.staticType, typeProvider.numType);
-
- expect(left.prefix.staticElement, c);
- expect(left.prefix.staticType, cClassElement.type);
-
- expect(left.identifier.staticElement, same(fElement.setter));
- expect(left.identifier.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_compound_propertyAccess() async {
- String content = r'''
-main() {
- new C().f += 2;
-}
-class C {
- num f;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cClassDeclaration = unit.declarations[1];
- ClassElement cClassElement = cClassDeclaration.element;
- FieldElement fElement = cClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = mainStatements[0];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.operator.type, TokenType.PLUS_EQ);
- expect(assignment.staticElement, isNotNull);
- expect(assignment.staticElement.name, '+');
- expect(assignment.staticType, typeProvider.numType); // num + int = num
-
- PropertyAccess left = assignment.leftHandSide;
- expect(left.staticType, typeProvider.numType);
-
- InstanceCreationExpression newC = left.target;
- expect(newC.staticElement, cClassElement.unnamedConstructor);
-
- expect(left.propertyName.staticElement, same(fElement.setter));
- expect(left.propertyName.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_nullAware_local() async {
- String content = r'''
-main() {
- String v;
- v ??= 'test';
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement v;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- v = statement.variables.variables[0].element;
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.operator.type, TokenType.QUESTION_QUESTION_EQ);
- expect(assignment.staticElement, isNull);
- expect(assignment.staticType, typeProvider.stringType);
-
- SimpleIdentifier left = assignment.leftHandSide;
- expect(left.staticElement, same(v));
- expect(left.staticType, typeProvider.stringType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.stringType);
- }
- }
-
- test_assignmentExpression_propertyAccess_forwardingStub() async {
- String content = r'''
-class A {
- int f;
-}
-abstract class I<T> {
- T f;
-}
-class B extends A implements I<int> {}
-main() {
- new B().f = 1;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration aNode = unit.declarations[0];
- ClassElement aElement = aNode.element;
- FieldElement fElement = aElement.getField('f');
-
- ClassDeclaration bNode = unit.declarations[2];
- ClassElement bElement = bNode.element;
-
- List<Statement> mainStatements = _getMainStatements(result);
- ExpressionStatement statement = mainStatements[0];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.staticType, typeProvider.intType);
-
- PropertyAccess left = assignment.leftHandSide;
- expect(left.staticType, typeProvider.intType);
-
- InstanceCreationExpression newB = left.target;
- expect(newB.staticElement, bElement.unnamedConstructor);
-
- expect(left.propertyName.staticElement, same(fElement.setter));
- expect(left.propertyName.staticType, typeProvider.intType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
-
- test_assignmentExpression_simple_indexExpression() async {
- String content = r'''
-main() {
- var items = <int>[1, 2, 3];
- items[0] = 4;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
-
- var typeProvider = unit.element.context.typeProvider;
- InterfaceType intType = typeProvider.intType;
- InterfaceType listType = typeProvider.listType;
- InterfaceType listIntType = listType.instantiate([intType]);
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement itemsElement;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- VariableDeclaration itemsNode = statement.variables.variables[0];
- itemsElement = itemsNode.element;
- expect(itemsElement.type, listIntType);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.operator.type, TokenType.EQ);
- expect(assignment.staticElement, isNull);
- expect(assignment.staticType, typeProvider.intType);
-
- IndexExpression indexExpression = assignment.leftHandSide;
- expect(indexExpression.staticType, intType);
- expect(indexExpression.index.staticType, intType);
-
- MethodMember actualElement = indexExpression.staticElement;
- MethodMember expectedElement = listIntType.getMethod('[]=');
- expect(actualElement.name, '[]=');
- expect(actualElement.baseElement, same(expectedElement.baseElement));
- expect(actualElement.returnType, VoidTypeImpl.instance);
- expect(actualElement.parameters[0].type, intType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_simple_instanceField_unqualified() async {
- String content = r'''
-class C {
- num f = 0;
- foo() {
- f = 2;
- }
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cDeclaration = unit.declarations[0];
- FieldElement fElement = cDeclaration.element.fields[0];
-
- MethodDeclaration fooDeclaration = cDeclaration.members[1];
- BlockFunctionBody fooBody = fooDeclaration.body;
-
- {
- ExpressionStatement statement = fooBody.block.statements[0];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.operator.type, TokenType.EQ);
- expect(assignment.staticElement, isNull);
- expect(assignment.staticType, typeProvider.intType);
-
- SimpleIdentifier left = assignment.leftHandSide;
- expect(left.staticElement, same(fElement.setter));
- expect(left.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_simple_local() async {
- String content = r'''
-main() {
- num v = 0;
- v = 2;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement v;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- v = statement.variables.variables[0].element;
- expect(v.type, typeProvider.numType);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.operator.type, TokenType.EQ);
- expect(assignment.staticElement, isNull);
- expect(assignment.staticType, typeProvider.intType);
-
- SimpleIdentifier left = assignment.leftHandSide;
- expect(left.staticElement, same(v));
- expect(left.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_simple_prefixedIdentifier() async {
- String content = r'''
-main() {
- var c = new C();
- c.f = 2;
-}
-class C {
- num f;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cClassDeclaration = unit.declarations[1];
- ClassElement cClassElement = cClassDeclaration.element;
- FieldElement fElement = cClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement c;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- c = statement.variables.variables[0].element;
- expect(c.type, cClassElement.type);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.staticType, typeProvider.intType);
-
- PrefixedIdentifier left = assignment.leftHandSide;
- expect(left.staticElement, same(fElement.setter));
- expect(left.staticType, typeProvider.numType);
-
- expect(left.prefix.staticElement, c);
- expect(left.prefix.staticType, cClassElement.type);
-
- expect(left.identifier.staticElement, same(fElement.setter));
- expect(left.identifier.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_simple_prefixedIdentifier_staticField() async {
- String content = r'''
-main() {
- C.f = 2;
-}
-class C {
- static num f;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cClassDeclaration = unit.declarations[1];
- ClassElement cClassElement = cClassDeclaration.element;
- FieldElement fElement = cClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = mainStatements[0];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.staticType, typeProvider.intType);
-
- PrefixedIdentifier left = assignment.leftHandSide;
- expect(left.staticElement, same(fElement.setter));
- expect(left.staticType, typeProvider.numType);
-
- expect(left.prefix.staticElement, cClassElement);
- expect(left.prefix.staticType, cClassElement.type);
-
- expect(left.identifier.staticElement, same(fElement.setter));
- expect(left.identifier.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_simple_propertyAccess() async {
- String content = r'''
-main() {
- new C().f = 2;
-}
-class C {
- num f;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cClassDeclaration = unit.declarations[1];
- ClassElement cClassElement = cClassDeclaration.element;
- FieldElement fElement = cClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = mainStatements[0];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.staticType, typeProvider.intType);
-
- PropertyAccess left = assignment.leftHandSide;
- expect(left.staticType, typeProvider.numType);
-
- InstanceCreationExpression newC = left.target;
- expect(newC.staticElement, cClassElement.unnamedConstructor);
-
- expect(left.propertyName.staticElement, same(fElement.setter));
- expect(left.propertyName.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_simple_propertyAccess_chained() async {
- String content = r'''
-main() {
- var a = new A();
- a.b.f = 2;
-}
-class A {
- B b;
-}
-class B {
- num f;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration aClassDeclaration = unit.declarations[1];
- ClassElement aClassElement = aClassDeclaration.element;
- FieldElement bElement = aClassElement.getField('b');
-
- ClassDeclaration bClassDeclaration = unit.declarations[2];
- ClassElement bClassElement = bClassDeclaration.element;
- FieldElement fElement = bClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement a;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- a = statement.variables.variables[0].element;
- expect(a.type, aClassElement.type);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.staticType, typeProvider.intType);
-
- PropertyAccess fAccess = assignment.leftHandSide;
- expect(fAccess.propertyName.name, 'f');
- expect(fAccess.propertyName.staticElement, same(fElement.setter));
- expect(fAccess.propertyName.staticType, typeProvider.numType);
-
- PrefixedIdentifier bAccess = fAccess.target;
- expect(bAccess.identifier.name, 'b');
- expect(bAccess.identifier.staticElement, same(bElement.getter));
- expect(bAccess.identifier.staticType, bClassElement.type);
-
- SimpleIdentifier aIdentifier = bAccess.prefix;
- expect(aIdentifier.name, 'a');
- expect(aIdentifier.staticElement, a);
- expect(aIdentifier.staticType, aClassElement.type);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_simple_propertyAccess_setter() async {
- String content = r'''
-main() {
- new C().f = 2;
-}
-class C {
- void set f(num _) {}
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cClassDeclaration = unit.declarations[1];
- ClassElement cClassElement = cClassDeclaration.element;
- FieldElement fElement = cClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = mainStatements[0];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.staticType, typeProvider.intType);
-
- PropertyAccess left = assignment.leftHandSide;
- expect(left.staticType, typeProvider.numType);
-
- InstanceCreationExpression newC = left.target;
- expect(newC.staticElement, cClassElement.unnamedConstructor);
-
- expect(left.propertyName.staticElement, same(fElement.setter));
- expect(left.propertyName.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_simple_staticField_unqualified() async {
- String content = r'''
-class C {
- static num f = 0;
- foo() {
- f = 2;
- }
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cDeclaration = unit.declarations[0];
- FieldElement fElement = cDeclaration.element.fields[0];
-
- MethodDeclaration fooDeclaration = cDeclaration.members[1];
- BlockFunctionBody fooBody = fooDeclaration.body;
-
- {
- ExpressionStatement statement = fooBody.block.statements[0];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.operator.type, TokenType.EQ);
- expect(assignment.staticElement, isNull);
- expect(assignment.staticType, typeProvider.intType);
-
- SimpleIdentifier left = assignment.leftHandSide;
- expect(left.staticElement, same(fElement.setter));
- expect(left.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_assignmentExpression_simple_topLevelVariable() async {
- String content = r'''
-main() {
- v = 2;
-}
-num v = 0;
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- TopLevelVariableElement v;
- {
- TopLevelVariableDeclaration declaration = unit.declarations[1];
- v = declaration.variables.variables[0].element;
- expect(v.type, typeProvider.numType);
- }
-
- List<Statement> mainStatements = _getMainStatements(result);
- {
- ExpressionStatement statement = mainStatements[0];
-
- AssignmentExpression assignment = statement.expression;
- expect(assignment.operator.type, TokenType.EQ);
- expect(assignment.staticElement, isNull);
- expect(assignment.staticType, typeProvider.intType);
-
- SimpleIdentifier left = assignment.leftHandSide;
- expect(left.staticElement, same(v.setter));
- expect(left.staticType, typeProvider.numType);
-
- Expression right = assignment.rightHandSide;
- expect(right.staticType, typeProvider.intType);
- }
- }
-
- test_binaryExpression() async {
- String content = r'''
-main() {
- var v = 1 + 2;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableDeclarationStatement statement = mainStatements[0];
- VariableDeclaration vNode = statement.variables.variables[0];
- VariableElement vElement = vNode.element;
- expect(vElement.type, typeProvider.intType);
-
- BinaryExpression value = vNode.initializer;
- expect(value.leftOperand.staticType, typeProvider.intType);
- expect(value.rightOperand.staticType, typeProvider.intType);
- expect(value.staticElement.name, '+');
- expect(value.staticType, typeProvider.intType);
- }
-
- test_binaryExpression_ifNull() async {
- String content = r'''
-main() {
- 1.2 ?? 3;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- ExpressionStatement statement = mainStatements[0];
- BinaryExpression binary = statement.expression;
- expect(binary.operator.type, TokenType.QUESTION_QUESTION);
- expect(binary.staticElement, isNull);
- expect(binary.staticType, typeProvider.numType);
-
- expect(binary.leftOperand.staticType, typeProvider.doubleType);
- expect(binary.rightOperand.staticType, typeProvider.intType);
- }
-
- test_binaryExpression_logical() async {
- addTestFile(r'''
-main() {
- true && true;
- true || true;
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = statements[0];
- BinaryExpression binaryExpression = statement.expression;
- expect(binaryExpression.staticElement, isNull);
- expect(binaryExpression.staticType, typeProvider.boolType);
- }
-
- {
- ExpressionStatement statement = statements[1];
- BinaryExpression binaryExpression = statement.expression;
- expect(binaryExpression.staticElement, isNull);
- expect(binaryExpression.staticType, typeProvider.boolType);
- }
- }
-
- test_binaryExpression_notEqual() async {
- String content = r'''
-main() {
- 1 != 2;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
- ExpressionStatement statement = statements[0];
- BinaryExpression expression = statement.expression;
- expect(expression.operator.type, TokenType.BANG_EQ);
- expect(expression.leftOperand.staticType, typeProvider.intType);
- expect(expression.rightOperand.staticType, typeProvider.intType);
- expect(expression.staticElement.name, '==');
- expect(expression.staticType, typeProvider.boolType);
- }
-
- test_cascadeExpression() async {
- String content = r'''
-void main() {
- new A()..a()..b();
-}
-class A {
- void a() {}
- void b() {}
-}
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
-
- List<Statement> statements = _getMainStatements(result);
-
- ExpressionStatement statement = statements[0];
- CascadeExpression expression = statement.expression;
- expect(expression.target.staticType, isNotNull);
- NodeList<Expression> sections = expression.cascadeSections;
-
- MethodInvocation a = sections[0];
- expect(a.methodName.staticElement, isNotNull);
- expect(a.staticType, isNotNull);
-
- MethodInvocation b = sections[1];
- expect(b.methodName.staticElement, isNotNull);
- expect(b.staticType, isNotNull);
- }
-
- test_closure() async {
- addTestFile(r'''
-main() {
- var items = <int>[1, 2, 3];
- items.forEach((item) {
- item;
- });
- items.forEach((item) {
- item;
- });
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- FunctionDeclaration mainDeclaration = result.unit.declarations[0];
- FunctionElement mainElement = mainDeclaration.element;
- BlockFunctionBody mainBody = mainDeclaration.functionExpression.body;
- List<Statement> mainStatements = mainBody.block.statements;
-
- VariableDeclarationStatement itemsStatement = mainStatements[0];
- var itemsElement = itemsStatement.variables.variables[0].element;
-
- // First closure.
- ParameterElement itemElement1;
- {
- ExpressionStatement forStatement = mainStatements[1];
- MethodInvocation forInvocation = forStatement.expression;
-
- SimpleIdentifier forTarget = forInvocation.target;
- expect(forTarget.staticElement, itemsElement);
-
- var closureTypeStr = '(int) → Null';
- FunctionExpression closure = forInvocation.argumentList.arguments[0];
-
- FunctionElementImpl closureElement = closure.element;
- expect(closureElement.enclosingElement, same(mainElement));
-
- ParameterElement itemElement = closureElement.parameters[0];
- itemElement1 = itemElement;
-
- expect(closureElement.returnType, typeProvider.nullType);
- expect(closureElement.type.element, same(closureElement));
- expect(closureElement.type.toString(), closureTypeStr);
- expect(closure.staticType, same(closureElement.type));
-
- List<FormalParameter> closureParameters = closure.parameters.parameters;
- expect(closureParameters, hasLength(1));
-
- SimpleFormalParameter itemNode = closureParameters[0];
- _assertSimpleParameter(itemNode, itemElement,
- name: 'item',
- offset: 56,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.intType);
-
- BlockFunctionBody closureBody = closure.body;
- List<Statement> closureStatements = closureBody.block.statements;
-
- ExpressionStatement itemStatement = closureStatements[0];
- SimpleIdentifier itemIdentifier = itemStatement.expression;
- expect(itemIdentifier.staticElement, itemElement);
- expect(itemIdentifier.staticType, typeProvider.intType);
- }
-
- // Second closure, same names, different elements.
- {
- ExpressionStatement forStatement = mainStatements[2];
- MethodInvocation forInvocation = forStatement.expression;
-
- SimpleIdentifier forTarget = forInvocation.target;
- expect(forTarget.staticElement, itemsElement);
-
- var closureTypeStr = '(int) → Null';
- FunctionExpression closure = forInvocation.argumentList.arguments[0];
-
- FunctionElementImpl closureElement = closure.element;
- expect(closureElement.enclosingElement, same(mainElement));
-
- ParameterElement itemElement = closureElement.parameters[0];
- expect(itemElement, isNot(same(itemElement1)));
-
- expect(closureElement.returnType, typeProvider.nullType);
- expect(closureElement.type.element, same(closureElement));
- expect(closureElement.type.toString(), closureTypeStr);
- expect(closure.staticType, same(closureElement.type));
-
- List<FormalParameter> closureParameters = closure.parameters.parameters;
- expect(closureParameters, hasLength(1));
-
- SimpleFormalParameter itemNode = closureParameters[0];
- _assertSimpleParameter(itemNode, itemElement,
- name: 'item',
- offset: 97,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.intType);
-
- BlockFunctionBody closureBody = closure.body;
- List<Statement> closureStatements = closureBody.block.statements;
-
- ExpressionStatement itemStatement = closureStatements[0];
- SimpleIdentifier itemIdentifier = itemStatement.expression;
- expect(itemIdentifier.staticElement, itemElement);
- expect(itemIdentifier.staticType, typeProvider.intType);
- }
- }
-
- test_conditionalExpression() async {
- String content = r'''
-void main() {
- true ? 1 : 2.3;
-}
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- ExpressionStatement statement = statements[0];
- ConditionalExpression expression = statement.expression;
- expect(expression.staticType, typeProvider.numType);
- expect(expression.condition.staticType, typeProvider.boolType);
- expect(expression.thenExpression.staticType, typeProvider.intType);
- expect(expression.elseExpression.staticType, typeProvider.doubleType);
- }
-
- test_constructor_context() async {
- addTestFile(r'''
-class C {
- C(int p) {
- p;
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration cNode = result.unit.declarations[0];
-
- ConstructorDeclaration constructorNode = cNode.members[0];
- ParameterElement pElement = constructorNode.element.parameters[0];
-
- BlockFunctionBody constructorBody = constructorNode.body;
- ExpressionStatement pStatement = constructorBody.block.statements[0];
-
- SimpleIdentifier pIdentifier = pStatement.expression;
- expect(pIdentifier.staticElement, same(pElement));
- expect(pIdentifier.staticType, typeProvider.intType);
- }
-
- test_constructor_initializer_field() async {
- addTestFile(r'''
-class C {
- int f;
- C(int p) : f = p {
- f;
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- ClassDeclaration cNode = result.unit.declarations[0];
- ClassElement cElement = cNode.element;
- FieldElement fElement = cElement.getField('f');
-
- ConstructorDeclaration constructorNode = cNode.members[1];
- ParameterElement pParameterElement = constructorNode.element.parameters[0];
-
- {
- ConstructorFieldInitializer initializer = constructorNode.initializers[0];
- expect(initializer.fieldName.staticElement, same(fElement));
-
- SimpleIdentifier expression = initializer.expression;
- expect(expression.staticElement, same(pParameterElement));
- }
- }
-
- test_constructor_initializer_super() async {
- addTestFile(r'''
-class A {
- A(int a);
- A.named(int a, {int b});
-}
-class B extends A {
- B.one(int p) : super(p + 1);
- B.two(int p) : super.named(p + 1, b: p + 2);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- ClassDeclaration aNode = result.unit.declarations[0];
- ClassElement aElement = aNode.element;
-
- ClassDeclaration bNode = result.unit.declarations[1];
-
- {
- ConstructorDeclaration constructor = bNode.members[0];
- SuperConstructorInvocation initializer = constructor.initializers[0];
- expect(initializer.staticElement, same(aElement.unnamedConstructor));
- expect(initializer.constructorName, isNull);
- }
-
- {
- var namedConstructor = aElement.getNamedConstructor('named');
-
- ConstructorDeclaration constructor = bNode.members[1];
- SuperConstructorInvocation initializer = constructor.initializers[0];
- expect(initializer.staticElement, same(namedConstructor));
-
- var constructorName = initializer.constructorName;
- expect(constructorName.staticElement, same(namedConstructor));
- expect(constructorName.staticType, isNull);
-
- List<Expression> arguments = initializer.argumentList.arguments;
- _assertArgumentToParameter(arguments[0], namedConstructor.parameters[0]);
- _assertArgumentToParameter(arguments[1], namedConstructor.parameters[1]);
- }
- }
-
- test_constructor_initializer_this() async {
- addTestFile(r'''
-class C {
- C(int a, [int b]);
- C.named(int a, {int b});
- C.one(int p) : this(1, 2);
- C.two(int p) : this.named(3, b: 4);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- ClassDeclaration cNode = result.unit.declarations[0];
- ClassElement cElement = cNode.element;
-
- {
- var unnamedConstructor = cElement.constructors[0];
-
- ConstructorDeclaration constructor = cNode.members[2];
- RedirectingConstructorInvocation initializer =
- constructor.initializers[0];
- expect(initializer.staticElement, same(unnamedConstructor));
- expect(initializer.constructorName, isNull);
-
- List<Expression> arguments = initializer.argumentList.arguments;
- _assertArgumentToParameter(
- arguments[0], unnamedConstructor.parameters[0]);
- _assertArgumentToParameter(
- arguments[1], unnamedConstructor.parameters[1]);
- }
-
- {
- var namedConstructor = cElement.constructors[1];
-
- ConstructorDeclaration constructor = cNode.members[3];
- RedirectingConstructorInvocation initializer =
- constructor.initializers[0];
- expect(initializer.staticElement, same(namedConstructor));
-
- var constructorName = initializer.constructorName;
- expect(constructorName.staticElement, same(namedConstructor));
- expect(constructorName.staticType, isNull);
-
- List<Expression> arguments = initializer.argumentList.arguments;
- _assertArgumentToParameter(arguments[0], namedConstructor.parameters[0]);
- _assertArgumentToParameter(arguments[1], namedConstructor.parameters[1]);
- }
- }
-
- test_constructor_redirected() async {
- addTestFile(r'''
-class A implements B {
- A(int a);
- A.named(double a);
-}
-class B {
- factory B.one(int b) = A;
- factory B.two(double b) = A.named;
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.errors, isEmpty);
-
- ClassDeclaration aNode = result.unit.declarations[0];
- ClassElement aElement = aNode.element;
-
- ClassDeclaration bNode = result.unit.declarations[1];
-
- {
- ConstructorElement aUnnamed = aElement.constructors[0];
-
- ConstructorDeclaration constructor = bNode.members[0];
- ConstructorElement element = constructor.element;
- expect(element.redirectedConstructor, same(aUnnamed));
-
- var constructorName = constructor.redirectedConstructor;
- expect(constructorName.staticElement, same(aUnnamed));
-
- TypeName typeName = constructorName.type;
- expect(typeName.type, aElement.type);
-
- SimpleIdentifier identifier = typeName.name;
- expect(identifier.staticElement, same(aElement));
- expect(identifier.staticType, aElement.type);
-
- expect(constructorName.name, isNull);
- }
-
- {
- ConstructorElement aNamed = aElement.constructors[1];
-
- ConstructorDeclaration constructor = bNode.members[1];
- ConstructorElement element = constructor.element;
- expect(element.redirectedConstructor, same(aNamed));
-
- var constructorName = constructor.redirectedConstructor;
- expect(constructorName.staticElement, same(aNamed));
-
- TypeName typeName = constructorName.type;
- expect(typeName.type, aElement.type);
-
- SimpleIdentifier identifier = typeName.name;
- expect(identifier.staticElement, same(aElement));
- expect(identifier.staticType, aElement.type);
-
- expect(constructorName.name.staticElement, aNamed);
- expect(constructorName.name.staticType, isNull);
- }
- }
-
- test_constructor_redirected_generic() async {
- addTestFile(r'''
-class A<T> implements B<T> {
- A(int a);
- A.named(double a);
-}
-class B<U> {
- factory B.one(int b) = A<U>;
- factory B.two(double b) = A<U>.named;
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.errors, isEmpty);
-
- ClassDeclaration aNode = result.unit.declarations[0];
- ClassElement aElement = aNode.element;
-
- ClassDeclaration bNode = result.unit.declarations[1];
- TypeParameterType uType = bNode.element.typeParameters[0].type;
- InterfaceType auType = aElement.type.instantiate([uType]);
-
- {
- ConstructorElement expectedElement = aElement.constructors[0];
-
- ConstructorDeclaration constructor = bNode.members[0];
- ConstructorElement element = constructor.element;
-
- ConstructorMember actualMember = element.redirectedConstructor;
- expect(actualMember.baseElement, same(expectedElement));
- expect(actualMember.definingType, auType);
-
- var constructorName = constructor.redirectedConstructor;
- expect(constructorName.staticElement, same(actualMember));
-
- TypeName typeName = constructorName.type;
- expect(typeName.type, auType);
-
- SimpleIdentifier identifier = typeName.name;
- expect(identifier.staticElement, same(aElement));
- expect(identifier.staticType, auType);
-
- expect(constructorName.name, isNull);
- }
-
- {
- ConstructorElement expectedElement = aElement.constructors[1];
-
- ConstructorDeclaration constructor = bNode.members[1];
- ConstructorElement element = constructor.element;
-
- ConstructorMember actualMember = element.redirectedConstructor;
- expect(actualMember.baseElement, same(expectedElement));
- expect(actualMember.definingType, auType);
-
- var constructorName = constructor.redirectedConstructor;
- expect(constructorName.staticElement, same(actualMember));
-
- TypeName typeName = constructorName.type;
- expect(typeName.type, auType);
-
- SimpleIdentifier identifier = typeName.name;
- expect(identifier.staticElement, same(aElement));
- expect(identifier.staticType, auType);
-
- expect(constructorName.name.staticElement, same(actualMember));
- expect(constructorName.name.staticType, isNull);
- }
- }
-
- test_enum_toString() async {
- addTestFile(r'''
-enum MyEnum { A, B, C }
-main(MyEnum e) {
- e.toString();
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- EnumDeclaration enumNode = result.unit.declarations[0];
- ClassElement enumElement = enumNode.element;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- expect(invocation.staticInvokeType.toString(), '() → String');
-
- MethodElement methodElement = invocation.methodName.staticElement;
- expect(methodElement.name, 'toString');
- expect(methodElement.enclosingElement, same(enumElement));
- }
-
- test_error_unresolvedTypeAnnotation() async {
- String content = r'''
-main() {
- Foo<int> v = null;
-}
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- var statements = _getMainStatements(result);
-
- VariableDeclarationStatement statement = statements[0];
-
- TypeName typeName = statement.variables.type;
- expect(typeName.type, isUndefinedType);
- if (useCFE) {
- expect(typeName.typeArguments.arguments[0].type, isUndefinedType);
- } else {
- expect(typeName.typeArguments.arguments[0].type, typeProvider.intType);
- }
-
- VariableDeclaration vNode = statement.variables.variables[0];
- expect(vNode.name.staticType, isUndefinedType);
- expect(vNode.element.type, isUndefinedType);
- }
-
- test_field_context() async {
- addTestFile(r'''
-class C<T> {
- var f = <T>[];
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration cNode = result.unit.declarations[0];
- var tElement = cNode.element.typeParameters[0];
-
- FieldDeclaration fDeclaration = cNode.members[0];
- VariableDeclaration fNode = fDeclaration.fields.variables[0];
- FieldElement fElement = fNode.element;
- expect(fElement.type, typeProvider.listType.instantiate([tElement.type]));
- }
-
- test_formalParameter_functionTyped() async {
- addTestFile(r'''
-class A {
- A(String p(int a));
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration clazz = result.unit.declarations[0];
- ConstructorDeclaration constructor = clazz.members[0];
- List<FormalParameter> parameters = constructor.parameters.parameters;
-
- FunctionTypedFormalParameter p = parameters[0];
- expect(p.element, same(constructor.element.parameters[0]));
-
- {
- FunctionType type = p.identifier.staticType;
- expect(type.returnType, typeProvider.stringType);
-
- expect(type.parameters, hasLength(1));
- expect(type.parameters[0].type, typeProvider.intType);
- }
-
- _assertTypeNameSimple(p.returnType, typeProvider.stringType);
-
- {
- SimpleFormalParameter a = p.parameters.parameters[0];
- _assertTypeNameSimple(a.type, typeProvider.intType);
- expect(a.identifier.staticType, typeProvider.intType);
- }
- }
-
- test_formalParameter_functionTyped_fieldFormal_typed() async {
- // TODO(scheglov) Add "untyped" version with precise type in field.
- addTestFile(r'''
-class A {
- Function f;
- A(String this.f(int a));
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration clazz = result.unit.declarations[0];
-
- FieldDeclaration fDeclaration = clazz.members[0];
- VariableDeclaration fNode = fDeclaration.fields.variables[0];
- FieldElement fElement = fNode.element;
-
- ConstructorDeclaration constructor = clazz.members[1];
-
- FieldFormalParameterElement pElement = constructor.element.parameters[0];
- expect(pElement.field, same(fElement));
-
- List<FormalParameter> parameters = constructor.parameters.parameters;
- FieldFormalParameter p = parameters[0];
- expect(p.element, same(pElement));
-
- expect(p.identifier.staticElement, same(pElement));
- expect(p.identifier.staticType.toString(), '(int) → String');
-
- {
- FunctionType type = p.identifier.staticType;
- expect(type.returnType, typeProvider.stringType);
-
- expect(type.parameters, hasLength(1));
- expect(type.parameters[0].type, typeProvider.intType);
- }
-
- _assertTypeNameSimple(p.type, typeProvider.stringType);
-
- {
- SimpleFormalParameter a = p.parameters.parameters[0];
- _assertTypeNameSimple(a.type, typeProvider.intType);
- expect(a.identifier.staticType, typeProvider.intType);
- }
- }
-
- test_formalParameter_simple_fieldFormal() async {
- addTestFile(r'''
-class A {
- int f;
- A(this.f);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration clazz = result.unit.declarations[0];
-
- FieldDeclaration fDeclaration = clazz.members[0];
- VariableDeclaration fNode = fDeclaration.fields.variables[0];
- FieldElement fElement = fNode.element;
-
- ConstructorDeclaration constructor = clazz.members[1];
- List<FormalParameter> parameters = constructor.parameters.parameters;
-
- FieldFormalParameterElement parameterElement =
- constructor.element.parameters[0];
- expect(parameterElement.field, same(fElement));
-
- FieldFormalParameter parameterNode = parameters[0];
- expect(parameterNode.type, isNull);
- expect(parameterNode.element, same(parameterElement));
-
- expect(parameterNode.identifier.staticElement, same(parameterElement));
- expect(parameterNode.identifier.staticType, typeProvider.intType);
- }
-
- test_formalParameter_simple_fieldFormal_typed() async {
- addTestFile(r'''
-class A {
- int f;
- A(int this.f);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration clazz = result.unit.declarations[0];
-
- FieldDeclaration fDeclaration = clazz.members[0];
- VariableDeclaration fNode = fDeclaration.fields.variables[0];
- FieldElement fElement = fNode.element;
-
- ConstructorDeclaration constructor = clazz.members[1];
- List<FormalParameter> parameters = constructor.parameters.parameters;
-
- FieldFormalParameterElement parameterElement =
- constructor.element.parameters[0];
- expect(parameterElement.field, same(fElement));
-
- FieldFormalParameter parameterNode = parameters[0];
- _assertTypeNameSimple(parameterNode.type, typeProvider.intType);
- expect(parameterNode.element, same(parameterElement));
-
- expect(parameterNode.identifier.staticElement, same(parameterElement));
- expect(parameterNode.identifier.staticType, typeProvider.intType);
- }
-
- test_forwardingStub_class() async {
- addTestFile(r'''
-class A<T> {
- void m(T t) {}
-}
-class B extends A<int> {}
-main(B b) {
- b.m(1);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- ClassDeclaration aNode = result.unit.declarations[0];
- ClassElement eElement = aNode.element;
- MethodElement mElement = eElement.getMethod('m');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- expect(invocation.staticInvokeType.toString(), '(int) → void');
- if (useCFE) {
- expect(invocation.methodName.staticElement, same(mElement));
- }
- }
-
- test_functionExpressionInvocation() async {
- addTestFile(r'''
-typedef Foo<S> = S Function<T>(T x);
-void main(f) {
- (f as Foo<int>)<String>('hello');
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- ExpressionStatement statement = statements[0];
- FunctionExpressionInvocation invocation = statement.expression;
-
- expect(invocation.staticElement, isNull);
- expect(invocation.staticInvokeType.toString(), '(String) → int');
- expect(invocation.staticType, typeProvider.intType);
-
- List<TypeAnnotation> typeArguments = invocation.typeArguments.arguments;
- expect(typeArguments, hasLength(1));
- _assertTypeNameSimple(typeArguments[0], typeProvider.stringType);
- }
-
- test_indexExpression() async {
- String content = r'''
-main() {
- var items = <int>[1, 2, 3];
- items[0];
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
-
- var typeProvider = unit.element.context.typeProvider;
- InterfaceType intType = typeProvider.intType;
- InterfaceType listType = typeProvider.listType;
- InterfaceType listIntType = listType.instantiate([intType]);
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement itemsElement;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- VariableDeclaration itemsNode = statement.variables.variables[0];
- itemsElement = itemsNode.element;
- expect(itemsElement.type, listIntType);
- }
-
- ExpressionStatement statement = mainStatements[1];
- IndexExpression indexExpression = statement.expression;
- expect(indexExpression.staticType, intType);
-
- MethodMember actualElement = indexExpression.staticElement;
- MethodMember expectedElement = listIntType.getMethod('[]');
- expect(actualElement.name, '[]');
- expect(actualElement.baseElement, same(expectedElement.baseElement));
- expect(actualElement.returnType, intType);
- expect(actualElement.parameters[0].type, intType);
- }
-
- test_instanceCreation_factory() async {
- String content = r'''
-class C {
- factory C() => null;
- factory C.named() => null;
-}
-var a = new C();
-var b = new C.named();
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
-
- ClassDeclaration cNode = unit.declarations[0];
- ClassElement cElement = cNode.element;
- ConstructorElement defaultConstructor = cElement.constructors[0];
- ConstructorElement namedConstructor = cElement.constructors[1];
-
- {
- TopLevelVariableDeclaration aDeclaration = unit.declarations[1];
- VariableDeclaration aNode = aDeclaration.variables.variables[0];
- InstanceCreationExpression value = aNode.initializer;
- expect(value.staticElement, defaultConstructor);
- expect(value.staticType, cElement.type);
-
- TypeName typeName = value.constructorName.type;
- expect(typeName.typeArguments, isNull);
-
- Identifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, cElement.type);
-
- expect(value.constructorName.name, isNull);
- }
-
- {
- TopLevelVariableDeclaration bDeclaration = unit.declarations[2];
- VariableDeclaration bNode = bDeclaration.variables.variables[0];
- InstanceCreationExpression value = bNode.initializer;
- expect(value.staticElement, namedConstructor);
- expect(value.staticType, cElement.type);
-
- TypeName typeName = value.constructorName.type;
- expect(typeName.typeArguments, isNull);
-
- SimpleIdentifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, cElement.type);
-
- SimpleIdentifier constructorName = value.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
- }
- }
-
- test_instanceCreation_namedArgument() async {
- addTestFile(r'''
-class X {
- X(int a, {bool b, double c});
-}
-var v = new X(1, b: true, c: 3.0);
-''');
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
-
- ClassDeclaration xNode = unit.declarations[0];
- ClassElement xElement = xNode.element;
- ConstructorElement constructorElement = xElement.constructors[0];
-
- TopLevelVariableDeclaration vDeclaration = unit.declarations[1];
- VariableDeclaration vNode = vDeclaration.variables.variables[0];
-
- InstanceCreationExpression creation = vNode.initializer;
- List<Expression> arguments = creation.argumentList.arguments;
- expect(creation.staticElement, constructorElement);
- expect(creation.staticType, xElement.type);
-
- TypeName typeName = creation.constructorName.type;
- expect(typeName.typeArguments, isNull);
-
- Identifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, xElement);
- expect(typeIdentifier.staticType, xElement.type);
-
- expect(creation.constructorName.name, isNull);
-
- _assertArgumentToParameter(arguments[0], constructorElement.parameters[0]);
- _assertArgumentToParameter(arguments[1], constructorElement.parameters[1]);
- _assertArgumentToParameter(arguments[2], constructorElement.parameters[2]);
- }
-
- test_instanceCreation_noTypeArguments() async {
- String content = r'''
-class C {
- C(int p);
- C.named(int p);
-}
-var a = new C(1);
-var b = new C.named(2);
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
-
- ClassDeclaration cNode = unit.declarations[0];
- ClassElement cElement = cNode.element;
- ConstructorElement defaultConstructor = cElement.constructors[0];
- ConstructorElement namedConstructor = cElement.constructors[1];
-
- {
- TopLevelVariableDeclaration aDeclaration = unit.declarations[1];
- VariableDeclaration aNode = aDeclaration.variables.variables[0];
- InstanceCreationExpression value = aNode.initializer;
- expect(value.staticElement, defaultConstructor);
- expect(value.staticType, cElement.type);
-
- TypeName typeName = value.constructorName.type;
- expect(typeName.typeArguments, isNull);
-
- Identifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, cElement.type);
-
- expect(value.constructorName.name, isNull);
-
- Expression argument = value.argumentList.arguments[0];
- _assertArgumentToParameter(argument, defaultConstructor.parameters[0]);
- }
-
- {
- TopLevelVariableDeclaration bDeclaration = unit.declarations[2];
- VariableDeclaration bNode = bDeclaration.variables.variables[0];
- InstanceCreationExpression value = bNode.initializer;
- expect(value.staticElement, namedConstructor);
- expect(value.staticType, cElement.type);
-
- TypeName typeName = value.constructorName.type;
- expect(typeName.typeArguments, isNull);
-
- SimpleIdentifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, cElement.type);
-
- SimpleIdentifier constructorName = value.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
-
- Expression argument = value.argumentList.arguments[0];
- _assertArgumentToParameter(argument, namedConstructor.parameters[0]);
- }
- }
-
- test_instanceCreation_prefixed() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
-class C<T> {
- C(T p);
- C.named(T p);
-}
-''');
- addTestFile(r'''
-import 'a.dart' as p;
-main() {
- new p.C(0);
- new p.C.named(1.2);
- new p.C<bool>.named(false);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ImportElement aImport = unit.element.library.imports[0];
- LibraryElement aLibrary = aImport.importedLibrary;
-
- ClassElement cElement = aLibrary.getType('C');
- ConstructorElement defaultConstructor = cElement.constructors[0];
- ConstructorElement namedConstructor = cElement.constructors[1];
- InterfaceType cType = cElement.type;
- var cTypeDynamic = cType.instantiate([DynamicTypeImpl.instance]);
-
- var statements = _getMainStatements(result);
- {
- var cTypeInt = cType.instantiate([typeProvider.intType]);
-
- ExpressionStatement statement = statements[0];
- InstanceCreationExpression creation = statement.expression;
- expect(creation.staticElement, defaultConstructor);
- expect(creation.staticType, cTypeInt);
-
- TypeName typeName = creation.constructorName.type;
- expect(typeName.typeArguments, isNull);
-
- PrefixedIdentifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, same(cElement));
- if (useCFE) {
- expect(typeIdentifier.staticType, cTypeInt);
- } else {
- expect(typeIdentifier.staticType, cTypeDynamic);
- }
-
- SimpleIdentifier typePrefix = typeIdentifier.prefix;
- expect(typePrefix.name, 'p');
- expect(typePrefix.staticElement, same(aImport.prefix));
- expect(typePrefix.staticType, isNull);
-
- expect(typeIdentifier.identifier.staticElement, same(cElement));
-
- expect(creation.constructorName.name, isNull);
- }
-
- {
- var cTypeDouble = cType.instantiate([typeProvider.doubleType]);
-
- ExpressionStatement statement = statements[1];
- InstanceCreationExpression creation = statement.expression;
- expect(creation.staticElement, namedConstructor);
- expect(creation.staticType, cTypeDouble);
-
- TypeName typeName = creation.constructorName.type;
- expect(typeName.typeArguments, isNull);
-
- PrefixedIdentifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, cElement);
- if (useCFE) {
- expect(typeIdentifier.staticType, cTypeDouble);
- } else {
- expect(typeIdentifier.staticType, cTypeDynamic);
- }
-
- SimpleIdentifier typePrefix = typeIdentifier.prefix;
- expect(typePrefix.name, 'p');
- expect(typePrefix.staticElement, same(aImport.prefix));
- expect(typePrefix.staticType, isNull);
-
- expect(typeIdentifier.identifier.staticElement, same(cElement));
-
- SimpleIdentifier constructorName = creation.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
- }
-
- {
- var cTypeBool = cType.instantiate([typeProvider.boolType]);
-
- ExpressionStatement statement = statements[2];
- InstanceCreationExpression creation = statement.expression;
- expect(creation.staticElement, namedConstructor);
- expect(creation.staticType, cTypeBool);
-
- TypeName typeName = creation.constructorName.type;
- expect(typeName.typeArguments.arguments, hasLength(1));
- _assertTypeNameSimple(
- typeName.typeArguments.arguments[0], typeProvider.boolType);
-
- PrefixedIdentifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, cTypeBool);
-
- SimpleIdentifier typePrefix = typeIdentifier.prefix;
- expect(typePrefix.name, 'p');
- expect(typePrefix.staticElement, same(aImport.prefix));
- expect(typePrefix.staticType, isNull);
-
- expect(typeIdentifier.identifier.staticElement, same(cElement));
-
- SimpleIdentifier constructorName = creation.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
- }
- }
-
- test_instanceCreation_withTypeArguments() async {
- String content = r'''
-class C<K, V> {
- C(K k, V v);
- C.named(K k, V v);
-}
-var a = new C<int, double>(1, 2.3);
-var b = new C<num, String>.named(4, 'five');
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cNode = unit.declarations[0];
- ClassElement cElement = cNode.element;
- ConstructorElement defaultConstructor = cElement.constructors[0];
- ConstructorElement namedConstructor = cElement.constructors[1];
-
- {
- TopLevelVariableDeclaration aDeclaration = unit.declarations[1];
- VariableDeclaration aNode = aDeclaration.variables.variables[0];
-
- InstanceCreationExpression value = aNode.initializer;
- InterfaceType instantiatedType = cElement.type
- .instantiate([typeProvider.intType, typeProvider.doubleType]);
-
- expect(value.staticElement, defaultConstructor);
- expect(value.staticType, instantiatedType);
-
- TypeName typeName = value.constructorName.type;
-
- Identifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, instantiatedType);
-
- TypeName typeArgument1 = typeName.typeArguments.arguments[0];
- expect(typeArgument1.type, typeProvider.intType);
- expect(typeArgument1.name.staticType, typeProvider.intType);
- expect(typeArgument1.name.staticElement, typeProvider.intType.element);
-
- TypeName typeArgument2 = typeName.typeArguments.arguments[1];
- expect(typeArgument2.type, typeProvider.doubleType);
- expect(typeArgument2.name.staticType, typeProvider.doubleType);
- expect(typeArgument2.name.staticElement, typeProvider.doubleType.element);
-
- expect(value.constructorName.name, isNull);
-
- Expression argument = value.argumentList.arguments[0];
- _assertArgumentToParameter(argument, defaultConstructor.parameters[0]);
- }
-
- {
- TopLevelVariableDeclaration bDeclaration = unit.declarations[2];
- VariableDeclaration bNode = bDeclaration.variables.variables[0];
-
- InstanceCreationExpression value = bNode.initializer;
- InterfaceType instantiatedType = cElement.type
- .instantiate([typeProvider.numType, typeProvider.stringType]);
-
- expect(value.staticElement, namedConstructor);
- expect(value.staticType, instantiatedType);
-
- TypeName typeName = value.constructorName.type;
-
- SimpleIdentifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, cElement);
- expect(typeIdentifier.staticType, instantiatedType);
-
- TypeName typeArgument1 = typeName.typeArguments.arguments[0];
- expect(typeArgument1.type, typeProvider.numType);
- expect(typeArgument1.name.staticType, typeProvider.numType);
- expect(typeArgument1.name.staticElement, typeProvider.numType.element);
-
- TypeName typeArgument2 = typeName.typeArguments.arguments[1];
- expect(typeArgument2.type, typeProvider.stringType);
- expect(typeArgument2.name.staticType, typeProvider.stringType);
- expect(typeArgument2.name.staticElement, typeProvider.stringType.element);
-
- SimpleIdentifier constructorName = value.constructorName.name;
- expect(constructorName.staticElement, namedConstructor);
- expect(constructorName.staticType, isNull);
-
- Expression argument = value.argumentList.arguments[0];
- _assertArgumentToParameter(argument, namedConstructor.parameters[0]);
- }
- }
-
- test_isExpression() async {
- String content = r'''
-void main() {
- var v = 42;
- v is num;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.path, testFile);
- expect(result.errors, isEmpty);
-
- var typeProvider = result.unit.element.context.typeProvider;
- NodeList<Statement> statements = _getMainStatements(result);
-
- // var v = 42;
- VariableElement vElement;
- {
- VariableDeclarationStatement statement = statements[0];
- vElement = statement.variables.variables[0].name.staticElement;
- }
-
- // v is num;
- {
- ExpressionStatement statement = statements[1];
- IsExpression isExpression = statement.expression;
- expect(isExpression.notOperator, isNull);
- expect(isExpression.staticType, typeProvider.boolType);
-
- SimpleIdentifier target = isExpression.expression;
- expect(target.staticElement, vElement);
- expect(target.staticType, typeProvider.intType);
-
- TypeName numName = isExpression.type;
- expect(numName.name.staticElement, typeProvider.numType.element);
- expect(numName.name.staticType, typeProvider.numType);
- }
- }
-
- test_isExpression_not() async {
- String content = r'''
-void main() {
- var v = 42;
- v is! num;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.path, testFile);
- expect(result.errors, isEmpty);
-
- var typeProvider = result.unit.element.context.typeProvider;
- NodeList<Statement> statements = _getMainStatements(result);
-
- // var v = 42;
- VariableElement vElement;
- {
- VariableDeclarationStatement statement = statements[0];
- vElement = statement.variables.variables[0].name.staticElement;
- }
-
- // v is! num;
- {
- ExpressionStatement statement = statements[1];
- IsExpression isExpression = statement.expression;
- expect(isExpression.notOperator, isNotNull);
- expect(isExpression.staticType, typeProvider.boolType);
-
- SimpleIdentifier target = isExpression.expression;
- expect(target.staticElement, vElement);
- expect(target.staticType, typeProvider.intType);
-
- TypeName numName = isExpression.type;
- expect(numName.name.staticElement, typeProvider.numType.element);
- expect(numName.name.staticType, typeProvider.numType);
- }
- }
-
- test_label_while() async {
- addTestFile(r'''
-main() {
- myLabel:
- while (true) {
- continue myLabel;
- break myLabel;
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- List<Statement> statements = _getMainStatements(result);
-
- LabeledStatement statement = statements[0];
-
- Label label = statement.labels.single;
- LabelElement labelElement = label.label.staticElement;
-
- WhileStatement whileStatement = statement.statement;
- Block whileBlock = whileStatement.body;
-
- ContinueStatement continueStatement = whileBlock.statements[0];
- expect(continueStatement.label.staticElement, same(labelElement));
- expect(continueStatement.label.staticType, isNull);
-
- BreakStatement breakStatement = whileBlock.statements[1];
- expect(breakStatement.label.staticElement, same(labelElement));
- expect(breakStatement.label.staticType, isNull);
- }
-
- test_local_function() async {
- addTestFile(r'''
-void main() {
- double f(int a, String b) {}
- var v = f(1, '2');
-}
-''');
- String fTypeString = '(int, String) → double';
-
- AnalysisResult result = await driver.getResult(testFile);
- List<Statement> mainStatements = _getMainStatements(result);
-
- var typeProvider = result.unit.element.context.typeProvider;
- InterfaceType doubleType = typeProvider.doubleType;
-
- FunctionDeclarationStatement fStatement = mainStatements[0];
- FunctionDeclaration fNode = fStatement.functionDeclaration;
- FunctionExpression fExpression = fNode.functionExpression;
- FunctionElement fElement = fNode.element;
- expect(fElement, isNotNull);
- expect(fElement.type.toString(), fTypeString);
-
- expect(fNode.name.staticElement, same(fElement));
- expect(fNode.name.staticType, fElement.type);
-
- TypeName fReturnTypeNode = fNode.returnType;
- expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
- expect(fReturnTypeNode.type, doubleType);
-
- expect(fExpression.element, same(fElement));
-
- {
- List<ParameterElement> elements = fElement.parameters;
- expect(elements, hasLength(2));
-
- List<FormalParameter> nodes = fExpression.parameters.parameters;
- expect(nodes, hasLength(2));
-
- _assertSimpleParameter(nodes[0], elements[0],
- name: 'a',
- offset: 29,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.intType);
-
- _assertSimpleParameter(nodes[1], elements[1],
- name: 'b',
- offset: 39,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.stringType);
- }
-
- VariableDeclarationStatement vStatement = mainStatements[1];
- VariableDeclaration vDeclaration = vStatement.variables.variables[0];
- expect(vDeclaration.element.type, same(doubleType));
-
- MethodInvocation fInvocation = vDeclaration.initializer;
- expect(fInvocation.methodName.staticElement, same(fElement));
- expect(fInvocation.methodName.staticType.toString(), fTypeString);
- expect(fInvocation.staticType, same(doubleType));
- expect(fInvocation.staticInvokeType.toString(), fTypeString);
- }
-
- test_local_function_generic() async {
- addTestFile(r'''
-void main() {
- T f<T, U>(T a, U b) {}
- var v = f(1, '2');
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
- List<Statement> mainStatements = _getMainStatements(result);
-
- FunctionDeclarationStatement fStatement = mainStatements[0];
- FunctionDeclaration fNode = fStatement.functionDeclaration;
- FunctionExpression fExpression = fNode.functionExpression;
- FunctionElement fElement = fNode.element;
-
- TypeParameterElement tElement = fElement.typeParameters[0];
- TypeParameterElement uElement = fElement.typeParameters[1];
-
- {
- var fTypeParameters = fExpression.typeParameters.typeParameters;
- expect(fTypeParameters, hasLength(2));
-
- TypeParameter tNode = fTypeParameters[0];
- expect(tNode.element, same(tElement));
- expect(tNode.name.staticElement, same(tElement));
- expect(tNode.name.staticType, typeProvider.typeType);
-
- TypeParameter uNode = fTypeParameters[1];
- expect(uNode.element, same(uElement));
- expect(uNode.name.staticElement, same(uElement));
- expect(uNode.name.staticType, typeProvider.typeType);
- }
-
- expect(fElement, isNotNull);
- expect(fElement.type.toString(), '<T,U>(T, U) → T');
-
- expect(fNode.name.staticElement, same(fElement));
- expect(fNode.name.staticType, fElement.type);
-
- TypeName fReturnTypeNode = fNode.returnType;
- expect(fReturnTypeNode.name.staticElement, same(tElement));
- expect(fReturnTypeNode.type, tElement.type);
-
- expect(fExpression.element, same(fElement));
-
- {
- List<ParameterElement> elements = fElement.parameters;
- expect(elements, hasLength(2));
-
- List<FormalParameter> nodes = fExpression.parameters.parameters;
- expect(nodes, hasLength(2));
-
- _assertSimpleParameter(nodes[0], elements[0],
- name: 'a',
- offset: 28,
- kind: ParameterKind.REQUIRED,
- type: tElement.type);
-
- _assertSimpleParameter(nodes[1], elements[1],
- name: 'b',
- offset: 33,
- kind: ParameterKind.REQUIRED,
- type: uElement.type);
- }
-
- VariableDeclarationStatement vStatement = mainStatements[1];
- VariableDeclaration vDeclaration = vStatement.variables.variables[0];
- expect(vDeclaration.element.type, typeProvider.intType);
-
- MethodInvocation fInvocation = vDeclaration.initializer;
- expect(fInvocation.methodName.staticElement, same(fElement));
- expect(fInvocation.staticType, typeProvider.intType);
- // TODO(scheglov) We don't support invoke types well.
-// if (useCFE) {
-// String fInstantiatedType = '(int, String) → int';
-// expect(fInvocation.methodName.staticType.toString(), fInstantiatedType);
-// expect(fInvocation.staticInvokeType.toString(), fInstantiatedType);
-// }
- }
-
- test_local_function_namedParameters() async {
- addTestFile(r'''
-void main() {
- double f(int a, {String b, bool c: false}) {}
- f(1, b: '2', c: true);
-}
-''');
- String fTypeString = '(int, {b: String, c: bool}) → double';
-
- AnalysisResult result = await driver.getResult(testFile);
- List<Statement> mainStatements = _getMainStatements(result);
-
- var typeProvider = result.unit.element.context.typeProvider;
- InterfaceType doubleType = typeProvider.doubleType;
-
- FunctionDeclarationStatement fStatement = mainStatements[0];
- FunctionDeclaration fNode = fStatement.functionDeclaration;
- FunctionExpression fExpression = fNode.functionExpression;
- FunctionElement fElement = fNode.element;
- expect(fElement, isNotNull);
- expect(fElement.type.toString(), fTypeString);
-
- expect(fNode.name.staticElement, same(fElement));
- expect(fNode.name.staticType, fElement.type);
-
- TypeName fReturnTypeNode = fNode.returnType;
- expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
- expect(fReturnTypeNode.type, doubleType);
-
- expect(fExpression.element, same(fElement));
-
- {
- List<ParameterElement> elements = fElement.parameters;
- expect(elements, hasLength(3));
-
- List<FormalParameter> nodes = fExpression.parameters.parameters;
- expect(nodes, hasLength(3));
-
- _assertSimpleParameter(nodes[0], elements[0],
- name: 'a',
- offset: 29,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.intType);
-
- _assertDefaultParameter(nodes[1], elements[1],
- name: 'b',
- offset: 40,
- kind: ParameterKind.NAMED,
- type: typeProvider.stringType);
-
- _assertDefaultParameter(nodes[2], elements[2],
- name: 'c',
- offset: 48,
- kind: ParameterKind.NAMED,
- type: typeProvider.boolType);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
- MethodInvocation invocation = statement.expression;
- List<Expression> arguments = invocation.argumentList.arguments;
-
- _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
- _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
- _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
- }
- }
-
- test_local_function_noReturnType() async {
- addTestFile(r'''
-void main() {
- f() {}
-}
-''');
-
- AnalysisResult result = await driver.getResult(testFile);
- List<Statement> mainStatements = _getMainStatements(result);
-
- FunctionDeclarationStatement fStatement = mainStatements[0];
- FunctionDeclaration fNode = fStatement.functionDeclaration;
- FunctionExpression fExpression = fNode.functionExpression;
- FunctionElement fElement = fNode.element;
-
- expect(fNode.returnType, isNull);
- expect(fElement, isNotNull);
- expect(fElement.type.toString(), '() → Null');
-
- expect(fNode.name.staticElement, same(fElement));
- expect(fNode.name.staticType, fElement.type);
-
- expect(fExpression.element, same(fElement));
- }
-
- test_local_function_optionalParameters() async {
- addTestFile(r'''
-void main() {
- double f(int a, [String b, bool c]) {}
- var v = f(1, '2', true);
-}
-''');
- String fTypeString = '(int, [String, bool]) → double';
-
- AnalysisResult result = await driver.getResult(testFile);
- List<Statement> mainStatements = _getMainStatements(result);
-
- var typeProvider = result.unit.element.context.typeProvider;
- InterfaceType doubleType = typeProvider.doubleType;
-
- FunctionDeclarationStatement fStatement = mainStatements[0];
- FunctionDeclaration fNode = fStatement.functionDeclaration;
- FunctionExpression fExpression = fNode.functionExpression;
- FunctionElement fElement = fNode.element;
- expect(fElement, isNotNull);
- expect(fElement.type.toString(), fTypeString);
-
- expect(fNode.name.staticElement, same(fElement));
- expect(fNode.name.staticType, fElement.type);
-
- TypeName fReturnTypeNode = fNode.returnType;
- expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
- expect(fReturnTypeNode.type, doubleType);
-
- expect(fExpression.element, same(fElement));
-
- {
- List<ParameterElement> elements = fElement.parameters;
- expect(elements, hasLength(3));
-
- List<FormalParameter> nodes = fExpression.parameters.parameters;
- expect(nodes, hasLength(3));
-
- _assertSimpleParameter(nodes[0], elements[0],
- name: 'a',
- offset: 29,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.intType);
-
- _assertDefaultParameter(nodes[1], elements[1],
- name: 'b',
- offset: 40,
- kind: ParameterKind.POSITIONAL,
- type: typeProvider.stringType);
-
- _assertDefaultParameter(nodes[2], elements[2],
- name: 'c',
- offset: 48,
- kind: ParameterKind.POSITIONAL,
- type: typeProvider.boolType);
- }
-
- {
- VariableDeclarationStatement statement = mainStatements[1];
- VariableDeclaration declaration = statement.variables.variables[0];
- expect(declaration.element.type, same(doubleType));
-
- MethodInvocation invocation = declaration.initializer;
- expect(invocation.methodName.staticElement, same(fElement));
- expect(invocation.methodName.staticType.toString(), fTypeString);
- expect(invocation.staticType, same(doubleType));
- expect(invocation.staticInvokeType.toString(), fTypeString);
-
- List<Expression> arguments = invocation.argumentList.arguments;
- _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
- _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
- _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
- }
- }
-
- test_local_parameter() async {
- String content = r'''
-void main(int p) {
- p;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.path, testFile);
- expect(result.errors, isEmpty);
-
- var typeProvider = result.unit.element.context.typeProvider;
- InterfaceType intType = typeProvider.intType;
-
- FunctionDeclaration main = result.unit.declarations[0];
- List<Statement> statements = _getMainStatements(result);
-
- // (int p)
- VariableElement pElement = main.element.parameters[0];
- expect(pElement.type, intType);
-
- // p;
- {
- ExpressionStatement statement = statements[0];
- SimpleIdentifier identifier = statement.expression;
- expect(identifier.staticElement, pElement);
- expect(identifier.staticType, intType);
- }
- }
-
- test_local_parameter_ofLocalFunction() async {
- addTestFile(r'''
-void main() {
- void f(int a) {
- a;
- void g(double b) {
- b;
- }
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- var typeProvider = result.unit.element.context.typeProvider;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- // f(int a) {}
- FunctionDeclarationStatement fStatement = mainStatements[0];
- FunctionDeclaration fNode = fStatement.functionDeclaration;
- FunctionExpression fExpression = fNode.functionExpression;
- FunctionElement fElement = fNode.element;
- ParameterElement aElement = fElement.parameters[0];
- _assertSimpleParameter(fExpression.parameters.parameters[0], aElement,
- name: 'a',
- offset: 27,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.intType);
-
- BlockFunctionBody fBody = fExpression.body;
- List<Statement> fStatements = fBody.block.statements;
-
- // a;
- ExpressionStatement aStatement = fStatements[0];
- SimpleIdentifier aNode = aStatement.expression;
- expect(aNode.staticElement, same(aElement));
- expect(aNode.staticType, typeProvider.intType);
-
- // g(double b) {}
- FunctionDeclarationStatement gStatement = fStatements[1];
- FunctionDeclaration gNode = gStatement.functionDeclaration;
- FunctionExpression gExpression = gNode.functionExpression;
- FunctionElement gElement = gNode.element;
- ParameterElement bElement = gElement.parameters[0];
- _assertSimpleParameter(gExpression.parameters.parameters[0], bElement,
- name: 'b',
- offset: 57,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.doubleType);
-
- BlockFunctionBody gBody = gExpression.body;
- List<Statement> gStatements = gBody.block.statements;
-
- // b;
- ExpressionStatement bStatement = gStatements[0];
- SimpleIdentifier bNode = bStatement.expression;
- expect(bNode.staticElement, same(bElement));
- expect(bNode.staticType, typeProvider.doubleType);
- }
-
- test_local_variable() async {
- addTestFile(r'''
-void main() {
- var v = 42;
- v;
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.path, testFile);
- expect(result.errors, isEmpty);
-
- var typeProvider = result.unit.element.context.typeProvider;
- InterfaceType intType = typeProvider.intType;
-
- FunctionDeclaration main = result.unit.declarations[0];
- expect(main.element, isNotNull);
- expect(main.name.staticElement, isNotNull);
- expect(main.name.staticType.toString(), '() → void');
-
- BlockFunctionBody body = main.functionExpression.body;
- NodeList<Statement> statements = body.block.statements;
-
- // var v = 42;
- VariableElement vElement;
- {
- VariableDeclarationStatement statement = statements[0];
- VariableDeclaration vNode = statement.variables.variables[0];
- expect(vNode.name.staticType, intType);
- expect(vNode.initializer.staticType, intType);
-
- vElement = vNode.name.staticElement;
- expect(vElement, isNotNull);
- expect(vElement.type, isNotNull);
- expect(vElement.type, intType);
- }
-
- // v;
- {
- ExpressionStatement statement = statements[1];
- SimpleIdentifier identifier = statement.expression;
- expect(identifier.staticElement, same(vElement));
- expect(identifier.staticType, intType);
- }
- }
-
- test_local_variable_forIn_identifier_field() async {
- addTestFile(r'''
-class C {
- num v;
- void foo() {
- for (v in <int>[]) {
- v;
- }
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cDeclaration = unit.declarations[0];
-
- FieldDeclaration vDeclaration = cDeclaration.members[0];
- VariableDeclaration vNode = vDeclaration.fields.variables[0];
- FieldElement vElement = vNode.element;
- expect(vElement.type, typeProvider.numType);
-
- MethodDeclaration fooDeclaration = cDeclaration.members[1];
- BlockFunctionBody fooBody = fooDeclaration.body;
- List<Statement> statements = fooBody.block.statements;
-
- ForEachStatement forEachStatement = statements[0];
- Block forBlock = forEachStatement.body;
-
- expect(forEachStatement.loopVariable, isNull);
-
- SimpleIdentifier vInFor = forEachStatement.identifier;
- expect(vInFor.staticElement, same(vElement.setter));
- expect(vInFor.staticType, typeProvider.numType);
-
- ExpressionStatement statement = forBlock.statements[0];
- SimpleIdentifier identifier = statement.expression;
- expect(identifier.staticElement, same(vElement.getter));
- expect(identifier.staticType, typeProvider.numType);
- }
-
- test_local_variable_forIn_identifier_localVariable() async {
- addTestFile(r'''
-void main() {
- num v;
- for (v in <int>[]) {
- v;
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- VariableDeclarationStatement vStatement = statements[0];
- VariableDeclaration vNode = vStatement.variables.variables[0];
- LocalVariableElement vElement = vNode.element;
- expect(vElement.type, typeProvider.numType);
-
- ForEachStatement forEachStatement = statements[1];
- Block forBlock = forEachStatement.body;
-
- expect(forEachStatement.loopVariable, isNull);
-
- SimpleIdentifier vInFor = forEachStatement.identifier;
- expect(vInFor.staticElement, vElement);
- expect(vInFor.staticType, typeProvider.numType);
-
- ExpressionStatement statement = forBlock.statements[0];
- SimpleIdentifier identifier = statement.expression;
- expect(identifier.staticElement, same(vElement));
- expect(identifier.staticType, typeProvider.numType);
- }
-
- test_local_variable_forIn_identifier_topLevelVariable() async {
- addTestFile(r'''
-void main() {
- for (v in <int>[]) {
- v;
- }
-}
-num v;
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- TopLevelVariableDeclaration vDeclaration = unit.declarations[1];
- VariableDeclaration vNode = vDeclaration.variables.variables[0];
- TopLevelVariableElement vElement = vNode.element;
- expect(vElement.type, typeProvider.numType);
-
- ForEachStatement forEachStatement = statements[0];
- Block forBlock = forEachStatement.body;
-
- expect(forEachStatement.loopVariable, isNull);
-
- SimpleIdentifier vInFor = forEachStatement.identifier;
- expect(vInFor.staticElement, same(vElement.setter));
- expect(vInFor.staticType, typeProvider.numType);
-
- ExpressionStatement statement = forBlock.statements[0];
- SimpleIdentifier identifier = statement.expression;
- expect(identifier.staticElement, same(vElement.getter));
- expect(identifier.staticType, typeProvider.numType);
- }
-
- test_local_variable_forIn_loopVariable() async {
- addTestFile(r'''
-void main() {
- for (var v in <int>[]) {
- v;
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- ForEachStatement forEachStatement = statements[0];
- Block forBlock = forEachStatement.body;
-
- DeclaredIdentifier vNode = forEachStatement.loopVariable;
- LocalVariableElement vElement = vNode.element;
- expect(vElement.type, typeProvider.intType);
-
- expect(vNode.identifier.staticElement, vElement);
- expect(vNode.identifier.staticType, typeProvider.intType);
-
- ExpressionStatement statement = forBlock.statements[0];
- SimpleIdentifier identifier = statement.expression;
- expect(identifier.staticElement, vElement);
- expect(identifier.staticType, typeProvider.intType);
- }
-
- test_local_variable_forIn_loopVariable_explicitType() async {
- addTestFile(r'''
-void main() {
- for (num v in <int>[]) {
- v;
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- ForEachStatement forEachStatement = statements[0];
- Block forBlock = forEachStatement.body;
-
- DeclaredIdentifier vNode = forEachStatement.loopVariable;
- LocalVariableElement vElement = vNode.element;
- expect(vElement.type, typeProvider.numType);
-
- TypeName vTypeName = vNode.type;
- expect(vTypeName.type, typeProvider.numType);
-
- SimpleIdentifier vTypeIdentifier = vTypeName.name;
- expect(vTypeIdentifier.staticElement, typeProvider.numType.element);
- expect(vTypeIdentifier.staticType, typeProvider.numType);
-
- expect(vNode.identifier.staticElement, vElement);
- expect(vNode.identifier.staticType, typeProvider.numType);
-
- ExpressionStatement statement = forBlock.statements[0];
- SimpleIdentifier identifier = statement.expression;
- expect(identifier.staticElement, vElement);
- expect(identifier.staticType, typeProvider.numType);
- }
-
- test_local_variable_multiple() async {
- addTestFile(r'''
-void main() {
- var a = 1, b = 2.3;
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- VariableDeclarationStatement declarationStatement = statements[0];
-
- VariableDeclaration aNode = declarationStatement.variables.variables[0];
- LocalVariableElement aElement = aNode.element;
- expect(aElement.type, typeProvider.intType);
-
- VariableDeclaration bNode = declarationStatement.variables.variables[1];
- LocalVariableElement bElement = bNode.element;
- expect(bElement.type, typeProvider.doubleType);
- }
-
- test_local_variable_ofLocalFunction() async {
- addTestFile(r'''
-void main() {
- void f() {
- int a;
- a;
- void g() {
- double b;
- a;
- b;
- }
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- var typeProvider = result.unit.element.context.typeProvider;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- // f() {}
- FunctionDeclarationStatement fStatement = mainStatements[0];
- FunctionDeclaration fNode = fStatement.functionDeclaration;
- BlockFunctionBody fBody = fNode.functionExpression.body;
- List<Statement> fStatements = fBody.block.statements;
-
- // int a;
- VariableDeclarationStatement aDeclaration = fStatements[0];
- VariableElement aElement = aDeclaration.variables.variables[0].element;
-
- // a;
- {
- ExpressionStatement aStatement = fStatements[1];
- SimpleIdentifier aNode = aStatement.expression;
- expect(aNode.staticElement, same(aElement));
- expect(aNode.staticType, typeProvider.intType);
- }
-
- // g(double b) {}
- FunctionDeclarationStatement gStatement = fStatements[2];
- FunctionDeclaration gNode = gStatement.functionDeclaration;
- BlockFunctionBody gBody = gNode.functionExpression.body;
- List<Statement> gStatements = gBody.block.statements;
-
- // double b;
- VariableDeclarationStatement bDeclaration = gStatements[0];
- VariableElement bElement = bDeclaration.variables.variables[0].element;
-
- // a;
- {
- ExpressionStatement aStatement = gStatements[1];
- SimpleIdentifier aNode = aStatement.expression;
- expect(aNode.staticElement, same(aElement));
- expect(aNode.staticType, typeProvider.intType);
- }
-
- // b;
- {
- ExpressionStatement bStatement = gStatements[2];
- SimpleIdentifier bNode = bStatement.expression;
- expect(bNode.staticElement, same(bElement));
- expect(bNode.staticType, typeProvider.doubleType);
- }
- }
-
- test_mapLiteral() async {
- addTestFile(r'''
-void main() {
- <int, double>{};
- const <bool, String>{};
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- var statements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = statements[0];
- MapLiteral mapLiteral = statement.expression;
- expect(
- mapLiteral.staticType,
- typeProvider.mapType
- .instantiate([typeProvider.intType, typeProvider.doubleType]));
- }
-
- {
- ExpressionStatement statement = statements[1];
- MapLiteral mapLiteral = statement.expression;
- expect(
- mapLiteral.staticType,
- typeProvider.mapType
- .instantiate([typeProvider.boolType, typeProvider.stringType]));
- }
- }
-
- test_method_namedParameters() async {
- addTestFile(r'''
-class C {
- double f(int a, {String b, bool c: false}) {}
-}
-void g(C c) {
- c.f(1, b: '2', c: true);
-}
-''');
- String fTypeString = '(int, {b: String, c: bool}) → double';
-
- AnalysisResult result = await driver.getResult(testFile);
- ClassDeclaration classDeclaration = result.unit.declarations[0];
- MethodDeclaration methodDeclaration = classDeclaration.members[0];
- MethodElement methodElement = methodDeclaration.element;
-
- var typeProvider = result.unit.element.context.typeProvider;
- InterfaceType doubleType = typeProvider.doubleType;
-
- expect(methodElement, isNotNull);
- expect(methodElement.type.toString(), fTypeString);
-
- expect(methodDeclaration.name.staticElement, same(methodElement));
- expect(methodDeclaration.name.staticType, methodElement.type);
-
- TypeName fReturnTypeNode = methodDeclaration.returnType;
- expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
- expect(fReturnTypeNode.type, doubleType);
- //
- // Validate the parameters at the declaration site.
- //
- List<ParameterElement> elements = methodElement.parameters;
- expect(elements, hasLength(3));
-
- List<FormalParameter> nodes = methodDeclaration.parameters.parameters;
- expect(nodes, hasLength(3));
-
- _assertSimpleParameter(nodes[0], elements[0],
- name: 'a',
- offset: 25,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.intType);
-
- _assertDefaultParameter(nodes[1], elements[1],
- name: 'b',
- offset: 36,
- kind: ParameterKind.NAMED,
- type: typeProvider.stringType);
-
- _assertDefaultParameter(nodes[2], elements[2],
- name: 'c',
- offset: 44,
- kind: ParameterKind.NAMED,
- type: typeProvider.boolType);
- //
- // Validate the arguments at the call site.
- //
- FunctionDeclaration functionDeclaration = result.unit.declarations[1];
- BlockFunctionBody body = functionDeclaration.functionExpression.body;
- ExpressionStatement statement = body.block.statements[0];
- MethodInvocation invocation = statement.expression;
-
- List<Expression> arguments = invocation.argumentList.arguments;
- _assertArgumentToParameter(arguments[0], methodElement.parameters[0]);
- _assertArgumentToParameter(arguments[1], methodElement.parameters[1]);
- _assertArgumentToParameter(arguments[2], methodElement.parameters[2]);
- }
-
- test_methodInvocation_explicitCall_classTarget() async {
- addTestFile(r'''
-class C {
- double call(int p) => 0.0;
-}
-main() {
- new C().call(0);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.errors, isEmpty);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration cNode = result.unit.declarations[0];
- ClassElement cElement = cNode.element;
- MethodElement callElement = cElement.methods[0];
-
- List<Statement> statements = _getMainStatements(result);
-
- ExpressionStatement statement = statements[0];
- MethodInvocation invocation = statement.expression;
-
- expect(invocation.staticType, typeProvider.doubleType);
- expect(invocation.staticInvokeType.toString(), '(int) → double');
-
- SimpleIdentifier methodName = invocation.methodName;
- expect(methodName.staticElement, same(callElement));
- expect(methodName.staticType.toString(), '(int) → double');
- }
-
- test_methodInvocation_explicitCall_functionTarget() async {
- addTestFile(r'''
-main(double computation(int p)) {
- computation.call(1);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.errors, isEmpty);
- var typeProvider = result.unit.element.context.typeProvider;
-
- FunctionDeclaration main = result.unit.declarations[0];
- FunctionElement mainElement = main.element;
- ParameterElement parameter = mainElement.parameters[0];
-
- BlockFunctionBody mainBody = main.functionExpression.body;
- List<Statement> statements = mainBody.block.statements;
-
- ExpressionStatement statement = statements[0];
- MethodInvocation invocation = statement.expression;
-
- expect(invocation.staticType, typeProvider.doubleType);
- expect(invocation.staticInvokeType.toString(), '(int) → double');
-
- SimpleIdentifier target = invocation.target;
- expect(target.staticElement, same(parameter));
- expect(target.staticType.toString(), '(int) → double');
-
- SimpleIdentifier methodName = invocation.methodName;
- if (useCFE) {
- expect(methodName.staticElement, isNull);
- expect(methodName.staticType, isNull);
- } else {
- expect(methodName.staticElement, same(parameter));
- expect(methodName.staticType, parameter.type);
- }
- }
-
- test_methodInvocation_instanceMethod_forwardingStub() async {
- addTestFile(r'''
-class A {
- void foo(int x) {}
-}
-abstract class I<T> {
- void foo(T x);
-}
-class B extends A implements I<int> {}
-main(B b) {
- b.foo(1);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- ClassDeclaration aNode = result.unit.declarations[0];
- MethodDeclaration fooNode = aNode.members[0];
- MethodElement fooElement = fooNode.element;
-
- List<Statement> mainStatements = _getMainStatements(result);
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- expect(invocation.methodName.staticElement, same(fooElement));
-
- var invokeTypeStr = '(int) → void';
- expect(invocation.staticType.toString(), 'void');
- expect(invocation.staticInvokeType.toString(), invokeTypeStr);
- }
-
- test_methodInvocation_instanceMethod_genericClass() async {
- addTestFile(r'''
-main() {
- new C<int, double>().m(1);
-}
-class C<T, U> {
- void m(T p) {}
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- List<Statement> mainStatements = _getMainStatements(result);
-
- ClassDeclaration cNode = result.unit.declarations[1];
- MethodDeclaration mNode = cNode.members[0];
- MethodElement mElement = mNode.element;
-
- {
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- List<Expression> arguments = invocation.argumentList.arguments;
-
- var invokeTypeStr = '(int) → void';
- expect(invocation.staticType.toString(), 'void');
- expect(invocation.staticInvokeType.toString(), invokeTypeStr);
- if (useCFE) {
- expect(invocation.methodName.staticElement, same(mElement));
- expect(invocation.methodName.staticType.toString(), invokeTypeStr);
- } else {
- expect(invocation.staticInvokeType.element, same(mElement));
- }
-
- _assertArgumentToParameter(arguments[0], mElement.parameters[0]);
- }
- }
-
- test_methodInvocation_instanceMethod_genericClass_genericMethod() async {
- addTestFile(r'''
-main() {
- new C<int>().m(1, 2.3);
-}
-class C<T> {
- Map<T, U> m<U>(T a, U b) => null;
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
- List<Statement> mainStatements = _getMainStatements(result);
-
- ClassDeclaration cNode = result.unit.declarations[1];
- MethodDeclaration mNode = cNode.members[0];
- MethodElement mElement = mNode.element;
-
- {
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- List<Expression> arguments = invocation.argumentList.arguments;
-
- var invokeTypeStr = '(int, double) → Map<int, double>';
- expect(invocation.staticType.toString(), 'Map<int, double>');
- expect(invocation.staticInvokeType.toString(), invokeTypeStr);
- if (useCFE) {
- expect(invocation.methodName.staticElement, same(mElement));
- expect(invocation.methodName.staticType.toString(), invokeTypeStr);
- }
-
- if (useCFE) {
- expect(arguments[0].staticParameterElement, isNull);
- expect(arguments[1].staticParameterElement, isNull);
- } else {
- Expression aArgument = arguments[0];
- ParameterMember aArgumentParameter = aArgument.staticParameterElement;
- ParameterElement aElement = mElement.parameters[0];
- expect(aArgumentParameter.type, typeProvider.intType);
- expect(aArgumentParameter.baseElement, same(aElement));
-
- Expression bArgument = arguments[1];
- ParameterMember bArgumentParameter = bArgument.staticParameterElement;
- expect(bArgumentParameter.type, typeProvider.doubleType);
- }
- }
- }
-
- test_methodInvocation_namedArgument() async {
- addTestFile(r'''
-void main() {
- foo(1, b: true, c: 3.0);
-}
-void foo(int a, {bool b, double c}) {}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- List<Statement> mainStatements = _getMainStatements(result);
-
- FunctionDeclaration foo = result.unit.declarations[1];
- ExecutableElement fooElement = foo.element;
-
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- List<Expression> arguments = invocation.argumentList.arguments;
-
- _assertArgumentToParameter(arguments[0], fooElement.parameters[0]);
- _assertArgumentToParameter(arguments[1], fooElement.parameters[1]);
- _assertArgumentToParameter(arguments[2], fooElement.parameters[2]);
- }
-
- test_methodInvocation_notFunction_field_dynamic() async {
- addTestFile(r'''
-class C {
- dynamic f;
- foo() {
- f(1);
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- ClassDeclaration cDeclaration = result.unit.declarations[0];
-
- FieldDeclaration fDeclaration = cDeclaration.members[0];
- VariableDeclaration fNode = fDeclaration.fields.variables[0];
- FieldElement fElement = fNode.element;
-
- MethodDeclaration fooDeclaration = cDeclaration.members[1];
- BlockFunctionBody fooBody = fooDeclaration.body;
- List<Statement> fooStatements = fooBody.block.statements;
-
- ExpressionStatement statement = fooStatements[0];
- MethodInvocation invocation = statement.expression;
- expect(invocation.methodName.staticElement, same(fElement.getter));
- if (useCFE) {
- _assertDynamicFunctionType(invocation.staticInvokeType);
- } else {
- expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
- }
- expect(invocation.staticType, DynamicTypeImpl.instance);
-
- List<Expression> arguments = invocation.argumentList.arguments;
- expect(arguments[0].staticParameterElement, isNull);
- }
-
- test_methodInvocation_notFunction_getter_dynamic() async {
- addTestFile(r'''
-class C {
- get f => null;
- foo() {
- f(1);
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- ClassDeclaration cDeclaration = result.unit.declarations[0];
-
- MethodDeclaration fDeclaration = cDeclaration.members[0];
- PropertyAccessorElement fElement = fDeclaration.element;
-
- MethodDeclaration fooDeclaration = cDeclaration.members[1];
- BlockFunctionBody fooBody = fooDeclaration.body;
- List<Statement> fooStatements = fooBody.block.statements;
-
- ExpressionStatement statement = fooStatements[0];
- MethodInvocation invocation = statement.expression;
- expect(invocation.methodName.staticElement, same(fElement));
- if (useCFE) {
- _assertDynamicFunctionType(invocation.staticInvokeType);
- } else {
- expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
- }
- expect(invocation.staticType, DynamicTypeImpl.instance);
-
- List<Expression> arguments = invocation.argumentList.arguments;
-
- Expression argument = arguments[0];
- expect(argument.staticParameterElement, isNull);
- }
-
- test_methodInvocation_notFunction_getter_typedef() async {
- addTestFile(r'''
-typedef String Fun(int a, {int b});
-class C {
- Fun get f => null;
- foo() {
- f(1, b: 2);
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- FunctionTypeAlias funDeclaration = result.unit.declarations[0];
- FunctionTypeAliasElement funElement = funDeclaration.element;
-
- ClassDeclaration cDeclaration = result.unit.declarations[1];
-
- MethodDeclaration fDeclaration = cDeclaration.members[0];
- PropertyAccessorElement fElement = fDeclaration.element;
-
- MethodDeclaration fooDeclaration = cDeclaration.members[1];
- BlockFunctionBody fooBody = fooDeclaration.body;
- List<Statement> fooStatements = fooBody.block.statements;
-
- ExpressionStatement statement = fooStatements[0];
- MethodInvocation invocation = statement.expression;
- expect(invocation.methodName.staticElement, same(fElement));
- expect(invocation.staticInvokeType.toString(), '(int, {b: int}) → String');
- expect(invocation.staticType, typeProvider.stringType);
-
- List<Expression> arguments = invocation.argumentList.arguments;
- _assertArgumentToParameter(arguments[0], funElement.parameters[0]);
- _assertArgumentToParameter(arguments[1], funElement.parameters[1]);
- }
-
- test_methodInvocation_notFunction_local_dynamic() async {
- addTestFile(r'''
-main(f) {
- f(1);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- FunctionDeclaration mainDeclaration = result.unit.declarations[0];
- FunctionExpression mainFunction = mainDeclaration.functionExpression;
- ParameterElement fElement = mainFunction.parameters.parameters[0].element;
-
- BlockFunctionBody mainBody = mainFunction.body;
- List<Statement> mainStatements = mainBody.block.statements;
-
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- expect(invocation.methodName.staticElement, same(fElement));
- _assertDynamicFunctionType(invocation.staticInvokeType);
- expect(invocation.staticType, DynamicTypeImpl.instance);
-
- List<Expression> arguments = invocation.argumentList.arguments;
-
- Expression argument = arguments[0];
- expect(argument.staticParameterElement, isNull);
- }
-
- test_methodInvocation_notFunction_local_functionTyped() async {
- addTestFile(r'''
-main(String f(int a)) {
- f(1);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- FunctionDeclaration mainDeclaration = result.unit.declarations[0];
- FunctionExpression mainFunction = mainDeclaration.functionExpression;
- ParameterElement fElement = mainFunction.parameters.parameters[0].element;
-
- BlockFunctionBody mainBody = mainFunction.body;
- List<Statement> mainStatements = mainBody.block.statements;
-
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- expect(invocation.methodName.staticElement, same(fElement));
- expect(invocation.staticInvokeType.toString(), '(int) → String');
- expect(invocation.staticType, typeProvider.stringType);
-
- List<Expression> arguments = invocation.argumentList.arguments;
- _assertArgumentToParameter(
- arguments[0], (fElement.type as FunctionType).parameters[0]);
- }
-
- test_methodInvocation_notFunction_topLevelVariable_dynamic() async {
- addTestFile(r'''
-dynamic f;
-main() {
- f(1);
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- TopLevelVariableDeclaration fDeclaration = result.unit.declarations[0];
- VariableDeclaration fNode = fDeclaration.variables.variables[0];
- TopLevelVariableElement fElement = fNode.element;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- expect(invocation.methodName.staticElement, same(fElement.getter));
- _assertDynamicFunctionType(invocation.staticInvokeType);
- expect(invocation.staticType, DynamicTypeImpl.instance);
-
- List<Expression> arguments = invocation.argumentList.arguments;
-
- Expression argument = arguments[0];
- expect(argument.staticParameterElement, isNull);
- }
-
- test_methodInvocation_staticMethod() async {
- addTestFile(r'''
-main() {
- C.m(1);
-}
-class C {
- static void m(int p) {}
- void foo() {
- m(2);
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- List<Statement> mainStatements = _getMainStatements(result);
-
- ClassDeclaration cNode = result.unit.declarations[1];
- ClassElement cElement = cNode.element;
- MethodDeclaration mNode = cNode.members[0];
- MethodElement mElement = mNode.element;
-
- {
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- List<Expression> arguments = invocation.argumentList.arguments;
-
- SimpleIdentifier target = invocation.target;
- expect(target.staticElement, same(cElement));
- expect(target.staticType, same(cElement.type));
-
- var invokeTypeStr = '(int) → void';
- expect(invocation.staticType.toString(), 'void');
- expect(invocation.staticInvokeType.toString(), invokeTypeStr);
- if (!useCFE) {
- expect(invocation.staticInvokeType.element, same(mElement));
- }
- expect(invocation.methodName.staticElement, same(mElement));
- expect(invocation.methodName.staticType.toString(), invokeTypeStr);
-
- Expression argument = arguments[0];
- _assertArgumentToParameter(argument, mElement.parameters[0]);
- }
-
- {
- MethodDeclaration fooNode = cNode.members[1];
- BlockFunctionBody fooBody = fooNode.body;
- List<Statement> statements = fooBody.block.statements;
-
- ExpressionStatement statement = statements[0];
- MethodInvocation invocation = statement.expression;
- List<Expression> arguments = invocation.argumentList.arguments;
-
- expect(invocation.target, isNull);
-
- var invokeTypeStr = '(int) → void';
- expect(invocation.staticType.toString(), 'void');
- expect(invocation.staticInvokeType.toString(), invokeTypeStr);
- if (!useCFE) {
- expect(invocation.staticInvokeType.element, same(mElement));
- }
- expect(invocation.methodName.staticElement, same(mElement));
- expect(invocation.methodName.staticType.toString(), invokeTypeStr);
-
- Expression argument = arguments[0];
- _assertArgumentToParameter(argument, mElement.parameters[0]);
- }
- }
-
- test_methodInvocation_staticMethod_contextTypeParameter() async {
- addTestFile(r'''
-class C<T> {
- static E foo<E>(C<E> c) => null;
- void bar() {
- foo(this);
- }
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
-
- ClassDeclaration cNode = result.unit.declarations[0];
- TypeParameterElement tElement = cNode.element.typeParameters[0];
-
- MethodDeclaration barNode = cNode.members[1];
- BlockFunctionBody barBody = barNode.body;
- ExpressionStatement fooStatement = barBody.block.statements[0];
- MethodInvocation fooInvocation = fooStatement.expression;
- expect(fooInvocation.staticInvokeType.toString(), '(C<T>) → T');
- expect(fooInvocation.staticType.toString(), 'T');
- expect(fooInvocation.staticType.element, same(tElement));
- }
-
- test_methodInvocation_topLevelFunction() async {
- addTestFile(r'''
-void main() {
- f(1, '2');
-}
-double f(int a, String b) {}
-''');
- String fTypeString = '(int, String) → double';
-
- AnalysisResult result = await driver.getResult(testFile);
- List<Statement> mainStatements = _getMainStatements(result);
-
- var typeProvider = result.unit.element.context.typeProvider;
- InterfaceType doubleType = typeProvider.doubleType;
-
- FunctionDeclaration fNode = result.unit.declarations[1];
- FunctionElement fElement = fNode.element;
-
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
- List<Expression> arguments = invocation.argumentList.arguments;
-
- expect(invocation.methodName.staticElement, same(fElement));
- expect(invocation.methodName.staticType.toString(), fTypeString);
- expect(invocation.staticType, same(doubleType));
- expect(invocation.staticInvokeType.toString(), fTypeString);
-
- _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
- _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
- }
-
- test_methodInvocation_topLevelFunction_generic() async {
- addTestFile(r'''
-void main() {
- f<bool, String>(true, 'str');
- f(1, 2.3);
-}
-void f<T, U>(T a, U b) {}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
- List<Statement> mainStatements = _getMainStatements(result);
-
- FunctionDeclaration fNode = result.unit.declarations[1];
- FunctionElement fElement = fNode.element;
-
- // f<bool, String>(true, 'str');
- {
- String fTypeString = '(bool, String) → void';
- ExpressionStatement statement = mainStatements[0];
- MethodInvocation invocation = statement.expression;
-
- List<TypeAnnotation> typeArguments = invocation.typeArguments.arguments;
- expect(typeArguments, hasLength(2));
- {
- TypeName typeArgument = typeArguments[0];
- InterfaceType boolType = typeProvider.boolType;
- expect(typeArgument.type, boolType);
- expect(typeArgument.name.staticElement, boolType.element);
- expect(typeArgument.name.staticType, boolType);
- }
- {
- TypeName typeArgument = typeArguments[1];
- InterfaceType stringType = typeProvider.stringType;
- expect(typeArgument.type, stringType);
- expect(typeArgument.name.staticElement, stringType.element);
- expect(typeArgument.name.staticType, stringType);
- }
-
- List<Expression> arguments = invocation.argumentList.arguments;
-
- expect(invocation.methodName.staticElement, same(fElement));
- if (useCFE) {
- expect(invocation.methodName.staticType.toString(), fTypeString);
- }
- expect(invocation.staticType, VoidTypeImpl.instance);
- expect(invocation.staticInvokeType.toString(), fTypeString);
-
- _assertArgumentToParameter(arguments[0], fElement.parameters[0],
- parameterMemberType: typeProvider.boolType);
- _assertArgumentToParameter(arguments[1], fElement.parameters[1],
- parameterMemberType: typeProvider.stringType);
- }
-
- // f(1, 2.3);
- {
- String fTypeString = '(int, double) → void';
- ExpressionStatement statement = mainStatements[1];
- MethodInvocation invocation = statement.expression;
- List<Expression> arguments = invocation.argumentList.arguments;
-
- expect(invocation.methodName.staticElement, same(fElement));
- if (useCFE) {
- expect(invocation.methodName.staticType.toString(), fTypeString);
- }
- expect(invocation.staticType, VoidTypeImpl.instance);
- expect(invocation.staticInvokeType.toString(), fTypeString);
-
- _assertArgumentToParameter(arguments[0], fElement.parameters[0],
- parameterMemberType: typeProvider.intType);
- _assertArgumentToParameter(arguments[1], fElement.parameters[1],
- parameterMemberType: typeProvider.doubleType);
- }
- }
-
- test_postfixExpression_local() async {
- String content = r'''
-main() {
- int v = 0;
- v++;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement v;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- v = statement.variables.variables[0].element;
- expect(v.type, typeProvider.intType);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- PostfixExpression postfix = statement.expression;
- expect(postfix.operator.type, TokenType.PLUS_PLUS);
- expect(postfix.staticElement.name, '+');
- expect(postfix.staticType, typeProvider.intType);
-
- SimpleIdentifier operand = postfix.operand;
- expect(operand.staticElement, same(v));
- expect(operand.staticType, typeProvider.intType);
- }
- }
-
- test_postfixExpression_propertyAccess() async {
- String content = r'''
-main() {
- new C().f++;
-}
-class C {
- int f;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cClassDeclaration = unit.declarations[1];
- ClassElement cClassElement = cClassDeclaration.element;
- FieldElement fElement = cClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = mainStatements[0];
-
- PostfixExpression postfix = statement.expression;
- expect(postfix.operator.type, TokenType.PLUS_PLUS);
- expect(postfix.staticElement.name, '+');
- expect(postfix.staticType, typeProvider.intType);
-
- PropertyAccess propertyAccess = postfix.operand;
- expect(propertyAccess.staticType, typeProvider.intType);
-
- SimpleIdentifier propertyName = propertyAccess.propertyName;
- expect(propertyName.staticElement, same(fElement.setter));
- expect(propertyName.staticType, typeProvider.intType);
- }
- }
-
- test_prefixedIdentifier_classInstance_instanceField() async {
- String content = r'''
-main() {
- var c = new C();
- c.f;
-}
-class C {
- int f;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- ClassDeclaration cDeclaration = result.unit.declarations[1];
- ClassElement cElement = cDeclaration.element;
- FieldElement fElement = cElement.fields[0];
-
- VariableDeclarationStatement cStatement = statements[0];
- VariableElement vElement = cStatement.variables.variables[0].element;
-
- ExpressionStatement statement = statements[1];
- PrefixedIdentifier prefixed = statement.expression;
-
- SimpleIdentifier prefix = prefixed.prefix;
- expect(prefix.staticElement, same(vElement));
- expect(prefix.staticType, cElement.type);
-
- SimpleIdentifier identifier = prefixed.identifier;
- expect(identifier.staticElement, same(fElement.getter));
- expect(identifier.staticType, typeProvider.intType);
- }
-
- test_prefixedIdentifier_className_staticField() async {
- String content = r'''
-main() {
- C.f;
-}
-class C {
- static f = 0;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- ClassDeclaration cDeclaration = result.unit.declarations[1];
- ClassElement cElement = cDeclaration.element;
- FieldElement fElement = cElement.fields[0];
-
- ExpressionStatement statement = statements[0];
- PrefixedIdentifier prefixed = statement.expression;
-
- SimpleIdentifier prefix = prefixed.prefix;
- expect(prefix.staticElement, same(cElement));
- expect(prefix.staticType, cElement.type);
-
- SimpleIdentifier identifier = prefixed.identifier;
- expect(identifier.staticElement, same(fElement.getter));
- expect(identifier.staticType, typeProvider.intType);
- }
-
- test_prefixedIdentifier_explicitCall() async {
- addTestFile(r'''
-main(double computation(int p)) {
- computation.call;
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.errors, isEmpty);
- var typeProvider = result.unit.element.context.typeProvider;
-
- FunctionDeclaration main = result.unit.declarations[0];
- FunctionElement mainElement = main.element;
- ParameterElement parameter = mainElement.parameters[0];
-
- BlockFunctionBody mainBody = main.functionExpression.body;
- List<Statement> statements = mainBody.block.statements;
-
- ExpressionStatement statement = statements[0];
- PrefixedIdentifier prefixed = statement.expression;
-
- expect(prefixed.prefix.staticElement, same(parameter));
- expect(prefixed.prefix.staticType.toString(), '(int) → double');
-
- SimpleIdentifier methodName = prefixed.identifier;
- expect(methodName.staticElement, isNull);
- if (useCFE) {
- expect(methodName.staticType, isNull);
- } else {
- expect(methodName.staticType, typeProvider.dynamicType);
- }
- }
-
- test_prefixedIdentifier_importPrefix_className() async {
- var libPath = _p('/test/lib/lib.dart');
- provider.newFile(libPath, '''
-class MyClass {}
-typedef void MyFunctionTypeAlias();
-int myTopVariable;
-int myTopFunction() => 0;
-int get myGetter => 0;
-void set mySetter(int _) {}
-''');
- addTestFile(r'''
-import 'lib.dart' as my;
-main() {
- my.MyClass;
- my.MyFunctionTypeAlias;
- my.myTopVariable;
- my.myTopFunction;
- my.myTopFunction();
- my.myGetter;
- my.mySetter = 0;
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- // TODO(scheglov) Uncomment and fix "unused imports" hint.
-// expect(result.errors, isEmpty);
-
- var unitElement = result.unit.element;
- ImportElement myImport = unitElement.library.imports[0];
- PrefixElement myPrefix = myImport.prefix;
- var typeProvider = unitElement.context.typeProvider;
-
- var myLibrary = myImport.importedLibrary;
- var myUnit = myLibrary.definingCompilationUnit;
- var myClass = myUnit.types.single;
- var myFunctionTypeAlias = myUnit.functionTypeAliases.single;
- var myTopVariable = myUnit.topLevelVariables[0];
- var myTopFunction = myUnit.functions.single;
- var myGetter = myUnit.topLevelVariables[1].getter;
- var mySetter = myUnit.topLevelVariables[2].setter;
- expect(myTopVariable.name, 'myTopVariable');
- expect(myGetter.displayName, 'myGetter');
- expect(mySetter.displayName, 'mySetter');
-
- List<Statement> statements = _getMainStatements(result);
-
- void assertPrefix(SimpleIdentifier identifier) {
- expect(identifier.staticElement, same(myPrefix));
- expect(identifier.staticType, isNull);
- }
-
- void assertPrefixedIdentifier(
- int statementIndex, Element expectedElement, DartType expectedType) {
- ExpressionStatement statement = statements[statementIndex];
- PrefixedIdentifier prefixed = statement.expression;
- assertPrefix(prefixed.prefix);
-
- expect(prefixed.identifier.staticElement, same(expectedElement));
- expect(prefixed.identifier.staticType, expectedType);
- }
-
- assertPrefixedIdentifier(0, myClass, typeProvider.typeType);
- assertPrefixedIdentifier(1, myFunctionTypeAlias, typeProvider.typeType);
- assertPrefixedIdentifier(2, myTopVariable.getter, typeProvider.intType);
-
- {
- ExpressionStatement statement = statements[3];
- PrefixedIdentifier prefixed = statement.expression;
- assertPrefix(prefixed.prefix);
-
- expect(prefixed.identifier.staticElement, same(myTopFunction));
- expect(prefixed.identifier.staticType, isNotNull);
- }
-
- {
- ExpressionStatement statement = statements[4];
- MethodInvocation invocation = statement.expression;
- assertPrefix(invocation.target);
-
- expect(invocation.methodName.staticElement, same(myTopFunction));
- expect(invocation.methodName.staticType, isNotNull);
- }
-
- assertPrefixedIdentifier(5, myGetter, typeProvider.intType);
-
- {
- ExpressionStatement statement = statements[6];
- AssignmentExpression assignment = statement.expression;
- PrefixedIdentifier left = assignment.leftHandSide;
- assertPrefix(left.prefix);
-
- expect(left.identifier.staticElement, same(mySetter));
- expect(left.identifier.staticType, typeProvider.intType);
- }
- }
-
- test_prefixExpression_local() async {
- String content = r'''
-main() {
- int v = 0;
- ++v;
- ~v;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement v;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- v = statement.variables.variables[0].element;
- expect(v.type, typeProvider.intType);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- PrefixExpression prefix = statement.expression;
- expect(prefix.operator.type, TokenType.PLUS_PLUS);
- expect(prefix.staticElement.name, '+');
- expect(prefix.staticType, typeProvider.intType);
-
- SimpleIdentifier operand = prefix.operand;
- expect(operand.staticElement, same(v));
- expect(operand.staticType, typeProvider.intType);
- }
-
- {
- ExpressionStatement statement = mainStatements[2];
-
- PrefixExpression prefix = statement.expression;
- expect(prefix.operator.type, TokenType.TILDE);
- expect(prefix.staticElement.name, '~');
- expect(prefix.staticType, typeProvider.intType);
-
- SimpleIdentifier operand = prefix.operand;
- expect(operand.staticElement, same(v));
- expect(operand.staticType, typeProvider.intType);
- }
- }
-
- test_prefixExpression_local_not() async {
- String content = r'''
-main() {
- bool v = true;
- !v;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- VariableElement v;
- {
- VariableDeclarationStatement statement = mainStatements[0];
- v = statement.variables.variables[0].element;
- expect(v.type, typeProvider.boolType);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- PrefixExpression prefix = statement.expression;
- expect(prefix.operator.type, TokenType.BANG);
- expect(prefix.staticElement, isNull);
- expect(prefix.staticType, typeProvider.boolType);
-
- SimpleIdentifier operand = prefix.operand;
- expect(operand.staticElement, same(v));
- expect(operand.staticType, typeProvider.boolType);
- }
- }
-
- test_prefixExpression_propertyAccess() async {
- String content = r'''
-main() {
- ++new C().f;
- ~new C().f;
-}
-class C {
- int f;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cClassDeclaration = unit.declarations[1];
- ClassElement cClassElement = cClassDeclaration.element;
- FieldElement fElement = cClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = mainStatements[0];
-
- PrefixExpression prefix = statement.expression;
- expect(prefix.operator.type, TokenType.PLUS_PLUS);
- expect(prefix.staticElement.name, '+');
- expect(prefix.staticType, typeProvider.intType);
-
- PropertyAccess propertyAccess = prefix.operand;
- expect(propertyAccess.staticType, typeProvider.intType);
-
- SimpleIdentifier propertyName = propertyAccess.propertyName;
- expect(propertyName.staticElement, same(fElement.setter));
- expect(propertyName.staticType, typeProvider.intType);
- }
-
- {
- ExpressionStatement statement = mainStatements[1];
-
- PrefixExpression prefix = statement.expression;
- expect(prefix.operator.type, TokenType.TILDE);
- expect(prefix.staticElement.name, '~');
- expect(prefix.staticType, typeProvider.intType);
-
- PropertyAccess propertyAccess = prefix.operand;
- expect(propertyAccess.staticType, typeProvider.intType);
-
- SimpleIdentifier propertyName = propertyAccess.propertyName;
- expect(propertyName.staticElement, same(fElement.getter));
- expect(propertyName.staticType, typeProvider.intType);
- }
- }
-
- test_propertyAccess_field() async {
- String content = r'''
-main() {
- new C().f;
-}
-class C {
- int f;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cClassDeclaration = unit.declarations[1];
- ClassElement cClassElement = cClassDeclaration.element;
- FieldElement fElement = cClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = mainStatements[0];
- PropertyAccess access = statement.expression;
- expect(access.staticType, typeProvider.intType);
-
- InstanceCreationExpression newC = access.target;
- expect(newC.staticElement, cClassElement.unnamedConstructor);
- expect(newC.staticType, cClassElement.type);
-
- expect(access.propertyName.staticElement, same(fElement.getter));
- expect(access.propertyName.staticType, typeProvider.intType);
- }
- }
-
- test_propertyAccess_getter() async {
- String content = r'''
-main() {
- new C().f;
-}
-class C {
- int get f => 0;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- ClassDeclaration cClassDeclaration = unit.declarations[1];
- ClassElement cClassElement = cClassDeclaration.element;
- FieldElement fElement = cClassElement.getField('f');
-
- List<Statement> mainStatements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = mainStatements[0];
- PropertyAccess access = statement.expression;
- expect(access.staticType, typeProvider.intType);
-
- InstanceCreationExpression newC = access.target;
- expect(newC.staticElement, cClassElement.unnamedConstructor);
- expect(newC.staticType, cClassElement.type);
-
- expect(access.propertyName.staticElement, same(fElement.getter));
- expect(access.propertyName.staticType, typeProvider.intType);
- }
- }
-
- test_stringInterpolation() async {
- String content = r'''
-void main() {
- var v = 42;
- '$v$v $v';
- ' ${v + 1} ';
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.path, testFile);
- expect(result.errors, isEmpty);
-
- var typeProvider = result.unit.element.context.typeProvider;
-
- FunctionDeclaration main = result.unit.declarations[0];
- expect(main.element, isNotNull);
- expect(main.name.staticElement, isNotNull);
- expect(main.name.staticType.toString(), '() → void');
-
- BlockFunctionBody body = main.functionExpression.body;
- NodeList<Statement> statements = body.block.statements;
-
- // var v = 42;
- VariableElement vElement;
- {
- VariableDeclarationStatement statement = statements[0];
- vElement = statement.variables.variables[0].name.staticElement;
- }
-
- {
- ExpressionStatement statement = statements[1];
- StringInterpolation interpolation = statement.expression;
-
- InterpolationExpression element_1 = interpolation.elements[1];
- SimpleIdentifier expression_1 = element_1.expression;
- expect(expression_1.staticElement, same(vElement));
- expect(expression_1.staticType, typeProvider.intType);
-
- InterpolationExpression element_3 = interpolation.elements[3];
- SimpleIdentifier expression_3 = element_3.expression;
- expect(expression_3.staticElement, same(vElement));
- expect(expression_3.staticType, typeProvider.intType);
-
- InterpolationExpression element_5 = interpolation.elements[5];
- SimpleIdentifier expression_5 = element_5.expression;
- expect(expression_5.staticElement, same(vElement));
- expect(expression_5.staticType, typeProvider.intType);
- }
-
- {
- ExpressionStatement statement = statements[2];
- StringInterpolation interpolation = statement.expression;
-
- InterpolationExpression element_1 = interpolation.elements[1];
- BinaryExpression expression = element_1.expression;
- expect(expression.staticType, typeProvider.intType);
-
- SimpleIdentifier left = expression.leftOperand;
- expect(left.staticElement, same(vElement));
- expect(left.staticType, typeProvider.intType);
- }
- }
-
- test_stringInterpolation_multiLine_emptyBeforeAfter() async {
- addTestFile(r"""
-void main() {
- var v = 42;
- '''$v''';
-}
-""");
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.errors, isEmpty);
- }
-
- test_super() async {
- String content = r'''
-class A {
- void method(int p) {}
- int get getter => 0;
- void set setter(int p) {}
- int operator+(int p) => 0;
-}
-class B extends A {
- void test() {
- method(1);
- super.method(2);
- getter;
- super.getter;
- setter = 3;
- super.setter = 4;
- this + 5;
- }
-}
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration aNode = result.unit.declarations[0];
- ClassDeclaration bNode = result.unit.declarations[1];
-
- MethodElement methodElement = aNode.members[0].element;
- PropertyAccessorElement getterElement = aNode.members[1].element;
- PropertyAccessorElement setterElement = aNode.members[2].element;
- MethodElement operatorElement = aNode.members[3].element;
-
- MethodDeclaration testNode = bNode.members[0];
- BlockFunctionBody testBody = testNode.body;
- List<Statement> testStatements = testBody.block.statements;
-
- // method(1);
- {
- ExpressionStatement statement = testStatements[0];
- MethodInvocation invocation = statement.expression;
-
- expect(invocation.target, isNull);
-
- expect(invocation.methodName.staticElement, same(methodElement));
- }
-
- // super.method(2);
- {
- ExpressionStatement statement = testStatements[1];
- MethodInvocation invocation = statement.expression;
-
- SuperExpression target = invocation.target;
- expect(target.staticType, bNode.element.type); // raw
-
- expect(invocation.methodName.staticElement, same(methodElement));
- }
-
- // getter;
- {
- ExpressionStatement statement = testStatements[2];
- SimpleIdentifier identifier = statement.expression;
-
- expect(identifier.staticElement, same(getterElement));
- expect(identifier.staticType, same(typeProvider.intType));
- }
-
- // super.getter;
- {
- ExpressionStatement statement = testStatements[3];
- PropertyAccess propertyAccess = statement.expression;
- expect(propertyAccess.staticType, same(typeProvider.intType));
-
- SuperExpression target = propertyAccess.target;
- expect(target.staticType, bNode.element.type); // raw
-
- expect(propertyAccess.propertyName.staticElement, same(getterElement));
- expect(
- propertyAccess.propertyName.staticType, same(typeProvider.intType));
- }
-
- // setter = 3;
- {
- ExpressionStatement statement = testStatements[4];
- AssignmentExpression assignment = statement.expression;
-
- SimpleIdentifier identifier = assignment.leftHandSide;
- expect(identifier.staticElement, same(setterElement));
- expect(identifier.staticType, same(typeProvider.intType));
- }
-
- // this.setter = 4;
- {
- ExpressionStatement statement = testStatements[5];
- AssignmentExpression assignment = statement.expression;
-
- PropertyAccess propertyAccess = assignment.leftHandSide;
-
- SuperExpression target = propertyAccess.target;
- expect(target.staticType, bNode.element.type); // raw
-
- expect(propertyAccess.propertyName.staticElement, same(setterElement));
- expect(
- propertyAccess.propertyName.staticType, same(typeProvider.intType));
- }
-
- // super + 5;
- {
- ExpressionStatement statement = testStatements[6];
- BinaryExpression binary = statement.expression;
-
- ThisExpression target = binary.leftOperand;
- expect(target.staticType, bNode.element.type); // raw
-
- expect(binary.staticElement, same(operatorElement));
- expect(binary.staticType, typeProvider.intType);
- }
- }
-
- test_this() async {
- String content = r'''
-class A {
- void method(int p) {}
- int get getter => 0;
- void set setter(int p) {}
- int operator+(int p) => 0;
- void test() {
- method(1);
- this.method(2);
- getter;
- this.getter;
- setter = 3;
- this.setter = 4;
- this + 5;
- }
-}
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration aNode = result.unit.declarations[0];
-
- MethodElement methodElement = aNode.members[0].element;
- PropertyAccessorElement getterElement = aNode.members[1].element;
- PropertyAccessorElement setterElement = aNode.members[2].element;
- MethodElement operatorElement = aNode.members[3].element;
-
- MethodDeclaration testNode = aNode.members[4];
- BlockFunctionBody testBody = testNode.body;
- List<Statement> testStatements = testBody.block.statements;
-
- // method(1);
- {
- ExpressionStatement statement = testStatements[0];
- MethodInvocation invocation = statement.expression;
-
- expect(invocation.target, isNull);
-
- expect(invocation.methodName.staticElement, same(methodElement));
- }
-
- // this.method(2);
- {
- ExpressionStatement statement = testStatements[1];
- MethodInvocation invocation = statement.expression;
-
- ThisExpression target = invocation.target;
- expect(target.staticType, aNode.element.type); // raw
-
- expect(invocation.methodName.staticElement, same(methodElement));
- }
-
- // getter;
- {
- ExpressionStatement statement = testStatements[2];
- SimpleIdentifier identifier = statement.expression;
-
- expect(identifier.staticElement, same(getterElement));
- expect(identifier.staticType, typeProvider.intType);
- }
-
- // this.getter;
- {
- ExpressionStatement statement = testStatements[3];
- PropertyAccess propertyAccess = statement.expression;
- expect(propertyAccess.staticType, typeProvider.intType);
-
- ThisExpression target = propertyAccess.target;
- expect(target.staticType, aNode.element.type); // raw
-
- expect(propertyAccess.propertyName.staticElement, same(getterElement));
- expect(propertyAccess.propertyName.staticType, typeProvider.intType);
- }
-
- // setter = 3;
- {
- ExpressionStatement statement = testStatements[4];
- AssignmentExpression assignment = statement.expression;
-
- SimpleIdentifier identifier = assignment.leftHandSide;
- expect(identifier.staticElement, same(setterElement));
- expect(identifier.staticType, typeProvider.intType);
- }
-
- // this.setter = 4;
- {
- ExpressionStatement statement = testStatements[5];
- AssignmentExpression assignment = statement.expression;
-
- PropertyAccess propertyAccess = assignment.leftHandSide;
-
- ThisExpression target = propertyAccess.target;
- expect(target.staticType, aNode.element.type); // raw
-
- expect(propertyAccess.propertyName.staticElement, same(setterElement));
- expect(propertyAccess.propertyName.staticType, typeProvider.intType);
- }
-
- // this + 5;
- {
- ExpressionStatement statement = testStatements[6];
- BinaryExpression binary = statement.expression;
-
- ThisExpression target = binary.leftOperand;
- expect(target.staticType, aNode.element.type); // raw
-
- expect(binary.staticElement, same(operatorElement));
- expect(binary.staticType, typeProvider.intType);
- }
- }
-
- test_top_class() async {
- String content = r'''
-class A<T> {}
-class B<T> {}
-class C<T> {}
-class D extends A<bool> with B<int> implements C<double> {}
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration aNode = result.unit.declarations[0];
- ClassElement aElement = aNode.element;
-
- ClassDeclaration bNode = result.unit.declarations[1];
- ClassElement bElement = bNode.element;
-
- ClassDeclaration cNode = result.unit.declarations[2];
- ClassElement cElement = cNode.element;
-
- ClassDeclaration dNode = result.unit.declarations[3];
- Element dElement = dNode.element;
-
- SimpleIdentifier dName = dNode.name;
- expect(dName.staticElement, same(dElement));
- expect(dName.staticType, typeProvider.typeType);
-
- {
- var aRawType = aElement.type;
- var expectedType = aRawType.instantiate([typeProvider.boolType]);
-
- TypeName superClass = dNode.extendsClause.superclass;
- expect(superClass.type, expectedType);
-
- SimpleIdentifier identifier = superClass.name;
- expect(identifier.staticElement, aElement);
- expect(identifier.staticType, expectedType);
- }
-
- {
- var bRawType = bElement.type;
- var expectedType = bRawType.instantiate([typeProvider.intType]);
-
- TypeName mixinType = dNode.withClause.mixinTypes[0];
- expect(mixinType.type, expectedType);
-
- SimpleIdentifier identifier = mixinType.name;
- expect(identifier.staticElement, bElement);
- expect(identifier.staticType, expectedType);
- }
-
- {
- var cRawType = cElement.type;
- var expectedType = cRawType.instantiate([typeProvider.doubleType]);
-
- TypeName implementedType = dNode.implementsClause.interfaces[0];
- expect(implementedType.type, expectedType);
-
- SimpleIdentifier identifier = implementedType.name;
- expect(identifier.staticElement, cElement);
- expect(identifier.staticType, expectedType);
- }
- }
-
- test_top_class_constructor_parameter_defaultValue() async {
- String content = r'''
-class C {
- double f;
- C([int a: 1 + 2]) : f = 3.4;
-}
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration cNode = result.unit.declarations[0];
- ClassElement cElement = cNode.element;
-
- ConstructorDeclaration constructorNode = cNode.members[1];
-
- DefaultFormalParameter aNode = constructorNode.parameters.parameters[0];
- _assertDefaultParameter(aNode, cElement.unnamedConstructor.parameters[0],
- name: 'a',
- offset: 31,
- kind: ParameterKind.POSITIONAL,
- type: typeProvider.intType);
-
- BinaryExpression binary = aNode.defaultValue;
- expect(binary.staticElement, isNotNull);
- expect(binary.staticType, typeProvider.intType);
- expect(binary.leftOperand.staticType, typeProvider.intType);
- expect(binary.rightOperand.staticType, typeProvider.intType);
- }
-
- test_top_classTypeAlias() async {
- String content = r'''
-class A<T> {}
-class B<T> {}
-class C<T> {}
-class D = A<bool> with B<int> implements C<double>;
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- ClassDeclaration aNode = result.unit.declarations[0];
- ClassElement aElement = aNode.element;
-
- ClassDeclaration bNode = result.unit.declarations[1];
- ClassElement bElement = bNode.element;
-
- ClassDeclaration cNode = result.unit.declarations[2];
- ClassElement cElement = cNode.element;
-
- ClassTypeAlias dNode = result.unit.declarations[3];
- Element dElement = dNode.element;
-
- SimpleIdentifier dName = dNode.name;
- expect(dName.staticElement, same(dElement));
- expect(dName.staticType, typeProvider.typeType);
-
- {
- var aRawType = aElement.type;
- var expectedType = aRawType.instantiate([typeProvider.boolType]);
-
- TypeName superClass = dNode.superclass;
- expect(superClass.type, expectedType);
-
- SimpleIdentifier identifier = superClass.name;
- expect(identifier.staticElement, same(aElement));
- expect(identifier.staticType, expectedType);
- }
-
- {
- var bRawType = bElement.type;
- var expectedType = bRawType.instantiate([typeProvider.intType]);
-
- TypeName mixinType = dNode.withClause.mixinTypes[0];
- expect(mixinType.type, expectedType);
-
- SimpleIdentifier identifier = mixinType.name;
- expect(identifier.staticElement, same(bElement));
- expect(identifier.staticType, expectedType);
- }
-
- {
- var cRawType = cElement.type;
- var expectedType = cRawType.instantiate([typeProvider.doubleType]);
-
- TypeName interfaceType = dNode.implementsClause.interfaces[0];
- expect(interfaceType.type, expectedType);
-
- SimpleIdentifier identifier = interfaceType.name;
- expect(identifier.staticElement, same(cElement));
- expect(identifier.staticType, expectedType);
- }
- }
-
- test_top_enum() async {
- String content = r'''
-enum MyEnum {
- A, B
-}
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
- var typeProvider = result.unit.element.context.typeProvider;
-
- EnumDeclaration enumNode = result.unit.declarations[0];
- ClassElement enumElement = enumNode.element;
-
- SimpleIdentifier dName = enumNode.name;
- expect(dName.staticElement, same(enumElement));
- if (useCFE) {
- expect(dName.staticType, typeProvider.typeType);
- }
-
- {
- var aElement = enumElement.getField('A');
- var aNode = enumNode.constants[0];
- expect(aNode.element, same(aElement));
- expect(aNode.name.staticElement, same(aElement));
- expect(aNode.name.staticType, same(enumElement.type));
- }
-
- {
- var bElement = enumElement.getField('B');
- var bNode = enumNode.constants[1];
- expect(bNode.element, same(bElement));
- expect(bNode.name.staticElement, same(bElement));
- expect(bNode.name.staticType, same(enumElement.type));
- }
- }
-
- test_top_executables_class() async {
- String content = r'''
-class C {
- C(int p);
- C.named(int p);
-
- int publicMethod(double p) => 0;
- int get publicGetter => 0;
- void set publicSetter(double p) {}
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.path, testFile);
-
- var typeProvider = result.unit.element.context.typeProvider;
- InterfaceType typeType = typeProvider.typeType;
- InterfaceType doubleType = typeProvider.doubleType;
- InterfaceType intType = typeProvider.intType;
- ClassElement doubleElement = doubleType.element;
- ClassElement intElement = intType.element;
-
- ClassDeclaration cNode = result.unit.declarations[0];
- ClassElement cElement = cNode.element;
-
- // The class name identifier.
- expect(cNode.name.staticElement, same(cElement));
- expect(cNode.name.staticType, typeType);
-
- // unnamed constructor
- {
- ConstructorDeclaration node = cNode.members[0];
- expect(node.element, isNotNull);
- expect(node.element.type.toString(), '(int) → C');
- expect(node.returnType.staticElement, same(cElement));
- expect(node.returnType.staticType, typeType);
- expect(node.name, isNull);
- }
-
- // named constructor
- {
- ConstructorDeclaration node = cNode.members[1];
- expect(node.element, isNotNull);
- expect(node.element.type.toString(), '(int) → C');
- expect(node.returnType.staticElement, same(cElement));
- expect(node.returnType.staticType, typeType);
- expect(node.name.staticElement, same(node.element));
- expect(node.name.staticType.toString(), '(int) → C');
- }
-
- // publicMethod()
- {
- MethodDeclaration node = cNode.members[2];
- expect(node.element, isNotNull);
- expect(node.element.type.toString(), '(double) → int');
-
- // method return type
- TypeName returnType = node.returnType;
- SimpleIdentifier returnTypeName = returnType.name;
- expect(returnType.type, intType);
- expect(returnTypeName.staticElement, intElement);
- expect(returnTypeName.staticType, intType);
-
- // method name
- expect(node.name.staticElement, same(node.element));
- expect(node.name.staticType, same(node.element.type));
-
- // method parameter
- {
- SimpleFormalParameter pNode = node.parameters.parameters[0];
- expect(pNode.element, isNotNull);
- expect(pNode.element.type, doubleType);
-
- TypeName pType = pNode.type;
- expect(pType.name.staticElement, doubleElement);
- expect(pType.name.staticType, doubleType);
-
- expect(pNode.identifier.staticElement, pNode.element);
- expect(pNode.identifier.staticType, doubleType);
- }
- }
-
- // publicGetter()
- {
- MethodDeclaration node = cNode.members[3];
- expect(node.element, isNotNull);
- expect(node.element.type.toString(), '() → int');
-
- // getter return type
- TypeName returnType = node.returnType;
- SimpleIdentifier returnTypeName = returnType.name;
- expect(returnType.type, intType);
- expect(returnTypeName.staticElement, intElement);
- expect(returnTypeName.staticType, intType);
-
- // getter name
- expect(node.name.staticElement, same(node.element));
- expect(node.name.staticType, intType);
- }
-
- // publicSetter()
- {
- MethodDeclaration node = cNode.members[4];
- expect(node.element, isNotNull);
- expect(node.element.type.toString(), '(double) → void');
-
- // setter return type
- TypeName returnType = node.returnType;
- SimpleIdentifier returnTypeName = returnType.name;
- expect(returnType.type, VoidTypeImpl.instance);
- expect(returnTypeName.staticElement, isNull);
- expect(returnTypeName.staticType, VoidTypeImpl.instance);
-
- // setter name
- expect(node.name.staticElement, same(node.element));
- expect(node.name.staticType, doubleType);
-
- // setter parameter
- {
- SimpleFormalParameter pNode = node.parameters.parameters[0];
- expect(pNode.element, isNotNull);
- expect(pNode.element.type, doubleType);
-
- TypeName pType = pNode.type;
- expect(pType.name.staticElement, doubleElement);
- expect(pType.name.staticType, doubleType);
-
- expect(pNode.identifier.staticElement, pNode.element);
- expect(pNode.identifier.staticType, doubleType);
- }
- }
- }
-
- test_top_executables_top() async {
- String content = r'''
-int topFunction(double p) => 0;
-int get topGetter => 0;
-void set topSetter(double p) {}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- expect(result.path, testFile);
-
- var typeProvider = result.unit.element.context.typeProvider;
- InterfaceType doubleType = typeProvider.doubleType;
- InterfaceType intType = typeProvider.intType;
- ClassElement doubleElement = doubleType.element;
- ClassElement intElement = intType.element;
-
- // topFunction()
- {
- FunctionDeclaration node = result.unit.declarations[0];
- expect(node.element, isNotNull);
- expect(node.element.type.toString(), '(double) → int');
-
- // function return type
- TypeName returnType = node.returnType;
- SimpleIdentifier returnTypeName = returnType.name;
- expect(returnType.type, intType);
- expect(returnTypeName.staticElement, intElement);
- expect(returnTypeName.staticType, intType);
-
- // function name
- expect(node.name.staticElement, same(node.element));
- expect(node.name.staticType, same(node.element.type));
-
- // function parameter
- {
- SimpleFormalParameter pNode =
- node.functionExpression.parameters.parameters[0];
- expect(pNode.element, isNotNull);
- expect(pNode.element.type, doubleType);
-
- TypeName pType = pNode.type;
- expect(pType.name.staticElement, doubleElement);
- expect(pType.name.staticType, doubleType);
-
- expect(pNode.identifier.staticElement, pNode.element);
- expect(pNode.identifier.staticType, doubleType);
- }
- }
-
- // topGetter()
- {
- FunctionDeclaration node = result.unit.declarations[1];
- expect(node.element, isNotNull);
- expect(node.element.type.toString(), '() → int');
-
- // getter return type
- TypeName returnType = node.returnType;
- SimpleIdentifier returnTypeName = returnType.name;
- expect(returnType.type, intType);
- expect(returnTypeName.staticElement, intElement);
- expect(returnTypeName.staticType, intType);
-
- // getter name
- expect(node.name.staticElement, same(node.element));
- expect(node.name.staticType, intType);
- }
-
- // topSetter()
- {
- FunctionDeclaration node = result.unit.declarations[2];
- expect(node.element, isNotNull);
- expect(node.element.type.toString(), '(double) → void');
-
- // setter return type
- TypeName returnType = node.returnType;
- SimpleIdentifier returnTypeName = returnType.name;
- expect(returnType.type, VoidTypeImpl.instance);
- expect(returnTypeName.staticElement, isNull);
- expect(returnTypeName.staticType, VoidTypeImpl.instance);
-
- // setter name
- expect(node.name.staticElement, same(node.element));
- expect(node.name.staticType, doubleType);
-
- // setter parameter
- {
- SimpleFormalParameter pNode =
- node.functionExpression.parameters.parameters[0];
- expect(pNode.element, isNotNull);
- expect(pNode.element.type, doubleType);
-
- TypeName pType = pNode.type;
- expect(pType.name.staticElement, doubleElement);
- expect(pType.name.staticType, doubleType);
-
- expect(pNode.identifier.staticElement, pNode.element);
- expect(pNode.identifier.staticType, doubleType);
- }
- }
- }
-
- test_top_field_class() async {
- String content = r'''
-class C<T> {
- var a = 1;
- T b;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- CompilationUnitElement unitElement = unit.element;
- var typeProvider = unitElement.context.typeProvider;
-
- ClassDeclaration cNode = unit.declarations[0];
- ClassElement cElement = cNode.element;
- TypeParameterElement tElement = cElement.typeParameters[0];
- expect(cElement, same(unitElement.types[0]));
-
- {
- FieldElement aElement = cElement.getField('a');
- FieldDeclaration aDeclaration = cNode.members[0];
- VariableDeclaration aNode = aDeclaration.fields.variables[0];
- expect(aNode.element, same(aElement));
- expect(aElement.type, typeProvider.intType);
- expect(aNode.name.staticElement, same(aElement));
- expect(aNode.name.staticType, same(aElement.type));
-
- Expression aValue = aNode.initializer;
- expect(aValue.staticType, typeProvider.intType);
- }
-
- {
- FieldElement bElement = cElement.getField('b');
- FieldDeclaration bDeclaration = cNode.members[1];
-
- TypeName typeName = bDeclaration.fields.type;
- SimpleIdentifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, same(tElement));
- expect(typeIdentifier.staticType, same(tElement.type));
-
- VariableDeclaration bNode = bDeclaration.fields.variables[0];
- expect(bNode.element, same(bElement));
- expect(bElement.type, tElement.type);
- expect(bNode.name.staticElement, same(bElement));
- expect(bNode.name.staticType, same(bElement.type));
- }
- }
-
- test_top_field_class_multiple() async {
- String content = r'''
-class C {
- var a = 1, b = 2.3;
-}
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- CompilationUnitElement unitElement = unit.element;
- var typeProvider = unitElement.context.typeProvider;
-
- ClassDeclaration cNode = unit.declarations[0];
- ClassElement cElement = cNode.element;
-
- FieldDeclaration fieldDeclaration = cNode.members[0];
-
- {
- FieldElement aElement = cElement.getField('a');
-
- VariableDeclaration aNode = fieldDeclaration.fields.variables[0];
- expect(aNode.element, same(aElement));
- expect(aElement.type, typeProvider.intType);
-
- expect(aNode.name.staticElement, same(aElement));
- expect(aNode.name.staticType, same(aElement.type));
-
- Expression aValue = aNode.initializer;
- expect(aValue.staticType, typeProvider.intType);
- }
-
- {
- FieldElement bElement = cElement.getField('b');
-
- VariableDeclaration bNode = fieldDeclaration.fields.variables[1];
- expect(bNode.element, same(bElement));
- expect(bElement.type, typeProvider.doubleType);
-
- expect(bNode.name.staticElement, same(bElement));
- expect(bNode.name.staticType, same(bElement.type));
-
- Expression aValue = bNode.initializer;
- expect(aValue.staticType, typeProvider.doubleType);
- }
- }
-
- test_top_field_top() async {
- String content = r'''
-var a = 1;
-double b = 2.3;
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- CompilationUnitElement unitElement = unit.element;
- var typeProvider = unitElement.context.typeProvider;
-
- {
- TopLevelVariableDeclaration aDeclaration = unit.declarations[0];
- VariableDeclaration aNode = aDeclaration.variables.variables[0];
- TopLevelVariableElement aElement = aNode.element;
- expect(aElement, same(unitElement.topLevelVariables[0]));
- expect(aElement.type, typeProvider.intType);
- expect(aNode.name.staticElement, same(aElement));
- expect(aNode.name.staticType, same(aElement.type));
-
- Expression aValue = aNode.initializer;
- expect(aValue.staticType, typeProvider.intType);
- }
-
- {
- TopLevelVariableDeclaration bDeclaration = unit.declarations[1];
-
- VariableDeclaration bNode = bDeclaration.variables.variables[0];
- TopLevelVariableElement bElement = bNode.element;
- expect(bElement, same(unitElement.topLevelVariables[1]));
- expect(bElement.type, typeProvider.doubleType);
-
- TypeName typeName = bDeclaration.variables.type;
- _assertTypeNameSimple(typeName, typeProvider.doubleType);
-
- expect(bNode.name.staticElement, same(bElement));
- expect(bNode.name.staticType, same(bElement.type));
-
- Expression aValue = bNode.initializer;
- expect(aValue.staticType, typeProvider.doubleType);
- }
- }
-
- test_top_field_top_multiple() async {
- String content = r'''
-var a = 1, b = 2.3;
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- CompilationUnitElement unitElement = unit.element;
- var typeProvider = unitElement.context.typeProvider;
-
- TopLevelVariableDeclaration variableDeclaration = unit.declarations[0];
- expect(variableDeclaration.variables.type, isNull);
-
- {
- VariableDeclaration aNode = variableDeclaration.variables.variables[0];
- TopLevelVariableElement aElement = aNode.element;
- expect(aElement, same(unitElement.topLevelVariables[0]));
- expect(aElement.type, typeProvider.intType);
-
- expect(aNode.name.staticElement, same(aElement));
- expect(aNode.name.staticType, aElement.type);
-
- Expression aValue = aNode.initializer;
- expect(aValue.staticType, typeProvider.intType);
- }
-
- {
- VariableDeclaration bNode = variableDeclaration.variables.variables[1];
- TopLevelVariableElement bElement = bNode.element;
- expect(bElement, same(unitElement.topLevelVariables[1]));
- expect(bElement.type, typeProvider.doubleType);
-
- expect(bNode.name.staticElement, same(bElement));
- expect(bNode.name.staticType, bElement.type);
-
- Expression aValue = bNode.initializer;
- expect(aValue.staticType, typeProvider.doubleType);
- }
- }
-
- test_top_function_namedParameters() async {
- addTestFile(r'''
-double f(int a, {String b, bool c: 1 == 2}) {}
-void main() {
- f(1, b: '2', c: true);
-}
-''');
- String fTypeString = '(int, {b: String, c: bool}) → double';
-
- AnalysisResult result = await driver.getResult(testFile);
- FunctionDeclaration fDeclaration = result.unit.declarations[0];
- FunctionElement fElement = fDeclaration.element;
-
- var typeProvider = result.unit.element.context.typeProvider;
- InterfaceType doubleType = typeProvider.doubleType;
-
- expect(fElement, isNotNull);
- expect(fElement.type.toString(), fTypeString);
-
- expect(fDeclaration.name.staticElement, same(fElement));
- expect(fDeclaration.name.staticType, fElement.type);
-
- TypeName fReturnTypeNode = fDeclaration.returnType;
- expect(fReturnTypeNode.name.staticElement, same(doubleType.element));
- expect(fReturnTypeNode.type, doubleType);
- //
- // Validate the parameters at the declaration site.
- //
- List<ParameterElement> elements = fElement.parameters;
- expect(elements, hasLength(3));
-
- List<FormalParameter> nodes =
- fDeclaration.functionExpression.parameters.parameters;
- expect(nodes, hasLength(3));
-
- _assertSimpleParameter(nodes[0], elements[0],
- name: 'a',
- offset: 13,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.intType);
-
- DefaultFormalParameter bNode = nodes[1];
- _assertDefaultParameter(bNode, elements[1],
- name: 'b',
- offset: 24,
- kind: ParameterKind.NAMED,
- type: typeProvider.stringType);
- expect(bNode.defaultValue, isNull);
-
- DefaultFormalParameter cNode = nodes[2];
- _assertDefaultParameter(cNode, elements[2],
- name: 'c',
- offset: 32,
- kind: ParameterKind.NAMED,
- type: typeProvider.boolType);
- {
- BinaryExpression defaultValue = cNode.defaultValue;
- expect(defaultValue.staticElement, isNotNull);
- expect(defaultValue.staticType, typeProvider.boolType);
- }
-
- //
- // Validate the arguments at the call site.
- //
- FunctionDeclaration mainDeclaration = result.unit.declarations[1];
- BlockFunctionBody body = mainDeclaration.functionExpression.body;
- ExpressionStatement statement = body.block.statements[0];
- MethodInvocation invocation = statement.expression;
- List<Expression> arguments = invocation.argumentList.arguments;
-
- _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
- _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
- _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
- }
-
- test_top_functionTypeAlias() async {
- String content = r'''
-typedef int F<T>(bool a, T b);
-''';
- addTestFile(content);
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- CompilationUnitElement unitElement = unit.element;
- var typeProvider = unitElement.context.typeProvider;
-
- FunctionTypeAlias alias = unit.declarations[0];
- FunctionTypeAliasElement aliasElement = alias.element;
- expect(aliasElement, same(unitElement.functionTypeAliases[0]));
- expect(aliasElement.returnType, typeProvider.intType);
-
- _assertTypeNameSimple(alias.returnType, typeProvider.intType);
-
- _assertSimpleParameter(
- alias.parameters.parameters[0], aliasElement.parameters[0],
- name: 'a',
- offset: 22,
- kind: ParameterKind.REQUIRED,
- type: typeProvider.boolType);
-
- _assertSimpleParameter(
- alias.parameters.parameters[1], aliasElement.parameters[1],
- name: 'b',
- offset: 27,
- kind: ParameterKind.REQUIRED,
- type: aliasElement.typeParameters[0].type);
- }
-
- test_top_typeParameter() async {
- String content = r'''
-class A {}
-class C<T extends A, U extends List<A>, V> {}
-''';
- addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- CompilationUnitElement unitElement = unit.element;
- var typeProvider = unitElement.context.typeProvider;
-
- ClassDeclaration aNode = unit.declarations[0];
- ClassElement aElement = aNode.element;
- expect(aElement, same(unitElement.types[0]));
-
- ClassDeclaration cNode = unit.declarations[1];
- ClassElement cElement = cNode.element;
- expect(cElement, same(unitElement.types[1]));
-
- {
- TypeParameter tNode = cNode.typeParameters.typeParameters[0];
- expect(tNode.element, same(cElement.typeParameters[0]));
-
- TypeName bound = tNode.bound;
- expect(bound.type, aElement.type);
-
- SimpleIdentifier boundIdentifier = bound.name;
- expect(boundIdentifier.staticElement, same(aElement));
- expect(boundIdentifier.staticType, aElement.type);
- }
-
- {
- var listElement = typeProvider.listType.element;
- var listOfA = typeProvider.listType.instantiate([aElement.type]);
-
- TypeParameter uNode = cNode.typeParameters.typeParameters[1];
- expect(uNode.element, same(cElement.typeParameters[1]));
-
- TypeName bound = uNode.bound;
- expect(bound.type, listOfA);
-
- SimpleIdentifier listIdentifier = bound.name;
- expect(listIdentifier.staticElement, same(listElement));
- expect(listIdentifier.staticType, listOfA);
-
- TypeName aTypeName = bound.typeArguments.arguments[0];
- expect(aTypeName.type, aElement.type);
-
- SimpleIdentifier aIdentifier = aTypeName.name;
- expect(aIdentifier.staticElement, same(aElement));
- expect(aIdentifier.staticType, aElement.type);
- }
-
- {
- TypeParameter vNode = cNode.typeParameters.typeParameters[2];
- expect(vNode.element, same(cElement.typeParameters[2]));
- expect(vNode.bound, isNull);
- }
- }
-
- test_tryCatch() async {
- addTestFile(r'''
-void main() {
- try {} catch (e, st) {
- e;
- st;
- }
- try {} on int catch (e, st) {
- e;
- st;
- }
- try {} catch (e) {
- e;
- }
- try {} on int catch (e) {
- e;
- }
- try {} on int {}
-}
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- List<Statement> statements = _getMainStatements(result);
-
- // catch (e, st)
- {
- TryStatement statement = statements[0];
- CatchClause catchClause = statement.catchClauses[0];
- expect(catchClause.exceptionType, isNull);
-
- SimpleIdentifier exceptionNode = catchClause.exceptionParameter;
- LocalVariableElement exceptionElement = exceptionNode.staticElement;
- expect(exceptionElement.type, DynamicTypeImpl.instance);
-
- SimpleIdentifier stackNode = catchClause.stackTraceParameter;
- LocalVariableElement stackElement = stackNode.staticElement;
- expect(stackElement.type, typeProvider.stackTraceType);
-
- List<Statement> catchStatements = catchClause.body.statements;
-
- ExpressionStatement exceptionStatement = catchStatements[0];
- SimpleIdentifier exceptionIdentifier = exceptionStatement.expression;
- expect(exceptionIdentifier.staticElement, same(exceptionElement));
- expect(exceptionIdentifier.staticType, DynamicTypeImpl.instance);
-
- ExpressionStatement stackStatement = catchStatements[1];
- SimpleIdentifier stackIdentifier = stackStatement.expression;
- expect(stackIdentifier.staticElement, same(stackElement));
- expect(stackIdentifier.staticType, typeProvider.stackTraceType);
- }
-
- // on int catch (e, st)
- {
- TryStatement statement = statements[1];
- CatchClause catchClause = statement.catchClauses[0];
- _assertTypeNameSimple(catchClause.exceptionType, typeProvider.intType);
-
- SimpleIdentifier exceptionNode = catchClause.exceptionParameter;
- LocalVariableElement exceptionElement = exceptionNode.staticElement;
- expect(exceptionElement.type, typeProvider.intType);
-
- SimpleIdentifier stackNode = catchClause.stackTraceParameter;
- LocalVariableElement stackElement = stackNode.staticElement;
- expect(stackElement.type, typeProvider.stackTraceType);
-
- List<Statement> catchStatements = catchClause.body.statements;
-
- ExpressionStatement exceptionStatement = catchStatements[0];
- SimpleIdentifier exceptionIdentifier = exceptionStatement.expression;
- expect(exceptionIdentifier.staticElement, same(exceptionElement));
- expect(exceptionIdentifier.staticType, typeProvider.intType);
-
- ExpressionStatement stackStatement = catchStatements[1];
- SimpleIdentifier stackIdentifier = stackStatement.expression;
- expect(stackIdentifier.staticElement, same(stackElement));
- expect(stackIdentifier.staticType, typeProvider.stackTraceType);
- }
-
- // catch (e)
- {
- TryStatement statement = statements[2];
- CatchClause catchClause = statement.catchClauses[0];
- expect(catchClause.exceptionType, isNull);
- expect(catchClause.stackTraceParameter, isNull);
-
- SimpleIdentifier exceptionNode = catchClause.exceptionParameter;
- LocalVariableElement exceptionElement = exceptionNode.staticElement;
- expect(exceptionElement.type, DynamicTypeImpl.instance);
- }
-
- // on int catch (e)
- {
- TryStatement statement = statements[3];
- CatchClause catchClause = statement.catchClauses[0];
- _assertTypeNameSimple(catchClause.exceptionType, typeProvider.intType);
- expect(catchClause.stackTraceParameter, isNull);
-
- SimpleIdentifier exceptionNode = catchClause.exceptionParameter;
- LocalVariableElement exceptionElement = exceptionNode.staticElement;
- expect(exceptionElement.type, typeProvider.intType);
- }
-
- // on int catch (e)
- {
- TryStatement statement = statements[4];
- CatchClause catchClause = statement.catchClauses[0];
- _assertTypeNameSimple(catchClause.exceptionType, typeProvider.intType);
- expect(catchClause.exceptionParameter, isNull);
- expect(catchClause.stackTraceParameter, isNull);
- }
- }
-
- test_type_functionTypeAlias() async {
- addTestFile(r'''
-typedef T F<T>(bool a);
-class C {
- F<int> f;
-}
-''');
-
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- CompilationUnitElement unitElement = unit.element;
- var typeProvider = unitElement.context.typeProvider;
-
- FunctionTypeAlias alias = unit.declarations[0];
- GenericTypeAliasElement aliasElement = alias.element;
- FunctionType aliasType = aliasElement.type;
-
- ClassDeclaration cNode = unit.declarations[1];
-
- FieldDeclaration fDeclaration = cNode.members[0];
- FunctionType instantiatedAliasType =
- aliasType.instantiate([typeProvider.intType]);
-
- TypeName typeName = fDeclaration.fields.type;
- expect(typeName.type, instantiatedAliasType);
-
- SimpleIdentifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, same(aliasElement));
- expect(typeIdentifier.staticType, instantiatedAliasType);
-
- List<TypeAnnotation> typeArguments = typeName.typeArguments.arguments;
- expect(typeArguments, hasLength(1));
- _assertTypeNameSimple(typeArguments[0], typeProvider.intType);
- }
-
- test_typeAnnotation_prefixed() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, "export 'a.dart';");
- provider.newFile(c, "export 'a.dart';");
- addTestFile(r'''
-import 'b.dart' as b;
-import 'c.dart' as c;
-b.A a1;
-c.A a2;
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
-
- ImportElement bImport = unit.element.library.imports[0];
- ImportElement cImport = unit.element.library.imports[1];
-
- LibraryElement bLibrary = bImport.importedLibrary;
- LibraryElement aLibrary = bLibrary.exports[0].exportedLibrary;
- ClassElement aClass = aLibrary.getType('A');
-
- {
- TopLevelVariableDeclaration declaration = unit.declarations[0];
- TypeName typeName = declaration.variables.type;
-
- PrefixedIdentifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, aClass);
-
- expect(typeIdentifier.prefix.name, 'b');
- expect(typeIdentifier.prefix.staticElement, same(bImport.prefix));
-
- expect(typeIdentifier.identifier.staticElement, aClass);
- }
-
- {
- TopLevelVariableDeclaration declaration = unit.declarations[1];
- TypeName typeName = declaration.variables.type;
-
- PrefixedIdentifier typeIdentifier = typeName.name;
- expect(typeIdentifier.staticElement, aClass);
-
- expect(typeIdentifier.prefix.name, 'c');
- expect(typeIdentifier.prefix.staticElement, same(cImport.prefix));
-
- expect(typeIdentifier.identifier.staticElement, aClass);
- }
- }
-
- test_typeLiteral() async {
- addTestFile(r'''
-void main() {
- int;
- F;
-}
-typedef void F(int p);
-''');
- AnalysisResult result = await driver.getResult(testFile);
- CompilationUnit unit = result.unit;
- var typeProvider = unit.element.context.typeProvider;
-
- FunctionTypeAlias fNode = unit.declarations[1];
- FunctionTypeAliasElement fElement = fNode.element;
-
- var statements = _getMainStatements(result);
-
- {
- ExpressionStatement statement = statements[0];
- SimpleIdentifier identifier = statement.expression;
- expect(identifier.staticElement, same(typeProvider.intType.element));
- expect(identifier.staticType, typeProvider.typeType);
- }
-
- {
- ExpressionStatement statement = statements[1];
- SimpleIdentifier identifier = statement.expression;
- expect(identifier.staticElement, same(fElement));
- expect(identifier.staticType, typeProvider.typeType);
- }
- }
-
- /// Assert that the [argument] is associated with the [expectedParameter],
- /// if [useCFE] is `null`. If the [argument] is a [NamedExpression],
- /// the name must be resolved to the parameter in both cases.
- void _assertArgumentToParameter(
- Expression argument, ParameterElement expectedParameter,
- {DartType parameterMemberType}) {
- ParameterElement actualParameter = argument.staticParameterElement;
- if (useCFE) {
- expect(actualParameter, isNull);
- if (argument is NamedExpression) {
- SimpleIdentifier name = argument.name.label;
- expect(name.staticElement, same(expectedParameter));
- }
- } else {
- ParameterElement baseActualParameter;
- if (actualParameter is ParameterMember) {
- if (parameterMemberType != null) {
- expect(actualParameter.type, parameterMemberType);
- }
- baseActualParameter = actualParameter.baseElement;
- // Unwrap ParameterMember one more time.
- // By some reason we wrap in twice.
- if (baseActualParameter is ParameterMember) {
- ParameterMember member = baseActualParameter;
- baseActualParameter = member.baseElement;
- }
- } else {
- baseActualParameter = actualParameter;
- }
- expect(baseActualParameter, same(expectedParameter));
- if (argument is NamedExpression) {
- SimpleIdentifier name = argument.name.label;
- expect(name.staticElement, same(actualParameter));
- }
- }
- }
-
- void _assertDefaultParameter(
- DefaultFormalParameter node, ParameterElement element,
- {String name, int offset, ParameterKind kind, DartType type}) {
- expect(node, isNotNull);
- NormalFormalParameter normalNode = node.parameter;
- _assertSimpleParameter(normalNode, element,
- name: name, offset: offset, kind: kind, type: type);
- }
-
- /// Assert that the [type] is a function type `() -> dynamic`.
- void _assertDynamicFunctionType(DartType type) {
- if (useCFE) {
- expect(type.toString(), '() → dynamic');
- } else {
- expect(type, DynamicTypeImpl.instance);
- }
- }
-
- void _assertParameterElement(ParameterElement element,
- {String name, int offset, ParameterKind kind, DartType type}) {
- expect(element, isNotNull);
- expect(name, isNotNull);
- expect(offset, isNotNull);
- expect(kind, isNotNull);
- expect(type, isNotNull);
- expect(element.name, name);
- expect(element.nameOffset, offset);
- // ignore: deprecated_member_use
- expect(element.parameterKind, kind);
- expect(element.type, type);
- }
-
- void _assertSimpleParameter(
- SimpleFormalParameter node, ParameterElement element,
- {String name, int offset, ParameterKind kind, DartType type}) {
- _assertParameterElement(element,
- name: name, offset: offset, kind: kind, type: type);
-
- expect(node, isNotNull);
- expect(node.element, same(element));
- expect(node.identifier.staticElement, same(element));
-
- TypeName typeName = node.type;
- if (typeName != null) {
- expect(typeName.type, same(type));
- expect(typeName.name.staticElement, same(type.element));
- }
- }
-
- void _assertTypeNameSimple(TypeName typeName, DartType type) {
- expect(typeName.type, type);
-
- SimpleIdentifier identifier = typeName.name;
- expect(identifier.staticElement, same(type.element));
- expect(identifier.staticType, type);
- }
-
- List<Statement> _getMainStatements(AnalysisResult result) {
- for (var declaration in result.unit.declarations) {
- if (declaration is FunctionDeclaration &&
- declaration.name.name == 'main') {
- BlockFunctionBody body = declaration.functionExpression.body;
- return body.block.statements;
- }
- }
- fail('Not found main() in ${result.unit}');
- }
-
- /**
- * Return the [provider] specific path for the given Posix [path].
- */
- String _p(String path) => provider.convertPath(path);
-}
-
@reflectiveTest
class AnalysisDriverSchedulerTest {
final MemoryResourceProvider provider = new MemoryResourceProvider();
@@ -6187,14 +492,8 @@
AnalysisResult libResult = await driver.getResult(lib);
List<AnalysisError> errors = libResult.errors;
- if (libResult.unit.element.context.analysisOptions.enableUriInPartOf) {
- expect(errors, hasLength(1));
- expect(errors[0].errorCode, ResolverErrorCode.PART_OF_UNNAMED_LIBRARY);
- } else {
- expect(errors, hasLength(1));
- expect(errors[0].errorCode,
- ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART);
- }
+ expect(errors, hasLength(1));
+ expect(errors[0].errorCode, ResolverErrorCode.PART_OF_UNNAMED_LIBRARY);
}
test_analyze_resolveDirectives_error_partOfDifferentLibrary_byName() async {
diff --git a/pkg/analyzer/test/src/dart/analysis/test_all.dart b/pkg/analyzer/test/src/dart/analysis/test_all.dart
index 0654881..527afbf 100644
--- a/pkg/analyzer/test/src/dart/analysis/test_all.dart
+++ b/pkg/analyzer/test/src/dart/analysis/test_all.dart
@@ -4,8 +4,12 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'context_locator_test.dart' as context_locator_test;
+import 'context_root_test.dart' as context_root_test;
import 'defined_names_test.dart' as defined_names_test;
import 'driver_kernel_test.dart' as driver_kernel;
+import 'driver_resolution_kernel_test.dart' as driver_resolution_kernel;
+import 'driver_resolution_test.dart' as driver_resolution;
import 'driver_test.dart' as driver;
import 'file_state_test.dart' as file_state;
import 'index_test.dart' as index;
@@ -17,9 +21,13 @@
main() {
defineReflectiveSuite(() {
+ context_locator_test.main();
+ context_root_test.main();
defined_names_test.main();
- driver_kernel.main();
driver.main();
+ driver_kernel.main();
+ driver_resolution.main();
+ driver_resolution_kernel.main();
file_state.main();
index.main();
mutex.main();
diff --git a/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart b/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
index af7574a..c555393 100644
--- a/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
@@ -27,11 +27,11 @@
validUnit =
parseCompilationUnit(validCode, codes: expectedErrorsInValidCode);
} catch (e) {
- print('');
- print(' Errors in valid code.');
- print(' Error: $e');
- print(' Code: $validCode');
- print('');
+// print('');
+// print(' Errors in valid code.');
+// print(' Error: $e');
+// print(' Code: $validCode');
+// print('');
rethrow;
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index a0c0970..0b1369a 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -8597,6 +8597,39 @@
''');
}
+ test_methodInvocation_implicitCall() async {
+ var library = await checkLibrary(r'''
+class A {
+ double call() => 0.0;
+}
+class B {
+ A a;
+}
+var c = new B().a();
+''');
+ if (isStrongMode) {
+ checkElementText(library, r'''
+class A {
+ double call() {}
+}
+class B {
+ A a;
+}
+double c;
+''');
+ } else {
+ checkElementText(library, r'''
+class A {
+ double call() {}
+}
+class B {
+ A a;
+}
+dynamic c;
+''');
+ }
+ }
+
test_nameConflict_exportedAndLocal() async {
namesThatCannotBeResolved.add('V');
addLibrarySource('/a.dart', 'class C {}');
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 1faae13..b4454ab 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -767,7 +767,6 @@
LibraryElement libraryElement;
test_perform() {
- enableUriInPartOf();
_performBuildTask({
'/lib.dart': '''
library lib;
@@ -822,6 +821,7 @@
(libraryUnit.directives[2] as PartDirective).element, same(secondPart));
}
+ @failingTest
test_perform_error_missingLibraryDirectiveWithPart() {
_performBuildTask({
'/lib.dart': '''
@@ -835,15 +835,11 @@
part of my_lib;
'''
});
- if (context.analysisOptions.enableUriInPartOf) {
- // TODO(28522)
- // Should report that names are wrong.
- } else {
- _assertErrorsWithCodes(
- [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
- }
+ // TODO(28522)
+ fail('Should report that names are wrong.');
}
+ @failingTest
test_perform_error_missingLibraryDirectiveWithPart_noCommon() {
_performBuildTask({
'/lib.dart': '''
@@ -857,13 +853,8 @@
part of libB;
'''
});
- if (context.analysisOptions.enableUriInPartOf) {
- // TODO(28522)
- // Should report that names are wrong.
- } else {
- _assertErrorsWithCodes(
- [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
- }
+ // TODO(28522)
+ fail('Should report that names are wrong.');
}
test_perform_error_partDoesNotExist() {
@@ -4962,16 +4953,6 @@
context.analysisOptions = options;
}
- /**
- * Enable the use of URIs in part-of directives in the current analysis
- * context.
- */
- void enableUriInPartOf() {
- AnalysisOptionsImpl options = context.analysisOptions;
- options.enableUriInPartOf = true;
- context.analysisOptions = options;
- }
-
void setUp() {
super.setUp();
emptySource = newSource('/test.dart');
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index acc3c41..15f7284 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -130,16 +130,6 @@
optype.inStaticMethodBody =
mthDecl is MethodDeclaration && mthDecl.isStatic;
- // If a value should be suggested, suggest also constructors.
- if (optype.includeReturnValueSuggestions) {
- // Careful: in angular plugin, `target.unit` may be null!
- CompilationUnitElement unitElement = target.unit?.element;
- if (unitElement != null &&
- unitElement.context.analysisOptions.previewDart2) {
- optype.includeConstructorSuggestions = true;
- }
- }
-
// Compute the type required by the context and set filters.
optype._computeRequiredTypeAndFilters(target);
diff --git a/pkg/compiler/lib/src/elements/resolution_types.dart b/pkg/compiler/lib/src/elements/resolution_types.dart
index e2f677a..2ae43fa 100644
--- a/pkg/compiler/lib/src/elements/resolution_types.dart
+++ b/pkg/compiler/lib/src/elements/resolution_types.dart
@@ -1084,6 +1084,7 @@
extends MoreSpecificVisitor<ResolutionDartType>
with AbstractTypeRelationMixin {
final Resolution resolution;
+ bool get strongMode => false;
ResolutionMoreSpecificVisitor(this.resolution);
}
@@ -1091,6 +1092,7 @@
class ResolutionSubtypeVisitor extends SubtypeVisitor<ResolutionDartType>
with AbstractTypeRelationMixin {
final Resolution resolution;
+ bool get strongMode => false;
ResolutionSubtypeVisitor(this.resolution);
}
@@ -1099,6 +1101,7 @@
extends PotentialSubtypeVisitor<ResolutionDartType>
with AbstractTypeRelationMixin {
final Resolution resolution;
+ bool get strongMode => false;
ResolutionPotentialSubtypeVisitor(this.resolution);
}
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index d91d8b3..c2110c7 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -105,15 +105,19 @@
Map<FunctionTypeVariable, Set<FunctionTypeVariable>> _assumptionMap =
<FunctionTypeVariable, Set<FunctionTypeVariable>>{};
- /// Assume that [a] and [b] are equivalent.
- void assume(FunctionTypeVariable a, FunctionTypeVariable b) {
+ void _addAssumption(FunctionTypeVariable a, FunctionTypeVariable b) {
_assumptionMap
.putIfAbsent(a, () => new Set<FunctionTypeVariable>.identity())
.add(b);
}
- /// Remove the assumption that [a] and [b] are equivalent.
- void forget(FunctionTypeVariable a, FunctionTypeVariable b) {
+ /// Assume that [a] and [b] are equivalent.
+ void assume(FunctionTypeVariable a, FunctionTypeVariable b) {
+ _addAssumption(a, b);
+ _addAssumption(b, a);
+ }
+
+ void _removeAssumption(FunctionTypeVariable a, FunctionTypeVariable b) {
Set<FunctionTypeVariable> set = _assumptionMap[a];
if (set != null) {
set.remove(b);
@@ -123,10 +127,30 @@
}
}
+ /// Remove the assumption that [a] and [b] are equivalent.
+ void forget(FunctionTypeVariable a, FunctionTypeVariable b) {
+ _removeAssumption(a, b);
+ _removeAssumption(b, a);
+ }
+
/// Returns `true` if [a] and [b] are assumed to be equivalent.
bool isAssumed(FunctionTypeVariable a, FunctionTypeVariable b) {
return _assumptionMap[a]?.contains(b) ?? false;
}
+
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.write('_Assumptions(');
+ String comma = '';
+ _assumptionMap
+ .forEach((FunctionTypeVariable a, Set<FunctionTypeVariable> set) {
+ sb.write('$comma$a (${identityHashCode(a)})->'
+ '{${set.map((b) => '$b (${identityHashCode(b)})').join(',')}}');
+ comma = ',';
+ });
+ sb.write(')');
+ return sb.toString();
+ }
}
class InterfaceType extends DartType {
@@ -878,6 +902,7 @@
abstract class AbstractTypeRelation<T extends DartType>
extends BaseDartTypeVisitor<bool, T> {
CommonElements get commonElements;
+ bool get strongMode;
final _Assumptions assumptions = new _Assumptions();
@@ -1103,18 +1128,32 @@
abstract class MoreSpecificVisitor<T extends DartType>
extends AbstractTypeRelation<T> {
bool isMoreSpecific(T t, T s) {
- if (identical(t, s) || s.treatAsDynamic || t == commonElements.nullType) {
- return true;
+ if (strongMode) {
+ if (identical(t, s) ||
+ s.treatAsDynamic ||
+ s.isVoid ||
+ s == commonElements.objectType ||
+ t == commonElements.nullType) {
+ return true;
+ }
+ if (t.treatAsDynamic) {
+ return false;
+ }
+ } else {
+ if (identical(t, s) || s.treatAsDynamic || t == commonElements.nullType) {
+ return true;
+ }
+ if (t.isVoid || s.isVoid) {
+ return false;
+ }
+ if (t.treatAsDynamic) {
+ return false;
+ }
+ if (s == commonElements.objectType) {
+ return true;
+ }
}
- if (t.isVoid || s.isVoid) {
- return false;
- }
- if (t.treatAsDynamic) {
- return false;
- }
- if (s == commonElements.objectType) {
- return true;
- }
+
t = getUnaliased(t);
s = getUnaliased(s);
@@ -1151,7 +1190,9 @@
abstract class SubtypeVisitor<T extends DartType>
extends MoreSpecificVisitor<T> {
bool isSubtype(DartType t, DartType s) {
- if (t.treatAsDynamic) return true;
+ if (!strongMode && t.treatAsDynamic) {
+ return true;
+ }
if (s.isFutureOr) {
FutureOrType sFutureOr = s;
if (isSubtype(t, sFutureOr.typeArgument)) {
@@ -1177,10 +1218,12 @@
}
bool invalidFunctionReturnTypes(T t, T s) {
+ if (strongMode) return !isSubtype(t, s);
return !s.isVoid && !isAssignable(t, s);
}
bool invalidFunctionParameterTypes(T t, T s) {
+ if (strongMode) return !isSubtype(s, t);
return !isAssignable(t, s);
}
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index f7489b2..d4a56bc 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -48,49 +48,48 @@
bool needsSuperGetter(FunctionEntity element) =>
_codegenWorldBuilder.methodsNeedingSuperGetter.contains(element);
- /**
- * Generates stubs to handle invocation of methods with optional
- * arguments.
- *
- * A method like `foo([x])` may be invoked by the following
- * calls: `foo(), foo(1), foo(x: 1)`. This method generates the stub for the
- * given [selector] and returns the generated [ParameterStubMethod].
- *
- * Returns null if no stub is needed.
- *
- * Members may be invoked in two ways: directly, or through a closure. In the
- * latter case the caller invokes the closure's `call` method. This method
- * accepts two selectors. The returned stub method has the corresponding
- * name [ParameterStubMethod.name] and [ParameterStubMethod.callName] set if
- * the input selector is non-null (and the member needs a stub).
- */
+ /// Generates stubs to fill in missing optional named or positional arguments
+ /// and missing type arguments. Returns `null` if no stub is needed.
+ ///
+ /// Methods like `foo([x])` and `bar({x})` may be invoked by the following
+ /// calls: `foo(), foo(1), bar(), bar(x: 1)`. This method generates the stub
+ /// for the given [selector] and returns the generated [ParameterStubMethod].
+ ///
+ /// Members may be invoked in two ways: directly, or through a closure. In the
+ /// latter case the caller invokes the tear-off closure's `call` method. This
+ /// method [generateParameterStub] accepts two selectors. The returned stub
+ /// method has the corresponding name [ParameterStubMethod.name] and
+ /// [ParameterStubMethod.callName] set if the input selector is non-null (and
+ /// the member needs a stub).
ParameterStubMethod generateParameterStub(
FunctionEntity member, Selector selector, Selector callSelector) {
- CallStructure callStructure = selector.callStructure;
- SourceInformationBuilder sourceInformationBuilder =
- _sourceInformationStrategy.createBuilderForContext(member);
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildStub(member, callStructure);
+ // The naming here can be a bit confusing. There is a call site somewhere
+ // that calls the stub via the [selector], which has a [CallStructure], so
+ // the *Call*Structure determines the *parameters* of the stub. The body of
+ // the stub calls the member which has a [ParameterStructure], so the
+ // *Parameter*Structure determines the *arguments* of the forwarding call.
+ CallStructure callStructure = selector.callStructure;
ParameterStructure parameterStructure = member.parameterStructure;
int positionalArgumentCount = callStructure.positionalArgumentCount;
assert(callStructure.typeArgumentCount == 0 ||
callStructure.typeArgumentCount == parameterStructure.typeParameters);
- bool needsTypeArguments =
- callStructure.typeArgumentCount != parameterStructure.typeParameters;
- if (positionalArgumentCount == parameterStructure.totalParameters &&
- !needsTypeArguments) {
- assert(callStructure.isUnnamed);
- return null;
- }
- if (parameterStructure.namedParameters.isNotEmpty &&
- callStructure.namedArgumentCount ==
- parameterStructure.namedParameters.length &&
- !needsTypeArguments) {
- // If the selector has the same number of named arguments as the element,
- // we don't need to add a stub. The call site will hit the method
- // directly.
- return null;
+
+ // We don't need a stub if the arguments match the target parameters,
+ // i.e. there are no missing optional arguments or types. The selector
+ // applies to the member, so we can check using counts.
+ if (callStructure.typeArgumentCount == parameterStructure.typeParameters) {
+ if (positionalArgumentCount == parameterStructure.totalParameters) {
+ // Positional optional arguments are all provided.
+ assert(callStructure.isUnnamed);
+ return null;
+ }
+ if (parameterStructure.namedParameters.isNotEmpty &&
+ callStructure.namedArgumentCount ==
+ parameterStructure.namedParameters.length) {
+ // Named optional arguments are all provided.
+ return null;
+ }
}
List<String> names = callStructure.getOrderedNamedArguments();
@@ -105,19 +104,21 @@
String receiverArgumentName = r'$receiver';
// The parameters that this stub takes.
- List<jsAst.Parameter> parametersBuffer =
- new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount);
+ List<jsAst.Parameter> stubParameters = new List<jsAst.Parameter>(
+ extraArgumentCount +
+ selector.argumentCount +
+ selector.typeArgumentCount);
// The arguments that will be passed to the real method.
- List<jsAst.Expression> argumentsBuffer = new List<jsAst.Expression>(
- parameterStructure.totalParameters +
- extraArgumentCount +
- (needsTypeArguments ? parameterStructure.typeParameters : 0));
+ List<jsAst.Expression> targetArguments = new List<jsAst.Expression>(
+ extraArgumentCount +
+ parameterStructure.totalParameters +
+ parameterStructure.typeParameters);
int count = 0;
if (isInterceptedMethod) {
count++;
- parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName);
- argumentsBuffer[0] = js('#', receiverArgumentName);
+ stubParameters[0] = new jsAst.Parameter(receiverArgumentName);
+ targetArguments[0] = js('#', receiverArgumentName);
}
int optionalParameterStart = positionalArgumentCount + extraArgumentCount;
@@ -129,20 +130,20 @@
String jsName = _namer.safeVariableName(name);
assert(jsName != receiverArgumentName);
if (count < optionalParameterStart) {
- parametersBuffer[count] = new jsAst.Parameter(jsName);
- argumentsBuffer[count] = js('#', jsName);
+ stubParameters[count] = new jsAst.Parameter(jsName);
+ targetArguments[count] = js('#', jsName);
} else {
int index = names.indexOf(name);
if (index != -1) {
indexOfLastOptionalArgumentInParameters = count;
// The order of the named arguments is not the same as the
// one in the real method (which is in Dart source order).
- argumentsBuffer[count] = js('#', jsName);
- parametersBuffer[optionalParameterStart + index] =
+ targetArguments[count] = js('#', jsName);
+ stubParameters[optionalParameterStart + index] =
new jsAst.Parameter(jsName);
} else {
if (value == null) {
- argumentsBuffer[count] =
+ targetArguments[count] =
_emitter.constantReference(new NullConstantValue());
} else {
if (!value.isNull) {
@@ -150,19 +151,27 @@
// down to the native method.
indexOfLastOptionalArgumentInParameters = count;
}
- argumentsBuffer[count] = _emitter.constantReference(value);
+ targetArguments[count] = _emitter.constantReference(value);
}
}
}
count++;
});
- if (needsTypeArguments) {
- // ignore: unused_local_variable
+
+ if (parameterStructure.typeParameters > 0) {
+ int parameterIndex =
+ stubParameters.length - parameterStructure.typeParameters;
for (TypeVariableType typeVariable
in _closedWorld.elementEnvironment.getFunctionTypeVariables(member)) {
- argumentsBuffer[count++] =
- // TODO(johnniwinther): Insert the type variable bound instead.
- _emitter.constantReference(new NullConstantValue());
+ if (selector.typeArgumentCount == 0) {
+ // TODO(32741): Insert the type variable bound instead of `null`.
+ targetArguments[count++] =
+ _emitter.constantReference(new NullConstantValue());
+ } else {
+ String jsName = '\$${typeVariable.element.name}';
+ stubParameters[parameterIndex++] = new jsAst.Parameter(jsName);
+ targetArguments[count++] = js('#', jsName);
+ }
}
}
@@ -172,8 +181,8 @@
member,
isInterceptedMethod,
_namer.invocationName(selector),
- parametersBuffer,
- argumentsBuffer,
+ stubParameters,
+ targetArguments,
indexOfLastOptionalArgumentInParameters);
} else if (member.isInstanceMember) {
if (needsSuperGetter(member)) {
@@ -186,18 +195,23 @@
body = js.statement('return #.#.call(this, #);', [
_emitterTask.prototypeAccess(superClass, hasBeenInstantiated: true),
methodName,
- argumentsBuffer
+ targetArguments
]);
} else {
body = js.statement('return this.#(#);',
- [_namer.instanceMethodName(member), argumentsBuffer]);
+ [_namer.instanceMethodName(member), targetArguments]);
}
} else {
body = js.statement('return #(#)',
- [_emitter.staticFunctionAccess(member), argumentsBuffer]);
+ [_emitter.staticFunctionAccess(member), targetArguments]);
}
- jsAst.Fun function = js('function(#) { #; }', [parametersBuffer, body])
+ SourceInformationBuilder sourceInformationBuilder =
+ _sourceInformationStrategy.createBuilderForContext(member);
+ SourceInformation sourceInformation =
+ sourceInformationBuilder.buildStub(member, callStructure);
+
+ jsAst.Fun function = js('function(#) { #; }', [stubParameters, body])
.withSourceInformation(sourceInformation);
jsAst.Name name = member.isStatic ? null : _namer.invocationName(selector);
@@ -262,10 +276,8 @@
}
assert(emptySelectorSet.isEmpty);
- if (liveSelectors == null)
- liveSelectors = const <Selector, SelectorConstraints>{};
- if (callSelectors == null)
- callSelectors = const <Selector, SelectorConstraints>{};
+ liveSelectors ??= const <Selector, SelectorConstraints>{};
+ callSelectors ??= const <Selector, SelectorConstraints>{};
List<ParameterStubMethod> stubs = <ParameterStubMethod>[];
diff --git a/pkg/compiler/lib/src/kernel/types.dart b/pkg/compiler/lib/src/kernel/types.dart
index cd97a06..b4be3ff 100644
--- a/pkg/compiler/lib/src/kernel/types.dart
+++ b/pkg/compiler/lib/src/kernel/types.dart
@@ -146,6 +146,7 @@
class _KernelSubtypeVisitor extends SubtypeVisitor<DartType>
with _AbstractTypeRelationMixin {
final KernelToElementMapBase elementMap;
+ bool get strongMode => elementMap.options.strongMode;
_KernelSubtypeVisitor(this.elementMap);
}
@@ -153,6 +154,7 @@
class _KernelPotentialSubtypeVisitor extends PotentialSubtypeVisitor<DartType>
with _AbstractTypeRelationMixin {
final KernelToElementMapBase elementMap;
+ bool get strongMode => elementMap.options.strongMode;
_KernelPotentialSubtypeVisitor(this.elementMap);
}
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index e9db66c..92be4c8 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -537,7 +537,7 @@
}
void detach(HInstruction instruction) {
- assert(contains(instruction));
+ assert(_truncatedContainsForAssert(instruction));
assert(instruction.isInBasicBlock());
if (instruction.previous == null) {
first = instruction.next;
@@ -565,6 +565,26 @@
if (identical(cursor, instruction)) return true;
cursor = cursor.next;
}
+
+ return false;
+ }
+
+ /// Linear search for [instruction], up to a limit of 100. Returns whether
+ /// the instruction is found or the list is too big.
+ ///
+ /// This is used for assertions only: some tests have pathological cases where
+ /// the basic blocks are huge (50K nodes!), and we found that checking for
+ /// [contains] within our assertions made compilation really slow.
+ bool _truncatedContainsForAssert(HInstruction instruction) {
+ HInstruction cursor = first;
+ int count = 0;
+ while (cursor != null) {
+ count++;
+ if (count > 100) return true;
+ if (identical(cursor, instruction)) return true;
+ cursor = cursor.next;
+ }
+
return false;
}
}
diff --git a/pkg/dev_compiler/bin/dartdevc.dart b/pkg/dev_compiler/bin/dartdevc.dart
index e1a9dcb..854700c 100755
--- a/pkg/dev_compiler/bin/dartdevc.dart
+++ b/pkg/dev_compiler/bin/dartdevc.dart
@@ -54,7 +54,7 @@
var watch = new Stopwatch()..start();
print('>>> BATCH START');
String line;
- while ((line = stdin.readLineSync(encoding: UTF8)).isNotEmpty) {
+ while ((line = stdin.readLineSync(encoding: utf8)).isNotEmpty) {
totalTests++;
var args = batchArgs.toList()..addAll(line.split(new RegExp(r'\s+')));
diff --git a/pkg/dev_compiler/bin/dartdevk.dart b/pkg/dev_compiler/bin/dartdevk.dart
index 36f4535..0d01d78 100755
--- a/pkg/dev_compiler/bin/dartdevk.dart
+++ b/pkg/dev_compiler/bin/dartdevk.dart
@@ -37,7 +37,7 @@
String line;
fe.InitializedCompilerState compilerState;
- while ((line = stdin.readLineSync(encoding: UTF8))?.isNotEmpty == true) {
+ while ((line = stdin.readLineSync(encoding: utf8))?.isNotEmpty == true) {
tests++;
var args = batchArgs.toList()..addAll(line.split(new RegExp(r'\s+')));
diff --git a/pkg/dev_compiler/lib/src/analyzer/ast_builder.dart b/pkg/dev_compiler/lib/src/analyzer/ast_builder.dart
index ec7174d..f4b4539 100644
--- a/pkg/dev_compiler/lib/src/analyzer/ast_builder.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/ast_builder.dart
@@ -382,8 +382,8 @@
FormalParameterList formalParameterList(List<FormalParameter> params) {
Token lp = new BeginToken(TokenType.OPEN_PAREN, 0);
Token rp = new Token(TokenType.CLOSE_PAREN, 0);
- bool hasOptional = params.any((p) => p.kind == ParameterKind.POSITIONAL);
- bool hasNamed = params.any((p) => p.kind == ParameterKind.NAMED);
+ bool hasOptional = params.any((p) => p.isPositional);
+ bool hasNamed = params.any((p) => p.isNamed);
assert(!(hasOptional && hasNamed));
Token ld = null;
Token rd = null;
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 17aa6ac..3f840d9 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -2155,8 +2155,7 @@
var type = _emitAnnotatedFunctionType(
reifiedType, annotationNode?.metadata,
- parameters: annotationNode?.parameters?.parameters,
- nameType: false);
+ parameters: annotationNode?.parameters?.parameters);
var property = new JS.Property(_declareMemberName(method), type);
if (method.isStatic) {
staticMethods.add(property);
@@ -2222,8 +2221,7 @@
var annotationNode = annotatedMembers[accessor] as MethodDeclaration;
var type = _emitAnnotatedFunctionType(
reifiedType, annotationNode?.metadata,
- parameters: annotationNode?.parameters?.parameters,
- nameType: false);
+ parameters: annotationNode?.parameters?.parameters);
var property = new JS.Property(_declareMemberName(accessor), type);
if (isStatic) {
@@ -2279,8 +2277,7 @@
var memberName = _constructorName(ctor.name);
var type = _emitAnnotatedFunctionType(
ctor.type, annotationNode?.metadata,
- parameters: annotationNode?.parameters?.parameters,
- nameType: false);
+ parameters: annotationNode?.parameters?.parameters);
constructors.add(new JS.Property(memberName, type));
}
}
@@ -2523,8 +2520,8 @@
var jsParam = _emitParameter(element)
..sourceInformation = _nodeStart(param.identifier);
- if (param.kind != ParameterKind.REQUIRED) {
- if (param.kind == ParameterKind.NAMED) {
+ if (param.isOptional) {
+ if (param.isNamed) {
// Parameters will be passed using their real names, not the (possibly
// renamed) local variable.
var paramName = js.string(param.identifier.name, "'");
@@ -2548,7 +2545,8 @@
paramName,
]));
}
- } else if (param.kind == ParameterKind.POSITIONAL) {
+ } else {
+ assert(param.isOptionalPositional);
var defaultValue = _defaultParamValue(param);
if (defaultValue != null) {
body.add(js.statement(
@@ -2744,8 +2742,8 @@
JS.Expression _emitFunctionTagged(JS.Expression fn, FunctionType type,
{bool topLevel: false}) {
var lazy = topLevel && !_typeIsLoaded(type);
- var typeRep = _emitFunctionType(type);
- return _callHelper(lazy ? 'lazyFn(#, () => #)' : 'fn(#, #)', [fn, typeRep]);
+ var typeRep = _emitFunctionType(type, lazy: lazy);
+ return _callHelper(lazy ? 'lazyFn(#, #)' : 'fn(#, #)', [fn, typeRep]);
}
/// Emits an arrow FunctionExpression node.
@@ -3192,13 +3190,6 @@
return result;
}
- JS.Expression _emitAnnotatedType(DartType type, List<Annotation> metadata,
- {bool nameType: true}) {
- metadata ??= [];
- var typeName = _emitType(type, nameType: nameType);
- return _emitAnnotatedResult(typeName, metadata);
- }
-
JS.Expression _emitFieldSignature(DartType type,
{List<Annotation> metadata, bool isFinal: true}) {
var args = [_emitType(type)];
@@ -3214,10 +3205,10 @@
{bool nameType: true}) {
var result = <JS.Expression>[];
for (int i = 0; i < types.length; ++i) {
- var metadata = parameters != null
- ? _parameterMetadata(parameters[i])
- : <Annotation>[];
- result.add(_emitAnnotatedType(types[i], metadata));
+ var metadata =
+ parameters != null ? _parameterMetadata(parameters[i]) : null;
+ var typeName = _emitType(types[i], nameType: nameType);
+ result.add(_emitAnnotatedResult(typeName, metadata));
}
return new JS.ArrayInitializer(result);
}
@@ -3235,7 +3226,9 @@
/// Emit the pieces of a function type, as an array of return type,
/// regular args, and optional/named args.
JS.Expression _emitFunctionType(FunctionType type,
- {List<FormalParameter> parameters, bool nameType: true}) {
+ {List<FormalParameter> parameters,
+ bool nameType = true,
+ bool lazy = false}) {
var parameterTypes = type.normalParameterTypes;
var optionalTypes = type.optionalParameterTypes;
var namedTypes = type.namedParameterTypes;
@@ -3285,14 +3278,14 @@
}
fullType = _callHelper(helperCall, [typeParts]);
if (!nameType) return fullType;
- return _typeTable.nameType(type, fullType);
+ return _typeTable.nameFunctionType(type, fullType, lazy: lazy);
}
JS.Expression _emitAnnotatedFunctionType(
FunctionType type, List<Annotation> metadata,
- {List<FormalParameter> parameters, bool nameType: true}) {
+ {List<FormalParameter> parameters}) {
var result =
- _emitFunctionType(type, parameters: parameters, nameType: nameType);
+ _emitFunctionType(type, parameters: parameters, nameType: false);
return _emitAnnotatedResult(result, metadata);
}
@@ -3300,8 +3293,8 @@
///
/// If [nameType] is true, then the type will be named. In addition,
/// if [hoistType] is true, then the named type will be hoisted.
- JS.Expression _emitConstructorAccess(DartType type, {bool nameType: true}) {
- return _emitJSInterop(type.element) ?? _emitType(type, nameType: nameType);
+ JS.Expression _emitConstructorAccess(DartType type) {
+ return _emitJSInterop(type.element) ?? _emitType(type);
}
/// Emits an expression that lets you access statics on an [c] from code.
@@ -3355,9 +3348,6 @@
// to canonicalize them too, at least when inside the same library.
var name = type.name;
if (name == '' || name == null) {
- // TODO(jmesserly): should we change how typedefs work? They currently
- // go through use similar logic as generic classes. This makes them
- // different from universal function types.
return _emitFunctionType(type as FunctionType, nameType: nameType);
}
@@ -3730,7 +3720,7 @@
var params = new List<JS.Identifier>.from(
_emitTypeFormals(method.typeParameters));
for (var param in method.parameters) {
- if (param.parameterKind == ParameterKind.NAMED) {
+ if (param.isNamed) {
params.add(namedArgumentTemp);
break;
}
@@ -3824,10 +3814,6 @@
return !isNullable(left) || !isNullable(right);
}
- bool _isCoreIdentical(Expression node) {
- return node is Identifier && node.staticElement == _coreIdentical;
- }
-
JS.Expression _emitJSDoubleEq(List<JS.Expression> args,
{bool negated = false}) {
var op = negated ? '# != #' : '# == #';
@@ -3862,15 +3848,23 @@
/// Emits a function call, to a top-level function, local function, or
/// an expression.
- JS.Expression _emitFunctionCall(InvocationExpression node,
- [Expression function]) {
+ JS.Node _emitFunctionCall(InvocationExpression node, [Expression function]) {
function ??= node.function;
var castTo = getImplicitOperationCast(function);
if (castTo != null) {
function = CoercionReifier.castExpression(function, castTo);
}
- if (_isCoreIdentical(function)) {
- return _emitCoreIdenticalCall(node.argumentList.arguments);
+ if (function is Identifier) {
+ var element = function.staticElement;
+ if (element == _coreIdentical) {
+ return _emitCoreIdenticalCall(node.argumentList.arguments);
+ }
+ var uri = element.librarySource.uri;
+ if (uri.scheme == 'dart' &&
+ uri.path.startsWith('developer') &&
+ element.name == 'debugger') {
+ return _emitDebuggerCall(node);
+ }
}
var fn = _visitExpression(function);
var args = _emitArgumentList(node.argumentList);
@@ -3891,6 +3885,47 @@
return new JS.Call(fn, args);
}
+ JS.Node _emitDebuggerCall(InvocationExpression node) {
+ var args = node.argumentList.arguments;
+ var isStatement = node.parent is ExpressionStatement;
+ if (args.isEmpty) {
+ // Inline `debugger()` with no arguments, as a statement if possible,
+ // otherwise as an immediately invoked function.
+ return isStatement
+ ? js.statement('debugger;')
+ : js.call('(() => { debugger; return true})()');
+ }
+
+ // The signature of `debugger()` is:
+ //
+ // bool debugger({bool when: true, String message})
+ //
+ // This code path handles the named arguments `when` and/or `message`.
+ // Both must be evaluated in the supplied order, and then `when` is used
+ // to decide whether to break or not.
+ //
+ // We also need to return the value of `when`.
+ var jsArgs = <JS.Property>[];
+ var foundWhen = false;
+ for (var arg in args) {
+ var namedArg = arg as NamedExpression;
+ if (namedArg.name.label.name == 'when') foundWhen = true;
+ jsArgs.add(visitNamedExpression(namedArg));
+ }
+ var when = jsArgs.length == 1
+ // For a single `when` argument, use it.
+ //
+ // For a single `message` argument, use `{message: ...}`, which
+ // coerces to true (the default value of `when`).
+ ? (foundWhen ? jsArgs[0].value : new JS.ObjectInitializer(jsArgs))
+ // If we have both `message` and `when` arguments, evaluate them in
+ // order, then extract the `when` argument.
+ : js.call('#.when', new JS.ObjectInitializer(jsArgs));
+ return isStatement
+ ? js.statement('if (#) debugger;', when)
+ : js.call('# && (() => { debugger; return true })()', when);
+ }
+
List<JS.Expression> _emitInvokeTypeArguments(InvocationExpression node) {
// add no reify generic check here: if (node.function)
// node is Identifier
@@ -4029,12 +4064,12 @@
// `throw` is emitted as a statement by `parseForeignJS`.
assert(result is JS.Expression ||
- result is JS.Throw && node.parent is ExpressionStatement);
+ result is JS.Statement && node.parent is ExpressionStatement);
return result;
}
@override
- JS.Expression visitFunctionExpressionInvocation(
+ JS.Node visitFunctionExpressionInvocation(
FunctionExpressionInvocation node) =>
_emitFunctionCall(node);
@@ -4067,7 +4102,7 @@
List<JS.Parameter> _emitParametersForElement(ExecutableElement member) {
var jsParams = <JS.Identifier>[];
for (var p in member.parameters) {
- if (p.parameterKind != ParameterKind.NAMED) {
+ if (p.isPositional) {
jsParams.add(new JS.Identifier(p.name));
} else {
jsParams.add(new JS.TemporaryId('namedArgs'));
@@ -4083,7 +4118,7 @@
var result = <JS.Parameter>[];
for (var param in parameters) {
- if (param.kind == ParameterKind.NAMED) {
+ if (param.isNamed) {
result.add(namedArgumentTemp);
break;
}
diff --git a/pkg/dev_compiler/lib/src/analyzer/command.dart b/pkg/dev_compiler/lib/src/analyzer/command.dart
index dd028f0..2aad791 100644
--- a/pkg/dev_compiler/lib/src/analyzer/command.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/command.dart
@@ -105,8 +105,7 @@
help: 'Ignore unrecognized command line flags.',
defaultsTo: false,
hide: hide)
- ..addOption('out',
- abbr: 'o', allowMultiple: true, help: 'Output file (required).')
+ ..addMultiOption('out', abbr: 'o', help: 'Output file (required).')
..addOption('module-root',
help: 'Root module directory. Module paths are relative to this root.')
..addOption('library-root',
@@ -284,7 +283,7 @@
Set<String> knownAbbreviations = new Set<String>();
parser.options.forEach((String name, option) {
knownOptions.add(name);
- String abbreviation = option.abbreviation;
+ String abbreviation = option.abbr;
if (abbreviation != null) {
knownAbbreviations.add(abbreviation);
}
diff --git a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
index ec95501..9a6ea0d 100644
--- a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
@@ -7,18 +7,10 @@
/// Helpers for Analyzer's Element model and corelib model.
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart'
- show
- ClassElement,
- CompilationUnitElement,
- Element,
- ExecutableElement,
- FunctionElement,
- LibraryElement,
- TypeParameterizedElement;
+import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart'
- show DartType, InterfaceType, ParameterizedType;
-import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl;
+ show DartType, InterfaceType, ParameterizedType, FunctionType;
+import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart'
show DartObject, DartObjectImpl;
@@ -183,6 +175,108 @@
return c.isMixinApplication && c.supertype.isObject && c.mixins.length == 1;
}
+bool isCallableClass(ClassElement c) {
+ // See if we have a "call" with a statically known function type:
+ //
+ // - if it's a method, then it does because all methods do,
+ // - if it's a getter, check the return type.
+ //
+ // Other cases like a getter returning dynamic/Object/Function will be
+ // handled at runtime by the dynamic call mechanism. So we only
+ // concern ourselves with statically known function types.
+ //
+ // We can ignore `noSuchMethod` because:
+ // * `dynamic d; d();` without a declared `call` method is handled by dcall.
+ // * for `class C implements Callable { noSuchMethod(i) { ... } }` we find
+ // the `call` method on the `Callable` interface.
+ var callMethod = c.type.lookUpInheritedGetterOrMethod('call');
+ return callMethod is PropertyAccessorElement
+ ? callMethod.returnType is FunctionType
+ : callMethod != null;
+}
+
+/// Returns true if [x] and [y] are equal, in other words, `x <: y` and `y <: x`
+/// and they have equivalent display form when printed.
+//
+// TODO(jmesserly): this exists to work around broken FunctionTypeImpl.== in
+// Analyzer. It has two bugs:
+// - typeArguments are considered, even though this has no semantic effect.
+// For example: `int -> int` that resulted from `(<T>(T) -> T)<int>` will not
+// equal another `int -> int`, even though they are the same type.
+// - named arguments are incorrectly treated as ordered, see
+// https://github.com/dart-lang/sdk/issues/26126.
+bool typesAreEqual(DartType x, DartType y) {
+ if (identical(x, y)) return true;
+ if (x is FunctionType) {
+ if (y is FunctionType) {
+ if (x.typeFormals.length != y.typeFormals.length) {
+ return false;
+ }
+ // `<T>T -> T` should be equal to `<U>U -> U`
+ // To test this, we instantiate both types with the same (unique) type
+ // variables, and see if the result is equal.
+ if (x.typeFormals.isNotEmpty) {
+ var fresh = FunctionTypeImpl.relateTypeFormals(
+ x, y, (t, s, _, __) => typesAreEqual(t, s));
+ if (fresh == null) return false;
+ return typesAreEqual(x.instantiate(fresh), y.instantiate(fresh));
+ }
+
+ return typesAreEqual(x.returnType, y.returnType) &&
+ _argumentsAreEqual(x.normalParameterTypes, y.normalParameterTypes) &&
+ _argumentsAreEqual(
+ x.optionalParameterTypes, y.optionalParameterTypes) &&
+ _namedArgumentsAreEqual(x.namedParameterTypes, y.namedParameterTypes);
+ } else {
+ return false;
+ }
+ }
+ if (x is InterfaceType) {
+ return y is InterfaceType &&
+ x.element == y.element &&
+ _argumentsAreEqual(x.typeArguments, y.typeArguments);
+ }
+ return x == y;
+}
+
+bool _argumentsAreEqual(List<DartType> first, List<DartType> second) {
+ if (first.length != second.length) return false;
+ for (int i = 0; i < first.length; i++) {
+ if (!typesAreEqual(first[i], second[i])) return false;
+ }
+ return true;
+}
+
+bool _namedArgumentsAreEqual(
+ Map<String, DartType> xArgs, Map<String, DartType> yArgs) {
+ if (yArgs.length != xArgs.length) return false;
+ for (var name in xArgs.keys) {
+ var x = xArgs[name];
+ var y = yArgs[name];
+ if (y == null || !typesAreEqual(x, y)) return false;
+ }
+ return true;
+}
+
+/// Returns a valid hashCode for [t] for use with [typesAreEqual].
+int typeHashCode(DartType t) {
+ if (t is FunctionType) {
+ // TODO(jmesserly): this is from Analyzer; it's not a great hash function.
+ int code = typeHashCode(t.returnType);
+ for (var p in t.normalParameterTypes) {
+ code = (code << 1) + typeHashCode(p);
+ }
+ for (var p in t.optionalParameterTypes) {
+ code = (code << 1) + typeHashCode(p);
+ }
+ for (var p in t.namedParameterTypes.values) {
+ code ^= typeHashCode(p); // xor because named parameters are unordered.
+ }
+ return code;
+ }
+ return t.hashCode;
+}
+
Uri uriForCompilationUnit(CompilationUnitElement unit) {
if (unit.source.isInSystemLibrary) {
return unit.source.uri;
diff --git a/pkg/dev_compiler/lib/src/analyzer/js_typeref_codegen.dart b/pkg/dev_compiler/lib/src/analyzer/js_typeref_codegen.dart
index 74be52e..18c13ee 100644
--- a/pkg/dev_compiler/lib/src/analyzer/js_typeref_codegen.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/js_typeref_codegen.dart
@@ -5,7 +5,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
-import 'package:analyzer/src/generated/utilities_dart.dart';
import '../js_ast/js_ast.dart' as JS;
import 'module_compiler.dart' show CompilerOptions;
@@ -52,12 +51,10 @@
if (type is FunctionType && type.name == null) {
var args = <JS.Identifier, JS.TypeRef>{};
for (var param in type.parameters) {
- if (param.parameterKind == ParameterKind.NAMED) break;
+ if (param.isNamed) break;
var type = emitTypeRef(param.type);
args[new JS.Identifier(param.name)] =
- param.parameterKind == ParameterKind.POSITIONAL
- ? type.toOptional()
- : type;
+ param.isPositional ? type.toOptional() : type;
}
var namedParamType = emitNamedParamsArgType(type.parameters);
if (namedParamType != null) {
@@ -85,7 +82,7 @@
var namedArgs = <JS.Identifier, JS.TypeRef>{};
for (ParameterElement param in params) {
- if (param.parameterKind != ParameterKind.NAMED) continue;
+ if (param.isPositional) continue;
namedArgs[new JS.Identifier(param.name)] =
emitTypeRef(param.type).toOptional();
}
diff --git a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
index b4343f9..c06fbec 100644
--- a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:collection' show HashSet, Queue;
-import 'dart:convert' show JSON;
+import 'dart:convert' show json;
import 'dart:io' show File;
import 'package:analyzer/analyzer.dart'
@@ -340,11 +340,10 @@
'allowing access to private members across library boundaries.',
defaultsTo: false,
hide: hide)
- ..addOption('bazel-mapping',
+ ..addMultiOption('bazel-mapping',
help:
'--bazel-mapping=genfiles/to/library.dart,to/library.dart uses \n'
'to/library.dart as the path for library.dart in source maps.',
- allowMultiple: true,
splitCommas: false,
hide: hide)
..addOption('summary-out',
@@ -473,7 +472,7 @@
var text = printer.getText();
var rawSourceMap = options.inlineSourceMap
- ? js.escapedString(JSON.encode(builtMap), "'").value
+ ? js.escapedString(json.encode(builtMap), "'").value
: 'null';
text = text.replaceFirst(sourceMapHoleID, rawSourceMap);
@@ -500,7 +499,7 @@
// to sources in the original sourcemap. The name of this file is bogus
// anyways, so it has very little effect on things.
c += '\n//# sourceURL=${name.replaceAll("/", ".")}.js\n';
- c = 'eval(${JSON.encode(c)});\n';
+ c = 'eval(${json.encode(c)});\n';
}
var file = new File(jsPath);
@@ -514,7 +513,7 @@
if (code.sourceMap != null) {
file = new File(mapPath);
if (!file.parent.existsSync()) file.parent.createSync(recursive: true);
- file.writeAsStringSync(JSON.encode(code.sourceMap));
+ file.writeAsStringSync(json.encode(code.sourceMap));
}
}
}
diff --git a/pkg/dev_compiler/lib/src/compiler/module_builder.dart b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
index 53f6735..17703195e 100644
--- a/pkg/dev_compiler/lib/src/compiler/module_builder.dart
+++ b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
@@ -47,23 +47,20 @@
/// file.
void addModuleFormatOptions(ArgParser argParser,
{bool allowMultiple: false, bool hide: true, bool singleOutFile: true}) {
- argParser.addOption('modules',
- help: 'module pattern to emit',
- allowed: [
- 'es6',
- 'common',
- 'amd',
- 'legacy', // deprecated
- 'node', // renamed to commonjs
- 'all' // to emit all flavors for the SDK
- ],
- allowedHelp: {
- 'es6': 'ECMAScript 6 modules',
- 'common': 'CommonJS/Node.js modules',
- 'amd': 'AMD/RequireJS modules'
- },
- allowMultiple: allowMultiple,
- defaultsTo: 'amd');
+ argParser.addMultiOption('modules', help: 'module pattern to emit', allowed: [
+ 'es6',
+ 'common',
+ 'amd',
+ 'legacy', // deprecated
+ 'node', // renamed to commonjs
+ 'all' // to emit all flavors for the SDK
+ ], allowedHelp: {
+ 'es6': 'ECMAScript 6 modules',
+ 'common': 'CommonJS/Node.js modules',
+ 'amd': 'AMD/RequireJS modules'
+ }, defaultsTo: [
+ 'amd'
+ ]);
if (singleOutFile) {
argParser.addFlag('single-out-file',
diff --git a/pkg/dev_compiler/lib/src/compiler/type_utilities.dart b/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
index a5dfc6f..23b34e7d 100644
--- a/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
+++ b/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
@@ -2,10 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:collection';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart' show TypeParameterMember;
import 'package:analyzer/dart/element/type.dart';
+import '../analyzer/element_helpers.dart';
import '../js_ast/js_ast.dart' as JS;
import '../js_ast/js_ast.dart' show js;
import 'js_names.dart' as JS;
@@ -41,7 +43,8 @@
// Use a LinkedHashMap to maintain key insertion order so the generated code
// is stable under slight perturbation. (If this is not good enough we could
// sort by name to canonicalize order.)
- final _names = <DartType, JS.TemporaryId>{};
+ final _names = new LinkedHashMap<DartType, JS.TemporaryId>(
+ equals: typesAreEqual, hashCode: typeHashCode);
Iterable<DartType> get keys => _names.keys.toList();
JS.Statement _dischargeType(DartType type) {
@@ -67,17 +70,6 @@
bool isNamed(DartType type) => _names.containsKey(type);
- /// If [type] is not already in the table, choose a new canonical
- /// variable to contain it. Emit an expression which uses [typeRep] to
- /// lazily initialize the cache in place.
- JS.Expression nameType(DartType type, JS.Expression typeRep) {
- var temp = _names[type];
- if (temp == null) {
- _names[type] = temp = chooseTypeName(type);
- }
- return js.call('# || (# = #)', [temp, temp, typeRep]);
- }
-
String _safeTypeName(String name) {
if (name == "<bottom>") return "bottom";
return name;
@@ -124,7 +116,8 @@
/// _GeneratorTable tracks types which have been
/// named and hoisted.
class _GeneratorTable extends _CacheTable {
- final _defs = <DartType, JS.Expression>{};
+ final _defs = new LinkedHashMap<DartType, JS.Expression>(
+ equals: typesAreEqual, hashCode: typeHashCode);
final JS.Identifier _runtimeModule;
@@ -143,14 +136,14 @@
/// If [type] does not already have a generator name chosen for it,
/// assign it one, using [typeRep] as the initializer for it.
- /// Emit an expression which calls the generator name.
- JS.Expression nameType(DartType type, JS.Expression typeRep) {
+ /// Emit the generator name.
+ JS.TemporaryId _nameType(DartType type, JS.Expression typeRep) {
var temp = _names[type];
if (temp == null) {
_names[type] = temp = chooseTypeName(type);
_defs[type] = typeRep;
}
- return js.call('#()', [temp]);
+ return temp;
}
}
@@ -200,30 +193,31 @@
/// 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).
- ///
- /// If [hoist] is true, then the JS representation will be hoisted up
- /// as far as possible and shared between instances of the type. For
- /// example, the generated code for dart.is(x, type) ends up as:
- /// let cacheVar;
- /// ...
- /// dart.is(x, (cacheVar || cacheVar = type))
- ///
- /// If [hoist] is false, the cache variable will be hoisted up as
- /// far as possible and shared between instances of the type, but the
- /// initializer expression will be emitted in place. The generated code
- /// for dart.is(x, type) in this case ends up as:
- /// let generator = () => (generator = dart.constFn(type))()
- /// ....
- /// dart.is(x, generator())
+ JS.Expression nameType(InterfaceType type, JS.Expression typeRep) {
+ if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
+ return typeRep;
+ }
+ var name = _generators._nameType(type, typeRep);
+ return js.call('#()', [name]);
+ }
+
+ /// Like [nameType] but for function types.
///
/// The boolean parameter [definite] distinguishes between definite function
/// types and other types (since the same DartType may have different
/// representations as definite and indefinite function types).
- JS.Expression nameType(DartType type, JS.Expression typeRep) {
- var table = _generators;
- if (!table.isNamed(type)) {
- if (recordScopeDependencies(type)) return typeRep;
+ ///
+ /// The boolean parameter [lazy] indicates that the resulting expression
+ /// should be a function that is invoked to compute the type, rather than the
+ /// type itself. This allows better integration with `lazyFn`, avoiding an
+ /// extra level of indirection.
+ JS.Expression nameFunctionType(FunctionType type, JS.Expression typeRep,
+ {bool lazy: false}) {
+ if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
+ return lazy ? new JS.ArrowFun([], typeRep) : typeRep;
}
- return table.nameType(type, typeRep);
+
+ var name = _generators._nameType(type, typeRep);
+ return lazy ? name : js.call('#()', [name]);
}
}
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart
index 16fea13..a918ee6 100644
--- a/pkg/dev_compiler/lib/src/js_ast/builder.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -1379,6 +1379,11 @@
return parseBreakOrContinue((label) => new Continue(label));
}
+ if (acceptString('debugger')) {
+ expectSemicolon();
+ return new DebuggerStatement();
+ }
+
if (acceptString('if')) return parseIfThenElse();
if (acceptString('for')) return parseFor();
diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
index cbbfa9b..5d37dac 100644
--- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
@@ -8,6 +8,7 @@
T visitProgram(Program node);
T visitBlock(Block node);
+ T visitDebuggerStatement(DebuggerStatement node);
T visitExpressionStatement(ExpressionStatement node);
T visitEmptyStatement(EmptyStatement node);
T visitIf(If node);
@@ -119,6 +120,7 @@
T visitJump(Statement node) => visitStatement(node);
T visitBlock(Block node) => visitStatement(node);
+ T visitDebuggerStatement(node) => visitStatement(node);
T visitExpressionStatement(ExpressionStatement node) => visitStatement(node);
T visitEmptyStatement(EmptyStatement node) => visitStatement(node);
T visitIf(If node) => visitStatement(node);
@@ -1869,6 +1871,12 @@
void visitChildren(NodeVisitor visitor) => expression.accept(visitor);
}
+class DebuggerStatement extends Statement {
+ T accept<T>(NodeVisitor<T> visitor) => visitor.visitDebuggerStatement(this);
+ DebuggerStatement _clone() => new DebuggerStatement();
+ void visitChildren(NodeVisitor visitor) {}
+}
+
/**
* Represents allowed module items:
* [Statement], [ImportDeclaration], and [ExportDeclaration].
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart
index 7688fc7..f2f785c 100644
--- a/pkg/dev_compiler/lib/src/js_ast/printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart
@@ -290,6 +290,10 @@
blockOut(block, true, true);
}
+ visitDebuggerStatement(node) {
+ outIndentLn('debugger;');
+ }
+
visitExpressionStatement(ExpressionStatement expressionStatement) {
indent();
outClosureAnnotation(expressionStatement);
diff --git a/pkg/dev_compiler/lib/src/js_ast/template.dart b/pkg/dev_compiler/lib/src/js_ast/template.dart
index 6b4bc6c..c52a3eb 100644
--- a/pkg/dev_compiler/lib/src/js_ast/template.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/template.dart
@@ -352,6 +352,9 @@
return (a) => makeExpression(a).toStatement();
}
+ Instantiator<DebuggerStatement> visitDebuggerStatement(node) =>
+ (a) => new DebuggerStatement();
+
Instantiator<EmptyStatement> visitEmptyStatement(EmptyStatement node) =>
(a) => new EmptyStatement();
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index f597ece..a3be2ea 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
-import 'dart:convert' show JSON;
+import 'dart:convert' show json;
import 'dart:io';
import 'package:args/args.dart';
@@ -113,13 +113,12 @@
..addOption('packages', help: 'The package spec file to use.')
..addOption('dart-sdk-summary',
help: 'The path to the Dart SDK summary file.', hide: true)
- ..addOption('summary',
+ ..addMultiOption('summary',
abbr: 's',
help: 'path to a summary of a transitive dependency of this module.\n'
- 'This path should be under a provided summary-input-dir',
- allowMultiple: true)
+ 'This path should be under a provided summary-input-dir')
..addFlag('source-map', help: 'emit source mapping', defaultsTo: true)
- ..addOption('summary-input-dir', allowMultiple: true)
+ ..addMultiOption('summary-input-dir')
..addOption('custom-app-scheme', defaultsTo: 'org-dartlang-app')
// Ignore dart2js options that we don't support in DDC.
..addFlag('enable-enum', hide: true)
@@ -213,7 +212,7 @@
if (jsCode.sourceMap != null) {
file = new File(output + '.map');
if (!file.parent.existsSync()) file.parent.createSync(recursive: true);
- file.writeAsStringSync(JSON.encode(jsCode.sourceMap));
+ file.writeAsStringSync(json.encode(jsCode.sourceMap));
}
return new CompilerResult(compilerState, true);
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index d603efe..87a5058 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -75,12 +75,15 @@
/// Let variables collected for the given function.
List<JS.TemporaryId> _letVariables;
- /// The class when it's emitting top-level code, used to order classes when
- /// they extend each other.
+ /// The class that is emitting its base class or mixin references, otherwise
+ /// null.
///
- /// This is not used when inside method bodies, or for other type information
- /// such as `implements`.
- Class _classEmittingTopLevel;
+ /// This is not used when inside the class method bodies, or for other type
+ /// information such as `implements`.
+ Class _classEmittingExtends;
+
+ /// The class that is emitting its signature information, otherwise null.
+ Class _classEmittingSignatures;
/// The current element being loaded.
/// We can use this to determine if we're loading top-level code or not:
@@ -522,8 +525,7 @@
/// declarations are assumed to be available before we start execution.
/// See [startTopLevel].
void _declareBeforeUse(Class c) {
- if (c == null) return;
- if (identical(_currentClass, _classEmittingTopLevel)) _emitClass(c);
+ if (c != null && _emittingClassExtends) _emitClass(c);
}
JS.Statement _emitClassDeclaration(Class c) {
@@ -730,8 +732,8 @@
}
}
- var savedTopLevelClass = _classEmittingTopLevel;
- _classEmittingTopLevel = c;
+ var savedTopLevelClass = _classEmittingExtends;
+ _classEmittingExtends = c;
// Unroll mixins.
if (shouldDefer(supertype)) {
@@ -760,8 +762,6 @@
mixinBody.add(
_callHelperStatement('mixinMembers(#, #)', [classExpr, mixinClass]));
- _classEmittingTopLevel = savedTopLevelClass;
-
if (methods.isNotEmpty) {
// However we may need to add some methods to this class that call
// `super` such as covariance checks.
@@ -777,6 +777,8 @@
}
emitMixinConstructors(className, m);
+
+ _classEmittingExtends = savedTopLevelClass;
return;
}
@@ -812,9 +814,8 @@
baseClass = mixinId;
}
- _classEmittingTopLevel = savedTopLevelClass;
-
body.add(_emitClassStatement(c, className, baseClass, methods));
+ _classEmittingExtends = savedTopLevelClass;
}
/// Defines all constructors for this class as ES5 constructors.
@@ -1150,6 +1151,9 @@
/// Emit the signature on the class recording the runtime type information
void _emitClassSignature(
Class c, JS.Expression className, List<JS.Statement> body) {
+ var savedClass = _classEmittingSignatures;
+ _classEmittingSignatures = c;
+
if (c.implementedTypes.isNotEmpty) {
body.add(js.statement('#[#.implements] = () => [#];', [
className,
@@ -1286,6 +1290,8 @@
body.add(_callHelperStatement('tagComputed(#, () => #.#);',
[className, emitLibraryName(coreTypes.coreLibrary), 'Type']));
}
+
+ _classEmittingSignatures = savedClass;
}
JS.Expression _emitFieldSignature(Field field, Class fromClass) {
@@ -1776,9 +1782,6 @@
}
/// Emits an expression that lets you access statics on a [type] from code.
- ///
- /// If [nameType] is true, then the type will be named. In addition,
- /// if [hoistType] is true, then the named type will be hoisted.
JS.Expression emitConstructorAccess(InterfaceType type) {
return _emitJSInterop(type.classNode) ?? visitInterfaceType(type);
}
@@ -2054,8 +2057,8 @@
void _emitTypedef(Typedef t) {
var savedUri = _currentUri;
_currentUri = t.fileUri;
- var body = _callHelper(
- 'typedef(#, () => #)', [js.string(t.name, "'"), _emitType(t.type)]);
+ var body = _callHelper('typedef(#, () => #)',
+ [js.string(t.name, "'"), visitFunctionType(t.type)]);
JS.Statement result;
if (t.typeParameters.isNotEmpty) {
@@ -2489,8 +2492,8 @@
JS.Expression _emitFunctionTagged(JS.Expression fn, FunctionType type,
{bool topLevel: false}) {
var lazy = topLevel && !_typeIsLoaded(type);
- var typeRep = visitFunctionType(type);
- return _callHelper(lazy ? 'lazyFn(#, () => #)' : 'fn(#, #)', [fn, typeRep]);
+ var typeRep = visitFunctionType(type, lazy: lazy);
+ return _callHelper(lazy ? 'lazyFn(#, #)' : 'fn(#, #)', [fn, typeRep]);
}
bool _typeIsLoaded(DartType type) {
@@ -2518,9 +2521,6 @@
[js.escapedString('node <${node.runtimeType}> $message`$node`')]);
}
- JS.Expression _nameType(DartType type, JS.Expression typeRep) =>
- _currentFunction != null ? _typeTable.nameType(type, typeRep) : typeRep;
-
@override
defaultDartType(type) => _emitInvalidNode(type);
@@ -2572,12 +2572,24 @@
jsArgs = [];
}
if (jsArgs != null) {
- return _nameType(type, _emitGenericClassType(type, jsArgs));
+ var typeRep = _emitGenericClassType(type, jsArgs);
+ return _cacheTypes ? _typeTable.nameType(type, typeRep) : typeRep;
}
return _emitTopLevelNameNoInterop(type.classNode);
}
+ bool get _emittingClassSignatures =>
+ _currentClass != null &&
+ identical(_currentClass, _classEmittingSignatures);
+
+ bool get _emittingClassExtends =>
+ _currentClass != null && identical(_currentClass, _classEmittingExtends);
+
+ bool get _cacheTypes =>
+ !_emittingClassExtends && !_emittingClassSignatures ||
+ _currentFunction != null;
+
JS.Expression _emitGenericClassType(
InterfaceType t, Iterable<JS.Expression> typeArgs) {
var genericName = _emitTopLevelNameNoInterop(t.classNode, suffix: '\$');
@@ -2588,7 +2600,7 @@
visitVectorType(type) => defaultDartType(type);
@override
- visitFunctionType(type, {bool lowerTypedef: false, FunctionNode function}) {
+ visitFunctionType(type, {FunctionNode function, bool lazy: false}) {
var requiredTypes =
type.positionalParameters.take(type.requiredParameterCount).toList();
var requiredParams = function?.positionalParameters
@@ -2641,7 +2653,10 @@
} else {
helperCall = 'fnType(#)';
}
- return _nameType(type, _callHelper(helperCall, [typeParts]));
+ var typeRep = _callHelper(helperCall, [typeParts]);
+ return _cacheTypes
+ ? _typeTable.nameFunctionType(type, typeRep, lazy: lazy)
+ : typeRep;
}
JS.Expression _emitAnnotatedFunctionType(FunctionType type, Member member) {
@@ -2723,7 +2738,8 @@
if (jsArgs != null) {
var genericName =
_emitTopLevelNameNoInterop(type.typedefNode, suffix: '\$');
- return _nameType(type, new JS.Call(genericName, jsArgs));
+ var typeRep = new JS.Call(genericName, jsArgs);
+ return _cacheTypes ? _typeTable.nameType(type, typeRep) : typeRep;
}
return _emitTopLevelNameNoInterop(type.typedefNode);
@@ -3186,9 +3202,13 @@
@override
visitExpressionStatement(ExpressionStatement node) {
var expr = node.expression;
- if (expr is StaticInvocation && isInlineJS(expr.target)) {
- var inlineJS = _emitInlineJSCode(expr);
- return inlineJS is JS.Statement ? inlineJS : inlineJS.toStatement();
+ if (expr is StaticInvocation) {
+ if (isInlineJS(expr.target)) {
+ return _emitInlineJSCode(expr).toStatement();
+ }
+ if (_isDebuggerCall(expr.target)) {
+ return _emitDebuggerCall(expr).toStatement();
+ }
}
return _visitExpression(expr).toStatement();
}
@@ -4325,12 +4345,57 @@
if (target == coreTypes.identicalProcedure) {
return _emitCoreIdenticalCall(node.arguments.positional);
}
+ if (_isDebuggerCall(target)) {
+ return _emitDebuggerCall(node) as JS.Expression;
+ }
var fn = _emitStaticTarget(target);
var args = _emitArgumentList(node.arguments);
return new JS.Call(fn, args);
}
+ bool _isDebuggerCall(Procedure target) {
+ return target.name.name == 'debugger' &&
+ target.enclosingLibrary.importUri.toString() == 'dart:developer';
+ }
+
+ JS.Node _emitDebuggerCall(StaticInvocation node) {
+ var args = node.arguments.named;
+ var isStatement = node.parent is ExpressionStatement;
+ if (args.isEmpty) {
+ // Inline `debugger()` with no arguments, as a statement if possible,
+ // otherwise as an immediately invoked function.
+ return isStatement
+ ? js.statement('debugger;')
+ : js.call('(() => { debugger; return true})()');
+ }
+
+ // The signature of `debugger()` is:
+ //
+ // bool debugger({bool when: true, String message})
+ //
+ // This code path handles the named arguments `when` and/or `message`.
+ // Both must be evaluated in the supplied order, and then `when` is used
+ // to decide whether to break or not.
+ //
+ // We also need to return the value of `when`.
+ var jsArgs = args.map(_emitNamedExpression).toList();
+ var when = args.length == 1
+ // For a single `when` argument, use it.
+ //
+ // For a single `message` argument, use `{message: ...}`, which
+ // coerces to true (the default value of `when`).
+ ? (args[0].name == 'when'
+ ? jsArgs[0].value
+ : new JS.ObjectInitializer(jsArgs))
+ // If we have both `message` and `when` arguments, evaluate them in
+ // order, then extract the `when` argument.
+ : js.call('#.when', new JS.ObjectInitializer(jsArgs));
+ return isStatement
+ ? js.statement('if (#) debugger;', when)
+ : js.call('# && (() => { debugger; return true })()', when);
+ }
+
/// Emits the target of a [StaticInvocation], [StaticGet], or [StaticSet].
JS.Expression _emitStaticTarget(Member target) {
var c = target.enclosingClass;
@@ -4357,17 +4422,18 @@
args.add(_visitExpression(arg));
}
}
- var named = <JS.Property>[];
- for (var arg in node.named) {
- named.add(new JS.Property(
- _propertyName(arg.name), _visitExpression(arg.value)));
- }
- if (named.isNotEmpty) {
- args.add(new JS.ObjectInitializer(named));
+ if (node.named.isNotEmpty) {
+ args.add(new JS.ObjectInitializer(
+ node.named.map(_emitNamedExpression).toList()));
}
return args;
}
+ JS.Property _emitNamedExpression(NamedExpression arg) {
+ return new JS.Property(
+ _propertyName(arg.name), _visitExpression(arg.value));
+ }
+
/// Emits code for the `JS(...)` macro.
JS.Node _emitInlineJSCode(StaticInvocation node) {
var args = node.arguments.positional;
@@ -4453,9 +4519,8 @@
var result = js.parseForeignJS(source).instantiate(jsArgs);
- // `throw` is emitted as a statement by `parseForeignJS`.
assert(result is JS.Expression ||
- result is JS.Throw && node.parent is ExpressionStatement);
+ result is JS.Statement && node.parent is ExpressionStatement);
return result;
}
diff --git a/pkg/dev_compiler/lib/src/kernel/type_table.dart b/pkg/dev_compiler/lib/src/kernel/type_table.dart
index bfb5e9c..d3f4ff7 100644
--- a/pkg/dev_compiler/lib/src/kernel/type_table.dart
+++ b/pkg/dev_compiler/lib/src/kernel/type_table.dart
@@ -63,17 +63,6 @@
bool isNamed(DartType type) => _names.containsKey(type);
- /// If [type] is not already in the table, choose a new canonical
- /// variable to contain it. Emit an expression which uses [typeRep] to
- /// lazily initialize the cache in place.
- JS.Expression nameType(DartType type, JS.Expression typeRep) {
- var temp = _names[type];
- if (temp == null) {
- _names[type] = temp = chooseTypeName(type);
- }
- return js.call('# || (# = #)', [temp, temp, typeRep]);
- }
-
String _typeString(DartType type, {bool flat: false}) {
if (type is InterfaceType) {
var name = type.classNode.name;
@@ -140,14 +129,14 @@
/// If [type] does not already have a generator name chosen for it,
/// assign it one, using [typeRep] as the initializer for it.
- /// Emit an expression which calls the generator name.
- JS.Expression nameType(DartType type, JS.Expression typeRep) {
+ /// Emit the generator name.
+ JS.TemporaryId _nameType(DartType type, JS.Expression typeRep) {
var temp = _names[type];
if (temp == null) {
_names[type] = temp = chooseTypeName(type);
_defs[type] = typeRep;
}
- return js.call('#()', [temp]);
+ return temp;
}
}
@@ -197,10 +186,25 @@
/// add the type and its representation to the table, returning an
/// expression which implements the type (but which caches the value).
JS.Expression nameType(DartType type, JS.Expression typeRep) {
- var table = _generators;
- if (!table.isNamed(type)) {
- if (recordScopeDependencies(type)) return typeRep;
+ if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
+ return typeRep;
}
- return table.nameType(type, typeRep);
+ var name = _generators._nameType(type, typeRep);
+ return js.call('#()', [name]);
+ }
+
+ /// Like [nameType] but for function types.
+ ///
+ /// The boolean parameter [lazy] indicates that the resulting expression
+ /// should be a function that is invoked to compute the type, rather than the
+ /// type itself. This allows better integration with `lazyFn`, avoiding an
+ /// extra level of indirection.
+ JS.Expression nameFunctionType(FunctionType type, JS.Expression typeRep,
+ {bool lazy: false}) {
+ if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
+ return lazy ? new JS.ArrowFun([], typeRep) : typeRep;
+ }
+ var name = _generators._nameType(type, typeRep);
+ return lazy ? name : js.call('#()', [name]);
}
}
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_ddc.status b/pkg/dev_compiler/test/sourcemap/stacktrace_ddc.status
index 4e909a6..af32f3c 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_ddc.status
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_ddc.status
@@ -6,7 +6,3 @@
throw_in_constructor_from_async: Crash
throw_in_instance_method: Crash
throw_in_static_method: Crash # Test works, but DDC's hover support means the expected column in the test is wrong
-
-throw_in_async: Crash # dartbug.com/31451
-throw_in_awaited_async: Crash # dartbug.com/31451
-throw_in_top_level_method_from_async: Crash # dartbug.com/31451
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_ddk.status b/pkg/dev_compiler/test/sourcemap/stacktrace_ddk.status
index 0a07791..7ba8da9 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_ddk.status
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_ddk.status
@@ -2,8 +2,4 @@
# 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.
-throw_in_async: Crash # dartbug.com/31451
-throw_in_awaited_async: Crash # dartbug.com/31451
-throw_in_constructor_from_async: Crash # dartbug.com/31451
throw_in_instance_method: Crash # Test works, but DDC's hover support means the expected column in the test is wrong
-throw_in_top_level_method_from_async: Crash # dartbug.com/31451
diff --git a/pkg/dev_compiler/test/worker/worker_test.dart b/pkg/dev_compiler/test/worker/worker_test.dart
index 047a7ae..d4caa69 100644
--- a/pkg/dev_compiler/test/worker/worker_test.dart
+++ b/pkg/dev_compiler/test/worker/worker_test.dart
@@ -120,7 +120,7 @@
var args = executableArgs.toList()..add('@${argsFile.path}');
var process = await Process.start(Platform.executable, args);
stderr.addStream(process.stderr);
- var futureProcessOutput = process.stdout.map(UTF8.decode).toList();
+ var futureProcessOutput = process.stdout.map(utf8.decode).toList();
expect(await process.exitCode, EXIT_CODE_OK);
expect((await futureProcessOutput).join(), isEmpty);
@@ -370,7 +370,7 @@
return new WorkResponse.fromBuffer(buffer);
} catch (_) {
var bufferAsString =
- buffer == null ? '' : 'String: ${UTF8.decode(buffer)}\n';
+ buffer == null ? '' : 'String: ${utf8.decode(buffer)}\n';
throw 'Failed to parse response:\nbytes: $buffer\n$bufferAsString';
}
}
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
index da1c67b..b04009e 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
@@ -4,12 +4,10 @@
// Patch file for the dart:async library.
-import 'dart:_js_helper' show patch, ReifyFunctionTypes;
+import 'dart:_js_helper' show patch, setTraceForException, ReifyFunctionTypes;
import 'dart:_isolate_helper'
show TimerImpl, global, leaveJsAsync, enterJsAsync;
-
import 'dart:_foreign_helper' show JS, JSExportName;
-
import 'dart:_runtime' as dart;
typedef void _Callback();
@@ -219,8 +217,6 @@
@patch
void _rethrow(Object error, StackTrace stackTrace) {
- // TODO(rnystrom): Not needed by dev_compiler.
- // error = wrapException(error);
- JS("void", "#.stack = #", error, stackTrace.toString());
- JS("void", "throw #", error);
+ setTraceForException(error, stackTrace);
+ dart.throw_(error);
}
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 5187db0..089d959 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
@@ -214,11 +214,12 @@
static String currentUri() {
// In a browser return self.location.href.
- if (JS('bool', '!!self.location')) {
- return JS('String', 'self.location.href');
+ if (JS('bool', '!!#.location', dart.global_)) {
+ return JS('String', '#.location.href', dart.global_);
}
- return null;
+ // TODO(vsm): Consider supporting properly in non-browser settings.
+ return '';
}
// This is to avoid stack overflows due to very large argument arrays in
@@ -570,7 +571,7 @@
*/
final _stackTrace = JS('', 'Symbol("_stackTrace")');
StackTrace getTraceFromException(exception) {
- var error = JS('', 'dart.recordJsError(#)', exception);
+ var error = dart.recordJsError(exception);
var trace = JS('StackTrace|Null', '#[#]', error, _stackTrace);
if (trace != null) return trace;
trace = new _StackTrace(error);
@@ -578,6 +579,14 @@
return trace;
}
+/**
+ * Called on rethrow to (potentially) set a different trace.
+ */
+void setTraceForException(exception, StackTrace trace) {
+ var error = dart.recordJsError(exception);
+ JS('', '#[#] = #', error, _stackTrace, trace);
+}
+
class _StackTrace implements StackTrace {
var _exception;
String _trace;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/profile.dart b/pkg/dev_compiler/tool/input_sdk/private/profile.dart
index 2026961..a325e27 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/profile.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/profile.dart
@@ -61,21 +61,13 @@
for (var record in _callMethodRecords) {
var stackStr = JS('String', '#.stack', record.jsError);
var frames = stackStr.split('\n');
- var src = '';
// Skip first two lines as the first couple frames are from the dart
// runtime.
- for (int i = 2; i < frames.length; ++i) {
- var frame = frames[i];
- var mappedFrame = _frameMappingCache.putIfAbsent(frame, () {
- return stackTraceMapper('\n${frame}');
- });
- if (!mappedFrame.contains('dart:_runtime/operations.dart') &&
- !mappedFrame.contains('dart:_debugger/profile.dart')) {
- src = mappedFrame;
-
- break;
- }
- }
+ var src = frames
+ .skip(2)
+ .map((f) =>
+ _frameMappingCache.putIfAbsent(f, () => stackTraceMapper('\n$f')))
+ .firstWhere((f) => !f.startsWith('dart:'), orElse: () => '');
var actualTypeName = dart.typeName(record.type);
callMethodStats
diff --git a/pkg/dev_compiler/tool/kernel_sdk.dart b/pkg/dev_compiler/tool/kernel_sdk.dart
index 4e8a20b..2cc7b9c 100755
--- a/pkg/dev_compiler/tool/kernel_sdk.dart
+++ b/pkg/dev_compiler/tool/kernel_sdk.dart
@@ -4,7 +4,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
-import 'dart:convert' show JSON;
+import 'dart:convert' show json;
import 'dart:io';
import 'package:args/args.dart' show ArgParser;
import 'package:dev_compiler/src/compiler/module_builder.dart';
@@ -60,6 +60,6 @@
await new Directory(jsDir).create();
var jsCode = jsProgramToCode(jsModule, format);
await new File(jsPath).writeAsString(jsCode.code);
- await new File('$jsPath.map').writeAsString(JSON.encode(jsCode.sourceMap));
+ await new File('$jsPath.map').writeAsString(json.encode(jsCode.sourceMap));
}
}
diff --git a/pkg/dev_compiler/web/web_command.dart b/pkg/dev_compiler/web/web_command.dart
index 857af1f..eae24da 100644
--- a/pkg/dev_compiler/web/web_command.dart
+++ b/pkg/dev_compiler/web/web_command.dart
@@ -268,7 +268,7 @@
// We emulate running code in the context of an existing library by
// importing that library and all libraries it imports.
- sb.write('import ${JSON.encode(existingLibrary)};\n');
+ sb.write('import ${json.encode(existingLibrary)};\n');
for (ImportElement importElement in libraryElement.imports) {
if (importElement.uri == null) continue;
@@ -281,7 +281,7 @@
!uri.startsWith('dart:')) {
uri = path.normalize(path.join(dir, uri));
}
- sb.write('import ${JSON.encode(uri)}');
+ sb.write('import ${json.encode(uri)}');
if (importElement.prefix != null)
sb.write(' as ${importElement.prefix.name}');
for (var combinator in importElement.combinators) {
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index 460e203..c60a782 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -22,8 +22,9 @@
bootstrapDill);
}
- /// Returns a component whose libraries are the recompiled libraries.
- Future<Component> computeDelta({Uri entryPoint});
+ /// Returns a component whose libraries are the recompiled libraries,
+ /// or - in the case of [fullComponent] - a full Component.
+ Future<Component> computeDelta({Uri entryPoint, bool fullComponent});
/// Remove the file associated with the given file [uri] from the set of
/// valid files. This guarantees that those files will be re-read on the
diff --git a/pkg/front_end/lib/src/base/errors.dart b/pkg/front_end/lib/src/base/errors.dart
index e6ebedf..7699dd1 100644
--- a/pkg/front_end/lib/src/base/errors.dart
+++ b/pkg/front_end/lib/src/base/errors.dart
@@ -36,7 +36,16 @@
* template. The correction associated with the error will be created from the
* given [correction] template.
*/
- const ErrorCode(this.name, this.message,
+ const ErrorCode(this.name, this.message, [this.correction])
+ : isUnresolvedIdentifier = false;
+
+ /**
+ * Initialize a newly created error code to have the given [name]. The message
+ * associated with the error will be created from the given [message]
+ * template. The correction associated with the error will be created from the
+ * given [correction] template.
+ */
+ const ErrorCode.temporary(this.name, this.message,
{this.correction, this.isUnresolvedIdentifier: false});
/**
diff --git a/pkg/front_end/lib/src/fasta/builder/builder.dart b/pkg/front_end/lib/src/fasta/builder/builder.dart
index a23ee34..9a49fd8 100644
--- a/pkg/front_end/lib/src/fasta/builder/builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/builder.dart
@@ -38,8 +38,6 @@
export 'library_builder.dart' show LibraryBuilder;
-export 'load_library_builder.dart' show LoadLibraryBuilder;
-
export 'member_builder.dart' show MemberBuilder;
export 'metadata_builder.dart' show MetadataBuilder;
diff --git a/pkg/front_end/lib/src/fasta/builder/prefix_builder.dart b/pkg/front_end/lib/src/fasta/builder/prefix_builder.dart
index daf4b6f..c115f35 100644
--- a/pkg/front_end/lib/src/fasta/builder/prefix_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/prefix_builder.dart
@@ -4,9 +4,7 @@
library fasta.prefix_builder;
-import 'package:kernel/ast.dart' show LibraryDependency;
-
-import 'builder.dart' show Builder, LibraryBuilder, Scope, LoadLibraryBuilder;
+import '../builder/builder.dart' show Builder, LibraryBuilder, Scope;
class PrefixBuilder extends Builder {
final String name;
@@ -15,26 +13,13 @@
final LibraryBuilder parent;
- final LibraryDependency dependency;
-
- LoadLibraryBuilder loadLibraryBuilder;
-
final bool deferred;
@override
final int charOffset;
- PrefixBuilder(this.name, this.deferred, LibraryBuilder parent,
- this.dependency, int charOffset)
- : parent = parent,
- charOffset = charOffset,
- super(parent, charOffset, parent.fileUri) {
- if (deferred) {
- loadLibraryBuilder =
- new LoadLibraryBuilder(parent, dependency, charOffset);
- addToExportScope('loadLibrary', loadLibraryBuilder, charOffset);
- }
- }
+ PrefixBuilder(this.name, this.deferred, this.parent, this.charOffset)
+ : super(parent, charOffset, parent.fileUri);
Builder lookup(String name, int charOffset, Uri fileUri) {
return exportScope.lookup(name, charOffset, fileUri);
diff --git a/pkg/front_end/lib/src/fasta/builder_graph.dart b/pkg/front_end/lib/src/fasta/builder_graph.dart
index b78d5f9..b4350b1 100644
--- a/pkg/front_end/lib/src/fasta/builder_graph.dart
+++ b/pkg/front_end/lib/src/fasta/builder_graph.dart
@@ -4,6 +4,8 @@
library fasta.builder_graph;
+import 'package:kernel/kernel.dart' show LibraryDependency, LibraryPart;
+
import 'package:kernel/util/graph.dart' show Graph;
import 'builder/builder.dart' show LibraryBuilder;
@@ -49,22 +51,15 @@
}
} else if (library is DillLibraryBuilder) {
// Imports and exports
- for (var dependency in library.library.dependencies) {
- var uriString;
- if (dependency.importedLibraryReference.node != null) {
- uriString = '${dependency.targetLibrary.importUri}';
- } else {
- uriString =
- '${dependency.importedLibraryReference.canonicalName.name}';
- }
- Uri uri = Uri.parse(uriString);
+ for (LibraryDependency dependency in library.library.dependencies) {
+ Uri uri = dependency.targetLibrary.importUri;
if (builders.containsKey(uri)) {
yield uri;
}
}
// Parts
- for (var part in library.library.parts) {
+ for (LibraryPart part in library.library.parts) {
Uri uri = part.fileUri;
if (builders.containsKey(uri)) {
yield uri;
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index 77ab869..54d8af3 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -125,7 +125,8 @@
return current.enableColorsCached ??= computeEnableColors(current);
}
- static void clear() {
+ void clear() {
StringToken.canonicalizer.clear();
+ errors.clear();
}
}
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 725203e..f234c10 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -1598,6 +1598,31 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(Token token)> templateExpectedEnumBody = const Template<
+ Message Function(Token token)>(
+ messageTemplate: r"""Expected a enum body, but got '#lexeme'.""",
+ tipTemplate:
+ r"""An enum definition must have a body with at least one constant name.""",
+ withArguments: _withArgumentsExpectedEnumBody);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Token token)> codeExpectedEnumBody =
+ const Code<Message Function(Token token)>(
+ "ExpectedEnumBody", templateExpectedEnumBody,
+ analyzerCode: "MISSING_ENUM_BODY", dart2jsCode: "*fatal*");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsExpectedEnumBody(Token token) {
+ String lexeme = token.lexeme;
+ return new Message(codeExpectedEnumBody,
+ message: """Expected a enum body, but got '$lexeme'.""",
+ tip:
+ """An enum definition must have a body with at least one constant name.""",
+ arguments: {'token': token});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(Token token)> templateExpectedFunctionBody =
const Template<Message Function(Token token)>(
messageTemplate: r"""Expected a function body, but got '#lexeme'.""",
@@ -2845,6 +2870,35 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String
+ string)> templateInternalVisitorUnsupportedDefault = const Template<
+ Message Function(String string)>(
+ messageTemplate:
+ r"""Trying to invoke a default visiting method of a visitor on a node #string.""",
+ tipTemplate:
+ r"""Try invoking one of the specialized 'visit' methods instead.""",
+ withArguments: _withArgumentsInternalVisitorUnsupportedDefault);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String string)>
+ codeInternalVisitorUnsupportedDefault =
+ const Code<Message Function(String string)>(
+ "InternalVisitorUnsupportedDefault",
+ templateInternalVisitorUnsupportedDefault,
+ severity: Severity.internalProblem);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsInternalVisitorUnsupportedDefault(String string) {
+ return new Message(codeInternalVisitorUnsupportedDefault,
+ message:
+ """Trying to invoke a default visiting method of a visitor on a node $string.""",
+ tip: """Try invoking one of the specialized 'visit' methods instead.""",
+ arguments: {'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeInterpolationInUri = messageInterpolationInUri;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/import.dart b/pkg/front_end/lib/src/fasta/import.dart
index f2c9ecc..1ae3b3b 100644
--- a/pkg/front_end/lib/src/fasta/import.dart
+++ b/pkg/front_end/lib/src/fasta/import.dart
@@ -6,10 +6,12 @@
import 'package:kernel/ast.dart' show LibraryDependency;
-import 'builder/builder.dart' show Builder, LibraryBuilder, PrefixBuilder;
+import 'builder/builder.dart' show Builder, LibraryBuilder;
import 'kernel/kernel_builder.dart' show toKernelCombinators;
+import 'kernel/kernel_prefix_builder.dart' show KernelPrefixBuilder;
+
import 'combinator.dart' show Combinator;
import 'configuration.dart' show Configuration;
@@ -23,7 +25,7 @@
/// The library being imported.
final LibraryBuilder imported;
- final PrefixBuilder prefixBuilder;
+ final KernelPrefixBuilder prefixBuilder;
final bool deferred;
@@ -101,6 +103,6 @@
combinators: toKernelCombinators(combinators))
..fileOffset = charOffset;
}
- return new PrefixBuilder(
+ return new KernelPrefixBuilder(
prefix, deferred, importer, dependency, prefixCharOffset);
}
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 4d1dc68..073b8d7 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -26,7 +26,8 @@
import 'dill/dill_target.dart' show DillTarget;
-import 'kernel/kernel_target.dart' show KernelTarget;
+import 'kernel/kernel_incremental_target.dart'
+ show KernelIncrementalTarget, KernelIncrementalTargetErroneousComponent;
import 'library_graph.dart' show LibraryGraph;
@@ -49,13 +50,14 @@
final Uri initializeFromDillUri;
bool initializedFromDill = false;
- KernelTarget userCode;
+ KernelIncrementalTarget userCode;
IncrementalCompiler(this.context, [this.initializeFromDillUri])
: ticker = context.options.ticker;
@override
- Future<Component> computeDelta({Uri entryPoint}) async {
+ Future<Component> computeDelta(
+ {Uri entryPoint, bool fullComponent: false}) async {
ticker.reset();
entryPoint ??= context.options.inputs.single;
return context.runInContext<Future<Component>>((CompilerContext c) async {
@@ -104,6 +106,9 @@
List<Uri> invalidatedUris = this.invalidatedUris.toList();
this.invalidatedUris.clear();
+ if (fullComponent) {
+ invalidatedUris.add(entryPoint);
+ }
List<LibraryBuilder> reusedLibraries =
computeReusedLibraries(invalidatedUris);
@@ -118,11 +123,13 @@
ticker.logMs("Decided to reuse ${reusedLibraries.length}"
" of ${userCode.loader.builders.length} libraries");
}
-
reusedLibraries.addAll(platformBuilders);
- userCode = new KernelTarget(
+
+ KernelIncrementalTarget userCodeOld = userCode;
+ userCode = new KernelIncrementalTarget(
c.fileSystem, false, dillLoadedData, dillLoadedData.uriTranslator,
uriToSource: c.uriToSource);
+
for (LibraryBuilder library in reusedLibraries) {
userCode.loader.builders[library.uri] = library;
if (library.uri.scheme == "dart" && library.uri.path == "core") {
@@ -130,14 +137,30 @@
}
}
- userCode.read(entryPoint);
+ Component componentWithDill;
+ try {
+ userCode.read(entryPoint);
+ await userCode.buildOutlines();
- await userCode.buildOutlines();
-
- // This is not the full component. It is the component including all
- // libraries loaded from .dill files.
- Component componentWithDill =
- await userCode.buildComponent(verify: c.options.verify);
+ // This is not the full component. It is the component including all
+ // libraries loaded from .dill files.
+ componentWithDill =
+ await userCode.buildComponent(verify: c.options.verify);
+ } on KernelIncrementalTargetErroneousComponent {
+ List<Library> librariesWithSdk = userCode.component.libraries;
+ List<Library> libraries = <Library>[];
+ for (Library lib in librariesWithSdk) {
+ if (lib.fileUri.scheme == "dart") continue;
+ libraries.add(lib);
+ break;
+ }
+ userCode.loader.builders.clear();
+ userCode = userCodeOld;
+ return new Component(
+ libraries: libraries, uriToSource: data.uriToSource);
+ }
+ userCodeOld?.loader?.builders?.clear();
+ userCodeOld = null;
List<Library> libraries =
new List<Library>.from(userCode.loader.libraries);
@@ -145,17 +168,20 @@
Procedure mainMethod = componentWithDill == null
? data.userLoadedUriMain
: componentWithDill.mainMethod;
- if (data.includeUserLoadedLibraries) {
- addUserLoadedLibraries(libraries, mainMethod, reusedLibraries, data);
+ if (data.includeUserLoadedLibraries || fullComponent) {
+ addReusedLibraries(libraries, mainMethod, reusedLibraries, data);
}
+ // Clean up.
+ userCode.loader.releaseAncillaryResources();
+
// This is the incremental component.
return new Component(libraries: libraries, uriToSource: data.uriToSource)
..mainMethod = mainMethod;
});
}
- void addUserLoadedLibraries(List<Library> libraries, Procedure mainMethod,
+ void addReusedLibraries(List<Library> libraries, Procedure mainMethod,
List<LibraryBuilder> reusedLibraries, IncrementalCompilerData data) {
Map<Uri, Library> libraryMap = <Uri, Library>{};
for (Library library in libraries) {
@@ -164,29 +190,31 @@
List<Uri> worklist = new List<Uri>.from(libraryMap.keys);
worklist.add(mainMethod?.enclosingLibrary?.fileUri);
- Map<Uri, Library> potentialLibraries = <Uri, Library>{};
+ Map<Uri, Library> potentiallyReferencedLibraries = <Uri, Library>{};
for (LibraryBuilder library in reusedLibraries) {
if (library.fileUri.scheme == "dart") continue;
- assert(library is DillLibraryBuilder);
- Library lib = (library as DillLibraryBuilder).library;
- potentialLibraries[library.fileUri] = lib;
+ Library lib = library.target;
+ potentiallyReferencedLibraries[library.fileUri] = lib;
libraryMap[library.fileUri] = lib;
}
LibraryGraph graph = new LibraryGraph(libraryMap);
- while (worklist.isNotEmpty) {
+ while (worklist.isNotEmpty && potentiallyReferencedLibraries.isNotEmpty) {
Uri uri = worklist.removeLast();
if (libraryMap.containsKey(uri)) {
for (Uri neighbor in graph.neighborsOf(uri)) {
worklist.add(neighbor);
}
libraryMap.remove(uri);
- Library library = potentialLibraries[uri];
+ Library library = potentiallyReferencedLibraries.remove(uri);
if (library != null) {
libraries.add(library);
}
}
}
+ for (Uri uri in potentiallyReferencedLibraries.keys) {
+ userCode.loader.builders.remove(uri);
+ }
// For now ensure original order of libraries to produce bit-perfect
// output.
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 01482b9..822a724 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -707,7 +707,7 @@
for (Expression invocation in constructorInvocationsWithImplicitConstness) {
if (invocation is ConstructorInvocation) {
ConstnessEffect constness =
- evaluateConstness(invocation, coreTypes).effect;
+ evaluateConstness(invocation, coreTypes, uri).effect;
if (constness == ConstnessEffect.taintedConst) {
// TODO(dmitryas): Find a better way to unwrap the error node.
ShadowSyntheticExpression errorMessage = buildCompileTimeError(
@@ -720,7 +720,7 @@
}
} else if (invocation is StaticInvocation) {
ConstnessEffect constness =
- evaluateConstness(invocation, coreTypes).effect;
+ evaluateConstness(invocation, coreTypes, uri).effect;
if (constness == ConstnessEffect.taintedConst) {
// TODO(dmitryas): Find a better way to unwrap the error node.
ShadowSyntheticExpression errorMessage = buildCompileTimeError(
@@ -3968,7 +3968,7 @@
@override
Expression wrapInDeferredCheck(
- Expression expression, PrefixBuilder prefix, int charOffset) {
+ Expression expression, KernelPrefixBuilder prefix, int charOffset) {
var check = new VariableDeclaration.forValue(
new CheckLibraryIsLoaded(prefix.dependency))
..fileOffset = charOffset;
diff --git a/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart
index 54371b0..6ed7d2b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart
@@ -6,7 +6,7 @@
import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/visitor.dart' show RecursiveVisitor;
+import 'package:kernel/visitor.dart' show ExpressionVisitor;
import '../names.dart'
show
@@ -34,7 +34,9 @@
tildaName,
unaryMinusName;
-import '../problems.dart' show unhandled;
+import '../fasta_codes.dart' show templateInternalVisitorUnsupportedDefault;
+
+import '../problems.dart' show unsupported;
enum ConstnessEffect {
decidedNew,
@@ -87,13 +89,31 @@
///
/// TODO(dmitryas): Share code with the constant evaluator from
/// pkg/kernel/lib/transformations/constants.dart.
-class ConstnessEvaluator extends RecursiveVisitor<ConstnessInfo> {
+class ConstnessEvaluator implements ExpressionVisitor<ConstnessInfo> {
final Map<Expression, ConstnessInfo> constnesses =
<Expression, ConstnessInfo>{};
final CoreTypes coreTypes;
- ConstnessEvaluator(this.coreTypes);
+ /// [Uri] of the file containing the expressions that are to be evaluated.
+ final Uri uri;
+
+ ConstnessEvaluator(this.coreTypes, this.uri);
+
+ @override
+ defaultExpression(Expression node) {
+ return unsupported(
+ templateInternalVisitorUnsupportedDefault
+ .withArguments("${node.runtimeType}")
+ .message,
+ node?.fileOffset ?? -1,
+ uri);
+ }
+
+ @override
+ defaultBasicLiteral(BasicLiteral node) {
+ return defaultExpression(node);
+ }
ConstnessInfo evaluate(Expression node) {
return node.accept(this);
@@ -108,40 +128,41 @@
}
@override
- defaultTreeNode(TreeNode node) {
- unhandled(
- "${node}", "defaultTreeNode", node.fileOffset, node.location.file);
- return null;
- }
-
visitNullLiteral(NullLiteral node) {
return const ConstnessInfo.allowedConst(ConstantKind.nullConstant);
}
+ @override
visitBoolLiteral(BoolLiteral node) {
return const ConstnessInfo.allowedConst(ConstantKind.boolConstant);
}
+ @override
visitIntLiteral(IntLiteral node) {
return const ConstnessInfo.allowedConst(ConstantKind.intConstant);
}
+ @override
visitDoubleLiteral(DoubleLiteral node) {
return const ConstnessInfo.allowedConst(ConstantKind.doubleConstant);
}
+ @override
visitStringLiteral(StringLiteral node) {
return const ConstnessInfo.allowedConst(ConstantKind.stringConstant);
}
+ @override
visitSymbolLiteral(SymbolLiteral node) {
return const ConstnessInfo.allowedConst(ConstantKind.symbolConstant);
}
+ @override
visitTypeLiteral(TypeLiteral node) {
return const ConstnessInfo.allowedConst(ConstantKind.typeConstant);
}
+ @override
visitListLiteral(ListLiteral node) {
if (node.isConst) {
return const ConstnessInfo.allowedConst(ConstantKind.listConstant);
@@ -149,6 +170,7 @@
return const ConstnessInfo.decidedNew();
}
+ @override
visitMapLiteral(MapLiteral node) {
if (node.isConst) {
return const ConstnessInfo.allowedConst(ConstantKind.mapConstant);
@@ -156,6 +178,7 @@
return const ConstnessInfo.decidedNew();
}
+ @override
visitConstructorInvocation(ConstructorInvocation node) {
if (constnesses[node] != null) return constnesses[node];
@@ -193,6 +216,7 @@
new ConstnessInfo(resultEffect, ConstantKind.interfaceConstant);
}
+ @override
visitMethodInvocation(MethodInvocation node) {
Expression receiver = node.receiver;
ConstnessInfo receiverConstness = receiver.accept(this);
@@ -244,6 +268,7 @@
return const ConstnessInfo.decidedNew();
}
+ @override
visitLogicalExpression(LogicalExpression node) {
ConstnessInfo left = node.left.accept(this);
if (node.operator == doubleBarName) {
@@ -277,11 +302,13 @@
return const ConstnessInfo.decidedNew();
}
+ @override
visitConditionalExpression(ConditionalExpression node) {
// TODO(dmitryas): Handle this case after boolean constants are handled.
return const ConstnessInfo.taintedConst(null);
}
+ @override
visitPropertyGet(PropertyGet node) {
// TODO(dmitryas): Handle this case after fields are handled.
ConstnessInfo receiverInfo = node.receiver.accept(this);
@@ -292,21 +319,25 @@
return const ConstnessInfo.taintedConst(null);
}
+ @override
visitLet(Let node) {
return node.body.accept(this);
}
+ @override
visitVariableGet(VariableGet node) {
if (!node.variable.isConst) return const ConstnessInfo.decidedNew();
// TODO(dmitryas): Handle the case of recursive dependencies.
return node.variable.initializer.accept(this);
}
+ @override
visitStaticGet(StaticGet node) {
// TODO(dmitryas): Handle this case.
return const ConstnessInfo.taintedConst(null);
}
+ @override
visitStringConcatenation(StringConcatenation node) {
List<ConstnessInfo> infos =
new List<ConstnessInfo>(node.expressions.length);
@@ -325,6 +356,7 @@
return new ConstnessInfo(effect, ConstantKind.stringConstant);
}
+ @override
visitStaticInvocation(StaticInvocation node) {
// TODO(dmitryas): Handle this case better.
Member target = node.target;
@@ -344,15 +376,167 @@
return const ConstnessInfo.taintedConst(null);
}
+ @override
visitAsExpression(AsExpression node) {
// TODO(dmitryas): Handle this case.
return const ConstnessInfo.taintedConst(null);
}
+ @override
visitNot(Not node) {
return node.operand.accept(this);
}
+ @override
+ visitInvalidExpression(InvalidExpression node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitVariableSet(VariableSet node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitPropertySet(PropertySet node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitDirectPropertyGet(DirectPropertyGet node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitDirectPropertySet(DirectPropertySet node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitSuperPropertyGet(SuperPropertyGet node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitSuperPropertySet(SuperPropertySet node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitStaticSet(StaticSet node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitDirectMethodInvocation(DirectMethodInvocation node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitSuperMethodInvocation(SuperMethodInvocation node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitIsExpression(IsExpression node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitThisExpression(ThisExpression node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitRethrow(Rethrow node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitThrow(Throw node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitAwaitExpression(AwaitExpression node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitFunctionExpression(FunctionExpression node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitConstantExpression(ConstantExpression node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitInstantiation(Instantiation node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitLoadLibrary(LoadLibrary node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitVectorCreation(VectorCreation node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitVectorGet(VectorGet node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitVectorSet(VectorSet node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitVectorCopy(VectorCopy node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
+ @override
+ visitClosureCreation(ClosureCreation node) {
+ // TODO(dmitryas): Handle this case.
+ return const ConstnessInfo.taintedConst(null);
+ }
+
/// Tells the minimum constness effect assuming the following:
/// * [ConstnessEffect.allowedConst] > [ConstnessEffect.taintedConst]
/// * [ConstnessEffect.taintedConst] > [ConstnessEffect.decidedNew]
@@ -462,6 +646,7 @@
}
// TODO(32717): Remove this helper function when the issue is resolved.
-ConstnessInfo evaluateConstness(Expression expression, CoreTypes coreTypes) {
- return new ConstnessEvaluator(coreTypes).evaluate(expression);
+ConstnessInfo evaluateConstness(
+ Expression expression, CoreTypes coreTypes, Uri uri) {
+ return new ConstnessEvaluator(coreTypes, uri).evaluate(expression);
}
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 fb16e2a..07560d3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
@@ -67,6 +67,7 @@
KernelFunctionTypeAliasBuilder,
KernelInvalidTypeBuilder,
KernelLibraryBuilder,
+ KernelPrefixBuilder,
KernelTypeVariableBuilder,
LibraryBuilder,
LoadLibraryBuilder,
@@ -141,7 +142,7 @@
StaticGet makeStaticGet(Member readTarget, Token token);
Expression wrapInDeferredCheck(
- Expression expression, PrefixBuilder prefix, int charOffset);
+ Expression expression, KernelPrefixBuilder prefix, int charOffset);
dynamic deprecated_addCompileTimeError(int charOffset, String message);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
index e9f65f3..a225661 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
@@ -17,6 +17,8 @@
export 'kernel_function_type_alias_builder.dart'
show KernelFunctionTypeAliasBuilder;
+export 'kernel_prefix_builder.dart' show KernelPrefixBuilder;
+
export 'kernel_named_type_builder.dart' show KernelNamedTypeBuilder;
export 'kernel_library_builder.dart' show KernelLibraryBuilder;
@@ -41,6 +43,8 @@
export 'kernel_invalid_type_builder.dart' show KernelInvalidTypeBuilder;
+export 'load_library_builder.dart' show LoadLibraryBuilder;
+
import 'package:kernel/ast.dart'
show
Combinator,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_incremental_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_incremental_target.dart
new file mode 100644
index 0000000..d83c9ae
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_incremental_target.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.
+
+library fasta.kernel_incremental_target;
+
+import 'package:kernel/ast.dart' show Component, Source;
+
+import '../../api_prototype/file_system.dart' show FileSystem;
+
+import '../dill/dill_target.dart' show DillTarget;
+
+import '../uri_translator.dart' show UriTranslator;
+
+import 'kernel_target.dart' show KernelTarget;
+
+class KernelIncrementalTarget extends KernelTarget {
+ Component component;
+
+ KernelIncrementalTarget(FileSystem fileSystem, bool includeComments,
+ DillTarget dillTarget, UriTranslator uriTranslator,
+ {Map<Uri, Source> uriToSource})
+ : super(fileSystem, includeComments, dillTarget, uriTranslator,
+ uriToSource: uriToSource);
+
+ @override
+ Component erroneousComponent(bool isFullComponent) {
+ component = super.erroneousComponent(isFullComponent);
+ throw const KernelIncrementalTargetErroneousComponent();
+ }
+}
+
+class KernelIncrementalTargetErroneousComponent {
+ const KernelIncrementalTargetErroneousComponent();
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_prefix_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_prefix_builder.dart
new file mode 100644
index 0000000..5c8aa36
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_prefix_builder.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fasta.kernel_prefix_builder;
+
+import 'package:kernel/ast.dart' show LibraryDependency;
+
+import '../builder/builder.dart' show LibraryBuilder, PrefixBuilder;
+
+import 'load_library_builder.dart' show LoadLibraryBuilder;
+
+class KernelPrefixBuilder extends PrefixBuilder {
+ final LibraryDependency dependency;
+
+ LoadLibraryBuilder loadLibraryBuilder;
+
+ KernelPrefixBuilder(String name, bool deferred, LibraryBuilder parent,
+ this.dependency, int charOffset)
+ : super(name, deferred, parent, charOffset) {
+ if (deferred) {
+ loadLibraryBuilder =
+ new LoadLibraryBuilder(parent, dependency, charOffset);
+ addToExportScope('loadLibrary', loadLibraryBuilder, charOffset);
+ }
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/load_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
similarity index 67%
rename from pkg/front_end/lib/src/fasta/builder/load_library_builder.dart
rename to pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
index c2365ca..57eace4 100644
--- a/pkg/front_end/lib/src/fasta/builder/load_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/load_library_builder.dart
@@ -4,20 +4,25 @@
import 'package:kernel/ast.dart'
show
- Member,
+ DartType,
+ DynamicType,
+ FunctionNode,
+ InterfaceType,
+ LibraryDependency,
LoadLibrary,
+ Member,
+ Name,
Procedure,
ProcedureKind,
- Name,
- FunctionNode,
- ReturnStatement,
- LibraryDependency;
+ ReturnStatement;
-import 'builder.dart' show Builder, LibraryBuilder;
+import '../builder/builder.dart' show Builder;
+
+import 'kernel_library_builder.dart' show KernelLibraryBuilder;
/// Builder to represent the `deferLibrary.loadLibrary` calls and tear-offs.
class LoadLibraryBuilder extends Builder {
- final LibraryBuilder parent;
+ final KernelLibraryBuilder parent;
final LibraryDependency importDependency;
@@ -39,9 +44,14 @@
if (tearoff != null) return tearoff;
LoadLibrary expression = createLoadLibrary(charOffset);
String prefix = expression.import.name;
- tearoff = new Procedure(new Name('__loadLibrary_$prefix', parent.target),
- ProcedureKind.Method, new FunctionNode(new ReturnStatement(expression)),
- fileUri: parent.target.fileUri, isStatic: true)
+ tearoff = new Procedure(
+ new Name('__loadLibrary_$prefix', parent.target),
+ ProcedureKind.Method,
+ new FunctionNode(new ReturnStatement(expression),
+ returnType: new InterfaceType(parent.loader.coreTypes.futureClass,
+ <DartType>[const DynamicType()])),
+ fileUri: parent.target.fileUri,
+ isStatic: true)
..fileOffset = charOffset;
return tearoff;
}
diff --git a/pkg/front_end/lib/src/fasta/library_graph.dart b/pkg/front_end/lib/src/fasta/library_graph.dart
index 6036c6f..0d7ab6f 100644
--- a/pkg/front_end/lib/src/fasta/library_graph.dart
+++ b/pkg/front_end/lib/src/fasta/library_graph.dart
@@ -4,8 +4,7 @@
library fasta.library_graph;
-import 'package:kernel/kernel.dart'
- show Library, LibraryDependency, LibraryPart;
+import 'package:kernel/kernel.dart' show Library, LibraryDependency;
import 'package:kernel/util/graph.dart' show Graph;
@@ -21,25 +20,17 @@
if (library == null) {
throw "Library not found: $vertex";
}
+
// Imports and exports
for (LibraryDependency dependency in library.dependencies) {
- String uriString;
- if (dependency.importedLibraryReference.node != null) {
- uriString = '${dependency.targetLibrary.importUri}';
- } else {
- uriString = '${dependency.importedLibraryReference.canonicalName.name}';
- }
- Uri uri = Uri.parse(uriString);
- if (libraries.containsKey(uri)) {
- yield uri;
- }
- }
-
- // Parts
- for (LibraryPart part in library.parts) {
- Uri uri = part.fileUri;
- if (libraries.containsKey(uri)) {
- yield uri;
+ Uri uri1 = dependency.targetLibrary.importUri;
+ Uri uri2 = dependency.targetLibrary.fileUri;
+ if (libraries.containsKey(uri1)) {
+ yield uri1;
+ } else if (uri2 != null) {
+ if (libraries.containsKey(uri2)) {
+ yield uri2;
+ }
}
}
}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 8f72afc..ed58944 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -1044,8 +1044,21 @@
/// type has already been parsed.
Token parseMixinApplicationRest(Token token) {
Token withKeyword = token.next;
+ if (!optional('with', withKeyword)) {
+ reportRecoverableError(
+ withKeyword, fasta.templateExpectedButGot.withArguments('with'));
+ withKeyword =
+ new SyntheticKeywordToken(Keyword.WITH, withKeyword.charOffset);
+ rewriter.insertTokenAfter(token, withKeyword);
+ if (!isValidTypeReference(withKeyword.next)) {
+ rewriter.insertTokenAfter(
+ withKeyword,
+ new SyntheticStringToken(
+ TokenType.IDENTIFIER, '', withKeyword.charOffset));
+ }
+ }
listener.beginMixinApplication(withKeyword);
- expect('with', withKeyword);
+ assert(optional('with', withKeyword));
token = parseTypeList(withKeyword);
listener.endMixinApplication(withKeyword);
return token;
@@ -1612,30 +1625,56 @@
Token enumKeyword = token.next;
assert(optional('enum', enumKeyword));
listener.beginEnum(enumKeyword);
- token =
- ensureIdentifier(enumKeyword, IdentifierContext.enumDeclaration).next;
- Token leftBrace = token;
- expect('{', token);
+ token = ensureIdentifier(enumKeyword, IdentifierContext.enumDeclaration);
+ Token leftBrace = token.next;
int count = 0;
- do {
- Token next = token.next;
- if (optional('}', next)) {
- token = next;
- if (count == 0) {
- reportRecoverableError(token, fasta.messageEnumDeclarationEmpty);
+ if (optional('{', leftBrace)) {
+ token = leftBrace;
+ while (true) {
+ Token next = token.next;
+ if (optional('}', next)) {
+ token = next;
+ if (count == 0) {
+ reportRecoverableError(token, fasta.messageEnumDeclarationEmpty);
+ }
+ break;
}
- break;
+ token = parseMetadataStar(token);
+ if (!identical(token.next, next)) {
+ listener.handleRecoverableError(
+ fasta.messageAnnotationOnEnumConstant, next, token);
+ }
+ token = ensureIdentifier(token, IdentifierContext.enumValueDeclaration);
+ next = token.next;
+ count++;
+ if (optional(',', next)) {
+ token = next;
+ } else if (optional('}', next)) {
+ token = next;
+ break;
+ } else {
+ // Recovery
+ if (next.isIdentifier) {
+ // If the next token is an identifier, assume a missing comma.
+ // TODO(danrubel): Consider improved recovery for missing `}`
+ // both here and when the scanner inserts a synthetic `}`
+ // for situations such as `enum Letter {a, b Letter e;`.
+ reportRecoverableError(
+ next, fasta.templateExpectedButGot.withArguments(','));
+ } else {
+ // Otherwise assume a missing `}` and exit the loop
+ reportRecoverableError(
+ next, fasta.templateExpectedButGot.withArguments('}'));
+ token = leftBrace.endGroup;
+ break;
+ }
+ }
}
- token = parseMetadataStar(token);
- if (!identical(token.next, next)) {
- listener.handleRecoverableError(
- fasta.messageAnnotationOnEnumConstant, next, token);
- }
- token =
- ensureIdentifier(token, IdentifierContext.enumValueDeclaration).next;
- count++;
- } while (optional(',', token));
- expect('}', token);
+ } else {
+ leftBrace = ensureBlock(token, fasta.templateExpectedEnumBody);
+ token = leftBrace.endGroup;
+ }
+ assert(optional('}', token));
listener.endEnum(enumKeyword, leftBrace, count);
return token;
}
@@ -3238,7 +3277,7 @@
if (optional('{', next)) return next;
Message message = template == null
? fasta.templateExpectedButGot.withArguments('{')
- : template.withArguments(token);
+ : template.withArguments(next);
reportRecoverableError(next, message);
return insertBlock(token);
}
@@ -4082,6 +4121,15 @@
int statementCount = 0;
if (!optional('{', next)) {
// Recovery
+ // If `return` used instead of `=>`, then report an error and continue
+ if (optional('return', next)) {
+ reportRecoverableError(next, fasta.messageExpectedBody);
+ next = rewriter
+ .insertTokenAfter(next,
+ new SyntheticToken(TokenType.FUNCTION, next.next.charOffset))
+ .next;
+ return parseExpressionFunctionBody(next, ofFunctionExpression);
+ }
// If there is a stray simple identifier in the function expression
// because the user is typing (e.g. `() asy => null;`)
// then report an error, skip the token, and continue parsing.
@@ -4129,12 +4177,6 @@
Token begin = token;
token = parseExpression(token);
if (!ofFunctionExpression) {
- // TODO(danrubel): Improve recovery and error message for `=> return`
- // If the token is `return` and
- // begin.next --> synthetic_id.next --> `return`
- // then discard the synthetic identifier and associated events (how?),
- // report an error on and skip the `return`,
- // and call parseExpression again.
token = ensureSemicolon(token);
listener.handleExpressionFunctionBody(begin, token);
} else {
@@ -4745,6 +4787,11 @@
return parseAssert(token, Assert.Expression);
} else if (token.next.isIdentifier) {
return parseSendOrFunctionLiteral(token, context);
+ } else if (identical(value, "return")) {
+ // Recovery
+ token = token.next;
+ reportRecoverableErrorWithToken(token, fasta.templateUnexpectedToken);
+ return parsePrimary(token, context);
} else {
// Fall through to the recovery code.
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index bc185c8..e3e168e 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -815,4 +815,9 @@
new InstrumentationValueLiteral(context.code.name));
}
}
+
+ void releaseAncillaryResources() {
+ hierarchy = null;
+ typeInferenceEngine = null;
+ }
}
diff --git a/pkg/front_end/lib/src/scanner/errors.dart b/pkg/front_end/lib/src/scanner/errors.dart
index b9fa104..454163c 100644
--- a/pkg/front_end/lib/src/scanner/errors.dart
+++ b/pkg/front_end/lib/src/scanner/errors.dart
@@ -62,7 +62,7 @@
* given [correction] template.
*/
const ScannerErrorCode(String name, String message, {String correction})
- : super(name, message, correction: correction);
+ : super.temporary(name, message, correction: correction);
@override
ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index dcdc6d1..795a7c7 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1254,6 +1254,11 @@
Verification of the generated program failed:
#string
+InternalVisitorUnsupportedDefault:
+ template: "Trying to invoke a default visiting method of a visitor on a node #string."
+ tip: "Try invoking one of the specialized 'visit' methods instead."
+ severity: INTERNAL_PROBLEM
+
LocalDefinitionHidesExport:
template: "Local definition of '#name' hides export from '#uri'."
severity: NIT
@@ -1434,6 +1439,14 @@
TypeVariableSameNameAsEnclosing:
template: "A type variable can't have the same name as its enclosing declaration."
+ExpectedEnumBody:
+ template: "Expected a enum body, but got '#lexeme'."
+ tip: "An enum definition must have a body with at least one constant name."
+ analyzerCode: MISSING_ENUM_BODY
+ dart2jsCode: "*fatal*"
+ script:
+ - "enum E"
+
EnumDeclarationEmpty:
template: "An enum declaration can't be empty."
analyzerCode: EMPTY_ENUM_BODY
diff --git a/pkg/front_end/test/incremental_bulk_compiler_full.dart b/pkg/front_end/test/incremental_bulk_compiler_full.dart
new file mode 100644
index 0000000..6a78e85
--- /dev/null
+++ b/pkg/front_end/test/incremental_bulk_compiler_full.dart
@@ -0,0 +1,180 @@
+// 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' show Future;
+
+import 'package:expect/expect.dart' show Expect;
+
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+ show CompilerOptions;
+
+import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart'
+ show IncrementalKernelGenerator;
+
+import 'package:front_end/src/compute_platform_binaries_location.dart'
+ show computePlatformBinariesLocation;
+
+import 'package:front_end/src/fasta/fasta_codes.dart' show LocatedMessage;
+
+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/text/ast_to_text.dart'
+ show globalDebuggingNames, NameSystem;
+
+import 'package:testing/testing.dart'
+ show Chain, ChainContext, Result, Step, TestDescription, runMe;
+
+main([List<String> arguments = const []]) =>
+ runMe(arguments, createContext, "../testing.json");
+
+Future<Context> createContext(
+ Chain suite, Map<String, String> environment) async {
+ return new Context();
+}
+
+class Context extends ChainContext {
+ final List<Step> steps = const <Step>[
+ const RunTest(),
+ ];
+
+ // Override special handling of negative tests.
+ @override
+ Result processTestResult(
+ TestDescription description, Result result, bool last) {
+ return result;
+ }
+
+ IncrementalCompiler compiler;
+}
+
+CompilerOptions getOptions(bool strong) {
+ final Uri sdkRoot = computePlatformBinariesLocation();
+ var options = new CompilerOptions()
+ ..sdkRoot = sdkRoot
+ ..librariesSpecificationUri = Uri.base.resolve("sdk/lib/libraries.json")
+ ..onProblem = (LocatedMessage message, Severity severity, String formatted,
+ int line, int column) {
+ // ignore
+ }
+ ..strongMode = strong;
+ if (strong) {
+ options.sdkSummary =
+ computePlatformBinariesLocation().resolve("vm_platform_strong.dill");
+ } else {
+ options.sdkSummary =
+ computePlatformBinariesLocation().resolve("vm_platform.dill");
+ }
+ return options;
+}
+
+class RunTest extends Step<TestDescription, TestDescription, Context> {
+ const RunTest();
+
+ String get name => "run test";
+
+ Future<Result<TestDescription>> run(
+ TestDescription description, Context context) async {
+ Uri uri = description.uri;
+
+ // "One shot compile"
+ bool oneShotFailed = false;
+ List<int> oneShotSerialized;
+ try {
+ IncrementalCompiler compiler =
+ new IncrementalKernelGenerator(getOptions(true), uri);
+ oneShotSerialized = postProcess(await compiler.computeDelta());
+ } catch (e) {
+ oneShotFailed = true;
+ }
+
+ // Bulk
+ bool bulkFailed = false;
+ List<int> bulkSerialized;
+ try {
+ globalDebuggingNames = new NameSystem();
+ if (context.compiler == null) {
+ context.compiler =
+ new IncrementalKernelGenerator(getOptions(true), uri);
+ }
+ Component bulkCompiledComponent = await context.compiler
+ .computeDelta(entryPoint: uri, fullComponent: true);
+ bulkSerialized = postProcess(bulkCompiledComponent);
+ } catch (e) {
+ bulkFailed = true;
+ }
+
+ // Compile again - the serialized output should be the same.
+ bool bulk2Failed = false;
+ List<int> bulkSerialized2;
+ try {
+ globalDebuggingNames = new NameSystem();
+ if (context.compiler == null) {
+ context.compiler =
+ new IncrementalKernelGenerator(getOptions(true), uri);
+ }
+ Component bulkCompiledComponent = await context.compiler
+ .computeDelta(entryPoint: uri, fullComponent: true);
+ bulkSerialized2 = postProcess(bulkCompiledComponent);
+ } catch (e) {
+ bulk2Failed = true;
+ }
+
+ if (bulkFailed || oneShotFailed) {
+ if (bulkFailed != oneShotFailed) {
+ throw "Bulk-compiler failed: $bulkFailed; "
+ "one-shot failed: $oneShotFailed";
+ }
+ } else {
+ checkIsEqual(oneShotSerialized, bulkSerialized);
+ }
+
+ if (bulkFailed || bulk2Failed) {
+ if (bulkFailed != bulk2Failed) {
+ throw "Bulk-compiler failed: $bulkFailed; "
+ "second bulk-comile failed: $bulk2Failed";
+ }
+ } else {
+ checkIsEqual(bulkSerialized, bulkSerialized2);
+ }
+
+ 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) {
+ length = b.length;
+ }
+ for (int i = 0; i < length; ++i) {
+ if (a[i] != b[i]) {
+ Expect.fail("Data differs at byte ${i+1}.");
+ }
+ }
+ Expect.equals(a.length, b.length);
+ }
+}
diff --git a/pkg/front_end/test/incremental_bulk_compiler_smoke_test.dart b/pkg/front_end/test/incremental_bulk_compiler_smoke_test.dart
new file mode 100644
index 0000000..5399635
--- /dev/null
+++ b/pkg/front_end/test/incremental_bulk_compiler_smoke_test.dart
@@ -0,0 +1,17 @@
+// 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' show Future;
+
+import 'package:testing/testing.dart' show Chain, runMe;
+
+import 'incremental_bulk_compiler_full.dart' show Context;
+
+main([List<String> arguments = const []]) =>
+ runMe(arguments, createContext, "../testing.json");
+
+Future<Context> createContext(
+ Chain suite, Map<String, String> environment) async {
+ return new Context();
+}
diff --git a/pkg/front_end/testcases/ast_builder.status b/pkg/front_end/testcases/ast_builder.status
index 71b880f..0007d0b 100644
--- a/pkg/front_end/testcases/ast_builder.status
+++ b/pkg/front_end/testcases/ast_builder.status
@@ -8,8 +8,6 @@
argument_mismatch: Fail
bug32629: Fail
dynamic_and_void: Fail
-illegal_named_function_expression: Crash
-illegal_named_function_expression_scope: Crash
inference/abstract_class_instantiation: Fail
inference/constructors_too_many_positional_arguments: Fail
inference/downwards_inference_annotations: Crash
@@ -48,16 +46,11 @@
override_check_with_covariant_modifier: Fail
rasta/bad_default_constructor: VerificationError
rasta/issue_000039: VerificationError
-rasta/issue_000042: Crash
rasta/mandatory_parameter_initializer: VerificationError
rasta/parser_error: VerificationError
rasta/unresolved_for_in: Crash
-regress/issue_29937: Crash
regress/issue_29941: Crash
-regress/issue_29942: Crash
regress/issue_29943: Crash
-regress/issue_29978: Crash
-regress/issue_29979: Crash
regress/issue_29983: Crash # 'package:analyzer/src/fasta/ast_builder.dart': Failed assertion: line 478 pos 12: 'star == null': is not true.
regress/issue_31155: Crash # Issue 31155.
regress/issue_31157: Crash
diff --git a/pkg/front_end/testcases/compile.status b/pkg/front_end/testcases/compile.status
index 31b8193..f06a2f9 100644
--- a/pkg/front_end/testcases/compile.status
+++ b/pkg/front_end/testcases/compile.status
@@ -126,3 +126,5 @@
co19_language_metadata_syntax_t04: RuntimeError # Fasta doesn't recover well
external_import: RuntimeError # Expected -- test uses import which doesn't exist.
+
+implicit_const_with_static_fields: Fail
diff --git a/pkg/front_end/testcases/implicit_const_with_static_fields.dart b/pkg/front_end/testcases/implicit_const_with_static_fields.dart
new file mode 100644
index 0000000..f5a8e03
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_const_with_static_fields.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.
+
+const constTopLevelField = 42;
+
+class C {
+ const C(x);
+ static const constField = 87;
+}
+
+main() {
+ C(C.constField);
+ C(constTopLevelField);
+}
diff --git a/pkg/front_end/testcases/incremental_bulk_compiler_full.status b/pkg/front_end/testcases/incremental_bulk_compiler_full.status
new file mode 100644
index 0000000..4240855
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_bulk_compiler_full.status
@@ -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.md file.
+language_2/deferred_super_dependency_test: Crash # missing "#errors"
+language_2/missing_part_of_tag_test: Crash # missing empty library that shouldn't have been there in the first place
+language_2/regress_27957_test: Crash # isSynthetic becomes false on C1 SuperInitializer.
+language_2/script1_negative_test: Crash # missing "#errors", missing empty library that shouldn't have been there in the first place
+language_2/script2_negative_test: Crash # missing "#errors", missing empty library that shouldn't have been there in the first place
+
diff --git a/pkg/front_end/testcases/incremental_bulk_compiler_smoke.status b/pkg/front_end/testcases/incremental_bulk_compiler_smoke.status
new file mode 100644
index 0000000..4240855
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_bulk_compiler_smoke.status
@@ -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.md file.
+language_2/deferred_super_dependency_test: Crash # missing "#errors"
+language_2/missing_part_of_tag_test: Crash # missing empty library that shouldn't have been there in the first place
+language_2/regress_27957_test: Crash # isSynthetic becomes false on C1 SuperInitializer.
+language_2/script1_negative_test: Crash # missing "#errors", missing empty library that shouldn't have been there in the first place
+language_2/script2_negative_test: Crash # missing "#errors", missing empty library that shouldn't have been there in the first place
+
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart
new file mode 100644
index 0000000..255ffe6
--- /dev/null
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.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.
+
+/*@testedFeatures=error*/
+
+const int foo = const int.fromEnvironment("fisk");
+
+class A {
+ final int bar;
+ const A(this.bar);
+}
+
+class B {
+ final A baz;
+ const B(this.baz);
+}
+
+class C {
+ fun() {
+ /*@error=CantDetermineConstness*/ B(
+ /*@error=CantDetermineConstness*/ A(foo));
+ }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.expect b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.expect
new file mode 100644
index 0000000..c486c02
--- /dev/null
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.expect
@@ -0,0 +1,28 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ final field core::int bar;
+ const constructor •(core::int bar) → void
+ : self::A::bar = bar, super core::Object::•()
+ ;
+}
+class B extends core::Object {
+ final field self::A baz;
+ const constructor •(self::A baz) → void
+ : self::B::baz = baz, super core::Object::•()
+ ;
+}
+class C extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method fun() → dynamic {
+ invalid-expression "pkg/front_end/testcases/nested_implicit_const_with_env_var.dart:21:39: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+ /*@error=CantDetermineConstness*/ B(
+ ^";
+ }
+}
+static const field core::int foo = const core::int::fromEnvironment("fisk");
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.transformed.expect b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.transformed.expect
new file mode 100644
index 0000000..c486c02
--- /dev/null
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.direct.transformed.expect
@@ -0,0 +1,28 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ final field core::int bar;
+ const constructor •(core::int bar) → void
+ : self::A::bar = bar, super core::Object::•()
+ ;
+}
+class B extends core::Object {
+ final field self::A baz;
+ const constructor •(self::A baz) → void
+ : self::B::baz = baz, super core::Object::•()
+ ;
+}
+class C extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method fun() → dynamic {
+ invalid-expression "pkg/front_end/testcases/nested_implicit_const_with_env_var.dart:21:39: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+ /*@error=CantDetermineConstness*/ B(
+ ^";
+ }
+}
+static const field core::int foo = const core::int::fromEnvironment("fisk");
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.outline.expect b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.outline.expect
new file mode 100644
index 0000000..17440e2
--- /dev/null
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.outline.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ final field core::int bar;
+ const constructor •(core::int bar) → void
+ ;
+}
+class B extends core::Object {
+ final field self::A baz;
+ const constructor •(self::A baz) → void
+ ;
+}
+class C extends core::Object {
+ synthetic constructor •() → void
+ ;
+ method fun() → dynamic
+ ;
+}
+static const field core::int foo;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.expect b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.expect
new file mode 100644
index 0000000..c486c02
--- /dev/null
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.expect
@@ -0,0 +1,28 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ final field core::int bar;
+ const constructor •(core::int bar) → void
+ : self::A::bar = bar, super core::Object::•()
+ ;
+}
+class B extends core::Object {
+ final field self::A baz;
+ const constructor •(self::A baz) → void
+ : self::B::baz = baz, super core::Object::•()
+ ;
+}
+class C extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method fun() → dynamic {
+ invalid-expression "pkg/front_end/testcases/nested_implicit_const_with_env_var.dart:21:39: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+ /*@error=CantDetermineConstness*/ B(
+ ^";
+ }
+}
+static const field core::int foo = const core::int::fromEnvironment("fisk");
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.transformed.expect b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.transformed.expect
new file mode 100644
index 0000000..c486c02
--- /dev/null
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.strong.transformed.expect
@@ -0,0 +1,28 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ final field core::int bar;
+ const constructor •(core::int bar) → void
+ : self::A::bar = bar, super core::Object::•()
+ ;
+}
+class B extends core::Object {
+ final field self::A baz;
+ const constructor •(self::A baz) → void
+ : self::B::baz = baz, super core::Object::•()
+ ;
+}
+class C extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method fun() → dynamic {
+ invalid-expression "pkg/front_end/testcases/nested_implicit_const_with_env_var.dart:21:39: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+ /*@error=CantDetermineConstness*/ B(
+ ^";
+ }
+}
+static const field core::int foo = const core::int::fromEnvironment("fisk");
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index 80f615e..a31e6b7 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -280,3 +280,5 @@
rasta/issue_000047: Fail
rasta/native_is_illegal: Pass # Issue 29763
rasta/type_with_parse_error: Fail
+
+implicit_const_with_static_fields: Fail
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
index ce0e482..9a7f7e0 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
@@ -16,7 +16,7 @@
let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(self::Fisk);
}
- for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Expected lvalue, but got Instance of 'PrefixBuilder'
+ for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
for (collection in x) {
^" in x) {
core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
@@ -47,7 +47,7 @@
let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t7].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(self::Fisk);
}
- for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Expected lvalue, but got Instance of 'PrefixBuilder'
+ for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
for (collection in arguments) {
^" in arguments) {
core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
index ce0e482..9a7f7e0 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
@@ -16,7 +16,7 @@
let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(self::Fisk);
}
- for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Expected lvalue, but got Instance of 'PrefixBuilder'
+ for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
for (collection in x) {
^" in x) {
core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
@@ -47,7 +47,7 @@
let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t7].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
core::print(self::Fisk);
}
- for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Expected lvalue, but got Instance of 'PrefixBuilder'
+ for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Expected lvalue, but got Instance of 'KernelPrefixBuilder'
for (collection in arguments) {
^" in arguments) {
core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
diff --git a/pkg/front_end/testcases/shaker/empty_program.dart.outline.expect b/pkg/front_end/testcases/shaker/empty_program.dart.outline.expect
index b48746b..99fafe3 100644
--- a/pkg/front_end/testcases/shaker/empty_program.dart.outline.expect
+++ b/pkg/front_end/testcases/shaker/empty_program.dart.outline.expect
@@ -85,8 +85,8 @@
get first() → self::Future<self::Stream::T>;
get last() → self::Future<self::Stream::T>;
get single() → self::Future<self::Stream::T>;
- method firstWhere((self::Stream::T) → core::bool test, {() → dynamic defaultValue, () → self::Stream::T orElse}) → self::Future<self::Stream::T>;
- method lastWhere((self::Stream::T) → core::bool test, {() → dynamic defaultValue, () → self::Stream::T orElse}) → self::Future<self::Stream::T>;
+ method firstWhere((self::Stream::T) → core::bool test, {() → self::Stream::T orElse}) → self::Future<self::Stream::T>;
+ method lastWhere((self::Stream::T) → core::bool test, {() → self::Stream::T orElse}) → self::Future<self::Stream::T>;
method singleWhere((self::Stream::T) → core::bool test, {() → self::Stream::T orElse}) → self::Future<self::Stream::T>;
method elementAt(core::int index) → self::Future<self::Stream::T>;
method timeout(core::Duration timeLimit, {(self::EventSink<self::Stream::T>) → void onTimeout}) → self::Stream<self::Stream::T>;
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 6f767dc..a1d3394 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -33,6 +33,7 @@
function_type_recovery: Fail
functions: Fail
hello: Fail
+implicit_const_with_static_fields: Fail
implicit_this: Fail
invocations: Fail
literals: Fail
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index d16fa77..0d7449a 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -161,6 +161,46 @@
},
{
+ "name": "incremental_bulk_compiler_smoke",
+ "kind": "Chain",
+ "source": "test/incremental_bulk_compiler_smoke_test.dart",
+ "path": "../../tests/",
+ "status": "testcases/incremental_bulk_compiler_smoke.status",
+ "pattern": [
+ "/language_2/accessor_conflict_export2_test\\.dart$",
+ "/language_2/accessor_conflict_export_test\\.dart$",
+ "/language_2/regress_14348_test\\.dart$",
+ "/language_2/regress_18535_test\\.dart$",
+ "/language_2/deferred_super_dependency_test\\.dart$",
+ "/language_2/export_ambiguous_main_test\\.dart$",
+ "/language_2/export_double_same_main_test\\.dart$",
+ "/language_2/export_main_test\\.dart$",
+ "/language_2/issue1578_negative_test\\.dart$",
+ "/language_2/missing_part_of_tag_test\\.dart$",
+ "/language_2/no_main_test\\.dart$",
+ "/language_2/regress_27957_test\\.dart$",
+ "/language_2/script1_negative_test\\.dart$",
+ "/language_2/script2_negative_test\\.dart$",
+ "/language_2/unbalanced_brace_test\\.dart$"
+ ],
+ "exclude": [
+ ]
+ },
+
+ {
+ "name": "incremental_bulk_compiler_full",
+ "kind": "Chain",
+ "source": "test/incremental_bulk_compiler_full.dart",
+ "path": "../../tests/",
+ "status": "testcases/incremental_bulk_compiler_full.status",
+ "pattern": [
+ "language_2/.*_test\\.dart$"
+ ],
+ "exclude": [
+ ]
+ },
+
+ {
"name": "sdk",
"kind": "Chain",
"source": "test/fasta/sdk_test.dart",
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index 0b96037..ebb7792 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -276,7 +276,6 @@
printer.writeComponentFile(component);
await sink.close();
_outputStream.writeln('$boundaryKey $_kernelBinaryFilename');
-
final String depfile = options['depfile'];
if (depfile != null) {
await _writeDepfile(component, _kernelBinaryFilename, depfile);
@@ -290,6 +289,10 @@
Future<Null> invalidateIfBootstrapping() async {
if (_kernelBinaryFilename != _kernelBinaryFilenameFull) return null;
+ // If the generator is initialized bootstrapping is not in effect anyway,
+ // so there's no reason to spend time invalidating what should be
+ // invalidated by the normal approach anyway.
+ if (_generator.initialized) return null;
try {
final File f = new File(_kernelBinaryFilenameFull);
@@ -362,7 +365,7 @@
@override
void resetIncrementalCompiler() {
- _generator = _createGenerator(new Uri.file(_kernelBinaryFilenameFull));
+ _generator.resetDeltaState();
_kernelBinaryFilename = _kernelBinaryFilenameFull;
}
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index bfe5919..91d9426 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -17,6 +17,8 @@
IncrementalKernelGenerator _generator;
List<Component> _pendingDeltas;
CompilerOptions _compilerOptions;
+ bool initialized = false;
+ bool fullComponent = false;
IncrementalCompiler(this._compilerOptions, Uri entryPoint,
{Uri bootstrapDill}) {
@@ -30,7 +32,10 @@
/// If [entryPoint] is specified, that points to new entry point for the
/// compilation. Otherwise, previously set entryPoint is used.
Future<Component> compile({Uri entryPoint}) async {
- Component component = await _generator.computeDelta(entryPoint: entryPoint);
+ Component component = await _generator.computeDelta(
+ entryPoint: entryPoint, fullComponent: fullComponent);
+ initialized = true;
+ fullComponent = false;
final bool firstDelta = _pendingDeltas.isEmpty;
_pendingDeltas.add(component);
if (firstDelta) {
@@ -64,4 +69,9 @@
invalidate(Uri uri) {
_generator.invalidate(uri);
}
+
+ resetDeltaState() {
+ _pendingDeltas.clear();
+ fullComponent = true;
+ }
}
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 276470b..f9bdcb1 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -1052,11 +1052,10 @@
@override
TypeExpr visitReturnStatement(ReturnStatement node) {
- if (node.expression != null) {
- TypeExpr ret = _visit(node.expression);
- if (_returnValue != null) {
- _returnValue.values.add(ret);
- }
+ TypeExpr ret =
+ (node.expression != null) ? _visit(node.expression) : _nullType;
+ if (_returnValue != null) {
+ _returnValue.values.add(ret);
}
return null;
}
diff --git a/pkg/vm/test/frontend_server_test.dart b/pkg/vm/test/frontend_server_test.dart
index 7109a00..f0f9159 100644
--- a/pkg/vm/test/frontend_server_test.dart
+++ b/pkg/vm/test/frontend_server_test.dart
@@ -379,6 +379,7 @@
final _MockedIncrementalCompiler generator =
new _MockedIncrementalCompiler();
+ when(generator.initialized).thenAnswer((_) => false);
when(generator.compile())
.thenAnswer((_) => new Future<Component>.value(new Component()));
final _MockedBinaryPrinterFactory printerFactory =
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart
index 8db45c9..16cfc50 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart
@@ -19,6 +19,10 @@
return3() => new T();
+void return4() {
+ return;
+}
+
expr1() {
new T();
}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
index e189190..1f8da63 100644
--- a/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/implicit_return_null.dart.expect
@@ -25,6 +25,9 @@
------------ #lib::return3 ------------
t0 = _Call direct [#lib::T::] (_T (#lib::T))
RESULT: _T (#lib::T)
+------------ #lib::return4 ------------
+
+RESULT: _T {}?
------------ #lib::expr1 ------------
t0 = _Call direct [#lib::T::] (_T (#lib::T))
RESULT: _T {}?
diff --git a/runtime/tests/vm/dart/regress32597_2_test.dart b/runtime/tests/vm/dart/regress32597_2_test.dart
new file mode 100644
index 0000000..9081470
--- /dev/null
+++ b/runtime/tests/vm/dart/regress32597_2_test.dart
@@ -0,0 +1,47 @@
+// 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.
+
+// Regression test for dartbug.com/32597: incorrect type was assigned to phi
+// in strong mode.
+
+// VMOptions=--optimization_counter_threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+class Token {
+ Token next;
+}
+
+class StringToken extends Token {}
+
+class ErrorToken extends Token {}
+
+bool failed = false;
+
+void foo(Token tokens, {bool x: false}) {
+ dynamic v;
+ {
+ Token current = tokens;
+ while (current is ErrorToken) {
+ failed = true;
+ current = null;
+ }
+ v = current;
+ }
+ if (x) {
+ ErrorToken second = v;
+ print(second);
+ }
+}
+
+void main() {
+ Token token = new StringToken();
+ token.next = token;
+
+ for (int i = 0; i < 100; i++) {
+ foo(token);
+ }
+ print(failed ? 'failure' : 'success');
+ Expect.isFalse(failed);
+}
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 77ca3cb..499bfc7 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1191,9 +1191,16 @@
if ((phi != NULL) && isolate()->strong() &&
FLAG_use_strong_mode_types) {
- // Assign type to phi only if phi was not copied from another local.
- const auto* phis = phi->block()->phis();
- if ((index < phis->length()) && ((*phis)[index] == phi)) {
+ // Assign type to Phi if it doesn't have a type yet.
+ // For a Phi to appear in the local variable it either was placed
+ // there as incoming value by renaming or it was stored there by
+ // StoreLocal which took this Phi from another local via LoadLocal,
+ // to which this reasoning applies recursively.
+ // This means that we are guaranteed to process LoadLocal for a
+ // matching variable first.
+ if (!phi->HasType()) {
+ ASSERT((index < phi->block()->phis()->length()) &&
+ ((*phi->block()->phis())[index] == phi));
phi->UpdateType(
CompileType::FromAbstractType(load->local().type()));
}
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 44a6a4e..3d404b1 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -1798,6 +1798,8 @@
return type_;
}
+ bool HasType() const { return (type_ != NULL); }
+
// Does this define a mint?
inline bool IsMintDefinition();
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index d8d8e85..56b11d6 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -112,7 +112,17 @@
if (FLAG_trace_timeline) {
THR_Print("Using the Systrace timeline recorder.\n");
}
- return TimelineEventPlatformRecorder::CreatePlatformRecorder();
+
+#if defined(HOST_OS_LINUX) || defined(HOST_OS_ANDROID)
+ return new TimelineEventSystraceRecorder();
+#elif defined(HOST_OS_FUCHSIA)
+ return new TimelineEventFuchsiaRecorder();
+#else
+ OS::PrintErr(
+ "Warning: The systrace timeline recorder is equivalent to the"
+ "ring recorder on this platform.");
+ return new TimelineEventRingRecorder();
+#endif
}
}
@@ -1342,6 +1352,42 @@
delete event;
}
+TimelineEventPlatformRecorder::TimelineEventPlatformRecorder() {}
+
+TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {}
+
+void TimelineEventPlatformRecorder::PrintJSON(JSONStream* js,
+ TimelineEventFilter* filter) {
+ if (!FLAG_support_service) {
+ return;
+ }
+ JSONObject topLevel(js);
+ topLevel.AddProperty("type", "_Timeline");
+ {
+ JSONArray events(&topLevel, "traceEvents");
+ PrintJSONMeta(&events);
+ }
+}
+
+void TimelineEventPlatformRecorder::PrintTraceEvent(
+ JSONStream* js,
+ TimelineEventFilter* filter) {
+ if (!FLAG_support_service) {
+ return;
+ }
+ JSONArray events(js);
+}
+
+TimelineEvent* TimelineEventPlatformRecorder::StartEvent() {
+ TimelineEvent* event = new TimelineEvent();
+ return event;
+}
+
+void TimelineEventPlatformRecorder::CompleteEvent(TimelineEvent* event) {
+ OnEvent(event);
+ delete event;
+}
+
TimelineEventEndlessRecorder::TimelineEventEndlessRecorder()
: head_(NULL), block_index_(0) {}
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index c37a982..98e00ce 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -442,6 +442,7 @@
friend class TimelineEventRingRecorder;
friend class TimelineEventStartupRecorder;
friend class TimelineEventPlatformRecorder;
+ friend class TimelineEventFuchsiaRecorder;
friend class TimelineStream;
friend class TimelineTestHelper;
DISALLOW_COPY_AND_ASSIGN(TimelineEvent);
@@ -860,37 +861,60 @@
// The TimelineEventPlatformRecorder records timeline events to a platform
// specific destination. It's implementation is in the timeline_{linux,...}.cc
// files.
-class TimelineEventPlatformRecorder : public TimelineEventFixedBufferRecorder {
+class TimelineEventPlatformRecorder : public TimelineEventRecorder {
public:
- explicit TimelineEventPlatformRecorder(intptr_t capacity = kDefaultCapacity);
+ TimelineEventPlatformRecorder();
virtual ~TimelineEventPlatformRecorder();
- static TimelineEventPlatformRecorder* CreatePlatformRecorder(
- intptr_t capacity = kDefaultCapacity);
+ void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
+ void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
- const char* name() const;
+ // Called when |event| is completed. It is unsafe to keep a reference to
+ // |event| as it may be freed as soon as this function returns.
+ virtual void OnEvent(TimelineEvent* event) = 0;
+
+ virtual const char* name() const = 0;
protected:
- TimelineEventBlock* GetNewBlockLocked();
- virtual void CompleteEvent(TimelineEvent* event);
+ TimelineEventBlock* GetNewBlockLocked() { return NULL; }
+ TimelineEventBlock* GetHeadBlockLocked() { return NULL; }
+ void Clear() {}
+ TimelineEvent* StartEvent();
+ void CompleteEvent(TimelineEvent* event);
};
+#if defined(HOST_OS_FUCHSIA)
+// A recorder that sends events to Fuchsia's tracing app. See:
+// https://fuchsia.googlesource.com/garnet/+/master/docs/tracing_usage_guide.md
+class TimelineEventFuchsiaRecorder : public TimelineEventPlatformRecorder {
+ public:
+ TimelineEventFuchsiaRecorder() {}
+ virtual ~TimelineEventFuchsiaRecorder() {}
+
+ const char* name() const { return "Fuchsia"; }
+
+ private:
+ void OnEvent(TimelineEvent* event);
+};
+#endif // defined(HOST_OS_FUCHSIA)
+
#if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX)
-// A recorder that writes events to Android Systrace. Events are also stored in
-// a buffer of fixed capacity. When the buffer is full, new events overwrite
-// old events. This class is exposed in this header file only so that
-// PrintSystrace can be visible to timeline_test.cc.
+// A recorder that writes events to Android Systrace. This class is exposed in
+// this header file only so that PrintSystrace can be visible to
+// timeline_test.cc.
class TimelineEventSystraceRecorder : public TimelineEventPlatformRecorder {
public:
- explicit TimelineEventSystraceRecorder(intptr_t capacity = kDefaultCapacity);
+ TimelineEventSystraceRecorder();
virtual ~TimelineEventSystraceRecorder();
static intptr_t PrintSystrace(TimelineEvent* event,
char* buffer,
intptr_t buffer_size);
+ const char* name() const { return "Systrace"; }
+
private:
- virtual void CompleteEvent(TimelineEvent* event);
+ void OnEvent(TimelineEvent* event);
int systrace_fd_;
};
diff --git a/runtime/vm/timeline_android.cc b/runtime/vm/timeline_android.cc
index 74376b1..cd316eb 100644
--- a/runtime/vm/timeline_android.cc
+++ b/runtime/vm/timeline_android.cc
@@ -23,8 +23,8 @@
DECLARE_FLAG(bool, trace_timeline);
-TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity)
- : TimelineEventPlatformRecorder(capacity), systrace_fd_(-1) {
+TimelineEventSystraceRecorder::TimelineEventSystraceRecorder()
+ : TimelineEventPlatformRecorder(), systrace_fd_(-1) {
const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker";
systrace_fd_ = open(kSystracePath, O_WRONLY);
if ((systrace_fd_ < 0) && FLAG_trace_timeline) {
@@ -69,55 +69,25 @@
return length;
}
-void TimelineEventSystraceRecorder::CompleteEvent(TimelineEvent* event) {
+void TimelineEventSystraceRecorder::OnEvent(TimelineEvent* event) {
if (event == NULL) {
return;
}
- if (systrace_fd_ >= 0) {
- // Serialize to the systrace format.
- const intptr_t kBufferLength = 1024;
- char buffer[kBufferLength];
- const intptr_t event_length =
- PrintSystrace(event, &buffer[0], kBufferLength);
- if (event_length > 0) {
- ssize_t result;
- // Repeatedly attempt the write while we are being interrupted.
- do {
- result = write(systrace_fd_, buffer, event_length);
- } while ((result == -1L) && (errno == EINTR));
- }
+ if (systrace_fd_ < 0) {
+ return;
}
- ThreadBlockCompleteEvent(event);
-}
-TimelineEventPlatformRecorder::TimelineEventPlatformRecorder(intptr_t capacity)
- : TimelineEventFixedBufferRecorder(capacity) {}
-
-TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {}
-
-TimelineEventPlatformRecorder*
-TimelineEventPlatformRecorder::CreatePlatformRecorder(intptr_t capacity) {
- return new TimelineEventSystraceRecorder(capacity);
-}
-
-const char* TimelineEventPlatformRecorder::name() const {
- return "Systrace";
-}
-
-TimelineEventBlock* TimelineEventPlatformRecorder::GetNewBlockLocked() {
- // TODO(johnmccutchan): This function should only hand out blocks
- // which have been marked as finished.
- if (block_cursor_ == num_blocks_) {
- block_cursor_ = 0;
+ // Serialize to the systrace format.
+ const intptr_t kBufferLength = 1024;
+ char buffer[kBufferLength];
+ const intptr_t event_length = PrintSystrace(event, &buffer[0], kBufferLength);
+ if (event_length > 0) {
+ ssize_t result;
+ // Repeatedly attempt the write while we are being interrupted.
+ do {
+ result = write(systrace_fd_, buffer, event_length);
+ } while ((result == -1L) && (errno == EINTR));
}
- TimelineEventBlock* block = &blocks_[block_cursor_++];
- block->Reset();
- block->Open();
- return block;
-}
-
-void TimelineEventPlatformRecorder::CompleteEvent(TimelineEvent* event) {
- UNREACHABLE();
}
} // namespace dart
diff --git a/runtime/vm/timeline_fuchsia.cc b/runtime/vm/timeline_fuchsia.cc
index bed504b..f39cc20 100644
--- a/runtime/vm/timeline_fuchsia.cc
+++ b/runtime/vm/timeline_fuchsia.cc
@@ -15,38 +15,7 @@
namespace dart {
-// A recorder that sends events to Fuchsia's tracing app. Events are also stored
-// in a buffer of fixed capacity. When the buffer is full, new events overwrite
-// old events.
-// See: https://fuchsia.googlesource.com/tracing/+/HEAD/docs/usage_guide.md
-
-TimelineEventPlatformRecorder::TimelineEventPlatformRecorder(intptr_t capacity)
- : TimelineEventFixedBufferRecorder(capacity) {}
-
-TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {}
-
-TimelineEventPlatformRecorder*
-TimelineEventPlatformRecorder::CreatePlatformRecorder(intptr_t capacity) {
- return new TimelineEventPlatformRecorder(capacity);
-}
-
-const char* TimelineEventPlatformRecorder::name() const {
- return "Fuchsia";
-}
-
-TimelineEventBlock* TimelineEventPlatformRecorder::GetNewBlockLocked() {
- // TODO(johnmccutchan): This function should only hand out blocks
- // which have been marked as finished.
- if (block_cursor_ == num_blocks_) {
- block_cursor_ = 0;
- }
- TimelineEventBlock* block = &blocks_[block_cursor_++];
- block->Reset();
- block->Open();
- return block;
-}
-
-void TimelineEventPlatformRecorder::CompleteEvent(TimelineEvent* event) {
+void TimelineEventFuchsiaRecorder::OnEvent(TimelineEvent* event) {
if (event == NULL) {
return;
}
@@ -54,7 +23,6 @@
trace_context_t* context =
trace_acquire_context_for_category("dart", &category);
if (context == NULL) {
- ThreadBlockCompleteEvent(event);
return;
}
@@ -149,7 +117,6 @@
break;
}
trace_release_context(context);
- ThreadBlockCompleteEvent(event);
}
} // namespace dart
diff --git a/runtime/vm/timeline_linux.cc b/runtime/vm/timeline_linux.cc
index 6ce1060..c1c5d53 100644
--- a/runtime/vm/timeline_linux.cc
+++ b/runtime/vm/timeline_linux.cc
@@ -23,8 +23,8 @@
DECLARE_FLAG(bool, trace_timeline);
-TimelineEventSystraceRecorder::TimelineEventSystraceRecorder(intptr_t capacity)
- : TimelineEventPlatformRecorder(capacity), systrace_fd_(-1) {
+TimelineEventSystraceRecorder::TimelineEventSystraceRecorder()
+ : TimelineEventPlatformRecorder(), systrace_fd_(-1) {
const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker";
systrace_fd_ = open(kSystracePath, O_WRONLY);
if ((systrace_fd_ < 0) && FLAG_trace_timeline) {
@@ -69,55 +69,25 @@
return length;
}
-void TimelineEventSystraceRecorder::CompleteEvent(TimelineEvent* event) {
+void TimelineEventSystraceRecorder::OnEvent(TimelineEvent* event) {
if (event == NULL) {
return;
}
- if (systrace_fd_ >= 0) {
- // Serialize to the systrace format.
- const intptr_t kBufferLength = 1024;
- char buffer[kBufferLength];
- const intptr_t event_length =
- PrintSystrace(event, &buffer[0], kBufferLength);
- if (event_length > 0) {
- ssize_t result;
- // Repeatedly attempt the write while we are being interrupted.
- do {
- result = write(systrace_fd_, buffer, event_length);
- } while ((result == -1L) && (errno == EINTR));
- }
+ if (systrace_fd_ < 0) {
+ return;
}
- ThreadBlockCompleteEvent(event);
-}
-TimelineEventPlatformRecorder::TimelineEventPlatformRecorder(intptr_t capacity)
- : TimelineEventFixedBufferRecorder(capacity) {}
-
-TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {}
-
-TimelineEventPlatformRecorder*
-TimelineEventPlatformRecorder::CreatePlatformRecorder(intptr_t capacity) {
- return new TimelineEventSystraceRecorder(capacity);
-}
-
-const char* TimelineEventPlatformRecorder::name() const {
- return "Systrace";
-}
-
-TimelineEventBlock* TimelineEventPlatformRecorder::GetNewBlockLocked() {
- // TODO(johnmccutchan): This function should only hand out blocks
- // which have been marked as finished.
- if (block_cursor_ == num_blocks_) {
- block_cursor_ = 0;
+ // Serialize to the systrace format.
+ const intptr_t kBufferLength = 1024;
+ char buffer[kBufferLength];
+ const intptr_t event_length = PrintSystrace(event, &buffer[0], kBufferLength);
+ if (event_length > 0) {
+ ssize_t result;
+ // Repeatedly attempt the write while we are being interrupted.
+ do {
+ result = write(systrace_fd_, buffer, event_length);
+ } while ((result == -1L) && (errno == EINTR));
}
- TimelineEventBlock* block = &blocks_[block_cursor_++];
- block->Reset();
- block->Open();
- return block;
-}
-
-void TimelineEventPlatformRecorder::CompleteEvent(TimelineEvent* event) {
- UNREACHABLE();
}
} // namespace dart
diff --git a/runtime/vm/timeline_macos.cc b/runtime/vm/timeline_macos.cc
deleted file mode 100644
index 4ef33e6..0000000
--- a/runtime/vm/timeline_macos.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "platform/globals.h"
-#if defined(HOST_OS_MACOS) && !defined(PRODUCT)
-
-#include "vm/timeline.h"
-
-namespace dart {
-
-TimelineEventPlatformRecorder::TimelineEventPlatformRecorder(intptr_t capacity)
- : TimelineEventFixedBufferRecorder(capacity) {
- OS::PrintErr(
- "Warning: The systrace timeline recorder is equivalent to the"
- "ring recorder on this platform.");
-}
-
-TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {}
-
-TimelineEventPlatformRecorder*
-TimelineEventPlatformRecorder::CreatePlatformRecorder(intptr_t capacity) {
- return new TimelineEventPlatformRecorder(capacity);
-}
-
-const char* TimelineEventPlatformRecorder::name() const {
- return "Systrace";
-}
-
-TimelineEventBlock* TimelineEventPlatformRecorder::GetNewBlockLocked() {
- // TODO(johnmccutchan): This function should only hand out blocks
- // which have been marked as finished.
- if (block_cursor_ == num_blocks_) {
- block_cursor_ = 0;
- }
- TimelineEventBlock* block = &blocks_[block_cursor_++];
- block->Reset();
- block->Open();
- return block;
-}
-
-void TimelineEventPlatformRecorder::CompleteEvent(TimelineEvent* event) {
- if (event == NULL) {
- return;
- }
- ThreadBlockCompleteEvent(event);
-}
-
-} // namespace dart
-
-#endif // defined(HOST_OS_MACOS) && !defined(PRODUCT)
diff --git a/runtime/vm/timeline_win.cc b/runtime/vm/timeline_win.cc
deleted file mode 100644
index d1d5f50..0000000
--- a/runtime/vm/timeline_win.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "platform/globals.h"
-#if defined(HOST_OS_WINDOWS) && !defined(PRODUCT)
-
-#include "vm/timeline.h"
-
-namespace dart {
-
-TimelineEventPlatformRecorder::TimelineEventPlatformRecorder(intptr_t capacity)
- : TimelineEventFixedBufferRecorder(capacity) {
- OS::PrintErr(
- "Warning: The systrace timeline recorder is equivalent to the"
- "ring recorder on this platform.");
-}
-
-TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {}
-
-TimelineEventPlatformRecorder*
-TimelineEventPlatformRecorder::CreatePlatformRecorder(intptr_t capacity) {
- return new TimelineEventPlatformRecorder(capacity);
-}
-
-const char* TimelineEventPlatformRecorder::name() const {
- return "Systrace";
-}
-
-TimelineEventBlock* TimelineEventPlatformRecorder::GetNewBlockLocked() {
- // TODO(johnmccutchan): This function should only hand out blocks
- // which have been marked as finished.
- if (block_cursor_ == num_blocks_) {
- block_cursor_ = 0;
- }
- TimelineEventBlock* block = &blocks_[block_cursor_++];
- block->Reset();
- block->Open();
- return block;
-}
-
-void TimelineEventPlatformRecorder::CompleteEvent(TimelineEvent* event) {
- if (event == NULL) {
- return;
- }
- ThreadBlockCompleteEvent(event);
-}
-
-} // namespace dart
-
-#endif // defined(HOST_OS_WINDOWS) && !defined(PRODUCT)
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index a2d0391..a4ee4fa 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -334,8 +334,6 @@
"timeline_android.cc",
"timeline_fuchsia.cc",
"timeline_linux.cc",
- "timeline_macos.cc",
- "timeline_win.cc",
"timer.cc",
"timer.h",
"token.cc",
diff --git a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
index 7d99498..e93af8f 100644
--- a/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
+++ b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
@@ -769,12 +769,12 @@
abstract class NativeTypedArrayOfDouble extends NativeTypedArray
with ListMixin<double>, FixedLengthListMixin<double> {
- num operator [](int index) {
+ double operator [](int index) {
_checkValidIndex(index, this, this.length);
return JS('num', '#[#]', this, index);
}
- void operator []=(int index, num value) {
+ void operator []=(int index, double value) {
_checkValidIndex(index, this, this.length);
JS('void', '#[#] = #', this, index, value);
}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index e564c8c..29afb71 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -1277,8 +1277,7 @@
* The [defaultValue] parameter is deprecated, and [orElse] should be used
* instead.
*/
- Future<T> firstWhere(bool test(T element),
- {@deprecated dynamic defaultValue(), T orElse()}) {
+ Future<T> firstWhere(bool test(T element), {T orElse()}) {
_Future<T> future = new _Future();
StreamSubscription subscription;
subscription = this.listen(
@@ -1291,9 +1290,6 @@
},
onError: future._completeError,
onDone: () {
- if (orElse == null && defaultValue != null) {
- orElse = () => defaultValue() as T;
- }
if (orElse != null) {
_runUserCode(orElse, future._complete, future._completeError);
return;
@@ -1322,8 +1318,7 @@
* The [defaultValue] parameter is deprecated, and [orElse] should be used
* instead.
*/
- Future<T> lastWhere(bool test(T element),
- {@deprecated dynamic defaultValue(), T orElse()}) {
+ Future<T> lastWhere(bool test(T element), {T orElse()}) {
_Future<T> future = new _Future();
T result = null;
bool foundResult = false;
@@ -1343,9 +1338,6 @@
future._complete(result);
return;
}
- if (orElse == null && defaultValue != null) {
- orElse = () => defaultValue() as T;
- }
if (orElse != null) {
_runUserCode(orElse, future._complete, future._completeError);
return;
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index ae6857a..9009dff 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -226,11 +226,10 @@
/**
* Returns the value for the given [key] or null if [key] is not in the map.
*
- * Some maps allows keys to have `null` as a value,
- * For those maps, a lookup using this operator does cannot be used to
- * distinguish between a key not being in the map, and the key having a null
- * value.
- * Methods like [containsKey] or [putIfAbsent] can be use if the distinction
+ * Some maps allow keys to have `null` as a value.
+ * For those maps, a lookup using this operator cannot distinguish between a
+ * key not being in the map and the key having a `null` value.
+ * Methods like [containsKey] or [putIfAbsent] can be used if the distinction
* is important.
*/
V operator [](Object key);
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 5061de2..a598e54 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -38,6 +38,28 @@
LibTest/typed_data/Uint8List/first_A01_t02: RuntimeError # co19 issue 130
LibTest/typed_data/Uint8List/last_A01_t02: RuntimeError # co19 issue 130
+# Tests that fail everywhere, including the analyzer.
+[ $strong ]
+Language/Expressions/Additive_Expressions/syntax_t01/07: CompileTimeError
+LibTest/async/Stream/firstWhere_A01_t01: CompileTimeError # co19 issue 137
+LibTest/async/Stream/firstWhere_A02_t01: CompileTimeError # co19 issue 137
+LibTest/async/Stream/lastWhere_A01_t01: CompileTimeError # co19 issue 137
+LibTest/async/Stream/lastWhere_A02_t01: CompileTimeError # co19 issue 137
+LibTest/isolate/ReceivePort/firstWhere_A01_t01: CompileTimeError # co19 issue 137
+LibTest/isolate/ReceivePort/firstWhere_A02_t01: CompileTimeError # co19 issue 137
+LibTest/isolate/ReceivePort/lastWhere_A01_t01: CompileTimeError # co19 issue 137
+LibTest/isolate/ReceivePort/lastWhere_A02_t01: CompileTimeError # co19 issue 137
+
+[ !$strong ]
+LibTest/async/Stream/firstWhere_A01_t01: RuntimeError # co19 issue 137
+LibTest/async/Stream/firstWhere_A02_t01: RuntimeError # co19 issue 137
+LibTest/async/Stream/lastWhere_A01_t01: RuntimeError # co19 issue 137
+LibTest/async/Stream/lastWhere_A02_t01: RuntimeError # co19 issue 137
+LibTest/isolate/ReceivePort/firstWhere_A01_t01: RuntimeError # co19 issue 137
+LibTest/isolate/ReceivePort/firstWhere_A02_t01: RuntimeError # co19 issue 137
+LibTest/isolate/ReceivePort/lastWhere_A01_t01: RuntimeError # co19 issue 137
+LibTest/isolate/ReceivePort/lastWhere_A02_t01: RuntimeError # co19 issue 137
+
# Tests that fail on every runtime, but not on the analyzer.
[ $compiler != dart2analyzer && $compiler != fasta ]
Language/Classes/same_name_type_variable_t04: Pass, MissingCompileTimeError, Fail # Issue 14513,25525
diff --git a/tests/compiler/dart2js/inference/data/list_strong.dart b/tests/compiler/dart2js/inference/data/list_strong.dart
new file mode 100644
index 0000000..577be23
--- /dev/null
+++ b/tests/compiler/dart2js/inference/data/list_strong.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:typed_data';
+
+/*element: main:[null]*/
+main() {
+ emptyList();
+ nullList();
+ constList();
+ constNullList();
+ intList();
+ newList();
+ newFixedList();
+ newFilledList();
+ newFloat32x4List();
+ newInt32x4List();
+ newFloat64x2List();
+ newFloat32List();
+ newFloat64List();
+ newInt16List();
+ newInt32List();
+ newInt8List();
+ newUint16List();
+ newUint32List();
+ newUint8ClampedList();
+ newUint8List();
+}
+
+/*element: emptyList:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
+emptyList() => [];
+
+/*element: constList:Container([exact=JSUnmodifiableArray], element: [empty], length: 0)*/
+constList() => const [];
+
+/*element: nullList:Container([exact=JSExtendableArray], element: [null], length: 1)*/
+nullList() => [null];
+
+/*element: constNullList:Container([exact=JSUnmodifiableArray], element: [null], length: 1)*/
+constNullList() => const [null];
+
+/*element: intList:Container([exact=JSExtendableArray], element: [exact=JSUInt31], length: 3)*/
+intList() => [1, 2, 3];
+
+/*element: newList:Container([exact=JSExtendableArray], element: [empty], length: 0)*/
+newList() => new List();
+
+/*element: newFixedList:Container([exact=JSFixedArray], element: [null], length: 2)*/
+newFixedList() => new List(2);
+
+/*element: newFilledList:Container([exact=JSFixedArray], element: Value([exact=JSString], value: ""), length: 3)*/
+newFilledList() => new List.filled(3, '');
+
+/*element: newFloat32x4List:[exact=NativeFloat32x4List]*/
+newFloat32x4List() => new Float32x4List(4);
+
+/*element: newInt32x4List:[exact=NativeInt32x4List]*/
+newInt32x4List() => new Int32x4List(5);
+
+/*element: newFloat64x2List:[exact=NativeFloat64x2List]*/
+newFloat64x2List() => new Float64x2List(6);
+
+/*element: newFloat32List:Container([exact=NativeFloat32List], element: [subclass=JSNumber], length: 7)*/
+newFloat32List() => new Float32List(7);
+
+/*element: newFloat64List:Container([exact=NativeFloat64List], element: [subclass=JSNumber], length: 8)*/
+newFloat64List() => new Float64List(8);
+
+/*element: newInt16List:Container([exact=NativeInt16List], element: [subclass=JSInt], length: 9)*/
+newInt16List() => new Int16List(9);
+
+////////////////////////////////////////////////////////////////////////////////
+// Create a Int32List using an unchanged non-final top-level field as length.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: _field1:[exact=JSUInt31]*/
+var _field1 = 10;
+
+/*element: newInt32List:Container([exact=NativeInt32List], element: [subclass=JSInt], length: null)*/
+newInt32List() => new Int32List(_field1);
+
+////////////////////////////////////////////////////////////////////////////////
+// Create a Int8List using a final top-level field as length.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: _field2:[exact=JSUInt31]*/
+final _field2 = 11;
+
+/*element: newInt8List:Container([exact=NativeInt8List], element: [subclass=JSInt], length: 11)*/
+newInt8List() => new Int8List(_field2);
+
+////////////////////////////////////////////////////////////////////////////////
+// Create a Uint16List using a const top-level field as length.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: _field3:[exact=JSUInt31]*/
+const _field3 = 12;
+
+/*element: newUint16List:Container([exact=NativeUint16List], element: [exact=JSUInt31], length: 12)*/
+newUint16List() => new Uint16List(_field3);
+
+////////////////////////////////////////////////////////////////////////////////
+// Create a Uint32List using a parenthesized literal int as length.
+////////////////////////////////////////////////////////////////////////////////
+
+/*ast.element: newUint32List:Container([exact=NativeUint32List], element: [subclass=JSUInt32], length: null)*/
+/*kernel.element: newUint32List:Container([exact=NativeUint32List], element: [subclass=JSUInt32], length: 13)*/
+newUint32List() => new Uint32List((13));
+
+////////////////////////////////////////////////////////////////////////////////
+// Create a Uint8ClampedList using a constant multiplication as length.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: newUint8ClampedList:Container([exact=NativeUint8ClampedList], element: [exact=JSUInt31], length: null)*/
+newUint8ClampedList() =>
+ new Uint8ClampedList(2 /*invoke: [exact=JSUInt31]*/ * 7);
+
+////////////////////////////////////////////////////////////////////////////////
+// Create a Uint8List using a const static field as length.
+////////////////////////////////////////////////////////////////////////////////
+
+abstract class Class1 {
+ /*element: Class1.field:[exact=JSUInt31]*/
+ static const field = 15;
+}
+
+/*element: newUint8List:Container([exact=NativeUint8List], element: [exact=JSUInt31], length: 15)*/
+newUint8List() => new Uint8List(Class1.field);
diff --git a/tests/compiler/dart2js/model/subtype_test.dart b/tests/compiler/dart2js/model/subtype_test.dart
index 711c84c..d54572c 100644
--- a/tests/compiler/dart2js/model/subtype_test.dart
+++ b/tests/compiler/dart2js/model/subtype_test.dart
@@ -34,6 +34,7 @@
await testFunctionSubtypingNamed(compileMode, strongMode);
await testTypedefSubtypingNamed(compileMode, strongMode);
await testTypeVariableSubtype(compileMode, strongMode);
+ await testStrongModeSubtyping(compileMode, strongMode);
}
void testTypes(TypeEnvironment env, DartType subtype, DartType supertype,
@@ -84,8 +85,8 @@
expect(true, void_, dynamic_);
// Unsure about the next one, see dartbug.com/14933.
expect(true, dynamic_, void_, expectMoreSpecific: false);
- expect(false, void_, Object_);
- expect(false, Object_, void_);
+ expect(strongMode, void_, Object_);
+ expect(strongMode, Object_, void_);
expect(true, Null_, void_);
expect(true, Object_, Object_);
@@ -99,21 +100,21 @@
expect(true, num_, num_);
expect(true, int_, num_);
expect(false, String_, num_);
- expect(true, dynamic_, num_, expectMoreSpecific: false);
+ expect(!strongMode, dynamic_, num_, expectMoreSpecific: false);
expect(true, Null_, num_);
expect(false, Object_, int_);
expect(false, num_, int_);
expect(true, int_, int_);
expect(false, String_, int_);
- expect(true, dynamic_, int_, expectMoreSpecific: false);
+ expect(!strongMode, dynamic_, int_, expectMoreSpecific: false);
expect(true, Null_, int_);
expect(false, Object_, String_);
expect(false, num_, String_);
expect(false, int_, String_);
expect(true, String_, String_);
- expect(true, dynamic_, String_, expectMoreSpecific: false);
+ expect(!strongMode, dynamic_, String_, expectMoreSpecific: false);
expect(true, Null_, String_);
expect(true, Object_, dynamic_);
@@ -127,7 +128,7 @@
expect(false, num_, Null_);
expect(false, int_, Null_);
expect(false, String_, Null_);
- expect(true, dynamic_, Null_, expectMoreSpecific: false);
+ expect(!strongMode, dynamic_, Null_, expectMoreSpecific: false);
expect(true, Null_, Null_);
DartType A_Object = instantiate(A, [Object_]);
@@ -155,21 +156,21 @@
expect(true, A_num, A_num);
expect(true, A_int, A_num);
expect(false, A_String, A_num);
- expect(true, A_dynamic, A_num, expectMoreSpecific: false);
+ expect(!strongMode, A_dynamic, A_num, expectMoreSpecific: false);
expect(true, A_Null, A_num);
expect(false, A_Object, A_int);
expect(false, A_num, A_int);
expect(true, A_int, A_int);
expect(false, A_String, A_int);
- expect(true, A_dynamic, A_int, expectMoreSpecific: false);
+ expect(!strongMode, A_dynamic, A_int, expectMoreSpecific: false);
expect(true, A_Null, A_int);
expect(false, A_Object, A_String);
expect(false, A_num, A_String);
expect(false, A_int, A_String);
expect(true, A_String, A_String);
- expect(true, A_dynamic, A_String, expectMoreSpecific: false);
+ expect(!strongMode, A_dynamic, A_String, expectMoreSpecific: false);
expect(true, A_Null, A_String);
expect(true, A_Object, A_dynamic);
@@ -183,7 +184,7 @@
expect(false, A_num, A_Null);
expect(false, A_int, A_Null);
expect(false, A_String, A_Null);
- expect(true, A_dynamic, A_Null, expectMoreSpecific: false);
+ expect(!strongMode, A_dynamic, A_Null, expectMoreSpecific: false);
expect(true, A_Null, A_Null);
DartType B_Object_Object = instantiate(B, [Object_, Object_]);
@@ -215,9 +216,9 @@
expect(true, B_dynamic_dynamic, Object_);
expect(true, B_dynamic_dynamic, A_Object, expectMoreSpecific: false);
- expect(true, B_dynamic_dynamic, A_num, expectMoreSpecific: false);
- expect(true, B_dynamic_dynamic, A_int, expectMoreSpecific: false);
- expect(true, B_dynamic_dynamic, A_String, expectMoreSpecific: false);
+ expect(!strongMode, B_dynamic_dynamic, A_num, expectMoreSpecific: false);
+ expect(!strongMode, B_dynamic_dynamic, A_int, expectMoreSpecific: false);
+ expect(!strongMode, B_dynamic_dynamic, A_String, expectMoreSpecific: false);
expect(true, B_dynamic_dynamic, A_dynamic);
expect(true, B_String_dynamic, Object_);
@@ -236,13 +237,15 @@
expect(false, B_Object_Object, B_num_num);
expect(true, B_num_num, B_num_num);
expect(true, B_int_num, B_num_num);
- expect(true, B_dynamic_dynamic, B_num_num, expectMoreSpecific: false);
+ expect(!strongMode, B_dynamic_dynamic, B_num_num,
+ expectMoreSpecific: false);
expect(false, B_String_dynamic, B_num_num);
expect(false, B_Object_Object, B_int_num);
expect(false, B_num_num, B_int_num);
expect(true, B_int_num, B_int_num);
- expect(true, B_dynamic_dynamic, B_int_num, expectMoreSpecific: false);
+ expect(!strongMode, B_dynamic_dynamic, B_int_num,
+ expectMoreSpecific: false);
expect(false, B_String_dynamic, B_int_num);
expect(true, B_Object_Object, B_dynamic_dynamic);
@@ -254,7 +257,7 @@
expect(false, B_Object_Object, B_String_dynamic);
expect(false, B_num_num, B_String_dynamic);
expect(false, B_int_num, B_String_dynamic);
- expect(true, B_dynamic_dynamic, B_String_dynamic,
+ expect(!strongMode, B_dynamic_dynamic, B_String_dynamic,
expectMoreSpecific: false);
expect(true, B_String_dynamic, B_String_dynamic);
@@ -282,10 +285,12 @@
expect(true, C_int_String, B_String_dynamic);
expect(true, C_dynamic_dynamic, B_Object_Object, expectMoreSpecific: false);
- expect(true, C_dynamic_dynamic, B_num_num, expectMoreSpecific: false);
- expect(true, C_dynamic_dynamic, B_int_num, expectMoreSpecific: false);
+ expect(!strongMode, C_dynamic_dynamic, B_num_num,
+ expectMoreSpecific: false);
+ expect(!strongMode, C_dynamic_dynamic, B_int_num,
+ expectMoreSpecific: false);
expect(true, C_dynamic_dynamic, B_dynamic_dynamic);
- expect(true, C_dynamic_dynamic, B_String_dynamic,
+ expect(!strongMode, C_dynamic_dynamic, B_String_dynamic,
expectMoreSpecific: false);
expect(false, C_int_String, A_int);
@@ -331,7 +336,7 @@
expect(!strongMode, A, function);
expect(!strongMode, A, call);
- expect(true, call, m1);
+ expect(!strongMode, call, m1);
expect(!strongMode, A, m1);
expect(!strongMode, A, m2, expectMoreSpecific: false);
expect(false, A, m3);
@@ -454,7 +459,7 @@
.create(createMethods(optionalFunctionTypesData),
compileMode: compileMode,
options: strongMode ? [Flags.strongMode] : [])
- .then(functionSubtypingOptionalHelper);
+ .then((env) => functionSubtypingOptionalHelper(env, strongMode));
}
Future testTypedefSubtypingOptional(
@@ -463,10 +468,10 @@
.create(createTypedefs(optionalFunctionTypesData),
compileMode: compileMode,
options: strongMode ? [Flags.strongMode] : [])
- .then(functionSubtypingOptionalHelper);
+ .then((env) => functionSubtypingOptionalHelper(env, strongMode));
}
-functionSubtypingOptionalHelper(TypeEnvironment env) {
+functionSubtypingOptionalHelper(TypeEnvironment env, bool strongMode) {
void expect(bool expectSubtype, String sub, String sup,
{bool expectMoreSpecific}) {
testElementTypes(env, sub, sup, expectSubtype, expectMoreSpecific);
@@ -483,7 +488,7 @@
// Test ([Object])->void <: ([int])->void.
expect(true, 'void___Object', 'void___int', expectMoreSpecific: false);
// Test ([int])->void <: ([Object])->void.
- expect(true, 'void___int', 'void___Object');
+ expect(!strongMode, 'void___int', 'void___Object');
// Test (int,[int])->void <: (int)->void.
expect(true, 'void__int__int', 'void__int');
// Test (int,[int])->void <: (int,[int])->void.
@@ -532,7 +537,7 @@
.create(createMethods(namedFunctionTypesData),
compileMode: compileMode,
options: strongMode ? [Flags.strongMode] : [])
- .then(functionSubtypingNamedHelper);
+ .then((env) => functionSubtypingNamedHelper(env, strongMode));
}
Future testTypedefSubtypingNamed(
@@ -541,10 +546,10 @@
.create(createTypedefs(namedFunctionTypesData),
compileMode: compileMode,
options: strongMode ? [Flags.strongMode] : [])
- .then(functionSubtypingNamedHelper);
+ .then((env) => functionSubtypingNamedHelper(env, strongMode));
}
-functionSubtypingNamedHelper(TypeEnvironment env) {
+functionSubtypingNamedHelper(TypeEnvironment env, bool strongMode) {
expect(bool expectSubtype, String sub, String sup,
{bool expectMoreSpecific}) {
testElementTypes(env, sub, sup, expectSubtype, expectMoreSpecific);
@@ -563,7 +568,7 @@
// Test ({Object a})->void <: ({int a})->void.
expect(true, 'void___a_Object', 'void___a_int', expectMoreSpecific: false);
// Test ({int a})->void <: ({Object a})->void.
- expect(true, 'void___a_int', 'void___a_Object');
+ expect(!strongMode, 'void___a_int', 'void___a_Object');
// Test (int,{int a})->void <: (int,{int a})->void.
expect(true, 'void__int__a_int', 'void__int__a_int2');
// Test ({int a})->void <: ({double a})->void.
@@ -803,3 +808,164 @@
expect(false, J_U, A_T);
});
}
+
+Future testStrongModeSubtyping(CompileMode compileMode, bool strongMode) async {
+ await TypeEnvironment.create(r"""
+ class ClassWithCall {
+ void call() {}
+ }
+ num returnNum() => null;
+ int returnInt() => null;
+ void returnVoid() => null;
+ Object returnObject() => null;
+
+ takeNum(num o) => null;
+ takeInt(int o) => null;
+ takeVoid(void o) => null;
+ takeObject(Object o) => null;
+ """,
+ compileMode: compileMode,
+ options: strongMode ? [Flags.strongMode] : []).then((env) {
+ void expect(bool expectSubtype, DartType T, DartType S) {
+ Expect.equals(expectSubtype, env.isSubtype(T, S), '$T <: $S');
+ }
+
+ InterfaceType ClassWithCall = env['ClassWithCall'];
+ DartType Object_ = env['Object'];
+ DartType dynamic_ = env['dynamic'];
+ DartType void_ = env['void'];
+ DartType Null_ = env['Null'];
+ DartType Function_ = env['Function'];
+ DartType ClassWithCallType =
+ env.getMemberType('call', ClassWithCall.element);
+
+ InterfaceType List_Object = env.commonElements.listType(Object_);
+ InterfaceType List_dynamic = env.commonElements.listType(dynamic_);
+ InterfaceType List_void = env.commonElements.listType(void_);
+ InterfaceType List_Null = env.commonElements.listType(Null_);
+ InterfaceType List_Function = env.commonElements.listType(Function_);
+
+ DartType returnNum = env.getMemberType('returnNum');
+ DartType returnInt = env.getMemberType('returnInt');
+ DartType returnVoid = env.getMemberType('returnVoid');
+ DartType returnObject = env.getMemberType('returnObject');
+
+ DartType takeNum = env.getMemberType('takeNum');
+ DartType takeInt = env.getMemberType('takeInt');
+ DartType takeVoid = env.getMemberType('takeVoid');
+ DartType takeObject = env.getMemberType('takeObject');
+
+ // Classes with call methods are no longer subtypes of Function.
+ expect(!strongMode, ClassWithCall, Function_);
+ // Classes with call methods are no longer subtype the function type of the
+ // call method.
+ expect(!strongMode, ClassWithCall, ClassWithCallType);
+
+ // At runtime `Object`, `dynamic` and `void` are the same and are therefore
+ // subtypes and supertypes of each other.
+ //
+ // `dynamic` is no longer a bottom type but `Null` is.
+
+ expect(true, Object_, Object_);
+ expect(strongMode, Object_, void_);
+ expect(true, Object_, dynamic_);
+ expect(false, Object_, Null_);
+ expect(false, Object_, Function_);
+
+ expect(true, dynamic_, Object_);
+ expect(true, dynamic_, void_);
+ expect(true, dynamic_, dynamic_);
+ expect(!strongMode, dynamic_, Null_);
+ expect(!strongMode, dynamic_, Function_);
+
+ expect(strongMode, void_, Object_);
+ expect(true, void_, void_);
+ expect(true, void_, dynamic_);
+ expect(false, void_, Null_);
+ expect(false, void_, Function_);
+
+ expect(true, Null_, Object_);
+ expect(true, Null_, void_);
+ expect(true, Null_, dynamic_);
+ expect(true, Null_, Null_);
+ expect(true, Null_, Function_);
+
+ expect(true, Function_, Object_);
+ expect(strongMode, Function_, void_);
+ expect(true, Function_, dynamic_);
+ expect(false, Function_, Null_);
+ expect(true, Function_, Function_);
+
+ expect(true, List_Object, List_Object);
+ expect(strongMode, List_Object, List_void);
+ expect(true, List_Object, List_dynamic);
+ expect(false, List_Object, List_Null);
+ expect(false, List_Object, List_Function);
+
+ expect(true, List_dynamic, List_Object);
+ expect(true, List_dynamic, List_void);
+ expect(true, List_dynamic, List_dynamic);
+ expect(!strongMode, List_dynamic, List_Null);
+ expect(!strongMode, List_dynamic, List_Function);
+
+ expect(strongMode, List_void, List_Object);
+ expect(true, List_void, List_void);
+ expect(true, List_void, List_dynamic);
+ expect(false, List_void, List_Null);
+ expect(false, List_void, List_Function);
+
+ expect(true, List_Null, List_Object);
+ expect(true, List_Null, List_void);
+ expect(true, List_Null, List_dynamic);
+ expect(true, List_Null, List_Null);
+ expect(true, List_Null, List_Function);
+
+ expect(true, List_Function, List_Object);
+ expect(strongMode, List_Function, List_void);
+ expect(true, List_Function, List_dynamic);
+ expect(false, List_Function, List_Null);
+ expect(true, List_Function, List_Function);
+
+ // Return type are now covariant.
+ expect(true, returnNum, returnNum);
+ expect(!strongMode, returnNum, returnInt);
+ expect(true, returnNum, returnVoid);
+ expect(true, returnNum, returnObject);
+
+ expect(true, returnInt, returnNum);
+ expect(true, returnInt, returnInt);
+ expect(true, returnInt, returnVoid);
+ expect(true, returnInt, returnObject);
+
+ expect(false, returnVoid, returnNum);
+ expect(false, returnVoid, returnInt);
+ expect(true, returnVoid, returnVoid);
+ expect(strongMode, returnVoid, returnObject);
+
+ expect(!strongMode, returnObject, returnNum);
+ expect(!strongMode, returnObject, returnInt);
+ expect(true, returnObject, returnVoid);
+ expect(true, returnObject, returnObject);
+
+ // Arguments types are now contravariant.
+ expect(true, takeNum, takeNum);
+ expect(true, takeNum, takeInt);
+ expect(false, takeNum, takeVoid);
+ expect(!strongMode, takeNum, takeObject);
+
+ expect(!strongMode, takeInt, takeNum);
+ expect(true, takeInt, takeInt);
+ expect(false, takeInt, takeVoid);
+ expect(!strongMode, takeInt, takeObject);
+
+ expect(strongMode, takeVoid, takeNum);
+ expect(strongMode, takeVoid, takeInt);
+ expect(true, takeVoid, takeVoid);
+ expect(strongMode, takeVoid, takeObject);
+
+ expect(true, takeObject, takeNum);
+ expect(true, takeObject, takeInt);
+ expect(strongMode, takeObject, takeVoid);
+ expect(true, takeObject, takeObject);
+ });
+}
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/rti/type_representation_test.dart
similarity index 98%
rename from tests/compiler/dart2js/type_representation_test.dart
rename to tests/compiler/dart2js/rti/type_representation_test.dart
index b4cfd1c..36fec2a 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/rti/type_representation_test.dart
@@ -18,9 +18,9 @@
show TypeRepresentationGenerator;
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
-import 'helpers/element_lookup.dart';
-import 'memory_compiler.dart';
-import 'type_test_helper.dart';
+import '../helpers/element_lookup.dart';
+import '../memory_compiler.dart';
+import '../type_test_helper.dart';
void main() {
asyncTest(() async {
diff --git a/tests/language_2/function_apply_generic_test.dart b/tests/language_2/function_apply_generic_test.dart
index 88d4857..464f591 100644
--- a/tests/language_2/function_apply_generic_test.dart
+++ b/tests/language_2/function_apply_generic_test.dart
@@ -59,4 +59,6 @@
check('[1, 2, 3, 4, 5, 6, 7, null, null, null]',
Function.apply(memberFn2, [1, 2, 3, 4, 5, 6, 7]));
+
+ // TODO(sra): Apply of instantiations
}
diff --git a/tests/language_2/function_call_generic_test.dart b/tests/language_2/function_call_generic_test.dart
new file mode 100644
index 0000000..0d90f52
--- /dev/null
+++ b/tests/language_2/function_call_generic_test.dart
@@ -0,0 +1,81 @@
+// 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=-Ddart.isdart2js=true
+
+import "package:expect/expect.dart";
+
+@NoInline()
+List staticFn<T>([T a1, T a2, T a3, T a4, T a5]) => [T, a1, a2, a3, a4, a5];
+
+class C {
+ @NoInline()
+ List memberFn<T>([T a1, T a2, T a3, T a4, T a5]) => [T, a1, a2, a3, a4, a5];
+
+ @NoInline()
+ // 'map' is implemented by native iterables. On dart2js, 'map' has interceptor
+ // calling convention.
+ List map<T>([T a1, T a2, T a3, T a4, T a5]) => [T, a1, a2, a3, a4, a5];
+}
+
+check(expected, actual) {
+ print('a: $expected');
+ print('b: $actual');
+ if (((actual[0] == Object && expected[0] == dynamic) ||
+ (actual[0] == dynamic && expected[0] == Object)) &&
+ !const bool.fromEnvironment('dart.isdart2js')) {
+ // TODO(32483): dartdevk sometimes defaults type to 'Object' when 'dynamic'
+ // is required. Remove this hack when fixed.
+ actual = actual.toList()..[0] = expected[0];
+ print('b*: $actual');
+ }
+ Expect.equals(expected.toString(), actual.toString());
+}
+
+main() {
+ check([dynamic, 1, 2, 3, null, null], staticFn(1 as dynamic, 2, 3));
+
+ check([Object, 'Z', 2, 4, null, null], staticFn('Z', 2, 4));
+
+ check([int, 3, 2, 1, null, null], staticFn(3, 2, 1));
+
+ dynamic f1 = staticFn;
+
+ check([dynamic, 4, 2, 3, null, null], f1(4 as dynamic, 2, 3));
+
+ check([dynamic, 'Q', 2, 3, null, null], f1('Q', 2, 3));
+
+ check([dynamic, 6, 2, 3, null, null], f1(6, 2, 3));
+
+ check([int, 7, 2, null, null, null], f1<int>(7, 2));
+
+ var c = new C();
+
+ check([dynamic, 8, 2, 3, null, null], c.memberFn(8 as dynamic, 2, 3));
+
+ check([Object, 'A', 2, 3, null, null], c.memberFn('A', 2, 3));
+
+ check([int, 9, 2, 3, null, null], c.memberFn<int>(9, 2, 3));
+
+ check([dynamic, 10, 2, 3, null, null], c.map(10 as dynamic, 2, 3));
+
+ check([Object, 'B', 2, 3, null, null], c.map('B', 2, 3));
+
+ check([int, 11, 2, 3, null, null], c.map(11, 2, 3));
+
+ dynamic o = new C();
+
+ check([dynamic, 12, 2, 3, null, null], o.memberFn(12 as dynamic, 2, 3));
+
+ check([dynamic, 'C', 2, 3, null, null], o.memberFn('C', 2, 3));
+
+ check([int, 13, 2, null, null, null], o.memberFn<int>(13, 2));
+
+ check([dynamic, 14, 2, 3, null, null], o.map(14 as dynamic, 2, 3));
+
+ check([dynamic, 'D', 2, 3, null, null], o.map('D', 2, 3));
+
+ check([int, 15, null, null, null, null], o.map<int>(15));
+
+ check([int, 16, 2, 3, 4, null], o.map<int>(16, 2, 3, 4));
+}
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 0c92c91..9099b15 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -1041,6 +1041,10 @@
partial_tearoff_instantiation_test/07: Pass # for the wrong reason.
partial_tearoff_instantiation_test/08: Pass # for the wrong reason.
partial_tearoff_instantiation_test/none: CompileTimeError
+type_alias_equality_test/01: RuntimeError # Issue 31359
+type_alias_equality_test/02: RuntimeError # Issue 31359
+type_alias_equality_test/03: RuntimeError # Issue 31359
+type_alias_equality_test/04: RuntimeError # Issue 31359
[ $compiler == dart2js && $fasta && $host_checked && $strong ]
abstract_factory_constructor_test/00: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 5eb7866..823ef0b 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -181,6 +181,10 @@
truncdiv_test: RuntimeError # Issue 29920
try_catch_on_syntax_test/10: MissingCompileTimeError
try_catch_on_syntax_test/11: MissingCompileTimeError
+type_alias_equality_test/01: RuntimeError # Issue 31359
+type_alias_equality_test/02: RuntimeError # Issue 31359
+type_alias_equality_test/03: RuntimeError # Issue 31359
+type_alias_equality_test/04: RuntimeError # Issue 31359
type_inference_circularity_test: MissingCompileTimeError
type_inference_inconsistent_inheritance_test: MissingCompileTimeError
type_promotion_functions_test/02: CompileTimeError # Issue 30895
@@ -394,6 +398,7 @@
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_subtype_closure0_test: RuntimeError # Expect.throws(TypeError) fails: Did not throw
generic_function_bounds_test: RuntimeError
@@ -650,6 +655,7 @@
syntax_test/33: MissingCompileTimeError
tearoff_dynamic_test: RuntimeError # Issue 32194
try_catch_test/01: MissingCompileTimeError
+type_alias_equality_test/02: RuntimeError # Issue 31359
type_literal_test: RuntimeError # Expect.equals(expected: <Func>, actual: <(bool) => int>) fails.
type_promotion_functions_test/02: CompileTimeError # Issue 31537
type_promotion_functions_test/03: CompileTimeError # Issue 31537
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index ef87534..2fb1e0f 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -538,6 +538,11 @@
vm/type_vm_test/35: MissingRuntimeError
vm/type_vm_test/36: MissingRuntimeError
+[ $compiler == dartk && $runtime == vm ]
+type_alias_equality_test/02: RuntimeError # Issue 31359
+type_alias_equality_test/03: RuntimeError # Issue 31359
+type_alias_equality_test/04: RuntimeError # Issue 31359
+
[ $compiler == dartk && $runtime == vm && $checked && $strong ]
assert_initializer_test/31: MissingCompileTimeError # KernelVM bug: Constant evaluation.
assert_initializer_test/32: MissingCompileTimeError # KernelVM bug: Constant evaluation.
@@ -696,8 +701,8 @@
named_constructor_test/01: MissingRuntimeError # Fasta bug: Bad compilation of constructor reference.
named_parameters_default_eq_test/none: RuntimeError
nested_generic_closure_test: RuntimeError
-no_main_test/01: Skip
no_main_test/01: DartkCrash
+no_main_test/01: Skip
no_such_method_mock_test: RuntimeError # Issue 31426
null_no_such_method_test: CompileTimeError # Issue 31533
override_inheritance_field_test/04: CompileTimeError # Issue 31616
@@ -802,6 +807,11 @@
vm/type_vm_test/35: MissingRuntimeError
vm/type_vm_test/36: MissingRuntimeError
+[ $compiler == dartkp && $runtime == dart_precompiled ]
+type_alias_equality_test/02: RuntimeError # Issue 31359
+type_alias_equality_test/03: RuntimeError # Issue 31359
+type_alias_equality_test/04: RuntimeError # Issue 31359
+
[ $compiler == dartkp && $runtime == dart_precompiled && $checked && $strong ]
assert_initializer_test/31: MissingCompileTimeError # KernelVM bug: Constant evaluation.
assert_initializer_test/32: MissingCompileTimeError # KernelVM bug: Constant evaluation.
@@ -2174,3 +2184,4 @@
[ $compiler == dartk || $compiler == dartkp ]
generic_function_bounds_test: RuntimeError # Issue 32076
generic_test/01: MissingCompileTimeError
+
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index 56d7d4f..a41c57f 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -1054,6 +1054,7 @@
covariance_type_parameter_test/none: RuntimeError
covariant_subtyping_test: RuntimeError
factory_implementation_test/00: Fail
+function_call_generic_test: RuntimeError # Type argument not inferred.
function_type/function_type0_test: RuntimeError # Issue 30475
function_type/function_type10_test: RuntimeError # Issue 30475
function_type/function_type12_test: RuntimeError # Issue 30475
@@ -1340,6 +1341,10 @@
nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
nsm5_test: MissingCompileTimeError
override_inheritance_no_such_method_test/05: MissingCompileTimeError
+type_alias_equality_test/01: RuntimeError # Issue 31359
+type_alias_equality_test/02: RuntimeError # Issue 31359
+type_alias_equality_test/03: RuntimeError # Issue 31359
+type_alias_equality_test/04: RuntimeError # Issue 31359
[ $compiler == none && $runtime == vm && !$checked ]
assertion_initializer_const_error_test/01: MissingCompileTimeError
diff --git a/tests/language_2/type_alias_equality_test.dart b/tests/language_2/type_alias_equality_test.dart
new file mode 100644
index 0000000..18b055d
--- /dev/null
+++ b/tests/language_2/type_alias_equality_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that type aliases perform equality tests according to the
+// underlying function type, not as if they were a distinct type
+// for each type alias declaration.
+
+import 'package:expect/expect.dart';
+
+typedef F1 = void Function(int);
+typedef F2 = void Function(int);
+typedef void F3(int);
+
+typedef G1 = X Function<X>(X);
+typedef G2 = X Function<X>(X);
+typedef G3 = Y Function<Y>(Y);
+
+main() {
+ Expect.equals(F1, F2); //# 01: ok
+ Expect.equals(F1, F3); //# 02: ok
+ Expect.equals(G1, G2); //# 03: ok
+ Expect.equals(G1, G3); //# 04: ok
+}
diff --git a/tools/VERSION b/tools/VERSION
index eda92b0..6492cf9 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 0
PATCH 0
-PRERELEASE 44
+PRERELEASE 45
PRERELEASE_PATCH 0
diff --git a/tools/gardening/lib/src/results/configuration_environment.dart b/tools/gardening/lib/src/results/configuration_environment.dart
index e2da3fb..667a772 100644
--- a/tools/gardening/lib/src/results/configuration_environment.dart
+++ b/tools/gardening/lib/src/results/configuration_environment.dart
@@ -46,6 +46,7 @@
}),
"minified": new _Variable.bool((c) => c.minified),
"mode": new _Variable((c) => c.mode, Mode.names),
+ "preview_dart_2": new _Variable.bool((c) => c.previewDart2),
"runtime": new _Variable(_runtimeName, Runtime.names),
"spec_parser": new _Variable.bool((c) => c.compiler == Compiler.specParser),
"strong": new _Variable.bool((c) => c.strong),
@@ -98,7 +99,7 @@
if (variable == null) {
// This shouldn't happen since we validate variables before evaluating
// expressions.
- throw new ArgumentError('Unknown variable "$variable".');
+ throw new ArgumentError('Unknown variable "$name".');
}
return variable.lookUp(_configuration);
diff --git a/tools/gardening/lib/src/results/status_expectations.dart b/tools/gardening/lib/src/results/status_expectations.dart
index 5131a48..58bd4e8 100644
--- a/tools/gardening/lib/src/results/status_expectations.dart
+++ b/tools/gardening/lib/src/results/status_expectations.dart
@@ -112,9 +112,17 @@
Set<Expectation> testExpectations =
expectationsFromTest(result.testExpectations);
Set<Expectation> expectationSet = expectations();
+ final allowedWithoutRuntime = [
+ Expectation.runtimeError,
+ Expectation.missingRuntimeError,
+ Expectation.timeout
+ ];
_isSuccess = testExpectations.contains(outcome) ||
expectationSet.contains(Expectation.skip) ||
expectationSet.contains(Expectation.skipByDesign) ||
+ outcome == Expectation.pass &&
+ configuration.runtime == "none" &&
+ allowedWithoutRuntime.any(expectationSet.contains) ||
expectationSet.any((expectation) {
return outcome.canBeOutcomeOf(expectation);
});