Version 1.16.0-dev.1.0
Merge commit 'e8a79c4f911c4b03b205365ac5868230e1bc5234' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f8fe8f0..863e8d6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -38,17 +38,28 @@
`SecurityContext.usePrivateKeyBytes`, for use as the password for PKCS12
data.
-### Dartium
+### Tool changes
+* Dartium and content shell
* The Chrome-based tools that ship as part of the Dart SDK – Dartium and
content shell – are now based on Chrome version 45 (instead of Chrome 39).
- * Dart browser libraries (`dart:html`, `dart:svg`, etc) have not been updated.
+ * Dart browser libraries (`dart:html`, `dart:svg`, etc) *have not* been
+ updated.
* These are still based on Chrome 39.
* These APIs will be updated in a future release.
* Note that there are experimental APIs which have changed in the underlying
browser, and will not work with the older libraries.
For example, `Element.animate`.
+* `dartfmt` - upgraded to v0.2.4
+ * Better handling for long collections with comments.
+ * Always put member metadata annotations on their own line.
+ * Indent functions in named argument lists with non-functions.
+ * Force the parameter list to split if a split occurs inside a function-typed
+ parameter.
+ * Don't force a split for before a single named argument if the argument
+ itself splits.
+
### Service protocol changes
* Fixed a documentation bug where the field `extensionRPCs` in `Isolate`
diff --git a/DEPS b/DEPS
index 97ab2cc..9ed1e3a 100644
--- a/DEPS
+++ b/DEPS
@@ -52,7 +52,7 @@
"intl_rev": "@a8b480b9c436f6c0ec16730804c914bdb4e30d53",
"jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "@1.1.1",
- "linter_rev": "@f90572f9be203a0ec9744aa3fb3b9509e3ca143d",
+ "linter_rev": "@a60289545b34ab1f047a0a3f0673a4c5abde0eaf",
"logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
"markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
"matcher_tag": "@0.12.0",
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index fd1e1ef..0c6b2dd 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -61,7 +61,7 @@
</style></head>
<body>
<h1>Analysis Server API Specification</h1>
- <h1 style="color:#999999">Version 1.14.0</h1>
+ <h1 style="color:#999999">Version 1.15.0</h1>
<p>
This document contains a specification of the API provided by the
analysis server. The API in this document is currently under
@@ -2454,6 +2454,11 @@
the error. The field is omitted if there is no correction
message associated with the error code.
</p>
+ </dd><dt class="field"><b><i>code ( String )</i></b></dt><dd>
+
+ <p>
+ The name, as a string, of the error code associated with this error.
+ </p>
</dd><dt class="field"><b><i>hasFix ( <span style="color:#999999">optional</span> bool )</i></b></dt><dd>
<p>
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
index 863ced0..5d288e3 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
@@ -7,7 +7,7 @@
import 'dart:async';
import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
index 6ef1bed..a0527d6 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
@@ -9,7 +9,7 @@
import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
import 'package:analysis_server/src/services/correction/fix_internal.dart'
show DartFixContextImpl;
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
index eab48cd..c547af5 100644
--- a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
@@ -7795,6 +7795,7 @@
* "location": Location
* "message": String
* "correction": optional String
+ * "code": String
* "hasFix": optional bool
* }
*
@@ -7811,6 +7812,8 @@
String _correction;
+ String _code;
+
bool _hasFix;
/**
@@ -7884,6 +7887,19 @@
}
/**
+ * The name, as a string, of the error code associated with this error.
+ */
+ String get code => _code;
+
+ /**
+ * The name, as a string, of the error code associated with this error.
+ */
+ void set code(String value) {
+ assert(value != null);
+ this._code = value;
+ }
+
+ /**
* A hint to indicate to interested clients that this error has an associated
* fix (or fixes). The absence of this field implies there are not known to
* be fixes. Note that since the operation to calculate whether fixes apply
@@ -7909,12 +7925,13 @@
this._hasFix = value;
}
- AnalysisError(AnalysisErrorSeverity severity, AnalysisErrorType type, Location location, String message, {String correction, bool hasFix}) {
+ AnalysisError(AnalysisErrorSeverity severity, AnalysisErrorType type, Location location, String message, String code, {String correction, bool hasFix}) {
this.severity = severity;
this.type = type;
this.location = location;
this.message = message;
this.correction = correction;
+ this.code = code;
this.hasFix = hasFix;
}
@@ -7951,11 +7968,17 @@
if (json.containsKey("correction")) {
correction = jsonDecoder.decodeString(jsonPath + ".correction", json["correction"]);
}
+ String code;
+ if (json.containsKey("code")) {
+ code = jsonDecoder.decodeString(jsonPath + ".code", json["code"]);
+ } else {
+ throw jsonDecoder.missingKey(jsonPath, "code");
+ }
bool hasFix;
if (json.containsKey("hasFix")) {
hasFix = jsonDecoder.decodeBool(jsonPath + ".hasFix", json["hasFix"]);
}
- return new AnalysisError(severity, type, location, message, correction: correction, hasFix: hasFix);
+ return new AnalysisError(severity, type, location, message, code, correction: correction, hasFix: hasFix);
} else {
throw jsonDecoder.mismatch(jsonPath, "AnalysisError", json);
}
@@ -7970,6 +7993,7 @@
if (correction != null) {
result["correction"] = correction;
}
+ result["code"] = code;
if (hasFix != null) {
result["hasFix"] = hasFix;
}
@@ -7987,6 +8011,7 @@
location == other.location &&
message == other.message &&
correction == other.correction &&
+ code == other.code &&
hasFix == other.hasFix;
}
return false;
@@ -8000,6 +8025,7 @@
hash = JenkinsSmiHash.combine(hash, location.hashCode);
hash = JenkinsSmiHash.combine(hash, message.hashCode);
hash = JenkinsSmiHash.combine(hash, correction.hashCode);
+ hash = JenkinsSmiHash.combine(hash, code.hashCode);
hash = JenkinsSmiHash.combine(hash, hasFix.hashCode);
return JenkinsSmiHash.finish(hash);
}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index cc068b3..4e5036d 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -20,8 +20,9 @@
import 'package:analysis_server/src/plugin/server_plugin.dart';
import 'package:analysis_server/src/services/correction/namespace.dart';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index2/index2.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analysis_server/src/services/search/search_engine_internal.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -29,7 +30,7 @@
import 'package:analyzer/plugin/resolver_provider.dart';
import 'package:analyzer/source/embedder.dart';
import 'package:analyzer/source/pub_package_map_provider.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_io.dart';
@@ -39,6 +40,7 @@
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/util/glob.dart';
+import 'package:analyzer/task/dart.dart';
import 'package:plugin/plugin.dart';
typedef void OptionUpdater(AnalysisOptionsImpl options);
@@ -76,14 +78,14 @@
* The version of the analysis server. The value should be replaced
* automatically during the build.
*/
- static final String VERSION = '1.14.0';
+ static final String VERSION = '1.15.0';
/**
* The number of milliseconds to perform operations before inserting
* a 1 millisecond delay so that the VM and dart:io can deliver content
* to stdin. This should be removed once the underlying problem is fixed.
*/
- static int performOperationDelayFreqency = 25;
+ static int performOperationDelayFrequency = 25;
/**
* The options of this server instance.
@@ -107,11 +109,6 @@
final Index index;
/**
- * The [Index2] for this server, may be `null` if indexing is disabled.
- */
- final Index2 index2;
-
- /**
* The [SearchEngine] for this server, may be `null` if indexing is disabled.
*/
final SearchEngine searchEngine;
@@ -311,7 +308,6 @@
this.resourceProvider,
PubPackageMapProvider packageMapProvider,
Index _index,
- Index2 _index2,
this.serverPlugin,
this.options,
this.defaultSdkCreator,
@@ -320,8 +316,7 @@
EmbeddedResolverProvider embeddedResolverProvider: null,
this.rethrowExceptions: true})
: index = _index,
- index2 = _index2,
- searchEngine = _index != null ? createSearchEngine(_index) : null {
+ searchEngine = _index != null ? new SearchEngineImpl(_index) : null {
_performance = performanceDuringStartup;
defaultContextOptions.incremental = true;
defaultContextOptions.incrementalApi =
@@ -330,8 +325,10 @@
options.enableIncrementalResolutionValidation;
defaultContextOptions.generateImplicitErrors = false;
operationQueue = new ServerOperationQueue();
+ sdkManager = new DartSdkManager(defaultSdkCreator);
contextManager = new ContextManagerImpl(
resourceProvider,
+ sdkManager,
packageResolverProvider,
embeddedResolverProvider,
packageMapProvider,
@@ -354,12 +351,12 @@
_performance = performanceAfterStartup;
});
});
+ _setupIndexInvalidation();
Notification notification =
new ServerConnectedParams(VERSION).toNotification();
channel.sendNotification(notification);
channel.listen(handleRequest, onDone: done, onError: error);
handlers = serverPlugin.createDomains(this);
- sdkManager = new DartSdkManager(defaultSdkCreator);
}
/**
@@ -675,23 +672,6 @@
return context.getErrors(source);
}
-// TODO(brianwilkerson) Add the following method after 'prioritySources' has
-// been added to InternalAnalysisContext.
-// /**
-// * Return a list containing the full names of all of the sources that are
-// * priority sources.
-// */
-// List<String> getPriorityFiles() {
-// List<String> priorityFiles = new List<String>();
-// folderMap.values.forEach((ContextDirectory directory) {
-// InternalAnalysisContext context = directory.context;
-// context.prioritySources.forEach((Source source) {
-// priorityFiles.add(source.fullName);
-// });
-// });
-// return priorityFiles;
-// }
-
/**
* Returns resolved [AstNode]s at the given [offset] of the given [file].
*
@@ -709,6 +689,23 @@
return nodes;
}
+// TODO(brianwilkerson) Add the following method after 'prioritySources' has
+// been added to InternalAnalysisContext.
+// /**
+// * Return a list containing the full names of all of the sources that are
+// * priority sources.
+// */
+// List<String> getPriorityFiles() {
+// List<String> priorityFiles = new List<String>();
+// folderMap.values.forEach((ContextDirectory directory) {
+// InternalAnalysisContext context = directory.context;
+// context.prioritySources.forEach((Source source) {
+// priorityFiles.add(source.fullName);
+// });
+// });
+// return priorityFiles;
+// }
+
/**
* Returns resolved [CompilationUnit]s of the Dart file with the given [path].
*
@@ -1209,7 +1206,6 @@
void shutdown() {
running = false;
if (index != null) {
- index.clear();
index.stop();
}
// Defer closing the channel and shutting down the instrumentation server so
@@ -1434,7 +1430,7 @@
}
/**
- * Schedules [performOperation] exection.
+ * Schedules [performOperation] execution.
*/
void _schedulePerformOperation() {
if (performOperationPending) {
@@ -1448,18 +1444,46 @@
* every 25 milliseconds.
*
* To disable this workaround and see the underlying problem,
- * set performOperationDelayFreqency to zero
+ * set performOperationDelayFrequency to zero
*/
int now = new DateTime.now().millisecondsSinceEpoch;
if (now > _nextPerformOperationDelayTime &&
- performOperationDelayFreqency > 0) {
- _nextPerformOperationDelayTime = now + performOperationDelayFreqency;
+ performOperationDelayFrequency > 0) {
+ _nextPerformOperationDelayTime = now + performOperationDelayFrequency;
new Future.delayed(new Duration(milliseconds: 1), performOperation);
} else {
new Future(performOperation);
}
performOperationPending = true;
}
+
+ /**
+ * Listen for context events and invalidate index.
+ *
+ * It is possible that this method will do more in the future, e.g. listening
+ * for summary information and linking pre-indexed packages into the index,
+ * but for now we only invalidate project specific index information.
+ */
+ void _setupIndexInvalidation() {
+ if (index == null) {
+ return;
+ }
+ onContextsChanged.listen((ContextsChangedEvent event) {
+ for (AnalysisContext context in event.added) {
+ context
+ .onResultChanged(RESOLVED_UNIT)
+ .listen((ResultChangedEvent event) {
+ if (event.wasInvalidated) {
+ LibrarySpecificUnit target = event.target;
+ index.removeUnit(event.context, target.library, target.unit);
+ }
+ });
+ }
+ for (AnalysisContext context in event.removed) {
+ index.removeContext(context);
+ }
+ });
+ }
}
class AnalysisServerOptions {
@@ -1553,9 +1577,6 @@
AnalysisContext context = analysisServer.folderMap.remove(folder);
sendAnalysisNotificationFlushResults(analysisServer, flushedFiles);
- if (analysisServer.index != null) {
- analysisServer.index.removeContext(context);
- }
analysisServer.operationQueue.contextRemoved(context);
analysisServer._onContextsChangedController
.add(new ContextsChangedEvent(removed: [context]));
@@ -1565,11 +1586,7 @@
}
@override
- void updateContextPackageUriResolver(
- Folder contextFolder, FolderDisposition disposition) {
- AnalysisContext context = analysisServer.folderMap[contextFolder];
- context.sourceFactory = _createSourceFactory(
- context, context.analysisOptions, disposition, contextFolder);
+ void updateContextPackageUriResolver(AnalysisContext context) {
analysisServer._onContextsChangedController
.add(new ContextsChangedEvent(changed: [context]));
analysisServer.schedulePerformAnalysisOperation(context);
@@ -1662,7 +1679,7 @@
int slowRequestCount = 0;
/**
- * Log performation information about the given request.
+ * Log performance information about the given request.
*/
void logRequest(Request request) {
++requestCount;
@@ -1717,7 +1734,7 @@
static PerformanceTag pub = new PerformanceTag('pub');
/**
- * The [PerformanceTag] for time spent in server comminication channels.
+ * The [PerformanceTag] for time spent in server communication channels.
*/
static PerformanceTag serverChannel = new PerformanceTag('serverChannel');
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index ed5e8e9..1214ea4 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -5,10 +5,11 @@
library computer.highlights;
import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
/**
* A computer for [HighlightRegion]s in a Dart [CompilationUnit].
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
index 5665d49..bfc9d66 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
@@ -5,10 +5,11 @@
library computer.highlights2;
import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
/**
* A computer for [HighlightRegion]s in a Dart [CompilationUnit].
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index 02c4f70..19ae943 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -8,9 +8,9 @@
show HoverInformation;
import 'package:analysis_server/src/computer/computer_overrides.dart';
import 'package:analysis_server/src/utilities/documentation.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
/**
* A computer for the hover at the specified offset of a Dart [CompilationUnit].
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 55c6560..8603884 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -6,9 +6,10 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/collections.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart' as engine;
import 'package:analyzer/dart/element/type.dart' as engine;
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.dart';
/**
diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
index 4eb93d1..e174b7d 100644
--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
@@ -8,7 +8,7 @@
import 'package:analysis_server/src/protocol_server.dart' as proto;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
/**
* Return the elements that the given [element] overrides.
@@ -138,6 +138,14 @@
_OverriddenElementsFinder(Element seed) {
_seed = seed;
_class = seed.enclosingElement;
+ if (_class == null) {
+ // TODO(brianwilkerson) Remove this code when the issue has been fixed
+ // (https://github.com/dart-lang/sdk/issues/25884)
+ Type type = seed.runtimeType;
+ String name = seed.name;
+ throw new ArgumentError(
+ 'The $type named $name does not have an enclosing element');
+ }
_library = _class.library;
_name = seed.displayName;
if (seed is MethodElement) {
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index c81ce7f..4ce26ae 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -27,6 +27,7 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/task/options.dart';
@@ -348,10 +349,9 @@
void removeContext(Folder folder, List<String> flushedFiles);
/**
- * Called when the disposition for a context has changed.
+ * Called when the package resolution for the given [context] has changed.
*/
- void updateContextPackageUriResolver(
- Folder contextFolder, FolderDisposition disposition);
+ void updateContextPackageUriResolver(AnalysisContext context);
}
/**
@@ -390,6 +390,12 @@
final ResourceProvider resourceProvider;
/**
+ * The manager used to access the SDK that should be associated with a
+ * particular context.
+ */
+ final DartSdkManager sdkManager;
+
+ /**
* The context used to work with absolute file system paths.
*
* TODO(scheglov) remove [pathContext].
@@ -488,6 +494,7 @@
ContextManagerImpl(
this.resourceProvider,
+ this.sdkManager,
this.packageResolverProvider,
this.embeddedUriResolverProvider,
this._packageMapProvider,
@@ -928,7 +935,7 @@
if (info.isPathToPackageDescription(path)) {
Packages packages = _readPackagespec(packagespec);
if (packages != null) {
- callbacks.updateContextPackageUriResolver(
+ _updateContextPackageUriResolver(
folder, new PackagesFileDisposition(packages));
}
}
@@ -1065,6 +1072,7 @@
info.setDependencies(dependencies);
info.context = callbacks.addContext(folder, options, disposition);
+ folderMap[folder] = info.context;
info.context.name = folder.path;
processOptionsForContext(info, optionMap);
@@ -1130,6 +1138,41 @@
}
/**
+ * Set up a [SourceFactory] that resolves packages as appropriate for the
+ * given [disposition].
+ */
+ SourceFactory _createSourceFactory(InternalAnalysisContext context,
+ AnalysisOptions options, FolderDisposition disposition, Folder folder) {
+ List<UriResolver> resolvers = [];
+ List<UriResolver> packageUriResolvers =
+ disposition.createPackageUriResolvers(resourceProvider);
+
+ EmbedderUriResolver embedderUriResolver;
+
+ // First check for a resolver provider.
+ if (embeddedUriResolverProvider != null) {
+ embedderUriResolver = embeddedUriResolverProvider(folder);
+ }
+
+ // If no embedded URI resolver was provided, defer to a locator-backed one.
+ embedderUriResolver ??=
+ new EmbedderUriResolver(context.embedderYamlLocator.embedderYamls);
+ if (embedderUriResolver.length == 0) {
+ // The embedder uri resolver has no mappings. Use the default Dart SDK
+ // uri resolver.
+ resolvers.add(new DartUriResolver(sdkManager.getSdkForOptions(options)));
+ } else {
+ // The embedder uri resolver has mappings, use it instead of the default
+ // Dart SDK uri resolver.
+ resolvers.add(embedderUriResolver);
+ }
+
+ resolvers.addAll(packageUriResolvers);
+ resolvers.add(new ResourceUriResolver(resourceProvider));
+ return new SourceFactory(resolvers, disposition.packages);
+ }
+
+ /**
* Clean up and destroy the context associated with the given folder.
*/
void _destroyContext(ContextInfo info) {
@@ -1499,7 +1542,7 @@
FolderDisposition disposition = _computeFolderDisposition(
info.folder, dependencies.add, _findPackageSpecFile(info.folder));
info.setDependencies(dependencies);
- callbacks.updateContextPackageUriResolver(info.folder, disposition);
+ _updateContextPackageUriResolver(info.folder, disposition);
}
/**
@@ -1520,6 +1563,14 @@
return false;
}
+ void _updateContextPackageUriResolver(
+ Folder contextFolder, FolderDisposition disposition) {
+ AnalysisContext context = folderMap[contextFolder];
+ context.sourceFactory = _createSourceFactory(
+ context, context.analysisOptions, disposition, contextFolder);
+ callbacks.updateContextPackageUriResolver(context);
+ }
+
/**
* Create and return a source representing the given [file] within the given
* [context].
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index df31682..df307fb 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -22,9 +22,9 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/services/dependencies/library_dependencies.dart';
import 'package:analysis_server/src/services/dependencies/reachable_source_collector.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart' as engine;
import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
index 20ddb4f..e978eb4 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
@@ -6,10 +6,12 @@
import 'package:analysis_server/plugin/analysis/navigation/navigation_core.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
index 7eea646..9434d19 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
@@ -6,10 +6,11 @@
import 'package:analysis_server/plugin/analysis/occurrences/occurrences_core.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 4197555..260f67f 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -19,9 +19,9 @@
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart' as engine;
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart' as engine;
import 'package:analyzer/src/generated/error.dart' as engine;
import 'package:analyzer/src/generated/parser.dart' as engine;
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index b3623b0..c16924a 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -15,10 +15,9 @@
import 'package:analysis_server/src/operation/operation.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analysis_server/src/services/dependencies/library_dependencies.dart';
-import 'package:analysis_server/src/services/index/index.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -456,10 +455,7 @@
void perform(AnalysisServer server) {
ServerPerformanceStatistics.indexOperation.makeCurrentWhile(() {
try {
- Index index = server.index;
- AnalysisContext context = unit.element.context;
- index.index(context, unit);
- server.index2?.indexUnit(unit);
+ server.index?.indexUnit(unit);
} catch (exception, stackTrace) {
server.sendServerErrorNotification(
'Failed to index: $file', exception, stackTrace);
diff --git a/pkg/analysis_server/lib/src/plugin/server_plugin.dart b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
index b35d5bd..91ecb32 100644
--- a/pkg/analysis_server/lib/src/plugin/server_plugin.dart
+++ b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
@@ -25,12 +25,9 @@
import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:analysis_server/src/provisional/completion/completion_core.dart';
-import 'package:analysis_server/src/provisional/index/index.dart';
-import 'package:analysis_server/src/provisional/index/index_core.dart';
import 'package:analysis_server/src/search/search_domain.dart';
import 'package:analysis_server/src/services/correction/assist_internal.dart';
import 'package:analysis_server/src/services/correction/fix_internal.dart';
-import 'package:analysis_server/src/services/index/index_contributor.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:plugin/plugin.dart';
@@ -138,11 +135,6 @@
ExtensionPoint fixContributorExtensionPoint;
/**
- * The extension point that allows plugins to register index contributors.
- */
- ExtensionPoint indexContributorExtensionPoint;
-
- /**
* The extension point that allows plugins to register navigation
* contributors.
*/
@@ -200,13 +192,6 @@
fixContributorExtensionPoint.extensions;
/**
- * Return a list containing all of the index contributors that were
- * contributed.
- */
- List<IndexContributor> get indexContributors =>
- indexContributorExtensionPoint.extensions;
-
- /**
* Return a list containing all of the navigation contributors that were
* contributed.
*/
@@ -261,8 +246,6 @@
DOMAIN_EXTENSION_POINT, _validateDomainExtension);
fixContributorExtensionPoint = registerExtensionPoint(
FIX_CONTRIBUTOR_EXTENSION_POINT, _validateFixContributorExtension);
- indexContributorExtensionPoint = registerExtensionPoint(
- INDEX_CONTRIBUTOR_EXTENSION_POINT, _validateIndexContributorExtension);
navigationContributorExtensionPoint = registerExtensionPoint(
NAVIGATION_CONTRIBUTOR_EXTENSION_POINT,
_validateNavigationContributorExtension);
@@ -323,11 +306,6 @@
//
registerExtension(
FIX_CONTRIBUTOR_EXTENSION_POINT_ID, new DefaultFixContributor());
- //
- // Register index contributors.
- //
- registerExtension(
- INDEX_CONTRIBUTOR_EXTENSION_POINT_ID, new DartIndexContributor());
}
/**
@@ -403,17 +381,6 @@
/**
* Validate the given extension by throwing an [ExtensionError] if it is not a
- * valid index contributor.
- */
- void _validateIndexContributorExtension(Object extension) {
- if (extension is! IndexContributor) {
- String id = indexContributorExtensionPoint.uniqueIdentifier;
- throw new ExtensionError('Extensions to $id must be an IndexContributor');
- }
- }
-
- /**
- * Validate the given extension by throwing an [ExtensionError] if it is not a
* valid navigation contributor.
*/
void _validateNavigationContributorExtension(Object extension) {
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 822727c..138c20f 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -9,10 +9,12 @@
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/search/search_engine.dart'
as engine;
+import 'package:analyzer/dart/ast/ast.dart' as engine;
+import 'package:analyzer/dart/ast/visitor.dart' as engine;
import 'package:analyzer/dart/element/element.dart' as engine;
import 'package:analyzer/dart/element/type.dart' as engine;
import 'package:analyzer/source/error_processor.dart';
-import 'package:analyzer/src/generated/ast.dart' as engine;
+import 'package:analyzer/src/dart/ast/utilities.dart' as engine;
import 'package:analyzer/src/generated/engine.dart' as engine;
import 'package:analyzer/src/generated/error.dart' as engine;
import 'package:analyzer/src/generated/source.dart' as engine;
@@ -111,16 +113,17 @@
location = new Location(file, offset, length, startLine, startColumn);
}
- // Deafult to the error's severity if none is specified.
+ // Default to the error's severity if none is specified.
errorSeverity ??= errorCode.errorSeverity;
// done
var severity = new AnalysisErrorSeverity(errorSeverity.name);
var type = new AnalysisErrorType(errorCode.type.name);
String message = error.message;
+ String code = errorCode.name.toLowerCase();
String correction = error.correction;
bool fix = hasFix(error.errorCode);
- return new AnalysisError(severity, type, location, message,
+ return new AnalysisError(severity, type, location, message, code,
correction: correction, hasFix: fix);
}
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
index 434ae63..6bdf510 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
@@ -9,9 +9,9 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/provisional/completion/completion_core.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.dart';
export 'package:analysis_server/src/provisional/completion/completion_core.dart'
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
index 9a03a1e..bbf9cb5 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
@@ -4,10 +4,10 @@
library analysis_server.src.provisional.completion.dart.completion_target;
+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/generated/ast.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
int _computeArgIndex(AstNode containingNode, Object entity) {
diff --git a/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart b/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart
index bdc0931..2ab9d6c 100644
--- a/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart
+++ b/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart
@@ -6,9 +6,9 @@
import 'package:analysis_server/src/provisional/edit/utilities/change_builder_core.dart';
import 'package:analysis_server/src/utilities/change_builder_dart.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
/**
diff --git a/pkg/analysis_server/lib/src/provisional/index/index.dart b/pkg/analysis_server/lib/src/provisional/index/index.dart
deleted file mode 100644
index c67feb2..0000000
--- a/pkg/analysis_server/lib/src/provisional/index/index.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Support for client code that extends the analysis server by adding new index
- * contributors.
- *
- * Plugins can register index contributors. The registered contributors will be
- * used to contribute relationships to the index when the analysis of a file has
- * been completed.
- *
- * Typical relationships include things like "this variable is referenced here"
- * or "this method is invoked here". The index is used to improve the
- * performance of operations such as search or building a type hierarchy by
- * pre-computing some of the information needed by those operations.
- *
- * If a plugin wants to contribute information to the index, it should implement
- * the class [IndexContributor] and then register the contributor by including
- * code like the following in the plugin's registerExtensions method:
- *
- * @override
- * void registerExtensions(RegisterExtension registerExtension) {
- * ...
- * registerExtension(
- * INDEX_CONTRIBUTOR_EXTENSION_POINT_ID,
- * new MyIndexContributor());
- * ...
- * }
- */
-library analysis_server.plugin.index.index;
-
-import 'package:analysis_server/src/plugin/server_plugin.dart';
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:plugin/plugin.dart';
-
-/**
- * The identifier of the extension point that allows plugins to register index
- * contributors. The object used as an extension must be an [IndexContributor].
- */
-final String INDEX_CONTRIBUTOR_EXTENSION_POINT_ID = Plugin.join(
- ServerPlugin.UNIQUE_IDENTIFIER,
- ServerPlugin.INDEX_CONTRIBUTOR_EXTENSION_POINT);
diff --git a/pkg/analysis_server/lib/src/provisional/index/index_core.dart b/pkg/analysis_server/lib/src/provisional/index/index_core.dart
deleted file mode 100644
index 6e927a5..0000000
--- a/pkg/analysis_server/lib/src/provisional/index/index_core.dart
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analysis_server.plugin.index.index_core;
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * Return the integer value that corresponds to the given [string]. The value of
- * [string] may be `null`.
- *
- * Clients are not expected to implement this signature. A function of this type
- * is provided by the framework to clients in order to implement the method
- * [IndexableObjectKind.encodeHash].
- */
-typedef int StringToInt(String string);
-
-/**
- * An object that can have a [Relationship] with various [Location]s in a code
- * base. The object is abstractly represented by a [kind] and an [offset] within
- * a file with the [filePath].
- *
- * Clients must ensure that two distinct objects in the same source cannot have
- * the same kind and offset. Failure to do so will make it impossible for
- * clients to identify the model element corresponding to the indexable object.
- *
- * Clients may implement this class when implementing plugins.
- */
-abstract class IndexableObject {
- /**
- * Return the absolute path of the file containing the indexable object.
- */
- String get filePath;
-
- /**
- * Return the kind of this object.
- */
- IndexableObjectKind get kind;
-
- /**
- * Return the offset of the indexable object within its file.
- */
- int get offset;
-}
-
-/**
- * The kind associated with an [IndexableObject].
- *
- * Clients may implement this class when implementing plugins.
- */
-abstract class IndexableObjectKind<T extends IndexableObject> {
- /**
- * The next available index for a newly created kind of indexable object.
- */
- static int _nextIndex = 0;
-
- /**
- * A table mapping indexes to object kinds.
- */
- static Map<int, IndexableObjectKind> _registry =
- new HashMap<int, IndexableObjectKind>();
-
- /**
- * Return the next available index for a newly created kind of indexable
- * object.
- */
- static int get nextIndex => _nextIndex++;
-
- /**
- * Return the unique index for this kind of indexable object. Implementations
- * should invoke [nextIndex] to allocate an index that cannot be used by any
- * other object kind.
- */
- int get index;
-
- /**
- * Return the indexable object of this kind that exists in the given
- * [context], in the source with the given [filePath], and at the given
- * [offset].
- */
- T decode(AnalysisContext context, String filePath, int offset);
-
- /**
- * Returns the hash value that corresponds to the given [indexable].
- *
- * This hash is used to remember buckets with relations of the given
- * [indexable]. Usually the name of the indexable object is encoded
- * using [stringToInt] and mixed with other information to produce the final
- * result.
- *
- * Clients must ensure that the same value is returned for the same object.
- *
- * Returned values must have good selectivity, e.g. if it is possible that
- * there are many different objects with the same name, then additional
- * information should be mixed in, for example the hash of the source that
- * declares the given [indexable].
- *
- * Clients don't have to use name to compute this result, so if an indexable
- * object does not have a name, some other value may be returned, but it still
- * must be always the same for the same object and have good selectivity.
- */
- int encodeHash(StringToInt stringToInt, T indexable);
-
- /**
- * Return the object kind with the given [index].
- */
- static IndexableObjectKind getKind(int index) {
- return _registry[index];
- }
-
- /**
- * Register the given object [kind] so that it can be found by it's unique
- * index. The index of the [kind] must not be changed after it is passed to
- * this method.
- */
- static void register(IndexableObjectKind kind) {
- int index = kind.index;
- if (_registry.containsKey(index)) {
- throw new ArgumentError('duplicate index for kind: $index');
- }
- _registry[index] = kind;
- }
-}
-
-/**
- * An object used to add relationships to the index.
- *
- * Clients may implement this class when implementing plugins.
- */
-abstract class IndexContributor {
- /**
- * Contribute relationships existing in the given [object] to the given
- * index [store] in the given [context].
- */
- void contributeTo(IndexStore store, AnalysisContext context, Object object);
-}
-
-/**
- * An object that stores information about the relationships between locations
- * in a code base.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class IndexStore {
- /**
- * Remove all of the information from the index.
- */
- void clear();
-
- /**
- * Return a future that completes with the locations that have the given
- * [relationship] with the given [indexable] object.
- *
- * For example, if the [indexable] object represents a function and the
- * relationship is the `is-invoked-by` relationship, then the returned
- * locations will be all of the places where the function is invoked.
- */
- Future<List<Location>> getRelationships(
- IndexableObject indexable, Relationship relationship);
-
- /**
- * Record that the given [indexable] object and [location] have the given
- * [relationship].
- *
- * For example, if the [relationship] is the `is-invoked-by` relationship,
- * then the [indexable] object would be the function being invoked and
- * [location] would be the point at which it is invoked. Each indexable object
- * can have the same relationship with multiple locations. In other words, if
- * the following code were executed
- *
- * recordRelationship(indexable, isReferencedBy, location1);
- * recordRelationship(indexable, isReferencedBy, location2);
- *
- * (where `location1 != location2`) then both relationships would be
- * maintained in the index and the result of executing
- *
- * getRelationship(indexable, isReferencedBy);
- *
- * would be a list containing both `location1` and `location2`.
- */
- void recordRelationship(
- IndexableObject indexable, Relationship relationship, Location location);
-
- /**
- * Remove from the index all of the information associated with the given
- * [context].
- *
- * This method should be invoked when the [context] is disposed.
- */
- void removeContext(AnalysisContext context);
-
- /**
- * Remove from the index all of the information associated with indexable
- * objects or locations in the given [source]. This includes relationships
- * between an indexable object in [source] and any other locations, as well as
- * relationships between any other indexable objects and locations within
- * the [source].
- *
- * This method should be invoked when [source] is no longer part of the given
- * [context].
- */
- void removeSource(AnalysisContext context, Source source);
-
- /**
- * Remove from the index all of the information associated with indexable
- * objects or locations in the given sources. This includes relationships
- * between an indexable object in the given sources and any other locations,
- * as well as relationships between any other indexable objects and a location
- * within the given sources.
- *
- * This method should be invoked when the sources described by the given
- * [container] are no longer part of the given [context].
- */
- void removeSources(AnalysisContext context, SourceContainer container);
-}
-
-/**
- * Instances of the class [Location] represent a location related to an
- * indexable object.
- *
- * The location is expressed as an offset and length, but the offset is relative
- * to the source containing the indexable object rather than the start of the
- * indexable object within that source.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Location {
- /**
- * An empty list of locations.
- */
- static const List<Location> EMPTY_LIST = const <Location>[];
-
- /**
- * Return the indexable object containing this location.
- */
- IndexableObject get indexable;
-
- /**
- * Return `true` if this location is a qualified reference.
- */
- bool get isQualified;
-
- /**
- * Return `true` if this location is a resolved reference.
- */
- bool get isResolved;
-
- /**
- * Return the length of this location.
- */
- int get length;
-
- /**
- * Return the offset of this location within the source containing the
- * indexable object.
- */
- int get offset;
-}
-
-/**
- * A relationship between an indexable object and a location. Relationships are
- * identified by a globally unique identifier.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Relationship {
- /**
- * Return a relationship that has the given [identifier]. If the relationship
- * has already been created, then it will be returned, otherwise a new
- * relationship will be created
- */
- factory Relationship(String identifier) =>
- RelationshipImpl.getRelationship(identifier);
-}
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index c60d4a5..4a0e1b7 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -9,14 +9,11 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
-import 'package:analysis_server/src/provisional/index/index_core.dart';
import 'package:analysis_server/src/search/element_references.dart';
import 'package:analysis_server/src/search/type_hierarchy.dart';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/indexable_file.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
/**
* Instances of the class [SearchDomainHandler] implement a [RequestHandler]
@@ -72,36 +69,14 @@
}).where((Element element) {
return element != null;
}).toList();
- // prepare referenced file
- String referencedFile = _getFileReferencedAt(params.file, params.offset);
// respond
String searchId = (_nextSearchId++).toString();
var result = new protocol.SearchFindElementReferencesResult();
if (elements.isNotEmpty) {
result.id = searchId;
result.element = protocol.convertElement(elements.first);
- } else if (referencedFile != null) {
- result.id = searchId;
- result.element =
- new protocol.Element(protocol.ElementKind.FILE, referencedFile, 0);
}
_sendSearchResult(request, result);
- // search for file
- if (referencedFile != null) {
- List<Location> locations = await index.getRelationships(
- new IndexableFile(referencedFile), IndexConstants.IS_REFERENCED_BY);
- List<protocol.SearchResult> results = <protocol.SearchResult>[];
- for (Location location in locations) {
- IndexableFile locationFile = location.indexable;
- results.add(new protocol.SearchResult(
- new protocol.Location(
- locationFile.path, location.offset, location.length, -1, -1),
- protocol.SearchResultKind.REFERENCE,
- false,
- []));
- }
- _sendSearchNotification(searchId, elements.isEmpty, results);
- }
// search elements
elements.forEach((Element element) async {
var computer = new ElementReferencesComputer(searchEngine);
@@ -223,31 +198,6 @@
return null;
}
- /**
- * Return the full path of the file referenced in the given [file] at the
- * given [offset], maybe `null`.
- */
- String _getFileReferencedAt(String file, int offset) {
- List<AstNode> nodes = server.getNodesAtOffset(file, offset);
- if (nodes.length == 1) {
- AstNode node = nodes.single;
- if (node is SimpleIdentifier &&
- node.parent is LibraryIdentifier &&
- node.parent.parent is LibraryDirective) {
- LibraryDirective libraryDirective = node.parent.parent;
- return libraryDirective?.element?.source?.fullName;
- }
- if (node is StringLiteral && node.parent is UriBasedDirective) {
- UriBasedDirective uriBasedDirective = node.parent;
- return uriBasedDirective.source?.fullName;
- }
- if (node is UriBasedDirective) {
- return node.source?.fullName;
- }
- }
- return null;
- }
-
void _sendSearchNotification(
String searchId, bool isLast, Iterable<protocol.SearchResult> results) {
server.sendNotification(
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 4f9e472..7db68b6 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -343,7 +343,7 @@
// TODO (danrubel) Remove this workaround
// once the underlying VM and dart:io issue has been fixed.
if (results[INTERNAL_DELAY_FREQUENCY] != null) {
- AnalysisServer.performOperationDelayFreqency =
+ AnalysisServer.performOperationDelayFrequency =
int.parse(results[INTERNAL_DELAY_FREQUENCY], onError: (_) => 0);
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index 5036e08..6071fae 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -9,8 +9,8 @@
import 'package:analysis_server/src/protocol_server.dart'
hide Element, ElementKind;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
/**
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index 26437e2..8b1d7a2 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -11,7 +11,7 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
/**
* A contributor for calculating `completion.getSuggestions` request results
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
index 6e8049b..f06cc07 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
@@ -13,9 +13,10 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/task/dart.dart';
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index b56bd9f..42ae3df 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -25,7 +25,7 @@
import 'package:analyzer/src/context/context.dart'
show AnalysisFutureHelper, AnalysisContextImpl;
import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
index 3c16a7d..43514fb 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
@@ -10,7 +10,7 @@
hide Element, ElementKind;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
/**
* A contributor for calculating invocation / access suggestions
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
index abed735..6a8c367 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
@@ -10,12 +10,30 @@
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/optype.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/resolver.dart';
import '../../../protocol_server.dart'
show CompletionSuggestion, CompletionSuggestionKind;
+List<String> hiddenNamesIn(ImportElement importElem) {
+ for (NamespaceCombinator combinator in importElem.combinators) {
+ if (combinator is HideElementCombinator) {
+ return combinator.hiddenNames;
+ }
+ }
+ return null;
+}
+
+List<String> showNamesIn(ImportElement importElem) {
+ for (NamespaceCombinator combinator in importElem.combinators) {
+ if (combinator is ShowElementCombinator) {
+ return combinator.shownNames;
+ }
+ }
+ return null;
+}
+
/**
* A contributor for calculating suggestions for imported top level members.
*/
@@ -69,21 +87,3 @@
return visitor.suggestions;
}
}
-
-List<String> showNamesIn(ImportElement importElem) {
- for (NamespaceCombinator combinator in importElem.combinators) {
- if (combinator is ShowElementCombinator) {
- return combinator.shownNames;
- }
- }
- return null;
-}
-
-List<String> hiddenNamesIn(ImportElement importElem) {
- for (NamespaceCombinator combinator in importElem.combinators) {
- if (combinator is HideElementCombinator) {
- return combinator.hiddenNames;
- }
- }
- return null;
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
index bf1633e..fed6a7b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
@@ -11,13 +11,40 @@
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/optype.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
import '../../../protocol_server.dart'
show CompletionSuggestion, CompletionSuggestionKind;
/**
+ * Return the class containing the target
+ * or `null` if the target is in a static method or field
+ * or not in a class.
+ */
+ClassDeclaration _enclosingClass(CompletionTarget target) {
+ AstNode node = target.containingNode;
+ while (node != null) {
+ if (node is ClassDeclaration) {
+ return node;
+ }
+ if (node is MethodDeclaration) {
+ if (node.isStatic) {
+ return null;
+ }
+ }
+ if (node is FieldDeclaration) {
+ if (node.isStatic) {
+ return null;
+ }
+ }
+ node = node.parent;
+ }
+ return null;
+}
+
+/**
* A contributor for calculating suggestions for inherited references.
*/
class InheritedReferenceContributor extends DartCompletionContributor
@@ -76,29 +103,3 @@
return suggestions;
}
}
-
-/**
- * Return the class containing the target
- * or `null` if the target is in a static method or field
- * or not in a class.
- */
-ClassDeclaration _enclosingClass(CompletionTarget target) {
- AstNode node = target.containingNode;
- while (node != null) {
- if (node is ClassDeclaration) {
- return node;
- }
- if (node is MethodDeclaration) {
- if (node.isStatic) {
- return null;
- }
- }
- if (node is FieldDeclaration) {
- if (node.isStatic) {
- return null;
- }
- }
- node = node.parent;
- }
- return null;
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 6008fe7..807a02e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -9,9 +9,10 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
const ASYNC = 'async';
const ASYNC_STAR = 'async*';
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
index b5bae6c..9688be3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
@@ -14,9 +14,9 @@
import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart'
show LocalDeclarationVisitor;
import 'package:analysis_server/src/services/completion/dart/optype.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import '../../../protocol_server.dart'
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
index 118103f..4587864 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -8,8 +8,8 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import '../../../protocol_server.dart'
show CompletionSuggestion, CompletionSuggestionKind;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
index c05a215..b9fea93 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
@@ -15,10 +15,10 @@
show LocalDeclarationVisitor;
import 'package:analysis_server/src/services/completion/dart/optype.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import '../../../protocol_server.dart'
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_declaration_visitor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_declaration_visitor.dart
index 586eac2..63c291e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_declaration_visitor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_declaration_visitor.dart
@@ -6,7 +6,8 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
/**
* `LocalDeclarationCollector` visits an [AstNode] and its parent recursively
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index 9b36935..7f04c6b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -11,42 +11,14 @@
import 'package:analysis_server/src/services/completion/dart/optype.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
show createSuggestion, ElementSuggestionBuilder;
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
import '../../../protocol_server.dart'
show CompletionSuggestion, CompletionSuggestionKind;
/**
- * A contributor for calculating suggestions for top level members
- * in the library in which the completion is requested
- * but outside the file in which the completion is requested.
- */
-class LocalLibraryContributor extends DartCompletionContributor {
- @override
- Future<List<CompletionSuggestion>> computeSuggestions(
- DartCompletionRequest request) async {
- if (!request.includeIdentifiers) {
- return EMPTY_LIST;
- }
-
- List<CompilationUnitElement> libraryUnits = await request.resolveUnits();
- if (libraryUnits == null) {
- return EMPTY_LIST;
- }
-
- OpType optype = (request as DartCompletionRequestImpl).opType;
- LibraryElementSuggestionBuilder visitor =
- new LibraryElementSuggestionBuilder(request, optype);
- for (CompilationUnitElement unit in libraryUnits) {
- if (unit != null && unit.source != request.source) {
- unit.accept(visitor);
- }
- }
- return visitor.suggestions;
- }
-}
-
-/**
* A visitor for building suggestions based upon the elements defined by
* a source file contained in the same library but not the same as
* the source in which the completions are being requested.
@@ -176,3 +148,33 @@
}
}
}
+
+/**
+ * A contributor for calculating suggestions for top level members
+ * in the library in which the completion is requested
+ * but outside the file in which the completion is requested.
+ */
+class LocalLibraryContributor extends DartCompletionContributor {
+ @override
+ Future<List<CompletionSuggestion>> computeSuggestions(
+ DartCompletionRequest request) async {
+ if (!request.includeIdentifiers) {
+ return EMPTY_LIST;
+ }
+
+ List<CompilationUnitElement> libraryUnits = await request.resolveUnits();
+ if (libraryUnits == null) {
+ return EMPTY_LIST;
+ }
+
+ OpType optype = (request as DartCompletionRequestImpl).opType;
+ LibraryElementSuggestionBuilder visitor =
+ new LibraryElementSuggestionBuilder(request, optype);
+ for (CompilationUnitElement unit in libraryUnits) {
+ if (unit != null && unit.source != request.source) {
+ unit.accept(visitor);
+ }
+ }
+ return visitor.suggestions;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
index 661f89a..6c20b0b9 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -15,9 +15,9 @@
show LocalDeclarationVisitor;
import 'package:analysis_server/src/services/completion/dart/optype.dart';
import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
index 760274e..3314403 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
@@ -9,9 +9,9 @@
import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
/**
* A contributor for calculating named constructor suggestions
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
index 71c1bfd..e61845e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
@@ -6,9 +6,10 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
/**
* An [AstVisitor] for determining whether top level suggestions or invocation
@@ -83,7 +84,8 @@
/**
* Indicate whether only type names should be suggested
*/
- bool get includeOnlyTypeNameSuggestions => includeTypeNameSuggestions &&
+ bool get includeOnlyTypeNameSuggestions =>
+ includeTypeNameSuggestions &&
!includeReturnValueSuggestions &&
!includeVoidReturnSuggestions;
}
@@ -136,7 +138,7 @@
}
}
-@override
+ @override
void visitAssertStatement(AssertStatement node) {
if (identical(entity, node.condition)) {
optype.includeReturnValueSuggestions = true;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index e61ebbe..d950448 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -13,8 +13,8 @@
import 'package:analysis_server/src/provisional/completion/completion_core.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
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 3ed05b3..d7687f9 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
@@ -8,9 +8,9 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
-import 'package:analyzer/src/generated/ast.dart';
import '../../../protocol_server.dart'
show CompletionSuggestion, CompletionSuggestionKind;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 7a0f760..cd9dfc0 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -10,9 +10,9 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart';
import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
import '../../../protocol_server.dart'
show CompletionSuggestion, CompletionSuggestionKind;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
index 7e849b1..949ec9c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
@@ -8,8 +8,9 @@
import 'dart:core' hide Resource;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:path/path.dart' show posix;
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 b5a7ea2..fbbd9a8 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -17,11 +17,13 @@
import 'package:analysis_server/src/services/correction/statement_analyzer.dart';
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 3fdd5f9..dbf0da7 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -24,15 +24,16 @@
import 'package:analysis_server/src/services/correction/strings.dart';
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/ast/utilities.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/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_core.dart';
@@ -428,7 +429,11 @@
.takeWhile((p) => p.parameterKind == ParameterKind.REQUIRED);
Iterable<ParameterElement> optionalParameters = parameters
.skipWhile((p) => p.parameterKind == ParameterKind.REQUIRED);
+ // prepare the argument to add a new parameter for
int numRequired = requiredParameters.length;
+ if (numRequired >= arguments.length) {
+ return;
+ }
Expression argument = arguments[numRequired];
// prepare target
int targetOffset;
@@ -966,7 +971,7 @@
// maybe static
if (target is Identifier) {
Identifier targetIdentifier = target;
- Element targetElement = targetIdentifier.staticElement;
+ Element targetElement = targetIdentifier.bestElement;
if (targetElement == null) {
return;
}
@@ -1102,7 +1107,7 @@
// maybe static
if (target is Identifier) {
Identifier targetIdentifier = target;
- Element targetElement = targetIdentifier.staticElement;
+ Element targetElement = targetIdentifier.bestElement;
staticModifier = targetElement.kind == ElementKind.CLASS;
}
} else {
@@ -1524,7 +1529,7 @@
}
// prepare LibraryElement
LibraryElement libraryElement =
- context.getResult(librarySource, LIBRARY_ELEMENT8);
+ context.getResult(librarySource, LIBRARY_ELEMENT4);
if (libraryElement == null) {
continue;
}
diff --git a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
index 1c80559..c28dae5 100644
--- a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
+++ b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
@@ -5,9 +5,9 @@
library services.src.correction.name_suggestion;
import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
List<String> _KNOWN_METHOD_NAME_PREFIXES = ['get', 'is', 'to'];
diff --git a/pkg/analysis_server/lib/src/services/correction/namespace.dart b/pkg/analysis_server/lib/src/services/correction/namespace.dart
index f1086fc..9a83cb2 100644
--- a/pkg/analysis_server/lib/src/services/correction/namespace.dart
+++ b/pkg/analysis_server/lib/src/services/correction/namespace.dart
@@ -4,8 +4,8 @@
library services.src.correction.namespace;
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/resolver.dart';
/**
diff --git a/pkg/analysis_server/lib/src/services/correction/organize_directives.dart b/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
index 9d9faa1..5d8a96db 100644
--- a/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
+++ b/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
@@ -8,7 +8,7 @@
hide AnalysisError, Element;
import 'package:analysis_server/src/services/correction/strings.dart';
import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/error.dart';
/**
diff --git a/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart
index 42addf6..a4cc1a9 100644
--- a/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart
@@ -5,7 +5,8 @@
library services.src.correction.selection_analyzer;
import 'package:analysis_server/src/services/correction/source_range.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/generated/source.dart';
/**
diff --git a/pkg/analysis_server/lib/src/services/correction/sort_members.dart b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
index 49f104b..f1d788c 100644
--- a/pkg/analysis_server/lib/src/services/correction/sort_members.dart
+++ b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
@@ -6,8 +6,8 @@
import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
/**
* Sorter for unit/class members.
diff --git a/pkg/analysis_server/lib/src/services/correction/source_range.dart b/pkg/analysis_server/lib/src/services/correction/source_range.dart
index 32c98b9..4440a5c 100644
--- a/pkg/analysis_server/lib/src/services/correction/source_range.dart
+++ b/pkg/analysis_server/lib/src/services/correction/source_range.dart
@@ -4,9 +4,9 @@
library services.src.correction.source_range_factory;
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
index 2ec69eb..974f9db 100644
--- a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
@@ -9,11 +9,11 @@
import 'package:analysis_server/src/services/correction/source_range.dart';
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/correction/util.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.dart';
/**
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 65c12c6..1603ef3 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -12,13 +12,15 @@
show doSourceChange_addElementEdit;
import 'package:analysis_server/src/services/correction/source_range.dart';
import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/index/index.dart b/pkg/analysis_server/lib/src/services/index/index.dart
index d86b322..5e866bc 100644
--- a/pkg/analysis_server/lib/src/services/index/index.dart
+++ b/pkg/analysis_server/lib/src/services/index/index.dart
@@ -1,255 +1,167 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// 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 services.index;
-
import 'dart:async';
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analysis_server/src/services/index/indexable_element.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/index_unit.dart';
+import 'package:collection/collection.dart';
/**
- * A filter for [Element] names.
+ * Return a new [Index] instance that keeps information in memory.
*/
-typedef bool ElementNameFilter(String name);
-
-/**
- * The interface [Index] defines the behavior of objects that maintain an index
- * storing relations between indexable objects.
- *
- * Any modification operations are executed before any read operation.
- * There is no guarantee about the order in which the [Future]s for read
- * operations will complete.
- */
-abstract class Index implements IndexStore {
- /**
- * Set the index contributors used by this index to the given list of
- * [contributors].
- */
- void set contributors(List<IndexContributor> contributors);
-
- /**
- * Answers index statistics.
- */
- String get statistics;
-
- /**
- * Returns top-level [Element]s whose names satisfy to [nameFilter].
- */
- List<Element> getTopLevelDeclarations(ElementNameFilter nameFilter);
-
- /**
- * Processes the given [object] in order to record the relationships.
- *
- * [context] - the [AnalysisContext] in which the [object] being indexed.
- * [object] - the object being indexed.
- */
- void index(AnalysisContext context, Object object);
-
- /**
- * Starts the index.
- * Should be called before any other method.
- */
- void run();
-
- /**
- * Stops the index.
- * After calling this method operations may not be executed.
- */
- void stop();
+Index createMemoryIndex() {
+ return new Index._();
}
/**
- * An [Element] which is used to index references to the name without specifying
- * a concrete kind of this name - field, method or something else.
+ * Return the index of the first occurrence of the [value] in the [sortedList],
+ * or `-1` if the [value] is not in the list.
*/
-class IndexableName implements IndexableObject {
- /**
- * The name to be indexed.
- */
- final String name;
-
- /**
- * Initialize a newly created indexable name to represent the given [name].
- */
- IndexableName(this.name);
-
- @override
- String get filePath => null;
-
- @override
- IndexableNameKind get kind => IndexableNameKind.INSTANCE;
-
- @override
- int get offset {
+int _findFirstOccurrence(List<int> sortedList, int value) {
+ // Find an occurrence.
+ int i = binarySearch(sortedList, value);
+ if (i == -1) {
return -1;
}
-
- @override
- bool operator ==(Object object) =>
- object is IndexableName && object.name == name;
-
- @override
- String toString() => name;
+ // Find the first occurrence.
+ while (i > 0 && sortedList[i - 1] == value) {
+ i--;
+ }
+ return i;
}
/**
- * The kind of an indexable name.
+ * Interface for storing and requesting relations.
*/
-class IndexableNameKind implements IndexableObjectKind<IndexableName> {
- /**
- * The unique instance of this class.
- */
- static final IndexableNameKind INSTANCE =
- new IndexableNameKind._(IndexableObjectKind.nextIndex);
+class Index {
+ final Map<AnalysisContext, _ContextIndex> _contextIndexMap =
+ <AnalysisContext, _ContextIndex>{};
+
+ Index._();
/**
- * The index uniquely identifying this kind.
+ * Complete with a list of locations where elements of the given [kind] with
+ * names satisfying the given [regExp] are defined.
*/
- final int index;
-
- /**
- * Initialize a newly created kind to have the given [index].
- */
- IndexableNameKind._(this.index) {
- IndexableObjectKind.register(this);
+ Future<List<Location>> getDefinedNames(RegExp regExp, IndexNameKind kind) {
+ return _mergeLocations((_ContextIndex index) {
+ return index.getDefinedNames(regExp, kind);
+ });
}
- @override
- IndexableName decode(AnalysisContext context, String filePath, int offset) {
- throw new UnsupportedError(
- 'Indexable names cannot be decoded through their kind');
+ /**
+ * Complete with a list of locations where the given [element] has relation
+ * of the given [kind].
+ */
+ Future<List<Location>> getRelations(Element element, IndexRelationKind kind) {
+ return _mergeLocations((_ContextIndex index) {
+ return index.getRelations(element, kind);
+ });
}
- @override
- int encodeHash(StringToInt stringToInt, IndexableName indexable) {
- String name = indexable.name;
- return stringToInt(name);
+ /**
+ * Complete with a list of locations where a class members with the given
+ * [name] is referenced with a qualifier, but is not resolved.
+ */
+ Future<List<Location>> getUnresolvedMemberReferences(String name) {
+ return _mergeLocations((_ContextIndex index) {
+ return index.getUnresolvedMemberReferences(name);
+ });
+ }
+
+ /**
+ * Index the given fully resolved [unit].
+ */
+ void indexUnit(CompilationUnit unit) {
+ if (unit == null || unit.element == null) {
+ return;
+ }
+ AnalysisContext context = unit.element.context;
+ _getContextIndex(context).indexUnit(unit);
+ }
+
+ /**
+ * Remove all index information for the given [context].
+ */
+ void removeContext(AnalysisContext context) {
+ _contextIndexMap.remove(context);
+ }
+
+ /**
+ * Remove index information about the unit in the given [context].
+ */
+ void removeUnit(
+ AnalysisContext context, Source librarySource, Source unitSource) {
+ _contextIndexMap[context]?.removeUnit(librarySource, unitSource);
+ }
+
+ /**
+ * Notify the index that the client is going to stop using it.
+ */
+ void stop() {}
+
+ /**
+ * Return the [_ContextIndex] instance for the given [context].
+ */
+ _ContextIndex _getContextIndex(AnalysisContext context) {
+ return _contextIndexMap.putIfAbsent(context, () {
+ return new _ContextIndex(context);
+ });
+ }
+
+ /**
+ * Complete with a list of all results returned by the [callback] for every
+ * context specific index.
+ */
+ Future<List<Location>> _mergeLocations(
+ Future<List<Location>> callback(_ContextIndex index)) async {
+ List<Location> locations = <Location>[];
+ for (_ContextIndex index in _contextIndexMap.values) {
+ List<Location> contextLocations = await callback(index);
+ locations.addAll(contextLocations);
+ }
+ return locations;
}
}
/**
- * Constants used when populating and accessing the index.
- */
-class IndexConstants {
- /**
- * Left: the Universe or a Library.
- * Defines an Element.
- * Right: an Element declaration.
- */
- static final RelationshipImpl DEFINES =
- RelationshipImpl.getRelationship("defines");
-
- /**
- * Left: class.
- * Has ancestor (extended or implemented, directly or indirectly).
- * Right: other class declaration.
- */
- static final RelationshipImpl HAS_ANCESTOR =
- RelationshipImpl.getRelationship("has-ancestor");
-
- /**
- * Left: class.
- * Is extended by.
- * Right: other class declaration.
- */
- static final RelationshipImpl IS_EXTENDED_BY =
- RelationshipImpl.getRelationship("is-extended-by");
-
- /**
- * Left: class.
- * Is implemented by.
- * Right: other class declaration.
- */
- static final RelationshipImpl IS_IMPLEMENTED_BY =
- RelationshipImpl.getRelationship("is-implemented-by");
-
- /**
- * Left: class.
- * Is mixed into.
- * Right: other class declaration.
- */
- static final RelationshipImpl IS_MIXED_IN_BY =
- RelationshipImpl.getRelationship("is-mixed-in-by");
-
- /**
- * Left: local variable, parameter.
- * Is read at.
- * Right: location.
- */
- static final RelationshipImpl IS_READ_BY =
- RelationshipImpl.getRelationship("is-read-by");
-
- /**
- * Left: local variable, parameter.
- * Is both read and written at.
- * Right: location.
- */
- static final RelationshipImpl IS_READ_WRITTEN_BY =
- RelationshipImpl.getRelationship("is-read-written-by");
-
- /**
- * Left: local variable, parameter.
- * Is written at.
- * Right: location.
- */
- static final RelationshipImpl IS_WRITTEN_BY =
- RelationshipImpl.getRelationship("is-written-by");
-
- /**
- * Left: function, method, variable, getter.
- * Is invoked at.
- * Right: location.
- */
- static final RelationshipImpl IS_INVOKED_BY =
- RelationshipImpl.getRelationship("is-invoked-by");
-
- /**
- * Left: function, function type, class, field, method.
- * Is referenced (and not invoked, read/written) at.
- * Right: location.
- */
- static final RelationshipImpl IS_REFERENCED_BY =
- RelationshipImpl.getRelationship("is-referenced-by");
-
- /**
- * Left: name element.
- * Is defined by.
- * Right: concrete element declaration.
- */
- static final RelationshipImpl NAME_IS_DEFINED_BY =
- RelationshipImpl.getRelationship("name-is-defined-by");
-
- IndexConstants._();
-}
-
-/**
- * Instances of the class [LocationImpl] represent a location related to an
- * element.
+ * Information about location of a single relation in the index.
*
- * The location is expressed as an offset and length, but the offset is relative
- * to the resource containing the element rather than the start of the element
- * within that resource.
+ * The location is expressed as a library specific unit containing the index
+ * relation, offset within this [Source] and length.
+ *
+ * Clients may not extend, implement or mix-in this class.
*/
-class LocationImpl implements Location {
- static const int _FLAG_QUALIFIED = 1 << 0;
- static const int _FLAG_RESOLVED = 1 << 1;
-
+class Location {
/**
- * An empty array of locations.
+ * The [AnalysisContext] containing this location.
*/
- static const List<LocationImpl> EMPTY_LIST = const <LocationImpl>[];
+ final AnalysisContext context;
/**
- * The indexable object containing this location.
+ * The URI of the source of the library containing this location.
*/
- final IndexableObject indexable;
+ final String libraryUri;
/**
- * The offset of this location within the resource containing the element.
+ * The URI of the source of the unit containing this location.
+ */
+ final String unitUri;
+
+ /**
+ * The kind of usage at this location.
+ */
+ final IndexRelationKind kind;
+
+ /**
+ * The offset of this location within the [unitUri].
*/
final int offset;
@@ -259,113 +171,389 @@
final int length;
/**
- * The flags of this location.
+ * Is `true` if this location is qualified.
*/
- int _flags;
+ final bool isQualified;
/**
- * Initializes a newly created location to be relative to the given
- * [indexable] object at the given [offset] with the given [length].
+ * Is `true` if this location is resolved.
*/
- LocationImpl(this.indexable, this.offset, this.length,
- {bool isQualified: false, bool isResolved: true}) {
- if (indexable == null) {
- throw new ArgumentError("indexable object cannot be null");
- }
- _flags = 0;
- if (isQualified) {
- _flags |= _FLAG_QUALIFIED;
- }
- if (isResolved) {
- _flags |= _FLAG_RESOLVED;
- }
+ final bool isResolved;
+
+ Location(this.context, this.libraryUri, this.unitUri, this.kind, this.offset,
+ this.length, this.isQualified, this.isResolved);
+
+ @override
+ String toString() => 'Location{librarySourceUri: $libraryUri, '
+ 'unitSourceUri: $unitUri, offset: $offset, length: $length, '
+ 'isQualified: $isQualified}, isResolved: $isResolved}';
+}
+
+/**
+ * Opaque identifier of a [PackageIndex].
+ */
+abstract class PackageIndexId {}
+
+/**
+ * Storage of [PackageIndex] objects.
+ */
+abstract class PackageIndexStore {
+ /**
+ * Complete with identifiers of all [PackageIndex] objects.
+ */
+ Future<Iterable<PackageIndexId>> getIds();
+
+ /**
+ * Complete with the [PackageIndex] with the given [id].
+ */
+ Future<PackageIndex> getIndex(PackageIndexId id);
+
+ /**
+ * Put the given [indexBuilder] into the store.
+ */
+ void putIndex(String unitLibraryUri, String unitUnitUri,
+ PackageIndexBuilder indexBuilder);
+}
+
+/**
+ * The [AnalysisContext] specific index.
+ */
+class _ContextIndex {
+ final AnalysisContext context;
+ final Map<String, PackageIndex> indexMap = <String, PackageIndex>{};
+
+ _ContextIndex(this.context);
+
+ /**
+ * Complete with a list of locations where elements of the given [kind] with
+ * names satisfying the given [regExp] are defined.
+ */
+ Future<List<Location>> getDefinedNames(
+ RegExp regExp, IndexNameKind kind) async {
+ return _mergeLocations((_PackageIndexRequester requester) {
+ return requester.getDefinedNames(context, regExp, kind);
+ });
}
/**
- * The element containing this location.
+ * Complete with a list of locations where the given [element] has relation
+ * of the given [kind].
*/
- @deprecated
- Element get element {
- if (indexable is IndexableElement) {
- return (indexable as IndexableElement).element;
- }
- return null;
+ Future<List<Location>> getRelations(Element element, IndexRelationKind kind) {
+ return _mergeLocations((_PackageIndexRequester requester) {
+ return requester.getRelations(context, element, kind);
+ });
}
- @override
- bool get isQualified => (_flags & _FLAG_QUALIFIED) != 0;
+ /**
+ * Complete with a list of locations where a class members with the given
+ * [name] is referenced with a qualifier, but is not resolved.
+ */
+ Future<List<Location>> getUnresolvedMemberReferences(String name) async {
+ return _mergeLocations((_PackageIndexRequester requester) {
+ return requester.getUnresolvedMemberReferences(context, name);
+ });
+ }
- @override
- bool get isResolved => (_flags & _FLAG_RESOLVED) != 0;
+ /**
+ * Index the given fully resolved [unit].
+ */
+ void indexUnit(CompilationUnit unit) {
+ // Index the unit.
+ PackageIndexAssembler assembler = new PackageIndexAssembler();
+ assembler.index(unit);
+ PackageIndexBuilder indexBuilder = assembler.assemble();
+ // Put the index into the map.
+ List<int> indexBytes = indexBuilder.toBuffer();
+ PackageIndex index = new PackageIndex.fromBuffer(indexBytes);
+ String key = _getUnitKeyForElement(unit.element);
+ indexMap[key] = index;
+ }
- @override
- String toString() {
- String flagsStr = '';
- if (isQualified) {
- flagsStr += ' qualified';
+ /**
+ * Remove index information about the unit.
+ */
+ void removeUnit(Source librarySource, Source unitSource) {
+ String key = _getUnitKeyForSource(librarySource, unitSource);
+ indexMap.remove(key);
+ }
+
+ String _getUnitKeyForElement(CompilationUnitElement unitElement) {
+ Source librarySource = unitElement.library.source;
+ Source unitSource = unitElement.source;
+ return _getUnitKeyForSource(librarySource, unitSource);
+ }
+
+ String _getUnitKeyForSource(Source librarySource, Source unitSource) {
+ String unitLibraryUri = librarySource.uri.toString();
+ String unitUnitUri = unitSource.uri.toString();
+ return '$unitLibraryUri;$unitUnitUri';
+ }
+
+ Future<List<Location>> _mergeLocations(
+ List<Location> callback(_PackageIndexRequester requester)) async {
+ List<Location> locations = <Location>[];
+ for (PackageIndex index in indexMap.values) {
+ _PackageIndexRequester requester = new _PackageIndexRequester(index);
+ List<Location> indexLocations = callback(requester);
+ locations.addAll(indexLocations);
}
- if (isResolved) {
- flagsStr += ' resolved';
- }
- return '[$offset - ${offset + length}) $flagsStr in $indexable';
+ return locations;
}
}
/**
- * A [LocationImpl] with attached data.
+ * Helper for requesting information from a single [PackageIndex].
*/
-class LocationWithData<D> extends LocationImpl {
- final D data;
+class _PackageIndexRequester {
+ final PackageIndex index;
- LocationWithData(LocationImpl location, this.data)
- : super(location.indexable, location.offset, location.length);
+ _PackageIndexRequester(this.index);
+
+ /**
+ * Return the [element]'s identifier in the [index] or `-1` if the
+ * [element] is not referenced in the [index].
+ */
+ int findElementId(Element element) {
+ // Find the id of the element's unit.
+ int unitId = getUnitId(element);
+ if (unitId == -1) {
+ return -1;
+ }
+ // Prepare information about the element.
+ ElementInfo info = PackageIndexAssembler.newElementInfo(unitId, element);
+ // Find the first occurrence of an element with the same offset.
+ int elementId = _findFirstOccurrence(index.elementOffsets, info.offset);
+ if (elementId == -1) {
+ return -1;
+ }
+ // Try to find the element id using offset, unit and kind.
+ for (;
+ elementId < index.elementOffsets.length &&
+ index.elementOffsets[elementId] == info.offset;
+ elementId++) {
+ if (index.elementUnits[elementId] == unitId &&
+ index.elementKinds[elementId] == info.kind) {
+ return elementId;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Complete with a list of locations where elements of the given [kind] with
+ * names satisfying the given [regExp] are defined.
+ */
+ List<Location> getDefinedNames(
+ AnalysisContext context, RegExp regExp, IndexNameKind kind) {
+ List<Location> locations = <Location>[];
+ for (UnitIndex unitIndex in index.units) {
+ _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex);
+ List<Location> unitLocations =
+ requester.getDefinedNames(context, regExp, kind);
+ locations.addAll(unitLocations);
+ }
+ return locations;
+ }
+
+ /**
+ * Complete with a list of locations where the given [element] has relation
+ * of the given [kind].
+ */
+ List<Location> getRelations(
+ AnalysisContext context, Element element, IndexRelationKind kind) {
+ int elementId = findElementId(element);
+ if (elementId == -1) {
+ return const <Location>[];
+ }
+ List<Location> locations = <Location>[];
+ for (UnitIndex unitIndex in index.units) {
+ _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex);
+ List<Location> unitLocations =
+ requester.getRelations(context, elementId, kind);
+ locations.addAll(unitLocations);
+ }
+ return locations;
+ }
+
+ /**
+ * Return the identifier of [str] in the [index] or `-1` if [str] is not used
+ * in the [index].
+ */
+ int getStringId(String str) {
+ return binarySearch(index.strings, str);
+ }
+
+ /**
+ * Return the identifier of the [CompilationUnitElement] containing the
+ * [element] in the [index] or `-1` if not found.
+ */
+ int getUnitId(Element element) {
+ CompilationUnitElement unitElement =
+ PackageIndexAssembler.getUnitElement(element);
+ int libraryUriId = getUriId(unitElement.library.source.uri);
+ if (libraryUriId == -1) {
+ return -1;
+ }
+ int unitUriId = getUriId(unitElement.source.uri);
+ if (unitUriId == -1) {
+ return -1;
+ }
+ for (int i = 0; i < index.unitLibraryUris.length; i++) {
+ if (index.unitLibraryUris[i] == libraryUriId &&
+ index.unitUnitUris[i] == unitUriId) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Return the URI of the library source of the library specific [unit].
+ */
+ String getUnitLibraryUri(int unit) {
+ int id = index.unitLibraryUris[unit];
+ return index.strings[id];
+ }
+
+ /**
+ * Return the URI of the unit source of the library specific [unit].
+ */
+ String getUnitUnitUri(int unit) {
+ int id = index.unitUnitUris[unit];
+ return index.strings[id];
+ }
+
+ /**
+ * Complete with a list of locations where a class members with the given
+ * [name] is referenced with a qualifier, but is not resolved.
+ */
+ List<Location> getUnresolvedMemberReferences(
+ AnalysisContext context, String name) {
+ List<Location> locations = <Location>[];
+ for (UnitIndex unitIndex in index.units) {
+ _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex);
+ List<Location> unitLocations =
+ requester.getUnresolvedMemberReferences(context, name);
+ locations.addAll(unitLocations);
+ }
+ return locations;
+ }
+
+ /**
+ * Return the identifier of the [uri] in the [index] or `-1` if the [uri] is
+ * not used in the [index].
+ */
+ int getUriId(Uri uri) {
+ String str = uri.toString();
+ return getStringId(str);
+ }
}
/**
- * Relationship between an element and a location. Relationships are identified
- * by a globally unique identifier.
+ * Helper for requesting information from a single [UnitIndex].
*/
-class RelationshipImpl implements Relationship {
- /**
- * A table mapping relationship identifiers to relationships.
- */
- static Map<String, RelationshipImpl> _RELATIONSHIP_MAP = {};
+class _UnitIndexRequester {
+ final _PackageIndexRequester packageRequester;
+ final UnitIndex unitIndex;
+
+ _UnitIndexRequester(this.packageRequester, this.unitIndex);
/**
- * The next artificial hash code.
+ * Complete with a list of locations where elements of the given [kind] with
+ * names satisfying the given [regExp] are defined.
*/
- static int _NEXT_HASH_CODE = 0;
-
- /**
- * The artificial hash code for this object.
- */
- final int _hashCode = _NEXT_HASH_CODE++;
-
- /**
- * The unique identifier for this relationship.
- */
- final String identifier;
-
- /**
- * Initialize a newly created relationship with the given unique identifier.
- */
- RelationshipImpl(this.identifier);
-
- @override
- int get hashCode => _hashCode;
-
- @override
- String toString() => identifier;
-
- /**
- * Returns the relationship with the given unique [identifier].
- */
- static RelationshipImpl getRelationship(String identifier) {
- RelationshipImpl relationship = _RELATIONSHIP_MAP[identifier];
- if (relationship == null) {
- relationship = new RelationshipImpl(identifier);
- _RELATIONSHIP_MAP[identifier] = relationship;
+ List<Location> getDefinedNames(
+ AnalysisContext context, RegExp regExp, IndexNameKind kind) {
+ List<Location> locations = <Location>[];
+ String unitLibraryUri = null;
+ String unitUnitUri = null;
+ for (int i = 0; i < unitIndex.definedNames.length; i++) {
+ if (unitIndex.definedNameKinds[i] == kind) {
+ int nameIndex = unitIndex.definedNames[i];
+ String name = packageRequester.index.strings[nameIndex];
+ if (regExp.matchAsPrefix(name) != null) {
+ unitLibraryUri ??= packageRequester.getUnitLibraryUri(unitIndex.unit);
+ unitUnitUri ??= packageRequester.getUnitUnitUri(unitIndex.unit);
+ locations.add(new Location(context, unitLibraryUri, unitUnitUri, null,
+ unitIndex.definedNameOffsets[i], name.length, false, true));
+ }
+ }
}
- return relationship;
+ return locations;
+ }
+
+ /**
+ * Return a list of locations where an element with the given [elementId] has
+ * relation of the given [kind].
+ */
+ List<Location> getRelations(
+ AnalysisContext context, int elementId, IndexRelationKind kind) {
+ // Find the first usage of the element.
+ int i = _findFirstOccurrence(unitIndex.usedElements, elementId);
+ if (i == -1) {
+ return const <Location>[];
+ }
+ // Create locations for every usage of the element.
+ List<Location> locations = <Location>[];
+ String unitLibraryUri = null;
+ String unitUnitUri = null;
+ for (;
+ i < unitIndex.usedElements.length &&
+ unitIndex.usedElements[i] == elementId;
+ i++) {
+ if (unitIndex.usedElementKinds[i] == kind) {
+ unitLibraryUri ??= packageRequester.getUnitLibraryUri(unitIndex.unit);
+ unitUnitUri ??= packageRequester.getUnitUnitUri(unitIndex.unit);
+ locations.add(new Location(
+ context,
+ unitLibraryUri,
+ unitUnitUri,
+ kind,
+ unitIndex.usedElementOffsets[i],
+ unitIndex.usedElementLengths[i],
+ unitIndex.usedElementIsQualifiedFlags[i],
+ true));
+ }
+ }
+ return locations;
+ }
+
+ /**
+ * Complete with a list of locations where a class members with the given
+ * [name] is referenced with a qualifier, but is not resolved.
+ */
+ List<Location> getUnresolvedMemberReferences(
+ AnalysisContext context, String name) {
+ // Find the name ID in the package index.
+ int nameId = packageRequester.getStringId(name);
+ if (nameId == -1) {
+ return const <Location>[];
+ }
+ // Find the first usage of the name.
+ int i = _findFirstOccurrence(unitIndex.usedNames, nameId);
+ if (i == -1) {
+ return const <Location>[];
+ }
+ // Create locations for every usage of the name.
+ List<Location> locations = <Location>[];
+ String unitLibraryUri = null;
+ String unitUnitUri = null;
+ for (;
+ i < unitIndex.usedNames.length && unitIndex.usedNames[i] == nameId;
+ i++) {
+ unitLibraryUri ??= packageRequester.getUnitLibraryUri(unitIndex.unit);
+ unitUnitUri ??= packageRequester.getUnitUnitUri(unitIndex.unit);
+ locations.add(new Location(
+ context,
+ unitLibraryUri,
+ unitUnitUri,
+ unitIndex.usedNameKinds[i],
+ unitIndex.usedNameOffsets[i],
+ name.length,
+ unitIndex.usedNameIsQualifiedFlags[i],
+ false));
+ }
+ return locations;
}
}
diff --git a/pkg/analysis_server/lib/src/services/index/index_contributor.dart b/pkg/analysis_server/lib/src/services/index/index_contributor.dart
deleted file mode 100644
index ebac4d6..0000000
--- a/pkg/analysis_server/lib/src/services/index/index_contributor.dart
+++ /dev/null
@@ -1,840 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.src.index.index_contributor;
-
-import 'dart:collection' show Queue;
-
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analysis_server/src/services/correction/namespace.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/index_store.dart';
-import 'package:analysis_server/src/services/index/indexable_element.dart';
-import 'package:analysis_server/src/services/index/indexable_file.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/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * An [IndexContributor] that contributes relationships for Dart files.
- */
-class DartIndexContributor extends IndexContributor {
- @override
- void contributeTo(IndexStore store, AnalysisContext context, Object object) {
- if (store is InternalIndexStore && object is CompilationUnit) {
- _IndexContributor contributor = new _IndexContributor(store);
- object.accept(contributor);
- }
- }
-}
-
-/**
- * Visits a resolved AST and adds relationships into [InternalIndexStore].
- */
-class _IndexContributor extends GeneralizingAstVisitor {
- final InternalIndexStore _store;
-
- CompilationUnitElement _unitElement;
- LibraryElement _libraryElement;
-
- Map<ImportElement, Set<Element>> _importElementsMap = {};
-
- /**
- * A stack whose top element (the element with the largest index) is an
- * element representing the inner-most enclosing scope.
- */
- Queue<Element> _elementStack = new Queue();
-
- _IndexContributor(this._store);
-
- /**
- * Enter a new scope represented by the given [Element].
- */
- void enterScope(Element element) {
- _elementStack.addFirst(element);
- }
-
- /**
- * Return the inner-most enclosing [Element], wrapped as an indexable object,
- * or `null` if there is no enclosing element.
- */
- IndexableElement peekElement() {
- for (Element element in _elementStack) {
- if (element != null) {
- return new IndexableElement(element);
- }
- }
- return null;
- }
-
- /**
- * Record the given relationship between the given [Element] and
- * [LocationImpl].
- */
- void recordRelationshipElement(
- Element element, RelationshipImpl relationship, LocationImpl location) {
- if (element != null && location != null) {
- _store.recordRelationship(
- new IndexableElement(element), relationship, location);
- }
- }
-
- /**
- * Record the given relationship between the given [IndexableObject] and
- * [LocationImpl].
- */
- void recordRelationshipIndexable(IndexableObject indexable,
- RelationshipImpl relationship, LocationImpl location) {
- if (indexable != null && location != null) {
- _store.recordRelationship(indexable, relationship, location);
- }
- }
-
- @override
- visitAssignmentExpression(AssignmentExpression node) {
- _recordOperatorReference(node.operator, node.bestElement);
- super.visitAssignmentExpression(node);
- }
-
- @override
- visitBinaryExpression(BinaryExpression node) {
- _recordOperatorReference(node.operator, node.bestElement);
- super.visitBinaryExpression(node);
- }
-
- @override
- visitClassDeclaration(ClassDeclaration node) {
- ClassElement element = node.element;
- enterScope(element);
- try {
- _recordTopLevelElementDefinition(element);
- _recordHasAncestor(element);
- {
- ExtendsClause extendsClause = node.extendsClause;
- if (extendsClause != null) {
- TypeName superclassNode = extendsClause.superclass;
- _recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY);
- } else {
- InterfaceType superType = element.supertype;
- if (superType != null) {
- ClassElement objectElement = superType.element;
- recordRelationshipElement(
- objectElement,
- IndexConstants.IS_EXTENDED_BY,
- _createLocationForOffset(node.name.offset, 0));
- }
- }
- }
- {
- WithClause withClause = node.withClause;
- if (withClause != null) {
- for (TypeName mixinNode in withClause.mixinTypes) {
- _recordSuperType(mixinNode, IndexConstants.IS_MIXED_IN_BY);
- }
- }
- }
- {
- ImplementsClause implementsClause = node.implementsClause;
- if (implementsClause != null) {
- for (TypeName interfaceNode in implementsClause.interfaces) {
- _recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY);
- }
- }
- }
- super.visitClassDeclaration(node);
- } finally {
- _exitScope();
- }
- }
-
- @override
- visitClassTypeAlias(ClassTypeAlias node) {
- ClassElement element = node.element;
- enterScope(element);
- try {
- _recordTopLevelElementDefinition(element);
- _recordHasAncestor(element);
- {
- TypeName superclassNode = node.superclass;
- if (superclassNode != null) {
- _recordSuperType(superclassNode, IndexConstants.IS_EXTENDED_BY);
- }
- }
- {
- WithClause withClause = node.withClause;
- if (withClause != null) {
- for (TypeName mixinNode in withClause.mixinTypes) {
- _recordSuperType(mixinNode, IndexConstants.IS_MIXED_IN_BY);
- }
- }
- }
- {
- ImplementsClause implementsClause = node.implementsClause;
- if (implementsClause != null) {
- for (TypeName interfaceNode in implementsClause.interfaces) {
- _recordSuperType(interfaceNode, IndexConstants.IS_IMPLEMENTED_BY);
- }
- }
- }
- super.visitClassTypeAlias(node);
- } finally {
- _exitScope();
- }
- }
-
- @override
- visitCompilationUnit(CompilationUnit node) {
- _unitElement = node.element;
- if (_unitElement != null) {
- _elementStack.add(_unitElement);
- _libraryElement = _unitElement.enclosingElement;
- if (_libraryElement != null) {
- super.visitCompilationUnit(node);
- }
- }
- }
-
- @override
- visitConstructorDeclaration(ConstructorDeclaration node) {
- ConstructorElement element = node.element;
- enterScope(element);
- try {
- super.visitConstructorDeclaration(node);
- } finally {
- _exitScope();
- }
- }
-
- @override
- visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
- SimpleIdentifier fieldName = node.fieldName;
- Expression expression = node.expression;
- // field reference is write here
- if (fieldName != null) {
- Element element = fieldName.staticElement;
- LocationImpl location = _createLocationForNode(fieldName);
- recordRelationshipElement(
- element, IndexConstants.IS_WRITTEN_BY, location);
- }
- // index expression
- if (expression != null) {
- expression.accept(this);
- }
- }
-
- @override
- visitConstructorName(ConstructorName node) {
- ConstructorElement element = node.staticElement;
- // in 'class B = A;' actually A constructors are invoked
- if (element != null &&
- element.isSynthetic &&
- element.redirectedConstructor != null) {
- element = element.redirectedConstructor;
- }
- // prepare location
- LocationImpl location;
- if (node.name != null) {
- int start = node.period.offset;
- int end = node.name.end;
- location = _createLocationForOffset(start, end - start);
- } else {
- int start = node.type.end;
- location = _createLocationForOffset(start, 0);
- }
- // record relationship
- recordRelationshipElement(
- element, IndexConstants.IS_REFERENCED_BY, location);
- super.visitConstructorName(node);
- }
-
- @override
- visitDeclaredIdentifier(DeclaredIdentifier node) {
- LocalVariableElement element = node.element;
- enterScope(element);
- try {
- super.visitDeclaredIdentifier(node);
- } finally {
- _exitScope();
- }
- }
-
- @override
- visitEnumDeclaration(EnumDeclaration node) {
- ClassElement element = node.element;
- enterScope(element);
- try {
- _recordTopLevelElementDefinition(element);
- super.visitEnumDeclaration(node);
- } finally {
- _exitScope();
- }
- }
-
- @override
- visitExportDirective(ExportDirective node) {
- ExportElement element = node.element;
- if (element != null) {
- LibraryElement expLibrary = element.exportedLibrary;
- _recordLibraryReference(node, expLibrary);
- }
- _recordUriFileReference(node);
- super.visitExportDirective(node);
- }
-
- @override
- visitFormalParameter(FormalParameter node) {
- ParameterElement element = node.element;
- enterScope(element);
- try {
- super.visitFormalParameter(node);
- } finally {
- _exitScope();
- }
- }
-
- @override
- visitFunctionDeclaration(FunctionDeclaration node) {
- Element element = node.element;
- _recordTopLevelElementDefinition(element);
- enterScope(element);
- try {
- super.visitFunctionDeclaration(node);
- } finally {
- _exitScope();
- }
- }
-
- @override
- visitFunctionTypeAlias(FunctionTypeAlias node) {
- Element element = node.element;
- _recordTopLevelElementDefinition(element);
- super.visitFunctionTypeAlias(node);
- }
-
- @override
- visitImportDirective(ImportDirective node) {
- ImportElement element = node.element;
- if (element != null) {
- LibraryElement impLibrary = element.importedLibrary;
- _recordLibraryReference(node, impLibrary);
- }
- _recordUriFileReference(node);
- super.visitImportDirective(node);
- }
-
- @override
- visitIndexExpression(IndexExpression node) {
- MethodElement element = node.bestElement;
- if (element is MethodElement) {
- Token operator = node.leftBracket;
- LocationImpl location =
- _createLocationForToken(operator, element != null);
- recordRelationshipElement(
- element, IndexConstants.IS_INVOKED_BY, location);
- }
- super.visitIndexExpression(node);
- }
-
- @override
- visitMethodDeclaration(MethodDeclaration node) {
- ExecutableElement element = node.element;
- enterScope(element);
- try {
- super.visitMethodDeclaration(node);
- } finally {
- _exitScope();
- }
- }
-
- @override
- visitMethodInvocation(MethodInvocation node) {
- SimpleIdentifier name = node.methodName;
- LocationImpl location = _createLocationForNode(name);
- // name invocation
- recordRelationshipIndexable(
- new IndexableName(name.name), IndexConstants.IS_INVOKED_BY, location);
- // element invocation
- Element element = name.bestElement;
- if (element is MethodElement ||
- element is PropertyAccessorElement ||
- element is FunctionElement ||
- element is VariableElement) {
- recordRelationshipElement(
- element, IndexConstants.IS_INVOKED_BY, location);
- } else if (element is ClassElement) {
- recordRelationshipElement(
- element, IndexConstants.IS_REFERENCED_BY, location);
- }
- _recordImportElementReferenceWithoutPrefix(name);
- super.visitMethodInvocation(node);
- }
-
- @override
- visitPartDirective(PartDirective node) {
- Element element = node.element;
- LocationImpl location = _createLocationForNode(node.uri);
- recordRelationshipElement(
- element, IndexConstants.IS_REFERENCED_BY, location);
- _recordUriFileReference(node);
- super.visitPartDirective(node);
- }
-
- @override
- visitPartOfDirective(PartOfDirective node) {
- LocationImpl location = _createLocationForNode(node.libraryName);
- recordRelationshipElement(
- node.element, IndexConstants.IS_REFERENCED_BY, location);
- }
-
- @override
- visitPostfixExpression(PostfixExpression node) {
- _recordOperatorReference(node.operator, node.bestElement);
- super.visitPostfixExpression(node);
- }
-
- @override
- visitPrefixExpression(PrefixExpression node) {
- _recordOperatorReference(node.operator, node.bestElement);
- super.visitPrefixExpression(node);
- }
-
- @override
- visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
- ConstructorElement element = node.staticElement;
- LocationImpl location;
- if (node.constructorName != null) {
- int start = node.period.offset;
- int end = node.constructorName.end;
- location = _createLocationForOffset(start, end - start);
- } else {
- int start = node.thisKeyword.end;
- location = _createLocationForOffset(start, 0);
- }
- recordRelationshipElement(
- element, IndexConstants.IS_REFERENCED_BY, location);
- super.visitRedirectingConstructorInvocation(node);
- }
-
- @override
- visitSimpleIdentifier(SimpleIdentifier node) {
- IndexableName indexableName = new IndexableName(node.name);
- LocationImpl location = _createLocationForNode(node);
- if (location == null) {
- return;
- }
- // name in declaration
- if (node.inDeclarationContext()) {
- recordRelationshipIndexable(
- indexableName, IndexConstants.NAME_IS_DEFINED_BY, location);
- return;
- }
- // prepare information
- Element element = node.bestElement;
- // stop if already handled
- if (_isAlreadyHandledName(node)) {
- return;
- }
- // record name read/write
- if (element != null && element.enclosingElement is ClassElement ||
- element == null && location.isQualified) {
- bool inGetterContext = node.inGetterContext();
- bool inSetterContext = node.inSetterContext();
- if (inGetterContext && inSetterContext) {
- recordRelationshipIndexable(
- indexableName, IndexConstants.IS_READ_WRITTEN_BY, location);
- } else if (inGetterContext) {
- recordRelationshipIndexable(
- indexableName, IndexConstants.IS_READ_BY, location);
- } else if (inSetterContext) {
- recordRelationshipIndexable(
- indexableName, IndexConstants.IS_WRITTEN_BY, location);
- }
- }
- // this.field parameter
- if (element is FieldFormalParameterElement) {
- RelationshipImpl relationship = peekElement().element == element
- ? IndexConstants.IS_WRITTEN_BY
- : IndexConstants.IS_REFERENCED_BY;
- recordRelationshipElement(element.field, relationship, location);
- return;
- }
- // record specific relations
- if (element is ClassElement ||
- element is FunctionElement ||
- element is FunctionTypeAliasElement ||
- element is LabelElement ||
- element is MethodElement ||
- element is PropertyAccessorElement ||
- element is PropertyInducingElement ||
- element is TypeParameterElement) {
- recordRelationshipElement(
- element, IndexConstants.IS_REFERENCED_BY, location);
- } else if (element is PrefixElement) {
- recordRelationshipElement(
- element, IndexConstants.IS_REFERENCED_BY, location);
- _recordImportElementReferenceWithPrefix(node);
- } else if (element is ParameterElement || element is LocalVariableElement) {
- bool inGetterContext = node.inGetterContext();
- bool inSetterContext = node.inSetterContext();
- if (inGetterContext && inSetterContext) {
- recordRelationshipElement(
- element, IndexConstants.IS_READ_WRITTEN_BY, location);
- } else if (inGetterContext) {
- recordRelationshipElement(element, IndexConstants.IS_READ_BY, location);
- } else if (inSetterContext) {
- recordRelationshipElement(
- element, IndexConstants.IS_WRITTEN_BY, location);
- } else {
- recordRelationshipElement(
- element, IndexConstants.IS_REFERENCED_BY, location);
- }
- }
- _recordImportElementReferenceWithoutPrefix(node);
- super.visitSimpleIdentifier(node);
- }
-
- @override
- visitSuperConstructorInvocation(SuperConstructorInvocation node) {
- ConstructorElement element = node.staticElement;
- LocationImpl location;
- if (node.constructorName != null) {
- int start = node.period.offset;
- int end = node.constructorName.end;
- location = _createLocationForOffset(start, end - start);
- } else {
- int start = node.superKeyword.end;
- location = _createLocationForOffset(start, 0);
- }
- recordRelationshipElement(
- element, IndexConstants.IS_REFERENCED_BY, location);
- super.visitSuperConstructorInvocation(node);
- }
-
- @override
- visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- VariableDeclarationList variables = node.variables;
- for (VariableDeclaration variableDeclaration in variables.variables) {
- Element element = variableDeclaration.element;
- _recordTopLevelElementDefinition(element);
- }
- super.visitTopLevelVariableDeclaration(node);
- }
-
- @override
- visitTypeParameter(TypeParameter node) {
- TypeParameterElement element = node.element;
- enterScope(element);
- try {
- super.visitTypeParameter(node);
- } finally {
- _exitScope();
- }
- }
-
- @override
- visitVariableDeclaration(VariableDeclaration node) {
- VariableElement element = node.element;
- // record declaration
- {
- SimpleIdentifier name = node.name;
- LocationImpl location = _createLocationForNode(name);
- location = _getLocationWithExpressionType(location, node.initializer);
- recordRelationshipElement(
- element, IndexConstants.NAME_IS_DEFINED_BY, location);
- }
- // visit
- enterScope(element);
- try {
- super.visitVariableDeclaration(node);
- } finally {
- _exitScope();
- }
- }
-
- @override
- visitVariableDeclarationList(VariableDeclarationList node) {
- NodeList<VariableDeclaration> variables = node.variables;
- if (variables != null) {
- // use first VariableDeclaration as Element for Location(s) in type
- {
- TypeName type = node.type;
- if (type != null) {
- for (VariableDeclaration variableDeclaration in variables) {
- enterScope(variableDeclaration.element);
- try {
- type.accept(this);
- } finally {
- _exitScope();
- }
- // only one iteration
- break;
- }
- }
- }
- // visit variables
- variables.accept(this);
- }
- }
-
- /**
- * @return the [LocationImpl] representing location of the [AstNode].
- */
- LocationImpl _createLocationForNode(AstNode node) {
- bool isQualified = _isQualifiedClassMemberAccess(node);
- bool isResolved = true;
- if (node is SimpleIdentifier) {
- isResolved = node.bestElement != null;
- }
- IndexableObject indexable = peekElement();
- return new LocationImpl(indexable, node.offset, node.length,
- isQualified: isQualified, isResolved: isResolved);
- }
-
- /**
- * [offset] - the offset of the location within [Source].
- * [length] - the length of the location.
- *
- * Returns the [LocationImpl] representing the given offset and length within the
- * inner-most [Element].
- */
- LocationImpl _createLocationForOffset(int offset, int length) {
- IndexableObject element = peekElement();
- return new LocationImpl(element, offset, length);
- }
-
- /**
- * @return the [LocationImpl] representing location of the [Token].
- */
- LocationImpl _createLocationForToken(Token token, bool isResolved) {
- IndexableObject element = peekElement();
- return new LocationImpl(element, token.offset, token.length,
- isQualified: true, isResolved: isResolved);
- }
-
- /**
- * Exit the current scope.
- */
- void _exitScope() {
- _elementStack.removeFirst();
- }
-
- /**
- * @return `true` if given node already indexed as more interesting reference, so it should
- * not be indexed again.
- */
- bool _isAlreadyHandledName(SimpleIdentifier node) {
- AstNode parent = node.parent;
- if (parent is MethodInvocation) {
- return parent.methodName == node;
- }
- return false;
- }
-
- bool _isQualifiedClassMemberAccess(AstNode node) {
- if (node is SimpleIdentifier) {
- AstNode parent = node.parent;
- if (parent is PrefixedIdentifier && parent.identifier == node) {
- return parent.prefix.staticElement is! PrefixElement;
- }
- if (parent is PropertyAccess && parent.propertyName == node) {
- return parent.realTarget != null;
- }
- if (parent is MethodInvocation && parent.methodName == node) {
- Expression target = parent.realTarget;
- if (target is SimpleIdentifier &&
- target.staticElement is PrefixElement) {
- return false;
- }
- return target != null;
- }
- }
- return false;
- }
-
- void _recordHasAncestor(ClassElement element) {
- int offset = element.nameOffset;
- int length = element.nameLength;
- LocationImpl location = _createLocationForOffset(offset, length);
- _recordHasAncestor0(location, element, false, <ClassElement>[]);
- }
-
- void _recordHasAncestor0(LocationImpl location, ClassElement element,
- bool includeThis, List<ClassElement> visitedElements) {
- if (element == null) {
- return;
- }
- if (visitedElements.contains(element)) {
- return;
- }
- visitedElements.add(element);
- if (includeThis) {
- recordRelationshipElement(element, IndexConstants.HAS_ANCESTOR, location);
- }
- {
- InterfaceType superType = element.supertype;
- if (superType != null) {
- _recordHasAncestor0(location, superType.element, true, visitedElements);
- }
- }
- for (InterfaceType mixinType in element.mixins) {
- _recordHasAncestor0(location, mixinType.element, true, visitedElements);
- }
- for (InterfaceType implementedType in element.interfaces) {
- _recordHasAncestor0(
- location, implementedType.element, true, visitedElements);
- }
- }
-
- /**
- * Records [ImportElement] reference if given [SimpleIdentifier] references some
- * top-level element and not qualified with import prefix.
- */
- void _recordImportElementReferenceWithoutPrefix(SimpleIdentifier node) {
- if (_isIdentifierInImportCombinator(node)) {
- return;
- }
- if (_isIdentifierInPrefixedIdentifier(node)) {
- return;
- }
- Element element = node.staticElement;
- ImportElement importElement = internal_getImportElement(
- _libraryElement, null, element, _importElementsMap);
- if (importElement != null) {
- LocationImpl location = _createLocationForOffset(node.offset, 0);
- recordRelationshipElement(
- importElement, IndexConstants.IS_REFERENCED_BY, location);
- }
- }
-
- /**
- * Records [ImportElement] that declares given prefix and imports library with element used
- * with given prefix node.
- */
- void _recordImportElementReferenceWithPrefix(SimpleIdentifier prefixNode) {
- ImportElementInfo info = internal_getImportElementInfo(prefixNode);
- if (info != null) {
- int offset = prefixNode.offset;
- int length = info.periodEnd - offset;
- LocationImpl location = _createLocationForOffset(offset, length);
- recordRelationshipElement(
- info.element, IndexConstants.IS_REFERENCED_BY, location);
- }
- }
-
- /**
- * Records reference to defining [CompilationUnitElement] of the given
- * [LibraryElement].
- */
- void _recordLibraryReference(UriBasedDirective node, LibraryElement library) {
- if (library != null) {
- LocationImpl location = _createLocationForNode(node.uri);
- recordRelationshipElement(library.definingCompilationUnit,
- IndexConstants.IS_REFERENCED_BY, location);
- }
- }
-
- /**
- * Record reference to the given operator [Element] and name.
- */
- void _recordOperatorReference(Token operator, Element element) {
- // prepare location
- LocationImpl location = _createLocationForToken(operator, element != null);
- // record name reference
- {
- String name = operator.lexeme;
- if (name == "++") {
- name = "+";
- }
- if (name == "--") {
- name = "-";
- }
- if (StringUtilities.endsWithChar(name, 0x3D) && name != "==") {
- name = name.substring(0, name.length - 1);
- }
- IndexableName indexableName = new IndexableName(name);
- recordRelationshipIndexable(
- indexableName, IndexConstants.IS_INVOKED_BY, location);
- }
- // record element reference
- if (element != null) {
- recordRelationshipElement(
- element, IndexConstants.IS_INVOKED_BY, location);
- }
- }
-
- /**
- * Records a relation between [superNode] and its [Element].
- */
- void _recordSuperType(TypeName superNode, RelationshipImpl relationship) {
- if (superNode != null) {
- Identifier superName = superNode.name;
- if (superName != null) {
- Element superElement = superName.staticElement;
- recordRelationshipElement(
- superElement, relationship, _createLocationForNode(superNode));
- }
- }
- }
-
- /**
- * Records the [Element] definition in the library and universe.
- */
- void _recordTopLevelElementDefinition(Element element) {
- if (element != null) {
- IndexableElement indexable = new IndexableElement(element);
- int offset = element.nameOffset;
- int length = element.nameLength;
- LocationImpl location = new LocationImpl(indexable, offset, length);
- recordRelationshipElement(
- _libraryElement, IndexConstants.DEFINES, location);
- _store.recordTopLevelDeclaration(element);
- }
- }
-
- void _recordUriFileReference(UriBasedDirective directive) {
- Source source = directive.source;
- if (source != null) {
- LocationImpl location = new LocationImpl(
- new IndexableFile(_unitElement.source.fullName),
- directive.uri.offset,
- directive.uri.length);
- _store.recordRelationship(new IndexableFile(source.fullName),
- IndexConstants.IS_REFERENCED_BY, location);
- }
- }
-
- /**
- * If the given expression has resolved type, returns the new location with this type.
- *
- * [location] - the base location
- * [expression] - the expression assigned at the given location
- */
- static LocationImpl _getLocationWithExpressionType(
- LocationImpl location, Expression expression) {
- if (expression != null) {
- return new LocationWithData<DartType>(location, expression.bestType);
- }
- return location;
- }
-
- /**
- * @return `true` if given "node" is part of an import [Combinator].
- */
- static bool _isIdentifierInImportCombinator(SimpleIdentifier node) {
- AstNode parent = node.parent;
- return parent is Combinator;
- }
-
- /**
- * @return `true` if given "node" is part of [PrefixedIdentifier] "prefix.node".
- */
- static bool _isIdentifierInPrefixedIdentifier(SimpleIdentifier node) {
- AstNode parent = node.parent;
- return parent is PrefixedIdentifier && parent.identifier == node;
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/index/index_store.dart b/pkg/analysis_server/lib/src/services/index/index_store.dart
deleted file mode 100644
index f5bebe1..0000000
--- a/pkg/analysis_server/lib/src/services/index/index_store.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.index_store;
-
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-
-/**
- * A container with information computed by an index - relations between
- * elements.
- */
-abstract class InternalIndexStore extends IndexStore {
- /**
- * Answers index statistics.
- */
- String get statistics;
-
- /**
- * Notifies the index store that we are going to index the given [object].
- *
- * [context] - the [AnalysisContext] in which the [object] being indexed.
- * [object] - the object being indexed.
- *
- * Returns `true` if the given [object] may be indexed, or `false` if
- * belongs to a disposed [AnalysisContext], is not resolved completely, etc.
- */
- bool aboutToIndex(AnalysisContext context, Object object);
-
- /**
- * Notifies the index store that there was an error during the current
- * indexing, and all the information recorded after the last
- * [aboutToIndex] invocation must be discarded.
- */
- void cancelIndex();
-
- /**
- * Notifies the index store that the current object indexing is done.
- *
- * If this method is not invoked after corresponding [aboutToIndex]
- * invocation, all recorded information may be lost.
- */
- void doneIndex();
-
- /**
- * Returns top-level [Element]s whose names satisfy to [nameFilter].
- */
- List<Element> getTopLevelDeclarations(ElementNameFilter nameFilter);
-
- /**
- * Records the declaration of the given top-level [element].
- */
- void recordTopLevelDeclaration(Element element);
-}
diff --git a/pkg/analysis_server/lib/src/services/index/indexable_element.dart b/pkg/analysis_server/lib/src/services/index/indexable_element.dart
deleted file mode 100644
index 916a099..0000000
--- a/pkg/analysis_server/lib/src/services/index/indexable_element.dart
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library src.services.index;
-
-import 'dart:collection';
-
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_general.dart';
-
-/**
- * A wrapper around an [Element] that implements the [IndexableObject] interface.
- */
-class IndexableElement implements IndexableObject {
- /**
- * The element being wrapped.
- */
- final Element element;
-
- /**
- * Initialize a newly created wrapper to wrap the given [element].
- */
- IndexableElement(this.element) {
- if (element == null) {
- throw new ArgumentError.notNull('element');
- }
- }
-
- @override
- String get filePath {
- return element.source?.fullName;
- }
-
- @override
- int get hashCode => element.hashCode;
-
- @override
- IndexableElementKind get kind => IndexableElementKind.forElement(element);
-
- @override
- int get offset {
- if (element is ConstructorElement) {
- return element.enclosingElement.nameOffset;
- }
- return element.nameOffset;
- }
-
- @override
- bool operator ==(Object object) =>
- object is IndexableElement && element == object.element;
-
- @override
- String toString() => element.toString();
-}
-
-/**
- * The kind associated with an [IndexableElement].
- */
-class IndexableElementKind implements IndexableObjectKind<IndexableElement> {
- /**
- * A table mapping element kinds to the corresponding indexable element kind.
- */
- static final Map<ElementKind, IndexableElementKind> _kindMap =
- new HashMap<ElementKind, IndexableElementKind>();
-
- /**
- * A table mapping the index of a constructor (in the lexically-ordered list
- * of constructors associated with a class) to the indexable element kind used
- * to represent it.
- */
- static final Map<int, IndexableElementKind> _constructorKinds =
- new HashMap<int, IndexableElementKind>();
-
- @override
- final int index = IndexableObjectKind.nextIndex;
-
- /**
- * The element kind represented by this index element kind.
- */
- final ElementKind elementKind;
-
- /**
- * Initialize a newly created kind to have the given [index] and be associated
- * with the given [elementKind].
- */
- IndexableElementKind._(this.elementKind) {
- IndexableObjectKind.register(this);
- }
-
- /**
- * Return the index of the constructor with this indexable element kind.
- */
- int get constructorIndex {
- for (int index in _constructorKinds.keys) {
- if (_constructorKinds[index] == this) {
- return index;
- }
- }
- return -1;
- }
-
- @override
- IndexableElement decode(
- AnalysisContext context, String filePath, int offset) {
- List<Source> unitSources = context.getSourcesWithFullName(filePath);
- for (Source unitSource in unitSources) {
- List<Source> libSources = context.getLibrariesContaining(unitSource);
- for (Source libSource in libSources) {
- CompilationUnitElement unitElement =
- context.getCompilationUnitElement(unitSource, libSource);
- if (unitElement == null) {
- return null;
- }
- if (elementKind == ElementKind.LIBRARY) {
- return new IndexableElement(unitElement.library);
- } else if (elementKind == ElementKind.COMPILATION_UNIT) {
- return new IndexableElement(unitElement);
- } else {
- Element element = unitElement.getElementAt(offset);
- if (element == null) {
- return null;
- }
- if (element is ClassElement &&
- elementKind == ElementKind.CONSTRUCTOR) {
- return new IndexableElement(element.constructors[constructorIndex]);
- }
- if (element is PropertyInducingElement) {
- if (elementKind == ElementKind.GETTER) {
- return new IndexableElement(element.getter);
- }
- if (elementKind == ElementKind.SETTER) {
- return new IndexableElement(element.setter);
- }
- }
- return new IndexableElement(element);
- }
- }
- }
- return null;
- }
-
- @override
- int encodeHash(StringToInt stringToInt, IndexableElement indexable) {
- Element element = indexable.element;
- String elementName = element.displayName;
- int elementNameId = stringToInt(elementName);
- LibraryElement libraryElement = element.library;
- if (libraryElement != null) {
- String libraryPath = libraryElement.source.fullName;
- int libraryPathId = stringToInt(libraryPath);
- return JenkinsSmiHash.combine(libraryPathId, elementNameId);
- }
- return elementNameId;
- }
-
- /**
- * Return the indexable element kind representing the given [element].
- */
- static IndexableElementKind forElement(Element element) {
- if (element is ConstructorElement) {
- ClassElement classElement = element.enclosingElement;
- int constructorIndex = classElement.constructors.indexOf(element);
- return _constructorKinds.putIfAbsent(constructorIndex,
- () => new IndexableElementKind._(ElementKind.CONSTRUCTOR));
- }
- ElementKind elementKind = element.kind;
- return _kindMap.putIfAbsent(
- elementKind, () => new IndexableElementKind._(elementKind));
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/index/indexable_file.dart b/pkg/analysis_server/lib/src/services/index/indexable_file.dart
deleted file mode 100644
index 4e1c873..0000000
--- a/pkg/analysis_server/lib/src/services/index/indexable_file.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.index.indexable_file;
-
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analyzer/src/generated/engine.dart';
-
-/**
- * An [IndexableObject] which is used to index references to a file.
- */
-class IndexableFile implements IndexableObject {
- /**
- * The path of the file to be indexed.
- */
- @override
- final String path;
-
- /**
- * Initialize a newly created indexable file to represent the given [path].
- */
- IndexableFile(this.path);
-
- @override
- String get filePath => path;
-
- @override
- IndexableObjectKind get kind => IndexableFileKind.INSTANCE;
-
- @override
- int get offset => -1;
-
- @override
- bool operator ==(Object object) =>
- object is IndexableFile && object.path == path;
-
- @override
- String toString() => path;
-}
-
-/**
- * The kind of an indexable file.
- */
-class IndexableFileKind implements IndexableObjectKind<IndexableFile> {
- /**
- * The unique instance of this class.
- */
- static final IndexableFileKind INSTANCE =
- new IndexableFileKind._(IndexableObjectKind.nextIndex);
-
- /**
- * The index uniquely identifying this kind.
- */
- final int index;
-
- /**
- * Initialize a newly created kind to have the given [index].
- */
- IndexableFileKind._(this.index) {
- IndexableObjectKind.register(this);
- }
-
- @override
- IndexableFile decode(AnalysisContext context, String filePath, int offset) {
- return new IndexableFile(filePath);
- }
-
- @override
- int encodeHash(StringToInt stringToInt, IndexableFile indexable) {
- String path = indexable.path;
- return stringToInt(path);
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/index/local_file_index.dart b/pkg/analysis_server/lib/src/services/index/local_file_index.dart
deleted file mode 100644
index 022fa1b..0000000
--- a/pkg/analysis_server/lib/src/services/index/local_file_index.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.index.local_file_index;
-
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_index.dart';
-import 'package:analysis_server/src/services/index/store/codec.dart';
-import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analysis_server/src/services/index/store/temporary_folder_file_manager.dart';
-import 'package:analyzer/src/generated/engine.dart';
-
-Index createLocalFileIndex() {
- var fileManager = new TemporaryFolderFileManager();
- var stringCodec = new StringCodec();
- var nodeManager = new FileNodeManager(
- fileManager,
- AnalysisEngine.instance.logger,
- stringCodec,
- new ContextCodec(),
- new ElementCodec(stringCodec),
- new RelationshipCodec(stringCodec));
- return new LocalIndex(nodeManager);
-}
diff --git a/pkg/analysis_server/lib/src/services/index/local_index.dart b/pkg/analysis_server/lib/src/services/index/local_index.dart
deleted file mode 100644
index 34c0e76..0000000
--- a/pkg/analysis_server/lib/src/services/index/local_index.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.src.index.local_index;
-
-import 'dart:async';
-
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * A local implementation of [Index].
- */
-class LocalIndex extends Index {
- /**
- * The index contributors used by this index.
- */
- List<IndexContributor> contributors = <IndexContributor>[];
-
- SplitIndexStore _store;
-
- LocalIndex(NodeManager nodeManager) {
- // TODO(scheglov) get IndexObjectManager(s) as a parameter
- _store = new SplitIndexStore(
- nodeManager, <IndexObjectManager>[new DartUnitIndexObjectManager()]);
- }
-
- @override
- String get statistics => _store.statistics;
-
- @override
- void clear() {
- _store.clear();
- }
-
- /**
- * Returns all relations with [Element]s with the given [name].
- */
- Future<Map<List<String>, List<InspectLocation>>> findElementsByName(
- String name) {
- return _store.inspect_getElementRelations(name);
- }
-
- /**
- * Returns a `Future<List<Location>>` that completes with the list of
- * [LocationImpl]s of the given [relationship] with the given [indexable].
- *
- * For example, if the [indexable] represents a function element and the
- * [relationship] is the `is-invoked-by` relationship, then the locations
- * will be all of the places where the function is invoked.
- */
- @override
- Future<List<LocationImpl>> getRelationships(
- IndexableObject indexable, RelationshipImpl relationship) {
- return _store.getRelationships(indexable, relationship);
- }
-
- @override
- List<Element> getTopLevelDeclarations(ElementNameFilter nameFilter) {
- return _store.getTopLevelDeclarations(nameFilter);
- }
-
- @override
- void index(AnalysisContext context, Object object) {
- // about to index
- bool mayIndex = _store.aboutToIndex(context, object);
- if (!mayIndex) {
- return;
- }
- // do index
- try {
- for (IndexContributor contributor in contributors) {
- contributor.contributeTo(_store, context, object);
- }
- _store.doneIndex();
- } catch (e) {
- _store.cancelIndex();
- rethrow;
- }
- }
-
- @override
- void recordRelationship(
- IndexableObject indexable, Relationship relationship, Location location) {
- _store.recordRelationship(indexable, relationship, location);
- }
-
- @override
- void removeContext(AnalysisContext context) {
- _store.removeContext(context);
- }
-
- @override
- void removeSource(AnalysisContext context, Source source) {
- _store.removeSource(context, source);
- }
-
- @override
- void removeSources(AnalysisContext context, SourceContainer container) {
- _store.removeSources(context, container);
- }
-
- @override
- void run() {
- // NO-OP for the local index
- }
-
- @override
- void stop() {
- // NO-OP for the local index
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/index/local_memory_index.dart b/pkg/analysis_server/lib/src/services/index/local_memory_index.dart
deleted file mode 100644
index ec69627..0000000
--- a/pkg/analysis_server/lib/src/services/index/local_memory_index.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.index.memory_file_index;
-
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/index_contributor.dart';
-import 'package:analysis_server/src/services/index/local_index.dart';
-import 'package:analysis_server/src/services/index/store/memory_node_manager.dart';
-
-Index createLocalMemoryIndex() {
- MemoryNodeManager nodeManager = new MemoryNodeManager();
- LocalIndex index = new LocalIndex(nodeManager);
- index.contributors = <IndexContributor>[new DartIndexContributor()];
- return index;
-}
diff --git a/pkg/analysis_server/lib/src/services/index/store/codec.dart b/pkg/analysis_server/lib/src/services/index/store/codec.dart
deleted file mode 100644
index 9771f56..0000000
--- a/pkg/analysis_server/lib/src/services/index/store/codec.dart
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.src.index.store.codec;
-
-import 'dart:collection';
-
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analyzer/src/generated/engine.dart';
-
-/**
- * A helper that encodes/decodes [AnalysisContext]s from/to integers.
- */
-class ContextCodec {
- /**
- * A table mapping contexts to their unique indices.
- */
- Map<AnalysisContext, int> _contextToIndex =
- new HashMap<AnalysisContext, int>();
-
- /**
- * A table mapping indices to the corresponding contexts.
- */
- Map<int, AnalysisContext> _indexToContext =
- new HashMap<int, AnalysisContext>();
-
- /**
- * The next id to assign.
- */
- int _nextId = 0;
-
- /**
- * Returns the [AnalysisContext] that corresponds to the given index.
- */
- AnalysisContext decode(int index) => _indexToContext[index];
-
- /**
- * Returns an unique index for the given [AnalysisContext].
- */
- int encode(AnalysisContext context) {
- int index = _contextToIndex[context];
- if (index == null) {
- index = _nextId++;
- _contextToIndex[context] = index;
- _indexToContext[index] = context;
- }
- return index;
- }
-
- /**
- * Removes the given [context].
- */
- void remove(AnalysisContext context) {
- int id = _contextToIndex.remove(context);
- if (id != null) {
- _indexToContext.remove(id);
- }
- }
-}
-
-/**
- * A helper that encodes/decodes [IndexableObject]s to/from integers.
- */
-class ElementCodec {
- // TODO(brianwilkerson) Rename this class now that if encodes indexable
- // objects rather than elements.
- final StringCodec _stringCodec;
-
- ElementCodec(this._stringCodec);
-
- /**
- * Returns an [IndexableObject] that corresponds to the given identifiers.
- */
- IndexableObject decode(
- AnalysisContext context, int fileId, int offset, int kindId) {
- IndexableObjectKind kind = IndexableObjectKind.getKind(kindId);
- if (kind == null) {
- return null;
- } else if (kind is IndexableNameKind) {
- String name = _stringCodec.decode(offset);
- return new IndexableName(name);
- }
- String filePath = _stringCodec.decode(fileId);
- return kind.decode(context, filePath, offset);
- }
-
- /**
- * Returns the first component of the [indexable] id.
- * In the most cases it is an encoding of the [indexable]'s file path.
- * If the given [indexable] is not defined in a file, returns `-1`.
- */
- int encode1(IndexableObject indexable) {
- String filePath = indexable.filePath;
- if (filePath == null) {
- return -1;
- }
- return _stringCodec.encode(filePath);
- }
-
- /**
- * Returns the second component of the [indexable] id.
- * In the most cases it is the [indexable]'s name offset.
- */
- int encode2(IndexableObject indexable) {
- if (indexable is IndexableName) {
- String name = indexable.name;
- return _stringCodec.encode(name);
- }
- return indexable.offset;
- }
-
- /**
- * Returns the third component of the [indexable] id.
- * In the most cases it is the [indexable]'s kind.
- */
- int encode3(IndexableObject indexable) {
- return indexable.kind.index;
- }
-
- /**
- * Returns an integer that corresponds to the name of [indexable].
- */
- int encodeHash(IndexableObject indexable) {
- return indexable.kind.encodeHash(_stringCodec.encode, indexable);
- }
-}
-
-/**
- * A helper that encodes/decodes [Relationship]s to/from integers.
- */
-class RelationshipCodec {
- final StringCodec _stringCodec;
-
- RelationshipCodec(this._stringCodec);
-
- RelationshipImpl decode(int idIndex) {
- String id = _stringCodec.decode(idIndex);
- return RelationshipImpl.getRelationship(id);
- }
-
- int encode(RelationshipImpl relationship) {
- String id = relationship.identifier;
- return _stringCodec.encode(id);
- }
-}
-
-/**
- * A helper that encodes/decodes [String]s from/to integers.
- */
-class StringCodec {
- /**
- * A table mapping names to their unique indices.
- */
- final Map<String, int> nameToIndex = new HashMap<String, int>();
-
- /**
- * A table mapping indices to the corresponding strings.
- */
- final List<String> _indexToName = <String>[];
-
- /**
- * Returns the [String] that corresponds to the given index.
- */
- String decode(int index) => _indexToName[index];
-
- /**
- * Returns an unique index for the given [String].
- */
- int encode(String name) {
- int index = nameToIndex[name];
- if (index == null) {
- index = _indexToName.length;
- nameToIndex[name] = index;
- _indexToName.add(name);
- }
- return index;
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/index/store/collection.dart b/pkg/analysis_server/lib/src/services/index/store/collection.dart
deleted file mode 100644
index de2d390..0000000
--- a/pkg/analysis_server/lib/src/services/index/store/collection.dart
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.src.index.store.collection;
-
-import 'dart:collection';
-import 'dart:typed_data' show Uint32List;
-
-import 'package:analyzer/src/generated/utilities_general.dart';
-
-/**
- * A hash map with `List<int>` keys and [int] values.
- */
-class IntArrayToIntMap {
- final Map<Uint32List, int> map = new HashMap<Uint32List, int>(
- equals: _intArrayEquals, hashCode: _intArrayHashCode);
-
- /**
- * Returns the value for the given [key] or null if [key] is not in the map.
- */
- int operator [](List<int> key) {
- Uint32List typedKey = _getTypedKey(key);
- return map[typedKey];
- }
-
- /**
- * Associates the [key] with the given [value].
- *
- * If the key was already in the map, its associated value is changed.
- * Otherwise the key-value pair is added to the map.
- */
- void operator []=(List<int> key, int value) {
- Uint32List typedKey = _getTypedKey(key);
- map[typedKey] = value;
- }
-
- /**
- * Returns an [Uint32List] version of the given `List<int>` key.
- */
- static Uint32List _getTypedKey(List<int> key) {
- if (key is Uint32List) {
- return key;
- }
- return new Uint32List.fromList(key);
- }
-
- static bool _intArrayEquals(List<int> a, List<int> b) {
- int length = a.length;
- if (length != b.length) {
- return false;
- }
- for (int i = 0; i < length; i++) {
- if (a[i] != b[i]) {
- return false;
- }
- }
- return true;
- }
-
- static int _intArrayHashCode(List<int> key) {
- return key.fold(0, JenkinsSmiHash.combine);
- }
-}
-
-/**
- * A table mapping [int] keys to sets of [int]s.
- */
-class IntToIntSetMap {
- final Map<int, Uint32List> _map = new HashMap<int, Uint32List>();
-
- /**
- * The number of key-value pairs in the map.
- */
- int get length => _map.length;
-
- /**
- * Adds the [value] to the set associated with the given [value].
- */
- void add(int key, int value) {
- Uint32List values = _map[key];
- if (values == null) {
- values = new Uint32List(1);
- values[0] = value;
- _map[key] = values;
- }
- if (values.indexOf(value) == -1) {
- int length = values.length;
- Uint32List newSet = new Uint32List(length + 1);
- newSet.setRange(0, length, values);
- newSet[length] = value;
- _map[key] = newSet;
- }
- }
-
- /**
- * Removes all pairs from the map.
- */
- void clear() {
- _map.clear();
- }
-
- /**
- * Returns the set of [int]s for the given [key] or an empty list if [key] is
- * not in the map.
- */
- List<int> get(int key) {
- List<int> values = _map[key];
- if (values == null) {
- values = <int>[];
- }
- return values;
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/index/store/memory_node_manager.dart b/pkg/analysis_server/lib/src/services/index/store/memory_node_manager.dart
deleted file mode 100644
index 500626b..0000000
--- a/pkg/analysis_server/lib/src/services/index/store/memory_node_manager.dart
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.src.index.store.store_memory_node_manager;
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:analysis_server/src/services/index/store/codec.dart';
-import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analyzer/src/generated/engine.dart';
-
-class MemoryNodeManager implements NodeManager {
- @override
- StringCodec stringCodec = new StringCodec();
-
- @override
- ContextCodec contextCodec = new ContextCodec();
-
- @override
- ElementCodec elementCodec;
-
- RelationshipCodec _relationshipCodec;
-
- int _locationCount = 0;
- final Map<String, int> _nodeLocationCounts = new HashMap<String, int>();
- final Map<String, IndexNode> _nodes = new HashMap<String, IndexNode>();
-
- MemoryNodeManager() {
- elementCodec = new ElementCodec(stringCodec);
- _relationshipCodec = new RelationshipCodec(stringCodec);
- }
-
- @override
- int get locationCount {
- return _locationCount;
- }
-
- @override
- void clear() {
- _nodes.clear();
- }
-
- int getLocationCount(String name) {
- int locationCount = _nodeLocationCounts[name];
- return locationCount != null ? locationCount : 0;
- }
-
- @override
- Future<IndexNode> getNode(String name) {
- return new Future.value(_nodes[name]);
- }
-
- bool isEmpty() {
- for (IndexNode node in _nodes.values) {
- Map<RelationKeyData, List<LocationData>> relations = node.relations;
- if (!relations.isEmpty) {
- return false;
- }
- }
- return true;
- }
-
- @override
- IndexNode newNode(AnalysisContext context) {
- return new IndexNode(context, elementCodec, _relationshipCodec);
- }
-
- @override
- void putNode(String name, IndexNode node) {
- // update location count
- {
- _locationCount -= getLocationCount(name);
- int nodeLocationCount = node.locationCount;
- _nodeLocationCounts[name] = nodeLocationCount;
- _locationCount += nodeLocationCount;
- }
- // remember the node
- _nodes[name] = node;
- }
-
- @override
- void removeNode(String name) {
- _nodes.remove(name);
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/index/store/split_store.dart b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
deleted file mode 100644
index 86e463b..0000000
--- a/pkg/analysis_server/lib/src/services/index/store/split_store.dart
+++ /dev/null
@@ -1,1168 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.src.index.store.split_store;
-
-import 'dart:async';
-import 'dart:collection';
-import 'dart:typed_data';
-
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/index_store.dart';
-import 'package:analysis_server/src/services/index/indexable_element.dart';
-import 'package:analysis_server/src/services/index/store/codec.dart';
-import 'package:analysis_server/src/services/index/store/collection.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart' show CompilationUnit;
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_general.dart';
-
-/**
- * The implementation of [IndexObjectManager] for indexing
- * [CompilationUnitElement]s.
- */
-class DartUnitIndexObjectManager extends IndexObjectManager {
- /**
- * The mapping of library [Source] to the [Source]s of part units.
- */
- Map<AnalysisContext, Map<Source, Set<Source>>> _contextToLibraryToUnits =
- new HashMap<AnalysisContext, Map<Source, Set<Source>>>();
-
- /**
- * The mapping of unit [Source] to the [Source]s of libraries it is used in.
- */
- Map<AnalysisContext, Map<Source, Set<Source>>> _contextToUnitToLibraries =
- new HashMap<AnalysisContext, Map<Source, Set<Source>>>();
-
- @override
- String aboutToIndex(AnalysisContext context, Object object) {
- CompilationUnitElement unitElement;
- if (object is CompilationUnit) {
- unitElement = object.element;
- } else if (object is CompilationUnitElement) {
- unitElement = object;
- }
- // validate unit
- if (unitElement == null) {
- return null;
- }
- LibraryElement libraryElement = unitElement.library;
- if (libraryElement == null) {
- return null;
- }
- CompilationUnitElement definingUnitElement =
- libraryElement.definingCompilationUnit;
- if (definingUnitElement == null) {
- return null;
- }
- // prepare sources
- Source library = definingUnitElement.source;
- Source unit = unitElement.source;
- // special handling for the defining library unit
- if (unit == library) {
- // prepare new parts
- HashSet<Source> newParts = new HashSet<Source>();
- for (CompilationUnitElement part in libraryElement.parts) {
- newParts.add(part.source);
- }
- // prepare old parts
- Map<Source, Set<Source>> libraryToUnits =
- _contextToLibraryToUnits[context];
- if (libraryToUnits == null) {
- libraryToUnits = new HashMap<Source, Set<Source>>();
- _contextToLibraryToUnits[context] = libraryToUnits;
- }
- Set<Source> oldParts = libraryToUnits[library];
- // check if some parts are not in the library now
- if (oldParts != null) {
- Set<Source> noParts = oldParts.difference(newParts);
- for (Source noPart in noParts) {
- String nodeName = _getNodeName(library, noPart);
- site.removeNodeByName(context, nodeName);
- site.removeSource(library);
- site.removeSource(noPart);
- }
- }
- // remember new parts
- libraryToUnits[library] = newParts;
- }
- // remember library/unit relations
- _recordUnitInLibrary(context, library, unit);
- _recordLibraryWithUnit(context, library, unit);
- site.addSource(library);
- site.addSource(unit);
- // prepare node
- String nodeName = _getNodeName(library, unit);
- return nodeName;
- }
-
- @override
- void removeContext(AnalysisContext context) {
- _contextToLibraryToUnits.remove(context);
- _contextToUnitToLibraries.remove(context);
- }
-
- @override
- void removeSource(AnalysisContext context, Source source) {
- // remove nodes for unit/library pairs
- Map<Source, Set<Source>> unitToLibraries =
- _contextToUnitToLibraries[context];
- if (unitToLibraries != null) {
- Set<Source> libraries = unitToLibraries.remove(source);
- if (libraries != null) {
- for (Source library in libraries) {
- String nodeName = _getNodeName(library, source);
- site.removeNodeByName(context, nodeName);
- site.removeSource(library);
- site.removeSource(source);
- }
- }
- }
- // remove nodes for library/unit pairs
- Map<Source, Set<Source>> libraryToUnits = _contextToLibraryToUnits[context];
- if (libraryToUnits != null) {
- Set<Source> units = libraryToUnits.remove(source);
- if (units != null) {
- for (Source unit in units) {
- String nodeName = _getNodeName(source, unit);
- site.removeNodeByName(context, nodeName);
- site.removeSource(source);
- site.removeSource(unit);
- }
- }
- }
- }
-
- @override
- void removeSources(AnalysisContext context, SourceContainer container) {
- // remove nodes for unit/library pairs
- Map<Source, Set<Source>> unitToLibraries =
- _contextToUnitToLibraries[context];
- if (unitToLibraries != null) {
- List<Source> units = unitToLibraries.keys.toList();
- for (Source source in units) {
- if (container == null || container.contains(source)) {
- removeSource(context, source);
- }
- }
- }
- // remove nodes for library/unit pairs
- Map<Source, Set<Source>> libraryToUnits = _contextToLibraryToUnits[context];
- if (libraryToUnits != null) {
- List<Source> libraries = libraryToUnits.keys.toList();
- for (Source source in libraries) {
- if (container == null || container.contains(source)) {
- removeSource(context, source);
- }
- }
- }
- }
-
- String _getNodeName(Source library, Source unit) {
- String libraryName = library != null ? library.fullName : null;
- String unitName = unit.fullName;
- int libraryNameIndex = site.encodeString(libraryName);
- int unitNameIndex = site.encodeString(unitName);
- return 'DartUnitElement_${libraryNameIndex}_$unitNameIndex.index';
- }
-
- void _recordLibraryWithUnit(
- AnalysisContext context, Source library, Source unit) {
- Map<Source, Set<Source>> libraryToUnits = _contextToLibraryToUnits[context];
- if (libraryToUnits == null) {
- libraryToUnits = new HashMap<Source, Set<Source>>();
- _contextToLibraryToUnits[context] = libraryToUnits;
- }
- Set<Source> units = libraryToUnits[library];
- if (units == null) {
- units = new HashSet<Source>();
- libraryToUnits[library] = units;
- }
- units.add(unit);
- }
-
- void _recordUnitInLibrary(
- AnalysisContext context, Source library, Source unit) {
- Map<Source, Set<Source>> unitToLibraries =
- _contextToUnitToLibraries[context];
- if (unitToLibraries == null) {
- unitToLibraries = new HashMap<Source, Set<Source>>();
- _contextToUnitToLibraries[context] = unitToLibraries;
- }
- Set<Source> libraries = unitToLibraries[unit];
- if (libraries == null) {
- libraries = new HashSet<Source>();
- unitToLibraries[unit] = libraries;
- }
- libraries.add(library);
- }
-}
-
-/**
- * A manager for files content.
- */
-abstract class FileManager {
- /**
- * Removes all files.
- */
- void clear();
-
- /**
- * Deletes the file with the given name.
- */
- void delete(String name);
-
- /**
- * Returns names of all known nodes.
- */
- List<String> inspect_getAllNodeNames();
-
- /**
- * Read the entire file contents as a list of bytes.
- */
- Future<List<int>> read(String name);
-
- /**
- * Write a list of bytes to a file.
- */
- Future write(String name, List<int> bytes);
-}
-
-/**
- * A [FileManager] based [NodeManager].
- */
-class FileNodeManager implements NodeManager {
- static int _VERSION = 1;
-
- final FileManager _fileManager;
- final Logger _logger;
-
- final ContextCodec contextCodec;
- final ElementCodec elementCodec;
- final StringCodec stringCodec;
- final RelationshipCodec _relationshipCodec;
-
- int _locationCount = 0;
-
- Map<String, int> _nodeLocationCounts = new HashMap<String, int>();
-
- FileNodeManager(this._fileManager, this._logger, this.stringCodec,
- this.contextCodec, this.elementCodec, this._relationshipCodec);
-
- @override
- int get locationCount => _locationCount;
-
- @override
- void clear() {
- _fileManager.clear();
- }
-
- @override
- Future<IndexNode> getNode(String name) {
- return _fileManager.read(name).then((List<int> bytes) {
- if (bytes == null) {
- return null;
- }
- _DataInputStream stream = new _DataInputStream(bytes);
- return _readNode(stream);
- }).catchError((exception, stackTrace) {
- _logger.logError('Exception during reading index file $name',
- new CaughtException(exception, stackTrace));
- });
- }
-
- /**
- * Returns names of all known nodes.
- */
- List<String> inspect_getAllNodeNames() {
- return _fileManager.inspect_getAllNodeNames();
- }
-
- @override
- IndexNode newNode(AnalysisContext context) =>
- new IndexNode(context, elementCodec, _relationshipCodec);
-
- @override
- Future putNode(String name, IndexNode node) {
- // update location count
- {
- _locationCount -= _getLocationCount(name);
- int nodeLocationCount = node.locationCount;
- _nodeLocationCounts[name] = nodeLocationCount;
- _locationCount += nodeLocationCount;
- }
- // write the node
- return new Future.microtask(() {
- return ServerPerformanceStatistics.splitStore.makeCurrentWhile(() {
- _DataOutputStream stream = new _DataOutputStream();
- _writeNode(node, stream);
- var bytes = stream.getBytes();
- return _fileManager.write(name, bytes);
- });
- }).catchError((exception, stackTrace) {
- _logger.logError('Exception during reading index file $name',
- new CaughtException(exception, stackTrace));
- });
- }
-
- @override
- void removeNode(String name) {
- // update location count
- _locationCount -= _getLocationCount(name);
- _nodeLocationCounts.remove(name);
- // remove node
- _fileManager.delete(name);
- }
-
- int _getLocationCount(String name) {
- int locationCount = _nodeLocationCounts[name];
- return locationCount != null ? locationCount : 0;
- }
-
- RelationKeyData _readElementRelationKey(_DataInputStream stream) {
- int elementId1 = stream.readInt();
- int elementId2 = stream.readInt();
- int elementId3 = stream.readInt();
- int relationshipId = stream.readInt();
- return new RelationKeyData.forData(
- elementId1, elementId2, elementId3, relationshipId);
- }
-
- LocationData _readLocationData(_DataInputStream stream) {
- int elementId1 = stream.readInt();
- int elementId2 = stream.readInt();
- int elementId3 = stream.readInt();
- int offset = stream.readInt();
- int length = stream.readInt();
- int flags = stream.readInt();
- return new LocationData.forData(
- elementId1, elementId2, elementId3, offset, length, flags);
- }
-
- IndexNode _readNode(_DataInputStream stream) {
- // check version
- {
- int version = stream.readInt();
- if (version != _VERSION) {
- throw new StateError('Version $_VERSION expected, but $version found.');
- }
- }
- // context
- int contextId = stream.readInt();
- AnalysisContext context = contextCodec.decode(contextId);
- if (context == null) {
- return null;
- }
- // relations
- Map<RelationKeyData, List<LocationData>> relations =
- new HashMap<RelationKeyData, List<LocationData>>();
- int numRelations = stream.readInt();
- for (int i = 0; i < numRelations; i++) {
- RelationKeyData key = _readElementRelationKey(stream);
- int numLocations = stream.readInt();
- List<LocationData> locations = new List<LocationData>();
- for (int j = 0; j < numLocations; j++) {
- locations.add(_readLocationData(stream));
- }
- relations[key] = locations;
- }
- // create IndexNode
- IndexNode node = new IndexNode(context, elementCodec, _relationshipCodec);
- node.relations = relations;
- return node;
- }
-
- void _writeElementRelationKey(_DataOutputStream stream, RelationKeyData key) {
- stream.writeInt(key.elementId1);
- stream.writeInt(key.elementId2);
- stream.writeInt(key.elementId3);
- stream.writeInt(key.relationshipId);
- }
-
- void _writeNode(IndexNode node, _DataOutputStream stream) {
- // version
- stream.writeInt(_VERSION);
- // context
- {
- AnalysisContext context = node.context;
- int contextId = contextCodec.encode(context);
- stream.writeInt(contextId);
- }
- // relations
- Map<RelationKeyData, List<LocationData>> relations = node.relations;
- stream.writeInt(relations.length);
- relations.forEach((key, locations) {
- _writeElementRelationKey(stream, key);
- stream.writeInt(locations.length);
- for (LocationData location in locations) {
- stream.writeInt(location.elementId1);
- stream.writeInt(location.elementId2);
- stream.writeInt(location.elementId3);
- stream.writeInt(location.offset);
- stream.writeInt(location.length);
- stream.writeInt(location.flags);
- }
- });
- }
-}
-
-/**
- * A single index file in-memory presentation.
- */
-class IndexNode {
- final AnalysisContext context;
-
- final ElementCodec _elementCodec;
- final RelationshipCodec _relationshipCodec;
-
- Map<RelationKeyData, List<LocationData>> _relations =
- new HashMap<RelationKeyData, List<LocationData>>();
-
- IndexNode(this.context, this._elementCodec, this._relationshipCodec);
-
- /**
- * Returns number of locations in this node.
- */
- int get locationCount {
- int locationCount = 0;
- for (List<LocationData> locations in _relations.values) {
- locationCount += locations.length;
- }
- return locationCount;
- }
-
- /**
- * Returns the recorded relations.
- */
- Map<RelationKeyData, List<LocationData>> get relations => _relations;
-
- /**
- * Sets relations data.
- * This method is used during loading data from a storage.
- */
- void set relations(Map<RelationKeyData, List<LocationData>> relations) {
- _relations = relations;
- }
-
- /**
- * Returns the locations of the elements that have the given relationship with
- * the given element.
- *
- * [element] - the the element that has the relationship with the locations to
- * be returned.
- * [relationship] - the [RelationshipImpl] between the given [element] and the
- * locations to be returned
- */
- List<LocationImpl> getRelationships(
- IndexableObject indexable, RelationshipImpl relationship) {
- // prepare key
- RelationKeyData key = new RelationKeyData.forObject(
- _elementCodec, _relationshipCodec, indexable, relationship);
- // find LocationData(s)
- List<LocationData> locationDatas = _relations[key];
- if (locationDatas == null) {
- return LocationImpl.EMPTY_LIST;
- }
- // convert to Location(s)
- List<LocationImpl> locations = <LocationImpl>[];
- for (LocationData locationData in locationDatas) {
- LocationImpl location = locationData.getLocation(context, _elementCodec);
- if (location != null) {
- locations.add(location);
- }
- }
- return locations;
- }
-
- /**
- * Returns [InspectLocation]s for the element with the given ID.
- */
- List<InspectLocation> inspect_getRelations(String name, int elementId) {
- List<InspectLocation> result = <InspectLocation>[];
- // TODO(scheglov) restore index inspections?
-// _relations.forEach((RelationKeyData key, locations) {
-// if (key.elementId == elementId) {
-// for (LocationData location in locations) {
-// Relationship relationship =
-// _relationshipCodec.decode(key.relationshipId);
-// List<String> path =
-// _elementCodec.inspect_decodePath(location.elementId);
-// result.add(new InspectLocation(name, relationship, path,
-// location.offset, location.length, location.flags));
-// }
-// }
-// });
- return result;
- }
-
- /**
- * Records that the given [element] and [location] have the given [relationship].
- *
- * [element] - the [Element] that is related to the location.
- * [relationship] - the [RelationshipImpl] between [element] and [location].
- * [location] - the [LocationImpl] where relationship happens.
- */
- void recordRelationship(IndexableObject indexable,
- RelationshipImpl relationship, LocationImpl location) {
- RelationKeyData key = new RelationKeyData.forObject(
- _elementCodec, _relationshipCodec, indexable, relationship);
- // prepare LocationData(s)
- List<LocationData> locationDatas = _relations[key];
- if (locationDatas == null) {
- locationDatas = <LocationData>[];
- _relations[key] = locationDatas;
- }
- // add new LocationData
- locationDatas.add(new LocationData.forObject(_elementCodec, location));
- }
-}
-
-/**
- * [SplitIndexStore] uses instances of this class to manager index nodes.
- */
-abstract class IndexObjectManager {
- SplitIndexStoreSite site;
-
- /**
- * Notifies the manager that the given [object] is to be indexed.
- * Returns the name of the index node to put information into.
- */
- String aboutToIndex(AnalysisContext context, Object object);
-
- /**
- * Notifies the manager that the given [context] is disposed.
- */
- void removeContext(AnalysisContext context);
-
- /**
- * Notifies the manager that the given [source] is no longer part of
- * the given [context].
- */
- void removeSource(AnalysisContext context, Source source);
-
- /**
- * Notifies the manager that the sources described by the given [container]
- * are no longer part of the given [context].
- */
- void removeSources(AnalysisContext context, SourceContainer container);
-}
-
-class InspectLocation {
- final String nodeName;
- final RelationshipImpl relationship;
- final List<String> path;
- final int offset;
- final int length;
- final int flags;
-
- InspectLocation(this.nodeName, this.relationship, this.path, this.offset,
- this.length, this.flags);
-}
-
-/**
- * A container with information about a [LocationImpl].
- */
-class LocationData {
- static const int _FLAG_QUALIFIED = 1 << 0;
- static const int _FLAG_RESOLVED = 1 << 1;
-
- final int elementId1;
- final int elementId2;
- final int elementId3;
- final int offset;
- final int length;
- final int flags;
-
- LocationData.forData(this.elementId1, this.elementId2, this.elementId3,
- this.offset, this.length, this.flags);
-
- LocationData.forObject(ElementCodec elementCodec, LocationImpl location)
- : elementId1 = elementCodec.encode1(location.indexable),
- elementId2 = elementCodec.encode2(location.indexable),
- elementId3 = elementCodec.encode3(location.indexable),
- offset = location.offset,
- length = location.length,
- flags = (location.isQualified ? _FLAG_QUALIFIED : 0) |
- (location.isResolved ? _FLAG_RESOLVED : 0);
-
- @override
- int get hashCode {
- int hash = 0;
- hash = JenkinsSmiHash.combine(hash, elementId1);
- hash = JenkinsSmiHash.combine(hash, elementId2);
- hash = JenkinsSmiHash.combine(hash, elementId3);
- hash = JenkinsSmiHash.combine(hash, offset);
- hash = JenkinsSmiHash.combine(hash, length);
- return JenkinsSmiHash.finish(hash);
- }
-
- @override
- bool operator ==(Object obj) {
- if (obj is! LocationData) {
- return false;
- }
- LocationData other = obj;
- return other.elementId1 == elementId1 &&
- other.elementId2 == elementId2 &&
- other.elementId3 == elementId3 &&
- other.offset == offset &&
- other.length == length &&
- other.flags == flags;
- }
-
- /**
- * Returns a {@link Location} that is represented by this {@link LocationData}.
- */
- LocationImpl getLocation(AnalysisContext context, ElementCodec elementCodec) {
- IndexableObject indexable =
- elementCodec.decode(context, elementId1, elementId2, elementId3);
- if (indexable == null) {
- return null;
- }
- bool isQualified = (flags & _FLAG_QUALIFIED) != 0;
- bool isResovled = (flags & _FLAG_RESOLVED) != 0;
- return new LocationImpl(indexable, offset, length,
- isQualified: isQualified, isResolved: isResovled);
- }
-}
-
-/**
- * A manager for [IndexNode]s.
- */
-abstract class NodeManager {
- /**
- * The shared {@link ContextCodec} instance.
- */
- ContextCodec get contextCodec;
-
- /**
- * The shared {@link ElementCodec} instance.
- */
- ElementCodec get elementCodec;
-
- /**
- * A number of locations in all nodes.
- */
- int get locationCount;
-
- /**
- * The shared {@link StringCodec} instance.
- */
- StringCodec get stringCodec;
-
- /**
- * Removes all nodes.
- */
- void clear();
-
- /**
- * Returns the {@link IndexNode} with the given name, {@code null} if not found.
- */
- Future<IndexNode> getNode(String name);
-
- /**
- * Returns a new {@link IndexNode}.
- */
- IndexNode newNode(AnalysisContext context);
-
- /**
- * Associates the given {@link IndexNode} with the given name.
- */
- void putNode(String name, IndexNode node);
-
- /**
- * Removes the {@link IndexNode} with the given name.
- */
- void removeNode(String name);
-}
-
-/**
- * An [Element] to [LocationImpl] relation key.
- */
-class RelationKeyData {
- final int elementId1;
- final int elementId2;
- final int elementId3;
- final int relationshipId;
-
- RelationKeyData.forData(
- this.elementId1, this.elementId2, this.elementId3, this.relationshipId);
-
- RelationKeyData.forObject(
- ElementCodec elementCodec,
- RelationshipCodec relationshipCodec,
- IndexableObject indexable,
- RelationshipImpl relationship)
- : elementId1 = elementCodec.encode1(indexable),
- elementId2 = elementCodec.encode2(indexable),
- elementId3 = elementCodec.encode3(indexable),
- relationshipId = relationshipCodec.encode(relationship);
-
- @override
- int get hashCode {
- int hash = 0;
- hash = JenkinsSmiHash.combine(hash, elementId1);
- hash = JenkinsSmiHash.combine(hash, elementId2);
- hash = JenkinsSmiHash.combine(hash, elementId3);
- hash = JenkinsSmiHash.combine(hash, relationshipId);
- return JenkinsSmiHash.finish(hash);
- }
-
- @override
- bool operator ==(Object obj) {
- if (obj is! RelationKeyData) {
- return false;
- }
- RelationKeyData other = obj;
- return other.elementId1 == elementId1 &&
- other.elementId2 == elementId2 &&
- other.elementId3 == elementId3 &&
- other.relationshipId == relationshipId;
- }
-
- @override
- String toString() {
- return 'Key($elementId2, $elementId2, $elementId3, $relationshipId)';
- }
-}
-
-/**
- * An [InternalIndexStore] which keeps index information in separate nodes for
- * each unit.
- */
-class SplitIndexStore implements InternalIndexStore {
- /**
- * The [NodeManager] to get/put [IndexNode]s.
- */
- final NodeManager _nodeManager;
-
- final List<IndexObjectManager> _objectManagers;
-
- /**
- * The [ContextCodec] to encode/decode [AnalysisContext]s.
- */
- final ContextCodec _contextCodec;
-
- /**
- * The [ElementCodec] to encode/decode [Element]s.
- */
- final ElementCodec _elementCodec;
-
- /**
- * The [StringCodec] to encode/decode [String]s.
- */
- final StringCodec _stringCodec;
-
- /**
- * Information about top-level elements.
- * We need to keep them together to avoid loading of all index nodes.
- *
- * Order of keys: contextId, nodeId.
- */
- final Map<int, Map<int, List<_TopElementData>>> _topDeclarations =
- new Map<int, Map<int, List<_TopElementData>>>();
-
- int _currentContextId;
- String _currentNodeName;
- int _currentNodeNameId;
- IndexNode _currentNode;
-
- /**
- * A table mapping element names to the node names that may have relations with elements with
- * these names.
- */
- final Map<RelationshipImpl, IntToIntSetMap> _relToNameMap =
- new HashMap<RelationshipImpl, IntToIntSetMap>();
-
- /**
- * The set of known [Source]s.
- */
- final Set<Source> _sources = new HashSet<Source>();
-
- SplitIndexStore(NodeManager _nodeManager, this._objectManagers)
- : _nodeManager = _nodeManager,
- _contextCodec = _nodeManager.contextCodec,
- _elementCodec = _nodeManager.elementCodec,
- _stringCodec = _nodeManager.stringCodec {
- SplitIndexStoreSiteImpl site = new SplitIndexStoreSiteImpl(this);
- for (IndexObjectManager manager in _objectManagers) {
- manager.site = site;
- }
- }
-
- @override
- String get statistics {
- StringBuffer buf = new StringBuffer();
- buf.write('[');
- buf.write(_nodeManager.locationCount);
- buf.write(' locations, ');
- buf.write(_sources.length);
- buf.write(' sources, ');
- int namesCount = _relToNameMap.values.fold(0, (c, m) => c + m.length);
- buf.write(namesCount);
- buf.write(' names');
- buf.write(']');
- return buf.toString();
- }
-
- @override
- bool aboutToIndex(AnalysisContext context, Object object) {
- if (context == null || context.isDisposed) {
- return false;
- }
- // try to find a node name
- _currentNodeName = null;
- for (IndexObjectManager manager in _objectManagers) {
- _currentNodeName = manager.aboutToIndex(context, object);
- if (_currentNodeName != null) {
- break;
- }
- }
- if (_currentNodeName == null) {
- return false;
- }
- // prepare node
- _currentNodeNameId = _stringCodec.encode(_currentNodeName);
- _currentNode = _nodeManager.newNode(context);
- _currentContextId = _contextCodec.encode(context);
- // remove top-level information for the current node
- for (Map<int, dynamic> nodeRelations in _topDeclarations.values) {
- nodeRelations.remove(_currentNodeNameId);
- }
- // done
- return true;
- }
-
- @override
- void cancelIndex() {
- if (_currentNode != null) {
- // remove top-level information for the current node
- for (Map<int, dynamic> nodeRelations in _topDeclarations.values) {
- nodeRelations.remove(_currentNodeNameId);
- }
- // clear fields
- _currentNodeName = null;
- _currentNodeNameId = -1;
- _currentNode = null;
- _currentContextId = -1;
- }
- }
-
- @override
- void clear() {
- _topDeclarations.clear();
- _nodeManager.clear();
- _relToNameMap.clear();
- }
-
- @override
- void doneIndex() {
- if (_currentNode != null) {
- _nodeManager.putNode(_currentNodeName, _currentNode);
- _currentNodeName = null;
- _currentNodeNameId = -1;
- _currentNode = null;
- _currentContextId = -1;
- }
- }
-
- Future<List<LocationImpl>> getRelationships(
- IndexableObject indexable, RelationshipImpl relationship) {
- // prepare node names
- List<int> nodeNameIds;
- {
- int nameId = _elementCodec.encodeHash(indexable);
- IntToIntSetMap nameToNodeNames = _relToNameMap[relationship];
- if (nameToNodeNames != null) {
- nodeNameIds = nameToNodeNames.get(nameId);
- } else {
- nodeNameIds = <int>[];
- }
- }
- // prepare Future(s) for reading each IndexNode
- List<Future<List<LocationImpl>>> nodeFutures =
- <Future<List<LocationImpl>>>[];
- for (int nodeNameId in nodeNameIds) {
- String nodeName = _stringCodec.decode(nodeNameId);
- Future<IndexNode> nodeFuture = _nodeManager.getNode(nodeName);
- Future<List<LocationImpl>> locationsFuture = nodeFuture.then((node) {
- if (node == null) {
- // TODO(scheglov) remove node
- return LocationImpl.EMPTY_LIST;
- }
- return node.getRelationships(indexable, relationship);
- });
- nodeFutures.add(locationsFuture);
- }
- // return Future that merges separate IndexNode Location(s)
- return Future
- .wait(nodeFutures)
- .then((List<List<LocationImpl>> locationsList) {
- List<LocationImpl> allLocations = <LocationImpl>[];
- for (List<LocationImpl> locations in locationsList) {
- allLocations.addAll(locations);
- }
- return allLocations;
- });
- }
-
- List<Element> getTopLevelDeclarations(ElementNameFilter nameFilter) {
- List<Element> elements = <Element>[];
- _topDeclarations.forEach((contextId, contextLocations) {
- AnalysisContext context = _contextCodec.decode(contextId);
- if (context != null) {
- for (List<_TopElementData> topDataList in contextLocations.values) {
- for (_TopElementData topData in topDataList) {
- if (nameFilter(topData.name)) {
- IndexableObject indexable =
- topData.getElement(context, _elementCodec);
- if (indexable is IndexableElement) {
- elements.add(indexable.element);
- }
- }
- }
- }
- }
- });
- return elements;
- }
-
- /**
- * Returns all relations with [Element]s with the given [name].
- */
- Future<Map<List<String>, List<InspectLocation>>> inspect_getElementRelations(
- String name) {
- Map<List<String>, List<InspectLocation>> result =
- <List<String>, List<InspectLocation>>{};
- // TODO(scheglov) restore index inspections?
- return new Future.value(result);
-// // prepare elements
-// Map<int, List<String>> elementMap = _elementCodec.inspect_getElements(name);
-// // prepare relations with each element
-// List<Future> futures = <Future>[];
-// if (_nodeManager is FileNodeManager) {
-// List<String> nodeNames =
-// (_nodeManager as FileNodeManager).inspect_getAllNodeNames();
-// nodeNames.forEach((nodeName) {
-// Future<IndexNode> nodeFuture = _nodeManager.getNode(nodeName);
-// Future relationsFuture = nodeFuture.then((node) {
-// if (node != null) {
-// elementMap.forEach((int elementId, List<String> elementPath) {
-// List<InspectLocation> relations =
-// node.inspect_getRelations(nodeName, elementId);
-// List<InspectLocation> resultLocations = result[elementPath];
-// if (resultLocations == null) {
-// resultLocations = <InspectLocation>[];
-// result[elementPath] = resultLocations;
-// }
-// resultLocations.addAll(relations);
-// });
-// }
-// });
-// futures.add(relationsFuture);
-// });
-// }
-// // wait for all nodex
-// return Future.wait(futures).then((_) {
-// return result;
-// });
- }
-
- @override
- void recordRelationship(IndexableObject indexable,
- RelationshipImpl relationship, LocationImpl location) {
- if (indexable == null ||
- (indexable is IndexableElement &&
- indexable.element is MultiplyDefinedElement)) {
- return;
- }
- if (location == null) {
- return;
- }
- // other elements
- _recordNodeNameForElement(indexable, relationship);
- _currentNode.recordRelationship(indexable, relationship, location);
- }
-
- void recordTopLevelDeclaration(Element element) {
- // in current context
- Map<int, List<_TopElementData>> nodeDeclarations =
- _topDeclarations[_currentContextId];
- if (nodeDeclarations == null) {
- nodeDeclarations = new Map<int, List<_TopElementData>>();
- _topDeclarations[_currentContextId] = nodeDeclarations;
- }
- // in current node
- List<_TopElementData> declarations = nodeDeclarations[_currentNodeNameId];
- if (declarations == null) {
- declarations = <_TopElementData>[];
- nodeDeclarations[_currentNodeNameId] = declarations;
- }
- // record LocationData
- declarations.add(new _TopElementData(
- _elementCodec, element.displayName, new IndexableElement(element)));
- }
-
- @override
- void removeContext(AnalysisContext context) {
- if (context == null) {
- return;
- }
- // remove sources
- removeSources(context, null);
- // remove context information
- for (IndexObjectManager manager in _objectManagers) {
- manager.removeContext(context);
- }
- _topDeclarations.remove(_contextCodec.encode(context));
- // remove context from codec
- _contextCodec.remove(context);
- }
-
- @override
- void removeSource(AnalysisContext context, Source source) {
- if (context == null) {
- return;
- }
- for (IndexObjectManager manager in _objectManagers) {
- manager.removeSource(context, source);
- }
- }
-
- @override
- void removeSources(AnalysisContext context, SourceContainer container) {
- if (context == null) {
- return;
- }
- for (IndexObjectManager manager in _objectManagers) {
- manager.removeSources(context, container);
- }
- }
-
- void _recordNodeNameForElement(
- IndexableObject indexable, RelationshipImpl relationship) {
- IntToIntSetMap nameToNodeNames = _relToNameMap[relationship];
- if (nameToNodeNames == null) {
- nameToNodeNames = new IntToIntSetMap();
- _relToNameMap[relationship] = nameToNodeNames;
- }
- int nameId = _elementCodec.encodeHash(indexable);
- nameToNodeNames.add(nameId, _currentNodeNameId);
- }
-
- void _removeNodeByName(AnalysisContext context, String nodeName) {
- int nodeNameId = _stringCodec.encode(nodeName);
- _nodeManager.removeNode(nodeName);
- // remove top-level relations
- {
- int contextId = _contextCodec.encode(context);
- Map<int, dynamic> nodeRelations = _topDeclarations[contextId];
- if (nodeRelations != null) {
- nodeRelations.remove(nodeNameId);
- }
- }
- }
-}
-
-/**
- * Interface to [SplitIndexStore] for [IndexObjectManager] implementations.
- */
-abstract class SplitIndexStoreSite {
- void addSource(Source source);
- int encodeString(String str);
- void removeNodeByName(AnalysisContext context, String nodeName);
- void removeSource(Source source);
-}
-
-/**
- * The implementaiton of [SplitIndexStoreSite].
- */
-class SplitIndexStoreSiteImpl implements SplitIndexStoreSite {
- final SplitIndexStore store;
-
- SplitIndexStoreSiteImpl(this.store);
-
- @override
- void addSource(Source source) {
- store._sources.add(source);
- }
-
- @override
- int encodeString(String str) {
- return store._stringCodec.encode(str);
- }
-
- @override
- void removeNodeByName(AnalysisContext context, String nodeName) {
- store._removeNodeByName(context, nodeName);
- }
-
- @override
- void removeSource(Source source) {
- store._sources.remove(source);
- }
-}
-
-class _DataInputStream {
- ByteData _byteData;
- int _byteOffset = 0;
-
- _DataInputStream(List<int> bytes) {
- ByteBuffer buffer = new Uint8List.fromList(bytes).buffer;
- _byteData = new ByteData.view(buffer);
- }
-
- int readInt() {
- int result = _byteData.getInt32(_byteOffset, Endianness.HOST_ENDIAN);
- _byteOffset += 4;
- return result;
- }
-}
-
-class _DataOutputStream {
- static const LIST_SIZE = 1024;
- int _size = LIST_SIZE;
- Uint32List _buf = new Uint32List(LIST_SIZE);
- int _pos = 0;
-
- Uint8List getBytes() {
- return new Uint8List.view(_buf.buffer, 0, _size << 2);
- }
-
- void writeInt(int value) {
- if (_pos == _size) {
- int newSize = _size << 1;
- Uint32List newBuf = new Uint32List(newSize);
- newBuf.setRange(0, _size, _buf);
- _size = newSize;
- _buf = newBuf;
- }
- _buf[_pos++] = value;
- }
-}
-
-class _TopElementData {
- final String name;
- final int elementId1;
- final int elementId2;
- final int elementId3;
-
- factory _TopElementData(
- ElementCodec elementCodec, String name, IndexableObject indexable) {
- return new _TopElementData._(name, elementCodec.encode1(indexable),
- elementCodec.encode2(indexable), elementCodec.encode3(indexable));
- }
-
- _TopElementData._(
- this.name, this.elementId1, this.elementId2, this.elementId3);
-
- IndexableObject getElement(
- AnalysisContext context, ElementCodec elementCodec) {
- return elementCodec.decode(context, elementId1, elementId2, elementId3);
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/index/store/temporary_folder_file_manager.dart b/pkg/analysis_server/lib/src/services/index/store/temporary_folder_file_manager.dart
deleted file mode 100644
index 9ba9473..0000000
--- a/pkg/analysis_server/lib/src/services/index/store/temporary_folder_file_manager.dart
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.src.index.store.temporary_folder_file_mananer;
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:path/path.dart' as pathos;
-
-/**
- * An implementation of [FileManager] that keeps each file in a separate file
- * in a temporary folder.
- */
-class TemporaryFolderFileManager implements FileManager {
- Directory _directory;
-
- Directory get test_directory => _directory;
-
- @override
- void clear() {
- if (_directory != null) {
- try {
- _directory.deleteSync(recursive: true);
- } on FileSystemException {
- // For some reason, on Windows this sometimes results in the error:
- // "FileSystemException: Deletion failed, path = '...' (OS Error: The
- // process cannot access the file because it is being used by another
- // process., errno = 32). (Speculation: perhaps createTempSync is not
- // successfully creating a unique name, so multiple processes are
- // trying to access the same file?)
- //
- // For now, work around the problem by ignoring the exception.
- // TODO(paulberry): fix the actual root cause of this bug.
- }
- _directory = null;
- }
- }
-
- @override
- void delete(String name) {
- if (_directory == null) {
- return;
- }
- File file = _getFile(name);
- try {
- file.deleteSync();
- } catch (e) {}
- }
-
- @override
- List<String> inspect_getAllNodeNames() {
- List<String> names = <String>[];
- List<FileSystemEntity> filePathList = _directory.listSync();
- for (FileSystemEntity file in filePathList) {
- String filePath = file.path;
- String name = pathos.basename(filePath);
- names.add(name);
- }
- return names;
- }
-
- @override
- Future<List<int>> read(String name) {
- if (_directory == null) {
- return new Future.value(null);
- }
- File file = _getFile(name);
- return file.readAsBytes().catchError((e) {
- return null;
- });
- }
-
- @override
- Future write(String name, List<int> bytes) {
- _ensureDirectory();
- return _getFile(name).writeAsBytes(bytes);
- }
-
- void _ensureDirectory() {
- if (_directory == null) {
- Directory temp = Directory.systemTemp;
- _directory = temp.createTempSync('AnalysisServices_Index');
- }
- }
-
- File _getFile(String name) {
- String path = pathos.join(_directory.path, name);
- return new File(path);
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/index2/index2.dart b/pkg/analysis_server/lib/src/services/index2/index2.dart
deleted file mode 100644
index a3da32b..0000000
--- a/pkg/analysis_server/lib/src/services/index2/index2.dart
+++ /dev/null
@@ -1,456 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/index_unit.dart';
-import 'package:collection/collection.dart';
-
-/**
- * Return a new [Index2] instance that keeps information in memory.
- */
-Index2 createMemoryIndex2() {
- _MemoryPackageIndexStore store = new _MemoryPackageIndexStore();
- return new Index2(store);
-}
-
-/**
- * Return the index of the first occurrence of the [value] in the [sortedList],
- * or `-1` if the [value] is not in the list.
- */
-int _findFirstOccurrence(List<int> sortedList, int value) {
- // Find an occurrence.
- int i = binarySearch(sortedList, value);
- if (i == -1) {
- return -1;
- }
- // Find the first occurrence.
- while (i > 0 && sortedList[i - 1] == value) {
- i--;
- }
- return i;
-}
-
-/**
- * Interface for storing and requesting relations.
- */
-class Index2 {
- final PackageIndexStore _store;
-
- Index2(this._store);
-
- /**
- * Complete with a list of locations where elements of the given [kind] with
- * names satisfying the given [regExp] are defined.
- */
- Future<List<Location>> getDefinedNames(
- RegExp regExp, IndexNameKind kind) async {
- List<Location> locations = <Location>[];
- Iterable<PackageIndexId> ids = await _store.getIds();
- for (PackageIndexId id in ids) {
- PackageIndex index = await _store.getIndex(id);
- _PackageIndexRequester requester = new _PackageIndexRequester(index);
- List<Location> packageLocations = requester.getDefinedNames(regExp, kind);
- locations.addAll(packageLocations);
- }
- return locations;
- }
-
- /**
- * Complete with a list of locations where the given [element] has relation
- * of the given [kind].
- */
- Future<List<Location>> getRelations(
- Element element, IndexRelationKind kind) async {
- List<Location> locations = <Location>[];
- Iterable<PackageIndexId> ids = await _store.getIds();
- for (PackageIndexId id in ids) {
- PackageIndex index = await _store.getIndex(id);
- _PackageIndexRequester requester = new _PackageIndexRequester(index);
- List<Location> packageLocations = requester.getRelations(element, kind);
- locations.addAll(packageLocations);
- }
- return locations;
- }
-
- /**
- * Complete with a list of locations where a class members with the given
- * [name] is referenced with a qualifier, but is not resolved.
- */
- Future<List<Location>> getUnresolvedMemberReferences(String name) async {
- List<Location> locations = <Location>[];
- Iterable<PackageIndexId> ids = await _store.getIds();
- for (PackageIndexId id in ids) {
- PackageIndex index = await _store.getIndex(id);
- _PackageIndexRequester requester = new _PackageIndexRequester(index);
- List<Location> packageLocations =
- requester.getUnresolvedMemberReferences(name);
- locations.addAll(packageLocations);
- }
- return locations;
- }
-
- /**
- * Index the given fully resolved [unit].
- */
- void indexUnit(CompilationUnit unit) {
- PackageIndexAssembler assembler = new PackageIndexAssembler();
- assembler.index(unit);
- PackageIndexBuilder indexBuilder = assembler.assemble();
- String unitLibraryUri = unit.element.library.source.uri.toString();
- String unitUnitUri = unit.element.source.uri.toString();
- _store.putIndex(unitLibraryUri, unitUnitUri, indexBuilder);
- }
-}
-
-/**
- * Information about location of a single relation in the index.
- *
- * The location is expressed as a library specific unit containing the index
- * relation, offset within this [Source] and length.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-class Location {
- /**
- * The URI of the source of the library containing this location.
- */
- final String libraryUri;
-
- /**
- * The URI of the source of the unit containing this location.
- */
- final String unitUri;
-
- /**
- * The offset of this location within the [unitUri].
- */
- final int offset;
-
- /**
- * The length of this location.
- */
- final int length;
-
- /**
- * Is `true` if this location is qualified.
- */
- final bool isQualified;
-
- Location(this.libraryUri, this.unitUri, this.offset, this.length,
- this.isQualified);
-
- @override
- String toString() => 'Location{librarySourceUri: $libraryUri, '
- 'unitSourceUri: $unitUri, offset: $offset, length: $length, '
- 'isQualified: $isQualified}';
-}
-
-/**
- * Opaque identifier of a [PackageIndex].
- */
-abstract class PackageIndexId {}
-
-/**
- * Storage of [PackageIndex] objects.
- */
-abstract class PackageIndexStore {
- /**
- * Complete with identifiers of all [PackageIndex] objects.
- */
- Future<Iterable<PackageIndexId>> getIds();
-
- /**
- * Complete with the [PackageIndex] with the given [id].
- */
- Future<PackageIndex> getIndex(PackageIndexId id);
-
- /**
- * Put the given [indexBuilder] into the store.
- */
- void putIndex(String unitLibraryUri, String unitUnitUri,
- PackageIndexBuilder indexBuilder);
-}
-
-/**
- * A [PackageIndexId] for [_MemoryPackageIndexStore].
- */
-class _MemoryPackageIndexId implements PackageIndexId {
- final String key;
-
- _MemoryPackageIndexId(this.key);
-}
-
-/**
- * A [PackageIndexStore] that keeps objects in memory;
- */
-class _MemoryPackageIndexStore implements PackageIndexStore {
- final Map<String, PackageIndex> indexMap = <String, PackageIndex>{};
-
- @override
- Future<Iterable<PackageIndexId>> getIds() async {
- return indexMap.keys.map((key) => new _MemoryPackageIndexId(key));
- }
-
- @override
- Future<PackageIndex> getIndex(PackageIndexId id) async {
- return indexMap[(id as _MemoryPackageIndexId).key];
- }
-
- @override
- putIndex(String unitLibraryUri, String unitUnitUri,
- PackageIndexBuilder indexBuilder) {
- List<int> indexBytes = indexBuilder.toBuffer();
- PackageIndex index = new PackageIndex.fromBuffer(indexBytes);
- String key = '$unitLibraryUri;$unitUnitUri';
- indexMap[key] = index;
- }
-}
-
-/**
- * Helper for requesting information from a single [PackageIndex].
- */
-class _PackageIndexRequester {
- final PackageIndex index;
-
- _PackageIndexRequester(this.index);
-
- /**
- * Return the [element]'s identifier in the [index] or `-1` if the
- * [element] is not referenced in the [index].
- */
- int findElementId(Element element) {
- // Find the id of the element's unit.
- int unitId = getUnitId(element);
- if (unitId == -1) {
- return -1;
- }
- // Prepare the offset of the element.
- int offset = element.nameOffset;
- if (element is LibraryElement || element is CompilationUnitElement) {
- offset = 0;
- }
- // Find the first occurrence of an element with the same offset.
- int elementId = _findFirstOccurrence(index.elementOffsets, offset);
- if (elementId == -1) {
- return -1;
- }
- // Try to find the element id using offset, unit and kind.
- IndexSyntheticElementKind kind =
- PackageIndexAssembler.getIndexElementKind(element);
- for (;
- elementId < index.elementOffsets.length &&
- index.elementOffsets[elementId] == offset;
- elementId++) {
- if (index.elementUnits[elementId] == unitId &&
- index.elementKinds[elementId] == kind) {
- return elementId;
- }
- }
- return -1;
- }
-
- /**
- * Complete with a list of locations where elements of the given [kind] with
- * names satisfying the given [regExp] are defined.
- */
- List<Location> getDefinedNames(RegExp regExp, IndexNameKind kind) {
- List<Location> locations = <Location>[];
- for (UnitIndex unitIndex in index.units) {
- _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex);
- List<Location> unitLocations = requester.getDefinedNames(regExp, kind);
- locations.addAll(unitLocations);
- }
- return locations;
- }
-
- /**
- * Complete with a list of locations where the given [element] has relation
- * of the given [kind].
- */
- List<Location> getRelations(Element element, IndexRelationKind kind) {
- int elementId = findElementId(element);
- if (elementId == -1) {
- return const <Location>[];
- }
- List<Location> locations = <Location>[];
- for (UnitIndex unitIndex in index.units) {
- _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex);
- List<Location> unitLocations = requester.getRelations(elementId, kind);
- locations.addAll(unitLocations);
- }
- return locations;
- }
-
- /**
- * Return the identifier of [str] in the [index] or `-1` if [str] is not used
- * in the [index].
- */
- int getStringId(String str) {
- return binarySearch(index.strings, str);
- }
-
- /**
- * Return the identifier of the [CompilationUnitElement] containing the
- * [element] in the [index] or `-1` if not found.
- */
- int getUnitId(Element element) {
- CompilationUnitElement unitElement =
- PackageIndexAssembler.getUnitElement(element);
- int libraryUriId = getUriId(unitElement.library.source.uri);
- if (libraryUriId == -1) {
- return -1;
- }
- int unitUriId = getUriId(unitElement.source.uri);
- if (unitUriId == -1) {
- return -1;
- }
- for (int i = 0; i < index.unitLibraryUris.length; i++) {
- if (index.unitLibraryUris[i] == libraryUriId &&
- index.unitUnitUris[i] == unitUriId) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Return the URI of the library source of the library specific [unit].
- */
- String getUnitLibraryUri(int unit) {
- int id = index.unitLibraryUris[unit];
- return index.strings[id];
- }
-
- /**
- * Return the URI of the unit source of the library specific [unit].
- */
- String getUnitUnitUri(int unit) {
- int id = index.unitUnitUris[unit];
- return index.strings[id];
- }
-
- /**
- * Complete with a list of locations where a class members with the given
- * [name] is referenced with a qualifier, but is not resolved.
- */
- List<Location> getUnresolvedMemberReferences(String name) {
- List<Location> locations = <Location>[];
- for (UnitIndex unitIndex in index.units) {
- _UnitIndexRequester requester = new _UnitIndexRequester(this, unitIndex);
- List<Location> unitLocations =
- requester.getUnresolvedMemberReferences(name);
- locations.addAll(unitLocations);
- }
- return locations;
- }
-
- /**
- * Return the identifier of the [uri] in the [index] or `-1` if the [uri] is
- * not used in the [index].
- */
- int getUriId(Uri uri) {
- String str = uri.toString();
- return getStringId(str);
- }
-}
-
-/**
- * Helper for requesting information from a single [UnitIndex].
- */
-class _UnitIndexRequester {
- final _PackageIndexRequester packageRequester;
- final UnitIndex unitIndex;
-
- _UnitIndexRequester(this.packageRequester, this.unitIndex);
-
- /**
- * Complete with a list of locations where elements of the given [kind] with
- * names satisfying the given [regExp] are defined.
- */
- List<Location> getDefinedNames(RegExp regExp, IndexNameKind kind) {
- List<Location> locations = <Location>[];
- String unitLibraryUri = null;
- String unitUnitUri = null;
- for (int i = 0; i < unitIndex.definedNames.length; i++) {
- if (unitIndex.definedNameKinds[i] == kind) {
- int nameIndex = unitIndex.definedNames[i];
- String name = packageRequester.index.strings[nameIndex];
- if (regExp.matchAsPrefix(name) != null) {
- unitLibraryUri ??= packageRequester.getUnitLibraryUri(unitIndex.unit);
- unitUnitUri ??= packageRequester.getUnitUnitUri(unitIndex.unit);
- locations.add(new Location(unitLibraryUri, unitUnitUri,
- unitIndex.definedNameOffsets[i], name.length, false));
- }
- }
- }
- return locations;
- }
-
- /**
- * Return a list of locations where an element with the given [elementId] has
- * relation of the given [kind].
- */
- List<Location> getRelations(int elementId, IndexRelationKind kind) {
- // Find the first usage of the element.
- int i = _findFirstOccurrence(unitIndex.usedElements, elementId);
- if (i == -1) {
- return const <Location>[];
- }
- // Create locations for every usage of the element.
- List<Location> locations = <Location>[];
- String unitLibraryUri = null;
- String unitUnitUri = null;
- for (;
- i < unitIndex.usedElements.length &&
- unitIndex.usedElements[i] == elementId;
- i++) {
- if (unitIndex.usedElementKinds[i] == kind) {
- unitLibraryUri ??= packageRequester.getUnitLibraryUri(unitIndex.unit);
- unitUnitUri ??= packageRequester.getUnitUnitUri(unitIndex.unit);
- locations.add(new Location(
- unitLibraryUri,
- unitUnitUri,
- unitIndex.usedElementOffsets[i],
- unitIndex.usedElementLengths[i],
- unitIndex.usedElementIsQualifiedFlags[i]));
- }
- }
- return locations;
- }
-
- /**
- * Complete with a list of locations where a class members with the given
- * [name] is referenced with a qualifier, but is not resolved.
- */
- List<Location> getUnresolvedMemberReferences(String name) {
- // Find the name ID in the package index.
- int nameId = packageRequester.getStringId(name);
- if (nameId == -1) {
- return const <Location>[];
- }
- // Find the first usage of the name.
- int i =_findFirstOccurrence(unitIndex.usedNames, nameId);
- if (i == -1) {
- return const <Location>[];
- }
- // Create locations for every usage of the name.
- List<Location> locations = <Location>[];
- String unitLibraryUri = null;
- String unitUnitUri = null;
- for (; i < unitIndex.usedNames.length &&
- unitIndex.usedNames[i] == nameId; i++) {
- unitLibraryUri ??= packageRequester.getUnitLibraryUri(unitIndex.unit);
- unitUnitUri ??= packageRequester.getUnitUnitUri(unitIndex.unit);
- locations.add(new Location(unitLibraryUri, unitUnitUri,
- unitIndex.usedNameOffsets[i], name.length, true));
- }
- return locations;
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
index d91306c..de6e761 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
@@ -13,9 +13,9 @@
import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.dart';
/**
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
index 59803be..b742612 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
@@ -13,8 +13,9 @@
import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/source.dart';
/**
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index bb513ba..5387a81 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -19,7 +19,9 @@
import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index b2223d0..8e059bc 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -20,10 +20,12 @@
import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
import 'package:analysis_server/src/services/search/element_visitors.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/resolver.dart' show ExitDetector;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
index d5c6894..6312658 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
@@ -13,9 +13,10 @@
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index 125c7ba..c136c21 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -16,8 +16,10 @@
import 'package:analysis_server/src/services/search/element_visitors.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index 5bf3194..b4abf87 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -24,9 +24,9 @@
import 'package:analysis_server/src/services/refactoring/rename_local.dart';
import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index 06b88c0..cdc8c2d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -16,8 +16,8 @@
import 'package:analysis_server/src/services/refactoring/rename.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart' show Identifier;
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart' show Identifier;
import 'package:analyzer/src/generated/java_core.dart';
/**
@@ -96,10 +96,6 @@
await searchEngine.searchMemberReferences(oldName);
List<SourceReference> nameRefs = getSourceReferences(nameMatches);
for (SourceReference reference in nameRefs) {
- // ignore resolved reference, we have already updated it
- if (reference.isResolved) {
- continue;
- }
// ignore references from SDK and pub cache
if (isElementInSdkOrPubCache(reference.element)) {
continue;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
index d82a56d..fa4b8bc 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
@@ -14,8 +14,9 @@
import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
import 'package:analysis_server/src/services/refactoring/rename.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/source.dart';
/**
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
index 4f1f150..5d8597f 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
@@ -14,8 +14,9 @@
import 'package:analysis_server/src/services/refactoring/rename.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -150,7 +151,8 @@
return;
}
// shadowing referenced element
- if (elementRange.contains(node.offset) &&
+ if (elementRange != null &&
+ elementRange.contains(node.offset) &&
!node.isQualified &&
!_isNamedExpressionName(node)) {
nodeElement = getSyntheticAccessorVariable(nodeElement);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
index 4f59af7..0bea805 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
@@ -15,8 +15,8 @@
import 'package:analysis_server/src/services/refactoring/rename.dart';
import 'package:analysis_server/src/services/search/element_visitors.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart' show Identifier;
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart' show Identifier;
import 'package:analyzer/src/generated/java_core.dart';
/**
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine.dart b/pkg/analysis_server/lib/src/services/search/search_engine.dart
index 217048c..e6d2738 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine.dart
@@ -6,8 +6,6 @@
import 'dart:async';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -16,13 +14,6 @@
import 'package:analyzer/src/generated/source.dart';
/**
- * Returns a new [SearchEngine] instance based on the given [Index].
- */
-SearchEngine createSearchEngine(Index index) {
- return new SearchEngineImpl(index);
-}
-
-/**
* Instances of the enum [MatchKind] represent the kind of reference that was
* found when a match represents a reference to an element.
*/
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
index 7718339..2d6f815 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
@@ -1,19 +1,22 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// 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 services.src.search.search_engine;
+library analysis_server.src.services.search.search_engine_internal;
import 'dart:async';
-import 'package:analysis_server/src/provisional/index/index_core.dart';
import 'package:analysis_server/src/services/correction/source_range.dart';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/indexable_element.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/resolver.dart' show NamespaceBuilder;
+import 'package:analyzer/src/generated/source.dart' show Source, SourceRange;
+import 'package:analyzer/src/summary/idl.dart';
/**
* A [SearchEngine] implementation.
@@ -24,240 +27,388 @@
SearchEngineImpl(this._index);
@override
- Future<List<SearchMatch>> searchAllSubtypes(ClassElement type) {
- _Requestor requestor = new _Requestor(_index);
- requestor.addElement(
- type, IndexConstants.HAS_ANCESTOR, MatchKind.DECLARATION);
- return requestor.merge();
+ Future<List<SearchMatch>> searchAllSubtypes(ClassElement type) async {
+ List<SearchMatch> matches = <SearchMatch>[];
+ await _addMatches(
+ matches, type, IndexRelationKind.IS_ANCESTOR_OF, MatchKind.DECLARATION);
+ return matches;
}
@override
- Future<List<SearchMatch>> searchMemberDeclarations(String name) async {
- List<SearchMatch> matches;
- {
- IndexableName indexableName = new IndexableName(name);
- _Requestor requestor = new _Requestor(_index);
- requestor.add(indexableName, IndexConstants.NAME_IS_DEFINED_BY,
- MatchKind.DECLARATION);
- matches = await requestor.merge();
- }
- return matches.where((match) {
- return match.element.enclosingElement is ClassElement;
+ Future<List<SearchMatch>> searchMemberDeclarations(String pattern) {
+ return _searchDefinedNames(pattern, IndexNameKind.classMember);
+ }
+
+ @override
+ Future<List<SearchMatch>> searchMemberReferences(String name) async {
+ List<Location> locations = await _index.getUnresolvedMemberReferences(name);
+ return locations.map((location) {
+ return _newMatchForLocation(location, null);
}).toList();
}
@override
- Future<List<SearchMatch>> searchMemberReferences(String name) {
- IndexableName indexableName = new IndexableName(name);
- _Requestor requestor = new _Requestor(_index);
- requestor.add(
- indexableName, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION);
- requestor.add(indexableName, IndexConstants.IS_READ_BY, MatchKind.READ);
- requestor.add(
- indexableName, IndexConstants.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE);
- requestor.add(indexableName, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE);
- return requestor.merge();
- }
-
- @override
Future<List<SearchMatch>> searchReferences(Element element) {
- if (element.kind == ElementKind.CLASS) {
+ ElementKind kind = element.kind;
+ if (kind == ElementKind.CLASS ||
+ kind == ElementKind.COMPILATION_UNIT ||
+ kind == ElementKind.CONSTRUCTOR ||
+ kind == ElementKind.FUNCTION_TYPE_ALIAS ||
+ kind == ElementKind.SETTER) {
return _searchReferences(element);
- } else if (element.kind == ElementKind.COMPILATION_UNIT) {
- return _searchReferences(element);
- } else if (element.kind == ElementKind.CONSTRUCTOR) {
- return _searchReferences_Constructor(element as ConstructorElement);
- } else if (element.kind == ElementKind.FIELD ||
- element.kind == ElementKind.TOP_LEVEL_VARIABLE) {
- return _searchReferences_Field(element as PropertyInducingElement);
- } else if (element.kind == ElementKind.FUNCTION) {
- return _searchReferences_Function(element as FunctionElement);
- } else if (element.kind == ElementKind.GETTER ||
- element.kind == ElementKind.SETTER) {
- return _searchReferences(element);
- } else if (element.kind == ElementKind.IMPORT) {
- return _searchReferences(element);
- } else if (element.kind == ElementKind.LABEL) {
- return _searchReferences(element);
- } else if (element.kind == ElementKind.LIBRARY) {
- return _searchReferences(element);
- } else if (element.kind == ElementKind.LOCAL_VARIABLE) {
- return _searchReferences_LocalVariable(element as LocalVariableElement);
- } else if (element.kind == ElementKind.METHOD) {
- return _searchReferences_Method(element as MethodElement);
- } else if (element.kind == ElementKind.PARAMETER) {
- return _searchReferences_Parameter(element as ParameterElement);
- } else if (element.kind == ElementKind.PREFIX) {
- return _searchReferences(element);
- } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) {
- return _searchReferences(element);
- } else if (element.kind == ElementKind.TYPE_PARAMETER) {
- return _searchReferences(element);
+ } else if (kind == ElementKind.GETTER) {
+ return _searchReferences_Getter(element);
+ } else if (kind == ElementKind.FIELD ||
+ kind == ElementKind.TOP_LEVEL_VARIABLE) {
+ return _searchReferences_Field(element);
+ } else if (kind == ElementKind.FUNCTION || kind == ElementKind.METHOD) {
+ if (element.enclosingElement is ExecutableElement) {
+ return _searchReferences_Local(element, (n) => n is Block);
+ }
+ return _searchReferences_Function(element);
+ } else if (kind == ElementKind.IMPORT) {
+ return _searchReferences_Import(element);
+ } else if (kind == ElementKind.LABEL ||
+ kind == ElementKind.LOCAL_VARIABLE) {
+ return _searchReferences_Local(element, (n) => n is Block);
+ } else if (kind == ElementKind.LIBRARY) {
+ return _searchReferences_Library(element);
+ } else if (kind == ElementKind.PARAMETER) {
+ return _searchReferences_Parameter(element);
+ } else if (kind == ElementKind.PREFIX) {
+ return _searchReferences_Prefix(element);
+ } else if (kind == ElementKind.TYPE_PARAMETER) {
+ return _searchReferences_Local(element, (n) => n is ClassDeclaration);
}
return new Future.value(<SearchMatch>[]);
}
@override
- Future<List<SearchMatch>> searchSubtypes(ClassElement type) {
- _Requestor requestor = new _Requestor(_index);
- requestor.addElement(
- type, IndexConstants.IS_EXTENDED_BY, MatchKind.REFERENCE);
- requestor.addElement(
- type, IndexConstants.IS_MIXED_IN_BY, MatchKind.REFERENCE);
- requestor.addElement(
- type, IndexConstants.IS_IMPLEMENTED_BY, MatchKind.REFERENCE);
- return requestor.merge();
+ Future<List<SearchMatch>> searchSubtypes(ClassElement type) async {
+ List<SearchMatch> matches = <SearchMatch>[];
+ await _addMatches(
+ matches, type, IndexRelationKind.IS_EXTENDED_BY, MatchKind.REFERENCE);
+ await _addMatches(
+ matches, type, IndexRelationKind.IS_MIXED_IN_BY, MatchKind.REFERENCE);
+ await _addMatches(matches, type, IndexRelationKind.IS_IMPLEMENTED_BY,
+ MatchKind.REFERENCE);
+ return matches;
}
@override
Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) {
- RegExp regExp = new RegExp(pattern);
- List<Element> elements =
- _index.getTopLevelDeclarations((String name) => regExp.hasMatch(name));
- List<SearchMatch> matches = <SearchMatch>[];
- for (Element element in elements) {
- matches.add(new SearchMatch(
- element.context,
- element.library.source.uri.toString(),
- element.source.uri.toString(),
- MatchKind.DECLARATION,
- rangeElementName(element),
- true,
- false));
+ return _searchDefinedNames(pattern, IndexNameKind.topLevel);
+ }
+
+ _addMatches(List<SearchMatch> matches, Element element,
+ IndexRelationKind relationKind, MatchKind kind) async {
+ List<Location> locations = await _index.getRelations(element, relationKind);
+ for (Location location in locations) {
+ SearchMatch match = _newMatchForLocation(location, kind);
+ matches.add(match);
}
- return new Future.value(matches);
}
- Future<List<SearchMatch>> _searchReferences(Element element) {
- _Requestor requestor = new _Requestor(_index);
- requestor.addElement(
- element, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE);
- return requestor.merge();
+ SearchMatch _newMatchForLocation(Location location, MatchKind kind) {
+ if (kind == null) {
+ IndexRelationKind relationKind = location.kind;
+ if (relationKind == IndexRelationKind.IS_INVOKED_BY) {
+ kind = MatchKind.INVOCATION;
+ } else if (relationKind == IndexRelationKind.IS_REFERENCED_BY) {
+ kind = MatchKind.REFERENCE;
+ } else if (relationKind == IndexRelationKind.IS_READ_BY) {
+ kind = MatchKind.READ;
+ } else if (relationKind == IndexRelationKind.IS_READ_WRITTEN_BY) {
+ kind = MatchKind.READ_WRITE;
+ } else if (relationKind == IndexRelationKind.IS_WRITTEN_BY) {
+ kind = MatchKind.WRITE;
+ } else {
+ throw new ArgumentError('Unsupported relation kind $relationKind');
+ }
+ }
+ return new SearchMatch(
+ location.context,
+ location.libraryUri,
+ location.unitUri,
+ kind,
+ new SourceRange(location.offset, location.length),
+ location.isResolved,
+ location.isQualified);
}
- Future<List<SearchMatch>> _searchReferences_Constructor(
- ConstructorElement constructor) {
- _Requestor requestor = new _Requestor(_index);
- requestor.addElement(
- constructor, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE);
- return requestor.merge();
+ Future<List<SearchMatch>> _searchDefinedNames(
+ String pattern, IndexNameKind nameKind) async {
+ RegExp regExp = new RegExp(pattern);
+ List<Location> locations = await _index.getDefinedNames(regExp, nameKind);
+ return locations.map((location) {
+ return _newMatchForLocation(location, MatchKind.DECLARATION);
+ }).toList();
+ }
+
+ Future<List<SearchMatch>> _searchReferences(Element element) async {
+ List<SearchMatch> matches = <SearchMatch>[];
+ await _addMatches(matches, element, IndexRelationKind.IS_REFERENCED_BY,
+ MatchKind.REFERENCE);
+ return matches;
}
Future<List<SearchMatch>> _searchReferences_Field(
- PropertyInducingElement field) {
+ PropertyInducingElement field) async {
+ List<SearchMatch> matches = <SearchMatch>[];
PropertyAccessorElement getter = field.getter;
PropertyAccessorElement setter = field.setter;
- _Requestor requestor = new _Requestor(_index);
// field itself
- requestor.addElement(
- field, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE);
- requestor.addElement(field, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE);
+ if (!field.isSynthetic) {
+ await _addMatches(
+ matches, field, IndexRelationKind.IS_WRITTEN_BY, MatchKind.WRITE);
+ await _addMatches(matches, field, IndexRelationKind.IS_REFERENCED_BY,
+ MatchKind.REFERENCE);
+ }
// getter
if (getter != null) {
- requestor.addElement(
- getter, IndexConstants.IS_REFERENCED_BY, MatchKind.READ);
- requestor.addElement(
- getter, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION);
+ await _addMatches(
+ matches, getter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.READ);
+ await _addMatches(matches, getter, IndexRelationKind.IS_INVOKED_BY,
+ MatchKind.INVOCATION);
}
// setter
if (setter != null) {
- requestor.addElement(
- setter, IndexConstants.IS_REFERENCED_BY, MatchKind.WRITE);
+ await _addMatches(
+ matches, setter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.WRITE);
}
// done
- return requestor.merge();
+ return matches;
}
- Future<List<SearchMatch>> _searchReferences_Function(
- FunctionElement function) {
- _Requestor requestor = new _Requestor(_index);
- requestor.addElement(
- function, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE);
- requestor.addElement(
- function, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION);
- return requestor.merge();
- }
-
- Future<List<SearchMatch>> _searchReferences_LocalVariable(
- LocalVariableElement variable) {
- _Requestor requestor = new _Requestor(_index);
- requestor.addElement(variable, IndexConstants.IS_READ_BY, MatchKind.READ);
- requestor.addElement(
- variable, IndexConstants.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE);
- requestor.addElement(
- variable, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE);
- requestor.addElement(
- variable, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION);
- return requestor.merge();
- }
-
- Future<List<SearchMatch>> _searchReferences_Method(MethodElement method) {
- _Requestor requestor = new _Requestor(_index);
- if (method is MethodMember) {
- method = (method as MethodMember).baseElement;
+ Future<List<SearchMatch>> _searchReferences_Function(Element element) async {
+ if (element is Member) {
+ element = (element as Member).baseElement;
}
- requestor.addElement(
- method, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE);
- requestor.addElement(
- method, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION);
- return requestor.merge();
+ List<SearchMatch> matches = <SearchMatch>[];
+ await _addMatches(matches, element, IndexRelationKind.IS_REFERENCED_BY,
+ MatchKind.REFERENCE);
+ await _addMatches(matches, element, IndexRelationKind.IS_INVOKED_BY,
+ MatchKind.INVOCATION);
+ return matches;
+ }
+
+ Future<List<SearchMatch>> _searchReferences_Getter(
+ PropertyAccessorElement getter) async {
+ List<SearchMatch> matches = <SearchMatch>[];
+ await _addMatches(matches, getter, IndexRelationKind.IS_REFERENCED_BY,
+ MatchKind.REFERENCE);
+ await _addMatches(
+ matches, getter, IndexRelationKind.IS_INVOKED_BY, MatchKind.INVOCATION);
+ return matches;
+ }
+
+ Future<List<SearchMatch>> _searchReferences_Import(
+ ImportElement element) async {
+ List<SearchMatch> matches = <SearchMatch>[];
+ LibraryElement libraryElement = element.library;
+ Source librarySource = libraryElement.source;
+ AnalysisContext context = libraryElement.context;
+ for (CompilationUnitElement unitElement in libraryElement.units) {
+ Source unitSource = unitElement.source;
+ CompilationUnit unit =
+ context.resolveCompilationUnit2(unitSource, librarySource);
+ _ImportElementReferencesVisitor visitor =
+ new _ImportElementReferencesVisitor(
+ element, unitSource.uri.toString());
+ unit.accept(visitor);
+ matches.addAll(visitor.matches);
+ }
+ return matches;
+ }
+
+ Future<List<SearchMatch>> _searchReferences_Library(Element element) async {
+ List<SearchMatch> matches = <SearchMatch>[];
+ LibraryElement libraryElement = element.library;
+ Source librarySource = libraryElement.source;
+ AnalysisContext context = libraryElement.context;
+ for (CompilationUnitElement unitElement in libraryElement.parts) {
+ Source unitSource = unitElement.source;
+ CompilationUnit unit =
+ context.resolveCompilationUnit2(unitSource, librarySource);
+ for (Directive directive in unit.directives) {
+ if (directive is PartOfDirective &&
+ directive.element == libraryElement) {
+ matches.add(new SearchMatch(
+ context,
+ librarySource.uri.toString(),
+ unitSource.uri.toString(),
+ MatchKind.REFERENCE,
+ rangeNode(directive.libraryName),
+ true,
+ false));
+ }
+ }
+ }
+ return matches;
+ }
+
+ Future<List<SearchMatch>> _searchReferences_Local(
+ Element element, bool isRootNode(AstNode n)) async {
+ _LocalReferencesVisitor visitor = new _LocalReferencesVisitor(element);
+ AstNode node = element.computeNode();
+ AstNode enclosingNode = node?.getAncestor(isRootNode);
+ enclosingNode?.accept(visitor);
+ return visitor.matches;
}
Future<List<SearchMatch>> _searchReferences_Parameter(
- ParameterElement parameter) {
- _Requestor requestor = new _Requestor(_index);
- requestor.addElement(parameter, IndexConstants.IS_READ_BY, MatchKind.READ);
- requestor.addElement(
- parameter, IndexConstants.IS_READ_WRITTEN_BY, MatchKind.READ_WRITE);
- requestor.addElement(
- parameter, IndexConstants.IS_WRITTEN_BY, MatchKind.WRITE);
- requestor.addElement(
- parameter, IndexConstants.IS_REFERENCED_BY, MatchKind.REFERENCE);
- requestor.addElement(
- parameter, IndexConstants.IS_INVOKED_BY, MatchKind.INVOCATION);
- return requestor.merge();
+ ParameterElement parameter) async {
+ List<SearchMatch> matches = <SearchMatch>[];
+ matches.addAll(await _searchReferences(parameter));
+ matches.addAll(await _searchReferences_Local(
+ parameter,
+ (n) =>
+ n is ConstructorDeclaration ||
+ n is MethodDeclaration ||
+ n is FunctionExpression));
+ return matches;
+ }
+
+ Future<List<SearchMatch>> _searchReferences_Prefix(
+ PrefixElement element) async {
+ List<SearchMatch> matches = <SearchMatch>[];
+ LibraryElement libraryElement = element.library;
+ Source librarySource = libraryElement.source;
+ AnalysisContext context = libraryElement.context;
+ for (CompilationUnitElement unitElement in libraryElement.units) {
+ Source unitSource = unitElement.source;
+ CompilationUnit unit =
+ context.resolveCompilationUnit2(unitSource, librarySource);
+ _LocalReferencesVisitor visitor =
+ new _LocalReferencesVisitor(element, unitSource.uri.toString());
+ unit.accept(visitor);
+ matches.addAll(visitor.matches);
+ }
+ return matches;
}
}
-class _Requestor {
- final List<Future<List<SearchMatch>>> futures = <Future<List<SearchMatch>>>[];
- final Index index;
+/**
+ * Visitor that adds [SearchMatch]es for [importElement], both with an explicit
+ * prefix or an implicit one.
+ */
+class _ImportElementReferencesVisitor extends RecursiveAstVisitor {
+ final List<SearchMatch> matches = <SearchMatch>[];
- _Requestor(this.index);
+ final ImportElement importElement;
+ final AnalysisContext context;
+ final String libraryUri;
+ final String unitUri;
+ Set<Element> importedElements;
- void add(IndexableObject indexable, RelationshipImpl relationship,
- MatchKind kind) {
- Future relationsFuture = index.getRelationships(indexable, relationship);
- Future matchesFuture = relationsFuture.then((List<LocationImpl> locations) {
- List<SearchMatch> matches = <SearchMatch>[];
- for (LocationImpl location in locations) {
- IndexableObject indexable = location.indexable;
- if (indexable is IndexableElement) {
- Element element = indexable.element;
- matches.add(new SearchMatch(
- element.context,
- element.library.source.uri.toString(),
- element.source.uri.toString(),
- kind,
- new SourceRange(location.offset, location.length),
- location.isResolved,
- location.isQualified));
+ _ImportElementReferencesVisitor(ImportElement element, this.unitUri)
+ : importElement = element,
+ context = element.context,
+ libraryUri = element.library.source.uri.toString() {
+ importedElements = new NamespaceBuilder()
+ .createImportNamespaceForDirective(element)
+ .definedNames
+ .values
+ .toSet();
+ }
+
+ @override
+ visitExportDirective(ExportDirective node) {}
+
+ @override
+ visitImportDirective(ImportDirective node) {}
+
+ @override
+ visitSimpleIdentifier(SimpleIdentifier node) {
+ if (node.inDeclarationContext()) {
+ return;
+ }
+ if (importElement.prefix != null) {
+ if (node.staticElement == importElement.prefix) {
+ AstNode parent = node.parent;
+ if (parent is PrefixedIdentifier && parent.prefix == node) {
+ if (importedElements.contains(parent.staticElement)) {
+ _addMatchForPrefix(node, parent.identifier);
+ }
+ }
+ if (parent is MethodInvocation && parent.target == node) {
+ if (importedElements.contains(parent.methodName.staticElement)) {
+ _addMatchForPrefix(node, parent.methodName);
+ }
}
}
- return matches;
- });
- futures.add(matchesFuture);
+ } else {
+ if (importedElements.contains(node.staticElement)) {
+ SourceRange range = rangeStartLength(node, 0);
+ _addMatchForRange(range);
+ }
+ }
}
- void addElement(
- Element element, RelationshipImpl relationship, MatchKind kind) {
- IndexableElement indexable = new IndexableElement(element);
- add(indexable, relationship, kind);
+ void _addMatchForPrefix(SimpleIdentifier prefixNode, AstNode nextNode) {
+ SourceRange range = rangeStartStart(prefixNode, nextNode);
+ _addMatchForRange(range);
}
- Future<List<SearchMatch>> merge() {
- return Future.wait(futures).then((List<List<SearchMatch>> matchesList) {
- return matchesList.expand((matches) => matches).toList();
- });
+ void _addMatchForRange(SourceRange range) {
+ matches.add(new SearchMatch(
+ context, libraryUri, unitUri, MatchKind.REFERENCE, range, true, false));
+ }
+}
+
+/**
+ * Visitor that adds [SearchMatch]es for local elements of a block, method,
+ * class or a library - labels, local functions, local variables and parameters,
+ * type parameters, import prefixes.
+ */
+class _LocalReferencesVisitor extends RecursiveAstVisitor {
+ final List<SearchMatch> matches = <SearchMatch>[];
+
+ final Element element;
+ final AnalysisContext context;
+ final String libraryUri;
+ final String unitUri;
+
+ _LocalReferencesVisitor(Element element, [String unitUri])
+ : element = element,
+ context = element.context,
+ libraryUri = element.library.source.uri.toString(),
+ unitUri = unitUri ?? element.source.uri.toString();
+
+ @override
+ visitSimpleIdentifier(SimpleIdentifier node) {
+ if (node.inDeclarationContext()) {
+ return;
+ }
+ if (node.bestElement == element) {
+ AstNode parent = node.parent;
+ MatchKind kind = MatchKind.REFERENCE;
+ if (element is FunctionElement) {
+ if (parent is MethodInvocation && parent.methodName == node) {
+ kind = MatchKind.INVOCATION;
+ }
+ } else if (element is VariableElement) {
+ bool isGet = node.inGetterContext();
+ bool isSet = node.inSetterContext();
+ if (isGet && isSet) {
+ kind = MatchKind.READ_WRITE;
+ } else if (isGet) {
+ if (parent is MethodInvocation && parent.methodName == node) {
+ kind = MatchKind.INVOCATION;
+ } else {
+ kind = MatchKind.READ;
+ }
+ } else if (isSet) {
+ kind = MatchKind.WRITE;
+ }
+ }
+ _addMatch(node, kind);
+ }
+ }
+
+ void _addMatch(AstNode node, MatchKind kind) {
+ bool isQualified = node is SimpleIdentifier && node.isQualified;
+ matches.add(new SearchMatch(context, libraryUri, unitUri, kind,
+ rangeNode(node), true, isQualified));
}
}
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart
deleted file mode 100644
index 2bb0d33..0000000
--- a/pkg/analysis_server/lib/src/services/search/search_engine_internal2.dart
+++ /dev/null
@@ -1,370 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library services.src.search.search_engine2;
-
-import 'dart:async';
-
-import 'package:analysis_server/src/services/correction/source_range.dart';
-import 'package:analysis_server/src/services/index2/index2.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
-import 'package:analyzer/src/generated/resolver.dart' show NamespaceBuilder;
-import 'package:analyzer/src/generated/source.dart' show Source, SourceRange;
-import 'package:analyzer/src/summary/idl.dart';
-
-/**
- * A [SearchEngine] implementation.
- */
-class SearchEngineImpl2 implements SearchEngine {
- final AnalysisContext context;
- final Index2 _index;
-
- SearchEngineImpl2(this.context, this._index);
-
- @override
- Future<List<SearchMatch>> searchAllSubtypes(ClassElement type) async {
- List<SearchMatch> matches = <SearchMatch>[];
- await _addMatches(
- matches, type, IndexRelationKind.IS_ANCESTOR_OF, MatchKind.DECLARATION);
- return matches;
- }
-
- @override
- Future<List<SearchMatch>> searchMemberDeclarations(String pattern) {
- return _searchDefinedNames(pattern, IndexNameKind.classMember);
- }
-
- @override
- Future<List<SearchMatch>> searchMemberReferences(String name) async {
- List<Location> locations = await _index.getUnresolvedMemberReferences(name);
- return locations.map((location) {
- return _newMatchForLocation(location, MatchKind.REFERENCE);
- }).toList();
- }
-
- @override
- Future<List<SearchMatch>> searchReferences(Element element) {
- ElementKind kind = element.kind;
- if (kind == ElementKind.CLASS ||
- kind == ElementKind.COMPILATION_UNIT ||
- kind == ElementKind.CONSTRUCTOR ||
- kind == ElementKind.FUNCTION_TYPE_ALIAS ||
- kind == ElementKind.GETTER ||
- kind == ElementKind.SETTER) {
- return _searchReferences(element);
- } else if (kind == ElementKind.FIELD ||
- kind == ElementKind.TOP_LEVEL_VARIABLE) {
- return _searchReferences_Field(element);
- } else if (kind == ElementKind.FUNCTION || kind == ElementKind.METHOD) {
- if (element.enclosingElement is ExecutableElement) {
- return _searchReferences_Local(element, (n) => n is Block);
- }
- return _searchReferences_Function(element);
- } else if (kind == ElementKind.IMPORT) {
- return _searchReferences_Import(element);
- } else if (kind == ElementKind.LABEL ||
- kind == ElementKind.LOCAL_VARIABLE) {
- return _searchReferences_Local(element, (n) => n is Block);
- } else if (kind == ElementKind.LIBRARY) {
- return _searchReferences_Library(element);
- } else if (kind == ElementKind.PARAMETER) {
- return _searchReferences_Parameter(element);
- } else if (kind == ElementKind.PREFIX) {
- return _searchReferences_Prefix(element);
- } else if (kind == ElementKind.TYPE_PARAMETER) {
- return _searchReferences_Local(element, (n) => n is ClassDeclaration);
- }
- return new Future.value(<SearchMatch>[]);
- }
-
- @override
- Future<List<SearchMatch>> searchSubtypes(ClassElement type) async {
- List<SearchMatch> matches = <SearchMatch>[];
- await _addMatches(
- matches, type, IndexRelationKind.IS_EXTENDED_BY, MatchKind.REFERENCE);
- await _addMatches(
- matches, type, IndexRelationKind.IS_MIXED_IN_BY, MatchKind.REFERENCE);
- await _addMatches(matches, type, IndexRelationKind.IS_IMPLEMENTED_BY,
- MatchKind.REFERENCE);
- return matches;
- }
-
- @override
- Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) {
- return _searchDefinedNames(pattern, IndexNameKind.topLevel);
- }
-
- _addMatches(List<SearchMatch> matches, Element element,
- IndexRelationKind relationKind, MatchKind kind) async {
- List<Location> locations = await _index.getRelations(element, relationKind);
- for (Location location in locations) {
- SearchMatch match = _newMatchForLocation(location, kind);
- matches.add(match);
- }
- }
-
- SearchMatch _newMatchForLocation(Location location, MatchKind kind) =>
- new SearchMatch(
- context,
- location.libraryUri,
- location.unitUri,
- kind,
- new SourceRange(location.offset, location.length),
- true,
- location.isQualified);
-
- Future<List<SearchMatch>> _searchDefinedNames(
- String pattern, IndexNameKind nameKind) async {
- RegExp regExp = new RegExp(pattern);
- List<Location> locations = await _index.getDefinedNames(regExp, nameKind);
- return locations.map((location) {
- return _newMatchForLocation(location, MatchKind.DECLARATION);
- }).toList();
- }
-
- Future<List<SearchMatch>> _searchReferences(Element element) async {
- List<SearchMatch> matches = <SearchMatch>[];
- await _addMatches(matches, element, IndexRelationKind.IS_REFERENCED_BY,
- MatchKind.REFERENCE);
- return matches;
- }
-
- Future<List<SearchMatch>> _searchReferences_Field(
- PropertyInducingElement field) async {
- List<SearchMatch> matches = <SearchMatch>[];
- PropertyAccessorElement getter = field.getter;
- PropertyAccessorElement setter = field.setter;
- // field itself
- await _addMatches(matches, field, IndexRelationKind.IS_REFERENCED_BY,
- MatchKind.REFERENCE);
- // getter
- if (getter != null) {
- await _addMatches(
- matches, getter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.READ);
- await _addMatches(matches, getter, IndexRelationKind.IS_INVOKED_BY,
- MatchKind.INVOCATION);
- }
- // setter
- if (setter != null) {
- await _addMatches(
- matches, setter, IndexRelationKind.IS_REFERENCED_BY, MatchKind.WRITE);
- }
- // done
- return matches;
- }
-
- Future<List<SearchMatch>> _searchReferences_Function(Element element) async {
- if (element is Member) {
- element = (element as Member).baseElement;
- }
- List<SearchMatch> matches = <SearchMatch>[];
- await _addMatches(matches, element, IndexRelationKind.IS_REFERENCED_BY,
- MatchKind.REFERENCE);
- await _addMatches(matches, element, IndexRelationKind.IS_INVOKED_BY,
- MatchKind.INVOCATION);
- return matches;
- }
-
- Future<List<SearchMatch>> _searchReferences_Import(
- ImportElement element) async {
- List<SearchMatch> matches = <SearchMatch>[];
- LibraryElement libraryElement = element.library;
- Source librarySource = libraryElement.source;
- for (CompilationUnitElement unitElement in libraryElement.units) {
- Source unitSource = unitElement.source;
- CompilationUnit unit =
- context.resolveCompilationUnit2(unitSource, librarySource);
- _ImportElementReferencesVisitor visitor =
- new _ImportElementReferencesVisitor(
- element, unitSource.uri.toString());
- unit.accept(visitor);
- matches.addAll(visitor.matches);
- }
- return matches;
- }
-
- Future<List<SearchMatch>> _searchReferences_Library(Element element) async {
- List<SearchMatch> matches = <SearchMatch>[];
- LibraryElement libraryElement = element.library;
- Source librarySource = libraryElement.source;
- for (CompilationUnitElement unitElement in libraryElement.parts) {
- Source unitSource = unitElement.source;
- CompilationUnit unit =
- context.resolveCompilationUnit2(unitSource, librarySource);
- for (Directive directive in unit.directives) {
- if (directive is PartOfDirective &&
- directive.element == libraryElement) {
- matches.add(new SearchMatch(
- context,
- librarySource.uri.toString(),
- unitSource.uri.toString(),
- MatchKind.REFERENCE,
- rangeNode(directive.libraryName),
- true,
- false));
- }
- }
- }
- return matches;
- }
-
- Future<List<SearchMatch>> _searchReferences_Local(
- Element element, bool isRootNode(AstNode n)) async {
- _LocalReferencesVisitor visitor = new _LocalReferencesVisitor(element);
- AstNode node = element.computeNode();
- AstNode enclosingNode = node?.getAncestor(isRootNode);
- enclosingNode?.accept(visitor);
- return visitor.matches;
- }
-
- Future<List<SearchMatch>> _searchReferences_Parameter(
- ParameterElement parameter) async {
- List<SearchMatch> matches = <SearchMatch>[];
- matches.addAll(await _searchReferences(parameter));
- matches.addAll(await _searchReferences_Local(
- parameter, (n) => n is MethodDeclaration || n is FunctionExpression));
- return matches;
- }
-
- Future<List<SearchMatch>> _searchReferences_Prefix(
- PrefixElement element) async {
- List<SearchMatch> matches = <SearchMatch>[];
- LibraryElement libraryElement = element.library;
- Source librarySource = libraryElement.source;
- for (CompilationUnitElement unitElement in libraryElement.units) {
- Source unitSource = unitElement.source;
- CompilationUnit unit =
- context.resolveCompilationUnit2(unitSource, librarySource);
- _LocalReferencesVisitor visitor =
- new _LocalReferencesVisitor(element, unitSource.uri.toString());
- unit.accept(visitor);
- matches.addAll(visitor.matches);
- }
- return matches;
- }
-}
-
-/**
- * Visitor that adds [SearchMatch]es for [importElement], both with an explicit
- * prefix or an implicit one.
- */
-class _ImportElementReferencesVisitor extends RecursiveAstVisitor {
- final List<SearchMatch> matches = <SearchMatch>[];
-
- final ImportElement importElement;
- final AnalysisContext context;
- final String libraryUri;
- final String unitUri;
- Set<Element> importedElements;
-
- _ImportElementReferencesVisitor(ImportElement element, this.unitUri)
- : importElement = element,
- context = element.context,
- libraryUri = element.library.source.uri.toString() {
- importedElements = new NamespaceBuilder()
- .createImportNamespaceForDirective(element)
- .definedNames
- .values
- .toSet();
- }
-
- @override
- visitSimpleIdentifier(SimpleIdentifier node) {
- if (node.inDeclarationContext()) {
- return;
- }
- if (importElement.prefix != null) {
- if (node.staticElement == importElement.prefix) {
- AstNode parent = node.parent;
- if (parent is PrefixedIdentifier && parent.prefix == node) {
- if (importedElements.contains(parent.staticElement)) {
- _addMatchForPrefix(node, parent.identifier);
- }
- }
- if (parent is MethodInvocation && parent.target == node) {
- if (importedElements.contains(parent.methodName.staticElement)) {
- _addMatchForPrefix(node, parent.methodName);
- }
- }
- }
- } else {
- if (importedElements.contains(node.staticElement)) {
- SourceRange range = rangeStartLength(node, 0);
- _addMatchForRange(range);
- }
- }
- }
-
- void _addMatchForPrefix(SimpleIdentifier prefixNode, AstNode nextNode) {
- SourceRange range = rangeStartStart(prefixNode, nextNode);
- _addMatchForRange(range);
- }
-
- void _addMatchForRange(SourceRange range) {
- matches.add(new SearchMatch(
- context, libraryUri, unitUri, MatchKind.REFERENCE, range, true, false));
- }
-}
-
-/**
- * Visitor that adds [SearchMatch]es for local elements of a block, method,
- * class or a library - labels, local functions, local variables and parameters,
- * type parameters, import prefixes.
- */
-class _LocalReferencesVisitor extends RecursiveAstVisitor {
- final List<SearchMatch> matches = <SearchMatch>[];
-
- final Element element;
- final AnalysisContext context;
- final String libraryUri;
- final String unitUri;
-
- _LocalReferencesVisitor(Element element, [String unitUri])
- : element = element,
- context = element.context,
- libraryUri = element.library.source.uri.toString(),
- unitUri = unitUri ?? element.source.uri.toString();
-
- @override
- visitSimpleIdentifier(SimpleIdentifier node) {
- if (node.inDeclarationContext()) {
- return;
- }
- if (node.bestElement == element) {
- AstNode parent = node.parent;
- MatchKind kind = MatchKind.REFERENCE;
- if (element is FunctionElement) {
- if (parent is MethodInvocation && parent.methodName == node) {
- kind = MatchKind.INVOCATION;
- }
- } else if (element is VariableElement) {
- bool isGet = node.inGetterContext();
- bool isSet = node.inSetterContext();
- if (isGet && isSet) {
- kind = MatchKind.READ_WRITE;
- } else if (isGet) {
- if (parent is MethodInvocation && parent.methodName == node) {
- kind = MatchKind.INVOCATION;
- } else {
- kind = MatchKind.READ;
- }
- } else if (isSet) {
- kind = MatchKind.WRITE;
- }
- }
- _addMatch(node, kind);
- }
- }
-
- void _addMatch(AstNode node, MatchKind kind) {
- bool isQualified = node is SimpleIdentifier && node.isQualified;
- matches.add(new SearchMatch(context, libraryUri, unitUri, kind,
- rangeNode(node), true, isQualified));
- }
-}
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index 9c0a809..c3f3fac 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -9,8 +9,6 @@
import 'package:analysis_server/src/channel/channel.dart';
import 'package:analysis_server/src/plugin/server_plugin.dart';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_file_index.dart';
-import 'package:analysis_server/src/services/index2/index2.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/plugin/embedded_resolver_provider.dart';
@@ -88,19 +86,14 @@
Index index = null;
if (!analysisServerOptions.noIndex) {
- index = createLocalFileIndex();
- index.contributors = serverPlugin.indexContributors;
- index.run();
+ index = createMemoryIndex();
}
- Index2 index2 = createMemoryIndex2();
-
analysisServer = new AnalysisServer(
serverChannel,
resourceProvider,
new PubPackageMapProvider(resourceProvider, defaultSdk),
index,
- index2,
serverPlugin,
analysisServerOptions,
defaultSdkCreator,
diff --git a/pkg/analysis_server/lib/src/status/ast_writer.dart b/pkg/analysis_server/lib/src/status/ast_writer.dart
index 5488a59..7303f69 100644
--- a/pkg/analysis_server/lib/src/status/ast_writer.dart
+++ b/pkg/analysis_server/lib/src/status/ast_writer.dart
@@ -7,7 +7,8 @@
import 'dart:collection';
import 'package:analysis_server/src/status/tree_writer.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
/**
* A visitor that will produce an HTML representation of an AST structure.
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index aa6a406..c3e4bc2 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -7,7 +7,6 @@
import 'dart:collection';
import 'dart:convert';
-import 'package:analysis_server/src/status/get_handler.dart';
import 'package:analysis_server/src/status/tree_writer.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
@@ -165,15 +164,6 @@
buffer.write(' <span style="color:gray">(');
buffer.write(element.runtimeType);
buffer.write(')</span>');
- if (element is! LibraryElement) {
- String name = element.name;
- if (name != null) {
- buffer.write(' [');
- buffer.write(GetHandler.makeLink(
- GetHandler.INDEX_ELEMENT_BY_NAME, {'name': name}, 'search index'));
- buffer.write(']');
- }
- }
buffer.write('<br>');
}
}
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 835488e..c466669 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -4,7 +4,6 @@
library analysis_server.src.status.get_handler;
-import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:io';
@@ -19,14 +18,12 @@
import 'package:analysis_server/src/operation/operation_analysis.dart';
import 'package:analysis_server/src/operation/operation_queue.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_index.dart';
-import 'package:analysis_server/src/services/index/store/split_store.dart';
import 'package:analysis_server/src/socket_server.dart';
import 'package:analysis_server/src/status/ast_writer.dart';
import 'package:analysis_server/src/status/element_writer.dart';
import 'package:analysis_server/src/status/validator.dart';
import 'package:analysis_server/src/utilities/average.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/file_system/file_system.dart';
@@ -34,7 +31,6 @@
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
import 'package:analyzer/src/context/source.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_engine.dart';
@@ -258,11 +254,6 @@
static const String ELEMENT_PATH = '/element';
/**
- * The path used to request information about elements with the given name.
- */
- static const String INDEX_ELEMENT_BY_NAME = '/index/element-by-name';
-
- /**
* The path used to request an overlay contents.
*/
static const String OVERLAY_PATH = '/overlay';
@@ -395,8 +386,6 @@
_returnDiagnosticInfo(request);
} else if (path == ELEMENT_PATH) {
_returnElement(request);
- } else if (path == INDEX_ELEMENT_BY_NAME) {
- _returnIndexElementByName(request);
} else if (path == OVERLAY_PATH) {
_returnOverlayContents(request);
} else if (path == OVERLAYS_PATH) {
@@ -1506,51 +1495,6 @@
});
}
- /**
- * Return a response containing information about elements with the given
- * name.
- */
- Future _returnIndexElementByName(HttpRequest request) async {
- AnalysisServer analysisServer = _server.analysisServer;
- if (analysisServer == null) {
- return _returnFailure(request, 'Analysis server not running');
- }
- Index index = analysisServer.index;
- if (index == null) {
- return _returnFailure(request, 'Indexing is disabled');
- }
- String name = request.uri.queryParameters[INDEX_ELEMENT_NAME];
- if (name == null) {
- return _returnFailure(
- request, 'Query parameter $INDEX_ELEMENT_NAME required');
- }
- if (index is LocalIndex) {
- Map<List<String>, List<InspectLocation>> relations =
- await index.findElementsByName(name);
- _writeResponse(request, (StringBuffer buffer) {
- _writePage(buffer, 'Analysis Server - Index Elements', ['Name: $name'],
- (StringBuffer buffer) {
- buffer.write('<table border="1">');
- _writeRow(buffer, ['Element', 'Relationship', 'Location'],
- header: true);
- relations.forEach(
- (List<String> elementPath, List<InspectLocation> relations) {
- String elementLocation = elementPath.join(' ');
- relations.forEach((InspectLocation location) {
- var relString = location.relationship.identifier;
- var locString = '${location.path} offset=${location.offset} '
- 'length=${location.length} flags=${location.flags}';
- _writeRow(buffer, [elementLocation, relString, locString]);
- });
- });
- buffer.write('</table>');
- });
- });
- } else {
- return _returnFailure(request, 'LocalIndex expected, but $index found.');
- }
- }
-
void _returnOverlayContents(HttpRequest request) {
String path = request.requestedUri.queryParameters[PATH_PARAM];
if (path == null) {
@@ -1707,7 +1651,7 @@
// TODO(brianwilkerson) Add items for the SDK contexts (currently only one).
buffer.write('</p>');
- int freq = AnalysisServer.performOperationDelayFreqency;
+ int freq = AnalysisServer.performOperationDelayFrequency;
String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
buffer.write('<p><b>Performance Data</b></p>');
diff --git a/pkg/analysis_server/lib/src/status/tree_writer.dart b/pkg/analysis_server/lib/src/status/tree_writer.dart
index d50a78e..daa7966 100644
--- a/pkg/analysis_server/lib/src/status/tree_writer.dart
+++ b/pkg/analysis_server/lib/src/status/tree_writer.dart
@@ -6,8 +6,6 @@
import 'dart:convert';
-import 'package:analysis_server/src/status/get_handler.dart';
-import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/java_engine.dart';
@@ -121,15 +119,6 @@
buffer.write('</span>');
} else {
buffer.write(HTML_ESCAPE.convert(valueString));
- if (value is Element && value is! LibraryElement) {
- String name = value.name;
- if (name != null) {
- buffer.write(' [');
- buffer.write(GetHandler.makeLink(GetHandler.INDEX_ELEMENT_BY_NAME,
- {'name': name}, 'search index'));
- buffer.write(']');
- }
- }
}
}
}
diff --git a/pkg/analysis_server/lib/src/status/validator.dart b/pkg/analysis_server/lib/src/status/validator.dart
index 5651b8e..75793e0 100644
--- a/pkg/analysis_server/lib/src/status/validator.dart
+++ b/pkg/analysis_server/lib/src/status/validator.dart
@@ -6,13 +6,14 @@
import 'dart:collection';
+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/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart'
show AnalysisEngine, AnalysisResult, CacheState, ChangeSet;
import 'package:analyzer/src/generated/error.dart';
@@ -422,14 +423,14 @@
_write('; found ');
_writeln(actual.nameOffset);
}
- SourceRange expectedRange = expected.docRange;
- SourceRange actualRange = actual.docRange;
- if (expectedRange.offset != actualRange.offset ||
- expectedRange.length != actualRange.length) {
- _write('Expected documentation range of ');
- _write(expectedRange);
- _write('; found ');
- _writeln(actualRange);
+ String expectedComment = expected.documentationComment;
+ String actualComment = actual.documentationComment;
+ if (expectedComment != actualComment) {
+ _write('Expected documentation comment of "');
+ _write(expectedComment);
+ _write('"; found "');
+ _write(actualComment);
+ _writeln('"');
}
}
diff --git a/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart b/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
index 51131dc..94853ad 100644
--- a/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
+++ b/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
@@ -10,10 +10,10 @@
import 'package:analysis_server/src/services/correction/name_suggestion.dart';
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analysis_server/src/utilities/change_builder_core.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index eded4062..c0d22f1 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -4,12 +4,12 @@
library testing.abstract_context;
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
import 'package:analyzer/src/generated/sdk.dart';
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index 4b0be0e..6a73d1c 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -4,8 +4,9 @@
library test.services.src.index.abstract_single_file;
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
index a24b811..265ee9b 100644
--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
@@ -296,12 +296,11 @@
expect(testContext.analysisOptions.strongMode, enabled);
if (enabled) {
- // Should produce a warning and an error.
+ // Should produce a type warning.
expect(
errors.map((error) => error.type),
unorderedEquals([
- AnalysisErrorType.STATIC_TYPE_WARNING,
- AnalysisErrorType.COMPILE_TIME_ERROR
+ AnalysisErrorType.STATIC_TYPE_WARNING
]));
} else {
// Should only produce a hint.
diff --git a/pkg/analysis_server/test/analysis/notification_implemented_test.dart b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
index ab0e0c1..ee3959a 100644
--- a/pkg/analysis_server/test/analysis/notification_implemented_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
@@ -9,7 +9,6 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
@@ -96,7 +95,7 @@
@override
Index createIndex() {
- return createLocalMemoryIndex();
+ return createMemoryIndex();
}
/**
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index 7ca1fba..a2ae03b 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_test.dart
@@ -8,8 +8,8 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/services/index/index.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -96,7 +96,7 @@
createProject();
addTestFile('main() { print(1); }');
await server.onAnalysisComplete;
- verify(server.index.index(anyObject, testUnitMatcher)).times(1);
+ verify(server.index.indexUnit(testUnitMatcher)).times(1);
// add an overlay
server.updateContent(
'1', {testFile: new AddContentOverlay('main() { print(2); }')});
@@ -108,7 +108,7 @@
server.updateContent('2', {testFile: new RemoveContentOverlay()});
// Validate that at the end the unit was indexed.
await server.onAnalysisComplete;
- verify(server.index.index(anyObject, testUnitMatcher)).times(3);
+ verify(server.index.indexUnit(testUnitMatcher)).times(3);
}
test_multiple_contexts() async {
@@ -160,6 +160,29 @@
}
}
+ test_overlay_addPreviouslyImported() async {
+ Folder project = resourceProvider.newFolder('/project');
+ handleSuccessfulRequest(
+ new AnalysisSetAnalysisRootsParams([project.path], []).toRequest('0'));
+
+ server.updateContent('1',
+ {'/project/main.dart': new AddContentOverlay('import "target.dart";')});
+ await server.onAnalysisComplete;
+ expect(filesErrors, {
+ '/project/main.dart': ["1: Target of URI does not exist: 'target.dart'"],
+ '/project/target.dart': []
+ });
+
+ server.updateContent('1',
+ {'/project/target.dart': new AddContentOverlay('import "none.dart";')});
+ await server.onAnalysisComplete;
+ expect(filesErrors, {
+ '/project/main.dart': ["1: Unused import"],
+ '/project/target.dart': ["1: Target of URI does not exist: 'none.dart'"],
+ '/project/none.dart': []
+ });
+ }
+
test_overlayOnly() async {
String filePath = '/User/project1/test.dart';
Folder folder1 = resourceProvider.newFolder('/User/project1');
@@ -189,29 +212,6 @@
expect(_getUserSources(context2), isEmpty);
}
- test_overlay_addPreviouslyImported() async {
- Folder project = resourceProvider.newFolder('/project');
- handleSuccessfulRequest(
- new AnalysisSetAnalysisRootsParams([project.path], []).toRequest('0'));
-
- server.updateContent('1',
- {'/project/main.dart': new AddContentOverlay('import "target.dart";')});
- await server.onAnalysisComplete;
- expect(filesErrors, {
- '/project/main.dart': ["1: Target of URI does not exist: 'target.dart'"],
- '/project/target.dart': []
- });
-
- server.updateContent('1',
- {'/project/target.dart': new AddContentOverlay('import "none.dart";')});
- await server.onAnalysisComplete;
- expect(filesErrors, {
- '/project/main.dart': ["1: Unused import"],
- '/project/target.dart': ["1: Target of URI does not exist: 'none.dart'"],
- '/project/none.dart': []
- });
- }
-
test_removeOverlay_incrementalChange() async {
createProject();
addTestFile('main() { print(1); }');
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 8286482..b241eda 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -14,7 +14,6 @@
import 'package:analysis_server/src/plugin/server_plugin.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_plugin.dart';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index2/index2.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -64,6 +63,9 @@
AbstractAnalysisTest();
+ AnalysisDomainHandler get analysisHandler => server.handlers
+ .singleWhere((handler) => handler is AnalysisDomainHandler);
+
void addAnalysisSubscription(AnalysisService service, String file) {
// add file to subscription
var files = analysisSubscriptions[service];
@@ -125,7 +127,6 @@
resourceProvider,
packageMapProvider,
index,
- createMemoryIndex2(),
serverPlugin,
new AnalysisServerOptions(),
() => new MockSdk(),
@@ -143,7 +144,7 @@
resourceProvider.newFolder(projectPath);
Request request =
new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
- handleSuccessfulRequest(request);
+ handleSuccessfulRequest(request, handler: analysisHandler);
}
/**
@@ -171,7 +172,8 @@
/**
* Validates that the given [request] is handled successfully.
*/
- Response handleSuccessfulRequest(Request request) {
+ Response handleSuccessfulRequest(Request request, {RequestHandler handler}) {
+ handler ??= this.handler;
Response response = handler.handleRequest(request);
expect(response, isResponseSuccess(request.id));
return response;
@@ -203,8 +205,7 @@
packageMapProvider = new MockPackageMapProvider();
Index index = createIndex();
server = createAnalysisServer(index);
- handler = server.handlers
- .singleWhere((handler) => handler is AnalysisDomainHandler);
+ handler = analysisHandler;
// listen for notifications
Stream<Notification> notificationStream =
serverChannel.notificationController.stream;
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index 6710d43..85a6bbc 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -142,7 +142,6 @@
resourceProvider,
packageMapProvider,
null,
- null,
plugin,
new AnalysisServerOptions(),
() => new MockSdk(),
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 17bfcab..8dbe635 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -15,19 +15,20 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/util/glob.dart';
import 'package:linter/src/plugin/linter_plugin.dart';
import 'package:linter/src/rules/avoid_as.dart';
-import 'package:package_config/packages.dart';
import 'package:path/path.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
+import 'mock_sdk.dart';
import 'mocks.dart';
import 'utils.dart';
@@ -112,6 +113,8 @@
AnalysisOptions get options => callbacks.currentContext.analysisOptions;
+ Map<String, List<Folder>> get _currentPackageMap => _packageMap(projPath);
+
void deleteFile(List<String> pathComponents) {
String filePath = posix.joinAll(pathComponents);
resourceProvider.deleteFile(filePath);
@@ -150,8 +153,12 @@
processRequiredPlugins();
resourceProvider = new MemoryResourceProvider();
packageMapProvider = new MockPackageMapProvider();
+ DartSdkManager sdkManager = new DartSdkManager(() {
+ return new MockSdk();
+ });
manager = new ContextManagerImpl(
resourceProvider,
+ sdkManager,
providePackageResolver,
provideEmbeddedUriResolver,
packageMapProvider,
@@ -1073,8 +1080,7 @@
<String, String>{projPath: packageRootPath});
expect(callbacks.currentContextPaths, hasLength(1));
expect(callbacks.currentContextPaths, contains(projPath));
- expect(callbacks.currentContextDispositions[projPath].packageRoot,
- packageRootPath);
+ _checkPackageRoot(projPath, packageRootPath);
}
void test_setRoots_addFolderWithPubspec() {
@@ -1185,11 +1191,11 @@
callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
// verify package maps
- _checkPackageMap(root, isNull);
- _checkPackageMap(
- subProjectA, equals(packageMapProvider.packageMaps[subProjectA]));
- _checkPackageMap(
- subProjectB, equals(packageMapProvider.packageMaps[subProjectB]));
+ expect(_packageMap(root), isNull);
+ expect(_packageMap(subProjectA),
+ equals(packageMapProvider.packageMaps[subProjectA]));
+ expect(_packageMap(subProjectB),
+ equals(packageMapProvider.packageMaps[subProjectB]));
}
void test_setRoots_addPackageRoot() {
@@ -1202,7 +1208,7 @@
List<String> includedPaths = <String>[projPath];
List<String> excludedPaths = <String>[];
manager.setRoots(includedPaths, excludedPaths, <String, String>{});
- _checkPackageMap(projPath, equals(packageMapProvider.packageMap));
+ expect(_currentPackageMap, equals(packageMapProvider.packageMap));
manager.setRoots(includedPaths, excludedPaths,
<String, String>{projPath: packageRootPath});
_checkPackageRoot(projPath, equals(packageRootPath));
@@ -1524,7 +1530,7 @@
'foo': [packageFolder]
};
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
- _checkPackageMap(projPath, equals(packageMapProvider.packageMap));
+ expect(_currentPackageMap, equals(packageMapProvider.packageMap));
}
void test_setRoots_noContext_excludedFolder() {
@@ -1712,7 +1718,7 @@
<String, String>{projPath: packageRootPath});
_checkPackageRoot(projPath, equals(packageRootPath));
manager.setRoots(includedPaths, excludedPaths, <String, String>{});
- _checkPackageMap(projPath, equals(packageMapProvider.packageMap));
+ expect(_currentPackageMap, equals(packageMapProvider.packageMap));
}
void test_setRoots_rootPathContainsDotFile() {
@@ -2250,20 +2256,22 @@
resourceProvider.newFile(dartFilePath, 'contents');
// the created context has the expected empty package map
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
- _checkPackageMap(projPath, isEmpty);
+ expect(_currentPackageMap, isEmpty);
// configure package map
String packagePath = '/package/foo';
resourceProvider.newFolder(packagePath);
- packageMapProvider.packageMap = {'foo': projPath};
+ packageMapProvider.packageMap = {
+ 'foo': [resourceProvider.newFolder(projPath)]
+ };
// Changing a .dart file in the project shouldn't cause a new
// package map to be picked up.
resourceProvider.modifyFile(dartFilePath, 'new contents');
return pumpEventQueue().then((_) {
- _checkPackageMap(projPath, isEmpty);
+ expect(_currentPackageMap, isEmpty);
// However, changing the package map dependency should.
resourceProvider.modifyFile(dependencyPath, 'new contents');
return pumpEventQueue().then((_) {
- _checkPackageMap(projPath, equals(packageMapProvider.packageMap));
+ expect(_currentPackageMap, equals(packageMapProvider.packageMap));
});
});
}
@@ -2278,14 +2286,14 @@
resourceProvider.newFile(dartFilePath, 'contents');
// the created context has the expected empty package map
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
- _checkPackageMap(projPath, isEmpty);
+ expect(_currentPackageMap, isEmpty);
// Change the package map dependency so that the packageMapProvider is
// re-run, and arrange for it to return null from computePackageMap().
packageMapProvider.packageMap = null;
resourceProvider.modifyFile(dependencyPath, 'new contents');
return pumpEventQueue().then((_) {
// The package map should have been changed to null.
- _checkPackageMap(projPath, isNull);
+ expect(_currentPackageMap, isNull);
});
}
@@ -2301,40 +2309,35 @@
Map<String, int> filePaths = callbacks.currentContextFilePaths[projPath];
expect(filePaths, hasLength(1));
expect(filePaths, contains(filePath));
- Packages packages = callbacks.currentContextDispositions[projPath].packages;
- expect(packages.packages, isEmpty);
+ expect(_currentPackageMap, isEmpty);
// update .packages
callbacks.now++;
resourceProvider.modifyFile(packagesPath, 'main:./lib/');
return pumpEventQueue().then((_) {
// verify new package info
- packages = callbacks.currentContextDispositions[projPath].packages;
- expect(packages.packages, unorderedEquals(['main']));
+ expect(_currentPackageMap.keys, unorderedEquals(['main']));
});
}
/**
* Verify that package URI's for source files in [path] will be resolved
- * using a package map matching [expectation].
- */
- void _checkPackageMap(String path, expectation) {
- FolderDisposition disposition = callbacks.currentContextDispositions[path];
- Map<String, List<Folder>> packageMap =
- disposition is PackageMapDisposition ? disposition.packageMap : null;
- expect(packageMap, expectation);
- }
-
- /**
- * Verify that package URI's for source files in [path] will be resolved
- * using a package root maching [expectation].
+ * using a package root matching [expectation].
*/
void _checkPackageRoot(String path, expectation) {
- FolderDisposition disposition = callbacks.currentContextDispositions[path];
- expect(disposition.packageRoot, expectation);
+ // TODO(brianwilkerson) Figure out how to test this. Possibly by comparing
+ // the contents of the package map (although that approach doesn't work at
+ // the moment).
+// FolderDisposition disposition = callbacks.currentContextDispositions[path];
+// expect(disposition.packageRoot, expectation);
// TODO(paulberry): we should also verify that the package map itself is
// correct. See dartbug.com/23909.
}
+
+ Map<String, List<Folder>> _packageMap(String contextPath) {
+ Folder folder = resourceProvider.getFolder(contextPath);
+ return manager.folderMap[folder]?.sourceFactory?.packageMap;
+ }
}
class TestContextManagerCallbacks extends ContextManagerCallbacks {
@@ -2367,12 +2370,6 @@
<String, Set<Source>>{};
/**
- * Map from context to folder disposition.
- */
- final Map<String, FolderDisposition> currentContextDispositions =
- <String, FolderDisposition>{};
-
- /**
* Resource provider used for this test.
*/
final ResourceProvider resourceProvider;
@@ -2392,7 +2389,6 @@
currentContextTimestamps[path] = now;
currentContextFilePaths[path] = <String, int>{};
currentContextSources[path] = new HashSet<Source>();
- currentContextDispositions[path] = disposition;
currentContext = AnalysisEngine.instance.createAnalysisContext();
_locateEmbedderYamls(currentContext, disposition);
List<UriResolver> resolvers = [];
@@ -2459,13 +2455,11 @@
currentContextTimestamps.remove(path);
currentContextFilePaths.remove(path);
currentContextSources.remove(path);
- currentContextDispositions.remove(path);
}
@override
- void updateContextPackageUriResolver(
- Folder contextFolder, FolderDisposition disposition) {
- currentContextDispositions[contextFolder.path] = disposition;
+ void updateContextPackageUriResolver(AnalysisContext context) {
+ // Nothing to do.
}
/// If [disposition] has a package map, attempt to locate `_embedder.yaml`
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 3566385..f8c0afd 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -45,7 +45,6 @@
resourceProvider,
new MockPackageMapProvider(),
null,
- null,
serverPlugin,
new AnalysisServerOptions(),
() => new MockSdk(),
@@ -473,7 +472,6 @@
resourceProvider,
new MockPackageMapProvider(),
null,
- null,
serverPlugin,
new AnalysisServerOptions(),
() => new MockSdk(),
diff --git a/pkg/analysis_server/test/domain_completion_util.dart b/pkg/analysis_server/test/domain_completion_util.dart
index 7c4ed6c..6045aee 100644
--- a/pkg/analysis_server/test/domain_completion_util.dart
+++ b/pkg/analysis_server/test/domain_completion_util.dart
@@ -10,8 +10,7 @@
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/domain_completion.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/index/index.dart' show Index;
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
+import 'package:analysis_server/src/services/index/index.dart';
import 'package:unittest/unittest.dart';
import 'analysis_abstract.dart';
@@ -24,7 +23,7 @@
int replacementLength;
List<CompletionSuggestion> suggestions = [];
bool suggestionsDone = false;
- Map<String,List<CompletionSuggestion>> allSuggestions = {};
+ Map<String, List<CompletionSuggestion>> allSuggestions = {};
String addTestFile(String content, {int offset}) {
completionOffset = content.indexOf('^');
@@ -80,7 +79,7 @@
@override
Index createIndex() {
- return createLocalMemoryIndex();
+ return createMemoryIndex();
}
Future getSuggestions() {
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index 543aba6..277279a 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -51,7 +51,6 @@
resourceProvider,
new MockPackageMapProvider(),
null,
- null,
serverPlugin,
new AnalysisServerOptions(),
() => new MockSdk(),
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index 6c1882f..e6d1dfb 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -46,7 +46,6 @@
provider,
new MockPackageMapProvider(),
null,
- null,
serverPlugin,
new AnalysisServerOptions(),
() => new MockSdk(),
diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart
index 81ab9ef..6dc24d1 100644
--- a/pkg/analysis_server/test/domain_server_test.dart
+++ b/pkg/analysis_server/test/domain_server_test.dart
@@ -35,7 +35,6 @@
resourceProvider,
new MockPackageMapProvider(),
null,
- null,
serverPlugin,
new AnalysisServerOptions(),
() => new MockSdk(),
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index fb2ee76..1b5cd87 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -7,14 +7,12 @@
import 'dart:async';
import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:plugin/manager.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart' hide ERROR;
import '../analysis_abstract.dart';
-import '../mocks.dart';
import '../utils.dart';
main() {
@@ -27,13 +25,13 @@
@override
void setUp() {
super.setUp();
- createProject();
ExtensionManager manager = new ExtensionManager();
manager.processPlugins([server.serverPlugin]);
handler = new EditDomainHandler(server);
}
test_fixUndefinedClass() async {
+ createProject();
addTestFile('''
main() {
Future<String> x = null;
@@ -52,6 +50,7 @@
}
test_hasFixes() async {
+ createProject();
addTestFile('''
foo() {
print(1)
@@ -77,19 +76,13 @@
}
test_overlayOnlyFile() async {
- // add an overlay-only file
- {
- testCode = '''
+ createProject();
+ testCode = '''
main() {
- print(1)
+print(1)
}
''';
- Request request = new AnalysisUpdateContentParams(
- {testFile: new AddContentOverlay(testCode)}).toRequest('0');
- Response response =
- new AnalysisDomainHandler(server).handleRequest(request);
- expect(response, isResponseSuccess('0'));
- }
+ _addOverlay(testFile, testCode);
// ask for fixes
await waitForTasksFinished();
List<AnalysisErrorFixes> errorFixes = await _getFixesAt('print(1)');
@@ -97,6 +90,40 @@
_isSyntacticErrorWithSingleFix(errorFixes[0]);
}
+ test_suggestImportFromDifferentAnalysisRoot() async {
+ // Set up two projects.
+ resourceProvider..newFolder("/project1")..newFolder("/project2");
+ handleSuccessfulRequest(
+ new AnalysisSetAnalysisRootsParams(["/project1", "/project2"], [])
+ .toRequest('0'),
+ handler: analysisHandler);
+
+ // Set up files.
+ testFile = "/project1/main.dart";
+ testCode = "main() { print(new Foo()); }";
+ _addOverlay(testFile, testCode);
+ // Add another file in the same project that imports the target file.
+ // This ensures it will be analyzed as an implicit Source.
+ _addOverlay("/project1/another.dart", 'import "../project2/target.dart";');
+ _addOverlay("/project2/target.dart", "class Foo() {}");
+
+ await waitForTasksFinished();
+
+ List<String> fixes = (await _getFixesAt('Foo()'))
+ .single
+ .fixes
+ .map((f) => f.message)
+ .toList();
+ expect(fixes, contains("Import library '../project2/target.dart'"));
+ }
+
+ void _addOverlay(String name, String contents) {
+ Request request =
+ new AnalysisUpdateContentParams({name: new AddContentOverlay(contents)})
+ .toRequest('0');
+ handleSuccessfulRequest(request, handler: analysisHandler);
+ }
+
Future<List<AnalysisErrorFixes>> _getFixes(int offset) async {
Request request = new EditGetFixesParams(testFile, offset).toRequest('0');
Response response = await waitResponse(request);
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index fcb0568..54a4e11 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -9,7 +9,6 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'package:plugin/manager.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart' hide ERROR;
@@ -119,11 +118,12 @@
Future<Response> _sendConvertRequest(String search) {
Request request = new EditGetRefactoringParams(
- RefactoringKind.CONVERT_GETTER_TO_METHOD,
- testFile,
- findOffset(search),
- 0,
- false).toRequest('0');
+ RefactoringKind.CONVERT_GETTER_TO_METHOD,
+ testFile,
+ findOffset(search),
+ 0,
+ false)
+ .toRequest('0');
return serverChannel.sendRequest(request);
}
}
@@ -232,11 +232,12 @@
Future<Response> _sendConvertRequest(String search) {
Request request = new EditGetRefactoringParams(
- RefactoringKind.CONVERT_METHOD_TO_GETTER,
- testFile,
- findOffset(search),
- 0,
- false).toRequest('0');
+ RefactoringKind.CONVERT_METHOD_TO_GETTER,
+ testFile,
+ findOffset(search),
+ 0,
+ false)
+ .toRequest('0');
return serverChannel.sendRequest(request);
}
}
@@ -729,7 +730,7 @@
@override
Index createIndex() {
- return createLocalMemoryIndex();
+ return createMemoryIndex();
}
/**
@@ -737,8 +738,9 @@
* [length].
*/
Future getRefactorings(int offset, int length) async {
- Request request = new EditGetAvailableRefactoringsParams(
- testFile, offset, length).toRequest('0');
+ Request request =
+ new EditGetAvailableRefactoringsParams(testFile, offset, length)
+ .toRequest('0');
serverChannel.sendRequest(request);
var response = await serverChannel.waitForResponse(request);
var result = new EditGetAvailableRefactoringsResult.fromResponse(response);
@@ -981,11 +983,12 @@
Future<Response> _sendInlineRequest(String search) {
Request request = new EditGetRefactoringParams(
- RefactoringKind.INLINE_LOCAL_VARIABLE,
- testFile,
- findOffset(search),
- 0,
- false).toRequest('0');
+ RefactoringKind.INLINE_LOCAL_VARIABLE,
+ testFile,
+ findOffset(search),
+ 0,
+ false)
+ .toRequest('0');
return serverChannel.sendRequest(request);
}
}
@@ -1108,8 +1111,13 @@
Future<Response> _sendInlineRequest(String search) {
Request request = new EditGetRefactoringParams(
- RefactoringKind.INLINE_METHOD, testFile, findOffset(search), 0, false,
- options: options).toRequest('0');
+ RefactoringKind.INLINE_METHOD,
+ testFile,
+ findOffset(search),
+ 0,
+ false,
+ options: options)
+ .toRequest('0');
return serverChannel.sendRequest(request);
}
}
@@ -1136,8 +1144,9 @@
Future<Response> _sendMoveRequest() {
Request request = new EditGetRefactoringParams(
- RefactoringKind.MOVE_FILE, testFile, 0, 0, false,
- options: options).toRequest('0');
+ RefactoringKind.MOVE_FILE, testFile, 0, 0, false,
+ options: options)
+ .toRequest('0');
return serverChannel.sendRequest(request);
}
@@ -1151,9 +1160,10 @@
Future<Response> sendRenameRequest(String search, String newName,
{String id: '0', bool validateOnly: false}) {
RenameOptions options = newName != null ? new RenameOptions(newName) : null;
- Request request = new EditGetRefactoringParams(
- RefactoringKind.RENAME, testFile, findOffset(search), 0, validateOnly,
- options: options).toRequest(id);
+ Request request = new EditGetRefactoringParams(RefactoringKind.RENAME,
+ testFile, findOffset(search), 0, validateOnly,
+ options: options)
+ .toRequest(id);
return serverChannel.sendRequest(request);
}
@@ -1853,7 +1863,7 @@
@override
Index createIndex() {
- return createLocalMemoryIndex();
+ return createMemoryIndex();
}
Future<EditGetRefactoringResult> getRefactoringResult(
@@ -1869,8 +1879,9 @@
RefactoringKind kind, int offset, int length, RefactoringOptions options,
[bool validateOnly = false]) {
Request request = new EditGetRefactoringParams(
- kind, testFile, offset, length, validateOnly,
- options: options).toRequest('0');
+ kind, testFile, offset, length, validateOnly,
+ options: options)
+ .toRequest('0');
return serverChannel.sendRequest(request);
}
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index 6266cb9..487d6a7 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -1070,6 +1070,7 @@
* "location": Location
* "message": String
* "correction": optional String
+ * "code": String
* "hasFix": optional bool
* }
*/
@@ -1078,7 +1079,8 @@
"severity": isAnalysisErrorSeverity,
"type": isAnalysisErrorType,
"location": isLocation,
- "message": isString
+ "message": isString,
+ "code": isString
}, optionalFields: {
"correction": isString,
"hasFix": isBool
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index 2d0eddd..8920e92 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -6,10 +6,12 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/plugin/protocol/protocol_dart.dart';
+import 'package:analyzer/dart/ast/ast.dart' as engine;
+import 'package:analyzer/dart/ast/visitor.dart' as engine;
import 'package:analyzer/dart/element/element.dart' as engine;
import 'package:analyzer/dart/element/type.dart' as engine;
+import 'package:analyzer/src/dart/ast/utilities.dart' as engine;
import 'package:analyzer/src/dart/element/element.dart' as engine;
-import 'package:analyzer/src/generated/ast.dart' as engine;
import 'package:analyzer/src/generated/error.dart' as engine;
import 'package:analyzer/src/generated/source.dart' as engine;
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 24d03a3..a22efee 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -9,9 +9,9 @@
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart' as engine;
import 'package:analyzer/dart/element/element.dart' as engine;
import 'package:analyzer/dart/element/type.dart' as engine;
-import 'package:analyzer/src/generated/ast.dart' as engine;
import 'package:analyzer/src/generated/error.dart' as engine;
import 'package:analyzer/src/generated/source.dart' as engine;
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -69,6 +69,7 @@
},
MESSAGE: 'my message',
CORRECTION: 'my correction',
+ CODE: 'ambiguous_export',
HAS_FIX: false
});
}
@@ -87,6 +88,7 @@
START_COLUMN: 2
},
MESSAGE: 'my message',
+ CODE: 'ambiguous_export',
HAS_FIX: false
});
}
@@ -105,6 +107,7 @@
START_COLUMN: -1
},
MESSAGE: 'my message',
+ CODE: 'ambiguous_export',
HAS_FIX: false
});
}
diff --git a/pkg/analysis_server/test/search/abstract_search_domain.dart b/pkg/analysis_server/test/search/abstract_search_domain.dart
index e88af42..9851d92 100644
--- a/pkg/analysis_server/test/search/abstract_search_domain.dart
+++ b/pkg/analysis_server/test/search/abstract_search_domain.dart
@@ -9,8 +9,8 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/search/search_domain.dart';
-import 'package:analysis_server/src/services/index/index.dart' show Index;
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
+import 'package:analysis_server/src/services/index/index.dart'
+ show Index, createMemoryIndex;
import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
@@ -39,7 +39,7 @@
@override
Index createIndex() {
- return createLocalMemoryIndex();
+ return createMemoryIndex();
}
void findResult(SearchResultKind kind, String file, int offset, int length,
@@ -94,8 +94,8 @@
@override
void setUp() {
super.setUp();
- server.handlers = [new SearchDomainHandler(server),];
createProject();
+ server.handlers = [new SearchDomainHandler(server),];
}
Future waitForSearchResults() {
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index 0ef1ccf..809a962 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -33,7 +33,8 @@
int offset = findOffset(search);
await waitForTasksFinished();
Request request = new SearchFindElementReferencesParams(
- testFile, offset, includePotential).toRequest('0');
+ testFile, offset, includePotential)
+ .toRequest('0');
Response response = await waitResponse(request);
var result = new SearchFindElementReferencesResult.fromResponse(response);
searchId = result.id;
@@ -222,178 +223,6 @@
assertHasResult(SearchResultKind.READ, 'fff); // in m()');
}
- test_file_libraryUnit_atImportDirective() async {
- String fileLib = '$testFolder/my_lib.dart';
- String fileUser = '$testFolder/userA.dart';
- String codeUser = "import 'my_lib.dart'; // U";
- addFile(fileLib, 'library my.lib;');
- addFile(fileUser, codeUser);
- addTestFile('''
-import 'my_lib.dart'; // T
-''');
- await findElementReferences('import ', false);
- expect(searchElement.kind, ElementKind.FILE);
- expect(results, hasLength(2));
- // in U
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == fileUser;
- });
- expect(result.location.offset, codeUser.indexOf("'my_lib.dart'; // U"));
- expect(result.location.length, "'my_lib.dart'".length);
- }
- // in T
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == testFile;
- });
- expect(result.location.offset, testCode.indexOf("'my_lib.dart'; // T"));
- expect(result.location.length, "'my_lib.dart'".length);
- }
- }
-
- test_file_libraryUnit_atImportDirectiveUri() async {
- String fileLib = '$testFolder/my_lib.dart';
- String fileA = '$testFolder/userA.dart';
- String fileB = '$testFolder/userB.dart';
- String codeA = "import 'my_lib.dart'; // A";
- String codeB = "export 'my_lib.dart'; // B";
- addFile(fileLib, 'library my.lib;');
- addFile(fileA, codeA);
- addFile(fileB, codeB);
- addTestFile('''
-import 'my_lib.dart'; // T
-''');
- await findElementReferences('my_', false);
- expect(searchElement.kind, ElementKind.FILE);
- expect(results, hasLength(3));
- // in A
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == fileA;
- });
- expect(result.location.offset, codeA.indexOf("'my_lib.dart'; // A"));
- expect(result.location.length, "'my_lib.dart'".length);
- }
- // in B
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == fileB;
- });
- expect(result.location.offset, codeB.indexOf("'my_lib.dart'; // B"));
- expect(result.location.length, "'my_lib.dart'".length);
- }
- // in T
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == testFile;
- });
- expect(result.location.offset, testCode.indexOf("'my_lib.dart'; // T"));
- expect(result.location.length, "'my_lib.dart'".length);
- }
- }
-
- test_file_libraryUnit_atLibraryDirectiveIdentifier() async {
- String fileA = '$testFolder/userA.dart';
- String fileB = '$testFolder/userB.dart';
- String codeA = "import 'test.dart'; // A";
- String codeB = "export 'test.dart'; // B";
- addFile(fileA, codeA);
- addFile(fileB, codeB);
- addTestFile('''
-library my.test.lib;
-''');
- await findElementReferences('test.', false);
- expect(searchElement.kind, ElementKind.LIBRARY);
- expect(results, hasLength(2));
- // in A
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == fileA;
- });
- expect(result.location.offset, codeA.indexOf("'test.dart'; // A"));
- expect(result.location.length, "'test.dart'".length);
- }
- // in B
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == fileB;
- });
- expect(result.location.offset, codeB.indexOf("'test.dart'; // B"));
- expect(result.location.length, "'test.dart'".length);
- }
- }
-
- test_file_partUnit_atPartDirective() async {
- String filePart = '$testFolder/my_part.dart';
- String fileOther = '$testFolder/userOther.dart';
- String codeOther = '''
-library lib;
-part 'my_part.dart'; // O
-''';
- addFile(filePart, 'part of lib;');
- addFile(fileOther, codeOther);
- addTestFile('''
-library lib;
-part 'my_part.dart'; // T
-''');
- await findElementReferences('part ', false);
- expect(searchElement.kind, ElementKind.FILE);
- expect(searchElement.name, filePart);
- expect(results, hasLength(2));
- // in O
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == fileOther;
- });
- expect(result.location.offset, codeOther.indexOf("'my_part.dart'; // O"));
- expect(result.location.length, "'my_part.dart'".length);
- }
- // in T
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == testFile;
- });
- expect(result.location.offset, testCode.indexOf("'my_part.dart'; // T"));
- expect(result.location.length, "'my_part.dart'".length);
- }
- }
-
- test_file_partUnit_atPartDirectiveUri() async {
- String filePart = '$testFolder/my_part.dart';
- String fileOther = '$testFolder/userOther.dart';
- String codeOther = '''
-library lib;
-part 'my_part.dart'; // O
-''';
- addFile(filePart, 'part of lib;');
- addFile(fileOther, codeOther);
- addTestFile('''
-library lib;
-part 'my_part.dart'; // T
-''');
- await findElementReferences('my_', false);
- expect(searchElement.kind, ElementKind.FILE);
- expect(searchElement.name, filePart);
- expect(results, hasLength(2));
- // in O
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == fileOther;
- });
- expect(result.location.offset, codeOther.indexOf("'my_part.dart'; // O"));
- expect(result.location.length, "'my_part.dart'".length);
- }
- // in T
- {
- SearchResult result = results.singleWhere((result) {
- return result.location.file == testFile;
- });
- expect(result.location.offset, testCode.indexOf("'my_part.dart'; // T"));
- expect(result.location.length, "'my_part.dart'".length);
- }
- }
-
test_function() async {
addTestFile('''
fff(p) {}
diff --git a/pkg/analysis_server/test/search/member_references_test.dart b/pkg/analysis_server/test/search/member_references_test.dart
index ba65bcc..23ea1c7 100644
--- a/pkg/analysis_server/test/search/member_references_test.dart
+++ b/pkg/analysis_server/test/search/member_references_test.dart
@@ -55,10 +55,10 @@
}
''');
await findMemberReferences('foo');
- assertHasRef(SearchResultKind.WRITE, 'foo = 1;', false);
- assertHasRef(SearchResultKind.WRITE, 'foo = 2;', false);
- assertHasRef(SearchResultKind.READ, 'foo); // resolved A', false);
- assertHasRef(SearchResultKind.READ, 'foo); // resolved B', false);
+ assertNoResult(SearchResultKind.WRITE, 'foo = 1;');
+ assertNoResult(SearchResultKind.WRITE, 'foo = 2;');
+ assertNoResult(SearchResultKind.READ, 'foo); // resolved A');
+ assertNoResult(SearchResultKind.READ, 'foo); // resolved B');
assertHasRef(SearchResultKind.WRITE, 'foo = 10;', true);
assertHasRef(SearchResultKind.WRITE, 'foo = 20;', true);
assertHasRef(SearchResultKind.READ, 'foo); // unresolved A', true);
@@ -83,8 +83,8 @@
}
''');
await findMemberReferences('foo');
- assertHasRef(SearchResultKind.READ, 'foo); // resolved A', false);
- assertHasRef(SearchResultKind.READ, 'foo); // resolved B', false);
+ assertNoResult(SearchResultKind.READ, 'foo); // resolved A');
+ assertNoResult(SearchResultKind.READ, 'foo); // resolved B');
assertHasRef(SearchResultKind.READ, 'foo); // unresolved A', true);
assertHasRef(SearchResultKind.READ, 'foo); // unresolved B', true);
}
@@ -107,8 +107,8 @@
}
''');
await findMemberReferences('foo');
- assertHasRef(SearchResultKind.INVOCATION, 'foo(1)', false);
- assertHasRef(SearchResultKind.INVOCATION, 'foo(2)', false);
+ assertNoResult(SearchResultKind.INVOCATION, 'foo(1)');
+ assertNoResult(SearchResultKind.INVOCATION, 'foo(2)');
assertHasRef(SearchResultKind.INVOCATION, 'foo(10)', true);
assertHasRef(SearchResultKind.INVOCATION, 'foo(20)', true);
}
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index c8b62dd..6f9c273 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -9,7 +9,6 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/search/search_domain.dart';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
@@ -27,14 +26,14 @@
@override
Index createIndex() {
- return createLocalMemoryIndex();
+ return createMemoryIndex();
}
@override
void setUp() {
super.setUp();
- server.handlers = [new SearchDomainHandler(server),];
createProject();
+ server.handlers = [new SearchDomainHandler(server),];
}
test_bad_function() async {
diff --git a/pkg/analysis_server/test/services/completion/completion_target_test.dart b/pkg/analysis_server/test/services/completion/completion_target_test.dart
index 169874b..569610c 100644
--- a/pkg/analysis_server/test/services/completion/completion_target_test.dart
+++ b/pkg/analysis_server/test/services/completion/completion_target_test.dart
@@ -5,7 +5,7 @@
library test.services.completion.target;
import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
@@ -201,7 +201,7 @@
test_FunctionDeclaration_inLineComment4() {
// Comment CompilationUnit
addTestSource('''
- // normal comment
+ // normal comment
// normal comment 2^
zoo(z) { } String name;''');
assertTarget('// normal comment 2', 'zoo(z) {} String name;');
@@ -386,7 +386,7 @@
// Comment ClassDeclaration CompilationUnit
addTestSource('''
class C2 {
- // normal comment
+ // normal comment
// normal comment 2^
zoo(z) { } String name; }''');
assertTarget('// normal comment 2', 'class C2 {zoo(z) {} String name;}');
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 8ecfc8f..549c8f1 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -13,17 +13,16 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
show DartCompletionRequestImpl, ReplacementRange;
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/task/dart.dart';
import 'package:unittest/unittest.dart';
import '../../../abstract_context.dart';
-import 'package:analysis_server/src/services/completion/completion_performance.dart';
int suggestionComparator(CompletionSuggestion s1, CompletionSuggestion s2) {
String c1 = s1.completion.toLowerCase();
@@ -541,7 +540,7 @@
@override
void setUp() {
super.setUp();
- index = createLocalMemoryIndex();
+ index = createMemoryIndex();
searchEngine = new SearchEngineImpl(index);
contributor = createContributor();
}
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index fa43aa1..3505da6 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -12,14 +12,13 @@
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/task/dart.dart';
import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
import '../../../utils.dart';
import 'completion_contributor_util.dart';
-import 'package:analyzer/src/generated/source.dart';
main() {
initializeTestEnvironment();
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 00d80df..ff07c34 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
@@ -9,7 +9,7 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -45,536 +45,6 @@
assertNotSuggested('two');
}
- test_doc_class() async {
- addSource(
- '/libA.dart',
- r'''
-library A;
-/// My class.
-/// Short description.
-///
-/// Longer description.
-class A {}
-''');
- addTestSource('import "/libA.dart"; main() {^}');
-
- await computeSuggestions();
-
- CompletionSuggestion suggestion = assertSuggestClass('A');
- expect(suggestion.docSummary, 'My class.\nShort description.');
- expect(suggestion.docComplete,
- 'My class.\nShort description.\n\nLonger description.');
- }
-
- test_doc_function() async {
- resolveSource(
- '/libA.dart',
- r'''
-library A;
-/// My function.
-/// Short description.
-///
-/// Longer description.
-int myFunc() {}
-''');
- addTestSource('import "/libA.dart"; main() {^}');
-
- await computeSuggestions();
-
- CompletionSuggestion suggestion = assertSuggestFunction('myFunc', 'int');
- expect(suggestion.docSummary, 'My function.\nShort description.');
- expect(suggestion.docComplete,
- 'My function.\nShort description.\n\nLonger description.');
- }
-
- test_doc_function_c_style() async {
- resolveSource(
- '/libA.dart',
- r'''
-library A;
-/**
- * My function.
- * Short description.
- *
- * Longer description.
- */
-int myFunc() {}
-''');
- addTestSource('import "/libA.dart"; main() {^}');
-
- await computeSuggestions();
-
- CompletionSuggestion suggestion = assertSuggestFunction('myFunc', 'int');
- expect(suggestion.docSummary, 'My function.\nShort description.');
- expect(suggestion.docComplete,
- 'My function.\nShort description.\n\nLonger description.');
- }
-
- test_enum() async {
- addSource('/libA.dart', 'library A; enum E { one, two }');
- addTestSource('import "/libA.dart"; main() {^}');
- await computeSuggestions();
- assertSuggestEnum('E');
- assertNotSuggested('one');
- assertNotSuggested('two');
- }
-
- test_function_parameters_mixed_required_and_named() async {
- resolveSource(
- '/libA.dart',
- '''
-int m(x, {int y}) {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'int');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 1);
- expect(suggestion.hasNamedParameters, true);
- }
-
- test_function_parameters_mixed_required_and_positional() async {
- resolveSource(
- '/libA.dart',
- '''
-void m(x, [int y]) {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 1);
- expect(suggestion.hasNamedParameters, false);
- }
-
- test_function_parameters_named() async {
- resolveSource(
- '/libA.dart',
- '''
-void m({x, int y}) {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, true);
- }
-
- test_function_parameters_none() async {
- resolveSource(
- '/libA.dart',
- '''
-void m() {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
-
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, isEmpty);
- expect(suggestion.parameterTypes, isEmpty);
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, false);
- }
-
- test_function_parameters_positional() async {
- resolveSource(
- '/libA.dart',
- '''
-void m([x, int y]) {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, false);
- }
-
- test_function_parameters_required() async {
- resolveSource(
- '/libA.dart',
- '''
-void m(x, int y) {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 2);
- expect(suggestion.hasNamedParameters, false);
- }
-
- test_InstanceCreationExpression() async {
- resolveSource(
- '/testA.dart',
- '''
-class A {foo(){var f; {var x;}}}
-class B {B(this.x, [String boo]) { } int x;}
-class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
- addTestSource('''
-import "/testA.dart";
-import "dart:math" as math;
-main() {new ^ String x = "hello";}''');
-
- await computeSuggestions();
- CompletionSuggestion suggestion;
-
- suggestion = assertSuggestConstructor('Object');
- expect(suggestion.element.parameters, '()');
- expect(suggestion.parameterNames, hasLength(0));
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, false);
-
- suggestion = assertSuggestConstructor('A');
- expect(suggestion.element.parameters, '()');
- expect(suggestion.parameterNames, hasLength(0));
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, false);
-
- suggestion = assertSuggestConstructor('B');
- expect(suggestion.element.parameters, '(int x, [String boo])');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'int');
- expect(suggestion.parameterNames[1], 'boo');
- expect(suggestion.parameterTypes[1], 'String');
- expect(suggestion.requiredParameterCount, 1);
- expect(suggestion.hasNamedParameters, false);
-
- suggestion = assertSuggestConstructor('C.bar');
- expect(suggestion.element.parameters, "({dynamic boo: 'hoo', int z: 0})");
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'boo');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'z');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, true);
-
- // Suggested by LibraryPrefixContributor
- assertNotSuggested('math');
- }
-
- test_internal_sdk_libs() async {
- addTestSource('main() {p^}');
-
- await computeSuggestions();
- assertSuggest('print');
- // Not imported, so not suggested
- assertNotSuggested('pow');
- // Do not suggest completions from internal SDK library
- assertNotSuggested('printToConsole');
- }
-
- test_method_parameters_mixed_required_and_named() async {
- resolveSource(
- '/libA.dart',
- '''
-void m(x, {int y}) {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 1);
- expect(suggestion.hasNamedParameters, true);
- }
-
- test_method_parameters_mixed_required_and_positional() async {
- resolveSource(
- '/libA.dart',
- '''
-void m(x, [int y]) {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 1);
- expect(suggestion.hasNamedParameters, false);
- }
-
- test_method_parameters_named() async {
- resolveSource(
- '/libA.dart',
- '''
-void m({x, int y}) {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, true);
- }
-
- test_method_parameters_none() async {
- resolveSource(
- '/libA.dart',
- '''
-void m() {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
-
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, isEmpty);
- expect(suggestion.parameterTypes, isEmpty);
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, false);
- }
-
- test_method_parameters_positional() async {
- resolveSource(
- '/libA.dart',
- '''
-void m([x, int y]) {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 0);
- expect(suggestion.hasNamedParameters, false);
- }
-
- test_method_parameters_required() async {
- resolveSource(
- '/libA.dart',
- '''
-void m(x, int y) {}
-''');
- addTestSource('''
-import '/libA.dart';
-class B {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
- expect(suggestion.parameterNames, hasLength(2));
- expect(suggestion.parameterNames[0], 'x');
- expect(suggestion.parameterTypes[0], 'dynamic');
- expect(suggestion.parameterNames[1], 'y');
- expect(suggestion.parameterTypes[1], 'int');
- expect(suggestion.requiredParameterCount, 2);
- expect(suggestion.hasNamedParameters, false);
- }
-
- test_mixin_ordering() async {
- addSource(
- '/libA.dart',
- '''
-class B {}
-class M1 {
- void m() {}
-}
-class M2 {
- void m() {}
-}
-''');
- addTestSource('''
-import '/libA.dart';
-class C extends B with M1, M2 {
- void f() {
- ^
- }
-}
-''');
- await computeSuggestions();
- assertNotSuggested('m');
- }
-
- /**
- * Ensure that completions in one context don't appear in another
- */
- test_multiple_contexts() async {
- // Create a 2nd context with source
- var context2 = AnalysisEngine.instance.createAnalysisContext();
- context2.sourceFactory =
- new SourceFactory([AbstractContextTest.SDK_RESOLVER, resourceResolver]);
- String content2 = 'class ClassFromAnotherContext { }';
- Source source2 =
- provider.newFile('/context2/foo.dart', content2).createSource();
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source2);
- context2.applyChanges(changeSet);
- context2.setContents(source2, content2);
-
- // Resolve the source in the 2nd context and update the index
- var result = context2.performAnalysisTask();
- while (result.hasMoreWork) {
- result.changeNotices.forEach((ChangeNotice notice) {
- CompilationUnit unit = notice.resolvedDartUnit;
- if (unit != null) {
- index.index(context2, unit);
- }
- });
- result = context2.performAnalysisTask();
- }
-
- // Check that source in 2nd context does not appear in completion in 1st
- addSource(
- '/context1/libA.dart',
- '''
- library libA;
- class ClassInLocalContext {int x;}''');
- testFile = '/context1/completionTest.dart';
- addTestSource('''
- import "/context1/libA.dart";
- import "/foo.dart";
- main() {C^}
- ''');
-
- await computeSuggestions();
- assertSuggestClass('ClassInLocalContext');
- // Assert contributor does not include results from 2nd context.
- assertNotSuggested('ClassFromAnotherContext');
- }
-
- test_no_parameters_field() async {
- addSource(
- '/libA.dart',
- '''
-int x;
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestTopLevelVar('x', null);
- assertHasNoParameterInfo(suggestion);
- }
-
- test_no_parameters_getter() async {
- resolveSource(
- '/libA.dart',
- '''
-int get x => null;
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
- assertHasNoParameterInfo(suggestion);
- }
-
- test_no_parameters_setter() async {
- addSource(
- '/libA.dart',
- '''
-set x(int value) {};
-''');
- addTestSource('''
-import '/libA.dart';
-class B extends A {
- main() {^}
-}
-''');
- await computeSuggestions();
- CompletionSuggestion suggestion = assertSuggestSetter('x');
- assertHasNoParameterInfo(suggestion);
- }
-
test_ArgumentList() async {
// ArgumentList MethodInvocation ExpressionStatement Block
resolveSource(
@@ -2373,6 +1843,80 @@
assertNotSuggested('bar');
}
+ test_doc_class() async {
+ addSource(
+ '/libA.dart',
+ r'''
+library A;
+/// My class.
+/// Short description.
+///
+/// Longer description.
+class A {}
+''');
+ addTestSource('import "/libA.dart"; main() {^}');
+
+ await computeSuggestions();
+
+ CompletionSuggestion suggestion = assertSuggestClass('A');
+ expect(suggestion.docSummary, 'My class.\nShort description.');
+ expect(suggestion.docComplete,
+ 'My class.\nShort description.\n\nLonger description.');
+ }
+
+ test_doc_function() async {
+ resolveSource(
+ '/libA.dart',
+ r'''
+library A;
+/// My function.
+/// Short description.
+///
+/// Longer description.
+int myFunc() {}
+''');
+ addTestSource('import "/libA.dart"; main() {^}');
+
+ await computeSuggestions();
+
+ CompletionSuggestion suggestion = assertSuggestFunction('myFunc', 'int');
+ expect(suggestion.docSummary, 'My function.\nShort description.');
+ expect(suggestion.docComplete,
+ 'My function.\nShort description.\n\nLonger description.');
+ }
+
+ test_doc_function_c_style() async {
+ resolveSource(
+ '/libA.dart',
+ r'''
+library A;
+/**
+ * My function.
+ * Short description.
+ *
+ * Longer description.
+ */
+int myFunc() {}
+''');
+ addTestSource('import "/libA.dart"; main() {^}');
+
+ await computeSuggestions();
+
+ CompletionSuggestion suggestion = assertSuggestFunction('myFunc', 'int');
+ expect(suggestion.docSummary, 'My function.\nShort description.');
+ expect(suggestion.docComplete,
+ 'My function.\nShort description.\n\nLonger description.');
+ }
+
+ test_enum() async {
+ addSource('/libA.dart', 'library A; enum E { one, two }');
+ addTestSource('import "/libA.dart"; main() {^}');
+ await computeSuggestions();
+ assertSuggestEnum('E');
+ assertNotSuggested('one');
+ assertNotSuggested('two');
+ }
+
test_ExpressionStatement_identifier() async {
// SimpleIdentifier ExpressionStatement Block
resolveSource(
@@ -2595,6 +2139,142 @@
assertNotSuggested('bar');
}
+ test_function_parameters_mixed_required_and_named() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+int m(x, {int y}) {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'int');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 1);
+ expect(suggestion.hasNamedParameters, true);
+ }
+
+ test_function_parameters_mixed_required_and_positional() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m(x, [int y]) {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 1);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
+ test_function_parameters_named() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m({x, int y}) {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, true);
+ }
+
+ test_function_parameters_none() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m() {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, isEmpty);
+ expect(suggestion.parameterTypes, isEmpty);
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
+ test_function_parameters_positional() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m([x, int y]) {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
+ test_function_parameters_required() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m(x, int y) {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 2);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
test_FunctionDeclaration_returnType_afterComment() async {
// ClassDeclaration CompilationUnit
resolveSource(
@@ -2827,6 +2507,57 @@
//assertSuggestImportedTopLevelVar('T1', 'int');
}
+ test_InstanceCreationExpression() async {
+ resolveSource(
+ '/testA.dart',
+ '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+ addTestSource('''
+import "/testA.dart";
+import "dart:math" as math;
+main() {new ^ String x = "hello";}''');
+
+ await computeSuggestions();
+ CompletionSuggestion suggestion;
+
+ suggestion = assertSuggestConstructor('Object');
+ expect(suggestion.element.parameters, '()');
+ expect(suggestion.parameterNames, hasLength(0));
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, false);
+
+ suggestion = assertSuggestConstructor('A');
+ expect(suggestion.element.parameters, '()');
+ expect(suggestion.parameterNames, hasLength(0));
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, false);
+
+ suggestion = assertSuggestConstructor('B');
+ expect(suggestion.element.parameters, '(int x, [String boo])');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'int');
+ expect(suggestion.parameterNames[1], 'boo');
+ expect(suggestion.parameterTypes[1], 'String');
+ expect(suggestion.requiredParameterCount, 1);
+ expect(suggestion.hasNamedParameters, false);
+
+ suggestion = assertSuggestConstructor('C.bar');
+ expect(suggestion.element.parameters, "({dynamic boo: 'hoo', int z: 0})");
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'boo');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'z');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, true);
+
+ // Suggested by LibraryPrefixContributor
+ assertNotSuggested('math');
+ }
+
test_InstanceCreationExpression_imported() async {
// SimpleIdentifier TypeName ConstructorName InstanceCreationExpression
addSource(
@@ -2874,6 +2605,17 @@
assertNotSuggested('Foo');
}
+ test_internal_sdk_libs() async {
+ addTestSource('main() {p^}');
+
+ await computeSuggestions();
+ assertSuggest('print');
+ // Not imported, so not suggested
+ assertNotSuggested('pow');
+ // Do not suggest completions from internal SDK library
+ assertNotSuggested('printToConsole');
+ }
+
test_InterpolationExpression() async {
// SimpleIdentifier InterpolationExpression StringInterpolation
addSource(
@@ -3197,6 +2939,142 @@
assertNotSuggested('T2');
}
+ test_method_parameters_mixed_required_and_named() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m(x, {int y}) {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 1);
+ expect(suggestion.hasNamedParameters, true);
+ }
+
+ test_method_parameters_mixed_required_and_positional() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m(x, [int y]) {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 1);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
+ test_method_parameters_named() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m({x, int y}) {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, true);
+ }
+
+ test_method_parameters_none() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m() {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, isEmpty);
+ expect(suggestion.parameterTypes, isEmpty);
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
+ test_method_parameters_positional() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m([x, int y]) {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 0);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
+ test_method_parameters_required() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+void m(x, int y) {}
+''');
+ addTestSource('''
+import '/libA.dart';
+class B {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+ expect(suggestion.parameterNames, hasLength(2));
+ expect(suggestion.parameterNames[0], 'x');
+ expect(suggestion.parameterTypes[0], 'dynamic');
+ expect(suggestion.parameterNames[1], 'y');
+ expect(suggestion.parameterTypes[1], 'int');
+ expect(suggestion.requiredParameterCount, 2);
+ expect(suggestion.hasNamedParameters, false);
+ }
+
test_MethodDeclaration_body_getters() async {
// Block BlockFunctionBody MethodDeclaration
addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
@@ -3453,6 +3331,77 @@
assertNotSuggested('==');
}
+ test_mixin_ordering() async {
+ addSource(
+ '/libA.dart',
+ '''
+class B {}
+class M1 {
+ void m() {}
+}
+class M2 {
+ void m() {}
+}
+''');
+ addTestSource('''
+import '/libA.dart';
+class C extends B with M1, M2 {
+ void f() {
+ ^
+ }
+}
+''');
+ await computeSuggestions();
+ assertNotSuggested('m');
+ }
+
+ /**
+ * Ensure that completions in one context don't appear in another
+ */
+ test_multiple_contexts() async {
+ // Create a 2nd context with source
+ var context2 = AnalysisEngine.instance.createAnalysisContext();
+ context2.sourceFactory =
+ new SourceFactory([AbstractContextTest.SDK_RESOLVER, resourceResolver]);
+ String content2 = 'class ClassFromAnotherContext { }';
+ Source source2 =
+ provider.newFile('/context2/foo.dart', content2).createSource();
+ ChangeSet changeSet = new ChangeSet();
+ changeSet.addedSource(source2);
+ context2.applyChanges(changeSet);
+ context2.setContents(source2, content2);
+
+ // Resolve the source in the 2nd context and update the index
+ var result = context2.performAnalysisTask();
+ while (result.hasMoreWork) {
+ result.changeNotices.forEach((ChangeNotice notice) {
+ CompilationUnit unit = notice.resolvedDartUnit;
+ if (unit != null) {
+ index.indexUnit(unit);
+ }
+ });
+ result = context2.performAnalysisTask();
+ }
+
+ // Check that source in 2nd context does not appear in completion in 1st
+ addSource(
+ '/context1/libA.dart',
+ '''
+ library libA;
+ class ClassInLocalContext {int x;}''');
+ testFile = '/context1/completionTest.dart';
+ addTestSource('''
+ import "/context1/libA.dart";
+ import "/foo.dart";
+ main() {C^}
+ ''');
+
+ await computeSuggestions();
+ assertSuggestClass('ClassInLocalContext');
+ // Assert contributor does not include results from 2nd context.
+ assertNotSuggested('ClassFromAnotherContext');
+ }
+
test_new_instance() async {
addTestSource('import "dart:math"; class A {x() {new Random().^}}');
@@ -3465,6 +3414,57 @@
assertNotSuggested('A');
}
+ test_no_parameters_field() async {
+ addSource(
+ '/libA.dart',
+ '''
+int x;
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestTopLevelVar('x', null);
+ assertHasNoParameterInfo(suggestion);
+ }
+
+ test_no_parameters_getter() async {
+ resolveSource(
+ '/libA.dart',
+ '''
+int get x => null;
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
+ assertHasNoParameterInfo(suggestion);
+ }
+
+ test_no_parameters_setter() async {
+ addSource(
+ '/libA.dart',
+ '''
+set x(int value) {};
+''');
+ addTestSource('''
+import '/libA.dart';
+class B extends A {
+ main() {^}
+}
+''');
+ await computeSuggestions();
+ CompletionSuggestion suggestion = assertSuggestSetter('x');
+ assertHasNoParameterInfo(suggestion);
+ }
+
test_parameterName_excludeTypes() async {
addTestSource('m(int ^) {}');
await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
index 5765c68..aa878d5 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
@@ -5,10 +5,10 @@
library test.services.completion.local_declaration_visitor_test;
import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/optype_test.dart b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
index bc7da40..14cc3a8 100644
--- a/pkg/analysis_server/test/services/completion/dart/optype_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
@@ -7,7 +7,7 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
import 'package:analysis_server/src/services/completion/dart/optype.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 853a448..b059279 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -1404,6 +1404,31 @@
''');
}
+ test_createField_getter_qualified_propagatedType() async {
+ resolveTestUnit('''
+class A {
+ A get self => this;
+}
+main() {
+ var a = new A();
+ int v = a.self.test;
+}
+''');
+ await assertHasFix(
+ DartFixKind.CREATE_FIELD,
+ '''
+class A {
+ int test;
+
+ A get self => this;
+}
+main() {
+ var a = new A();
+ int v = a.self.test;
+}
+''');
+ }
+
test_createField_getter_unqualified_instance_asInvocationArgument() async {
resolveTestUnit('''
class A {
@@ -1983,6 +2008,31 @@
''');
}
+ test_createGetter_qualified_propagatedType() async {
+ resolveTestUnit('''
+class A {
+ A get self => this;
+}
+main() {
+ var a = new A();
+ int v = a.self.test;
+}
+''');
+ await assertHasFix(
+ DartFixKind.CREATE_GETTER,
+ '''
+class A {
+ A get self => this;
+
+ int get test => null;
+}
+main() {
+ var a = new A();
+ int v = a.self.test;
+}
+''');
+ }
+
test_createGetter_setterContext() async {
resolveTestUnit('''
class A {
diff --git a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
index 1c2a964..d74328f 100644
--- a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
+++ b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
@@ -5,9 +5,9 @@
library test.services.correction.name_suggestion;
import 'package:analysis_server/src/services/correction/name_suggestion.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/correction/source_range_test.dart b/pkg/analysis_server/test/services/correction/source_range_test.dart
index 43d080b..dfc6544 100644
--- a/pkg/analysis_server/test/services/correction/source_range_test.dart
+++ b/pkg/analysis_server/test/services/correction/source_range_test.dart
@@ -5,8 +5,8 @@
library test.services.correction.source_range;
import 'package:analysis_server/src/services/correction/source_range.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/test/services/correction/status_test.dart b/pkg/analysis_server/test/services/correction/status_test.dart
index fe0aae6..0de1517 100644
--- a/pkg/analysis_server/test/services/correction/status_test.dart
+++ b/pkg/analysis_server/test/services/correction/status_test.dart
@@ -8,8 +8,8 @@
import 'package:analysis_server/src/services/correction/source_range.dart';
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart b/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
index b040926..89369cd 100644
--- a/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
+++ b/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
@@ -5,7 +5,7 @@
library test.services.dependencies.import_collector;
import 'package:analysis_server/src/services/dependencies/reachable_source_collector.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart b/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
deleted file mode 100644
index a33bd47..0000000
--- a/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
+++ /dev/null
@@ -1,1803 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.src.index.dart_index_contributor;
-
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/index_contributor.dart';
-import 'package:analysis_server/src/services/index/index_store.dart';
-import 'package:analysis_server/src/services/index/indexable_element.dart';
-import 'package:analysis_server/src/services/index/indexable_file.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_single_unit.dart';
-import '../../utils.dart';
-
-main() {
- initializeTestEnvironment();
- defineReflectiveTests(DartUnitContributorTest);
-}
-
-void indexDartUnit(
- InternalIndexStore store, AnalysisContext context, CompilationUnit unit) {
- new DartIndexContributor().contributeTo(store, context, unit);
-}
-
-/**
- * Returns `true` if the [actual] location the same properties as [expected].
- */
-bool _equalsLocation(LocationImpl actual, ExpectedLocation expected) {
- return _equalsLocationProperties(actual, expected.indexable, expected.offset,
- expected.length, expected.isQualified, expected.isResolved);
-}
-
-/**
- * Returns `true` if the [actual] location the expected properties.
- */
-bool _equalsLocationProperties(
- LocationImpl actual,
- IndexableObject expectedIndexable,
- int expectedOffset,
- int expectedLength,
- bool isQualified,
- bool isResolved) {
- return (expectedIndexable == null || expectedIndexable == actual.indexable) &&
- expectedOffset == actual.offset &&
- expectedLength == actual.length &&
- isQualified == actual.isQualified &&
- isResolved == actual.isResolved;
-}
-
-bool _equalsRecordedRelation(
- RecordedRelation recordedRelation,
- IndexableObject expectedIndexable,
- RelationshipImpl expectedRelationship,
- ExpectedLocation expectedLocation) {
- return expectedIndexable == recordedRelation.indexable &&
- (expectedRelationship == null ||
- expectedRelationship == recordedRelation.relationship) &&
- (expectedLocation == null ||
- _equalsLocation(recordedRelation.location, expectedLocation));
-}
-
-@reflectiveTest
-class DartUnitContributorTest extends AbstractSingleUnitTest {
- InternalIndexStore store = new MockIndexStore();
- List<RecordedRelation> recordedRelations = <RecordedRelation>[];
- List<Element> recordedTopElements = <Element>[];
-
- CompilationUnitElement importedUnit({int index: 0}) {
- List<ImportElement> imports = testLibraryElement.imports;
- return imports[index].importedLibrary.definingCompilationUnit;
- }
-
- void setUp() {
- super.setUp();
- when(store.aboutToIndex(context, anyObject)).thenReturn(true);
- when(store.recordRelationship(anyObject, anyObject, anyObject)).thenInvoke(
- (IndexableObject indexable, RelationshipImpl relationship,
- LocationImpl location) {
- recordedRelations
- .add(new RecordedRelation(indexable, relationship, location));
- });
- when(store.recordTopLevelDeclaration(anyObject))
- .thenInvoke((Element element) {
- recordedTopElements.add(element);
- });
- }
-
- void test_bad_unresolvedFieldFormalParameter() {
- verifyNoTestUnitErrors = false;
- _indexTestUnit('''
-class Test {
- final field;
- Test(this.fie);
-}''');
- }
-
- void test_definesClass() {
- _indexTestUnit('class A {}');
- // prepare elements
- ClassElement classElement = findElement("A");
- // verify
- _assertDefinesTopLevelElement(classElement);
- }
-
- void test_definesClassAlias() {
- _indexTestUnit('''
-class Mix {}
-class MyClass = Object with Mix;''');
- // prepare elements
- Element classElement = findElement("MyClass");
- // verify
- _assertDefinesTopLevelElement(classElement);
- }
-
- void test_definesClassEnum() {
- _indexTestUnit('enum MyEnum {A, B, c}');
- // prepare elements
- ClassElement classElement = findElement("MyEnum");
- // verify
- _assertDefinesTopLevelElement(classElement);
- }
-
- void test_definesFunction() {
- _indexTestUnit('myFunction() {}');
- // prepare elements
- FunctionElement functionElement = findElement("myFunction");
- // verify
- _assertDefinesTopLevelElement(functionElement);
- }
-
- void test_definesFunctionType() {
- _indexTestUnit('typedef MyFunction(int p);');
- // prepare elements
- FunctionTypeAliasElement typeAliasElement = findElement("MyFunction");
- // verify
- _assertDefinesTopLevelElement(typeAliasElement);
- }
-
- void test_definesVariable() {
- _indexTestUnit('var myVar = 42;');
- // prepare elements
- VariableElement varElement = findElement("myVar");
- // verify
- _assertDefinesTopLevelElement(varElement);
- }
-
- void test_forIn() {
- _indexTestUnit('''
-main() {
- for (var v in []) {
- }
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- VariableElement variableElement = findElement("v");
- // verify
- _assertNoRecordedRelationForElement(variableElement,
- IndexConstants.IS_READ_BY, _expectedLocation(mainElement, 'v in []'));
- }
-
- void test_hasAncestor_ClassDeclaration() {
- _indexTestUnit('''
-class A {}
-class B1 extends A {}
-class B2 implements A {}
-class C1 extends B1 {}
-class C2 extends B2 {}
-class C3 implements B1 {}
-class C4 implements B2 {}
-class M extends Object with A {}
-''');
- // prepare elements
- ClassElement classElementA = findElement("A");
- ClassElement classElementB1 = findElement("B1");
- ClassElement classElementB2 = findElement("B2");
- ClassElement classElementC1 = findElement("C1");
- ClassElement classElementC2 = findElement("C2");
- ClassElement classElementC3 = findElement("C3");
- ClassElement classElementC4 = findElement("C4");
- ClassElement classElementM = findElement("M");
- // verify
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.HAS_ANCESTOR,
- _expectedLocation(classElementB1, 'B1 extends A'));
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.HAS_ANCESTOR,
- _expectedLocation(classElementB2, 'B2 implements A'));
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.HAS_ANCESTOR,
- _expectedLocation(classElementC1, 'C1 extends B1'));
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.HAS_ANCESTOR,
- _expectedLocation(classElementC2, 'C2 extends B2'));
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.HAS_ANCESTOR,
- _expectedLocation(classElementC3, 'C3 implements B1'));
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.HAS_ANCESTOR,
- _expectedLocation(classElementC4, 'C4 implements B2'));
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.HAS_ANCESTOR,
- _expectedLocation(classElementM, 'M extends Object with A'));
- }
-
- void test_hasAncestor_ClassTypeAlias() {
- _indexTestUnit('''
-class A {}
-class B extends A {}
-class C1 = Object with A;
-class C2 = Object with B;
-''');
- // prepare elements
- ClassElement classElementA = findElement("A");
- ClassElement classElementB = findElement("B");
- ClassElement classElementC1 = findElement("C1");
- ClassElement classElementC2 = findElement("C2");
- // verify
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.HAS_ANCESTOR,
- _expectedLocation(classElementC1, 'C1 = Object with A'));
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.HAS_ANCESTOR,
- _expectedLocation(classElementC2, 'C2 = Object with B'));
- _assertRecordedRelationForElement(
- classElementB,
- IndexConstants.HAS_ANCESTOR,
- _expectedLocation(classElementC2, 'C2 = Object with B'));
- }
-
- void test_IndexableName_field() {
- _indexTestUnit('''
-class A {
- int field;
-}
-main(A a, p) {
- print(a.field); // r
- print(p.field); // ur
- {
- var field = 42;
- print(field); // not a member
- }
-}
-''');
- // prepare elements
- Element mainElement = findElement('main');
- FieldElement fieldElement = findElement('field');
- IndexableName indexable = new IndexableName('field');
- // verify
- _assertRecordedRelation(indexable, IndexConstants.NAME_IS_DEFINED_BY,
- _expectedLocation(fieldElement, 'field;'));
- _assertRecordedRelation(indexable, IndexConstants.IS_READ_BY,
- _expectedLocationQ(mainElement, 'field); // r'));
- _assertRecordedRelation(indexable, IndexConstants.IS_READ_BY,
- _expectedLocationQU(mainElement, 'field); // ur'));
- _assertNoRecordedRelation(indexable, IndexConstants.IS_READ_BY,
- _expectedLocation(mainElement, 'field); // not a member'));
- }
-
- void test_IndexableName_isDefinedBy_localVariable_inForEach() {
- _indexTestUnit('''
-class A {
- main() {
- for (int test in []) {
- }
- }
-}
-''');
- // prepare elements
- LocalVariableElement testElement = findElement('test');
- IndexableName indexable = new IndexableName('test');
- // verify
- _assertRecordedRelation(indexable, IndexConstants.NAME_IS_DEFINED_BY,
- _expectedLocation(testElement, 'test in []'));
- }
-
- void test_IndexableName_method() {
- _indexTestUnit('''
-class A {
- method() {}
-}
-main(A a, p) {
- a.method(); // r
- p.method(); // ur
-}
-''');
- // prepare elements
- Element mainElement = findElement('main');
- MethodElement methodElement = findElement('method');
- IndexableName indexable = new IndexableName('method');
- // verify
- _assertRecordedRelation(indexable, IndexConstants.NAME_IS_DEFINED_BY,
- _expectedLocation(methodElement, 'method() {}'));
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, 'method(); // r'));
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQU(mainElement, 'method(); // ur'));
- }
-
- void test_IndexableName_operator_resolved() {
- _indexTestUnit('''
-class A {
- operator +(o) {}
- operator -(o) {}
- operator ~() {}
- operator ==(o) {}
-}
-main(A a) {
- a + 5;
- a += 5;
- a == 5;
- ++a;
- --a;
- ~a;
- a++;
- a--;
-}
-''');
- // prepare elements
- Element mainElement = findElement('main');
- // binary
- _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '+ 5', length: 1));
- _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '+= 5', length: 2));
- _assertRecordedRelationForName('==', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '== 5', length: 2));
- // prefix
- _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '++a', length: 2));
- _assertRecordedRelationForName('-', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '--a', length: 2));
- _assertRecordedRelationForName('~', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '~a', length: 1));
- // postfix
- _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '++;', length: 2));
- _assertRecordedRelationForName('-', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '--;', length: 2));
- }
-
- void test_IndexableName_operator_unresolved() {
- _indexTestUnit('''
-class A {
- operator +(o) {}
- operator -(o) {}
- operator ~() {}
- operator ==(o) {}
-}
-main(a) {
- a + 5;
- a += 5;
- a == 5;
- ++a;
- --a;
- ~a;
- a++;
- a--;
-}
-''');
- // prepare elements
- Element mainElement = findElement('main');
- // binary
- _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQU(mainElement, '+ 5', length: 1));
- _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQU(mainElement, '+= 5', length: 2));
- _assertRecordedRelationForName('==', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQU(mainElement, '== 5', length: 2));
- // prefix
- _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQU(mainElement, '++a', length: 2));
- _assertRecordedRelationForName('-', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQU(mainElement, '--a', length: 2));
- _assertRecordedRelationForName('~', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQU(mainElement, '~a', length: 1));
- // postfix
- _assertRecordedRelationForName('+', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQU(mainElement, '++;', length: 2));
- _assertRecordedRelationForName('-', IndexConstants.IS_INVOKED_BY,
- _expectedLocationQU(mainElement, '--;', length: 2));
- }
-
- void test_isDefinedBy_IndexableName_method() {
- _indexTestUnit('''
-class A {
- m() {}
-}''');
- // prepare elements
- Element methodElement = findElement("m");
- IndexableName nameIndexable = new IndexableName("m");
- // verify
- _assertRecordedRelationForIndexable(
- nameIndexable,
- IndexConstants.NAME_IS_DEFINED_BY,
- _expectedLocation(methodElement, 'm() {}'));
- }
-
- void test_isDefinedBy_IndexableName_operator() {
- _indexTestUnit('''
-class A {
- operator +(o) {}
-}''');
- // prepare elements
- Element methodElement = findElement("+");
- IndexableName nameIndexable = new IndexableName("+");
- // verify
- _assertRecordedRelationForIndexable(
- nameIndexable,
- IndexConstants.NAME_IS_DEFINED_BY,
- _expectedLocation(methodElement, '+(o) {}', length: 1));
- }
-
- void test_isExtendedBy_ClassDeclaration() {
- _indexTestUnit('''
-class A {} // 1
-class B extends A {} // 2
-''');
- // prepare elements
- ClassElement classElementA = findElement("A");
- ClassElement classElementB = findElement("B");
- // verify
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.IS_EXTENDED_BY,
- _expectedLocation(classElementB, 'A {} // 2'));
- }
-
- void test_isExtendedBy_ClassDeclaration_Object() {
- _indexTestUnit('''
-class A {} // 1
-''');
- // prepare elements
- ClassElement classElementA = findElement("A");
- ClassElement classElementObject = classElementA.supertype.element;
- // verify
- _assertRecordedRelationForElement(
- classElementObject,
- IndexConstants.IS_EXTENDED_BY,
- _expectedLocation(classElementA, 'A {}', length: 0));
- }
-
- void test_isExtendedBy_ClassTypeAlias() {
- _indexTestUnit('''
-class A {} // 1
-class B {} // 2
-class C = A with B; // 3
-''');
- // prepare elements
- ClassElement classElementA = findElement("A");
- ClassElement classElementC = findElement("C");
- // verify
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.IS_EXTENDED_BY,
- _expectedLocation(classElementC, 'A with'));
- }
-
- void test_isImplementedBy_ClassDeclaration() {
- _indexTestUnit('''
-class A {} // 1
-class B implements A {} // 2
-''');
- // prepare elements
- ClassElement classElementA = findElement("A");
- ClassElement classElementB = findElement("B");
- // verify
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.IS_IMPLEMENTED_BY,
- _expectedLocation(classElementB, 'A {} // 2'));
- }
-
- void test_isImplementedBy_ClassTypeAlias() {
- _indexTestUnit('''
-class A {} // 1
-class B {} // 2
-class C = Object with A implements B; // 3
-''');
- // prepare elements
- ClassElement classElementB = findElement("B");
- ClassElement classElementC = findElement("C");
- // verify
- _assertRecordedRelationForElement(
- classElementB,
- IndexConstants.IS_IMPLEMENTED_BY,
- _expectedLocation(classElementC, 'B; // 3'));
- }
-
- void test_isInvokedBy_FieldElement() {
- _indexTestUnit('''
-class A {
- var field;
- main() {
- this.field(); // q
- field(); // nq
- }
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- FieldElement fieldElement = findElement("field");
- PropertyAccessorElement getterElement = fieldElement.getter;
- IndexableElement indexable = new IndexableElement(getterElement);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, 'field(); // q'));
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocation(mainElement, 'field(); // nq'));
- }
-
- void test_isInvokedBy_FunctionElement() {
- addSource(
- '/lib.dart',
- '''
-library lib;
-foo() {}
-''');
- _indexTestUnit('''
-import 'lib.dart';
-import 'lib.dart' as pref;
-main() {
- pref.foo(); // q
- foo(); // nq
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- FunctionElement functionElement = importedUnit().functions[0];
- IndexableElement indexable = new IndexableElement(functionElement);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocation(mainElement, 'foo(); // q'));
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocation(mainElement, 'foo(); // nq'));
- }
-
- void test_isInvokedBy_LocalVariableElement() {
- _indexTestUnit('''
-main() {
- var v;
- v();
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- Element element = findElement("v");
- // verify
- _assertRecordedRelationForElement(element, IndexConstants.IS_INVOKED_BY,
- _expectedLocation(mainElement, 'v();'));
- }
-
- void test_isInvokedBy_MethodElement() {
- _indexTestUnit('''
-class A {
- foo() {}
- main() {
- this.foo(); // q
- foo(); // nq
- }
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- Element methodElement = findElement("foo");
- IndexableElement indexable = new IndexableElement(methodElement);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, 'foo(); // q'));
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocation(mainElement, 'foo(); // nq'));
- }
-
- void test_isInvokedBy_MethodElement_propagatedType() {
- _indexTestUnit('''
-class A {
- foo() {}
-}
-main() {
- var a = new A();
- a.foo();
-}
-''');
- // prepare elements
- Element mainElement = findElement("main");
- Element methodElement = findElement("foo");
- // verify
- _assertRecordedRelationForElement(
- methodElement,
- IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, 'foo();'));
- }
-
- void test_isInvokedBy_operator_binary() {
- _indexTestUnit('''
-class A {
- operator +(other) => this;
-}
-main(A a) {
- print(a + 1);
- a += 2;
- ++a;
- a++;
-}
-''');
- // prepare elements
- MethodElement element = findElement('+');
- Element mainElement = findElement('main');
- IndexableElement indexable = new IndexableElement(element);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '+ 1', length: 1));
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '+= 2', length: 2));
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '++a;', length: 2));
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '++;', length: 2));
- }
-
- void test_isInvokedBy_operator_index() {
- _indexTestUnit('''
-class A {
- operator [](i) => null;
- operator []=(i, v) {}
-}
-main(A a) {
- print(a[0]);
- a[1] = 42;
-}
-''');
- // prepare elements
- MethodElement readElement = findElement("[]");
- MethodElement writeElement = findElement("[]=");
- Element mainElement = findElement('main');
- // verify
- _assertRecordedRelationForElement(readElement, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '[0]', length: 1));
- _assertRecordedRelationForElement(
- writeElement,
- IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '[1] =', length: 1));
- }
-
- void test_isInvokedBy_operator_prefix() {
- _indexTestUnit('''
-class A {
- A operator ~() => this;
-}
-main(A a) {
- print(~a);
-}
-''');
- // prepare elements
- MethodElement element = findElement("~");
- Element mainElement = findElement('main');
- // verify
- _assertRecordedRelationForElement(element, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, '~a', length: 1));
- }
-
- void test_isInvokedBy_ParameterElement() {
- _indexTestUnit('''
-main(p()) {
- p();
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- Element element = findElement("p");
- // verify
- _assertRecordedRelationForElement(element, IndexConstants.IS_INVOKED_BY,
- _expectedLocation(mainElement, 'p();'));
- }
-
- void test_isMixedInBy_ClassDeclaration() {
- _indexTestUnit('''
-class A {} // 1
-class B extends Object with A {} // 2
-''');
- // prepare elements
- ClassElement classElementA = findElement("A");
- ClassElement classElementB = findElement("B");
- // verify
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.IS_MIXED_IN_BY,
- _expectedLocation(classElementB, 'A {} // 2'));
- }
-
- void test_isMixedInBy_ClassTypeAlias() {
- _indexTestUnit('''
-class A {} // 1
-class B = Object with A; // 2
-''');
- // prepare elements
- ClassElement classElementA = findElement("A");
- ClassElement classElementB = findElement("B");
- // verify
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.IS_MIXED_IN_BY,
- _expectedLocation(classElementB, 'A; // 2'));
- }
-
- void test_isReadBy_ParameterElement() {
- _indexTestUnit('''
-main(var p) {
- print(p);
-}
-''');
- // prepare elements
- Element mainElement = findElement("main");
- Element parameterElement = findElement("p");
- // verify
- _assertRecordedRelationForElement(parameterElement,
- IndexConstants.IS_READ_BY, _expectedLocation(mainElement, 'p);'));
- }
-
- void test_isReadBy_VariableElement() {
- _indexTestUnit('''
-main() {
- var v = 0;
- print(v);
-}
-''');
- // prepare elements
- Element mainElement = findElement("main");
- Element variableElement = findElement("v");
- // verify
- _assertRecordedRelationForElement(variableElement,
- IndexConstants.IS_READ_BY, _expectedLocation(mainElement, 'v);'));
- }
-
- void test_isReadWrittenBy_ParameterElement() {
- _indexTestUnit('''
-main(int p) {
- p += 1;
-}
-''');
- // prepare elements
- Element mainElement = findElement("main");
- Element parameterElement = findElement("p");
- // verify
- _assertRecordedRelationForElement(
- parameterElement,
- IndexConstants.IS_READ_WRITTEN_BY,
- _expectedLocation(mainElement, 'p += 1'));
- }
-
- void test_isReadWrittenBy_VariableElement() {
- _indexTestUnit('''
-main() {
- var v = 0;
- v += 1;
-}
-''');
- // prepare elements
- Element mainElement = findElement("main");
- Element variableElement = findElement("v");
- // verify
- _assertRecordedRelationForElement(
- variableElement,
- IndexConstants.IS_READ_WRITTEN_BY,
- _expectedLocation(mainElement, 'v += 1'));
- }
-
- void test_isReferencedBy_ClassElement() {
- _indexTestUnit('''
-class A {
- static var field;
-}
-main(A p) {
- A v;
- new A(); // 2
- A.field = 1;
- print(A.field); // 3
-}
-''');
- // prepare elements
- ClassElement aElement = findElement("A");
- Element mainElement = findElement("main");
- ParameterElement pElement = findElement("p");
- VariableElement vElement = findElement("v");
- IndexableElement indexable = new IndexableElement(aElement);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(pElement, 'A p) {'));
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(vElement, 'A v;'));
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'A(); // 2'));
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'A.field = 1;'));
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'A.field); // 3'));
- }
-
- void test_isReferencedBy_ClassElement_invocation() {
- verifyNoTestUnitErrors = false;
- _indexTestUnit('''
-class A {}
-main() {
- A(); // invalid code, but still a reference
-}''');
- // prepare elements
- Element mainElement = findElement('main');
- Element classElement = findElement('A');
- IndexableElement indexable = new IndexableElement(classElement);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'A();'));
- }
-
- void test_isReferencedBy_ClassTypeAlias() {
- _indexTestUnit('''
-class A {}
-class B = Object with A;
-main(B p) {
- B v;
-}
-''');
- // prepare elements
- ClassElement bElement = findElement("B");
- ParameterElement pElement = findElement("p");
- VariableElement vElement = findElement("v");
- IndexableElement indexable = new IndexableElement(bElement);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(pElement, 'B p) {'));
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(vElement, 'B v;'));
- }
-
- void test_isReferencedBy_CompilationUnitElement_export() {
- addSource(
- '/lib.dart',
- '''
-library lib;
-''');
- _indexTestUnit('''
-export 'lib.dart';
-''');
- // prepare elements
- LibraryElement libElement = testLibraryElement.exportedLibraries[0];
- CompilationUnitElement libUnitElement = libElement.definingCompilationUnit;
- // verify
- _assertRecordedRelationForElement(
- libUnitElement,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(testUnitElement, "'lib.dart'", length: 10));
- }
-
- void test_isReferencedBy_CompilationUnitElement_import() {
- addSource(
- '/lib.dart',
- '''
-library lib;
-''');
- _indexTestUnit('''
-import 'lib.dart';
-''');
- // prepare elements
- LibraryElement libElement = testLibraryElement.imports[0].importedLibrary;
- CompilationUnitElement libUnitElement = libElement.definingCompilationUnit;
- // verify
- _assertRecordedRelationForElement(
- libUnitElement,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(testUnitElement, "'lib.dart'", length: 10));
- }
-
- void test_isReferencedBy_CompilationUnitElement_part() {
- addSource('/my_unit.dart', 'part of my_lib;');
- _indexTestUnit('''
-library my_lib;
-part 'my_unit.dart';
-''');
- // prepare elements
- CompilationUnitElement myUnitElement = testLibraryElement.parts[0];
- // verify
- _assertRecordedRelationForElement(
- myUnitElement,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(testUnitElement, "'my_unit.dart';", length: 14));
- }
-
- void test_isReferencedBy_ConstructorElement() {
- _indexTestUnit('''
-class A implements B {
- A() {}
- A.foo() {}
-}
-class B extends A {
- B() : super(); // marker-1
- B.foo() : super.foo(); // marker-2
- factory B.bar() = A.foo; // marker-3
-}
-main() {
- new A(); // marker-main-1
- new A.foo(); // marker-main-2
-}
-''');
- // prepare elements
- Element mainElement = findElement('main');
- var isConstructor = (node) => node is ConstructorDeclaration;
- ConstructorElement consA = findNodeElementAtString("A()", isConstructor);
- ConstructorElement consA_foo =
- findNodeElementAtString("A.foo()", isConstructor);
- ConstructorElement consB = findNodeElementAtString("B()", isConstructor);
- ConstructorElement consB_foo =
- findNodeElementAtString("B.foo()", isConstructor);
- ConstructorElement consB_bar =
- findNodeElementAtString("B.bar()", isConstructor);
- IndexableElement indexableA = new IndexableElement(consA);
- IndexableElement indexableA_foo = new IndexableElement(consA_foo);
- // A()
- _assertRecordedRelation(indexableA, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(consB, '(); // marker-1', length: 0));
- _assertRecordedRelation(indexableA, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, '(); // marker-main-1', length: 0));
- // A.foo()
- _assertRecordedRelation(indexableA_foo, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(consB_foo, '.foo(); // marker-2', length: 4));
- _assertRecordedRelation(indexableA_foo, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(consB_bar, '.foo; // marker-3', length: 4));
- _assertRecordedRelation(indexableA_foo, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, '.foo(); // marker-main-2', length: 4));
- }
-
- void test_isReferencedBy_ConstructorElement_classTypeAlias() {
- _indexTestUnit('''
-class M {}
-class A implements B {
- A() {}
- A.named() {}
-}
-class B = A with M;
-main() {
- new B(); // marker-main-1
- new B.named(); // marker-main-2
-}
-''');
- // prepare elements
- Element mainElement = findElement('main');
- var isConstructor = (node) => node is ConstructorDeclaration;
- ConstructorElement consA = findNodeElementAtString("A()", isConstructor);
- ConstructorElement consA_named =
- findNodeElementAtString("A.named()", isConstructor);
- // verify
- _assertRecordedRelationForElement(consA, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, '(); // marker-main-1', length: 0));
- _assertRecordedRelationForElement(
- consA_named,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, '.named(); // marker-main-2',
- length: 6));
- }
-
- void test_isReferencedBy_ConstructorElement_redirection() {
- _indexTestUnit('''
-class A {
- A() : this.bar();
- A.foo() : this(); // marker
- A.bar();
-}
-''');
- // prepare elements
- var isConstructor = (node) => node is ConstructorDeclaration;
- ConstructorElement constructorA =
- findNodeElementAtString("A()", isConstructor);
- ConstructorElement constructorA_foo =
- findNodeElementAtString("A.foo()", isConstructor);
- ConstructorElement constructorA_bar =
- findNodeElementAtString("A.bar()", isConstructor);
- // A()
- _assertRecordedRelationForElement(
- constructorA,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(constructorA_foo, '(); // marker', length: 0));
- // A.foo()
- _assertRecordedRelationForElement(
- constructorA_bar,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(constructorA, '.bar();', length: 4));
- }
-
- void test_isReferencedBy_FieldElement() {
- _indexTestUnit('''
-class A {
- var field;
- A({this.field});
- m() {
- field = 1; // nq
- print(field); // nq
- }
-}
-main(A a) {
- a.field = 2; // q
- print(a.field); // q
- new A(field: 3);
-}
-''');
- // prepare elements
- Element mElement = findElement("m");
- Element mainElement = findElement("main");
- FieldElement fieldElement = findElement("field");
- PropertyAccessorElement getter = fieldElement.getter;
- PropertyAccessorElement setter = fieldElement.setter;
- IndexableElement indexableGetter = new IndexableElement(getter);
- IndexableElement indexableSetter = new IndexableElement(setter);
- // m()
- _assertRecordedRelation(indexableSetter, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mElement, 'field = 1; // nq'));
- _assertRecordedRelation(indexableGetter, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mElement, 'field); // nq'));
- // main()
- _assertRecordedRelation(indexableSetter, IndexConstants.IS_REFERENCED_BY,
- _expectedLocationQ(mainElement, 'field = 2; // q'));
- _assertRecordedRelation(indexableGetter, IndexConstants.IS_REFERENCED_BY,
- _expectedLocationQ(mainElement, 'field); // q'));
- _assertRecordedRelationForElement(
- fieldElement,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'field: 3'));
- }
-
- void test_isReferencedBy_fileOfLibrary_byImportingExportingFile() {
- addSource('/lib.dart', '');
- _indexTestUnit('''
-import 'lib.dart'; // 1
-export 'lib.dart'; // 2
-''');
- // verify
- IndexableFile libIndexableFile = new IndexableFile('/lib.dart');
- IndexableFile testIndexableFile = new IndexableFile(testFile);
- _assertRecordedRelationForIndexable(
- libIndexableFile,
- IndexConstants.IS_REFERENCED_BY,
- new ExpectedLocation(
- testIndexableFile,
- testCode.indexOf("'lib.dart'; // 1"),
- "'lib.dart'".length,
- false,
- true));
- _assertRecordedRelationForIndexable(
- libIndexableFile,
- IndexConstants.IS_REFERENCED_BY,
- new ExpectedLocation(
- testIndexableFile,
- testCode.indexOf("'lib.dart'; // 2"),
- "'lib.dart'".length,
- false,
- true));
- }
-
- void test_isReferencedBy_fileOfPart_bySourcingFile() {
- addSource('/part.dart', 'part of my.lib;');
- _indexTestUnit('''
-library my.lib;
-part 'part.dart';
-''');
- // verify
- IndexableFile partIndexableFile = new IndexableFile('/part.dart');
- IndexableFile testIndexableFile = new IndexableFile(testFile);
- _assertRecordedRelationForIndexable(
- partIndexableFile,
- IndexConstants.IS_REFERENCED_BY,
- new ExpectedLocation(testIndexableFile, testCode.indexOf("'part.dart'"),
- "'part.dart'".length, false, true));
- }
-
- void test_isReferencedBy_FunctionElement() {
- _indexTestUnit('''
-foo() {}
-main() {
- print(foo);
- print(foo());
-}
-''');
- // prepare elements
- FunctionElement element = findElement("foo");
- Element mainElement = findElement("main");
- IndexableElement indexable = new IndexableElement(element);
- // "referenced" here
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'foo);'));
- // only "invoked", but not "referenced"
- {
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocation(mainElement, 'foo());'));
- _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'foo());'));
- }
- }
-
- void test_isReferencedBy_FunctionTypeAliasElement() {
- _indexTestUnit('''
-typedef A();
-main(A p) {
-}
-''');
- // prepare elements
- Element aElement = findElement('A');
- Element pElement = findElement('p');
- // verify
- _assertRecordedRelationForElement(aElement, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(pElement, 'A p) {'));
- }
-
- /**
- * There was a bug in the AST structure, when single [Comment] was cloned and
- * assigned to both [FieldDeclaration] and [VariableDeclaration].
- *
- * This caused duplicate indexing.
- * Here we test that the problem is fixed one way or another.
- */
- void test_isReferencedBy_identifierInComment() {
- _indexTestUnit('''
-class A {}
-/// [A] text
-var myVariable = null;
-''');
- // prepare elements
- Element aElement = findElement('A');
- Element variableElement = findElement('myVariable');
- IndexableElement indexable = new IndexableElement(aElement);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(testUnitElement, 'A] text'));
- _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(variableElement, 'A] text'));
- }
-
- void test_isReferencedBy_ImportElement_noPrefix() {
- addSource(
- '/lib.dart',
- '''
-library lib;
-var myVar;
-myFunction() {}
-myToHide() {}
-''');
- _indexTestUnit('''
-import 'lib.dart' show myVar, myFunction hide myToHide;
-main() {
- myVar = 1;
- myFunction();
- print(0);
-}
-''');
- // prepare elements
- ImportElement importElement = testLibraryElement.imports[0];
- Element mainElement = findElement('main');
- IndexableElement indexable = new IndexableElement(importElement);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'myVar = 1;', length: 0));
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'myFunction();', length: 0));
- _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'print(0);', length: 0));
- // no references from import combinators
- _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(testUnitElement, 'myVar, ', length: 0));
- _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(testUnitElement, 'myFunction hide', length: 0));
- _assertNoRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(testUnitElement, 'myToHide;', length: 0));
- }
-
- void test_isReferencedBy_ImportElement_withPrefix() {
- addSource(
- '/libA.dart',
- '''
-library libA;
-var myVar;
-''');
- addSource(
- '/libB.dart',
- '''
-library libB;
-class MyClass {}
-''');
- _indexTestUnit('''
-import 'libA.dart' as pref;
-import 'libB.dart' as pref;
-main() {
- pref.myVar = 1;
- new pref.MyClass();
-}
-''');
- // prepare elements
- ImportElement importElementA = testLibraryElement.imports[0];
- ImportElement importElementB = testLibraryElement.imports[1];
- Element mainElement = findElement('main');
- // verify
- _assertRecordedRelationForElement(
- importElementA,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'pref.myVar = 1;', length: 5));
- _assertRecordedRelationForElement(
- importElementB,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'pref.MyClass();', length: 5));
- }
-
- void test_isReferencedBy_ImportElement_withPrefix_combinators() {
- addSource(
- '/lib.dart',
- '''
-library lib;
-class A {}
-class B {}
-''');
- _indexTestUnit('''
-import 'lib.dart' as pref show A;
-import 'lib.dart' as pref show B;
-import 'lib.dart';
-import 'lib.dart' as otherPrefix;
-main() {
- new pref.A();
- new pref.B();
-}
-''');
- // prepare elements
- ImportElement importElementA = testLibraryElement.imports[0];
- ImportElement importElementB = testLibraryElement.imports[1];
- Element mainElement = findElement('main');
- // verify
- _assertRecordedRelationForElement(
- importElementA,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'pref.A();', length: 5));
- _assertRecordedRelationForElement(
- importElementB,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'pref.B();', length: 5));
- }
-
- void test_isReferencedBy_ImportElement_withPrefix_invocation() {
- addSource(
- '/lib.dart',
- '''
-library lib;
-myFunc() {}
-''');
- _indexTestUnit('''
-import 'lib.dart' as pref;
-main() {
- pref.myFunc();
-}
-''');
- // prepare elements
- ImportElement importElement = testLibraryElement.imports[0];
- Element mainElement = findElement('main');
- // verify
- _assertRecordedRelationForElement(
- importElement,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'pref.myFunc();', length: 5));
- }
-
- void test_isReferencedBy_ImportElement_withPrefix_oneCandidate() {
- addSource(
- '/lib.dart',
- '''
-library lib;
-class A {}
-class B {}
-''');
- _indexTestUnit('''
-import 'lib.dart' as pref show A;
-main() {
- new pref.A();
-}
-''');
- // prepare elements
- ImportElement importElement = testLibraryElement.imports[0];
- Element mainElement = findElement('main');
- // verify
- _assertRecordedRelationForElement(
- importElement,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'pref.A();', length: 5));
- }
-
- void test_isReferencedBy_ImportElement_withPrefix_unresolvedElement() {
- verifyNoTestUnitErrors = false;
- addSource(
- '/lib.dart',
- '''
-library lib;
-''');
- _indexTestUnit('''
-import 'lib.dart' as pref;
-main() {
- pref.myVar = 1;
-}
-''');
- }
-
- void test_isReferencedBy_ImportElement_withPrefix_wrongInvocation() {
- verifyNoTestUnitErrors = false;
- _indexTestUnit('''
-import 'dart:math' as m;
-main() {
- m();
-}''');
- }
-
- void test_isReferencedBy_ImportElement_withPrefix_wrongPrefixedIdentifier() {
- verifyNoTestUnitErrors = false;
- _indexTestUnit('''
-import 'dart:math' as m;
-main() {
- x.m;
-}
-''');
- }
-
- void test_isReferencedBy_LabelElement() {
- _indexTestUnit('''
-main() {
- L: while (true) {
- break L;
- }
-}
-''');
- // prepare elements
- Element mainElement = findElement('main');
- Element element = findElement('L');
- // verify
- _assertRecordedRelationForElement(element, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'L;'));
- }
-
- void test_isReferencedBy_libraryName_byPartOf() {
- Source libSource = addSource(
- '/lib.dart',
- '''
-library lib;
-part 'test.dart';
-''');
- testCode = 'part of lib;';
- testSource = addSource('/test.dart', testCode);
- testUnit = resolveDartUnit(testSource, libSource);
- testUnitElement = testUnit.element;
- testLibraryElement = testUnitElement.library;
- indexDartUnit(store, context, testUnit);
- // verify
- _assertRecordedRelationForElement(
- testLibraryElement,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(testUnitElement, "lib;"));
- }
-
- void test_isReferencedBy_MethodElement() {
- _indexTestUnit('''
-class A {
- method() {}
- main() {
- print(this.method); // q
- print(method); // nq
- }
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- MethodElement methodElement = findElement("method");
- IndexableElement indexable = new IndexableElement(methodElement);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocationQ(mainElement, 'method); // q'));
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'method); // nq'));
- }
-
- void test_isReferencedBy_ParameterElement() {
- _indexTestUnit('''
-foo({var p}) {}
-main() {
- foo(p: 1);
-}
-''');
- // prepare elements
- Element mainElement = findElement('main');
- Element element = findElement('p');
- // verify
- _assertRecordedRelationForElement(element, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'p: 1'));
- }
-
- void test_isReferencedBy_PrefixElement() {
- _indexTestUnit('''
-import 'dart:async' as ppp;
-main() {
- ppp.Future a;
- ppp.Stream b;
-}
-''');
- // prepare elements
- PrefixElement element = findNodeElementAtString('ppp;');
- Element elementA = findElement('a');
- Element elementB = findElement('b');
- IndexableElement indexable = new IndexableElement(element);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(elementA, 'ppp.Future'));
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(elementB, 'ppp.Stream'));
- _assertNoRecordedRelation(indexable, null, _expectedLocation(null, 'ppp;'));
- }
-
- void test_isReferencedBy_TopLevelVariableElement() {
- addSource(
- '/lib.dart',
- '''
-library lib;
-var V;
-''');
- _indexTestUnit('''
-import 'lib.dart' show V; // imp
-import 'lib.dart' as pref;
-main() {
- pref.V = 5; // q
- print(pref.V); // q
- V = 5; // nq
- print(V); // nq
-}''');
- // prepare elements
- TopLevelVariableElement variable = importedUnit().topLevelVariables[0];
- Element mainElement = findElement("main");
- IndexableElement indexableGetter = new IndexableElement(variable.getter);
- IndexableElement indexableSetter = new IndexableElement(variable.setter);
- // verify
- _assertRecordedRelationForElement(variable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(testUnitElement, 'V; // imp'));
- _assertRecordedRelation(indexableSetter, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'V = 5; // q'));
- _assertRecordedRelation(indexableGetter, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'V); // q'));
- _assertRecordedRelation(indexableSetter, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'V = 5; // nq'));
- _assertRecordedRelation(indexableGetter, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(mainElement, 'V); // nq'));
- }
-
- void test_isReferencedBy_typeInVariableList() {
- _indexTestUnit('''
-class A {}
-A myVariable = null;
-''');
- // prepare elements
- Element classElementA = findElement('A');
- Element variableElement = findElement('myVariable');
- // verify
- _assertRecordedRelationForElement(
- classElementA,
- IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(variableElement, 'A myVariable'));
- }
-
- void test_isReferencedBy_TypeParameterElement() {
- _indexTestUnit('''
-class A<T> {
- T f;
- foo(T p) {
- T v;
- }
-}
-''');
- // prepare elements
- Element typeParameterElement = findElement('T');
- Element fieldElement = findElement('f');
- Element parameterElement = findElement('p');
- Element variableElement = findElement('v');
- IndexableElement indexable = new IndexableElement(typeParameterElement);
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(fieldElement, 'T f'));
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(parameterElement, 'T p'));
- _assertRecordedRelation(indexable, IndexConstants.IS_REFERENCED_BY,
- _expectedLocation(variableElement, 'T v'));
- }
-
- void test_isWrittenBy_ConstructorFieldInitializer() {
- _indexTestUnit('''
-class A {
- int field;
- A() : field = 5;
-}
-''');
- // prepare elements
- ClassElement classElement = findElement('A');
- ConstructorElement constructorElement = classElement.constructors[0];
- FieldElement fieldElement = findElement("field");
- // verify
- _assertRecordedRelationForElement(
- fieldElement,
- IndexConstants.IS_WRITTEN_BY,
- _expectedLocation(constructorElement, 'field = 5'));
- }
-
- void test_isWrittenBy_FieldElement_fieldFormalParameter() {
- _indexTestUnit('''
-class A {
- int field;
- A(this.field);
-}
-''');
- // prepare elements
- FieldElement fieldElement = findElement("field");
- Element fieldParameterElement = findNodeElementAtString("field);");
- // verify
- _assertRecordedRelationForElement(
- fieldElement,
- IndexConstants.IS_WRITTEN_BY,
- _expectedLocation(fieldParameterElement, 'field);'));
- }
-
- void test_isWrittenBy_ParameterElement() {
- _indexTestUnit('''
-main(var p) {
- p = 1;
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- ParameterElement pElement = findElement("p");
- // verify
- _assertRecordedRelationForElement(pElement, IndexConstants.IS_WRITTEN_BY,
- _expectedLocation(mainElement, 'p = 1'));
- }
-
- void test_isWrittenBy_VariableElement() {
- _indexTestUnit('''
-main() {
- var v = 0;
- v = 1;
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- LocalVariableElement vElement = findElement("v");
- // verify
- _assertRecordedRelationForElement(vElement, IndexConstants.IS_WRITTEN_BY,
- _expectedLocation(mainElement, 'v = 1'));
- }
-
- void test_nameIsInvokedBy() {
- _indexTestUnit('''
-class A {
- test(x) {}
-}
-main(A a, p) {
- a.test(1);
- p.test(2);
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- IndexableName indexable = new IndexableName('test');
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQ(mainElement, 'test(1)'));
- _assertRecordedRelation(indexable, IndexConstants.IS_INVOKED_BY,
- _expectedLocationQU(mainElement, 'test(2)'));
- _assertNoRecordedRelation(indexable, IndexConstants.IS_READ_BY,
- _expectedLocationQU(mainElement, 'test(2)'));
- }
-
- void test_nameIsReadBy() {
- _indexTestUnit('''
-class A {
- var test;
-}
-main(A a, p) {
- print(a.test); // a
- print(p.test); // p
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- IndexableName indexable = new IndexableName('test');
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_READ_BY,
- _expectedLocationQ(mainElement, 'test); // a'));
- _assertRecordedRelation(indexable, IndexConstants.IS_READ_BY,
- _expectedLocationQU(mainElement, 'test); // p'));
- }
-
- void test_nameIsReadWrittenBy() {
- _indexTestUnit('''
-class A {
- var test;
-}
-main(A a, p) {
- a.test += 1;
- p.test += 2;
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- IndexableName indexable = new IndexableName('test');
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_READ_WRITTEN_BY,
- _expectedLocationQ(mainElement, 'test += 1'));
- _assertRecordedRelation(indexable, IndexConstants.IS_READ_WRITTEN_BY,
- _expectedLocationQU(mainElement, 'test += 2'));
- }
-
- void test_nameIsWrittenBy() {
- _indexTestUnit('''
-class A {
- var test;
-}
-main(A a, p) {
- a.test = 1;
- p.test = 2;
-}''');
- // prepare elements
- Element mainElement = findElement("main");
- IndexableName indexable = new IndexableName('test');
- // verify
- _assertRecordedRelation(indexable, IndexConstants.IS_WRITTEN_BY,
- _expectedLocationQ(mainElement, 'test = 1'));
- _assertRecordedRelation(indexable, IndexConstants.IS_WRITTEN_BY,
- _expectedLocationQU(mainElement, 'test = 2'));
- }
-
- void test_nullUnit() {
- indexDartUnit(store, context, null);
- }
-
- void test_nullUnitElement() {
- CompilationUnit unit = new CompilationUnit(null, null, [], [], null);
- indexDartUnit(store, context, unit);
- }
-
- void _assertDefinesTopLevelElement(Element element) {
- ExpectedLocation location = new ExpectedLocation(
- new IndexableElement(element),
- element.nameOffset,
- element.nameLength,
- false,
- true);
- _assertRecordedRelationForElement(
- testLibraryElement, IndexConstants.DEFINES, location);
- expect(recordedTopElements, contains(element));
- }
-
- /**
- * Asserts that [recordedRelations] has no item with the specified properties.
- */
- void _assertNoRecordedRelation(IndexableObject expectedIndexable,
- RelationshipImpl relationship, ExpectedLocation location) {
- for (RecordedRelation recordedRelation in recordedRelations) {
- if (_equalsRecordedRelation(
- recordedRelation, expectedIndexable, relationship, location)) {
- fail('not expected: $recordedRelation in\n' +
- recordedRelations.join('\n'));
- }
- }
- }
-
- /**
- * Asserts that [recordedRelations] has no item with the specified properties.
- */
- void _assertNoRecordedRelationForElement(Element expectedElement,
- RelationshipImpl relationship, ExpectedLocation location) {
- _assertNoRecordedRelation(
- new IndexableElement(expectedElement), relationship, location);
- }
-
- /**
- * Asserts that [recordedRelations] has an item with the expected properties.
- */
- LocationImpl _assertRecordedRelation(
- IndexableObject expectedIndexable,
- RelationshipImpl expectedRelationship,
- ExpectedLocation expectedLocation) {
- for (RecordedRelation recordedRelation in recordedRelations) {
- if (_equalsRecordedRelation(recordedRelation, expectedIndexable,
- expectedRelationship, expectedLocation)) {
- return recordedRelation.location;
- }
- }
- fail("not found\n$expectedIndexable $expectedRelationship "
- "in $expectedLocation in\n" +
- recordedRelations.join('\n'));
- return null;
- }
-
- /**
- * Asserts that [recordedRelations] has an item with the expected properties.
- */
- LocationImpl _assertRecordedRelationForElement(
- Element expectedElement,
- RelationshipImpl expectedRelationship,
- ExpectedLocation expectedLocation) {
- return _assertRecordedRelationForIndexable(
- new IndexableElement(expectedElement),
- expectedRelationship,
- expectedLocation);
- }
-
- /**
- * Asserts that [recordedRelations] has an item with the expected properties.
- */
- LocationImpl _assertRecordedRelationForIndexable(
- IndexableObject expectedIndexable,
- RelationshipImpl expectedRelationship,
- ExpectedLocation expectedLocation) {
- return _assertRecordedRelation(
- expectedIndexable, expectedRelationship, expectedLocation);
- }
-
- /**
- * Asserts that [recordedRelations] has an item with the expected properties.
- */
- LocationImpl _assertRecordedRelationForName(
- String expectedName,
- RelationshipImpl expectedRelationship,
- ExpectedLocation expectedLocation) {
- return _assertRecordedRelationForIndexable(new IndexableName(expectedName),
- expectedRelationship, expectedLocation);
- }
-
- ExpectedLocation _expectedLocation(Element element, String search,
- {int length: -1, bool isQualified: false, bool isResolved: true}) {
- int offset = findOffset(search);
- if (length == -1) {
- length = getLeadingIdentifierLength(search);
- }
- IndexableObject indexable =
- element != null ? new IndexableElement(element) : null;
- return new ExpectedLocation(
- indexable, offset, length, isQualified, isResolved);
- }
-
- ExpectedLocation _expectedLocationQ(Element element, String search,
- {int length: -1}) {
- return _expectedLocation(element, search,
- length: length, isQualified: true);
- }
-
- ExpectedLocation _expectedLocationQU(Element element, String search,
- {int length: -1}) {
- return _expectedLocation(element, search,
- length: length, isQualified: true, isResolved: false);
- }
-
- void _indexTestUnit(String code) {
- resolveTestUnit(code);
- indexDartUnit(store, context, testUnit);
- }
-}
-
-class ExpectedLocation {
- IndexableObject indexable;
- int offset;
- int length;
- bool isQualified;
- bool isResolved;
-
- ExpectedLocation(this.indexable, this.offset, this.length, this.isQualified,
- this.isResolved);
-
- @override
- String toString() {
- return 'ExpectedLocation(indexable=$indexable; offset=$offset; length=$length;'
- ' isQualified=$isQualified isResolved=$isResolved)';
- }
-}
-
-class MockIndexStore extends TypedMock implements InternalIndexStore {}
-
-/**
- * Information about a relation recorded into {@link IndexStore}.
- */
-class RecordedRelation {
- final IndexableObject indexable;
- final RelationshipImpl relationship;
- final LocationImpl location;
-
- RecordedRelation(this.indexable, this.relationship, this.location);
-
- @override
- String toString() {
- return 'RecordedRelation(indexable=$indexable; relationship=$relationship; '
- 'location=$location; flags='
- '${location.isQualified ? "Q" : ""}'
- '${location.isResolved ? "R" : ""})';
- }
-}
diff --git a/pkg/analysis_server/test/services/index/index_test.dart b/pkg/analysis_server/test/services/index/index_test.dart
new file mode 100644
index 0000000..406479e
--- /dev/null
+++ b/pkg/analysis_server/test/services/index/index_test.dart
@@ -0,0 +1,312 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/index/index.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../abstract_single_unit.dart';
+import '../../utils.dart';
+
+main() {
+ initializeTestEnvironment();
+ defineReflectiveTests(IndexTest);
+}
+
+@reflectiveTest
+class IndexTest extends AbstractSingleUnitTest {
+ Index index = createMemoryIndex();
+
+ /**
+ * Return the [Location] with given properties, or fail.
+ */
+ Location findLocation(List<Location> locations, String libraryUri,
+ String unitUri, int offset, int length, bool isQualified) {
+ for (Location location in locations) {
+ if (location.libraryUri == libraryUri &&
+ location.unitUri == unitUri &&
+ location.offset == offset &&
+ location.length == length &&
+ location.isQualified == isQualified) {
+ return location;
+ }
+ }
+ fail('No at $offset with length $length qualified=$isQualified in\n'
+ '${locations.join('\n')}');
+ return null;
+ }
+
+ /**
+ * Return the [Location] with given properties, or fail.
+ */
+ Location findLocationSource(
+ List<Location> locations, Source source, String search, bool isQualified,
+ {int length}) {
+ String code = source.contents.data;
+ int offset = code.indexOf(search);
+ expect(offset, isNonNegative, reason: 'Not found "$search" in\n$code');
+ length ??= getLeadingIdentifierLength(search);
+ String uri = source.uri.toString();
+ return findLocation(locations, uri, uri, offset, length, isQualified);
+ }
+
+ /**
+ * Return the [Location] with given properties, or fail.
+ */
+ Location findLocationTest(
+ List<Location> locations, String search, bool isQualified,
+ {int length}) {
+ int offset = findOffset(search);
+ length ??= getLeadingIdentifierLength(search);
+ String testUri = testSource.uri.toString();
+ return findLocation(
+ locations, testUri, testUri, offset, length, isQualified);
+ }
+
+ void setUp() {
+ super.setUp();
+ }
+
+ void tearDown() {
+ super.tearDown();
+ index = null;
+ }
+
+ test_getDefinedNames_classMember() async {
+ _indexTestUnit('''
+class A {
+ test() {}
+}
+class B {
+ int test = 1;
+ main() {
+ int test = 2;
+ }
+}
+''');
+ ClassElement classA = findElement('A');
+ ClassElement classB = findElement('B');
+ List<Location> locations = await index.getDefinedNames(
+ new RegExp(r'^test$'), IndexNameKind.classMember);
+ expect(locations, hasLength(2));
+ _assertHasDefinedName(locations, classA.methods[0]);
+ _assertHasDefinedName(locations, classB.fields[0]);
+ }
+
+ test_getDefinedNames_topLevel() async {
+ _indexTestUnit('''
+class A {} // A
+class B = Object with A;
+typedef C();
+D() {}
+var E = null;
+class NoMatchABCDE {}
+''');
+ Element topA = findElement('A');
+ Element topB = findElement('B');
+ Element topC = findElement('C');
+ Element topD = findElement('D');
+ Element topE = findElement('E');
+ List<Location> locations = await index.getDefinedNames(
+ new RegExp(r'^[A-E]$'), IndexNameKind.topLevel);
+ expect(locations, hasLength(5));
+ _assertHasDefinedName(locations, topA);
+ _assertHasDefinedName(locations, topB);
+ _assertHasDefinedName(locations, topC);
+ _assertHasDefinedName(locations, topD);
+ _assertHasDefinedName(locations, topE);
+ }
+
+ test_getRelations_isExtendedBy() async {
+ _indexTestUnit(r'''
+class A {}
+class B extends A {} // B
+''');
+ Source source2 = _indexUnit(
+ '/test2.dart',
+ r'''
+import 'test.dart';
+class C extends A {} // C
+''');
+ ClassElement elementA = testUnitElement.getType('A');
+ List<Location> locations =
+ await index.getRelations(elementA, IndexRelationKind.IS_EXTENDED_BY);
+ findLocationTest(locations, 'A {} // B', false);
+ findLocationSource(locations, source2, 'A {} // C', false);
+ }
+
+ test_getRelations_isReferencedBy() async {
+ _indexTestUnit(r'''
+main(int a, int b) {
+}
+''');
+ ClassElement intElement = context.typeProvider.intType.element;
+ List<Location> locations = await index.getRelations(
+ intElement, IndexRelationKind.IS_REFERENCED_BY);
+ findLocationTest(locations, 'int a', false);
+ findLocationTest(locations, 'int b', false);
+ }
+
+ test_getUnresolvedMemberReferences_qualified_resolved() async {
+ _indexTestUnit('''
+class A {
+ var test; // A
+}
+main(A a) {
+ print(a.test);
+ a.test = 1;
+ a.test += 2;
+ a.test();
+}
+''');
+ List<Location> locations =
+ await index.getUnresolvedMemberReferences('test');
+ expect(locations, isEmpty);
+ }
+
+ test_getUnresolvedMemberReferences_qualified_unresolved() async {
+ _indexTestUnit('''
+class A {
+ var test; // A
+}
+main(p) {
+ print(p.test);
+ p.test = 1;
+ p.test += 2;
+ p.test();
+ print(p.test2); // not requested
+}
+''');
+ List<Location> locations =
+ await index.getUnresolvedMemberReferences('test');
+ expect(locations, hasLength(4));
+ findLocationTest(locations, 'test);', true);
+ findLocationTest(locations, 'test = 1;', true);
+ findLocationTest(locations, 'test += 2;', true);
+ findLocationTest(locations, 'test();', true);
+ }
+
+ test_getUnresolvedMemberReferences_unqualified_resolved() async {
+ _indexTestUnit('''
+class A {
+ var test;
+ m() {
+ print(test);
+ test = 1;
+ test += 2;
+ test();
+ }
+}
+''');
+ List<Location> locations =
+ await index.getUnresolvedMemberReferences('test');
+ expect(locations, isEmpty);
+ }
+
+ test_getUnresolvedMemberReferences_unqualified_unresolved() async {
+ verifyNoTestUnitErrors = false;
+ _indexTestUnit('''
+class A {
+ m() {
+ print(test);
+ test = 1;
+ test += 2;
+ test();
+ print(test2); // not requested
+ }
+}
+''');
+ List<Location> locations =
+ await index.getUnresolvedMemberReferences('test');
+ expect(locations, hasLength(4));
+ findLocationTest(locations, 'test);', false);
+ findLocationTest(locations, 'test = 1;', false);
+ findLocationTest(locations, 'test += 2;', false);
+ findLocationTest(locations, 'test();', false);
+ }
+
+ test_indexUnit_nullUnit() async {
+ index.indexUnit(null);
+ }
+
+ test_indexUnit_nullUnitElement() async {
+ resolveTestUnit('');
+ testUnit.element = null;
+ index.indexUnit(testUnit);
+ }
+
+ test_removeContext() async {
+ _indexTestUnit('''
+class A {}
+''');
+ RegExp regExp = new RegExp(r'^A$');
+ expect(await index.getDefinedNames(regExp, IndexNameKind.topLevel),
+ hasLength(1));
+ // remove the context - no top-level declarations
+ index.removeContext(context);
+ expect(
+ await index.getDefinedNames(regExp, IndexNameKind.topLevel), isEmpty);
+ }
+
+ test_removeUnit() async {
+ RegExp regExp = new RegExp(r'^[AB]$');
+ Source sourceA = addSource('/a.dart', 'class A {}');
+ Source sourceB = addSource('/b.dart', 'class B {}');
+ CompilationUnit unitA = resolveLibraryUnit(sourceA);
+ CompilationUnit unitB = resolveLibraryUnit(sourceB);
+ index.indexUnit(unitA);
+ index.indexUnit(unitB);
+ {
+ List<Location> locations =
+ await index.getDefinedNames(regExp, IndexNameKind.topLevel);
+ expect(locations, hasLength(2));
+ expect(locations.map((l) => l.libraryUri),
+ unorderedEquals([sourceA.uri.toString(), sourceB.uri.toString()]));
+ }
+ // remove a.dart - no a.dart location
+ index.removeUnit(context, sourceA, sourceA);
+ {
+ List<Location> locations =
+ await index.getDefinedNames(regExp, IndexNameKind.topLevel);
+ expect(locations, hasLength(1));
+ expect(locations.map((l) => l.libraryUri),
+ unorderedEquals([sourceB.uri.toString()]));
+ }
+ }
+
+ /**
+ * Assert that the given list of [locations] has a [Location] corresponding
+ * to the [element].
+ */
+ void _assertHasDefinedName(List<Location> locations, Element element) {
+ String libraryUri = element.library.source.uri.toString();
+ String unitUri = element.source.uri.toString();
+ for (Location location in locations) {
+ if (location.libraryUri == libraryUri &&
+ location.unitUri == unitUri &&
+ location.offset == element.nameOffset &&
+ location.length == element.nameLength) {
+ return;
+ }
+ }
+ fail('No declaration of $element at ${element.nameOffset} in\n'
+ '${locations.join('\n')}');
+ }
+
+ void _indexTestUnit(String code) {
+ resolveTestUnit(code);
+ index.indexUnit(testUnit);
+ }
+
+ Source _indexUnit(String path, String code) {
+ Source source = addSource(path, code);
+ CompilationUnit unit = resolveLibraryUnit(source);
+ index.indexUnit(unit);
+ return source;
+ }
+}
diff --git a/pkg/analysis_server/test/services/index/indexable_file_test.dart b/pkg/analysis_server/test/services/index/indexable_file_test.dart
deleted file mode 100644
index e790b84..0000000
--- a/pkg/analysis_server/test/services/index/indexable_file_test.dart
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.index.indexable_file;
-
-import 'package:analysis_server/src/services/index/indexable_file.dart';
-import 'package:analysis_server/src/services/index/store/codec.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-
-main() {
- initializeTestEnvironment();
- defineReflectiveTests(IndexableFileKindTest);
- defineReflectiveTests(IndexableFileTest);
-}
-
-@reflectiveTest
-class IndexableFileKindTest {
- void test_decode() {
- IndexableFile object =
- IndexableFileKind.INSTANCE.decode(null, '/a.dart', -1);
- expect(object.path, '/a.dart');
- }
-
- void test_encodeHash() {
- StringCodec stringCodec = new StringCodec();
- String path = '/a/bb/ccc.dart';
- int hash1 = IndexableFileKind.INSTANCE
- .encodeHash(stringCodec.encode, new IndexableFile(path));
- int hash2 = IndexableFileKind.INSTANCE
- .encodeHash(stringCodec.encode, new IndexableFile(path));
- expect(hash2, hash1);
- }
-}
-
-@reflectiveTest
-class IndexableFileTest {
- void test_equals() {
- IndexableFile a = new IndexableFile('/a.dart');
- IndexableFile a2 = new IndexableFile('/a.dart');
- IndexableFile b = new IndexableFile('/b.dart');
- expect(a == a, isTrue);
- expect(a == a2, isTrue);
- expect(a == b, isFalse);
- }
-
- void test_getters() {
- String path = '/a/bb/ccc.dart';
- IndexableFile indexable = new IndexableFile(path);
- expect(indexable.kind, IndexableFileKind.INSTANCE);
- expect(indexable.filePath, path);
- expect(indexable.offset, -1);
- expect(indexable.toString(), path);
- }
-}
diff --git a/pkg/analysis_server/test/services/index/local_file_index_test.dart b/pkg/analysis_server/test/services/index/local_file_index_test.dart
deleted file mode 100644
index a92a22f..0000000
--- a/pkg/analysis_server/test/services/index/local_file_index_test.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.src.index.local_file_index;
-
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_file_index.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-
-main() {
- initializeTestEnvironment();
- test('createLocalFileIndex', () {
- Index index = createLocalFileIndex();
- expect(index, isNotNull);
- index.clear();
- });
-}
diff --git a/pkg/analysis_server/test/services/index/local_index_test.dart b/pkg/analysis_server/test/services/index/local_index_test.dart
deleted file mode 100644
index 5f318ad..0000000
--- a/pkg/analysis_server/test/services/index/local_index_test.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.src.index.local_index;
-
-import 'package:analysis_server/src/services/index/index_contributor.dart';
-import 'package:analysis_server/src/services/index/local_index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_context.dart';
-import '../../utils.dart';
-import 'store/single_source_container.dart';
-
-main() {
- initializeTestEnvironment();
- defineReflectiveTests(LocalIndexTest);
-}
-
-void _assertElementNames(List<Element> elements, List expected) {
- expect(_toElementNames(elements), unorderedEquals(expected));
-}
-
-Iterable<String> _toElementNames(List<Element> elements) {
- return elements.map((element) => element.name);
-}
-
-@reflectiveTest
-class LocalIndexTest extends AbstractContextTest {
- LocalIndex index;
-
- void setUp() {
- super.setUp();
- index = createLocalMemoryIndex();
- index.contributors = [new DartIndexContributor()];
- }
-
- void tearDown() {
- super.tearDown();
- index = null;
- }
-
- void test_clear() {
- _indexTest('main() {}');
- _assertElementNames(_getTopElements(), ['main']);
- // clear
- index.clear();
- expect(_getTopElements(), isEmpty);
- }
-
- void test_index() {
- _indexTest('main() {}');
- _assertElementNames(_getTopElements(), ['main']);
- }
-
- void test_index_nullObject() {
- index.index(context, null);
- }
-
- void test_index_nullUnitElement() {
- CompilationUnit unit = new CompilationUnit(null, null, [], [], null);
- index.index(context, unit);
- }
-
- void test_removeContext() {
- _indexTest('main() {}');
- // OK, there is an element
- _assertElementNames(_getTopElements(), ['main']);
- // remove context
- index.removeContext(context);
- expect(_getTopElements(), isEmpty);
- }
-
- void test_removeSource() {
- Source sourceA = _indexLibraryUnit('/testA.dart', 'fa() {}');
- _indexLibraryUnit('/testB.dart', 'fb() {}');
- // OK, there are 2 functions
- _assertElementNames(_getTopElements(), ['fa', 'fb']);
- // remove source
- index.removeSource(context, sourceA);
- _assertElementNames(_getTopElements(), ['fb']);
- }
-
- void test_removeSources() {
- Source sourceA = _indexLibraryUnit('/testA.dart', 'fa() {}');
- _indexLibraryUnit('/testB.dart', 'fb() {}');
- // OK, there are 2 functions
- _assertElementNames(_getTopElements(), ['fa', 'fb']);
- // remove source(s)
- index.removeSources(context, new SingleSourceContainer(sourceA));
- _assertElementNames(_getTopElements(), ['fb']);
- }
-
- void test_statistics() {
- expect(index.statistics, '[0 locations, 0 sources, 0 names]');
- }
-
- List<Element> _getTopElements() {
- return index.getTopLevelDeclarations((_) => true);
- }
-
- Source _indexLibraryUnit(String path, String content) {
- Source source = addSource(path, content);
- CompilationUnit dartUnit = resolveLibraryUnit(source);
- index.index(context, dartUnit);
- return source;
- }
-
- void _indexTest(String content) {
- _indexLibraryUnit('/test.dart', content);
- }
-}
diff --git a/pkg/analysis_server/test/services/index/store/codec_test.dart b/pkg/analysis_server/test/services/index/store/codec_test.dart
deleted file mode 100644
index e7914b8..0000000
--- a/pkg/analysis_server/test/services/index/store/codec_test.dart
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.src.index.store.codec;
-
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/indexable_element.dart';
-import 'package:analysis_server/src/services/index/store/codec.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../../abstract_single_unit.dart';
-import '../../../mocks.dart';
-import '../../../utils.dart';
-
-main() {
- initializeTestEnvironment();
- defineReflectiveTests(_ContextCodecTest);
- defineReflectiveTests(_ElementCodecTest);
- defineReflectiveTests(_RelationshipCodecTest);
- defineReflectiveTests(_StringCodecTest);
-}
-
-@reflectiveTest
-class _ContextCodecTest {
- ContextCodec codec = new ContextCodec();
-
- void test_encode_decode() {
- AnalysisContext contextA = new MockAnalysisContext('contextA');
- AnalysisContext contextB = new MockAnalysisContext('contextB');
- int idA = codec.encode(contextA);
- int idB = codec.encode(contextB);
- expect(idA, codec.encode(contextA));
- expect(idB, codec.encode(contextB));
- expect(codec.decode(idA), contextA);
- expect(codec.decode(idB), contextB);
- }
-
- void test_remove() {
- // encode
- {
- AnalysisContext context = new MockAnalysisContext('context');
- // encode
- int id = codec.encode(context);
- expect(id, 0);
- expect(codec.decode(id), context);
- // remove
- codec.remove(context);
- expect(codec.decode(id), isNull);
- }
- // encode again
- {
- AnalysisContext context = new MockAnalysisContext('context');
- // encode
- int id = codec.encode(context);
- expect(id, 1);
- expect(codec.decode(id), context);
- }
- }
-}
-
-@reflectiveTest
-class _ElementCodecTest extends AbstractSingleUnitTest {
- ElementCodec codec;
- AnalysisContext context = new MockAnalysisContext('context');
- StringCodec stringCodec = new StringCodec();
-
- void setUp() {
- super.setUp();
- codec = new ElementCodec(stringCodec);
- }
-
- void test_encode_CompilationUnitElement() {
- addSource(
- '/my_part.dart',
- '''
-part of my_lib;
-''');
- resolveTestUnit('''
-library my_lib;
-part 'my_part.dart';
-''');
- // defining unit
- {
- Element element = testLibraryElement.definingCompilationUnit;
- expect(element.source.fullName, '/test.dart');
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, -1);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
- // part
- {
- Element element = testLibraryElement.parts[0];
- expect(element.source.fullName, '/my_part.dart');
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, -1);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
- }
-
- void test_encode_ConstructorElement_default_real() {
- resolveTestUnit('''
-class A {
- A();
-}
-''');
- ClassElement classA = findElement('A');
- ConstructorElement element = classA.constructors[0];
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, classA.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
-
- void test_encode_ConstructorElement_default_synthetic() {
- resolveTestUnit('''
-class A {
-}
-''');
- ClassElement classA = findElement('A');
- ConstructorElement element = classA.constructors[0];
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, classA.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
-
- void test_encode_ConstructorElement_named_real() {
- resolveTestUnit('''
-class A {
- A.aaa();
- A.bbb();
-}
-''');
- ClassElement classA = findElement('A');
- // A.aaa()
- {
- ConstructorElement element = classA.getNamedConstructor('aaa');
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, classA.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
- // A.bbb()
- {
- ConstructorElement element = classA.getNamedConstructor('bbb');
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, classA.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
- }
-
- void test_encode_ConstructorElement_named_synthetic() {
- resolveTestUnit('''
-class A {
- A.aaa();
- A.bbb();
-}
-class M {}
-class X = A with M;
-''');
- ClassElement classX = findElement('X');
- // X.aaa()
- {
- ConstructorElement element = classX.getNamedConstructor('aaa');
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, classX.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
- // X.bbb()
- {
- ConstructorElement element = classX.getNamedConstructor('bbb');
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, classX.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
- }
-
- void test_encode_getter_real() {
- resolveTestUnit('''
-class A {
- int get test => 42;
-}
-''');
- PropertyAccessorElement element = findElement('test', ElementKind.GETTER);
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, element.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
-
- void test_encode_getter_synthetic() {
- resolveTestUnit('''
-class A {
- int test;
-}
-''');
- FieldElement field = findElement('test', ElementKind.FIELD);
- PropertyAccessorElement element = field.getter;
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, element.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
-
- void test_encode_IndexableName() {
- IndexableName indexable = new IndexableName('test');
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, -1);
- expect(id2, isNonNegative);
- expect(id3, IndexableNameKind.INSTANCE.index);
- expect(codec.decode(context, id1, id2, id3), indexable);
- }
-
- void test_encode_LibraryElement() {
- resolveTestUnit('''
-class A {
- test() {}
-}
-''');
- Element element = testLibraryElement;
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, -1);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
-
- void test_encode_MethodElement() {
- resolveTestUnit('''
-class A {
- test() {}
-}
-''');
- Element element = findElement('test');
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, element.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
-
- void test_encode_nullLibraryElement() {
- resolveTestUnit('''
-test() {}
-''');
- Element element = findElement('test');
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- context.setContents(testSource, '');
- IndexableObject object2 = codec.decode(context, id1, id2, id3);
- expect(object2, isNull);
- }
-
- void test_encode_setter_real() {
- resolveTestUnit('''
-class A {
- void set test(x) {}
-}
-''');
- PropertyAccessorElement element = findElement('test=', ElementKind.SETTER);
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, element.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
-
- void test_encode_setter_synthetic() {
- resolveTestUnit('''
-class A {
- int test;
-}
-''');
- FieldElement field = findElement('test', ElementKind.FIELD);
- PropertyAccessorElement element = field.setter;
- IndexableObject indexable = new IndexableElement(element);
- int id1 = codec.encode1(indexable);
- int id2 = codec.encode2(indexable);
- int id3 = codec.encode3(indexable);
- expect(id1, isNonNegative);
- expect(id2, element.nameOffset);
- expect(id3, IndexableElementKind.forElement(element).index);
- validateDecode(id1, id2, id3, element);
- }
-
- void test_encodeHash_notLocal() {
- resolveTestUnit('''
-class A {
- void mainA() {
- int foo; // A
- }
- void mainB() {
- int foo; // B
- int bar;
- }
-}
-''');
- MethodElement mainA = findElement('mainA');
- MethodElement mainB = findElement('mainB');
- Element fooA = mainA.localVariables[0];
- Element fooB = mainB.localVariables[0];
- Element bar = mainB.localVariables[1];
- int id_fooA = codec.encodeHash(new IndexableElement(fooA));
- int id_fooB = codec.encodeHash(new IndexableElement(fooB));
- int id_bar = codec.encodeHash(new IndexableElement(bar));
- expect(id_fooA == id_fooB, isTrue);
- expect(id_fooA == id_bar, isFalse);
- }
-
- void validateDecode(int id1, int id2, int id3, Element element) {
- IndexableObject object2 = codec.decode(context, id1, id2, id3);
- expect(object2, new isInstanceOf<IndexableElement>());
- Element element2 = (object2 as IndexableElement).element;
- expect(element2, element);
- }
-}
-
-@reflectiveTest
-class _RelationshipCodecTest {
- StringCodec stringCodec = new StringCodec();
- RelationshipCodec codec;
-
- void setUp() {
- codec = new RelationshipCodec(stringCodec);
- }
-
- void test_all() {
- RelationshipImpl relationship =
- RelationshipImpl.getRelationship('my-relationship');
- int id = codec.encode(relationship);
- expect(codec.decode(id), relationship);
- }
-}
-
-@reflectiveTest
-class _StringCodecTest {
- StringCodec codec = new StringCodec();
-
- void test_all() {
- int idA = codec.encode('aaa');
- int idB = codec.encode('bbb');
- expect(codec.decode(idA), 'aaa');
- expect(codec.decode(idB), 'bbb');
- }
-}
diff --git a/pkg/analysis_server/test/services/index/store/collection_test.dart b/pkg/analysis_server/test/services/index/store/collection_test.dart
deleted file mode 100644
index 77e6bb7..0000000
--- a/pkg/analysis_server/test/services/index/store/collection_test.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.src.index.store.collection;
-
-import 'package:analysis_server/src/services/index/store/collection.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../../utils.dart';
-
-main() {
- initializeTestEnvironment();
- defineReflectiveTests(_IntArrayToIntMapTest);
- defineReflectiveTests(_IntToIntSetMapTest);
-}
-
-@reflectiveTest
-class _IntArrayToIntMapTest {
- IntArrayToIntMap map = new IntArrayToIntMap();
-
- void test_put_get() {
- map[<int>[1, 2, 3]] = 1;
- map[<int>[2, 3, 4, 5]] = 2;
- expect(map[<int>[0]], isNull);
- expect(map[<int>[1, 2, 3]], 1);
- expect(map[<int>[2, 3, 4, 5]], 2);
- }
-}
-
-@reflectiveTest
-class _IntToIntSetMapTest {
- IntToIntSetMap map = new IntToIntSetMap();
-
- void test_add_duplicate() {
- map.add(1, 0);
- map.add(1, 0);
- List<int> set = map.get(1);
- expect(set, hasLength(1));
- }
-
- void test_clear() {
- map.add(1, 10);
- map.add(2, 20);
- expect(map.length, 2);
- map.clear();
- expect(map.length, 0);
- }
-
- void test_get() {
- map.add(1, 10);
- map.add(1, 11);
- map.add(1, 12);
- map.add(2, 20);
- map.add(2, 21);
- expect(map.get(1), unorderedEquals([10, 11, 12]));
- expect(map.get(2), unorderedEquals([20, 21]));
- }
-
- void test_get_no() {
- expect(map.get(3), []);
- }
-
- void test_length() {
- expect(map.length, 0);
- map.add(1, 10);
- expect(map.length, 1);
- map.add(1, 11);
- map.add(1, 12);
- expect(map.length, 1);
- map.add(2, 20);
- expect(map.length, 2);
- map.add(2, 21);
- expect(map.length, 2);
- }
-}
diff --git a/pkg/analysis_server/test/services/index/store/mocks.dart b/pkg/analysis_server/test/services/index/store/mocks.dart
deleted file mode 100644
index a197342..0000000
--- a/pkg/analysis_server/test/services/index/store/mocks.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.index.store.mocks;
-
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/store/codec.dart';
-import 'package:typed_mock/typed_mock.dart';
-
-class MockContextCodec extends TypedMock implements ContextCodec {}
-
-class MockElementCodec extends TypedMock implements ElementCodec {}
-
-class MockLocation extends TypedMock implements LocationImpl {}
-
-class MockRelationshipCodec extends TypedMock implements RelationshipCodec {}
diff --git a/pkg/analysis_server/test/services/index/store/single_source_container.dart b/pkg/analysis_server/test/services/index/store/single_source_container.dart
deleted file mode 100644
index 780e3c8..0000000
--- a/pkg/analysis_server/test/services/index/store/single_source_container.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.src.index.store.single_source_container;
-
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * A [SourceContainer] with a single [Source].
- */
-class SingleSourceContainer implements SourceContainer {
- final Source _source;
-
- SingleSourceContainer(this._source);
-
- @override
- bool contains(Source source) => source == _source;
-}
diff --git a/pkg/analysis_server/test/services/index/store/split_store_test.dart b/pkg/analysis_server/test/services/index/store/split_store_test.dart
deleted file mode 100644
index fbe43d7..0000000
--- a/pkg/analysis_server/test/services/index/store/split_store_test.dart
+++ /dev/null
@@ -1,1108 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.src.index.store.split_store;
-
-import 'dart:async';
-
-import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/indexable_element.dart';
-import 'package:analysis_server/src/services/index/store/codec.dart';
-import 'package:analysis_server/src/services/index/store/memory_node_manager.dart';
-import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../../mocks.dart';
-import '../../../utils.dart';
-import 'mocks.dart';
-import 'single_source_container.dart';
-
-main() {
- initializeTestEnvironment();
- defineReflectiveTests(_FileNodeManagerTest);
- defineReflectiveTests(_IndexNodeTest);
- defineReflectiveTests(_LocationDataTest);
- defineReflectiveTests(_RelationKeyDataTest);
- defineReflectiveTests(_SplitIndexStoreTest);
-}
-
-void _assertHasLocation(List<LocationImpl> locations, IndexableElement element,
- int offset, int length,
- {bool isQualified: false, bool isResolved: true}) {
- for (LocationImpl location in locations) {
- if ((element == null || location.indexable == element) &&
- location.offset == offset &&
- location.length == length &&
- location.isQualified == isQualified &&
- location.isResolved == isResolved) {
- return;
- }
- }
- fail('Expected to find Location'
- '(element=$element, offset=$offset, length=$length)');
-}
-
-void _assertHasLocationQ(List<LocationImpl> locations, IndexableElement element,
- int offset, int length) {
- _assertHasLocation(locations, element, offset, length, isQualified: true);
-}
-
-@reflectiveTest
-class _FileNodeManagerTest {
- MockLogger logger = new MockLogger();
- StringCodec stringCodec = new StringCodec();
- RelationshipCodec relationshipCodec;
-
- AnalysisContext context = new MockAnalysisContext('context');
- ContextCodec contextCodec = new MockContextCodec();
- int contextId = 13;
-
- ElementCodec elementCodec = new MockElementCodec();
- int nextElementId = 0;
-
- FileNodeManager nodeManager;
- FileManager fileManager = new _MockFileManager();
-
- void setUp() {
- relationshipCodec = new RelationshipCodec(stringCodec);
- nodeManager = new FileNodeManager(fileManager, logger, stringCodec,
- contextCodec, elementCodec, relationshipCodec);
- when(contextCodec.encode(context)).thenReturn(contextId);
- when(contextCodec.decode(contextId)).thenReturn(context);
- }
-
- void test_clear() {
- nodeManager.clear();
- verify(fileManager.clear()).once();
- }
-
- void test_getLocationCount_empty() {
- expect(nodeManager.locationCount, 0);
- }
-
- void test_getNode_contextNull() {
- String name = '42.index';
- // record bytes
- List<int> bytes;
- when(fileManager.write(name, anyObject)).thenInvoke((name, bs) {
- bytes = bs;
- });
- // put Node
- Future putFuture;
- {
- IndexNode node = new IndexNode(context, elementCodec, relationshipCodec);
- putFuture = nodeManager.putNode(name, node);
- }
- // do in the "put" Future
- putFuture.then((_) {
- // force "null" context
- when(contextCodec.decode(contextId)).thenReturn(null);
- // prepare input bytes
- when(fileManager.read(name)).thenReturn(new Future.value(bytes));
- // get Node
- return nodeManager.getNode(name).then((IndexNode node) {
- expect(node, isNull);
- // no exceptions
- verifyZeroInteractions(logger);
- });
- });
- }
-
- test_getNode_invalidVersion() {
- String name = '42.index';
- // prepare a stream with an invalid version
- when(fileManager.read(name))
- .thenReturn(new Future.value([0x01, 0x02, 0x03, 0x04]));
- // do in the Future
- return nodeManager.getNode(name).then((IndexNode node) {
- // no IndexNode
- expect(node, isNull);
- // failed
- verify(logger.logError(anyObject, anyObject)).once();
- });
- }
-
- test_getNode_streamException() {
- String name = '42.index';
- when(fileManager.read(name)).thenReturn(new Future(() {
- return throw new Exception();
- }));
- // do in the Future
- return nodeManager.getNode(name).then((IndexNode node) {
- expect(node, isNull);
- // failed
- verify(logger.logError(anyString, anyObject)).once();
- });
- }
-
- test_getNode_streamNull() {
- String name = '42.index';
- when(fileManager.read(name)).thenReturn(new Future.value(null));
- // do in the Future
- return nodeManager.getNode(name).then((IndexNode node) {
- expect(node, isNull);
- // OK
- verifyZeroInteractions(logger);
- });
- }
-
- void test_newNode() {
- IndexNode node = nodeManager.newNode(context);
- expect(node.context, context);
- expect(node.locationCount, 0);
- }
-
- test_putNode_getNode() {
- String name = '42.index';
- // record bytes
- List<int> bytes;
- when(fileManager.write(name, anyObject)).thenInvoke((name, bs) {
- bytes = bs;
- });
- // prepare elements
- IndexableElement elementA = _mockElement();
- IndexableElement elementB = _mockElement();
- IndexableElement elementC = _mockElement();
- RelationshipImpl relationship =
- RelationshipImpl.getRelationship('my-relationship');
- // put Node
- Future putFuture;
- {
- // prepare relations
- int relationshipId = relationshipCodec.encode(relationship);
- RelationKeyData key =
- new RelationKeyData.forData(0, 1, 2, relationshipId);
- List<LocationData> locations = [
- new LocationData.forData(3, 4, 5, 1, 10, 2),
- new LocationData.forData(6, 7, 8, 2, 20, 3)
- ];
- Map<RelationKeyData, List<LocationData>> relations = {key: locations};
- // prepare Node
- IndexNode node = new _MockIndexNode();
- when(node.context).thenReturn(context);
- when(node.relations).thenReturn(relations);
- when(node.locationCount).thenReturn(2);
- // put Node
- putFuture = nodeManager.putNode(name, node);
- }
- // do in the Future
- putFuture.then((_) {
- // has locations
- expect(nodeManager.locationCount, 2);
- // prepare input bytes
- when(fileManager.read(name)).thenReturn(new Future.value(bytes));
- // get Node
- return nodeManager.getNode(name).then((IndexNode node) {
- expect(2, node.locationCount);
- {
- List<LocationImpl> locations =
- node.getRelationships(elementA, relationship);
- expect(locations, hasLength(2));
- _assertHasLocation(locations, elementB, 1, 10);
- _assertHasLocationQ(locations, elementC, 2, 20);
- }
- });
- });
- }
-
- test_putNode_streamException() {
- String name = '42.index';
- Exception exception = new Exception();
- when(fileManager.write(name, anyObject)).thenReturn(new Future(() {
- return throw exception;
- }));
- // prepare IndexNode
- IndexNode node = new _MockIndexNode();
- when(node.context).thenReturn(context);
- when(node.locationCount).thenReturn(0);
- when(node.relations).thenReturn({});
- // try to put
- return nodeManager.putNode(name, node).then((_) {
- // failed
- verify(logger.logError(anyString, anyObject)).once();
- });
- }
-
- void test_removeNode() {
- String name = '42.index';
- nodeManager.removeNode(name);
- verify(fileManager.delete(name)).once();
- }
-
- IndexableElement _mockElement() {
- int id1 = nextElementId++;
- int id2 = nextElementId++;
- int id3 = nextElementId++;
- Element element = new MockElement();
- IndexableObject indexable = new IndexableElement(element);
- when(elementCodec.encode1(indexable)).thenReturn(id1);
- when(elementCodec.encode2(indexable)).thenReturn(id2);
- when(elementCodec.encode3(indexable)).thenReturn(id3);
- when(elementCodec.decode(context, id1, id2, id3)).thenReturn(indexable);
- return indexable;
- }
-}
-
-@reflectiveTest
-class _IndexNodeTest {
- AnalysisContext context = new MockAnalysisContext('context');
- ElementCodec elementCodec = new MockElementCodec();
- int nextElementId = 0;
- IndexNode node;
- RelationshipCodec relationshipCodec;
- StringCodec stringCodec = new StringCodec();
-
- void setUp() {
- relationshipCodec = new RelationshipCodec(stringCodec);
- node = new IndexNode(context, elementCodec, relationshipCodec);
- }
-
- void test_getContext() {
- expect(node.context, context);
- }
-
- void test_recordRelationship() {
- IndexableElement elementA = _mockElement();
- IndexableElement elementB = _mockElement();
- IndexableElement elementC = _mockElement();
- RelationshipImpl relationship =
- RelationshipImpl.getRelationship('my-relationship');
- LocationImpl locationA = new LocationImpl(elementB, 1, 2);
- LocationImpl locationB = new LocationImpl(elementC, 10, 20);
- // empty initially
- expect(node.locationCount, 0);
- // record
- node.recordRelationship(elementA, relationship, locationA);
- expect(node.locationCount, 1);
- node.recordRelationship(elementA, relationship, locationB);
- expect(node.locationCount, 2);
- // get relations
- expect(node.getRelationships(elementB, relationship), isEmpty);
- {
- List<LocationImpl> locations =
- node.getRelationships(elementA, relationship);
- expect(locations, hasLength(2));
- _assertHasLocation(locations, null, 1, 2);
- _assertHasLocation(locations, null, 10, 20);
- }
- // verify relations map
- {
- Map<RelationKeyData, List<LocationData>> relations = node.relations;
- expect(relations, hasLength(1));
- List<LocationData> locations = relations.values.first;
- expect(locations, hasLength(2));
- }
- }
-
- void test_setRelations() {
- IndexableElement elementA = _mockElement();
- IndexableElement elementB = _mockElement();
- IndexableElement elementC = _mockElement();
- RelationshipImpl relationship =
- RelationshipImpl.getRelationship('my-relationship');
- // record
- {
- int relationshipId = relationshipCodec.encode(relationship);
- RelationKeyData key =
- new RelationKeyData.forData(0, 1, 2, relationshipId);
- List<LocationData> locations = [
- new LocationData.forData(3, 4, 5, 1, 10, 2),
- new LocationData.forData(6, 7, 8, 2, 20, 3)
- ];
- node.relations = {key: locations};
- }
- // request
- List<LocationImpl> locations =
- node.getRelationships(elementA, relationship);
- expect(locations, hasLength(2));
- _assertHasLocation(locations, elementB, 1, 10);
- _assertHasLocationQ(locations, elementC, 2, 20);
- }
-
- IndexableElement _mockElement() {
- int id1 = nextElementId++;
- int id2 = nextElementId++;
- int id3 = nextElementId++;
- Element element = new MockElement();
- IndexableElement indexable = new IndexableElement(element);
- when(elementCodec.encode1(indexable)).thenReturn(id1);
- when(elementCodec.encode2(indexable)).thenReturn(id2);
- when(elementCodec.encode3(indexable)).thenReturn(id3);
- when(elementCodec.decode(context, id1, id2, id3)).thenReturn(indexable);
- return indexable;
- }
-}
-
-@reflectiveTest
-class _LocationDataTest {
- AnalysisContext context = new MockAnalysisContext('context');
- ElementCodec elementCodec = new MockElementCodec();
- StringCodec stringCodec = new StringCodec();
-
- void test_newForData() {
- Element element = new MockElement();
- IndexableElement indexable = new IndexableElement(element);
- when(elementCodec.decode(context, 11, 12, 13)).thenReturn(indexable);
- LocationData locationData = new LocationData.forData(11, 12, 13, 1, 2, 0);
- LocationImpl location = locationData.getLocation(context, elementCodec);
- expect(location.indexable, indexable);
- expect(location.offset, 1);
- expect(location.length, 2);
- expect(location.isQualified, isFalse);
- expect(location.isResolved, isFalse);
- }
-
- void test_newForObject() {
- // prepare Element
- Element element = new MockElement();
- IndexableElement indexable = new IndexableElement(element);
- when(elementCodec.encode1(indexable)).thenReturn(11);
- when(elementCodec.encode2(indexable)).thenReturn(12);
- when(elementCodec.encode3(indexable)).thenReturn(13);
- when(elementCodec.decode(context, 11, 12, 13)).thenReturn(indexable);
- // create
- LocationImpl location = new LocationImpl(indexable, 1, 2);
- LocationData locationData =
- new LocationData.forObject(elementCodec, location);
- // touch 'hashCode'
- locationData.hashCode;
- // ==
- expect(
- locationData == new LocationData.forData(11, 12, 13, 1, 2, 2), isTrue);
- // getLocation()
- {
- LocationImpl newLocation =
- locationData.getLocation(context, elementCodec);
- expect(newLocation.indexable, indexable);
- expect(newLocation.offset, 1);
- expect(newLocation.length, 2);
- }
- // no Element - no Location
- {
- when(elementCodec.decode(context, 11, 12, 13)).thenReturn(null);
- LocationImpl newLocation =
- locationData.getLocation(context, elementCodec);
- expect(newLocation, isNull);
- }
- }
-}
-
-/**
- * [LocationImpl] has no [==] and [hashCode], so to compare locations by value we
- * need to wrap them into such object.
- */
-class _LocationEqualsWrapper {
- final LocationImpl location;
-
- _LocationEqualsWrapper(this.location);
-
- @override
- int get hashCode {
- return 31 * (31 * location.indexable.hashCode + location.offset) +
- location.length;
- }
-
- @override
- bool operator ==(Object other) {
- if (other is _LocationEqualsWrapper) {
- return other.location.offset == location.offset &&
- other.location.length == location.length &&
- other.location.indexable == location.indexable;
- }
- return false;
- }
-}
-
-class _MockFileManager extends TypedMock implements FileManager {}
-
-class _MockIndexNode extends TypedMock implements IndexNode {}
-
-@reflectiveTest
-class _RelationKeyDataTest {
- AnalysisContext context = new MockAnalysisContext('context');
- ElementCodec elementCodec = new MockElementCodec();
- RelationshipCodec relationshipCodec = new MockRelationshipCodec();
- StringCodec stringCodec = new StringCodec();
-
- void test_newFromData() {
- RelationKeyData keyData = new RelationKeyData.forData(11, 12, 13, 2);
- // equals
- expect(keyData == this, isFalse);
- expect(keyData == new RelationKeyData.forData(11, 12, 13, 20), isFalse);
- expect(keyData == keyData, isTrue);
- expect(keyData == new RelationKeyData.forData(11, 12, 13, 2), isTrue);
- }
-
- void test_newFromObjects() {
- // prepare Element
- IndexableElement indexable;
- {
- Element element = new MockElement();
- indexable = new IndexableElement(element);
- ElementLocation location = new ElementLocationImpl.con3(['foo', 'bar']);
- when(element.location).thenReturn(location);
- when(context.getElement(location)).thenReturn(indexable);
- when(elementCodec.encode1(indexable)).thenReturn(11);
- when(elementCodec.encode2(indexable)).thenReturn(12);
- when(elementCodec.encode3(indexable)).thenReturn(13);
- }
- // prepare relationship
- RelationshipImpl relationship =
- RelationshipImpl.getRelationship('my-relationship');
- int relationshipId = 1;
- when(relationshipCodec.encode(relationship)).thenReturn(relationshipId);
- // create RelationKeyData
- RelationKeyData keyData = new RelationKeyData.forObject(
- elementCodec, relationshipCodec, indexable, relationship);
- // touch
- keyData.hashCode;
- // equals
- expect(keyData == this, isFalse);
- expect(keyData == new RelationKeyData.forData(11, 12, 13, 20), isFalse);
- expect(keyData == keyData, isTrue);
- expect(keyData == new RelationKeyData.forData(11, 12, 13, relationshipId),
- isTrue);
- }
-}
-
-@reflectiveTest
-class _SplitIndexStoreTest {
- AnalysisContext contextA = new MockAnalysisContext('contextA');
- AnalysisContext contextB = new MockAnalysisContext('contextB');
- AnalysisContext contextC = new MockAnalysisContext('contextC');
-
- Element elementA = new MockElement('elementA');
- Element elementB = new MockElement('elementB');
- Element elementC = new MockElement('elementC');
- Element elementD = new MockElement('elementD');
-
- IndexableElement indexableA;
- IndexableElement indexableB;
- IndexableElement indexableC;
- IndexableElement indexableD;
-
- Source librarySource = new MockSource('librarySource');
- CompilationUnitElement libraryUnitElement = new MockCompilationUnitElement();
- LibraryElement libraryElement = new MockLibraryElement();
-
- Source librarySourceB = new MockSource('librarySourceB');
- LibraryElement libraryElementB = new MockLibraryElement();
- CompilationUnitElement libraryUnitElementB = new MockCompilationUnitElement();
-
- ElementCodec elementCodec = new MockElementCodec();
- MemoryNodeManager nodeManager = new MemoryNodeManager();
- RelationshipImpl relationship =
- RelationshipImpl.getRelationship('test-relationship');
- Source sourceA = new MockSource('sourceA');
- Source sourceB = new MockSource('sourceB');
- Source sourceC = new MockSource('sourceC');
- Source sourceD = new MockSource('sourceD');
- SplitIndexStore store;
- CompilationUnitElement unitElementA = new MockCompilationUnitElement();
- CompilationUnitElement unitElementB = new MockCompilationUnitElement();
- CompilationUnitElement unitElementC = new MockCompilationUnitElement();
- CompilationUnitElement unitElementD = new MockCompilationUnitElement();
-
- void setUp() {
- indexableA = new IndexableElement(elementA);
- indexableB = new IndexableElement(elementB);
- indexableC = new IndexableElement(elementC);
- indexableD = new IndexableElement(elementD);
-
- nodeManager.elementCodec = elementCodec;
- store = new SplitIndexStore(
- nodeManager, <IndexObjectManager>[new DartUnitIndexObjectManager()]);
- when(elementCodec.encode1(indexableA)).thenReturn(11);
- when(elementCodec.encode2(indexableA)).thenReturn(12);
- when(elementCodec.encode3(indexableA)).thenReturn(13);
- when(elementCodec.encode1(indexableB)).thenReturn(21);
- when(elementCodec.encode2(indexableB)).thenReturn(22);
- when(elementCodec.encode3(indexableB)).thenReturn(23);
- when(elementCodec.encode1(indexableC)).thenReturn(31);
- when(elementCodec.encode2(indexableC)).thenReturn(32);
- when(elementCodec.encode3(indexableC)).thenReturn(33);
- when(elementCodec.encode1(indexableD)).thenReturn(41);
- when(elementCodec.encode2(indexableD)).thenReturn(42);
- when(elementCodec.encode3(indexableD)).thenReturn(43);
- when(elementCodec.decode(contextA, 11, 12, 13)).thenReturn(indexableA);
- when(elementCodec.decode(contextA, 21, 22, 23)).thenReturn(indexableB);
- when(elementCodec.decode(contextA, 31, 32, 33)).thenReturn(indexableC);
- when(elementCodec.decode(contextA, 41, 42, 43)).thenReturn(indexableD);
- when(contextA.isDisposed).thenReturn(false);
- when(contextB.isDisposed).thenReturn(false);
- when(contextC.isDisposed).thenReturn(false);
- when(sourceA.fullName).thenReturn('/home/user/sourceA.dart');
- when(sourceB.fullName).thenReturn('/home/user/sourceB.dart');
- when(sourceC.fullName).thenReturn('/home/user/sourceC.dart');
- when(sourceD.fullName).thenReturn('/home/user/sourceD.dart');
- when(elementA.context).thenReturn(contextA);
- when(elementB.context).thenReturn(contextA);
- when(elementC.context).thenReturn(contextA);
- when(elementD.context).thenReturn(contextA);
- when(elementA.enclosingElement).thenReturn(unitElementA);
- when(elementB.enclosingElement).thenReturn(unitElementB);
- when(elementC.enclosingElement).thenReturn(unitElementC);
- when(elementD.enclosingElement).thenReturn(unitElementD);
- when(elementA.source).thenReturn(sourceA);
- when(elementB.source).thenReturn(sourceB);
- when(elementC.source).thenReturn(sourceC);
- when(elementD.source).thenReturn(sourceD);
- when(elementA.library).thenReturn(libraryElement);
- when(elementB.library).thenReturn(libraryElement);
- when(elementC.library).thenReturn(libraryElement);
- when(elementD.library).thenReturn(libraryElement);
- when(unitElementA.source).thenReturn(sourceA);
- when(unitElementB.source).thenReturn(sourceB);
- when(unitElementC.source).thenReturn(sourceC);
- when(unitElementD.source).thenReturn(sourceD);
- when(unitElementA.library).thenReturn(libraryElement);
- when(unitElementB.library).thenReturn(libraryElement);
- when(unitElementC.library).thenReturn(libraryElement);
- when(unitElementD.library).thenReturn(libraryElement);
- // library
- when(librarySource.fullName).thenReturn('/home/user/librarySource.dart');
- when(libraryUnitElement.library).thenReturn(libraryElement);
- when(libraryUnitElement.source).thenReturn(librarySource);
- when(libraryElement.source).thenReturn(librarySource);
- when(libraryElement.definingCompilationUnit).thenReturn(libraryUnitElement);
- // library B
- when(librarySourceB.fullName).thenReturn('/home/user/librarySource.dart');
- when(libraryUnitElementB.library).thenReturn(libraryElementB);
- when(libraryUnitElementB.source).thenReturn(librarySourceB);
- when(libraryElementB.source).thenReturn(librarySourceB);
- when(libraryElementB.definingCompilationUnit)
- .thenReturn(libraryUnitElementB);
- }
-
- void test_aboutToIndexDart_disposedContext() {
- when(contextA.isDisposed).thenReturn(true);
- expect(store.aboutToIndex(contextA, unitElementA), isFalse);
- }
-
- Future test_aboutToIndexDart_library_first() {
- when(libraryElement.parts)
- .thenReturn(<CompilationUnitElement>[unitElementA, unitElementB]);
- {
- store.aboutToIndex(contextA, libraryUnitElement);
- store.doneIndex();
- }
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, []);
- });
- }
-
- test_aboutToIndexDart_library_secondWithoutOneUnit() {
- LocationImpl locationA = mockLocation(indexableA);
- LocationImpl locationB = mockLocation(indexableB);
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableA, relationship, locationA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementB);
- store.recordRelationship(indexableA, relationship, locationB);
- store.doneIndex();
- }
- // "A" and "B" locations
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, [locationA, locationB]);
- // apply "libraryUnitElement", only with "B"
- when(libraryElement.parts).thenReturn([unitElementB]);
- {
- store.aboutToIndex(contextA, libraryUnitElement);
- store.doneIndex();
- }
- }).then((_) {
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, [locationB]);
- });
- });
- }
-
- void test_aboutToIndexDart_nullContext() {
- expect(store.aboutToIndex(null, unitElementA), isFalse);
- }
-
- void test_aboutToIndexDart_nullLibraryElement() {
- when(unitElementA.library).thenReturn(null);
- expect(store.aboutToIndex(contextA, unitElementA), isFalse);
- }
-
- void test_aboutToIndexDart_nullLibraryUnitElement() {
- when(libraryElement.definingCompilationUnit).thenReturn(null);
- expect(store.aboutToIndex(contextA, unitElementA), isFalse);
- }
-
- void test_aboutToIndexDart_nullUnitElement() {
- expect(store.aboutToIndex(contextA, null), isFalse);
- }
-
- test_cancelIndexDart() {
- LocationImpl locationA = mockLocation(indexableA);
- LocationImpl locationB = mockLocation(indexableA);
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableA, relationship, locationA);
- store.recordRelationship(indexableA, relationship, locationB);
- store.recordTopLevelDeclaration(elementA);
- store.cancelIndex();
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, []);
- expect(store.getTopLevelDeclarations((name) => true), isEmpty);
- });
- }
-
- void test_clear() {
- LocationImpl locationA = mockLocation(indexableA);
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableA, relationship, locationA);
- store.doneIndex();
- expect(nodeManager.isEmpty(), isFalse);
- // clear
- store.clear();
- expect(nodeManager.isEmpty(), isTrue);
- }
-
- test_getRelationships_empty() {
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- expect(locations, isEmpty);
- });
- }
-
- void test_getStatistics() {
- // empty initially
- {
- String statistics = store.statistics;
- expect(statistics, contains('0 locations'));
- expect(statistics, contains('0 sources'));
- }
- // add 2 locations
- LocationImpl locationA = mockLocation(indexableA);
- LocationImpl locationB = mockLocation(indexableB);
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableA, relationship, locationA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementB);
- store.recordRelationship(indexableA, relationship, locationB);
- store.doneIndex();
- }
- {
- String statistics = store.statistics;
- expect(statistics, contains('2 locations'));
- expect(statistics, contains('3 sources'));
- }
- }
-
- void test_recordRelationship_multiplyDefinedElement() {
- Element multiplyElement =
- new MultiplyDefinedElementImpl(contextA, <Element>[elementA, elementB]);
- LocationImpl location = mockLocation(indexableA);
- store.recordRelationship(
- new IndexableElement(multiplyElement), relationship, location);
- store.doneIndex();
- expect(nodeManager.isEmpty(), isTrue);
- }
-
- void test_recordRelationship_nullElement() {
- LocationImpl locationA = mockLocation(indexableA);
- store.recordRelationship(null, relationship, locationA);
- store.doneIndex();
- expect(nodeManager.isEmpty(), isTrue);
- }
-
- void test_recordRelationship_nullLocation() {
- store.recordRelationship(indexableA, relationship, null);
- store.doneIndex();
- expect(nodeManager.isEmpty(), isTrue);
- }
-
- test_recordRelationship_oneElement_twoNodes() {
- LocationImpl locationA = mockLocation(indexableA);
- LocationImpl locationB = mockLocation(indexableB);
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableA, relationship, locationA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementB);
- store.recordRelationship(indexableA, relationship, locationB);
- store.doneIndex();
- }
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, [locationA, locationB]);
- });
- }
-
- test_recordRelationship_oneLocation() {
- LocationImpl locationA = mockLocation(indexableA);
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableA, relationship, locationA);
- store.doneIndex();
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, [locationA]);
- });
- }
-
- test_recordRelationship_twoLocations() {
- LocationImpl locationA = mockLocation(indexableA);
- LocationImpl locationB = mockLocation(indexableA);
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableA, relationship, locationA);
- store.recordRelationship(indexableA, relationship, locationB);
- store.doneIndex();
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, [locationA, locationB]);
- });
- }
-
- test_removeContext() {
- LocationImpl locationA = mockLocation(indexableA);
- LocationImpl locationB = mockLocation(indexableB);
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableA, relationship, locationA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementB);
- store.recordRelationship(indexableA, relationship, locationB);
- store.doneIndex();
- }
- // "A" and "B" locations
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, [locationA, locationB]);
- // remove "A" context
- store.removeContext(contextA);
- }).then((_) {
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, []);
- });
- });
- }
-
- void test_removeContext_nullContext() {
- store.removeContext(null);
- }
-
- test_removeSource_library() async {
- when(elementB.library).thenReturn(libraryElementB);
- when(unitElementB.library).thenReturn(libraryElementB);
- LocationImpl locationA = mockLocation(indexableA);
- LocationImpl locationB = mockLocation(indexableB);
- LocationImpl locationC = mockLocation(indexableC);
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableD, relationship, locationA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementB);
- store.recordRelationship(indexableD, relationship, locationB);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementC);
- store.recordRelationship(indexableD, relationship, locationC);
- store.doneIndex();
- }
- // "A", "B" and "C" locations
- {
- var locations = await store.getRelationships(indexableD, relationship);
- assertLocations(locations, [locationA, locationB, locationC]);
- }
- // remove "librarySource"
- store.removeSource(contextA, librarySource);
- // only "B" location, which is in "librarySourceB"
- {
- var locations = await store.getRelationships(indexableD, relationship);
- assertLocations(locations, [locationB]);
- }
- }
-
- void test_removeSource_nullContext() {
- store.removeSource(null, sourceA);
- }
-
- test_removeSource_unit() {
- LocationImpl locationA = mockLocation(indexableA);
- LocationImpl locationB = mockLocation(indexableB);
- LocationImpl locationC = mockLocation(indexableC);
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableA, relationship, locationA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementB);
- store.recordRelationship(indexableA, relationship, locationB);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementC);
- store.recordRelationship(indexableA, relationship, locationC);
- store.doneIndex();
- }
- // "A", "B" and "C" locations
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, [locationA, locationB, locationC]);
- }).then((_) {
- // remove "A" source
- store.removeSource(contextA, sourceA);
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, [locationB, locationC]);
- });
- });
- }
-
- test_removeSources_library() {
- LocationImpl locationA = mockLocation(indexableA);
- LocationImpl locationB = mockLocation(indexableB);
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordRelationship(indexableA, relationship, locationA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementB);
- store.recordRelationship(indexableA, relationship, locationB);
- store.doneIndex();
- }
- // "A" and "B" locations
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, [locationA, locationB]);
- }).then((_) {
- // remove "librarySource"
- store.removeSources(contextA, new SingleSourceContainer(librarySource));
- return store
- .getRelationships(indexableA, relationship)
- .then((List<LocationImpl> locations) {
- assertLocations(locations, []);
- });
- });
- }
-
- void test_removeSources_nullContext() {
- store.removeSources(null, null);
- }
-
- void test_removeSources_unit() {
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordTopLevelDeclaration(elementA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementB);
- store.recordTopLevelDeclaration(elementB);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextA, unitElementC);
- store.recordTopLevelDeclaration(elementC);
- store.doneIndex();
- }
- // A, B, C elements
- {
- List<Element> elements = store.getTopLevelDeclarations(anyName);
- expect(elements, unorderedEquals([elementA, elementB, elementC]));
- }
- // remove "A" source
- store.removeSources(contextA, new SingleSourceContainer(sourceA));
- store.removeSource(contextA, sourceA);
- {
- List<Element> elements = store.getTopLevelDeclarations(anyName);
- expect(elements, unorderedEquals([elementB, elementC]));
- }
- }
-
- void test_universe_aboutToIndex() {
- when(elementCodec.decode(contextA, 11, 12, 13))
- .thenReturn(new IndexableElement(elementA));
- when(elementCodec.decode(contextB, 21, 22, 23))
- .thenReturn(new IndexableElement(elementB));
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordTopLevelDeclaration(elementA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextB, unitElementB);
- store.recordTopLevelDeclaration(elementB);
- store.doneIndex();
- }
- // elementA, elementB
- {
- List<Element> elements = store.getTopLevelDeclarations(anyName);
- expect(elements, unorderedEquals([elementA, elementB]));
- }
- // re-index "unitElementA"
- {
- store.aboutToIndex(contextA, unitElementA);
- store.doneIndex();
- }
- {
- List<Element> elements = store.getTopLevelDeclarations(anyName);
- expect(elements, unorderedEquals([elementB]));
- }
- }
-
- void test_universe_clear() {
- when(elementCodec.decode(contextA, 11, 12, 13))
- .thenReturn(new IndexableElement(elementA));
- when(elementCodec.decode(contextB, 21, 22, 23))
- .thenReturn(new IndexableElement(elementB));
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordTopLevelDeclaration(elementA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextB, unitElementB);
- store.recordTopLevelDeclaration(elementB);
- store.doneIndex();
- }
- // elementA, elementB
- {
- List<Element> elements = store.getTopLevelDeclarations(anyName);
- expect(elements, unorderedEquals([elementA, elementB]));
- }
- // clear
- store.clear();
- {
- List<Element> elements = store.getTopLevelDeclarations(anyName);
- expect(elements, isEmpty);
- }
- }
-
- void test_universe_removeContext() {
- when(elementCodec.decode(contextA, 11, 12, 13))
- .thenReturn(new IndexableElement(elementA));
- when(elementCodec.decode(contextB, 21, 22, 23))
- .thenReturn(new IndexableElement(elementB));
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordTopLevelDeclaration(elementA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextB, unitElementB);
- store.recordTopLevelDeclaration(elementB);
- store.doneIndex();
- }
- // elementA, elementB
- {
- List<Element> elements = store.getTopLevelDeclarations(anyName);
- expect(elements, unorderedEquals([elementA, elementB]));
- }
- // remove "contextA"
- store.removeContext(contextA);
- {
- List<Element> elements = store.getTopLevelDeclarations(anyName);
- expect(elements, unorderedEquals([elementB]));
- }
- }
-
- void test_universe_removeSource() {
- when(elementCodec.decode(contextA, 11, 12, 13))
- .thenReturn(new IndexableElement(elementA));
- when(elementCodec.decode(contextB, 21, 22, 23))
- .thenReturn(new IndexableElement(elementB));
- {
- store.aboutToIndex(contextA, unitElementA);
- store.recordTopLevelDeclaration(elementA);
- store.doneIndex();
- }
- {
- store.aboutToIndex(contextB, unitElementB);
- store.recordTopLevelDeclaration(elementB);
- store.doneIndex();
- }
- // elementA, elementB
- {
- List<Element> elements = store.getTopLevelDeclarations(anyName);
- expect(elements, unorderedEquals([elementA, elementB]));
- }
- // remove "sourceA"
- store.removeSource(contextA, sourceA);
- {
- List<Element> elements = store.getTopLevelDeclarations(anyName);
- expect(elements, unorderedEquals([elementB]));
- }
- }
-
- static bool anyName(String name) => true;
-
- /**
- * Asserts that the [actual] locations have all the [expected] locations and
- * only them.
- */
- static void assertLocations(
- List<LocationImpl> actual, List<LocationImpl> expected) {
- List<_LocationEqualsWrapper> actualWrappers = wrapLocations(actual);
- List<_LocationEqualsWrapper> expectedWrappers = wrapLocations(expected);
- expect(actualWrappers, unorderedEquals(expectedWrappers));
- }
-
- /**
- * @return the new [LocationImpl] mock.
- */
- static LocationImpl mockLocation(IndexableElement indexable) {
- LocationImpl location = new MockLocation();
- when(location.indexable).thenReturn(indexable);
- when(location.offset).thenReturn(0);
- when(location.length).thenReturn(0);
- when(location.isQualified).thenReturn(true);
- when(location.isResolved).thenReturn(true);
- return location;
- }
-
- /**
- * Wraps the given locations into [LocationEqualsWrapper].
- */
- static List<_LocationEqualsWrapper> wrapLocations(
- List<LocationImpl> locations) {
- List<_LocationEqualsWrapper> wrappers = <_LocationEqualsWrapper>[];
- for (LocationImpl location in locations) {
- wrappers.add(new _LocationEqualsWrapper(location));
- }
- return wrappers;
- }
-}
diff --git a/pkg/analysis_server/test/services/index/store/temporary_folder_file_manager_test.dart b/pkg/analysis_server/test/services/index/store/temporary_folder_file_manager_test.dart
deleted file mode 100644
index a6974aa..0000000
--- a/pkg/analysis_server/test/services/index/store/temporary_folder_file_manager_test.dart
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.src.index.store.temporary_folder_file_mananer;
-
-import 'dart:io';
-
-import 'package:analysis_server/src/services/index/store/temporary_folder_file_manager.dart';
-import 'package:path/path.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../../utils.dart';
-
-main() {
- initializeTestEnvironment();
- defineReflectiveTests(_SeparateFileManagerTest);
-}
-
-@reflectiveTest
-class _SeparateFileManagerTest {
- TemporaryFolderFileManager fileManager;
-
- void setUp() {
- fileManager = new TemporaryFolderFileManager();
- }
-
- void tearDown() {
- fileManager.clear();
- }
-
- test_clear() {
- String name = "42.index";
- // create the file
- return fileManager.write(name, <int>[1, 2, 3, 4]).then((_) {
- // check that the file exists
- expect(_existsSync(name), isTrue);
- // clear
- fileManager.clear();
- expect(_existsSync(name), isFalse);
- });
- }
-
- test_delete_doesNotExist() {
- return fileManager.write('other.index', <int>[1, 2, 3, 4]).then((_) {
- String name = "42.index";
- fileManager.delete(name);
- });
- }
-
- test_delete_noDirectory() {
- String name = "42.index";
- fileManager.delete(name);
- }
-
- test_outputInput() {
- String name = "42.index";
- // create the file
- return fileManager.write(name, <int>[1, 2, 3, 4]).then((_) {
- // check that that the file exists
- expect(_existsSync(name), isTrue);
- // read the file
- return fileManager.read(name).then((bytes) {
- expect(bytes, <int>[1, 2, 3, 4]);
- // delete
- fileManager.delete(name);
- // the file does not exist anymore
- return fileManager.read(name).then((bytes) {
- expect(bytes, isNull);
- });
- });
- });
- }
-
- test_read_noDirectory() {
- String name = "42.index";
- return fileManager.read(name).then((bytes) {
- expect(bytes, isNull);
- });
- }
-
- bool _existsSync(String name) {
- Directory directory = fileManager.test_directory;
- if (directory == null) {
- return false;
- }
- return new File(join(directory.path, name)).existsSync();
- }
-}
diff --git a/pkg/analysis_server/test/services/index/store/test_all.dart b/pkg/analysis_server/test/services/index/store/test_all.dart
deleted file mode 100644
index ab63c97..0000000
--- a/pkg/analysis_server/test/services/index/store/test_all.dart
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.src.index.store;
-
-import 'package:unittest/unittest.dart';
-
-import '../../../utils.dart';
-import 'codec_test.dart' as codec_test;
-import 'collection_test.dart' as collection_test;
-import 'split_store_test.dart' as split_store_test;
-import 'temporary_folder_file_manager_test.dart' as tmp_file_manager_test;
-
-/**
- * Utility for manually running all tests.
- */
-main() {
- initializeTestEnvironment();
- group('store', () {
- codec_test.main();
- collection_test.main();
- tmp_file_manager_test.main();
- split_store_test.main();
- });
-}
diff --git a/pkg/analysis_server/test/services/index/test_all.dart b/pkg/analysis_server/test/services/index/test_all.dart
index 8f64484..27a2cd2 100644
--- a/pkg/analysis_server/test/services/index/test_all.dart
+++ b/pkg/analysis_server/test/services/index/test_all.dart
@@ -1,17 +1,11 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.services.src.index.all;
-
import 'package:unittest/unittest.dart';
import '../../utils.dart';
-import 'dart_index_contributor_test.dart' as dart_index_contributor_test;
-import 'indexable_file_test.dart' as indexable_file_test;
-import 'local_file_index_test.dart' as local_file_index_test;
-import 'local_index_test.dart' as local_index_test;
-import 'store/test_all.dart' as store_test_all;
+import 'index_test.dart' as index_test;
/**
* Utility for manually running all tests.
@@ -19,10 +13,6 @@
main() {
initializeTestEnvironment();
group('index', () {
- dart_index_contributor_test.main();
- indexable_file_test.main();
- local_file_index_test.main();
- local_index_test.main();
- store_test_all.main();
+ index_test.main();
});
}
diff --git a/pkg/analysis_server/test/services/index2/index2_test.dart b/pkg/analysis_server/test/services/index2/index2_test.dart
deleted file mode 100644
index 5a9abb0..0000000
--- a/pkg/analysis_server/test/services/index2/index2_test.dart
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/services/index2/index2.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_single_unit.dart';
-import '../../utils.dart';
-
-main() {
- initializeTestEnvironment();
- defineReflectiveTests(Index2Test);
-}
-
-@reflectiveTest
-class Index2Test extends AbstractSingleUnitTest {
- Index2 index = createMemoryIndex2();
-
- /**
- * Return the [Location] with given properties, or fail.
- */
- Location findLocation(List<Location> locations, String libraryUri,
- String unitUri, int offset, int length) {
- for (Location location in locations) {
- if (location.libraryUri == libraryUri &&
- location.unitUri == unitUri &&
- location.offset == offset &&
- location.length == length) {
- return location;
- }
- }
- fail('No at $offset with length $length in\n${locations.join('\n')}');
- return null;
- }
-
- /**
- * Return the [Location] with given properties, or fail.
- */
- Location findLocationSource(
- List<Location> locations, Source source, String search,
- {int length}) {
- String code = source.contents.data;
- int offset = code.indexOf(search);
- expect(offset, isNonNegative, reason: 'Not found "$search" in\n$code');
- length ??= getLeadingIdentifierLength(search);
- String uri = source.uri.toString();
- return findLocation(locations, uri, uri, offset, length);
- }
-
- /**
- * Return the [Location] with given properties, or fail.
- */
- Location findLocationTest(List<Location> locations, String search,
- {int length}) {
- int offset = findOffset(search);
- length ??= getLeadingIdentifierLength(search);
- String testUri = testSource.uri.toString();
- return findLocation(locations, testUri, testUri, offset, length);
- }
-
- void setUp() {
- super.setUp();
- }
-
- void tearDown() {
- super.tearDown();
- index = null;
- }
-
- test_getDefinedNames_classMember() async {
- _indexTestUnit('''
-class A {
- test() {}
-}
-class B {
- int test = 1;
- main() {
- int test = 2;
- }
-}
-''');
- ClassElement classA = findElement('A');
- ClassElement classB = findElement('B');
- List<Location> locations = await index.getDefinedNames(
- new RegExp(r'^test$'), IndexNameKind.classMember);
- expect(locations, hasLength(2));
- _assertHasDefinedName(locations, classA.methods[0]);
- _assertHasDefinedName(locations, classB.fields[0]);
- }
-
- test_getDefinedNames_topLevel() async {
- _indexTestUnit('''
-class A {} // A
-class B = Object with A;
-typedef C();
-D() {}
-var E = null;
-class NoMatchABCDE {}
-''');
- Element topA = findElement('A');
- Element topB = findElement('B');
- Element topC = findElement('C');
- Element topD = findElement('D');
- Element topE = findElement('E');
- List<Location> locations = await index.getDefinedNames(
- new RegExp(r'^[A-E]$'), IndexNameKind.topLevel);
- expect(locations, hasLength(5));
- _assertHasDefinedName(locations, topA);
- _assertHasDefinedName(locations, topB);
- _assertHasDefinedName(locations, topC);
- _assertHasDefinedName(locations, topD);
- _assertHasDefinedName(locations, topE);
- }
-
- test_getRelations_isExtendedBy() async {
- _indexTestUnit(r'''
-class A {}
-class B extends A {} // B
-''');
- Source source2 = _indexUnit(
- '/test2.dart',
- r'''
-import 'test.dart';
-class C extends A {} // C
-''');
- ClassElement elementA = testUnitElement.getType('A');
- List<Location> locations =
- await index.getRelations(elementA, IndexRelationKind.IS_EXTENDED_BY);
- findLocationTest(locations, 'A {} // B');
- findLocationSource(locations, source2, 'A {} // C');
- }
-
- test_getRelations_isReferencedBy() async {
- _indexTestUnit(r'''
-main(int a, int b) {
-}
-''');
- ClassElement intElement = context.typeProvider.intType.element;
- List<Location> locations = await index.getRelations(
- intElement, IndexRelationKind.IS_REFERENCED_BY);
- findLocationTest(locations, 'int a');
- findLocationTest(locations, 'int b');
- }
-
- test_getUnresolvedMemberReferences() async {
- _indexTestUnit('''
-class A {
- var test; // A
- mainA() {
- test(); // a-inv-r-nq
- test = 1; // a-ref-r-nq
- test += 2; // a-ref-r-nq
- print(test); // a-ref-r-nq
- }
-}
-main(A a, p) {
- a.test(); // a-inv-r-q
- a.test = 1; // a-ref-r-q
- a.test += 2; // a-ref-r-q
- print(a.test); // a-ref-r-q
- p.test(); // p-inv-ur-q
- p.test = 1; // p-ref-ur-q
- p.test += 2; // p-ref-ur-q
- print(p.test); // p-ref-ur-q
- print(p.test2); // not requested
-}
-''');
- List<Location> locations =
- await index.getUnresolvedMemberReferences('test');
- expect(locations, hasLength(4));
- findLocationTest(locations, 'test(); // p-inv-ur-q');
- findLocationTest(locations, 'test = 1; // p-ref-ur-q');
- findLocationTest(locations, 'test += 2; // p-ref-ur-q');
- findLocationTest(locations, 'test); // p-ref-ur-q');
- }
-
- /**
- * Assert that the given list of [locations] has a [Location] corresponding
- * to the [element].
- */
- void _assertHasDefinedName(List<Location> locations, Element element) {
- String libraryUri = element.library.source.uri.toString();
- String unitUri = element.source.uri.toString();
- for (Location location in locations) {
- if (location.libraryUri == libraryUri &&
- location.unitUri == unitUri &&
- location.offset == element.nameOffset &&
- location.length == element.nameLength) {
- return;
- }
- }
- fail('No declaration of $element at ${element.nameOffset} in\n'
- '${locations.join('\n')}');
- }
-
- void _indexTestUnit(String code) {
- resolveTestUnit(code);
- index.indexUnit(testUnit);
- }
-
- Source _indexUnit(String path, String code) {
- Source source = addSource(path, code);
- CompilationUnit unit = resolveLibraryUnit(source);
- index.indexUnit(unit);
- return source;
- }
-}
diff --git a/pkg/analysis_server/test/services/index2/test_all.dart b/pkg/analysis_server/test/services/index2/test_all.dart
deleted file mode 100644
index ebc17d6..0000000
--- a/pkg/analysis_server/test/services/index2/test_all.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-import 'index2_test.dart' as index_test;
-
-/**
- * Utility for manually running all tests.
- */
-main() {
- initializeTestEnvironment();
- group('index', () {
- index_test.main();
- });
-}
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
index 576f364..a565c87 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
@@ -9,11 +9,10 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:unittest/unittest.dart';
@@ -148,18 +147,18 @@
void indexTestUnit(String code) {
resolveTestUnit(code);
- index.index(context, testUnit);
+ index.indexUnit(testUnit);
}
void indexUnit(String file, String code) {
Source source = addSource(file, code);
CompilationUnit unit = resolveLibraryUnit(source);
- index.index(context, unit);
+ index.indexUnit(unit);
}
void setUp() {
super.setUp();
- index = createLocalMemoryIndex();
+ index = createMemoryIndex();
searchEngine = new SearchEngineImpl(index);
}
}
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
index f7b036f..e6238e3 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
@@ -7,8 +7,8 @@
import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
import 'package:analysis_server/src/services/correction/namespace.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:unittest/unittest.dart';
import 'abstract_refactoring.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index 2de53d8..9146b93 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -108,10 +108,10 @@
test_file_importedLibrary_package() async {
// configure packages
- testFile = '/packages/my_pkg/aaa/test.dart';
+ testFile = '/packages/my_pkg/lib/aaa/test.dart';
provider.newFile(testFile, '');
Map<String, List<Folder>> packageMap = {
- 'my_pkg': [provider.getResource('/packages/my_pkg')]
+ 'my_pkg': [provider.getResource('/packages/my_pkg/lib')]
};
context.sourceFactory = new SourceFactory([
AbstractContextTest.SDK_RESOLVER,
@@ -125,10 +125,10 @@
'''
import 'package:my_pkg/aaa/test.dart';
''');
- addTestSource('');
+ addTestSource('', Uri.parse('package:my_pkg/aaa/test.dart'));
_performAnalysis();
// perform refactoring
- _createRefactoring('/packages/my_pkg/bbb/ccc/new_name.dart');
+ _createRefactoring('/packages/my_pkg/lib/bbb/ccc/new_name.dart');
await _assertSuccessfulRefactoring();
assertFileChangeResult(
pathA,
@@ -291,7 +291,7 @@
}
for (ChangeNotice notice in result.changeNotices) {
if (notice.source.fullName.startsWith('/project/')) {
- index.index(context, notice.resolvedDartUnit);
+ index.indexUnit(notice.resolvedDartUnit);
}
}
}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
index 74d2ca8..bb4318b 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
@@ -7,8 +7,8 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_import_test.dart b/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
index 538baaf..8d061ed 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
@@ -5,7 +5,7 @@
library test.services.refactoring.rename_import;
import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
index 9a8f259..597df6e 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
@@ -52,8 +52,7 @@
library my.app;
part 'part.dart';
''');
- index.index(
- context, context.resolveCompilationUnit2(unitSource, testSource));
+ index.indexUnit(context.resolveCompilationUnit2(unitSource, testSource));
// configure refactoring
_createRenameRefactoring();
expect(refactoring.refactoringName, 'Rename Library');
@@ -81,8 +80,7 @@
library my . app;
part 'part.dart';
''');
- index.index(
- context, context.resolveCompilationUnit2(unitSource, testSource));
+ index.indexUnit(context.resolveCompilationUnit2(unitSource, testSource));
// configure refactoring
_createRenameRefactoring();
expect(refactoring.refactoringName, 'Rename Library');
diff --git a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
index a92bd0d..e454ece 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
@@ -101,6 +101,32 @@
return assertRefactoringConditionsOK();
}
+ test_checkFinalConditions_hasLocalVariable_otherForEachLoop() {
+ indexTestUnit('''
+main() {
+ for (int newName in []) {}
+ for (int test in []) {}
+}
+''');
+ createRenameRefactoringAtString('test in');
+ // check status
+ refactoring.newName = 'newName';
+ return assertRefactoringConditionsOK();
+ }
+
+ test_checkFinalConditions_hasLocalVariable_otherForLoop() {
+ indexTestUnit('''
+main() {
+ for (int newName = 0; newName < 10; newName++) {}
+ for (int test = 0; test < 10; test++) {}
+}
+''');
+ createRenameRefactoringAtString('test = 0');
+ // check status
+ refactoring.newName = 'newName';
+ return assertRefactoringConditionsOK();
+ }
+
test_checkFinalConditions_hasLocalVariable_otherFunction() {
indexTestUnit('''
main() {
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index 4d96523..027c237 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -7,7 +7,6 @@
import 'dart:async';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -29,7 +28,7 @@
void setUp() {
super.setUp();
- index = createLocalMemoryIndex();
+ index = createMemoryIndex();
searchEngine = new SearchEngineImpl(index);
}
@@ -316,6 +315,6 @@
void _indexTestUnit(String code) {
resolveTestUnit(code);
- index.index(context, testUnit);
+ index.indexUnit(testUnit);
}
}
diff --git a/pkg/analysis_server/test/services/search/search_engine2_test.dart b/pkg/analysis_server/test/services/search/search_engine2_test.dart
deleted file mode 100644
index 782c892..0000000
--- a/pkg/analysis_server/test/services/search/search_engine2_test.dart
+++ /dev/null
@@ -1,714 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.services.src.search.search_engine2;
-
-import 'dart:async';
-
-import 'package:analysis_server/src/services/index2/index2.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analysis_server/src/services/search/search_engine_internal2.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_single_unit.dart';
-import '../../utils.dart';
-
-main() {
- initializeTestEnvironment();
- defineReflectiveTests(SearchEngineImpl2Test);
-}
-
-class ExpectedMatch {
- final Element element;
- final MatchKind kind;
- SourceRange range;
- final bool isResolved;
- final bool isQualified;
-
- ExpectedMatch(this.element, this.kind, int offset, int length,
- {this.isResolved: true, this.isQualified: false}) {
- this.range = new SourceRange(offset, length);
- }
-
- bool operator ==(SearchMatch match) {
- return match.element == this.element &&
- match.kind == this.kind &&
- match.isResolved == this.isResolved &&
- match.isQualified == this.isQualified &&
- match.sourceRange == this.range;
- }
-
- @override
- String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.write("ExpectedMatch(kind=");
- buffer.write(kind);
- buffer.write(", element=");
- buffer.write(element != null ? element.displayName : 'null');
- buffer.write(", range=");
- buffer.write(range);
- buffer.write(", isResolved=");
- buffer.write(isResolved);
- buffer.write(", isQualified=");
- buffer.write(isQualified);
- buffer.write(")");
- return buffer.toString();
- }
-}
-
-@reflectiveTest
-class SearchEngineImpl2Test extends AbstractSingleUnitTest {
- Index2 index;
- SearchEngineImpl2 searchEngine;
-
- void setUp() {
- super.setUp();
- index = createMemoryIndex2();
- searchEngine = new SearchEngineImpl2(context, index);
- }
-
- test_searchAllSubtypes() async {
- _indexTestUnit('''
-class T {}
-class A extends T {}
-class B extends A {}
-class C implements B {}
-''');
- ClassElement element = findElement('T');
- ClassElement elementA = findElement('A');
- ClassElement elementB = findElement('B');
- ClassElement elementC = findElement('C');
- var expected = [
- _expectId(elementA, MatchKind.DECLARATION, 'A extends T'),
- _expectId(elementB, MatchKind.DECLARATION, 'B extends A'),
- _expectId(elementC, MatchKind.DECLARATION, 'C implements B')
- ];
- List<SearchMatch> matches = await searchEngine.searchAllSubtypes(element);
- _assertMatches(matches, expected);
- }
-
- test_searchMemberDeclarations() async {
- _indexTestUnit('''
-class A {
- test() {}
-}
-class B {
- int test = 1;
- main() {
- int test = 2;
- }
-}
-''');
- ClassElement elementA = findElement('A');
- ClassElement elementB = findElement('B');
- var expected = [
- _expectId(elementA.methods[0], MatchKind.DECLARATION, 'test() {}'),
- _expectId(elementB.fields[0], MatchKind.DECLARATION, 'test = 1;')
- ];
- List<SearchMatch> matches =
- await searchEngine.searchMemberDeclarations('test');
- _assertMatches(matches, expected);
- }
-
- test_searchMemberReferences() async {
- _indexTestUnit('''
-class A {
- var test; // A
- mainA() {
- test(); // a-inv-r-nq
- test = 1; // a-ref-r-nq
- test += 2; // a-ref-r-nq
- print(test); // a-ref-r-nq
- }
-}
-main(A a, p) {
- a.test(); // a-inv-r-q
- a.test = 1; // a-ref-r-q
- a.test += 2; // a-ref-r-q
- print(a.test); // a-ref-r-q
- p.test(); // p-inv-ur-q
- p.test = 1; // p-ref-ur-q
- p.test += 2; // p-ref-ur-q
- print(p.test); // p-ref-ur-q
-}
-''');
- Element main = findElement('main');
- var expected = [
- _expectIdQ(main, MatchKind.REFERENCE, 'test(); // p-inv-ur-q'),
- _expectIdQ(main, MatchKind.REFERENCE, 'test = 1; // p-ref-ur-q'),
- _expectIdQ(main, MatchKind.REFERENCE, 'test += 2; // p-ref-ur-q'),
- _expectIdQ(main, MatchKind.REFERENCE, 'test); // p-ref-ur-q'),
- ];
- List<SearchMatch> matches =
- await searchEngine.searchMemberReferences('test');
- _assertMatches(matches, expected);
- }
-
- test_searchReferences_ClassElement() async {
- _indexTestUnit('''
-class A {}
-main(A p) {
- A v;
-}
-''');
- ClassElement element = findElement('A');
- Element pElement = findElement('p');
- Element vElement = findElement('v');
- var expected = [
- _expectId(pElement, MatchKind.REFERENCE, 'A p'),
- _expectId(vElement, MatchKind.REFERENCE, 'A v')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_CompilationUnitElement() async {
- addSource(
- '/my_part.dart',
- '''
-part of lib;
-''');
- _indexTestUnit('''
-library lib;
-part 'my_part.dart';
-''');
- CompilationUnitElement element = testLibraryElement.parts[0];
- var expected = [
- _expectIdQ(testUnitElement, MatchKind.REFERENCE, "'my_part.dart'",
- length: "'my_part.dart'".length)
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_ConstructorElement() async {
- _indexTestUnit('''
-class A {
- A.named() {}
-}
-main() {
- new A.named();
-}
-''');
- ConstructorElement element = findElement('named');
- Element mainElement = findElement('main');
- var expected = [
- _expectIdQ(mainElement, MatchKind.REFERENCE, '.named();', length: 6)
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_Element_unknown() async {
- await _verifyReferences(DynamicElementImpl.instance, []);
- }
-
- test_searchReferences_FieldElement() async {
- _indexTestUnit('''
-class A {
- var field;
- A({this.field});
- main() {
- new A(field: 1);
- // getter
- print(field); // ref-nq
- print(this.field); // ref-q
- field(); // inv-nq
- this.field(); // inv-q
- // setter
- field = 2; // ref-nq;
- this.field = 3; // ref-q;
- }
-}
-''');
- FieldElement element = findElement('field');
- Element main = findElement('main');
- Element fieldParameter = findElement('field', ElementKind.PARAMETER);
- var expected = [
- _expectIdQ(fieldParameter, MatchKind.REFERENCE, 'field}'),
- _expectIdQ(main, MatchKind.REFERENCE, 'field: 1'),
- _expectId(main, MatchKind.READ, 'field); // ref-nq'),
- _expectIdQ(main, MatchKind.READ, 'field); // ref-q'),
- _expectId(main, MatchKind.INVOCATION, 'field(); // inv-nq'),
- _expectIdQ(main, MatchKind.INVOCATION, 'field(); // inv-q'),
- _expectId(main, MatchKind.WRITE, 'field = 2; // ref-nq'),
- _expectIdQ(main, MatchKind.WRITE, 'field = 3; // ref-q'),
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_FunctionElement() async {
- _indexTestUnit('''
-test() {}
-main() {
- test();
- print(test);
-}
-''');
- FunctionElement element = findElement('test');
- Element mainElement = findElement('main');
- var expected = [
- _expectId(mainElement, MatchKind.INVOCATION, 'test();'),
- _expectId(mainElement, MatchKind.REFERENCE, 'test);')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_FunctionElement_local() async {
- _indexTestUnit('''
-main() {
- test() {}
- test();
- print(test);
-}
-''');
- FunctionElement element = findElement('test');
- Element mainElement = findElement('main');
- var expected = [
- _expectId(mainElement, MatchKind.INVOCATION, 'test();'),
- _expectId(mainElement, MatchKind.REFERENCE, 'test);')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_FunctionTypeAliasElement() async {
- _indexTestUnit('''
-typedef Test();
-main() {
- Test a;
- Test b;
-}
-''');
- FunctionTypeAliasElement element = findElement('Test');
- Element aElement = findElement('a');
- Element bElement = findElement('b');
- var expected = [
- _expectId(aElement, MatchKind.REFERENCE, 'Test a;'),
- _expectId(bElement, MatchKind.REFERENCE, 'Test b;')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_ImportElement_noPrefix() async {
- _indexTestUnit('''
-import 'dart:math';
-main() {
- print(PI);
- print(new Random());
- print(max(1, 2));
-}
-Random bar() => null;
-''');
- ImportElement element = testLibraryElement.imports[0];
- Element mainElement = findElement('main');
- Element barElement = findElement('bar');
- var kind = MatchKind.REFERENCE;
- var expected = [
- _expectId(mainElement, kind, 'PI);', length: 0),
- _expectId(mainElement, kind, 'Random()', length: 0),
- _expectId(mainElement, kind, 'max(', length: 0),
- _expectId(barElement, kind, 'Random bar()', length: 0),
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_ImportElement_withPrefix() async {
- _indexTestUnit('''
-import 'dart:math' as math;
-main() {
- print(math.PI);
- print(new math.Random());
- print(math.max(1, 2));
-}
-math.Random bar() => null;
-''');
- ImportElement element = testLibraryElement.imports[0];
- Element mainElement = findElement('main');
- Element barElement = findElement('bar');
- var kind = MatchKind.REFERENCE;
- var length = 'math.'.length;
- var expected = [
- _expectId(mainElement, kind, 'math.PI);', length: length),
- _expectId(mainElement, kind, 'math.Random()', length: length),
- _expectId(mainElement, kind, 'math.max(', length: length),
- _expectId(barElement, kind, 'math.Random bar()', length: length),
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_LabelElement() async {
- _indexTestUnit('''
-main() {
-label:
- while (true) {
- if (true) {
- break label; // 1
- }
- break label; // 2
- }
-}
-''');
- LabelElement element = findElement('label');
- Element mainElement = findElement('main');
- var expected = [
- _expectId(mainElement, MatchKind.REFERENCE, 'label; // 1'),
- _expectId(mainElement, MatchKind.REFERENCE, 'label; // 2')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_LibraryElement() async {
- var codeA = 'part of lib; // A';
- var codeB = 'part of lib; // B';
- addSource('/unitA.dart', codeA);
- addSource('/unitB.dart', codeB);
- _indexTestUnit('''
-library lib;
-part 'unitA.dart';
-part 'unitB.dart';
-''');
- LibraryElement element = testLibraryElement;
- CompilationUnitElement unitElementA = element.parts[0];
- CompilationUnitElement unitElementB = element.parts[1];
- index.indexUnit(unitElementA.computeNode());
- index.indexUnit(unitElementB.computeNode());
- var expected = [
- new ExpectedMatch(unitElementA, MatchKind.REFERENCE,
- codeA.indexOf('lib; // A'), 'lib'.length),
- new ExpectedMatch(unitElementB, MatchKind.REFERENCE,
- codeB.indexOf('lib; // B'), 'lib'.length),
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_LocalVariableElement() async {
- _indexTestUnit('''
-main() {
- var v;
- v = 1;
- v += 2;
- print(v);
- v();
-}
-''');
- LocalVariableElement element = findElement('v');
- Element mainElement = findElement('main');
- var expected = [
- _expectId(mainElement, MatchKind.WRITE, 'v = 1;'),
- _expectId(mainElement, MatchKind.READ_WRITE, 'v += 2;'),
- _expectId(mainElement, MatchKind.READ, 'v);'),
- _expectId(mainElement, MatchKind.INVOCATION, 'v();')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_MethodElement() async {
- _indexTestUnit('''
-class A {
- m() {}
- main() {
- m(); // 1
- this.m(); // 2
- print(m); // 3
- print(this.m); // 4
- }
-}
-''');
- MethodElement method = findElement('m');
- Element mainElement = findElement('main');
- var expected = [
- _expectId(mainElement, MatchKind.INVOCATION, 'm(); // 1'),
- _expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // 2'),
- _expectId(mainElement, MatchKind.REFERENCE, 'm); // 3'),
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'm); // 4')
- ];
- await _verifyReferences(method, expected);
- }
-
- test_searchReferences_MethodMember() async {
- _indexTestUnit('''
-class A<T> {
- T m() => null;
-}
-main(A<int> a) {
- a.m(); // ref
-}
-''');
- MethodMember method = findNodeElementAtString('m(); // ref');
- Element mainElement = findElement('main');
- var expected = [
- _expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // ref')
- ];
- await _verifyReferences(method, expected);
- }
-
- test_searchReferences_ParameterElement_ofLocalFunction() async {
- _indexTestUnit('''
-main() {
- foo({p}) {
- p = 1;
- p += 2;
- print(p);
- p();
- }
- foo(p: 42);
-}
-''');
- ParameterElement element = findElement('p');
- Element fooElement = findElement('foo');
- Element mainElement = findElement('main');
- var expected = [
- _expectId(fooElement, MatchKind.WRITE, 'p = 1;'),
- _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'),
- _expectId(fooElement, MatchKind.READ, 'p);'),
- _expectId(fooElement, MatchKind.INVOCATION, 'p();'),
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_ParameterElement_ofMethod() async {
- _indexTestUnit('''
-class C {
- foo({p}) {
- p = 1;
- p += 2;
- print(p);
- p();
- }
-}
-main(C c) {
- c.foo(p: 42);
-}
-''');
- ParameterElement element = findElement('p');
- Element fooElement = findElement('foo');
- Element mainElement = findElement('main');
- var expected = [
- _expectId(fooElement, MatchKind.WRITE, 'p = 1;'),
- _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'),
- _expectId(fooElement, MatchKind.READ, 'p);'),
- _expectId(fooElement, MatchKind.INVOCATION, 'p();'),
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_ParameterElement_ofTopLevelFunction() async {
- _indexTestUnit('''
-foo({p}) {
- p = 1;
- p += 2;
- print(p);
- p();
-}
-main() {
- foo(p: 42);
-}
-''');
- ParameterElement element = findElement('p');
- Element fooElement = findElement('foo');
- Element mainElement = findElement('main');
- var expected = [
- _expectId(fooElement, MatchKind.WRITE, 'p = 1;'),
- _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'),
- _expectId(fooElement, MatchKind.READ, 'p);'),
- _expectId(fooElement, MatchKind.INVOCATION, 'p();'),
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_PrefixElement() async {
- _indexTestUnit('''
-import 'dart:async' as ppp;
-main() {
- ppp.Future a;
- ppp.Stream b;
-}
-''');
- PrefixElement element = findNodeElementAtString('ppp;');
- Element elementA = findElement('a');
- Element elementB = findElement('b');
- var expected = [
- _expectId(elementA, MatchKind.REFERENCE, 'ppp.Future'),
- _expectId(elementB, MatchKind.REFERENCE, 'ppp.Stream')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_PropertyAccessorElement_getter() async {
- _indexTestUnit('''
-class A {
- get g => null;
- main() {
- g; // 1
- this.g; // 2
- }
-}
-''');
- PropertyAccessorElement element = findElement('g', ElementKind.GETTER);
- Element mainElement = findElement('main');
- var expected = [
- _expectId(mainElement, MatchKind.REFERENCE, 'g; // 1'),
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'g; // 2')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_PropertyAccessorElement_setter() async {
- _indexTestUnit('''
-class A {
- set s(x) {}
- main() {
- s = 1;
- this.s = 2;
- }
-}
-''');
- PropertyAccessorElement element = findElement('s=');
- Element mainElement = findElement('main');
- var expected = [
- _expectId(mainElement, MatchKind.REFERENCE, 's = 1'),
- _expectIdQ(mainElement, MatchKind.REFERENCE, 's = 2')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchReferences_TopLevelVariableElement() async {
- addSource(
- '/lib.dart',
- '''
-library lib;
-var V;
-''');
- _indexTestUnit('''
-import 'lib.dart' show V; // imp
-import 'lib.dart' as pref;
-main() {
- pref.V = 1; // q
- print(pref.V); // q
- pref.V(); // q
- V = 1; // nq
- print(V); // nq
- V(); // nq
-}
-''');
- ImportElement importElement = testLibraryElement.imports[0];
- CompilationUnitElement impUnit =
- importElement.importedLibrary.definingCompilationUnit;
- TopLevelVariableElement variable = impUnit.topLevelVariables[0];
- Element main = findElement('main');
- var expected = [
- _expectIdQ(testUnitElement, MatchKind.REFERENCE, 'V; // imp'),
- _expectIdQ(main, MatchKind.WRITE, 'V = 1; // q'),
- _expectIdQ(main, MatchKind.READ, 'V); // q'),
- _expectIdQ(main, MatchKind.INVOCATION, 'V(); // q'),
- _expectId(main, MatchKind.WRITE, 'V = 1; // nq'),
- _expectId(main, MatchKind.READ, 'V); // nq'),
- _expectId(main, MatchKind.INVOCATION, 'V(); // nq'),
- ];
- await _verifyReferences(variable, expected);
- }
-
- test_searchReferences_TypeParameterElement() async {
- _indexTestUnit('''
-class A<T> {
- main(T a, T b) {}
-}
-''');
- TypeParameterElement element = findElement('T');
- Element aElement = findElement('a');
- Element bElement = findElement('b');
- var expected = [
- _expectId(aElement, MatchKind.REFERENCE, 'T a'),
- _expectId(bElement, MatchKind.REFERENCE, 'T b')
- ];
- await _verifyReferences(element, expected);
- }
-
- test_searchSubtypes() async {
- _indexTestUnit('''
-class T {}
-class A extends T {} // A
-class B = Object with T; // B
-class C implements T {} // C
-''');
- ClassElement element = findElement('T');
- ClassElement elementA = findElement('A');
- ClassElement elementB = findElement('B');
- ClassElement elementC = findElement('C');
- var expected = [
- _expectId(elementA, MatchKind.REFERENCE, 'T {} // A'),
- _expectId(elementB, MatchKind.REFERENCE, 'T; // B'),
- _expectId(elementC, MatchKind.REFERENCE, 'T {} // C')
- ];
- List<SearchMatch> matches = await searchEngine.searchSubtypes(element);
- _assertMatches(matches, expected);
- }
-
- test_searchTopLevelDeclarations() async {
- _indexTestUnit('''
-class A {} // A
-class B = Object with A;
-typedef C();
-D() {}
-var E = null;
-class NoMatchABCDE {}
-''');
- Element topA = findElement('A');
- Element topB = findElement('B');
- Element topC = findElement('C');
- Element topD = findElement('D');
- Element topE = findElement('E');
- var expected = [
- _expectId(topA, MatchKind.DECLARATION, 'A {} // A'),
- _expectId(topB, MatchKind.DECLARATION, 'B ='),
- _expectId(topC, MatchKind.DECLARATION, 'C()'),
- _expectId(topD, MatchKind.DECLARATION, 'D() {}'),
- _expectId(topE, MatchKind.DECLARATION, 'E = null')
- ];
- List<SearchMatch> matches =
- await searchEngine.searchTopLevelDeclarations(r'^[A-E]$');
- _assertMatches(matches, expected);
- }
-
- ExpectedMatch _expectId(Element element, MatchKind kind, String search,
- {int length, bool isResolved: true, bool isQualified: false}) {
- int offset = findOffset(search);
- if (length == null) {
- length = getLeadingIdentifierLength(search);
- }
- return new ExpectedMatch(element, kind, offset, length,
- isResolved: isResolved, isQualified: isQualified);
- }
-
- ExpectedMatch _expectIdQ(Element element, MatchKind kind, String search,
- {int length}) {
- return _expectId(element, kind, search, isQualified: true, length: length);
- }
-
-// ExpectedMatch _expectIdU(Element element, MatchKind kind, String search) {
-// return _expectId(element, kind, search,
-// isQualified: true, isResolved: false);
-// }
-
- void _indexTestUnit(String code) {
- resolveTestUnit(code);
- index.indexUnit(testUnit);
- }
-
- Future _verifyReferences(
- Element element, List<ExpectedMatch> expectedMatches) async {
- List<SearchMatch> matches = await searchEngine.searchReferences(element);
- _assertMatches(matches, expectedMatches);
- }
-
- static void _assertMatches(
- List<SearchMatch> matches, List<ExpectedMatch> expectedMatches) {
- expect(matches, unorderedEquals(expectedMatches));
- }
-}
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index c4e757c..70caeff 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -2,12 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library test.services.src.search.search_engine;
+library test.services.src.search.search_engine_internal;
import 'dart:async';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -70,11 +69,11 @@
void setUp() {
super.setUp();
- index = createLocalMemoryIndex();
+ index = createMemoryIndex();
searchEngine = new SearchEngineImpl(index);
}
- Future test_searchAllSubtypes() {
+ test_searchAllSubtypes() async {
_indexTestUnit('''
class T {}
class A extends T {}
@@ -90,12 +89,11 @@
_expectId(elementB, MatchKind.DECLARATION, 'B extends A'),
_expectId(elementC, MatchKind.DECLARATION, 'C implements B')
];
- return searchEngine.searchAllSubtypes(element).then((matches) {
- _assertMatches(matches, expected);
- });
+ List<SearchMatch> matches = await searchEngine.searchAllSubtypes(element);
+ _assertMatches(matches, expected);
}
- Future test_searchMemberDeclarations() {
+ test_searchMemberDeclarations() async {
_indexTestUnit('''
class A {
test() {}
@@ -113,55 +111,91 @@
_expectId(elementA.methods[0], MatchKind.DECLARATION, 'test() {}'),
_expectId(elementB.fields[0], MatchKind.DECLARATION, 'test = 1;')
];
- return searchEngine.searchMemberDeclarations('test').then((matches) {
- _assertMatches(matches, expected);
- });
+ List<SearchMatch> matches =
+ await searchEngine.searchMemberDeclarations('test');
+ _assertMatches(matches, expected);
}
- Future test_searchMemberReferences() {
+ test_searchMemberReferences_qualified_resolved() async {
_indexTestUnit('''
-class A {
- var test; // A
- mainA() {
- test(); // a-inv-r-nq
- test = 1; // a-write-r-nq
- test += 2; // a-read-write-r-nq
- print(test); // a-read-r-nq
- }
+class C {
+ var test;
}
-main(A a, p) {
- a.test(); // a-inv-r-q
- a.test = 1; // a-write-r-q
- a.test += 2; // a-read-write-r-q
- print(a.test); // a-read-r-q
- p.test(); // p-inv-ur-q
- p.test = 1; // p-write-ur-q
- p.test += 2; // p-read-write-ur-q
- print(p.test); // p-read-ur-q
+main(C c) {
+ print(c.test);
+ c.test = 1;
+ c.test += 2;
+ c.test();
}
''');
- Element mainA = findElement('mainA');
- Element main = findElement('main');
- var expected = [
- _expectId(mainA, MatchKind.INVOCATION, 'test(); // a-inv-r-nq'),
- _expectId(mainA, MatchKind.WRITE, 'test = 1; // a-write-r-nq'),
- _expectId(mainA, MatchKind.READ_WRITE, 'test += 2; // a-read-write-r-nq'),
- _expectId(mainA, MatchKind.READ, 'test); // a-read-r-nq'),
- _expectIdQ(main, MatchKind.INVOCATION, 'test(); // a-inv-r-q'),
- _expectIdQ(main, MatchKind.WRITE, 'test = 1; // a-write-r-q'),
- _expectIdQ(main, MatchKind.READ_WRITE, 'test += 2; // a-read-write-r-q'),
- _expectIdQ(main, MatchKind.READ, 'test); // a-read-r-q'),
- _expectIdU(main, MatchKind.INVOCATION, 'test(); // p-inv-ur-q'),
- _expectIdU(main, MatchKind.WRITE, 'test = 1; // p-write-ur-q'),
- _expectIdU(main, MatchKind.READ_WRITE, 'test += 2; // p-read-write-ur-q'),
- _expectIdU(main, MatchKind.READ, 'test); // p-read-ur-q'),
- ];
- return searchEngine.searchMemberReferences('test').then((matches) {
- _assertMatches(matches, expected);
- });
+ List<SearchMatch> matches =
+ await searchEngine.searchMemberReferences('test');
+ expect(matches, isEmpty);
}
- Future test_searchReferences_ClassElement() {
+ test_searchMemberReferences_qualified_unresolved() async {
+ _indexTestUnit('''
+main(p) {
+ print(p.test);
+ p.test = 1;
+ p.test += 2;
+ p.test();
+}
+''');
+ Element main = findElement('main');
+ var expected = [
+ _expectIdQU(main, MatchKind.READ, 'test);'),
+ _expectIdQU(main, MatchKind.WRITE, 'test = 1;'),
+ _expectIdQU(main, MatchKind.READ_WRITE, 'test += 2;'),
+ _expectIdQU(main, MatchKind.INVOCATION, 'test();'),
+ ];
+ List<SearchMatch> matches =
+ await searchEngine.searchMemberReferences('test');
+ _assertMatches(matches, expected);
+ }
+
+ test_searchMemberReferences_unqualified_resolved() async {
+ _indexTestUnit('''
+class C {
+ var test;
+ main() {
+ print(test);
+ test = 1;
+ test += 2;
+ test();
+ }
+}
+''');
+ List<SearchMatch> matches =
+ await searchEngine.searchMemberReferences('test');
+ expect(matches, isEmpty);
+ }
+
+ test_searchMemberReferences_unqualified_unresolved() async {
+ verifyNoTestUnitErrors = false;
+ _indexTestUnit('''
+class C {
+ main() {
+ print(test);
+ test = 1;
+ test += 2;
+ test();
+ }
+}
+''');
+ Element main = findElement('main');
+ var expected = [
+ _expectIdU(main, MatchKind.READ, 'test);'),
+ _expectIdU(main, MatchKind.WRITE, 'test = 1;'),
+ _expectIdU(main, MatchKind.READ_WRITE, 'test += 2;'),
+ _expectIdU(main, MatchKind.INVOCATION, 'test();'),
+ ];
+ List<SearchMatch> matches =
+ await searchEngine.searchMemberReferences('test');
+ _assertMatches(matches, expected);
+ }
+
+ test_searchReferences_ClassElement() async {
_indexTestUnit('''
class A {}
main(A p) {
@@ -175,10 +209,10 @@
_expectId(pElement, MatchKind.REFERENCE, 'A p'),
_expectId(vElement, MatchKind.REFERENCE, 'A v')
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_CompilationUnitElement() {
+ test_searchReferences_CompilationUnitElement() async {
addSource(
'/my_part.dart',
'''
@@ -190,13 +224,13 @@
''');
CompilationUnitElement element = testLibraryElement.parts[0];
var expected = [
- _expectId(testUnitElement, MatchKind.REFERENCE, "'my_part.dart'",
+ _expectIdQ(testUnitElement, MatchKind.REFERENCE, "'my_part.dart'",
length: "'my_part.dart'".length)
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_ConstructorElement() {
+ test_searchReferences_ConstructorElement() async {
_indexTestUnit('''
class A {
A.named() {}
@@ -208,16 +242,33 @@
ConstructorElement element = findElement('named');
Element mainElement = findElement('main');
var expected = [
- _expectId(mainElement, MatchKind.REFERENCE, '.named();', length: 6)
+ _expectIdQ(mainElement, MatchKind.REFERENCE, '.named();', length: 6)
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_Element_unknown() {
- return _verifyReferences(DynamicElementImpl.instance, []);
+ test_searchReferences_ConstructorElement_synthetic() async {
+ _indexTestUnit('''
+class A {
+}
+main() {
+ new A();
+}
+''');
+ ClassElement classElement = findElement('A');
+ ConstructorElement element = classElement.unnamedConstructor;
+ Element mainElement = findElement('main');
+ var expected = [
+ _expectIdQ(mainElement, MatchKind.REFERENCE, '();', length: 0)
+ ];
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_FieldElement() {
+ test_searchReferences_Element_unknown() async {
+ await _verifyReferences(DynamicElementImpl.instance, []);
+ }
+
+ test_searchReferences_FieldElement() async {
_indexTestUnit('''
class A {
var field;
@@ -239,8 +290,8 @@
Element main = findElement('main');
Element fieldParameter = findElement('field', ElementKind.PARAMETER);
var expected = [
- _expectId(fieldParameter, MatchKind.WRITE, 'field}'),
- _expectId(main, MatchKind.REFERENCE, 'field: 1'),
+ _expectIdQ(fieldParameter, MatchKind.WRITE, 'field}'),
+ _expectIdQ(main, MatchKind.REFERENCE, 'field: 1'),
_expectId(main, MatchKind.READ, 'field); // ref-nq'),
_expectIdQ(main, MatchKind.READ, 'field); // ref-q'),
_expectId(main, MatchKind.INVOCATION, 'field(); // inv-nq'),
@@ -248,10 +299,66 @@
_expectId(main, MatchKind.WRITE, 'field = 2; // ref-nq'),
_expectIdQ(main, MatchKind.WRITE, 'field = 3; // ref-q'),
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_FunctionElement() {
+ test_searchReferences_FieldElement_ofEnum() async {
+ _indexTestUnit('''
+enum MyEnum {
+ A, B, C
+}
+main() {
+ print(MyEnum.A.index);
+ print(MyEnum.values);
+ print(MyEnum.A);
+ print(MyEnum.B);
+}
+''');
+ ClassElement enumElement = findElement('MyEnum');
+ Element mainElement = findElement('main');
+ await _verifyReferences(enumElement.getField('index'),
+ [_expectIdQ(mainElement, MatchKind.READ, 'index);')]);
+ await _verifyReferences(enumElement.getField('values'),
+ [_expectIdQ(mainElement, MatchKind.READ, 'values);')]);
+ await _verifyReferences(enumElement.getField('A'), [
+ _expectIdQ(mainElement, MatchKind.READ, 'A.index);'),
+ _expectIdQ(mainElement, MatchKind.READ, 'A);')
+ ]);
+ await _verifyReferences(enumElement.getField('B'),
+ [_expectIdQ(mainElement, MatchKind.READ, 'B);')]);
+ }
+
+ test_searchReferences_FieldElement_synthetic() async {
+ _indexTestUnit('''
+class A {
+ get field => null;
+ set field(x) {}
+ main() {
+ // getter
+ print(field); // ref-nq
+ print(this.field); // ref-q
+ field(); // inv-nq
+ this.field(); // inv-q
+ // setter
+ field = 2; // ref-nq;
+ this.field = 3; // ref-q;
+ }
+}
+''');
+ FieldElement element = findElement('field', ElementKind.FIELD);
+ Element main = findElement('main');
+ var expected = [
+ _expectId(main, MatchKind.READ, 'field); // ref-nq'),
+ _expectIdQ(main, MatchKind.READ, 'field); // ref-q'),
+ _expectId(main, MatchKind.INVOCATION, 'field(); // inv-nq'),
+ _expectIdQ(main, MatchKind.INVOCATION, 'field(); // inv-q'),
+ _expectId(main, MatchKind.WRITE, 'field = 2; // ref-nq'),
+ _expectIdQ(main, MatchKind.WRITE, 'field = 3; // ref-q'),
+ ];
+ await _verifyReferences(element, expected);
+ }
+
+ test_searchReferences_FunctionElement() async {
_indexTestUnit('''
test() {}
main() {
@@ -265,10 +372,27 @@
_expectId(mainElement, MatchKind.INVOCATION, 'test();'),
_expectId(mainElement, MatchKind.REFERENCE, 'test);')
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_FunctionTypeAliasElement() {
+ test_searchReferences_FunctionElement_local() async {
+ _indexTestUnit('''
+main() {
+ test() {}
+ test();
+ print(test);
+}
+''');
+ FunctionElement element = findElement('test');
+ Element mainElement = findElement('main');
+ var expected = [
+ _expectId(mainElement, MatchKind.INVOCATION, 'test();'),
+ _expectId(mainElement, MatchKind.REFERENCE, 'test);')
+ ];
+ await _verifyReferences(element, expected);
+ }
+
+ test_searchReferences_FunctionTypeAliasElement() async {
_indexTestUnit('''
typedef Test();
main() {
@@ -283,40 +407,59 @@
_expectId(aElement, MatchKind.REFERENCE, 'Test a;'),
_expectId(bElement, MatchKind.REFERENCE, 'Test b;')
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_ImportElement_noPrefix() {
+ test_searchReferences_ImportElement_noPrefix() async {
_indexTestUnit('''
-import 'dart:math';
+import 'dart:math' show max, PI, Random hide min;
+export 'dart:math' show max, PI, Random hide min;
main() {
- print(E);
+ print(PI);
+ print(new Random());
+ print(max(1, 2));
}
+Random bar() => null;
''');
ImportElement element = testLibraryElement.imports[0];
Element mainElement = findElement('main');
- var kind = MatchKind.REFERENCE;
- var expected = [_expectId(mainElement, kind, 'E);', length: 0)];
- return _verifyReferences(element, expected);
- }
-
- Future test_searchReferences_ImportElement_withPrefix() {
- _indexTestUnit('''
-import 'dart:math' as math;
-main() {
- print(math.PI);
-}
-''');
- ImportElement element = testLibraryElement.imports[0];
- Element mainElement = findElement('main');
+ Element barElement = findElement('bar');
var kind = MatchKind.REFERENCE;
var expected = [
- _expectId(mainElement, kind, 'math.PI);', length: 'math.'.length)
+ _expectId(mainElement, kind, 'PI);', length: 0),
+ _expectId(mainElement, kind, 'Random()', length: 0),
+ _expectId(mainElement, kind, 'max(', length: 0),
+ _expectId(barElement, kind, 'Random bar()', length: 0),
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_LabelElement() {
+ test_searchReferences_ImportElement_withPrefix() async {
+ _indexTestUnit('''
+import 'dart:math' as math show max, PI, Random hide min;
+export 'dart:math' show max, PI, Random hide min;
+main() {
+ print(math.PI);
+ print(new math.Random());
+ print(math.max(1, 2));
+}
+math.Random bar() => null;
+''');
+ ImportElement element = testLibraryElement.imports[0];
+ Element mainElement = findElement('main');
+ Element barElement = findElement('bar');
+ var kind = MatchKind.REFERENCE;
+ var length = 'math.'.length;
+ var expected = [
+ _expectId(mainElement, kind, 'math.PI);', length: length),
+ _expectId(mainElement, kind, 'math.Random()', length: length),
+ _expectId(mainElement, kind, 'math.max(', length: length),
+ _expectId(barElement, kind, 'math.Random bar()', length: length),
+ ];
+ await _verifyReferences(element, expected);
+ }
+
+ test_searchReferences_LabelElement() async {
_indexTestUnit('''
main() {
label:
@@ -334,10 +477,10 @@
_expectId(mainElement, MatchKind.REFERENCE, 'label; // 1'),
_expectId(mainElement, MatchKind.REFERENCE, 'label; // 2')
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_LibraryElement() {
+ test_searchReferences_LibraryElement() async {
var codeA = 'part of lib; // A';
var codeB = 'part of lib; // B';
addSource('/unitA.dart', codeA);
@@ -348,20 +491,20 @@
part 'unitB.dart';
''');
LibraryElement element = testLibraryElement;
- CompilationUnitElement elementA = element.parts[0];
- CompilationUnitElement elementB = element.parts[1];
- index.index(context, elementA.computeNode());
- index.index(context, elementB.computeNode());
+ CompilationUnitElement unitElementA = element.parts[0];
+ CompilationUnitElement unitElementB = element.parts[1];
+ index.indexUnit(unitElementA.computeNode());
+ index.indexUnit(unitElementB.computeNode());
var expected = [
- new ExpectedMatch(elementA, MatchKind.REFERENCE,
+ new ExpectedMatch(unitElementA, MatchKind.REFERENCE,
codeA.indexOf('lib; // A'), 'lib'.length),
- new ExpectedMatch(elementB, MatchKind.REFERENCE,
+ new ExpectedMatch(unitElementB, MatchKind.REFERENCE,
codeB.indexOf('lib; // B'), 'lib'.length),
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_LocalVariableElement() {
+ test_searchReferences_LocalVariableElement() async {
_indexTestUnit('''
main() {
var v;
@@ -379,10 +522,10 @@
_expectId(mainElement, MatchKind.READ, 'v);'),
_expectId(mainElement, MatchKind.INVOCATION, 'v();')
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_MethodElement() {
+ test_searchReferences_MethodElement() async {
_indexTestUnit('''
class A {
m() {}
@@ -402,10 +545,10 @@
_expectId(mainElement, MatchKind.REFERENCE, 'm); // 3'),
_expectIdQ(mainElement, MatchKind.REFERENCE, 'm); // 4')
];
- return _verifyReferences(method, expected);
+ await _verifyReferences(method, expected);
}
- Future test_searchReferences_MethodMember() {
+ test_searchReferences_MethodMember() async {
_indexTestUnit('''
class A<T> {
T m() => null;
@@ -419,10 +562,92 @@
var expected = [
_expectIdQ(mainElement, MatchKind.INVOCATION, 'm(); // ref')
];
- return _verifyReferences(method, expected);
+ await _verifyReferences(method, expected);
}
- Future test_searchReferences_ParameterElement() {
+ test_searchReferences_ParameterElement_ofConstructor() async {
+ _indexTestUnit('''
+class C {
+ var f;
+ C({p}) : f = p + 1 {
+ p = 2;
+ p += 3;
+ print(p);
+ p();
+ }
+}
+main() {
+ new C(p: 42);
+}
+''');
+ ParameterElement element = findElement('p');
+ ClassElement classC = findElement('C');
+ ConstructorElement constructorA = classC.unnamedConstructor;
+ Element mainElement = findElement('main');
+ var expected = [
+ _expectId(constructorA, MatchKind.READ, 'p + 1 {'),
+ _expectId(constructorA, MatchKind.WRITE, 'p = 2;'),
+ _expectId(constructorA, MatchKind.READ_WRITE, 'p += 3;'),
+ _expectId(constructorA, MatchKind.READ, 'p);'),
+ _expectId(constructorA, MatchKind.INVOCATION, 'p();'),
+ _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42')
+ ];
+ await _verifyReferences(element, expected);
+ }
+
+ test_searchReferences_ParameterElement_ofLocalFunction() async {
+ _indexTestUnit('''
+main() {
+ foo({p}) {
+ p = 1;
+ p += 2;
+ print(p);
+ p();
+ }
+ foo(p: 42);
+}
+''');
+ ParameterElement element = findElement('p');
+ Element fooElement = findElement('foo');
+ Element mainElement = findElement('main');
+ var expected = [
+ _expectId(fooElement, MatchKind.WRITE, 'p = 1;'),
+ _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'),
+ _expectId(fooElement, MatchKind.READ, 'p);'),
+ _expectId(fooElement, MatchKind.INVOCATION, 'p();'),
+ _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42')
+ ];
+ await _verifyReferences(element, expected);
+ }
+
+ test_searchReferences_ParameterElement_ofMethod() async {
+ _indexTestUnit('''
+class C {
+ foo({p}) {
+ p = 1;
+ p += 2;
+ print(p);
+ p();
+ }
+}
+main(C c) {
+ c.foo(p: 42);
+}
+''');
+ ParameterElement element = findElement('p');
+ Element fooElement = findElement('foo');
+ Element mainElement = findElement('main');
+ var expected = [
+ _expectId(fooElement, MatchKind.WRITE, 'p = 1;'),
+ _expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'),
+ _expectId(fooElement, MatchKind.READ, 'p);'),
+ _expectId(fooElement, MatchKind.INVOCATION, 'p();'),
+ _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42')
+ ];
+ await _verifyReferences(element, expected);
+ }
+
+ test_searchReferences_ParameterElement_ofTopLevelFunction() async {
_indexTestUnit('''
foo({p}) {
p = 1;
@@ -442,12 +667,12 @@
_expectId(fooElement, MatchKind.READ_WRITE, 'p += 2;'),
_expectId(fooElement, MatchKind.READ, 'p);'),
_expectId(fooElement, MatchKind.INVOCATION, 'p();'),
- _expectId(mainElement, MatchKind.REFERENCE, 'p: 42')
+ _expectIdQ(mainElement, MatchKind.REFERENCE, 'p: 42')
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_PrefixElement() {
+ test_searchReferences_PrefixElement() async {
_indexTestUnit('''
import 'dart:async' as ppp;
main() {
@@ -462,29 +687,33 @@
_expectId(elementA, MatchKind.REFERENCE, 'ppp.Future'),
_expectId(elementB, MatchKind.REFERENCE, 'ppp.Stream')
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_PropertyAccessorElement_getter() {
+ test_searchReferences_PropertyAccessorElement_getter() async {
_indexTestUnit('''
class A {
- get g => null;
+ get ggg => null;
main() {
- g; // 1
- this.g; // 2
+ print(ggg); // ref-nq
+ print(this.ggg); // ref-q
+ ggg(); // inv-nq
+ this.ggg(); // inv-q
}
}
''');
- PropertyAccessorElement element = findElement('g', ElementKind.GETTER);
- Element mainElement = findElement('main');
+ PropertyAccessorElement element = findElement('ggg', ElementKind.GETTER);
+ Element main = findElement('main');
var expected = [
- _expectId(mainElement, MatchKind.REFERENCE, 'g; // 1'),
- _expectIdQ(mainElement, MatchKind.REFERENCE, 'g; // 2')
+ _expectId(main, MatchKind.REFERENCE, 'ggg); // ref-nq'),
+ _expectIdQ(main, MatchKind.REFERENCE, 'ggg); // ref-q'),
+ _expectId(main, MatchKind.INVOCATION, 'ggg(); // inv-nq'),
+ _expectIdQ(main, MatchKind.INVOCATION, 'ggg(); // inv-q'),
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_PropertyAccessorElement_setter() {
+ test_searchReferences_PropertyAccessorElement_setter() async {
_indexTestUnit('''
class A {
set s(x) {}
@@ -500,10 +729,10 @@
_expectId(mainElement, MatchKind.REFERENCE, 's = 1'),
_expectIdQ(mainElement, MatchKind.REFERENCE, 's = 2')
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchReferences_TopLevelVariableElement() {
+ test_searchReferences_TopLevelVariableElement() async {
addSource(
'/lib.dart',
'''
@@ -528,18 +757,18 @@
TopLevelVariableElement variable = impUnit.topLevelVariables[0];
Element main = findElement('main');
var expected = [
- _expectId(testUnitElement, MatchKind.REFERENCE, 'V; // imp'),
- _expectId(main, MatchKind.WRITE, 'V = 1; // q'),
- _expectId(main, MatchKind.READ, 'V); // q'),
- _expectId(main, MatchKind.INVOCATION, 'V(); // q'),
+ _expectIdQ(testUnitElement, MatchKind.REFERENCE, 'V; // imp'),
+ _expectIdQ(main, MatchKind.WRITE, 'V = 1; // q'),
+ _expectIdQ(main, MatchKind.READ, 'V); // q'),
+ _expectIdQ(main, MatchKind.INVOCATION, 'V(); // q'),
_expectId(main, MatchKind.WRITE, 'V = 1; // nq'),
_expectId(main, MatchKind.READ, 'V); // nq'),
_expectId(main, MatchKind.INVOCATION, 'V(); // nq'),
];
- return _verifyReferences(variable, expected);
+ await _verifyReferences(variable, expected);
}
- Future test_searchReferences_TypeParameterElement() {
+ test_searchReferences_TypeParameterElement() async {
_indexTestUnit('''
class A<T> {
main(T a, T b) {}
@@ -552,10 +781,10 @@
_expectId(aElement, MatchKind.REFERENCE, 'T a'),
_expectId(bElement, MatchKind.REFERENCE, 'T b')
];
- return _verifyReferences(element, expected);
+ await _verifyReferences(element, expected);
}
- Future test_searchSubtypes() {
+ test_searchSubtypes() async {
_indexTestUnit('''
class T {}
class A extends T {} // A
@@ -571,12 +800,11 @@
_expectId(elementB, MatchKind.REFERENCE, 'T; // B'),
_expectId(elementC, MatchKind.REFERENCE, 'T {} // C')
];
- return searchEngine.searchSubtypes(element).then((matches) {
- _assertMatches(matches, expected);
- });
+ List<SearchMatch> matches = await searchEngine.searchSubtypes(element);
+ _assertMatches(matches, expected);
}
- Future test_searchTopLevelDeclarations() {
+ test_searchTopLevelDeclarations() async {
_indexTestUnit('''
class A {} // A
class B = Object with A;
@@ -597,7 +825,9 @@
_expectId(topD, MatchKind.DECLARATION, 'D() {}'),
_expectId(topE, MatchKind.DECLARATION, 'E = null')
];
- return _verifyTopLevelDeclarations('^[A-E]\$', expected);
+ List<SearchMatch> matches =
+ await searchEngine.searchTopLevelDeclarations(r'^[A-E]$');
+ _assertMatches(matches, expected);
}
ExpectedMatch _expectId(Element element, MatchKind kind, String search,
@@ -610,36 +840,42 @@
isResolved: isResolved, isQualified: isQualified);
}
- ExpectedMatch _expectIdQ(Element element, MatchKind kind, String search) {
- return _expectId(element, kind, search, isQualified: true);
+ /**
+ * Create [ExpectedMatch] for a qualified and resolved match.
+ */
+ ExpectedMatch _expectIdQ(Element element, MatchKind kind, String search,
+ {int length, bool isResolved: true}) {
+ return _expectId(element, kind, search, isQualified: true, length: length);
}
- ExpectedMatch _expectIdU(Element element, MatchKind kind, String search) {
+ /**
+ * Create [ExpectedMatch] for a qualified and unresolved match.
+ */
+ ExpectedMatch _expectIdQU(Element element, MatchKind kind, String search,
+ {int length}) {
return _expectId(element, kind, search,
- isQualified: true, isResolved: false);
+ isQualified: true, isResolved: false, length: length);
+ }
+
+ /**
+ * Create [ExpectedMatch] for a unqualified and unresolved match.
+ */
+ ExpectedMatch _expectIdU(Element element, MatchKind kind, String search,
+ {int length}) {
+ return _expectId(element, kind, search,
+ isQualified: false, isResolved: false, length: length);
}
void _indexTestUnit(String code) {
resolveTestUnit(code);
- index.index(context, testUnit);
+ index.indexUnit(testUnit);
}
Future _verifyReferences(
- Element element, List<ExpectedMatch> expectedMatches) {
- return searchEngine
- .searchReferences(element)
- .then((List<SearchMatch> matches) {
- _assertMatches(matches, expectedMatches);
- });
- }
-
- Future _verifyTopLevelDeclarations(
- String pattern, List<ExpectedMatch> expectedMatches) {
- return searchEngine
- .searchTopLevelDeclarations(pattern)
- .then((List<SearchMatch> matches) {
- _assertMatches(matches, expectedMatches);
- });
+ Element element, List<ExpectedMatch> expectedMatches) async {
+ List<SearchMatch> matches = await searchEngine.searchReferences(element);
+ _assertMatches(matches, expectedMatches);
+ expect(matches, hasLength(expectedMatches.length));
}
static void _assertMatches(
diff --git a/pkg/analysis_server/test/services/search/test_all.dart b/pkg/analysis_server/test/services/search/test_all.dart
index 513c397..187d3f3 100644
--- a/pkg/analysis_server/test/services/search/test_all.dart
+++ b/pkg/analysis_server/test/services/search/test_all.dart
@@ -8,7 +8,6 @@
import '../../utils.dart';
import 'hierarchy_test.dart' as hierarchy_test;
-import 'search_engine2_test.dart' as search_engine2_test;
import 'search_engine_test.dart' as search_engine_test;
/**
@@ -18,7 +17,6 @@
initializeTestEnvironment();
group('search', () {
hierarchy_test.main();
- search_engine2_test.main();
search_engine_test.main();
});
}
diff --git a/pkg/analysis_server/test/services/test_all.dart b/pkg/analysis_server/test/services/test_all.dart
index 6373800..e0c2086 100644
--- a/pkg/analysis_server/test/services/test_all.dart
+++ b/pkg/analysis_server/test/services/test_all.dart
@@ -9,7 +9,6 @@
import 'correction/test_all.dart' as correction_all;
import 'dependencies/test_all.dart' as dependencies_all;
import 'index/test_all.dart' as index_all;
-import 'index2/test_all.dart' as index2_all;
import 'linter/linter_test.dart' as linter_all;
import 'refactoring/test_all.dart' as refactoring_all;
import 'search/test_all.dart' as search_all;
@@ -21,7 +20,6 @@
correction_all.main();
dependencies_all.main();
index_all.main();
- index2_all.main();
linter_all.main();
refactoring_all.main();
search_all.main();
diff --git a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
index 3d4f6ae..e8fdbee 100644
--- a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
+++ b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
@@ -7,7 +7,7 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/provisional/edit/utilities/change_builder_dart.dart';
import 'package:analysis_server/src/utilities/change_builder_dart.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
index 9020207..00c4495 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisError.java
@@ -72,6 +72,11 @@
private final String correction;
/**
+ * The name, as a string, of the error code associated with this error.
+ */
+ private final String code;
+
+ /**
* A hint to indicate to interested clients that this error has an associated fix (or fixes). The
* absence of this field implies there are not known to be fixes. Note that since the operation to
* calculate whether fixes apply needs to be performant it is possible that complicated tests will
@@ -85,12 +90,13 @@
/**
* Constructor for {@link AnalysisError}.
*/
- public AnalysisError(String severity, String type, Location location, String message, String correction, Boolean hasFix) {
+ public AnalysisError(String severity, String type, Location location, String message, String correction, String code, Boolean hasFix) {
this.severity = severity;
this.type = type;
this.location = location;
this.message = message;
this.correction = correction;
+ this.code = code;
this.hasFix = hasFix;
}
@@ -104,6 +110,7 @@
ObjectUtilities.equals(other.location, location) &&
ObjectUtilities.equals(other.message, message) &&
ObjectUtilities.equals(other.correction, correction) &&
+ ObjectUtilities.equals(other.code, code) &&
ObjectUtilities.equals(other.hasFix, hasFix);
}
return false;
@@ -115,8 +122,9 @@
Location location = Location.fromJson(jsonObject.get("location").getAsJsonObject());
String message = jsonObject.get("message").getAsString();
String correction = jsonObject.get("correction") == null ? null : jsonObject.get("correction").getAsString();
+ String code = jsonObject.get("code").getAsString();
Boolean hasFix = jsonObject.get("hasFix") == null ? null : jsonObject.get("hasFix").getAsBoolean();
- return new AnalysisError(severity, type, location, message, correction, hasFix);
+ return new AnalysisError(severity, type, location, message, correction, code, hasFix);
}
public static List<AnalysisError> fromJsonArray(JsonArray jsonArray) {
@@ -132,6 +140,13 @@
}
/**
+ * The name, as a string, of the error code associated with this error.
+ */
+ public String getCode() {
+ return code;
+ }
+
+ /**
* The correction message to be displayed for this error. The correction message should indicate
* how the user can fix the error. The field is omitted if there is no correction message
* associated with the error code.
@@ -190,6 +205,7 @@
builder.append(location);
builder.append(message);
builder.append(correction);
+ builder.append(code);
builder.append(hasFix);
return builder.toHashCode();
}
@@ -203,6 +219,7 @@
if (correction != null) {
jsonObject.addProperty("correction", correction);
}
+ jsonObject.addProperty("code", code);
if (hasFix != null) {
jsonObject.addProperty("hasFix", hasFix);
}
@@ -223,6 +240,8 @@
builder.append(message + ", ");
builder.append("correction=");
builder.append(correction + ", ");
+ builder.append("code=");
+ builder.append(code + ", ");
builder.append("hasFix=");
builder.append(hasFix);
builder.append("]");
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index fa4664f..644a1a9 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -6,7 +6,7 @@
</head>
<body>
<h1>Analysis Server API Specification</h1>
- <h1 style="color:#999999">Version <version>1.14.0</version></h1>
+ <h1 style="color:#999999">Version <version>1.15.0</version></h1>
<p>
This document contains a specification of the API provided by the
analysis server. The API in this document is currently under
@@ -2088,6 +2088,12 @@
message associated with the error code.
</p>
</field>
+ <field name="code">
+ <ref>String</ref>
+ <p>
+ The name, as a string, of the error code associated with this error.
+ </p>
+ </field>
<field name="hasFix" optional="true">
<ref>bool</ref>
<p>
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index 5cbc96a..0454992 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -77,7 +77,6 @@
/// [suppressErrors] is `true`, in which case any errors are discarded.
CompilationUnit parseDirectives(String contents,
{String name, bool suppressErrors: false}) {
- if (name == null) name = '<unknown source>';
var source = new StringSource(contents, name);
var errorCollector = new _ErrorCollector();
var reader = new CharSequenceReader(contents);
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index f76fb1d..f387048 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -895,6 +895,893 @@
}
/**
+ * An AST Visitor that captures visit call timings.
+ */
+class TimedAstVisitor<T> implements AstVisitor<T> {
+ /**
+ * The base visitor whose visit methods will be timed.
+ */
+ final AstVisitor<T> _baseVisitor;
+
+ /**
+ * Collects elapsed time for visit calls.
+ */
+ final Stopwatch stopwatch;
+
+ /**
+ * Initialize a newly created visitor to time calls to the given base
+ * visitor's visits.
+ */
+ TimedAstVisitor(this._baseVisitor, [Stopwatch watch])
+ : stopwatch = watch ?? new Stopwatch();
+
+ @override
+ T visitAdjacentStrings(AdjacentStrings node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitAdjacentStrings(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitAnnotation(Annotation node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitAnnotation(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitArgumentList(ArgumentList node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitArgumentList(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitAsExpression(AsExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitAsExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitAssertStatement(AssertStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitAssertStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitAssignmentExpression(AssignmentExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitAssignmentExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitAwaitExpression(AwaitExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitAwaitExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitBinaryExpression(BinaryExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitBinaryExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitBlock(Block node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitBlock(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitBlockFunctionBody(BlockFunctionBody node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitBlockFunctionBody(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitBooleanLiteral(BooleanLiteral node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitBooleanLiteral(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitBreakStatement(BreakStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitBreakStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitCascadeExpression(CascadeExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitCascadeExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitCatchClause(CatchClause node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitCatchClause(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitClassDeclaration(ClassDeclaration node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitClassDeclaration(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitClassTypeAlias(ClassTypeAlias node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitClassTypeAlias(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitComment(Comment node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitComment(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitCommentReference(CommentReference node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitCommentReference(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitCompilationUnit(CompilationUnit node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitCompilationUnit(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitConditionalExpression(ConditionalExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitConditionalExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitConfiguration(Configuration node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitConfiguration(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitConstructorDeclaration(ConstructorDeclaration node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitConstructorDeclaration(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitConstructorFieldInitializer(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitConstructorName(ConstructorName node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitConstructorName(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitContinueStatement(ContinueStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitContinueStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitDeclaredIdentifier(DeclaredIdentifier node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitDeclaredIdentifier(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitDefaultFormalParameter(DefaultFormalParameter node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitDefaultFormalParameter(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitDoStatement(DoStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitDoStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitDottedName(DottedName node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitDottedName(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitDoubleLiteral(DoubleLiteral node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitDoubleLiteral(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitEmptyFunctionBody(EmptyFunctionBody node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitEmptyFunctionBody(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitEmptyStatement(EmptyStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitEmptyStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitEnumConstantDeclaration(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitEnumDeclaration(EnumDeclaration node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitEnumDeclaration(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitExportDirective(ExportDirective node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitExportDirective(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitExpressionFunctionBody(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitExpressionStatement(ExpressionStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitExpressionStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitExtendsClause(ExtendsClause node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitExtendsClause(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitFieldDeclaration(FieldDeclaration node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitFieldDeclaration(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitFieldFormalParameter(FieldFormalParameter node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitFieldFormalParameter(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitForEachStatement(ForEachStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitForEachStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitFormalParameterList(FormalParameterList node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitFormalParameterList(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitForStatement(ForStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitForStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitFunctionDeclaration(FunctionDeclaration node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitFunctionDeclaration(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitFunctionDeclarationStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitFunctionExpression(FunctionExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitFunctionExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitFunctionExpressionInvocation(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitFunctionTypeAlias(FunctionTypeAlias node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitFunctionTypeAlias(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitFunctionTypedFormalParameter(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitHideCombinator(HideCombinator node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitHideCombinator(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitIfStatement(IfStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitIfStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitImplementsClause(ImplementsClause node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitImplementsClause(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitImportDirective(ImportDirective node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitImportDirective(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitIndexExpression(IndexExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitIndexExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitInstanceCreationExpression(InstanceCreationExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitInstanceCreationExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitIntegerLiteral(IntegerLiteral node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitIntegerLiteral(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitInterpolationExpression(InterpolationExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitInterpolationExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitInterpolationString(InterpolationString node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitInterpolationString(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitIsExpression(IsExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitIsExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitLabel(Label node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitLabel(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitLabeledStatement(LabeledStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitLabeledStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitLibraryDirective(LibraryDirective node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitLibraryDirective(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitLibraryIdentifier(LibraryIdentifier node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitLibraryIdentifier(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitListLiteral(ListLiteral node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitListLiteral(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitMapLiteral(MapLiteral node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitMapLiteral(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitMapLiteralEntry(MapLiteralEntry node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitMapLiteralEntry(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitMethodDeclaration(MethodDeclaration node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitMethodDeclaration(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitMethodInvocation(MethodInvocation node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitMethodInvocation(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitNamedExpression(NamedExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitNamedExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitNativeClause(NativeClause node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitNativeClause(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitNativeFunctionBody(NativeFunctionBody node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitNativeFunctionBody(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitNullLiteral(NullLiteral node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitNullLiteral(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitParenthesizedExpression(ParenthesizedExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitParenthesizedExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitPartDirective(PartDirective node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitPartDirective(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitPartOfDirective(PartOfDirective node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitPartOfDirective(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitPostfixExpression(PostfixExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitPostfixExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitPrefixedIdentifier(PrefixedIdentifier node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitPrefixedIdentifier(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitPrefixExpression(PrefixExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitPrefixExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitPropertyAccess(PropertyAccess node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitPropertyAccess(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitRedirectingConstructorInvocation(
+ RedirectingConstructorInvocation node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitRedirectingConstructorInvocation(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitRethrowExpression(RethrowExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitRethrowExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitReturnStatement(ReturnStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitReturnStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitScriptTag(ScriptTag node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitScriptTag(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitShowCombinator(ShowCombinator node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitShowCombinator(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitSimpleFormalParameter(SimpleFormalParameter node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitSimpleFormalParameter(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitSimpleIdentifier(SimpleIdentifier node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitSimpleIdentifier(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitSimpleStringLiteral(SimpleStringLiteral node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitSimpleStringLiteral(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitStringInterpolation(StringInterpolation node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitStringInterpolation(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitSuperConstructorInvocation(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitSuperExpression(SuperExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitSuperExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitSwitchCase(SwitchCase node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitSwitchCase(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitSwitchDefault(SwitchDefault node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitSwitchDefault(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitSwitchStatement(SwitchStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitSwitchStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitSymbolLiteral(SymbolLiteral node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitSymbolLiteral(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitThisExpression(ThisExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitThisExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitThrowExpression(ThrowExpression node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitThrowExpression(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitTopLevelVariableDeclaration(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitTryStatement(TryStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitTryStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitTypeArgumentList(TypeArgumentList node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitTypeArgumentList(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitTypeName(TypeName node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitTypeName(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitTypeParameter(TypeParameter node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitTypeParameter(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitTypeParameterList(TypeParameterList node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitTypeParameterList(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitVariableDeclaration(VariableDeclaration node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitVariableDeclaration(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitVariableDeclarationList(VariableDeclarationList node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitVariableDeclarationList(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitVariableDeclarationStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitWhileStatement(WhileStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitWhileStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitWithClause(WithClause node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitWithClause(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
+ T visitYieldStatement(YieldStatement node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitYieldStatement(node);
+ stopwatch.stop();
+ return result;
+ }
+}
+
+/**
* An AST visitor that will recursively visit all of the nodes in an AST
* structure (like instances of the class [RecursiveAstVisitor]). In addition,
* when a node of a specific type is visited not only will the visit method for
diff --git a/pkg/analyzer/lib/source/error_processor.dart b/pkg/analyzer/lib/source/error_processor.dart
index 8e369aa..6b69cb7 100644
--- a/pkg/analyzer/lib/source/error_processor.dart
+++ b/pkg/analyzer/lib/source/error_processor.dart
@@ -93,9 +93,37 @@
if (context == null) {
return null;
}
+
+ // By default, the error is not processed.
+ ErrorProcessor processor;
+
+ // Give strong mode a chance to upgrade it.
+ if (context.analysisOptions.strongMode) {
+ processor = _StrongModeTypeErrorProcessor.instance;
+ }
+
+ // Let the user configure how specific errors are processed.
List<ErrorProcessor> processors =
context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+
return processors.firstWhere((ErrorProcessor p) => p.appliesTo(error),
- orElse: () => null);
+ orElse: () => processor);
}
}
+
+/// In strong mode, this upgrades static type warnings to errors.
+class _StrongModeTypeErrorProcessor implements ErrorProcessor {
+ static final instance = new _StrongModeTypeErrorProcessor();
+
+ // TODO(rnystrom): As far as I know, this is only used to implement
+ // appliesTo(). Consider making it private in ErrorProcessor if possible.
+ String get code => throw new UnsupportedError(
+ "_StrongModeTypeErrorProcessor is not specific to an error code.");
+
+ /// In strong mode, type warnings are upgraded to errors.
+ ErrorSeverity get severity => ErrorSeverity.ERROR;
+
+ /// Check if this processor applies to the given [error].
+ bool appliesTo(AnalysisError error) =>
+ error.errorCode.type == ErrorType.STATIC_TYPE_WARNING;
+}
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index dbbba10..331d6d9 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -3690,8 +3690,6 @@
}
try {
node.accept(this);
- } on NodeLocator_NodeFoundException {
- // A node with the right source position was found.
} catch (exception, stackTrace) {
AnalysisEngine.instance.logger.logInformation(
"Unable to locate element at offset ($_startOffset - $_endOffset)",
@@ -3703,6 +3701,11 @@
@override
Object visitNode(AstNode node) {
+ // Don't visit a new tree if the result has been already found.
+ if (_foundNode != null) {
+ return null;
+ }
+ // Check whether the current node covers the selection.
Token beginToken = node.beginToken;
Token endToken = node.endToken;
// Don't include synthetic tokens.
@@ -3720,10 +3723,9 @@
if (start > _endOffset) {
return null;
}
+ // Check children.
try {
node.visitChildren(this);
- } on NodeLocator_NodeFoundException {
- rethrow;
} catch (exception, stackTrace) {
// Ignore the exception and proceed in order to visit the rest of the
// structure.
@@ -3731,9 +3733,13 @@
"Exception caught while traversing an AST structure.",
new CaughtException(exception, stackTrace));
}
+ // Found a child.
+ if (_foundNode != null) {
+ return null;
+ }
+ // Check this node.
if (start <= _startOffset && _endOffset <= end) {
_foundNode = node;
- throw new NodeLocator_NodeFoundException();
}
return null;
}
@@ -3781,7 +3787,7 @@
}
try {
node.accept(this);
- } on NodeLocator_NodeFoundException {} catch (exception, stackTrace) {
+ } catch (exception, stackTrace) {
AnalysisEngine.instance.logger.logInformation(
"Unable to locate element at offset ($_startOffset - $_endOffset)",
new CaughtException(exception, stackTrace));
@@ -3792,6 +3798,11 @@
@override
Object visitNode(AstNode node) {
+ // Don't visit a new tree if the result has been already found.
+ if (_foundNode != null) {
+ return null;
+ }
+ // Check whether the current node covers the selection.
Token beginToken = node.beginToken;
Token endToken = node.endToken;
// Don't include synthetic tokens.
@@ -3809,10 +3820,9 @@
if (start > _endOffset) {
return null;
}
+ // Check children.
try {
node.visitChildren(this);
- } on NodeLocator_NodeFoundException {
- rethrow;
} catch (exception, stackTrace) {
// Ignore the exception and proceed in order to visit the rest of the
// structure.
@@ -3820,21 +3830,19 @@
"Exception caught while traversing an AST structure.",
new CaughtException(exception, stackTrace));
}
+ // Found a child.
+ if (_foundNode != null) {
+ return null;
+ }
+ // Check this node.
if (start <= _startOffset && _endOffset < end) {
_foundNode = node;
- throw new NodeLocator_NodeFoundException();
}
return null;
}
}
/**
- * An exception used by [NodeLocator] to cancel visiting after a node has been
- * found.
- */
-class NodeLocator_NodeFoundException extends RuntimeException {}
-
-/**
* An object that will replace one child node in an AST node with another node.
*/
class NodeReplacer implements AstVisitor<bool> {
@@ -5028,6 +5036,1426 @@
}
/**
+ * An object that copies resolution information from one AST structure to
+ * another as long as the structures of the corresponding children of a pair of
+ * nodes are the same.
+ */
+class ResolutionCopier implements AstVisitor<bool> {
+ /**
+ * The AST node with which the node being visited is to be compared. This is
+ * only valid at the beginning of each visit method (until [isEqualNodes] is
+ * invoked).
+ */
+ AstNode _toNode;
+
+ @override
+ bool visitAdjacentStrings(AdjacentStrings node) {
+ AdjacentStrings toNode = this._toNode as AdjacentStrings;
+ if (_isEqualNodeLists(node.strings, toNode.strings)) {
+ toNode.staticType = node.staticType;
+ toNode.propagatedType = node.propagatedType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitAnnotation(Annotation node) {
+ Annotation toNode = this._toNode as Annotation;
+ if (_and(
+ _isEqualTokens(node.atSign, toNode.atSign),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualTokens(node.period, toNode.period),
+ _isEqualNodes(node.constructorName, toNode.constructorName),
+ _isEqualNodes(node.arguments, toNode.arguments))) {
+ toNode.element = node.element;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitArgumentList(ArgumentList node) {
+ ArgumentList toNode = this._toNode as ArgumentList;
+ return _and(
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodeLists(node.arguments, toNode.arguments),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis));
+ }
+
+ @override
+ bool visitAsExpression(AsExpression node) {
+ AsExpression toNode = this._toNode as AsExpression;
+ if (_and(
+ _isEqualNodes(node.expression, toNode.expression),
+ _isEqualTokens(node.asOperator, toNode.asOperator),
+ _isEqualNodes(node.type, toNode.type))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitAssertStatement(AssertStatement node) {
+ AssertStatement toNode = this._toNode as AssertStatement;
+ return _and(
+ _isEqualTokens(node.assertKeyword, toNode.assertKeyword),
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.condition, toNode.condition),
+ _isEqualTokens(node.comma, toNode.comma),
+ _isEqualNodes(node.message, toNode.message),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitAssignmentExpression(AssignmentExpression node) {
+ AssignmentExpression toNode = this._toNode as AssignmentExpression;
+ if (_and(
+ _isEqualNodes(node.leftHandSide, toNode.leftHandSide),
+ _isEqualTokens(node.operator, toNode.operator),
+ _isEqualNodes(node.rightHandSide, toNode.rightHandSide))) {
+ toNode.propagatedElement = node.propagatedElement;
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticElement = node.staticElement;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitAwaitExpression(AwaitExpression node) {
+ AwaitExpression toNode = this._toNode as AwaitExpression;
+ if (_and(_isEqualTokens(node.awaitKeyword, toNode.awaitKeyword),
+ _isEqualNodes(node.expression, toNode.expression))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitBinaryExpression(BinaryExpression node) {
+ BinaryExpression toNode = this._toNode as BinaryExpression;
+ if (_and(
+ _isEqualNodes(node.leftOperand, toNode.leftOperand),
+ _isEqualTokens(node.operator, toNode.operator),
+ _isEqualNodes(node.rightOperand, toNode.rightOperand))) {
+ toNode.propagatedElement = node.propagatedElement;
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticElement = node.staticElement;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitBlock(Block node) {
+ Block toNode = this._toNode as Block;
+ return _and(
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodeLists(node.statements, toNode.statements),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket));
+ }
+
+ @override
+ bool visitBlockFunctionBody(BlockFunctionBody node) {
+ BlockFunctionBody toNode = this._toNode as BlockFunctionBody;
+ return _isEqualNodes(node.block, toNode.block);
+ }
+
+ @override
+ bool visitBooleanLiteral(BooleanLiteral node) {
+ BooleanLiteral toNode = this._toNode as BooleanLiteral;
+ if (_and(_isEqualTokens(node.literal, toNode.literal),
+ node.value == toNode.value)) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitBreakStatement(BreakStatement node) {
+ BreakStatement toNode = this._toNode as BreakStatement;
+ if (_and(
+ _isEqualTokens(node.breakKeyword, toNode.breakKeyword),
+ _isEqualNodes(node.label, toNode.label),
+ _isEqualTokens(node.semicolon, toNode.semicolon))) {
+ // TODO(paulberry): map node.target to toNode.target.
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitCascadeExpression(CascadeExpression node) {
+ CascadeExpression toNode = this._toNode as CascadeExpression;
+ if (_and(_isEqualNodes(node.target, toNode.target),
+ _isEqualNodeLists(node.cascadeSections, toNode.cascadeSections))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitCatchClause(CatchClause node) {
+ CatchClause toNode = this._toNode as CatchClause;
+ return _and(
+ _isEqualTokens(node.onKeyword, toNode.onKeyword),
+ _isEqualNodes(node.exceptionType, toNode.exceptionType),
+ _isEqualTokens(node.catchKeyword, toNode.catchKeyword),
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.exceptionParameter, toNode.exceptionParameter),
+ _isEqualTokens(node.comma, toNode.comma),
+ _isEqualNodes(node.stackTraceParameter, toNode.stackTraceParameter),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+ _isEqualNodes(node.body, toNode.body));
+ }
+
+ @override
+ bool visitClassDeclaration(ClassDeclaration node) {
+ ClassDeclaration toNode = this._toNode as ClassDeclaration;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.abstractKeyword, toNode.abstractKeyword),
+ _isEqualTokens(node.classKeyword, toNode.classKeyword),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualNodes(node.typeParameters, toNode.typeParameters),
+ _isEqualNodes(node.extendsClause, toNode.extendsClause),
+ _isEqualNodes(node.withClause, toNode.withClause),
+ _isEqualNodes(node.implementsClause, toNode.implementsClause),
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodeLists(node.members, toNode.members),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket));
+ }
+
+ @override
+ bool visitClassTypeAlias(ClassTypeAlias node) {
+ ClassTypeAlias toNode = this._toNode as ClassTypeAlias;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.typedefKeyword, toNode.typedefKeyword),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualNodes(node.typeParameters, toNode.typeParameters),
+ _isEqualTokens(node.equals, toNode.equals),
+ _isEqualTokens(node.abstractKeyword, toNode.abstractKeyword),
+ _isEqualNodes(node.superclass, toNode.superclass),
+ _isEqualNodes(node.withClause, toNode.withClause),
+ _isEqualNodes(node.implementsClause, toNode.implementsClause),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitComment(Comment node) {
+ Comment toNode = this._toNode as Comment;
+ return _isEqualNodeLists(node.references, toNode.references);
+ }
+
+ @override
+ bool visitCommentReference(CommentReference node) {
+ CommentReference toNode = this._toNode as CommentReference;
+ return _and(_isEqualTokens(node.newKeyword, toNode.newKeyword),
+ _isEqualNodes(node.identifier, toNode.identifier));
+ }
+
+ @override
+ bool visitCompilationUnit(CompilationUnit node) {
+ CompilationUnit toNode = this._toNode as CompilationUnit;
+ if (_and(
+ _isEqualTokens(node.beginToken, toNode.beginToken),
+ _isEqualNodes(node.scriptTag, toNode.scriptTag),
+ _isEqualNodeLists(node.directives, toNode.directives),
+ _isEqualNodeLists(node.declarations, toNode.declarations),
+ _isEqualTokens(node.endToken, toNode.endToken))) {
+ toNode.element = node.element;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitConditionalExpression(ConditionalExpression node) {
+ ConditionalExpression toNode = this._toNode as ConditionalExpression;
+ if (_and(
+ _isEqualNodes(node.condition, toNode.condition),
+ _isEqualTokens(node.question, toNode.question),
+ _isEqualNodes(node.thenExpression, toNode.thenExpression),
+ _isEqualTokens(node.colon, toNode.colon),
+ _isEqualNodes(node.elseExpression, toNode.elseExpression))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitConfiguration(Configuration node) {
+ Configuration toNode = this._toNode as Configuration;
+ if (_and(
+ _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualTokens(node.equalToken, toNode.equalToken),
+ _isEqualNodes(node.value, toNode.value),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+ _isEqualNodes(node.libraryUri, toNode.libraryUri))) {
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitConstructorDeclaration(ConstructorDeclaration node) {
+ ConstructorDeclaration toNode = this._toNode as ConstructorDeclaration;
+ if (_and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
+ _isEqualTokens(node.constKeyword, toNode.constKeyword),
+ _isEqualTokens(node.factoryKeyword, toNode.factoryKeyword),
+ _isEqualNodes(node.returnType, toNode.returnType),
+ _isEqualTokens(node.period, toNode.period),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualNodes(node.parameters, toNode.parameters),
+ _isEqualTokens(node.separator, toNode.separator),
+ _isEqualNodeLists(node.initializers, toNode.initializers),
+ _isEqualNodes(node.redirectedConstructor, toNode.redirectedConstructor),
+ _isEqualNodes(node.body, toNode.body))) {
+ toNode.element = node.element;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ ConstructorFieldInitializer toNode =
+ this._toNode as ConstructorFieldInitializer;
+ return _and(
+ _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
+ _isEqualTokens(node.period, toNode.period),
+ _isEqualNodes(node.fieldName, toNode.fieldName),
+ _isEqualTokens(node.equals, toNode.equals),
+ _isEqualNodes(node.expression, toNode.expression));
+ }
+
+ @override
+ bool visitConstructorName(ConstructorName node) {
+ ConstructorName toNode = this._toNode as ConstructorName;
+ if (_and(
+ _isEqualNodes(node.type, toNode.type),
+ _isEqualTokens(node.period, toNode.period),
+ _isEqualNodes(node.name, toNode.name))) {
+ toNode.staticElement = node.staticElement;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitContinueStatement(ContinueStatement node) {
+ ContinueStatement toNode = this._toNode as ContinueStatement;
+ if (_and(
+ _isEqualTokens(node.continueKeyword, toNode.continueKeyword),
+ _isEqualNodes(node.label, toNode.label),
+ _isEqualTokens(node.semicolon, toNode.semicolon))) {
+ // TODO(paulberry): map node.target to toNode.target.
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitDeclaredIdentifier(DeclaredIdentifier node) {
+ DeclaredIdentifier toNode = this._toNode as DeclaredIdentifier;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualNodes(node.type, toNode.type),
+ _isEqualNodes(node.identifier, toNode.identifier));
+ }
+
+ @override
+ bool visitDefaultFormalParameter(DefaultFormalParameter node) {
+ DefaultFormalParameter toNode = this._toNode as DefaultFormalParameter;
+ return _and(
+ _isEqualNodes(node.parameter, toNode.parameter),
+ node.kind == toNode.kind,
+ _isEqualTokens(node.separator, toNode.separator),
+ _isEqualNodes(node.defaultValue, toNode.defaultValue));
+ }
+
+ @override
+ bool visitDoStatement(DoStatement node) {
+ DoStatement toNode = this._toNode as DoStatement;
+ return _and(
+ _isEqualTokens(node.doKeyword, toNode.doKeyword),
+ _isEqualNodes(node.body, toNode.body),
+ _isEqualTokens(node.whileKeyword, toNode.whileKeyword),
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.condition, toNode.condition),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitDottedName(DottedName node) {
+ DottedName toNode = this._toNode as DottedName;
+ return _isEqualNodeLists(node.components, toNode.components);
+ }
+
+ @override
+ bool visitDoubleLiteral(DoubleLiteral node) {
+ DoubleLiteral toNode = this._toNode as DoubleLiteral;
+ if (_and(_isEqualTokens(node.literal, toNode.literal),
+ node.value == toNode.value)) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitEmptyFunctionBody(EmptyFunctionBody node) {
+ EmptyFunctionBody toNode = this._toNode as EmptyFunctionBody;
+ return _isEqualTokens(node.semicolon, toNode.semicolon);
+ }
+
+ @override
+ bool visitEmptyStatement(EmptyStatement node) {
+ EmptyStatement toNode = this._toNode as EmptyStatement;
+ return _isEqualTokens(node.semicolon, toNode.semicolon);
+ }
+
+ @override
+ bool visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+ EnumConstantDeclaration toNode = this._toNode as EnumConstantDeclaration;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualNodes(node.name, toNode.name));
+ }
+
+ @override
+ bool visitEnumDeclaration(EnumDeclaration node) {
+ EnumDeclaration toNode = this._toNode as EnumDeclaration;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.enumKeyword, toNode.enumKeyword),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodeLists(node.constants, toNode.constants),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket));
+ }
+
+ @override
+ bool visitExportDirective(ExportDirective node) {
+ ExportDirective toNode = this._toNode as ExportDirective;
+ if (_and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualNodes(node.uri, toNode.uri),
+ _isEqualNodeLists(node.combinators, toNode.combinators),
+ _isEqualTokens(node.semicolon, toNode.semicolon))) {
+ toNode.element = node.element;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ ExpressionFunctionBody toNode = this._toNode as ExpressionFunctionBody;
+ return _and(
+ _isEqualTokens(node.functionDefinition, toNode.functionDefinition),
+ _isEqualNodes(node.expression, toNode.expression),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitExpressionStatement(ExpressionStatement node) {
+ ExpressionStatement toNode = this._toNode as ExpressionStatement;
+ return _and(_isEqualNodes(node.expression, toNode.expression),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitExtendsClause(ExtendsClause node) {
+ ExtendsClause toNode = this._toNode as ExtendsClause;
+ return _and(_isEqualTokens(node.extendsKeyword, toNode.extendsKeyword),
+ _isEqualNodes(node.superclass, toNode.superclass));
+ }
+
+ @override
+ bool visitFieldDeclaration(FieldDeclaration node) {
+ FieldDeclaration toNode = this._toNode as FieldDeclaration;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.staticKeyword, toNode.staticKeyword),
+ _isEqualNodes(node.fields, toNode.fields),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitFieldFormalParameter(FieldFormalParameter node) {
+ FieldFormalParameter toNode = this._toNode as FieldFormalParameter;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualNodes(node.type, toNode.type),
+ _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
+ _isEqualTokens(node.period, toNode.period),
+ _isEqualNodes(node.identifier, toNode.identifier));
+ }
+
+ @override
+ bool visitForEachStatement(ForEachStatement node) {
+ ForEachStatement toNode = this._toNode as ForEachStatement;
+ return _and(
+ _isEqualTokens(node.forKeyword, toNode.forKeyword),
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.loopVariable, toNode.loopVariable),
+ _isEqualTokens(node.inKeyword, toNode.inKeyword),
+ _isEqualNodes(node.iterable, toNode.iterable),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+ _isEqualNodes(node.body, toNode.body));
+ }
+
+ @override
+ bool visitFormalParameterList(FormalParameterList node) {
+ FormalParameterList toNode = this._toNode as FormalParameterList;
+ return _and(
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodeLists(node.parameters, toNode.parameters),
+ _isEqualTokens(node.leftDelimiter, toNode.leftDelimiter),
+ _isEqualTokens(node.rightDelimiter, toNode.rightDelimiter),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis));
+ }
+
+ @override
+ bool visitForStatement(ForStatement node) {
+ ForStatement toNode = this._toNode as ForStatement;
+ return _and(
+ _isEqualTokens(node.forKeyword, toNode.forKeyword),
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.variables, toNode.variables),
+ _isEqualNodes(node.initialization, toNode.initialization),
+ _isEqualTokens(node.leftSeparator, toNode.leftSeparator),
+ _isEqualNodes(node.condition, toNode.condition),
+ _isEqualTokens(node.rightSeparator, toNode.rightSeparator),
+ _isEqualNodeLists(node.updaters, toNode.updaters),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+ _isEqualNodes(node.body, toNode.body));
+ }
+
+ @override
+ bool visitFunctionDeclaration(FunctionDeclaration node) {
+ FunctionDeclaration toNode = this._toNode as FunctionDeclaration;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
+ _isEqualNodes(node.returnType, toNode.returnType),
+ _isEqualTokens(node.propertyKeyword, toNode.propertyKeyword),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualNodes(node.functionExpression, toNode.functionExpression));
+ }
+
+ @override
+ bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+ FunctionDeclarationStatement toNode =
+ this._toNode as FunctionDeclarationStatement;
+ return _isEqualNodes(node.functionDeclaration, toNode.functionDeclaration);
+ }
+
+ @override
+ bool visitFunctionExpression(FunctionExpression node) {
+ FunctionExpression toNode = this._toNode as FunctionExpression;
+ if (_and(_isEqualNodes(node.parameters, toNode.parameters),
+ _isEqualNodes(node.body, toNode.body))) {
+ toNode.element = node.element;
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ FunctionExpressionInvocation toNode =
+ this._toNode as FunctionExpressionInvocation;
+ if (_and(_isEqualNodes(node.function, toNode.function),
+ _isEqualNodes(node.argumentList, toNode.argumentList))) {
+ toNode.propagatedElement = node.propagatedElement;
+ toNode.propagatedInvokeType = node.propagatedInvokeType;
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticInvokeType = node.staticInvokeType;
+ toNode.staticElement = node.staticElement;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitFunctionTypeAlias(FunctionTypeAlias node) {
+ FunctionTypeAlias toNode = this._toNode as FunctionTypeAlias;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.typedefKeyword, toNode.typedefKeyword),
+ _isEqualNodes(node.returnType, toNode.returnType),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualNodes(node.typeParameters, toNode.typeParameters),
+ _isEqualNodes(node.parameters, toNode.parameters),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ FunctionTypedFormalParameter toNode =
+ this._toNode as FunctionTypedFormalParameter;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualNodes(node.returnType, toNode.returnType),
+ _isEqualNodes(node.identifier, toNode.identifier),
+ _isEqualNodes(node.parameters, toNode.parameters));
+ }
+
+ @override
+ bool visitHideCombinator(HideCombinator node) {
+ HideCombinator toNode = this._toNode as HideCombinator;
+ return _and(_isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualNodeLists(node.hiddenNames, toNode.hiddenNames));
+ }
+
+ @override
+ bool visitIfStatement(IfStatement node) {
+ IfStatement toNode = this._toNode as IfStatement;
+ return _and(
+ _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.condition, toNode.condition),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+ _isEqualNodes(node.thenStatement, toNode.thenStatement),
+ _isEqualTokens(node.elseKeyword, toNode.elseKeyword),
+ _isEqualNodes(node.elseStatement, toNode.elseStatement));
+ }
+
+ @override
+ bool visitImplementsClause(ImplementsClause node) {
+ ImplementsClause toNode = this._toNode as ImplementsClause;
+ return _and(
+ _isEqualTokens(node.implementsKeyword, toNode.implementsKeyword),
+ _isEqualNodeLists(node.interfaces, toNode.interfaces));
+ }
+
+ @override
+ bool visitImportDirective(ImportDirective node) {
+ ImportDirective toNode = this._toNode as ImportDirective;
+ if (_and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualNodes(node.uri, toNode.uri),
+ _isEqualTokens(node.asKeyword, toNode.asKeyword),
+ _isEqualNodes(node.prefix, toNode.prefix),
+ _isEqualNodeLists(node.combinators, toNode.combinators),
+ _isEqualTokens(node.semicolon, toNode.semicolon))) {
+ toNode.element = node.element;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitIndexExpression(IndexExpression node) {
+ IndexExpression toNode = this._toNode as IndexExpression;
+ if (_and(
+ _isEqualNodes(node.target, toNode.target),
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodes(node.index, toNode.index),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
+ toNode.auxiliaryElements = node.auxiliaryElements;
+ toNode.propagatedElement = node.propagatedElement;
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticElement = node.staticElement;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitInstanceCreationExpression(InstanceCreationExpression node) {
+ InstanceCreationExpression toNode =
+ this._toNode as InstanceCreationExpression;
+ if (_and(
+ _isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualNodes(node.constructorName, toNode.constructorName),
+ _isEqualNodes(node.argumentList, toNode.argumentList))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticElement = node.staticElement;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitIntegerLiteral(IntegerLiteral node) {
+ IntegerLiteral toNode = this._toNode as IntegerLiteral;
+ if (_and(_isEqualTokens(node.literal, toNode.literal),
+ node.value == toNode.value)) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitInterpolationExpression(InterpolationExpression node) {
+ InterpolationExpression toNode = this._toNode as InterpolationExpression;
+ return _and(
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodes(node.expression, toNode.expression),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket));
+ }
+
+ @override
+ bool visitInterpolationString(InterpolationString node) {
+ InterpolationString toNode = this._toNode as InterpolationString;
+ return _and(_isEqualTokens(node.contents, toNode.contents),
+ node.value == toNode.value);
+ }
+
+ @override
+ bool visitIsExpression(IsExpression node) {
+ IsExpression toNode = this._toNode as IsExpression;
+ if (_and(
+ _isEqualNodes(node.expression, toNode.expression),
+ _isEqualTokens(node.isOperator, toNode.isOperator),
+ _isEqualTokens(node.notOperator, toNode.notOperator),
+ _isEqualNodes(node.type, toNode.type))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitLabel(Label node) {
+ Label toNode = this._toNode as Label;
+ return _and(_isEqualNodes(node.label, toNode.label),
+ _isEqualTokens(node.colon, toNode.colon));
+ }
+
+ @override
+ bool visitLabeledStatement(LabeledStatement node) {
+ LabeledStatement toNode = this._toNode as LabeledStatement;
+ return _and(_isEqualNodeLists(node.labels, toNode.labels),
+ _isEqualNodes(node.statement, toNode.statement));
+ }
+
+ @override
+ bool visitLibraryDirective(LibraryDirective node) {
+ LibraryDirective toNode = this._toNode as LibraryDirective;
+ if (_and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.libraryKeyword, toNode.libraryKeyword),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualTokens(node.semicolon, toNode.semicolon))) {
+ toNode.element = node.element;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitLibraryIdentifier(LibraryIdentifier node) {
+ LibraryIdentifier toNode = this._toNode as LibraryIdentifier;
+ if (_isEqualNodeLists(node.components, toNode.components)) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitListLiteral(ListLiteral node) {
+ ListLiteral toNode = this._toNode as ListLiteral;
+ if (_and(
+ _isEqualTokens(node.constKeyword, toNode.constKeyword),
+ _isEqualNodes(node.typeArguments, toNode.typeArguments),
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodeLists(node.elements, toNode.elements),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitMapLiteral(MapLiteral node) {
+ MapLiteral toNode = this._toNode as MapLiteral;
+ if (_and(
+ _isEqualTokens(node.constKeyword, toNode.constKeyword),
+ _isEqualNodes(node.typeArguments, toNode.typeArguments),
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodeLists(node.entries, toNode.entries),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitMapLiteralEntry(MapLiteralEntry node) {
+ MapLiteralEntry toNode = this._toNode as MapLiteralEntry;
+ return _and(
+ _isEqualNodes(node.key, toNode.key),
+ _isEqualTokens(node.separator, toNode.separator),
+ _isEqualNodes(node.value, toNode.value));
+ }
+
+ @override
+ bool visitMethodDeclaration(MethodDeclaration node) {
+ MethodDeclaration toNode = this._toNode as MethodDeclaration;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
+ _isEqualTokens(node.modifierKeyword, toNode.modifierKeyword),
+ _isEqualNodes(node.returnType, toNode.returnType),
+ _isEqualTokens(node.propertyKeyword, toNode.propertyKeyword),
+ _isEqualTokens(node.propertyKeyword, toNode.propertyKeyword),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualNodes(node.parameters, toNode.parameters),
+ _isEqualNodes(node.body, toNode.body));
+ }
+
+ @override
+ bool visitMethodInvocation(MethodInvocation node) {
+ MethodInvocation toNode = this._toNode as MethodInvocation;
+ if (_and(
+ _isEqualNodes(node.target, toNode.target),
+ _isEqualTokens(node.operator, toNode.operator),
+ _isEqualNodes(node.methodName, toNode.methodName),
+ _isEqualNodes(node.argumentList, toNode.argumentList))) {
+ toNode.propagatedInvokeType = node.propagatedInvokeType;
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticInvokeType = node.staticInvokeType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitNamedExpression(NamedExpression node) {
+ NamedExpression toNode = this._toNode as NamedExpression;
+ if (_and(_isEqualNodes(node.name, toNode.name),
+ _isEqualNodes(node.expression, toNode.expression))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitNativeClause(NativeClause node) {
+ NativeClause toNode = this._toNode as NativeClause;
+ return _and(_isEqualTokens(node.nativeKeyword, toNode.nativeKeyword),
+ _isEqualNodes(node.name, toNode.name));
+ }
+
+ @override
+ bool visitNativeFunctionBody(NativeFunctionBody node) {
+ NativeFunctionBody toNode = this._toNode as NativeFunctionBody;
+ return _and(
+ _isEqualTokens(node.nativeKeyword, toNode.nativeKeyword),
+ _isEqualNodes(node.stringLiteral, toNode.stringLiteral),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitNullLiteral(NullLiteral node) {
+ NullLiteral toNode = this._toNode as NullLiteral;
+ if (_isEqualTokens(node.literal, toNode.literal)) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitParenthesizedExpression(ParenthesizedExpression node) {
+ ParenthesizedExpression toNode = this._toNode as ParenthesizedExpression;
+ if (_and(
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.expression, toNode.expression),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitPartDirective(PartDirective node) {
+ PartDirective toNode = this._toNode as PartDirective;
+ if (_and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.partKeyword, toNode.partKeyword),
+ _isEqualNodes(node.uri, toNode.uri),
+ _isEqualTokens(node.semicolon, toNode.semicolon))) {
+ toNode.element = node.element;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitPartOfDirective(PartOfDirective node) {
+ PartOfDirective toNode = this._toNode as PartOfDirective;
+ if (_and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.partKeyword, toNode.partKeyword),
+ _isEqualTokens(node.ofKeyword, toNode.ofKeyword),
+ _isEqualNodes(node.libraryName, toNode.libraryName),
+ _isEqualTokens(node.semicolon, toNode.semicolon))) {
+ toNode.element = node.element;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitPostfixExpression(PostfixExpression node) {
+ PostfixExpression toNode = this._toNode as PostfixExpression;
+ if (_and(_isEqualNodes(node.operand, toNode.operand),
+ _isEqualTokens(node.operator, toNode.operator))) {
+ toNode.propagatedElement = node.propagatedElement;
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticElement = node.staticElement;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitPrefixedIdentifier(PrefixedIdentifier node) {
+ PrefixedIdentifier toNode = this._toNode as PrefixedIdentifier;
+ if (_and(
+ _isEqualNodes(node.prefix, toNode.prefix),
+ _isEqualTokens(node.period, toNode.period),
+ _isEqualNodes(node.identifier, toNode.identifier))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitPrefixExpression(PrefixExpression node) {
+ PrefixExpression toNode = this._toNode as PrefixExpression;
+ if (_and(_isEqualTokens(node.operator, toNode.operator),
+ _isEqualNodes(node.operand, toNode.operand))) {
+ toNode.propagatedElement = node.propagatedElement;
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticElement = node.staticElement;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitPropertyAccess(PropertyAccess node) {
+ PropertyAccess toNode = this._toNode as PropertyAccess;
+ if (_and(
+ _isEqualNodes(node.target, toNode.target),
+ _isEqualTokens(node.operator, toNode.operator),
+ _isEqualNodes(node.propertyName, toNode.propertyName))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitRedirectingConstructorInvocation(
+ RedirectingConstructorInvocation node) {
+ RedirectingConstructorInvocation toNode =
+ this._toNode as RedirectingConstructorInvocation;
+ if (_and(
+ _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
+ _isEqualTokens(node.period, toNode.period),
+ _isEqualNodes(node.constructorName, toNode.constructorName),
+ _isEqualNodes(node.argumentList, toNode.argumentList))) {
+ toNode.staticElement = node.staticElement;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitRethrowExpression(RethrowExpression node) {
+ RethrowExpression toNode = this._toNode as RethrowExpression;
+ if (_isEqualTokens(node.rethrowKeyword, toNode.rethrowKeyword)) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitReturnStatement(ReturnStatement node) {
+ ReturnStatement toNode = this._toNode as ReturnStatement;
+ return _and(
+ _isEqualTokens(node.returnKeyword, toNode.returnKeyword),
+ _isEqualNodes(node.expression, toNode.expression),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitScriptTag(ScriptTag node) {
+ ScriptTag toNode = this._toNode as ScriptTag;
+ return _isEqualTokens(node.scriptTag, toNode.scriptTag);
+ }
+
+ @override
+ bool visitShowCombinator(ShowCombinator node) {
+ ShowCombinator toNode = this._toNode as ShowCombinator;
+ return _and(_isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualNodeLists(node.shownNames, toNode.shownNames));
+ }
+
+ @override
+ bool visitSimpleFormalParameter(SimpleFormalParameter node) {
+ SimpleFormalParameter toNode = this._toNode as SimpleFormalParameter;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualNodes(node.type, toNode.type),
+ _isEqualNodes(node.identifier, toNode.identifier));
+ }
+
+ @override
+ bool visitSimpleIdentifier(SimpleIdentifier node) {
+ SimpleIdentifier toNode = this._toNode as SimpleIdentifier;
+ if (_isEqualTokens(node.token, toNode.token)) {
+ toNode.staticElement = node.staticElement;
+ toNode.staticType = node.staticType;
+ toNode.propagatedElement = node.propagatedElement;
+ toNode.propagatedType = node.propagatedType;
+ toNode.auxiliaryElements = node.auxiliaryElements;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitSimpleStringLiteral(SimpleStringLiteral node) {
+ SimpleStringLiteral toNode = this._toNode as SimpleStringLiteral;
+ if (_and(_isEqualTokens(node.literal, toNode.literal),
+ node.value == toNode.value)) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitStringInterpolation(StringInterpolation node) {
+ StringInterpolation toNode = this._toNode as StringInterpolation;
+ if (_isEqualNodeLists(node.elements, toNode.elements)) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ SuperConstructorInvocation toNode =
+ this._toNode as SuperConstructorInvocation;
+ if (_and(
+ _isEqualTokens(node.superKeyword, toNode.superKeyword),
+ _isEqualTokens(node.period, toNode.period),
+ _isEqualNodes(node.constructorName, toNode.constructorName),
+ _isEqualNodes(node.argumentList, toNode.argumentList))) {
+ toNode.staticElement = node.staticElement;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitSuperExpression(SuperExpression node) {
+ SuperExpression toNode = this._toNode as SuperExpression;
+ if (_isEqualTokens(node.superKeyword, toNode.superKeyword)) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitSwitchCase(SwitchCase node) {
+ SwitchCase toNode = this._toNode as SwitchCase;
+ return _and(
+ _isEqualNodeLists(node.labels, toNode.labels),
+ _isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualNodes(node.expression, toNode.expression),
+ _isEqualTokens(node.colon, toNode.colon),
+ _isEqualNodeLists(node.statements, toNode.statements));
+ }
+
+ @override
+ bool visitSwitchDefault(SwitchDefault node) {
+ SwitchDefault toNode = this._toNode as SwitchDefault;
+ return _and(
+ _isEqualNodeLists(node.labels, toNode.labels),
+ _isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualTokens(node.colon, toNode.colon),
+ _isEqualNodeLists(node.statements, toNode.statements));
+ }
+
+ @override
+ bool visitSwitchStatement(SwitchStatement node) {
+ SwitchStatement toNode = this._toNode as SwitchStatement;
+ return _and(
+ _isEqualTokens(node.switchKeyword, toNode.switchKeyword),
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.expression, toNode.expression),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodeLists(node.members, toNode.members),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket));
+ }
+
+ @override
+ bool visitSymbolLiteral(SymbolLiteral node) {
+ SymbolLiteral toNode = this._toNode as SymbolLiteral;
+ if (_and(_isEqualTokens(node.poundSign, toNode.poundSign),
+ _isEqualTokenLists(node.components, toNode.components))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitThisExpression(ThisExpression node) {
+ ThisExpression toNode = this._toNode as ThisExpression;
+ if (_isEqualTokens(node.thisKeyword, toNode.thisKeyword)) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitThrowExpression(ThrowExpression node) {
+ ThrowExpression toNode = this._toNode as ThrowExpression;
+ if (_and(_isEqualTokens(node.throwKeyword, toNode.throwKeyword),
+ _isEqualNodes(node.expression, toNode.expression))) {
+ toNode.propagatedType = node.propagatedType;
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ TopLevelVariableDeclaration toNode =
+ this._toNode as TopLevelVariableDeclaration;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualNodes(node.variables, toNode.variables),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitTryStatement(TryStatement node) {
+ TryStatement toNode = this._toNode as TryStatement;
+ return _and(
+ _isEqualTokens(node.tryKeyword, toNode.tryKeyword),
+ _isEqualNodes(node.body, toNode.body),
+ _isEqualNodeLists(node.catchClauses, toNode.catchClauses),
+ _isEqualTokens(node.finallyKeyword, toNode.finallyKeyword),
+ _isEqualNodes(node.finallyBlock, toNode.finallyBlock));
+ }
+
+ @override
+ bool visitTypeArgumentList(TypeArgumentList node) {
+ TypeArgumentList toNode = this._toNode as TypeArgumentList;
+ return _and(
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodeLists(node.arguments, toNode.arguments),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket));
+ }
+
+ @override
+ bool visitTypeName(TypeName node) {
+ TypeName toNode = this._toNode as TypeName;
+ if (_and(_isEqualNodes(node.name, toNode.name),
+ _isEqualNodes(node.typeArguments, toNode.typeArguments))) {
+ toNode.type = node.type;
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ bool visitTypeParameter(TypeParameter node) {
+ TypeParameter toNode = this._toNode as TypeParameter;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualTokens(node.extendsKeyword, toNode.extendsKeyword),
+ _isEqualNodes(node.bound, toNode.bound));
+ }
+
+ @override
+ bool visitTypeParameterList(TypeParameterList node) {
+ TypeParameterList toNode = this._toNode as TypeParameterList;
+ return _and(
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodeLists(node.typeParameters, toNode.typeParameters),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket));
+ }
+
+ @override
+ bool visitVariableDeclaration(VariableDeclaration node) {
+ VariableDeclaration toNode = this._toNode as VariableDeclaration;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualNodes(node.name, toNode.name),
+ _isEqualTokens(node.equals, toNode.equals),
+ _isEqualNodes(node.initializer, toNode.initializer));
+ }
+
+ @override
+ bool visitVariableDeclarationList(VariableDeclarationList node) {
+ VariableDeclarationList toNode = this._toNode as VariableDeclarationList;
+ return _and(
+ _isEqualNodes(node.documentationComment, toNode.documentationComment),
+ _isEqualNodeLists(node.metadata, toNode.metadata),
+ _isEqualTokens(node.keyword, toNode.keyword),
+ _isEqualNodes(node.type, toNode.type),
+ _isEqualNodeLists(node.variables, toNode.variables));
+ }
+
+ @override
+ bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+ VariableDeclarationStatement toNode =
+ this._toNode as VariableDeclarationStatement;
+ return _and(_isEqualNodes(node.variables, toNode.variables),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ @override
+ bool visitWhileStatement(WhileStatement node) {
+ WhileStatement toNode = this._toNode as WhileStatement;
+ return _and(
+ _isEqualTokens(node.whileKeyword, toNode.whileKeyword),
+ _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+ _isEqualNodes(node.condition, toNode.condition),
+ _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+ _isEqualNodes(node.body, toNode.body));
+ }
+
+ @override
+ bool visitWithClause(WithClause node) {
+ WithClause toNode = this._toNode as WithClause;
+ return _and(_isEqualTokens(node.withKeyword, toNode.withKeyword),
+ _isEqualNodeLists(node.mixinTypes, toNode.mixinTypes));
+ }
+
+ @override
+ bool visitYieldStatement(YieldStatement node) {
+ YieldStatement toNode = this._toNode as YieldStatement;
+ return _and(
+ _isEqualTokens(node.yieldKeyword, toNode.yieldKeyword),
+ _isEqualNodes(node.expression, toNode.expression),
+ _isEqualTokens(node.semicolon, toNode.semicolon));
+ }
+
+ /**
+ * Return `true` if all of the parameters are `true`.
+ */
+ bool _and(bool b1, bool b2,
+ [bool b3 = true,
+ bool b4 = true,
+ bool b5 = true,
+ bool b6 = true,
+ bool b7 = true,
+ bool b8 = true,
+ bool b9 = true,
+ bool b10 = true,
+ bool b11 = true,
+ bool b12 = true,
+ bool b13 = true]) {
+ // TODO(brianwilkerson) Inline this method.
+ return b1 &&
+ b2 &&
+ b3 &&
+ b4 &&
+ b5 &&
+ b6 &&
+ b7 &&
+ b8 &&
+ b9 &&
+ b10 &&
+ b11 &&
+ b12 &&
+ b13;
+ }
+
+ /**
+ * Return `true` if the [first] and [second] lists of AST nodes have the same
+ * size and corresponding elements are equal.
+ */
+ bool _isEqualNodeLists(NodeList first, NodeList second) {
+ if (first == null) {
+ return second == null;
+ } else if (second == null) {
+ return false;
+ }
+ int size = first.length;
+ if (second.length != size) {
+ return false;
+ }
+ bool equal = true;
+ for (int i = 0; i < size; i++) {
+ if (!_isEqualNodes(first[i], second[i])) {
+ equal = false;
+ }
+ }
+ return equal;
+ }
+
+ /**
+ * Return `true` if the [fromNode] and [toNode] have the same structure. As a
+ * side-effect, if the nodes do have the same structure, any resolution data
+ * from the first node will be copied to the second node.
+ */
+ bool _isEqualNodes(AstNode fromNode, AstNode toNode) {
+ if (fromNode == null) {
+ return toNode == null;
+ } else if (toNode == null) {
+ return false;
+ } else if (fromNode.runtimeType == toNode.runtimeType) {
+ this._toNode = toNode;
+ return fromNode.accept(this);
+ }
+ //
+ // Check for a simple transformation caused by entering a period.
+ //
+ if (toNode is PrefixedIdentifier) {
+ SimpleIdentifier prefix = toNode.prefix;
+ if (fromNode.runtimeType == prefix.runtimeType) {
+ this._toNode = prefix;
+ return fromNode.accept(this);
+ }
+ } else if (toNode is PropertyAccess) {
+ Expression target = toNode.target;
+ if (fromNode.runtimeType == target.runtimeType) {
+ this._toNode = target;
+ return fromNode.accept(this);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return `true` if the [first] and [second] arrays of tokens have the same
+ * length and corresponding elements are equal.
+ */
+ bool _isEqualTokenLists(List<Token> first, List<Token> second) {
+ int length = first.length;
+ if (second.length != length) {
+ return false;
+ }
+ for (int i = 0; i < length; i++) {
+ if (!_isEqualTokens(first[i], second[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return `true` if the [first] and [second] tokens have the same structure.
+ */
+ bool _isEqualTokens(Token first, Token second) {
+ if (first == null) {
+ return second == null;
+ } else if (second == null) {
+ return false;
+ }
+ return first.lexeme == second.lexeme;
+ }
+
+ /**
+ * Copy resolution data from the [fromNode] to the [toNode].
+ */
+ static void copyResolutionData(AstNode fromNode, AstNode toNode) {
+ ResolutionCopier copier = new ResolutionCopier();
+ copier._isEqualNodes(fromNode, toNode);
+ }
+}
+
+/**
* Traverse the AST from initial child node to successive parents, building a
* collection of local variable and parameter names visible to the initial child
* node. In case of name shadowing, the first name seen is the most specific one
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index 8dfc781..2754786 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -543,9 +543,7 @@
_setCodeRange(element, node);
element.metadata = _createElementAnnotations(node.metadata);
ForEachStatement statement = node.parent as ForEachStatement;
- int declarationEnd = node.offset + node.length;
- int statementEnd = statement.offset + statement.length;
- element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1);
+ element.setVisibleRange(statement.offset, statement.length);
element.const3 = node.isConst;
element.final2 = node.isFinal;
if (node.type == null) {
@@ -1201,10 +1199,7 @@
}
element = variable;
_setCodeRange(element, node);
- Block enclosingBlock = node.getAncestor((node) => node is Block);
- // TODO(brianwilkerson) This isn't right for variables declared in a for
- // loop.
- variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
+ _setVariableVisibleRange(variable, node);
variable.hasImplicitType = varList.type == null;
_currentHolder.addLocalVariable(variable);
variableName.staticElement = element;
@@ -1401,6 +1396,18 @@
}
}
+ void _setVariableVisibleRange(
+ LocalVariableElementImpl element, VariableDeclaration node) {
+ AstNode scopeNode;
+ AstNode parent2 = node.parent.parent;
+ if (parent2 is ForStatement) {
+ scopeNode = parent2;
+ } else {
+ scopeNode = node.getAncestor((node) => node is Block);
+ }
+ element.setVisibleRange(scopeNode.offset, scopeNode.length);
+ }
+
/**
* Make the given holder be the current holder while visiting the given node.
*
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 310e4e9..24241df 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -13,10 +13,10 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart'
show DartObject, EvaluationResultImpl;
-import 'package:analyzer/src/generated/element_handle.dart';
import 'package:analyzer/src/generated/engine.dart'
show AnalysisContext, AnalysisEngine;
import 'package:analyzer/src/generated/java_core.dart';
@@ -1987,6 +1987,27 @@
}
/**
+ * Append to the given [buffer] a comma-separated list of the names of the
+ * types of this element and every enclosing element.
+ */
+ void appendPathTo(StringBuffer buffer) {
+ Element element = this;
+ while (element != null) {
+ if (element != this) {
+ buffer.write(', ');
+ }
+ buffer.write(element.runtimeType);
+ String name = element.name;
+ if (name != null) {
+ buffer.write(' (');
+ buffer.write(name);
+ buffer.write(')');
+ }
+ element = element.enclosingElement;
+ }
+ }
+
+ /**
* Append a textual representation of this element to the given [buffer].
*/
void appendTo(StringBuffer buffer) {
@@ -2229,10 +2250,10 @@
@override
int get hashCode {
- int result = 1;
+ int result = 0;
for (int i = 0; i < _components.length; i++) {
String component = _components[i];
- result = 31 * result + component.hashCode;
+ result = JenkinsSmiHash.combine(result, component.hashCode);
}
return result;
}
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
new file mode 100644
index 0000000..dfecff2
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -0,0 +1,1091 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.generated.element_handle;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/**
+ * A handle to a [ClassElement].
+ */
+class ClassElementHandle extends ElementHandle implements ClassElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ ClassElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ List<PropertyAccessorElement> get accessors => actualElement.accessors;
+
+ @override
+ ClassElement get actualElement => super.actualElement as ClassElement;
+
+ @override
+ List<InterfaceType> get allSupertypes => actualElement.allSupertypes;
+
+ @override
+ List<ConstructorElement> get constructors => actualElement.constructors;
+
+ @override
+ List<FieldElement> get fields => actualElement.fields;
+
+ @override
+ bool get hasNonFinalField => actualElement.hasNonFinalField;
+
+ @override
+ bool get hasReferenceToSuper => actualElement.hasReferenceToSuper;
+
+ @override
+ bool get hasStaticMember => actualElement.hasStaticMember;
+
+ @override
+ List<InterfaceType> get interfaces => actualElement.interfaces;
+
+ @override
+ bool get isAbstract => actualElement.isAbstract;
+
+ @override
+ bool get isEnum => actualElement.isEnum;
+
+ @override
+ bool get isMixinApplication => actualElement.isMixinApplication;
+
+ @override
+ bool get isOrInheritsProxy => actualElement.isOrInheritsProxy;
+
+ @override
+ bool get isProxy => actualElement.isProxy;
+
+ @override
+ bool get isValidMixin => actualElement.isValidMixin;
+
+ @override
+ ElementKind get kind => ElementKind.CLASS;
+
+ @override
+ List<MethodElement> get methods => actualElement.methods;
+
+ @override
+ List<InterfaceType> get mixins => actualElement.mixins;
+
+ @override
+ InterfaceType get supertype => actualElement.supertype;
+
+ @override
+ InterfaceType get type => actualElement.type;
+
+ @override
+ List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
+
+ @override
+ ConstructorElement get unnamedConstructor => actualElement.unnamedConstructor;
+
+ @override
+ FieldElement getField(String fieldName) => actualElement.getField(fieldName);
+
+ @override
+ PropertyAccessorElement getGetter(String getterName) =>
+ actualElement.getGetter(getterName);
+
+ @override
+ MethodElement getMethod(String methodName) =>
+ actualElement.getMethod(methodName);
+
+ @override
+ ConstructorElement getNamedConstructor(String name) =>
+ actualElement.getNamedConstructor(name);
+
+ @override
+ PropertyAccessorElement getSetter(String setterName) =>
+ actualElement.getSetter(setterName);
+
+ @override
+ bool isSuperConstructorAccessible(ConstructorElement constructor) =>
+ actualElement.isSuperConstructorAccessible(constructor);
+
+ @override
+ MethodElement lookUpConcreteMethod(
+ String methodName, LibraryElement library) =>
+ actualElement.lookUpConcreteMethod(methodName, library);
+
+ @override
+ PropertyAccessorElement lookUpGetter(
+ String getterName, LibraryElement library) =>
+ actualElement.lookUpGetter(getterName, library);
+
+ @override
+ PropertyAccessorElement lookUpInheritedConcreteGetter(
+ String methodName, LibraryElement library) =>
+ actualElement.lookUpInheritedConcreteGetter(methodName, library);
+
+ @override
+ MethodElement lookUpInheritedConcreteMethod(
+ String methodName, LibraryElement library) =>
+ actualElement.lookUpInheritedConcreteMethod(methodName, library);
+
+ @override
+ PropertyAccessorElement lookUpInheritedConcreteSetter(
+ String methodName, LibraryElement library) =>
+ actualElement.lookUpInheritedConcreteSetter(methodName, library);
+
+ @override
+ MethodElement lookUpInheritedMethod(
+ String methodName, LibraryElement library) =>
+ actualElement.lookUpInheritedMethod(methodName, library);
+
+ @override
+ MethodElement lookUpMethod(String methodName, LibraryElement library) =>
+ actualElement.lookUpMethod(methodName, library);
+
+ @override
+ PropertyAccessorElement lookUpSetter(
+ String setterName, LibraryElement library) =>
+ actualElement.lookUpSetter(setterName, library);
+}
+
+/**
+ * A handle to a [CompilationUnitElement].
+ */
+class CompilationUnitElementHandle extends ElementHandle
+ implements CompilationUnitElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ CompilationUnitElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ List<PropertyAccessorElement> get accessors => actualElement.accessors;
+
+ @override
+ CompilationUnitElement get actualElement =>
+ super.actualElement as CompilationUnitElement;
+
+ @override
+ LibraryElement get enclosingElement =>
+ super.enclosingElement as LibraryElement;
+
+ @override
+ List<ClassElement> get enums => actualElement.enums;
+
+ @override
+ List<FunctionElement> get functions => actualElement.functions;
+
+ @override
+ List<FunctionTypeAliasElement> get functionTypeAliases =>
+ actualElement.functionTypeAliases;
+
+ @override
+ bool get hasLoadLibraryFunction => actualElement.hasLoadLibraryFunction;
+
+ @override
+ ElementKind get kind => ElementKind.COMPILATION_UNIT;
+
+ @override
+ Source get source => actualElement.source;
+
+ @override
+ List<TopLevelVariableElement> get topLevelVariables =>
+ actualElement.topLevelVariables;
+
+ @override
+ List<ClassElement> get types => actualElement.types;
+
+ @override
+ String get uri => actualElement.uri;
+
+ @override
+ int get uriEnd => actualElement.uriEnd;
+
+ @override
+ int get uriOffset => actualElement.uriOffset;
+
+ @override
+ CompilationUnit computeNode() => actualElement.computeNode();
+
+ @override
+ Element getElementAt(int offset) {
+ return actualElement.getElementAt(offset);
+ }
+
+ @override
+ ClassElement getEnum(String enumName) => actualElement.getEnum(enumName);
+
+ @override
+ ClassElement getType(String className) => actualElement.getType(className);
+}
+
+/**
+ * A handle to a [ConstructorElement].
+ */
+class ConstructorElementHandle extends ExecutableElementHandle
+ implements ConstructorElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ ConstructorElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ ConstructorElement get actualElement =>
+ super.actualElement as ConstructorElement;
+
+ @override
+ ClassElement get enclosingElement => actualElement.enclosingElement;
+
+ @override
+ bool get isConst => actualElement.isConst;
+
+ @override
+ bool get isDefaultConstructor => actualElement.isDefaultConstructor;
+
+ @override
+ bool get isFactory => actualElement.isFactory;
+
+ @override
+ ElementKind get kind => ElementKind.CONSTRUCTOR;
+
+ @override
+ int get nameEnd => actualElement.nameEnd;
+
+ @override
+ int get periodOffset => actualElement.periodOffset;
+
+ @override
+ ConstructorElement get redirectedConstructor =>
+ actualElement.redirectedConstructor;
+
+ @override
+ ConstructorDeclaration computeNode() => actualElement.computeNode();
+}
+
+/**
+ * A handle to an [Element].
+ */
+abstract class ElementHandle implements Element {
+ /**
+ * The unique integer identifier of this element.
+ */
+ final int id = 0;
+
+ /**
+ * The [ElementResynthesizer] which will be used to resynthesize elements on
+ * demand.
+ */
+ final ElementResynthesizer _resynthesizer;
+
+ /**
+ * The location of this element, used to reconstitute the element if it has
+ * not yet been resynthesized.
+ */
+ final ElementLocation _location;
+
+ /**
+ * A reference to the element being referenced by this handle, or `null` if
+ * the element has not yet been resynthesized.
+ */
+ Element _elementReference;
+
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ ElementHandle(this._resynthesizer, this._location);
+
+ /**
+ * Return the element being represented by this handle, reconstituting the
+ * element if the reference has been set to `null`.
+ */
+ Element get actualElement {
+ if (_elementReference == null) {
+ _elementReference = _resynthesizer.getElement(_location);
+ }
+ return _elementReference;
+ }
+
+ @override
+ AnalysisContext get context => _resynthesizer.context;
+
+ @override
+ String get displayName => actualElement.displayName;
+
+ @deprecated
+ @override
+ SourceRange get docRange => actualElement.docRange;
+
+ @override
+ String get documentationComment => actualElement.documentationComment;
+
+ @override
+ Element get enclosingElement => actualElement.enclosingElement;
+
+ @override
+ int get hashCode => _location.hashCode;
+
+ @override
+ bool get isDeprecated => actualElement.isDeprecated;
+
+ @override
+ bool get isOverride => actualElement.isOverride;
+
+ @override
+ bool get isPrivate => actualElement.isPrivate;
+
+ @override
+ bool get isProtected => actualElement.isProtected;
+
+ @override
+ bool get isPublic => actualElement.isPublic;
+
+ @override
+ bool get isSynthetic => actualElement.isSynthetic;
+
+ @override
+ LibraryElement get library =>
+ getAncestor((element) => element is LibraryElement);
+
+ @override
+ ElementLocation get location => _location;
+
+ @override
+ List<ElementAnnotation> get metadata => actualElement.metadata;
+
+ @override
+ String get name => actualElement.name;
+
+ @override
+ int get nameLength => actualElement.nameLength;
+
+ @override
+ int get nameOffset => actualElement.nameOffset;
+
+ @override
+ Source get source => actualElement.source;
+
+ @override
+ CompilationUnit get unit => actualElement.unit;
+
+ @override
+ bool operator ==(Object object) =>
+ object is Element && object.location == _location;
+
+ @override
+ accept(ElementVisitor visitor) => actualElement.accept(visitor);
+
+ @override
+ String computeDocumentationComment() => documentationComment;
+
+ @override
+ AstNode computeNode() => actualElement.computeNode();
+
+ @override
+ Element getAncestor(Predicate<Element> predicate) =>
+ actualElement.getAncestor(predicate);
+
+ @override
+ String getExtendedDisplayName(String shortName) =>
+ actualElement.getExtendedDisplayName(shortName);
+
+ @override
+ bool isAccessibleIn(LibraryElement library) =>
+ actualElement.isAccessibleIn(library);
+
+ @override
+ void visitChildren(ElementVisitor visitor) {
+ actualElement.visitChildren(visitor);
+ }
+}
+
+/**
+ * Interface which allows an [Element] handle to be resynthesized based on an
+ * [ElementLocation]. The concrete classes implementing element handles use
+ * this interface to retrieve the underlying elements when queried.
+ */
+abstract class ElementResynthesizer {
+ /**
+ * The context that owns the element to be resynthesized.
+ */
+ final AnalysisContext context;
+
+ /**
+ * Initialize a newly created resynthesizer to resynthesize elements in the
+ * given [context].
+ */
+ ElementResynthesizer(this.context);
+
+ /**
+ * Return the element referenced by the given [location].
+ */
+ Element getElement(ElementLocation location);
+}
+
+/**
+ * A handle to an [ExecutableElement].
+ */
+abstract class ExecutableElementHandle extends ElementHandle
+ implements ExecutableElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ ExecutableElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ ExecutableElement get actualElement =>
+ super.actualElement as ExecutableElement;
+
+ @override
+ List<FunctionElement> get functions => actualElement.functions;
+
+ @override
+ bool get hasImplicitReturnType => actualElement.hasImplicitReturnType;
+
+ @override
+ bool get isAbstract => actualElement.isAbstract;
+
+ @override
+ bool get isAsynchronous => actualElement.isAsynchronous;
+
+ @override
+ bool get isExternal => actualElement.isExternal;
+
+ @override
+ bool get isGenerator => actualElement.isGenerator;
+
+ @override
+ bool get isOperator => actualElement.isOperator;
+
+ @override
+ bool get isStatic => actualElement.isStatic;
+
+ @override
+ bool get isSynchronous => actualElement.isSynchronous;
+
+ @override
+ List<LabelElement> get labels => actualElement.labels;
+
+ @override
+ List<LocalVariableElement> get localVariables => actualElement.localVariables;
+
+ @override
+ List<ParameterElement> get parameters => actualElement.parameters;
+
+ @override
+ DartType get returnType => actualElement.returnType;
+
+ @override
+ FunctionType get type => actualElement.type;
+
+ @override
+ List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
+}
+
+/**
+ * A handle to an [ExportElement].
+ */
+class ExportElementHandle extends ElementHandle implements ExportElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ ExportElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ ExportElement get actualElement => super.actualElement as ExportElement;
+
+ @override
+ List<NamespaceCombinator> get combinators => actualElement.combinators;
+
+ @override
+ LibraryElement get exportedLibrary => actualElement.exportedLibrary;
+
+ @override
+ ElementKind get kind => ElementKind.EXPORT;
+
+ @override
+ String get uri => actualElement.uri;
+
+ @override
+ int get uriEnd => actualElement.uriEnd;
+
+ @override
+ int get uriOffset => actualElement.uriOffset;
+}
+
+/**
+ * A handle to a [FieldElement].
+ */
+class FieldElementHandle extends PropertyInducingElementHandle
+ implements FieldElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ FieldElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ FieldElement get actualElement => super.actualElement as FieldElement;
+
+ @override
+ ClassElement get enclosingElement => actualElement.enclosingElement;
+
+ @override
+ bool get isEnumConstant => actualElement.isEnumConstant;
+
+ @override
+ ElementKind get kind => ElementKind.FIELD;
+
+ @override
+ VariableDeclaration computeNode() => actualElement.computeNode();
+}
+
+/**
+ * A handle to a [FunctionElement].
+ */
+class FunctionElementHandle extends ExecutableElementHandle
+ implements FunctionElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ FunctionElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ FunctionElement get actualElement => super.actualElement as FunctionElement;
+
+ @override
+ bool get isEntryPoint => actualElement.isEntryPoint;
+
+ @override
+ ElementKind get kind => ElementKind.FUNCTION;
+
+ @override
+ SourceRange get visibleRange => actualElement.visibleRange;
+
+ @override
+ FunctionDeclaration computeNode() => actualElement.computeNode();
+}
+
+/**
+ * A handle to a [FunctionTypeAliasElement].
+ */
+class FunctionTypeAliasElementHandle extends ElementHandle
+ implements FunctionTypeAliasElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ FunctionTypeAliasElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ FunctionTypeAliasElement get actualElement =>
+ super.actualElement as FunctionTypeAliasElement;
+
+ @override
+ CompilationUnitElement get enclosingElement =>
+ super.enclosingElement as CompilationUnitElement;
+
+ @override
+ ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
+
+ @override
+ List<ParameterElement> get parameters => actualElement.parameters;
+
+ @override
+ DartType get returnType => actualElement.returnType;
+
+ @override
+ FunctionType get type => actualElement.type;
+
+ @override
+ List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
+
+ @override
+ FunctionTypeAlias computeNode() => actualElement.computeNode();
+}
+
+/**
+ * A handle to an [ImportElement].
+ */
+class ImportElementHandle extends ElementHandle implements ImportElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ ImportElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ ImportElement get actualElement => super.actualElement as ImportElement;
+
+ @override
+ List<NamespaceCombinator> get combinators => actualElement.combinators;
+
+ @override
+ LibraryElement get importedLibrary => actualElement.importedLibrary;
+
+ @override
+ bool get isDeferred => actualElement.isDeferred;
+
+ @override
+ ElementKind get kind => ElementKind.IMPORT;
+
+ @override
+ PrefixElement get prefix => actualElement.prefix;
+
+ @override
+ int get prefixOffset => actualElement.prefixOffset;
+
+ @override
+ String get uri => actualElement.uri;
+
+ @override
+ int get uriEnd => actualElement.uriEnd;
+
+ @override
+ int get uriOffset => actualElement.uriOffset;
+}
+
+/**
+ * A handle to a [LabelElement].
+ */
+class LabelElementHandle extends ElementHandle implements LabelElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ LabelElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ ExecutableElement get enclosingElement =>
+ super.enclosingElement as ExecutableElement;
+
+ @override
+ ElementKind get kind => ElementKind.LABEL;
+}
+
+/**
+ * A handle to a [LibraryElement].
+ */
+class LibraryElementHandle extends ElementHandle implements LibraryElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ LibraryElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ LibraryElement get actualElement => super.actualElement as LibraryElement;
+
+ @override
+ CompilationUnitElement get definingCompilationUnit =>
+ actualElement.definingCompilationUnit;
+
+ @override
+ FunctionElement get entryPoint => actualElement.entryPoint;
+
+ @override
+ List<LibraryElement> get exportedLibraries => actualElement.exportedLibraries;
+
+ @override
+ Namespace get exportNamespace => actualElement.exportNamespace;
+
+ @override
+ List<ExportElement> get exports => actualElement.exports;
+
+ @override
+ bool get hasExtUri => actualElement.hasExtUri;
+
+ @override
+ bool get hasLoadLibraryFunction => actualElement.hasLoadLibraryFunction;
+
+ @override
+ String get identifier => location.components.last;
+
+ @override
+ List<LibraryElement> get importedLibraries => actualElement.importedLibraries;
+
+ @override
+ List<ImportElement> get imports => actualElement.imports;
+
+ @override
+ bool get isBrowserApplication => actualElement.isBrowserApplication;
+
+ @override
+ bool get isDartAsync => actualElement.isDartAsync;
+
+ @override
+ bool get isDartCore => actualElement.isDartCore;
+
+ @override
+ bool get isInSdk => actualElement.isInSdk;
+
+ @override
+ ElementKind get kind => ElementKind.LIBRARY;
+
+ @override
+ List<LibraryElement> get libraryCycle => actualElement.libraryCycle;
+
+ @override
+ FunctionElement get loadLibraryFunction => actualElement.loadLibraryFunction;
+
+ @override
+ List<CompilationUnitElement> get parts => actualElement.parts;
+
+ @override
+ List<PrefixElement> get prefixes => actualElement.prefixes;
+
+ @override
+ Namespace get publicNamespace => actualElement.publicNamespace;
+
+ @override
+ List<CompilationUnitElement> get units => actualElement.units;
+
+ @override
+ List<LibraryElement> get visibleLibraries => actualElement.visibleLibraries;
+
+ @override
+ List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) =>
+ actualElement.getImportsWithPrefix(prefixElement);
+
+ @override
+ ClassElement getType(String className) => actualElement.getType(className);
+
+ @override
+ bool isUpToDate(int timeStamp) => actualElement.isUpToDate(timeStamp);
+}
+
+/**
+ * A handle to a [LocalVariableElement].
+ */
+class LocalVariableElementHandle extends VariableElementHandle
+ implements LocalVariableElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ LocalVariableElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ LocalVariableElement get actualElement =>
+ super.actualElement as LocalVariableElement;
+
+ @override
+ ElementKind get kind => ElementKind.LOCAL_VARIABLE;
+
+ @override
+ SourceRange get visibleRange => actualElement.visibleRange;
+
+ @override
+ VariableDeclaration computeNode() => actualElement.computeNode();
+}
+
+/**
+ * A handle to a [MethodElement].
+ */
+class MethodElementHandle extends ExecutableElementHandle
+ implements MethodElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ MethodElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ MethodElement get actualElement => super.actualElement as MethodElement;
+
+ @override
+ ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+
+ @override
+ bool get isStatic => actualElement.isStatic;
+
+ @override
+ ElementKind get kind => ElementKind.METHOD;
+
+ @override
+ MethodDeclaration computeNode() => actualElement.computeNode();
+}
+
+/**
+ * A handle to a [ParameterElement].
+ */
+class ParameterElementHandle extends VariableElementHandle
+ with ParameterElementMixin
+ implements ParameterElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ ParameterElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ ParameterElement get actualElement => super.actualElement as ParameterElement;
+
+ @override
+ String get defaultValueCode => actualElement.defaultValueCode;
+
+ @override
+ bool get isInitializingFormal => actualElement.isInitializingFormal;
+
+ @override
+ ElementKind get kind => ElementKind.PARAMETER;
+
+ @override
+ ParameterKind get parameterKind => actualElement.parameterKind;
+
+ @override
+ List<ParameterElement> get parameters => actualElement.parameters;
+
+ @override
+ List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
+
+ @override
+ SourceRange get visibleRange => actualElement.visibleRange;
+}
+
+/**
+ * A handle to a [PrefixElement].
+ */
+class PrefixElementHandle extends ElementHandle implements PrefixElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ PrefixElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ PrefixElement get actualElement => super.actualElement as PrefixElement;
+
+ @override
+ LibraryElement get enclosingElement =>
+ super.enclosingElement as LibraryElement;
+
+ @override
+ List<LibraryElement> get importedLibraries => LibraryElement.EMPTY_LIST;
+
+ @override
+ ElementKind get kind => ElementKind.PREFIX;
+}
+
+/**
+ * A handle to a [PropertyAccessorElement].
+ */
+class PropertyAccessorElementHandle extends ExecutableElementHandle
+ implements PropertyAccessorElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ PropertyAccessorElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ PropertyAccessorElement get actualElement =>
+ super.actualElement as PropertyAccessorElement;
+
+ @override
+ PropertyAccessorElement get correspondingGetter =>
+ actualElement.correspondingGetter;
+
+ @override
+ PropertyAccessorElement get correspondingSetter =>
+ actualElement.correspondingSetter;
+
+ @override
+ bool get isGetter => actualElement.isGetter;
+
+ @override
+ bool get isSetter => actualElement.isSetter;
+
+ @override
+ ElementKind get kind {
+ if (isGetter) {
+ return ElementKind.GETTER;
+ } else {
+ return ElementKind.SETTER;
+ }
+ }
+
+ @override
+ PropertyInducingElement get variable => actualElement.variable;
+}
+
+/**
+ * A handle to an [PropertyInducingElement].
+ */
+abstract class PropertyInducingElementHandle extends VariableElementHandle
+ implements PropertyInducingElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ PropertyInducingElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ PropertyInducingElement get actualElement =>
+ super.actualElement as PropertyInducingElement;
+
+ @override
+ PropertyAccessorElement get getter => actualElement.getter;
+
+ @override
+ DartType get propagatedType => actualElement.propagatedType;
+
+ @override
+ PropertyAccessorElement get setter => actualElement.setter;
+}
+
+/**
+ * A handle to a [TopLevelVariableElement].
+ */
+class TopLevelVariableElementHandle extends PropertyInducingElementHandle
+ implements TopLevelVariableElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ TopLevelVariableElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
+}
+
+/**
+ * A handle to a [TypeParameterElement].
+ */
+class TypeParameterElementHandle extends ElementHandle
+ implements TypeParameterElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ TypeParameterElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ TypeParameterElement get actualElement =>
+ super.actualElement as TypeParameterElement;
+
+ @override
+ DartType get bound => actualElement.bound;
+
+ @override
+ ElementKind get kind => ElementKind.TYPE_PARAMETER;
+
+ @override
+ TypeParameterType get type => actualElement.type;
+}
+
+/**
+ * A handle to an [VariableElement].
+ */
+abstract class VariableElementHandle extends ElementHandle
+ implements VariableElement {
+ /**
+ * Initialize a newly created element handle to represent the element at the
+ * given [_location]. The [_resynthesizer] will be used to resynthesize the
+ * element when needed.
+ */
+ VariableElementHandle(
+ ElementResynthesizer resynthesizer, ElementLocation location)
+ : super(resynthesizer, location);
+
+ @override
+ VariableElement get actualElement => super.actualElement as VariableElement;
+
+ @override
+ DartObject get constantValue => actualElement.constantValue;
+
+ @override
+ bool get hasImplicitType => actualElement.hasImplicitType;
+
+ @override
+ FunctionElement get initializer => actualElement.initializer;
+
+ @override
+ bool get isConst => actualElement.isConst;
+
+ @override
+ bool get isFinal => actualElement.isFinal;
+
+ @override
+ bool get isPotentiallyMutatedInClosure =>
+ actualElement.isPotentiallyMutatedInClosure;
+
+ @override
+ bool get isPotentiallyMutatedInScope =>
+ actualElement.isPotentiallyMutatedInScope;
+
+ @override
+ bool get isStatic => actualElement.isStatic;
+
+ @override
+ DartType get type => actualElement.type;
+}
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index b0851de..aedd7b2 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -270,66 +270,8 @@
if (name == null || name.length == 0) {
// Function types have an empty name when they are defined implicitly by
// either a closure or as part of a parameter declaration.
- List<DartType> normalParameterTypes = this.normalParameterTypes;
- List<DartType> optionalParameterTypes = this.optionalParameterTypes;
- Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
- DartType returnType = this.returnType;
StringBuffer buffer = new StringBuffer();
- buffer.write("(");
- bool needsComma = false;
- if (normalParameterTypes.length > 0) {
- for (DartType type in normalParameterTypes) {
- if (needsComma) {
- buffer.write(", ");
- } else {
- needsComma = true;
- }
- buffer.write(type.displayName);
- }
- }
- if (optionalParameterTypes.length > 0) {
- if (needsComma) {
- buffer.write(", ");
- needsComma = false;
- }
- buffer.write("[");
- for (DartType type in optionalParameterTypes) {
- if (needsComma) {
- buffer.write(", ");
- } else {
- needsComma = true;
- }
- buffer.write(type.displayName);
- }
- buffer.write("]");
- needsComma = true;
- }
- if (namedParameterTypes.length > 0) {
- if (needsComma) {
- buffer.write(", ");
- needsComma = false;
- }
- buffer.write("{");
- namedParameterTypes.forEach((String name, DartType type) {
- if (needsComma) {
- buffer.write(", ");
- } else {
- needsComma = true;
- }
- buffer.write(name);
- buffer.write(": ");
- buffer.write(type.displayName);
- });
- buffer.write("}");
- needsComma = true;
- }
- buffer.write(")");
- buffer.write(ElementImpl.RIGHT_ARROW);
- if (returnType == null) {
- buffer.write("null");
- } else {
- buffer.write(returnType.displayName);
- }
+ appendTo(buffer);
name = buffer.toString();
}
return name;
@@ -627,47 +569,44 @@
List<DartType> optionalParameterTypes = this.optionalParameterTypes;
Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
DartType returnType = this.returnType;
- buffer.write("(");
+
bool needsComma = false;
- if (normalParameterTypes.isNotEmpty) {
- for (DartType type in normalParameterTypes) {
- if (needsComma) {
- buffer.write(", ");
- } else {
- needsComma = true;
- }
- (type as TypeImpl).appendTo(buffer);
+ void writeSeparator() {
+ if (needsComma) {
+ buffer.write(", ");
+ } else {
+ needsComma = true;
}
}
- if (optionalParameterTypes.isNotEmpty) {
+ void startOptionalParameters() {
if (needsComma) {
buffer.write(", ");
needsComma = false;
}
+ }
+
+ buffer.write("(");
+ if (normalParameterTypes.isNotEmpty) {
+ for (DartType type in normalParameterTypes) {
+ writeSeparator();
+ (type as TypeImpl).appendTo(buffer);
+ }
+ }
+ if (optionalParameterTypes.isNotEmpty) {
+ startOptionalParameters();
buffer.write("[");
for (DartType type in optionalParameterTypes) {
- if (needsComma) {
- buffer.write(", ");
- } else {
- needsComma = true;
- }
+ writeSeparator();
(type as TypeImpl).appendTo(buffer);
}
buffer.write("]");
needsComma = true;
}
if (namedParameterTypes.isNotEmpty) {
- if (needsComma) {
- buffer.write(", ");
- needsComma = false;
- }
+ startOptionalParameters();
buffer.write("{");
namedParameterTypes.forEach((String name, DartType type) {
- if (needsComma) {
- buffer.write(", ");
- } else {
- needsComma = true;
- }
+ writeSeparator();
buffer.write(name);
buffer.write(": ");
(type as TypeImpl).appendTo(buffer);
@@ -800,7 +739,7 @@
TypeParameterTypeImpl.getTypes(this.typeParameters);
for (ParameterElement parameter in baseParameters) {
if (parameter.parameterKind == kind) {
- TypeImpl type = parameter.type;
+ TypeImpl type = parameter.type ?? DynamicTypeImpl.instance;
if (typeArguments.length != 0 &&
typeArguments.length == typeParameters.length) {
type = type.substitute2(typeArguments, typeParameters, newPrune);
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index 18c14d8..3b0eba2 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -12,6 +12,7 @@
* contact the analyzer team to either find an alternate API or have the API you
* depend on added to the public API.
*/
+@deprecated
library analyzer.src.generated.ast;
export 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index db35618..0f1d7e9 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -13,9 +13,9 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/generated/element_handle.dart'
+import 'package:analyzer/src/dart/element/handle.dart'
show ConstructorElementHandle;
+import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/engine.dart'
show AnalysisEngine, RecordingErrorListener;
@@ -1321,8 +1321,8 @@
element is FieldElement &&
node.isFinal &&
!element.isStatic)) {
- if (node.element != null) {
- constantsToCompute.add(node.element);
+ if (element != null) {
+ constantsToCompute.add(element);
}
}
return null;
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 4ff96d5..5518d7c 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -13,6 +13,7 @@
* contact the analyzer team to either find an alternate API or have the API you
* depend on added to the public API.
*/
+@deprecated
library analyzer.src.generated.element;
export 'package:analyzer/dart/element/element.dart';
diff --git a/pkg/analyzer/lib/src/generated/element_handle.dart b/pkg/analyzer/lib/src/generated/element_handle.dart
index 9ed587f..115c44d 100644
--- a/pkg/analyzer/lib/src/generated/element_handle.dart
+++ b/pkg/analyzer/lib/src/generated/element_handle.dart
@@ -2,1101 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+@deprecated
library analyzer.src.generated.element_handle;
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-
-/**
- * Instances of the class `ClassElementHandle` implement a handle to a `ClassElement`.
- */
-class ClassElementHandle extends ElementHandle implements ClassElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- ClassElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- List<PropertyAccessorElement> get accessors => actualElement.accessors;
-
- @override
- ClassElement get actualElement => super.actualElement as ClassElement;
-
- @override
- List<InterfaceType> get allSupertypes => actualElement.allSupertypes;
-
- @override
- List<ConstructorElement> get constructors => actualElement.constructors;
-
- @override
- List<FieldElement> get fields => actualElement.fields;
-
- @override
- bool get hasNonFinalField => actualElement.hasNonFinalField;
-
- @override
- bool get hasReferenceToSuper => actualElement.hasReferenceToSuper;
-
- @override
- bool get hasStaticMember => actualElement.hasStaticMember;
-
- @override
- List<InterfaceType> get interfaces => actualElement.interfaces;
-
- @override
- bool get isAbstract => actualElement.isAbstract;
-
- @override
- bool get isEnum => actualElement.isEnum;
-
- @override
- bool get isMixinApplication => actualElement.isMixinApplication;
-
- @override
- bool get isOrInheritsProxy => actualElement.isOrInheritsProxy;
-
- @override
- bool get isProxy => actualElement.isProxy;
-
- @override
- bool get isValidMixin => actualElement.isValidMixin;
-
- @override
- ElementKind get kind => ElementKind.CLASS;
-
- @override
- List<MethodElement> get methods => actualElement.methods;
-
- @override
- List<InterfaceType> get mixins => actualElement.mixins;
-
- @override
- InterfaceType get supertype => actualElement.supertype;
-
- @override
- InterfaceType get type => actualElement.type;
-
- @override
- List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
-
- @override
- ConstructorElement get unnamedConstructor => actualElement.unnamedConstructor;
-
- @override
- FieldElement getField(String fieldName) => actualElement.getField(fieldName);
-
- @override
- PropertyAccessorElement getGetter(String getterName) =>
- actualElement.getGetter(getterName);
-
- @override
- MethodElement getMethod(String methodName) =>
- actualElement.getMethod(methodName);
-
- @override
- ConstructorElement getNamedConstructor(String name) =>
- actualElement.getNamedConstructor(name);
-
- @override
- PropertyAccessorElement getSetter(String setterName) =>
- actualElement.getSetter(setterName);
-
- @override
- bool isSuperConstructorAccessible(ConstructorElement constructor) =>
- actualElement.isSuperConstructorAccessible(constructor);
-
- @override
- MethodElement lookUpConcreteMethod(
- String methodName, LibraryElement library) =>
- actualElement.lookUpConcreteMethod(methodName, library);
-
- @override
- PropertyAccessorElement lookUpGetter(
- String getterName, LibraryElement library) =>
- actualElement.lookUpGetter(getterName, library);
-
- @override
- PropertyAccessorElement lookUpInheritedConcreteGetter(
- String methodName, LibraryElement library) =>
- actualElement.lookUpInheritedConcreteGetter(methodName, library);
-
- @override
- MethodElement lookUpInheritedConcreteMethod(
- String methodName, LibraryElement library) =>
- actualElement.lookUpInheritedConcreteMethod(methodName, library);
-
- @override
- PropertyAccessorElement lookUpInheritedConcreteSetter(
- String methodName, LibraryElement library) =>
- actualElement.lookUpInheritedConcreteSetter(methodName, library);
-
- @override
- MethodElement lookUpInheritedMethod(
- String methodName, LibraryElement library) =>
- actualElement.lookUpInheritedMethod(methodName, library);
-
- @override
- MethodElement lookUpMethod(String methodName, LibraryElement library) =>
- actualElement.lookUpMethod(methodName, library);
-
- @override
- PropertyAccessorElement lookUpSetter(
- String setterName, LibraryElement library) =>
- actualElement.lookUpSetter(setterName, library);
-}
-
-/**
- * Instances of the class `CompilationUnitElementHandle` implements a handle to a
- * [CompilationUnitElement].
- */
-class CompilationUnitElementHandle extends ElementHandle
- implements CompilationUnitElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- CompilationUnitElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- List<PropertyAccessorElement> get accessors => actualElement.accessors;
-
- @override
- CompilationUnitElement get actualElement =>
- super.actualElement as CompilationUnitElement;
-
- @override
- LibraryElement get enclosingElement =>
- super.enclosingElement as LibraryElement;
-
- @override
- List<ClassElement> get enums => actualElement.enums;
-
- @override
- List<FunctionElement> get functions => actualElement.functions;
-
- @override
- List<FunctionTypeAliasElement> get functionTypeAliases =>
- actualElement.functionTypeAliases;
-
- @override
- bool get hasLoadLibraryFunction => actualElement.hasLoadLibraryFunction;
-
- @override
- ElementKind get kind => ElementKind.COMPILATION_UNIT;
-
- @override
- Source get source => actualElement.source;
-
- @override
- List<TopLevelVariableElement> get topLevelVariables =>
- actualElement.topLevelVariables;
-
- @override
- List<ClassElement> get types => actualElement.types;
-
- @override
- String get uri => actualElement.uri;
-
- @override
- int get uriEnd => actualElement.uriEnd;
-
- @override
- int get uriOffset => actualElement.uriOffset;
-
- @override
- CompilationUnit computeNode() => actualElement.computeNode();
-
- @override
- Element getElementAt(int offset) {
- return actualElement.getElementAt(offset);
- }
-
- @override
- ClassElement getEnum(String enumName) => actualElement.getEnum(enumName);
-
- @override
- ClassElement getType(String className) => actualElement.getType(className);
-}
-
-/**
- * Instances of the class `ConstructorElementHandle` implement a handle to a
- * `ConstructorElement`.
- */
-class ConstructorElementHandle extends ExecutableElementHandle
- implements ConstructorElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- ConstructorElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- ConstructorElement get actualElement =>
- super.actualElement as ConstructorElement;
-
- @override
- ClassElement get enclosingElement => actualElement.enclosingElement;
-
- @override
- bool get isConst => actualElement.isConst;
-
- @override
- bool get isDefaultConstructor => actualElement.isDefaultConstructor;
-
- @override
- bool get isFactory => actualElement.isFactory;
-
- @override
- ElementKind get kind => ElementKind.CONSTRUCTOR;
-
- @override
- int get nameEnd => actualElement.nameEnd;
-
- @override
- int get periodOffset => actualElement.periodOffset;
-
- @override
- ConstructorElement get redirectedConstructor =>
- actualElement.redirectedConstructor;
-
- @override
- ConstructorDeclaration computeNode() => actualElement.computeNode();
-}
-
-/**
- * The abstract class `ElementHandle` implements the behavior common to objects that implement
- * a handle to an [Element].
- */
-abstract class ElementHandle implements Element {
- /**
- * The unique integer identifier of this element.
- */
- final int id = 0;
-
- /**
- * The [ElementResynthesizer] which will be used to resynthesize elements on
- * demand.
- */
- final ElementResynthesizer _resynthesizer;
-
- /**
- * The location of this element, used to reconstitute the element if it has been garbage
- * collected.
- */
- final ElementLocation _location;
-
- /**
- * A reference to the element being referenced by this handle, or `null` if the element has
- * been garbage collected.
- */
- Element _elementReference;
-
- /**
- * Initialize a newly created element handle to represent the element at the
- * given [_location]. [_resynthesizer] will be used to resynthesize the
- * element when needed.
- */
- ElementHandle(this._resynthesizer, this._location);
-
- /**
- * Return the element being represented by this handle, reconstituting the element if the
- * reference has been set to `null`.
- *
- * @return the element being represented by this handle
- */
- Element get actualElement {
- if (_elementReference == null) {
- _elementReference = _resynthesizer.getElement(_location);
- }
- return _elementReference;
- }
-
- @override
- AnalysisContext get context => _resynthesizer.context;
-
- @override
- String get displayName => actualElement.displayName;
-
- @deprecated
- @override
- SourceRange get docRange => actualElement.docRange;
-
- @override
- String get documentationComment => actualElement.documentationComment;
-
- @override
- Element get enclosingElement => actualElement.enclosingElement;
-
- @override
- int get hashCode => _location.hashCode;
-
- @override
- bool get isDeprecated => actualElement.isDeprecated;
-
- @override
- bool get isOverride => actualElement.isOverride;
-
- @override
- bool get isPrivate => actualElement.isPrivate;
-
- @override
- bool get isProtected => actualElement.isProtected;
-
- @override
- bool get isPublic => actualElement.isPublic;
-
- @override
- bool get isSynthetic => actualElement.isSynthetic;
-
- @override
- LibraryElement get library =>
- getAncestor((element) => element is LibraryElement);
-
- @override
- ElementLocation get location => _location;
-
- @override
- List<ElementAnnotation> get metadata => actualElement.metadata;
-
- @override
- String get name => actualElement.name;
-
- @override
- int get nameLength => actualElement.nameLength;
-
- @override
- int get nameOffset => actualElement.nameOffset;
-
- @override
- Source get source => actualElement.source;
-
- @override
- CompilationUnit get unit => actualElement.unit;
-
- @override
- bool operator ==(Object object) =>
- object is Element && object.location == _location;
-
- @override
- accept(ElementVisitor visitor) => actualElement.accept(visitor);
-
- @override
- String computeDocumentationComment() => documentationComment;
-
- @override
- AstNode computeNode() => actualElement.computeNode();
-
- @override
- Element getAncestor(Predicate<Element> predicate) =>
- actualElement.getAncestor(predicate);
-
- @override
- String getExtendedDisplayName(String shortName) =>
- actualElement.getExtendedDisplayName(shortName);
-
- @override
- bool isAccessibleIn(LibraryElement library) =>
- actualElement.isAccessibleIn(library);
-
- @override
- void visitChildren(ElementVisitor visitor) {
- actualElement.visitChildren(visitor);
- }
-}
-
-/**
- * Interface which allows an [Element] handle to be resynthesized based on an
- * [ElementLocation]. The concrete classes implementing element handles use
- * this interface to retrieve the underlying elements when queried.
- */
-abstract class ElementResynthesizer {
- final AnalysisContext context;
-
- ElementResynthesizer(this.context);
-
- Element getElement(ElementLocation location);
-}
-
-/**
- * The abstract class `ExecutableElementHandle` implements the behavior common to objects that
- * implement a handle to an [ExecutableElement].
- */
-abstract class ExecutableElementHandle extends ElementHandle
- implements ExecutableElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- ExecutableElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- ExecutableElement get actualElement =>
- super.actualElement as ExecutableElement;
-
- @override
- List<FunctionElement> get functions => actualElement.functions;
-
- @override
- bool get hasImplicitReturnType => actualElement.hasImplicitReturnType;
-
- @override
- bool get isAbstract => actualElement.isAbstract;
-
- @override
- bool get isAsynchronous => actualElement.isAsynchronous;
-
- @override
- bool get isExternal => actualElement.isExternal;
-
- @override
- bool get isGenerator => actualElement.isGenerator;
-
- @override
- bool get isOperator => actualElement.isOperator;
-
- @override
- bool get isStatic => actualElement.isStatic;
-
- @override
- bool get isSynchronous => actualElement.isSynchronous;
-
- @override
- List<LabelElement> get labels => actualElement.labels;
-
- @override
- List<LocalVariableElement> get localVariables => actualElement.localVariables;
-
- @override
- List<ParameterElement> get parameters => actualElement.parameters;
-
- @override
- DartType get returnType => actualElement.returnType;
-
- @override
- FunctionType get type => actualElement.type;
-
- @override
- List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
-}
-
-/**
- * Instances of the class `ExportElementHandle` implement a handle to an `ExportElement`
- * .
- */
-class ExportElementHandle extends ElementHandle implements ExportElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- ExportElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- ExportElement get actualElement => super.actualElement as ExportElement;
-
- @override
- List<NamespaceCombinator> get combinators => actualElement.combinators;
-
- @override
- LibraryElement get exportedLibrary => actualElement.exportedLibrary;
-
- @override
- ElementKind get kind => ElementKind.EXPORT;
-
- @override
- String get uri => actualElement.uri;
-
- @override
- int get uriEnd => actualElement.uriEnd;
-
- @override
- int get uriOffset => actualElement.uriOffset;
-}
-
-/**
- * Instances of the class `FieldElementHandle` implement a handle to a `FieldElement`.
- */
-class FieldElementHandle extends PropertyInducingElementHandle
- implements FieldElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- FieldElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- FieldElement get actualElement => super.actualElement as FieldElement;
-
- @override
- ClassElement get enclosingElement => actualElement.enclosingElement;
-
- @override
- bool get isEnumConstant => actualElement.isEnumConstant;
-
- @override
- ElementKind get kind => ElementKind.FIELD;
-
- @override
- VariableDeclaration computeNode() => actualElement.computeNode();
-}
-
-/**
- * Instances of the class `FunctionElementHandle` implement a handle to a
- * `FunctionElement`.
- */
-class FunctionElementHandle extends ExecutableElementHandle
- implements FunctionElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- FunctionElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- FunctionElement get actualElement => super.actualElement as FunctionElement;
-
- @override
- bool get isEntryPoint => actualElement.isEntryPoint;
-
- @override
- ElementKind get kind => ElementKind.FUNCTION;
-
- @override
- SourceRange get visibleRange => actualElement.visibleRange;
-
- @override
- FunctionDeclaration computeNode() => actualElement.computeNode();
-}
-
-/**
- * Instances of the class `FunctionTypeAliasElementHandle` implement a handle to a
- * `FunctionTypeAliasElement`.
- */
-class FunctionTypeAliasElementHandle extends ElementHandle
- implements FunctionTypeAliasElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- FunctionTypeAliasElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- FunctionTypeAliasElement get actualElement =>
- super.actualElement as FunctionTypeAliasElement;
-
- @override
- CompilationUnitElement get enclosingElement =>
- super.enclosingElement as CompilationUnitElement;
-
- @override
- ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
-
- @override
- List<ParameterElement> get parameters => actualElement.parameters;
-
- @override
- DartType get returnType => actualElement.returnType;
-
- @override
- FunctionType get type => actualElement.type;
-
- @override
- List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
-
- @override
- FunctionTypeAlias computeNode() => actualElement.computeNode();
-}
-
-/**
- * Instances of the class `ImportElementHandle` implement a handle to an `ImportElement`
- * .
- */
-class ImportElementHandle extends ElementHandle implements ImportElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- ImportElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- ImportElement get actualElement => super.actualElement as ImportElement;
-
- @override
- List<NamespaceCombinator> get combinators => actualElement.combinators;
-
- @override
- LibraryElement get importedLibrary => actualElement.importedLibrary;
-
- @override
- bool get isDeferred => actualElement.isDeferred;
-
- @override
- ElementKind get kind => ElementKind.IMPORT;
-
- @override
- PrefixElement get prefix => actualElement.prefix;
-
- @override
- int get prefixOffset => actualElement.prefixOffset;
-
- @override
- String get uri => actualElement.uri;
-
- @override
- int get uriEnd => actualElement.uriEnd;
-
- @override
- int get uriOffset => actualElement.uriOffset;
-}
-
-/**
- * Instances of the class `LabelElementHandle` implement a handle to a `LabelElement`.
- */
-class LabelElementHandle extends ElementHandle implements LabelElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- LabelElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- ExecutableElement get enclosingElement =>
- super.enclosingElement as ExecutableElement;
-
- @override
- ElementKind get kind => ElementKind.LABEL;
-}
-
-/**
- * Instances of the class `LibraryElementHandle` implement a handle to a
- * `LibraryElement`.
- */
-class LibraryElementHandle extends ElementHandle implements LibraryElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- LibraryElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- LibraryElement get actualElement => super.actualElement as LibraryElement;
-
- @override
- CompilationUnitElement get definingCompilationUnit =>
- actualElement.definingCompilationUnit;
-
- @override
- FunctionElement get entryPoint => actualElement.entryPoint;
-
- @override
- List<LibraryElement> get exportedLibraries => actualElement.exportedLibraries;
-
- @override
- Namespace get exportNamespace => actualElement.exportNamespace;
-
- @override
- List<ExportElement> get exports => actualElement.exports;
-
- @override
- bool get hasExtUri => actualElement.hasExtUri;
-
- @override
- bool get hasLoadLibraryFunction => actualElement.hasLoadLibraryFunction;
-
- @override
- String get identifier => location.components.last;
-
- @override
- List<LibraryElement> get importedLibraries => actualElement.importedLibraries;
-
- @override
- List<ImportElement> get imports => actualElement.imports;
-
- @override
- bool get isBrowserApplication => actualElement.isBrowserApplication;
-
- @override
- bool get isDartAsync => actualElement.isDartAsync;
-
- @override
- bool get isDartCore => actualElement.isDartCore;
-
- @override
- bool get isInSdk => actualElement.isInSdk;
-
- @override
- ElementKind get kind => ElementKind.LIBRARY;
-
- @override
- List<LibraryElement> get libraryCycle => actualElement.libraryCycle;
-
- @override
- FunctionElement get loadLibraryFunction => actualElement.loadLibraryFunction;
-
- @override
- List<CompilationUnitElement> get parts => actualElement.parts;
-
- @override
- List<PrefixElement> get prefixes => actualElement.prefixes;
-
- @override
- Namespace get publicNamespace => actualElement.publicNamespace;
-
- @override
- List<CompilationUnitElement> get units => actualElement.units;
-
- @override
- List<LibraryElement> get visibleLibraries => actualElement.visibleLibraries;
-
- @override
- List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) =>
- actualElement.getImportsWithPrefix(prefixElement);
-
- @override
- ClassElement getType(String className) => actualElement.getType(className);
-
- @override
- bool isUpToDate(int timeStamp) => actualElement.isUpToDate(timeStamp);
-}
-
-/**
- * Instances of the class `LocalVariableElementHandle` implement a handle to a
- * `LocalVariableElement`.
- */
-class LocalVariableElementHandle extends VariableElementHandle
- implements LocalVariableElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- LocalVariableElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- LocalVariableElement get actualElement =>
- super.actualElement as LocalVariableElement;
-
- @override
- ElementKind get kind => ElementKind.LOCAL_VARIABLE;
-
- @override
- SourceRange get visibleRange => actualElement.visibleRange;
-
- @override
- VariableDeclaration computeNode() => actualElement.computeNode();
-}
-
-/**
- * Instances of the class `MethodElementHandle` implement a handle to a `MethodElement`.
- */
-class MethodElementHandle extends ExecutableElementHandle
- implements MethodElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- MethodElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- MethodElement get actualElement => super.actualElement as MethodElement;
-
- @override
- ClassElement get enclosingElement => super.enclosingElement as ClassElement;
-
- @override
- bool get isStatic => actualElement.isStatic;
-
- @override
- ElementKind get kind => ElementKind.METHOD;
-
- @override
- MethodDeclaration computeNode() => actualElement.computeNode();
-}
-
-/**
- * Instances of the class `ParameterElementHandle` implement a handle to a
- * `ParameterElement`.
- */
-class ParameterElementHandle extends VariableElementHandle
- with ParameterElementMixin
- implements ParameterElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- ParameterElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- ParameterElement get actualElement => super.actualElement as ParameterElement;
-
- @override
- String get defaultValueCode => actualElement.defaultValueCode;
-
- @override
- bool get isInitializingFormal => actualElement.isInitializingFormal;
-
- @override
- ElementKind get kind => ElementKind.PARAMETER;
-
- @override
- ParameterKind get parameterKind => actualElement.parameterKind;
-
- @override
- List<ParameterElement> get parameters => actualElement.parameters;
-
- @override
- List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
-
- @override
- SourceRange get visibleRange => actualElement.visibleRange;
-}
-
-/**
- * Instances of the class `PrefixElementHandle` implement a handle to a `PrefixElement`.
- */
-class PrefixElementHandle extends ElementHandle implements PrefixElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- PrefixElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- PrefixElement get actualElement => super.actualElement as PrefixElement;
-
- @override
- LibraryElement get enclosingElement =>
- super.enclosingElement as LibraryElement;
-
- @override
- List<LibraryElement> get importedLibraries => LibraryElement.EMPTY_LIST;
-
- @override
- ElementKind get kind => ElementKind.PREFIX;
-}
-
-/**
- * Instances of the class `PropertyAccessorElementHandle` implement a handle to a
- * `PropertyAccessorElement`.
- */
-class PropertyAccessorElementHandle extends ExecutableElementHandle
- implements PropertyAccessorElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- PropertyAccessorElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- PropertyAccessorElement get actualElement =>
- super.actualElement as PropertyAccessorElement;
-
- @override
- PropertyAccessorElement get correspondingGetter =>
- actualElement.correspondingGetter;
-
- @override
- PropertyAccessorElement get correspondingSetter =>
- actualElement.correspondingSetter;
-
- @override
- bool get isGetter => actualElement.isGetter;
-
- @override
- bool get isSetter => actualElement.isSetter;
-
- @override
- ElementKind get kind {
- if (isGetter) {
- return ElementKind.GETTER;
- } else {
- return ElementKind.SETTER;
- }
- }
-
- @override
- PropertyInducingElement get variable => actualElement.variable;
-}
-
-/**
- * The abstract class `PropertyInducingElementHandle` implements the behavior common to
- * objects that implement a handle to an `PropertyInducingElement`.
- */
-abstract class PropertyInducingElementHandle extends VariableElementHandle
- implements PropertyInducingElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- PropertyInducingElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- PropertyInducingElement get actualElement =>
- super.actualElement as PropertyInducingElement;
-
- @override
- PropertyAccessorElement get getter => actualElement.getter;
-
- @override
- DartType get propagatedType => actualElement.propagatedType;
-
- @override
- PropertyAccessorElement get setter => actualElement.setter;
-}
-
-/**
- * Instances of the class `TopLevelVariableElementHandle` implement a handle to a
- * `TopLevelVariableElement`.
- */
-class TopLevelVariableElementHandle extends PropertyInducingElementHandle
- implements TopLevelVariableElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- TopLevelVariableElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
-}
-
-/**
- * Instances of the class `TypeParameterElementHandle` implement a handle to a
- * [TypeParameterElement].
- */
-class TypeParameterElementHandle extends ElementHandle
- implements TypeParameterElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- TypeParameterElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- TypeParameterElement get actualElement =>
- super.actualElement as TypeParameterElement;
-
- @override
- DartType get bound => actualElement.bound;
-
- @override
- ElementKind get kind => ElementKind.TYPE_PARAMETER;
-
- @override
- TypeParameterType get type => actualElement.type;
-}
-
-/**
- * The abstract class `VariableElementHandle` implements the behavior common to objects that
- * implement a handle to an `VariableElement`.
- */
-abstract class VariableElementHandle extends ElementHandle
- implements VariableElement {
- /**
- * Initialize a newly created element handle to represent the given element.
- *
- * @param element the element being represented
- */
- VariableElementHandle(
- ElementResynthesizer resynthesizer, ElementLocation location)
- : super(resynthesizer, location);
-
- @override
- VariableElement get actualElement => super.actualElement as VariableElement;
-
- @override
- DartObject get constantValue => actualElement.constantValue;
-
- @override
- bool get hasImplicitType => actualElement.hasImplicitType;
-
- @override
- FunctionElement get initializer => actualElement.initializer;
-
- @override
- bool get isConst => actualElement.isConst;
-
- @override
- bool get isFinal => actualElement.isFinal;
-
- @override
- bool get isPotentiallyMutatedInClosure =>
- actualElement.isPotentiallyMutatedInClosure;
-
- @override
- bool get isPotentiallyMutatedInScope =>
- actualElement.isPotentiallyMutatedInScope;
-
- @override
- bool get isStatic => actualElement.isStatic;
-
- @override
- DartType get type => actualElement.type;
-}
+export 'package:analyzer/src/dart/element/handle.dart';
/**
* TODO(scheglov) invalid implementation
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 7d77680..0219d7e 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -11,6 +11,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart' show ScannerErrorCode;
import 'package:analyzer/src/generated/generated/shared_messages.dart'
as shared_messages;
@@ -3059,6 +3060,9 @@
* The unique name of this error code.
*/
String get uniqueName => "$runtimeType.$name";
+
+ @override
+ String toString() => uniqueName;
}
/**
@@ -3239,6 +3243,18 @@
* clarify the message.
*/
void _convertTypeNames(List<Object> arguments) {
+ String displayName(DartType type) {
+ if (type is FunctionType) {
+ String name = type.name;
+ if (name != null && name.length > 0) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write(name);
+ (type as TypeImpl).appendTo(buffer);
+ return buffer.toString();
+ }
+ }
+ return type.displayName;
+ }
if (_hasEqualTypeNames(arguments)) {
int count = arguments.length;
for (int i = 0; i < count; i++) {
@@ -3247,9 +3263,9 @@
DartType type = argument;
Element element = type.element;
if (element == null) {
- arguments[i] = type.displayName;
+ arguments[i] = displayName(type);
} else {
- arguments[i] = element.getExtendedDisplayName(type.displayName);
+ arguments[i] = element.getExtendedDisplayName(displayName(type));
}
}
}
@@ -3258,7 +3274,7 @@
for (int i = 0; i < count; i++) {
Object argument = arguments[i];
if (argument is DartType) {
- arguments[i] = argument.displayName;
+ arguments[i] = displayName(argument);
}
}
}
@@ -3578,7 +3594,7 @@
static const HintCode MUST_CALL_SUPER = const HintCode(
'MUST_CALL_SUPER',
"This method overrides a method annotated as @mustCall super in '{0}', "
- "but does invoke the overriden method");
+ "but does invoke the overriden method");
/**
* A condition in a control flow statement could evaluate to `null` because it
@@ -4406,8 +4422,8 @@
* 1: The sequence type -- Iterable for `for` or Stream for `await for`.
*/
static const StaticTypeWarningCode FOR_IN_OF_INVALID_TYPE =
- const StaticTypeWarningCode('FOR_IN_OF_INVALID_TYPE',
- "The type '{0}' used in the 'for' loop must implement {1}");
+ const StaticTypeWarningCode('FOR_IN_OF_INVALID_TYPE',
+ "The type '{0}' used in the 'for' loop must implement {1}");
/**
* 17.6.2 For-in. It the iterable expression does not implement Iterable with
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 7d0c52b..efd0f93 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -846,8 +846,9 @@
}
}
_checkForExpectedOneListTypeArgument(node, typeArguments);
- _checkForListElementTypeNotAssignable(node, typeArguments);
}
+
+ _checkForListElementTypeNotAssignable(node);
return super.visitListLiteral(node);
}
@@ -863,8 +864,9 @@
}
}
_checkExpectedTwoMapTypeArguments(typeArguments);
- _checkForMapTypeNotAssignable(node, typeArguments);
}
+
+ _checkForMapTypeNotAssignable(node);
_checkForNonConstMapAsExpressionStatement(node);
return super.visitMapLiteral(node);
}
@@ -4038,63 +4040,62 @@
}
/**
- * Verify that the elements given list [literal] are subtypes of the specified
- * element type. The [typeArguments] are the type arguments.
+ * Verify that the elements given list [literal] are subtypes of the list's
+ * static type.
*
* See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and
* [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE].
*/
- bool _checkForListElementTypeNotAssignable(
- ListLiteral literal, TypeArgumentList typeArguments) {
- NodeList<TypeName> typeNames = typeArguments.arguments;
- if (typeNames.length < 1) {
- return false;
- }
- DartType listElementType = typeNames[0].type;
+ void _checkForListElementTypeNotAssignable(ListLiteral literal) {
+ // Determine the list's element type. We base this on the static type and
+ // not the literal's type arguments because in strong mode, the type
+ // arguments may be inferred.
+ DartType listType = literal.staticType;
+ assert(listType is InterfaceTypeImpl);
+
+ List<DartType> typeArguments =
+ (listType as InterfaceTypeImpl).typeArguments;
+ assert(typeArguments.length == 1);
+
+ DartType listElementType = typeArguments[0];
+
// Check every list element.
- bool hasProblems = false;
for (Expression element in literal.elements) {
if (literal.constKeyword != null) {
// TODO(paulberry): this error should be based on the actual type of the
// list element, not the static type. See dartbug.com/21119.
- if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
+ _checkForArgumentTypeNotAssignableWithExpectedTypes(
element,
listElementType,
- CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) {
- hasProblems = true;
- }
+ CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE);
}
- if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
- element,
- listElementType,
- StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) {
- hasProblems = true;
- }
+ _checkForArgumentTypeNotAssignableWithExpectedTypes(element,
+ listElementType, StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE);
}
- return hasProblems;
}
/**
* Verify that the key/value of entries of the given map [literal] are
- * subtypes of the key/value types specified in the type arguments. The
- * [typeArguments] are the type arguments.
+ * subtypes of the map's static type.
*
* See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
* [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
* [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
* [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
*/
- bool _checkForMapTypeNotAssignable(
- MapLiteral literal, TypeArgumentList typeArguments) {
- // Prepare maps key/value types.
- NodeList<TypeName> typeNames = typeArguments.arguments;
- if (typeNames.length < 2) {
- return false;
- }
- DartType keyType = typeNames[0].type;
- DartType valueType = typeNames[1].type;
- // Check every map entry.
- bool hasProblems = false;
+ void _checkForMapTypeNotAssignable(MapLiteral literal) {
+ // Determine the map's key and value types. We base this on the static type
+ // and not the literal's type arguments because in strong mode, the type
+ // arguments may be inferred.
+ DartType mapType = literal.staticType;
+ assert(mapType is InterfaceTypeImpl);
+
+ List<DartType> typeArguments =
+ (mapType as InterfaceTypeImpl).typeArguments;
+ assert(typeArguments.length == 2);
+ DartType keyType = typeArguments[0];
+ DartType valueType = typeArguments[1];
+
NodeList<MapLiteralEntry> entries = literal.entries;
for (MapLiteralEntry entry in entries) {
Expression key = entry.key;
@@ -4102,27 +4103,18 @@
if (literal.constKeyword != null) {
// TODO(paulberry): this error should be based on the actual type of the
// list element, not the static type. See dartbug.com/21119.
- if (_checkForArgumentTypeNotAssignableWithExpectedTypes(key, keyType,
- CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) {
- hasProblems = true;
- }
- if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
+ _checkForArgumentTypeNotAssignableWithExpectedTypes(key, keyType,
+ CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE);
+ _checkForArgumentTypeNotAssignableWithExpectedTypes(
value,
valueType,
- CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) {
- hasProblems = true;
- }
+ CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE);
}
- if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
- key, keyType, StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) {
- hasProblems = true;
- }
- if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
- value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) {
- hasProblems = true;
- }
+ _checkForArgumentTypeNotAssignableWithExpectedTypes(
+ key, keyType, StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE);
+ _checkForArgumentTypeNotAssignableWithExpectedTypes(
+ value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE);
}
- return hasProblems;
}
/**
@@ -5193,7 +5185,7 @@
}
/**
- * Check the given [typeReference] and that the [name] is not the reference to
+ * Check the given [typeReference] and that the [name] is not a reference to
* an instance member.
*
* See [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER].
@@ -5694,25 +5686,23 @@
: _typeProvider.iterableType;
// Use an explicit string instead of [loopType] to remove the "<E>".
- String loopTypeName = node.awaitKeyword != null
- ? "Stream"
- : "Iterable";
+ String loopTypeName = node.awaitKeyword != null ? "Stream" : "Iterable";
// The object being iterated has to implement Iterable<T> for some T that
// is assignable to the variable's type.
// TODO(rnystrom): Move this into mostSpecificTypeArgument()?
iterableType = iterableType.resolveToBound(_typeProvider.objectType);
- DartType bestIterableType = _typeSystem.mostSpecificTypeArgument(
- iterableType, loopType);
+ DartType bestIterableType =
+ _typeSystem.mostSpecificTypeArgument(iterableType, loopType);
if (bestIterableType == null) {
_errorReporter.reportTypeErrorForNode(
StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE,
- node,
+ node.iterable,
[iterableType, loopTypeName]);
} else if (!_typeSystem.isAssignableTo(bestIterableType, variableType)) {
_errorReporter.reportTypeErrorForNode(
StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE,
- node,
+ node.iterable,
[iterableType, loopTypeName, variableType]);
}
}
diff --git a/pkg/analyzer/lib/src/generated/incremental_scanner.dart b/pkg/analyzer/lib/src/generated/incremental_scanner.dart
index ae34471..a0bd238 100644
--- a/pkg/analyzer/lib/src/generated/incremental_scanner.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_scanner.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+@deprecated
library analyzer.src.generated.incremental_scanner;
import "dart:math" as math;
@@ -18,6 +19,7 @@
* An `IncrementalScanner` is a scanner that scans a subset of a string and
* inserts the resulting tokens into the middle of an existing token stream.
*/
+@deprecated
class IncrementalScanner {
/**
* The source being scanned.
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 9eff933..adf9a73 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -26,6 +26,8 @@
import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
import 'package:analyzer/src/generated/utilities_dart.dart';
+export 'package:analyzer/src/dart/ast/utilities.dart' show ResolutionCopier;
+
Map<String, MethodTrampoline> methodTable_Parser = <String, MethodTrampoline>{
'parseCompilationUnit_1': new MethodTrampoline(
1, (Parser target, arg0) => target.parseCompilationUnit(arg0)),
@@ -525,6 +527,7 @@
* the methods will throw an [IncrementalParseException] if the node could not
* be parsed for some reason.
*/
+@deprecated
class IncrementalParseDispatcher implements AstVisitor<AstNode> {
/**
* The parser used to parse the replacement for the node.
@@ -1662,6 +1665,7 @@
* An exception that occurred while attempting to parse a replacement for a
* specified node in an existing AST structure.
*/
+@deprecated
class IncrementalParseException extends RuntimeException {
/**
* Initialize a newly created exception to have no message and to be its own
@@ -1686,6 +1690,7 @@
* An object used to re-parse a single AST structure within a larger AST
* structure.
*/
+@deprecated
class IncrementalParser {
/**
* The source being parsed.
@@ -1857,6 +1862,7 @@
* given parent. Once it has visited all of these relationships, the parser
* will be in the correct state for reparsing the node to be replaced.
*/
+@deprecated
class IncrementalParseStateBuilder extends SimpleAstVisitor {
// TODO(paulberry): add support for other pieces of parser state (_inAsync,
// _inGenerator, _inLoop, and _inSwitch). Note that _inLoop and _inSwitch
@@ -1948,6 +1954,7 @@
* not enough context to know how to re-parse the node. Clients can attempt to
* re-parse the parent of the node.
*/
+@deprecated
class InsufficientContextException extends IncrementalParseException {
/**
* Initialize a newly created exception to have no message and to be its own
@@ -9939,1423 +9946,3 @@
@override
ErrorType get type => ErrorType.SYNTACTIC_ERROR;
}
-
-/**
- * An object that copies resolution information from one AST structure to
- * another as long as the structures of the corresponding children of a pair of
- * nodes are the same.
- */
-class ResolutionCopier implements AstVisitor<bool> {
- /**
- * The AST node with which the node being visited is to be compared. This is
- * only valid at the beginning of each visit method (until [isEqualNodes] is
- * invoked).
- */
- AstNode _toNode;
-
- @override
- bool visitAdjacentStrings(AdjacentStrings node) {
- AdjacentStrings toNode = this._toNode as AdjacentStrings;
- if (_isEqualNodeLists(node.strings, toNode.strings)) {
- toNode.staticType = node.staticType;
- toNode.propagatedType = node.propagatedType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitAnnotation(Annotation node) {
- Annotation toNode = this._toNode as Annotation;
- if (_and(
- _isEqualTokens(node.atSign, toNode.atSign),
- _isEqualNodes(node.name, toNode.name),
- _isEqualTokens(node.period, toNode.period),
- _isEqualNodes(node.constructorName, toNode.constructorName),
- _isEqualNodes(node.arguments, toNode.arguments))) {
- toNode.element = node.element;
- return true;
- }
- return false;
- }
-
- @override
- bool visitArgumentList(ArgumentList node) {
- ArgumentList toNode = this._toNode as ArgumentList;
- return _and(
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodeLists(node.arguments, toNode.arguments),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis));
- }
-
- @override
- bool visitAsExpression(AsExpression node) {
- AsExpression toNode = this._toNode as AsExpression;
- if (_and(
- _isEqualNodes(node.expression, toNode.expression),
- _isEqualTokens(node.asOperator, toNode.asOperator),
- _isEqualNodes(node.type, toNode.type))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitAssertStatement(AssertStatement node) {
- AssertStatement toNode = this._toNode as AssertStatement;
- return _and(
- _isEqualTokens(node.assertKeyword, toNode.assertKeyword),
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodes(node.condition, toNode.condition),
- _isEqualTokens(node.comma, toNode.comma),
- _isEqualNodes(node.message, toNode.message),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitAssignmentExpression(AssignmentExpression node) {
- AssignmentExpression toNode = this._toNode as AssignmentExpression;
- if (_and(
- _isEqualNodes(node.leftHandSide, toNode.leftHandSide),
- _isEqualTokens(node.operator, toNode.operator),
- _isEqualNodes(node.rightHandSide, toNode.rightHandSide))) {
- toNode.propagatedElement = node.propagatedElement;
- toNode.propagatedType = node.propagatedType;
- toNode.staticElement = node.staticElement;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitAwaitExpression(AwaitExpression node) {
- AwaitExpression toNode = this._toNode as AwaitExpression;
- if (_and(_isEqualTokens(node.awaitKeyword, toNode.awaitKeyword),
- _isEqualNodes(node.expression, toNode.expression))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitBinaryExpression(BinaryExpression node) {
- BinaryExpression toNode = this._toNode as BinaryExpression;
- if (_and(
- _isEqualNodes(node.leftOperand, toNode.leftOperand),
- _isEqualTokens(node.operator, toNode.operator),
- _isEqualNodes(node.rightOperand, toNode.rightOperand))) {
- toNode.propagatedElement = node.propagatedElement;
- toNode.propagatedType = node.propagatedType;
- toNode.staticElement = node.staticElement;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitBlock(Block node) {
- Block toNode = this._toNode as Block;
- return _and(
- _isEqualTokens(node.leftBracket, toNode.leftBracket),
- _isEqualNodeLists(node.statements, toNode.statements),
- _isEqualTokens(node.rightBracket, toNode.rightBracket));
- }
-
- @override
- bool visitBlockFunctionBody(BlockFunctionBody node) {
- BlockFunctionBody toNode = this._toNode as BlockFunctionBody;
- return _isEqualNodes(node.block, toNode.block);
- }
-
- @override
- bool visitBooleanLiteral(BooleanLiteral node) {
- BooleanLiteral toNode = this._toNode as BooleanLiteral;
- if (_and(_isEqualTokens(node.literal, toNode.literal),
- node.value == toNode.value)) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitBreakStatement(BreakStatement node) {
- BreakStatement toNode = this._toNode as BreakStatement;
- if (_and(
- _isEqualTokens(node.breakKeyword, toNode.breakKeyword),
- _isEqualNodes(node.label, toNode.label),
- _isEqualTokens(node.semicolon, toNode.semicolon))) {
- // TODO(paulberry): map node.target to toNode.target.
- return true;
- }
- return false;
- }
-
- @override
- bool visitCascadeExpression(CascadeExpression node) {
- CascadeExpression toNode = this._toNode as CascadeExpression;
- if (_and(_isEqualNodes(node.target, toNode.target),
- _isEqualNodeLists(node.cascadeSections, toNode.cascadeSections))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitCatchClause(CatchClause node) {
- CatchClause toNode = this._toNode as CatchClause;
- return _and(
- _isEqualTokens(node.onKeyword, toNode.onKeyword),
- _isEqualNodes(node.exceptionType, toNode.exceptionType),
- _isEqualTokens(node.catchKeyword, toNode.catchKeyword),
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodes(node.exceptionParameter, toNode.exceptionParameter),
- _isEqualTokens(node.comma, toNode.comma),
- _isEqualNodes(node.stackTraceParameter, toNode.stackTraceParameter),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
- _isEqualNodes(node.body, toNode.body));
- }
-
- @override
- bool visitClassDeclaration(ClassDeclaration node) {
- ClassDeclaration toNode = this._toNode as ClassDeclaration;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.abstractKeyword, toNode.abstractKeyword),
- _isEqualTokens(node.classKeyword, toNode.classKeyword),
- _isEqualNodes(node.name, toNode.name),
- _isEqualNodes(node.typeParameters, toNode.typeParameters),
- _isEqualNodes(node.extendsClause, toNode.extendsClause),
- _isEqualNodes(node.withClause, toNode.withClause),
- _isEqualNodes(node.implementsClause, toNode.implementsClause),
- _isEqualTokens(node.leftBracket, toNode.leftBracket),
- _isEqualNodeLists(node.members, toNode.members),
- _isEqualTokens(node.rightBracket, toNode.rightBracket));
- }
-
- @override
- bool visitClassTypeAlias(ClassTypeAlias node) {
- ClassTypeAlias toNode = this._toNode as ClassTypeAlias;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.typedefKeyword, toNode.typedefKeyword),
- _isEqualNodes(node.name, toNode.name),
- _isEqualNodes(node.typeParameters, toNode.typeParameters),
- _isEqualTokens(node.equals, toNode.equals),
- _isEqualTokens(node.abstractKeyword, toNode.abstractKeyword),
- _isEqualNodes(node.superclass, toNode.superclass),
- _isEqualNodes(node.withClause, toNode.withClause),
- _isEqualNodes(node.implementsClause, toNode.implementsClause),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitComment(Comment node) {
- Comment toNode = this._toNode as Comment;
- return _isEqualNodeLists(node.references, toNode.references);
- }
-
- @override
- bool visitCommentReference(CommentReference node) {
- CommentReference toNode = this._toNode as CommentReference;
- return _and(_isEqualTokens(node.newKeyword, toNode.newKeyword),
- _isEqualNodes(node.identifier, toNode.identifier));
- }
-
- @override
- bool visitCompilationUnit(CompilationUnit node) {
- CompilationUnit toNode = this._toNode as CompilationUnit;
- if (_and(
- _isEqualTokens(node.beginToken, toNode.beginToken),
- _isEqualNodes(node.scriptTag, toNode.scriptTag),
- _isEqualNodeLists(node.directives, toNode.directives),
- _isEqualNodeLists(node.declarations, toNode.declarations),
- _isEqualTokens(node.endToken, toNode.endToken))) {
- toNode.element = node.element;
- return true;
- }
- return false;
- }
-
- @override
- bool visitConditionalExpression(ConditionalExpression node) {
- ConditionalExpression toNode = this._toNode as ConditionalExpression;
- if (_and(
- _isEqualNodes(node.condition, toNode.condition),
- _isEqualTokens(node.question, toNode.question),
- _isEqualNodes(node.thenExpression, toNode.thenExpression),
- _isEqualTokens(node.colon, toNode.colon),
- _isEqualNodes(node.elseExpression, toNode.elseExpression))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitConfiguration(Configuration node) {
- Configuration toNode = this._toNode as Configuration;
- if (_and(
- _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodes(node.name, toNode.name),
- _isEqualTokens(node.equalToken, toNode.equalToken),
- _isEqualNodes(node.value, toNode.value),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
- _isEqualNodes(node.libraryUri, toNode.libraryUri))) {
- return true;
- }
- return false;
- }
-
- @override
- bool visitConstructorDeclaration(ConstructorDeclaration node) {
- ConstructorDeclaration toNode = this._toNode as ConstructorDeclaration;
- if (_and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
- _isEqualTokens(node.constKeyword, toNode.constKeyword),
- _isEqualTokens(node.factoryKeyword, toNode.factoryKeyword),
- _isEqualNodes(node.returnType, toNode.returnType),
- _isEqualTokens(node.period, toNode.period),
- _isEqualNodes(node.name, toNode.name),
- _isEqualNodes(node.parameters, toNode.parameters),
- _isEqualTokens(node.separator, toNode.separator),
- _isEqualNodeLists(node.initializers, toNode.initializers),
- _isEqualNodes(node.redirectedConstructor, toNode.redirectedConstructor),
- _isEqualNodes(node.body, toNode.body))) {
- toNode.element = node.element;
- return true;
- }
- return false;
- }
-
- @override
- bool visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
- ConstructorFieldInitializer toNode =
- this._toNode as ConstructorFieldInitializer;
- return _and(
- _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
- _isEqualTokens(node.period, toNode.period),
- _isEqualNodes(node.fieldName, toNode.fieldName),
- _isEqualTokens(node.equals, toNode.equals),
- _isEqualNodes(node.expression, toNode.expression));
- }
-
- @override
- bool visitConstructorName(ConstructorName node) {
- ConstructorName toNode = this._toNode as ConstructorName;
- if (_and(
- _isEqualNodes(node.type, toNode.type),
- _isEqualTokens(node.period, toNode.period),
- _isEqualNodes(node.name, toNode.name))) {
- toNode.staticElement = node.staticElement;
- return true;
- }
- return false;
- }
-
- @override
- bool visitContinueStatement(ContinueStatement node) {
- ContinueStatement toNode = this._toNode as ContinueStatement;
- if (_and(
- _isEqualTokens(node.continueKeyword, toNode.continueKeyword),
- _isEqualNodes(node.label, toNode.label),
- _isEqualTokens(node.semicolon, toNode.semicolon))) {
- // TODO(paulberry): map node.target to toNode.target.
- return true;
- }
- return false;
- }
-
- @override
- bool visitDeclaredIdentifier(DeclaredIdentifier node) {
- DeclaredIdentifier toNode = this._toNode as DeclaredIdentifier;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.keyword, toNode.keyword),
- _isEqualNodes(node.type, toNode.type),
- _isEqualNodes(node.identifier, toNode.identifier));
- }
-
- @override
- bool visitDefaultFormalParameter(DefaultFormalParameter node) {
- DefaultFormalParameter toNode = this._toNode as DefaultFormalParameter;
- return _and(
- _isEqualNodes(node.parameter, toNode.parameter),
- node.kind == toNode.kind,
- _isEqualTokens(node.separator, toNode.separator),
- _isEqualNodes(node.defaultValue, toNode.defaultValue));
- }
-
- @override
- bool visitDoStatement(DoStatement node) {
- DoStatement toNode = this._toNode as DoStatement;
- return _and(
- _isEqualTokens(node.doKeyword, toNode.doKeyword),
- _isEqualNodes(node.body, toNode.body),
- _isEqualTokens(node.whileKeyword, toNode.whileKeyword),
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodes(node.condition, toNode.condition),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitDottedName(DottedName node) {
- DottedName toNode = this._toNode as DottedName;
- return _isEqualNodeLists(node.components, toNode.components);
- }
-
- @override
- bool visitDoubleLiteral(DoubleLiteral node) {
- DoubleLiteral toNode = this._toNode as DoubleLiteral;
- if (_and(_isEqualTokens(node.literal, toNode.literal),
- node.value == toNode.value)) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitEmptyFunctionBody(EmptyFunctionBody node) {
- EmptyFunctionBody toNode = this._toNode as EmptyFunctionBody;
- return _isEqualTokens(node.semicolon, toNode.semicolon);
- }
-
- @override
- bool visitEmptyStatement(EmptyStatement node) {
- EmptyStatement toNode = this._toNode as EmptyStatement;
- return _isEqualTokens(node.semicolon, toNode.semicolon);
- }
-
- @override
- bool visitEnumConstantDeclaration(EnumConstantDeclaration node) {
- EnumConstantDeclaration toNode = this._toNode as EnumConstantDeclaration;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualNodes(node.name, toNode.name));
- }
-
- @override
- bool visitEnumDeclaration(EnumDeclaration node) {
- EnumDeclaration toNode = this._toNode as EnumDeclaration;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.enumKeyword, toNode.enumKeyword),
- _isEqualNodes(node.name, toNode.name),
- _isEqualTokens(node.leftBracket, toNode.leftBracket),
- _isEqualNodeLists(node.constants, toNode.constants),
- _isEqualTokens(node.rightBracket, toNode.rightBracket));
- }
-
- @override
- bool visitExportDirective(ExportDirective node) {
- ExportDirective toNode = this._toNode as ExportDirective;
- if (_and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.keyword, toNode.keyword),
- _isEqualNodes(node.uri, toNode.uri),
- _isEqualNodeLists(node.combinators, toNode.combinators),
- _isEqualTokens(node.semicolon, toNode.semicolon))) {
- toNode.element = node.element;
- return true;
- }
- return false;
- }
-
- @override
- bool visitExpressionFunctionBody(ExpressionFunctionBody node) {
- ExpressionFunctionBody toNode = this._toNode as ExpressionFunctionBody;
- return _and(
- _isEqualTokens(node.functionDefinition, toNode.functionDefinition),
- _isEqualNodes(node.expression, toNode.expression),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitExpressionStatement(ExpressionStatement node) {
- ExpressionStatement toNode = this._toNode as ExpressionStatement;
- return _and(_isEqualNodes(node.expression, toNode.expression),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitExtendsClause(ExtendsClause node) {
- ExtendsClause toNode = this._toNode as ExtendsClause;
- return _and(_isEqualTokens(node.extendsKeyword, toNode.extendsKeyword),
- _isEqualNodes(node.superclass, toNode.superclass));
- }
-
- @override
- bool visitFieldDeclaration(FieldDeclaration node) {
- FieldDeclaration toNode = this._toNode as FieldDeclaration;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.staticKeyword, toNode.staticKeyword),
- _isEqualNodes(node.fields, toNode.fields),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitFieldFormalParameter(FieldFormalParameter node) {
- FieldFormalParameter toNode = this._toNode as FieldFormalParameter;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.keyword, toNode.keyword),
- _isEqualNodes(node.type, toNode.type),
- _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
- _isEqualTokens(node.period, toNode.period),
- _isEqualNodes(node.identifier, toNode.identifier));
- }
-
- @override
- bool visitForEachStatement(ForEachStatement node) {
- ForEachStatement toNode = this._toNode as ForEachStatement;
- return _and(
- _isEqualTokens(node.forKeyword, toNode.forKeyword),
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodes(node.loopVariable, toNode.loopVariable),
- _isEqualTokens(node.inKeyword, toNode.inKeyword),
- _isEqualNodes(node.iterable, toNode.iterable),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
- _isEqualNodes(node.body, toNode.body));
- }
-
- @override
- bool visitFormalParameterList(FormalParameterList node) {
- FormalParameterList toNode = this._toNode as FormalParameterList;
- return _and(
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodeLists(node.parameters, toNode.parameters),
- _isEqualTokens(node.leftDelimiter, toNode.leftDelimiter),
- _isEqualTokens(node.rightDelimiter, toNode.rightDelimiter),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis));
- }
-
- @override
- bool visitForStatement(ForStatement node) {
- ForStatement toNode = this._toNode as ForStatement;
- return _and(
- _isEqualTokens(node.forKeyword, toNode.forKeyword),
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodes(node.variables, toNode.variables),
- _isEqualNodes(node.initialization, toNode.initialization),
- _isEqualTokens(node.leftSeparator, toNode.leftSeparator),
- _isEqualNodes(node.condition, toNode.condition),
- _isEqualTokens(node.rightSeparator, toNode.rightSeparator),
- _isEqualNodeLists(node.updaters, toNode.updaters),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
- _isEqualNodes(node.body, toNode.body));
- }
-
- @override
- bool visitFunctionDeclaration(FunctionDeclaration node) {
- FunctionDeclaration toNode = this._toNode as FunctionDeclaration;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
- _isEqualNodes(node.returnType, toNode.returnType),
- _isEqualTokens(node.propertyKeyword, toNode.propertyKeyword),
- _isEqualNodes(node.name, toNode.name),
- _isEqualNodes(node.functionExpression, toNode.functionExpression));
- }
-
- @override
- bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
- FunctionDeclarationStatement toNode =
- this._toNode as FunctionDeclarationStatement;
- return _isEqualNodes(node.functionDeclaration, toNode.functionDeclaration);
- }
-
- @override
- bool visitFunctionExpression(FunctionExpression node) {
- FunctionExpression toNode = this._toNode as FunctionExpression;
- if (_and(_isEqualNodes(node.parameters, toNode.parameters),
- _isEqualNodes(node.body, toNode.body))) {
- toNode.element = node.element;
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
- FunctionExpressionInvocation toNode =
- this._toNode as FunctionExpressionInvocation;
- if (_and(_isEqualNodes(node.function, toNode.function),
- _isEqualNodes(node.argumentList, toNode.argumentList))) {
- toNode.propagatedElement = node.propagatedElement;
- toNode.propagatedInvokeType = node.propagatedInvokeType;
- toNode.propagatedType = node.propagatedType;
- toNode.staticInvokeType = node.staticInvokeType;
- toNode.staticElement = node.staticElement;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitFunctionTypeAlias(FunctionTypeAlias node) {
- FunctionTypeAlias toNode = this._toNode as FunctionTypeAlias;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.typedefKeyword, toNode.typedefKeyword),
- _isEqualNodes(node.returnType, toNode.returnType),
- _isEqualNodes(node.name, toNode.name),
- _isEqualNodes(node.typeParameters, toNode.typeParameters),
- _isEqualNodes(node.parameters, toNode.parameters),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
- FunctionTypedFormalParameter toNode =
- this._toNode as FunctionTypedFormalParameter;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualNodes(node.returnType, toNode.returnType),
- _isEqualNodes(node.identifier, toNode.identifier),
- _isEqualNodes(node.parameters, toNode.parameters));
- }
-
- @override
- bool visitHideCombinator(HideCombinator node) {
- HideCombinator toNode = this._toNode as HideCombinator;
- return _and(_isEqualTokens(node.keyword, toNode.keyword),
- _isEqualNodeLists(node.hiddenNames, toNode.hiddenNames));
- }
-
- @override
- bool visitIfStatement(IfStatement node) {
- IfStatement toNode = this._toNode as IfStatement;
- return _and(
- _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodes(node.condition, toNode.condition),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
- _isEqualNodes(node.thenStatement, toNode.thenStatement),
- _isEqualTokens(node.elseKeyword, toNode.elseKeyword),
- _isEqualNodes(node.elseStatement, toNode.elseStatement));
- }
-
- @override
- bool visitImplementsClause(ImplementsClause node) {
- ImplementsClause toNode = this._toNode as ImplementsClause;
- return _and(
- _isEqualTokens(node.implementsKeyword, toNode.implementsKeyword),
- _isEqualNodeLists(node.interfaces, toNode.interfaces));
- }
-
- @override
- bool visitImportDirective(ImportDirective node) {
- ImportDirective toNode = this._toNode as ImportDirective;
- if (_and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.keyword, toNode.keyword),
- _isEqualNodes(node.uri, toNode.uri),
- _isEqualTokens(node.asKeyword, toNode.asKeyword),
- _isEqualNodes(node.prefix, toNode.prefix),
- _isEqualNodeLists(node.combinators, toNode.combinators),
- _isEqualTokens(node.semicolon, toNode.semicolon))) {
- toNode.element = node.element;
- return true;
- }
- return false;
- }
-
- @override
- bool visitIndexExpression(IndexExpression node) {
- IndexExpression toNode = this._toNode as IndexExpression;
- if (_and(
- _isEqualNodes(node.target, toNode.target),
- _isEqualTokens(node.leftBracket, toNode.leftBracket),
- _isEqualNodes(node.index, toNode.index),
- _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
- toNode.auxiliaryElements = node.auxiliaryElements;
- toNode.propagatedElement = node.propagatedElement;
- toNode.propagatedType = node.propagatedType;
- toNode.staticElement = node.staticElement;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitInstanceCreationExpression(InstanceCreationExpression node) {
- InstanceCreationExpression toNode =
- this._toNode as InstanceCreationExpression;
- if (_and(
- _isEqualTokens(node.keyword, toNode.keyword),
- _isEqualNodes(node.constructorName, toNode.constructorName),
- _isEqualNodes(node.argumentList, toNode.argumentList))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticElement = node.staticElement;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitIntegerLiteral(IntegerLiteral node) {
- IntegerLiteral toNode = this._toNode as IntegerLiteral;
- if (_and(_isEqualTokens(node.literal, toNode.literal),
- node.value == toNode.value)) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitInterpolationExpression(InterpolationExpression node) {
- InterpolationExpression toNode = this._toNode as InterpolationExpression;
- return _and(
- _isEqualTokens(node.leftBracket, toNode.leftBracket),
- _isEqualNodes(node.expression, toNode.expression),
- _isEqualTokens(node.rightBracket, toNode.rightBracket));
- }
-
- @override
- bool visitInterpolationString(InterpolationString node) {
- InterpolationString toNode = this._toNode as InterpolationString;
- return _and(_isEqualTokens(node.contents, toNode.contents),
- node.value == toNode.value);
- }
-
- @override
- bool visitIsExpression(IsExpression node) {
- IsExpression toNode = this._toNode as IsExpression;
- if (_and(
- _isEqualNodes(node.expression, toNode.expression),
- _isEqualTokens(node.isOperator, toNode.isOperator),
- _isEqualTokens(node.notOperator, toNode.notOperator),
- _isEqualNodes(node.type, toNode.type))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitLabel(Label node) {
- Label toNode = this._toNode as Label;
- return _and(_isEqualNodes(node.label, toNode.label),
- _isEqualTokens(node.colon, toNode.colon));
- }
-
- @override
- bool visitLabeledStatement(LabeledStatement node) {
- LabeledStatement toNode = this._toNode as LabeledStatement;
- return _and(_isEqualNodeLists(node.labels, toNode.labels),
- _isEqualNodes(node.statement, toNode.statement));
- }
-
- @override
- bool visitLibraryDirective(LibraryDirective node) {
- LibraryDirective toNode = this._toNode as LibraryDirective;
- if (_and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.libraryKeyword, toNode.libraryKeyword),
- _isEqualNodes(node.name, toNode.name),
- _isEqualTokens(node.semicolon, toNode.semicolon))) {
- toNode.element = node.element;
- return true;
- }
- return false;
- }
-
- @override
- bool visitLibraryIdentifier(LibraryIdentifier node) {
- LibraryIdentifier toNode = this._toNode as LibraryIdentifier;
- if (_isEqualNodeLists(node.components, toNode.components)) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitListLiteral(ListLiteral node) {
- ListLiteral toNode = this._toNode as ListLiteral;
- if (_and(
- _isEqualTokens(node.constKeyword, toNode.constKeyword),
- _isEqualNodes(node.typeArguments, toNode.typeArguments),
- _isEqualTokens(node.leftBracket, toNode.leftBracket),
- _isEqualNodeLists(node.elements, toNode.elements),
- _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitMapLiteral(MapLiteral node) {
- MapLiteral toNode = this._toNode as MapLiteral;
- if (_and(
- _isEqualTokens(node.constKeyword, toNode.constKeyword),
- _isEqualNodes(node.typeArguments, toNode.typeArguments),
- _isEqualTokens(node.leftBracket, toNode.leftBracket),
- _isEqualNodeLists(node.entries, toNode.entries),
- _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitMapLiteralEntry(MapLiteralEntry node) {
- MapLiteralEntry toNode = this._toNode as MapLiteralEntry;
- return _and(
- _isEqualNodes(node.key, toNode.key),
- _isEqualTokens(node.separator, toNode.separator),
- _isEqualNodes(node.value, toNode.value));
- }
-
- @override
- bool visitMethodDeclaration(MethodDeclaration node) {
- MethodDeclaration toNode = this._toNode as MethodDeclaration;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.externalKeyword, toNode.externalKeyword),
- _isEqualTokens(node.modifierKeyword, toNode.modifierKeyword),
- _isEqualNodes(node.returnType, toNode.returnType),
- _isEqualTokens(node.propertyKeyword, toNode.propertyKeyword),
- _isEqualTokens(node.propertyKeyword, toNode.propertyKeyword),
- _isEqualNodes(node.name, toNode.name),
- _isEqualNodes(node.parameters, toNode.parameters),
- _isEqualNodes(node.body, toNode.body));
- }
-
- @override
- bool visitMethodInvocation(MethodInvocation node) {
- MethodInvocation toNode = this._toNode as MethodInvocation;
- if (_and(
- _isEqualNodes(node.target, toNode.target),
- _isEqualTokens(node.operator, toNode.operator),
- _isEqualNodes(node.methodName, toNode.methodName),
- _isEqualNodes(node.argumentList, toNode.argumentList))) {
- toNode.propagatedInvokeType = node.propagatedInvokeType;
- toNode.propagatedType = node.propagatedType;
- toNode.staticInvokeType = node.staticInvokeType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitNamedExpression(NamedExpression node) {
- NamedExpression toNode = this._toNode as NamedExpression;
- if (_and(_isEqualNodes(node.name, toNode.name),
- _isEqualNodes(node.expression, toNode.expression))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitNativeClause(NativeClause node) {
- NativeClause toNode = this._toNode as NativeClause;
- return _and(_isEqualTokens(node.nativeKeyword, toNode.nativeKeyword),
- _isEqualNodes(node.name, toNode.name));
- }
-
- @override
- bool visitNativeFunctionBody(NativeFunctionBody node) {
- NativeFunctionBody toNode = this._toNode as NativeFunctionBody;
- return _and(
- _isEqualTokens(node.nativeKeyword, toNode.nativeKeyword),
- _isEqualNodes(node.stringLiteral, toNode.stringLiteral),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitNullLiteral(NullLiteral node) {
- NullLiteral toNode = this._toNode as NullLiteral;
- if (_isEqualTokens(node.literal, toNode.literal)) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitParenthesizedExpression(ParenthesizedExpression node) {
- ParenthesizedExpression toNode = this._toNode as ParenthesizedExpression;
- if (_and(
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodes(node.expression, toNode.expression),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitPartDirective(PartDirective node) {
- PartDirective toNode = this._toNode as PartDirective;
- if (_and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.partKeyword, toNode.partKeyword),
- _isEqualNodes(node.uri, toNode.uri),
- _isEqualTokens(node.semicolon, toNode.semicolon))) {
- toNode.element = node.element;
- return true;
- }
- return false;
- }
-
- @override
- bool visitPartOfDirective(PartOfDirective node) {
- PartOfDirective toNode = this._toNode as PartOfDirective;
- if (_and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.partKeyword, toNode.partKeyword),
- _isEqualTokens(node.ofKeyword, toNode.ofKeyword),
- _isEqualNodes(node.libraryName, toNode.libraryName),
- _isEqualTokens(node.semicolon, toNode.semicolon))) {
- toNode.element = node.element;
- return true;
- }
- return false;
- }
-
- @override
- bool visitPostfixExpression(PostfixExpression node) {
- PostfixExpression toNode = this._toNode as PostfixExpression;
- if (_and(_isEqualNodes(node.operand, toNode.operand),
- _isEqualTokens(node.operator, toNode.operator))) {
- toNode.propagatedElement = node.propagatedElement;
- toNode.propagatedType = node.propagatedType;
- toNode.staticElement = node.staticElement;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitPrefixedIdentifier(PrefixedIdentifier node) {
- PrefixedIdentifier toNode = this._toNode as PrefixedIdentifier;
- if (_and(
- _isEqualNodes(node.prefix, toNode.prefix),
- _isEqualTokens(node.period, toNode.period),
- _isEqualNodes(node.identifier, toNode.identifier))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitPrefixExpression(PrefixExpression node) {
- PrefixExpression toNode = this._toNode as PrefixExpression;
- if (_and(_isEqualTokens(node.operator, toNode.operator),
- _isEqualNodes(node.operand, toNode.operand))) {
- toNode.propagatedElement = node.propagatedElement;
- toNode.propagatedType = node.propagatedType;
- toNode.staticElement = node.staticElement;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitPropertyAccess(PropertyAccess node) {
- PropertyAccess toNode = this._toNode as PropertyAccess;
- if (_and(
- _isEqualNodes(node.target, toNode.target),
- _isEqualTokens(node.operator, toNode.operator),
- _isEqualNodes(node.propertyName, toNode.propertyName))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitRedirectingConstructorInvocation(
- RedirectingConstructorInvocation node) {
- RedirectingConstructorInvocation toNode =
- this._toNode as RedirectingConstructorInvocation;
- if (_and(
- _isEqualTokens(node.thisKeyword, toNode.thisKeyword),
- _isEqualTokens(node.period, toNode.period),
- _isEqualNodes(node.constructorName, toNode.constructorName),
- _isEqualNodes(node.argumentList, toNode.argumentList))) {
- toNode.staticElement = node.staticElement;
- return true;
- }
- return false;
- }
-
- @override
- bool visitRethrowExpression(RethrowExpression node) {
- RethrowExpression toNode = this._toNode as RethrowExpression;
- if (_isEqualTokens(node.rethrowKeyword, toNode.rethrowKeyword)) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitReturnStatement(ReturnStatement node) {
- ReturnStatement toNode = this._toNode as ReturnStatement;
- return _and(
- _isEqualTokens(node.returnKeyword, toNode.returnKeyword),
- _isEqualNodes(node.expression, toNode.expression),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitScriptTag(ScriptTag node) {
- ScriptTag toNode = this._toNode as ScriptTag;
- return _isEqualTokens(node.scriptTag, toNode.scriptTag);
- }
-
- @override
- bool visitShowCombinator(ShowCombinator node) {
- ShowCombinator toNode = this._toNode as ShowCombinator;
- return _and(_isEqualTokens(node.keyword, toNode.keyword),
- _isEqualNodeLists(node.shownNames, toNode.shownNames));
- }
-
- @override
- bool visitSimpleFormalParameter(SimpleFormalParameter node) {
- SimpleFormalParameter toNode = this._toNode as SimpleFormalParameter;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.keyword, toNode.keyword),
- _isEqualNodes(node.type, toNode.type),
- _isEqualNodes(node.identifier, toNode.identifier));
- }
-
- @override
- bool visitSimpleIdentifier(SimpleIdentifier node) {
- SimpleIdentifier toNode = this._toNode as SimpleIdentifier;
- if (_isEqualTokens(node.token, toNode.token)) {
- toNode.staticElement = node.staticElement;
- toNode.staticType = node.staticType;
- toNode.propagatedElement = node.propagatedElement;
- toNode.propagatedType = node.propagatedType;
- toNode.auxiliaryElements = node.auxiliaryElements;
- return true;
- }
- return false;
- }
-
- @override
- bool visitSimpleStringLiteral(SimpleStringLiteral node) {
- SimpleStringLiteral toNode = this._toNode as SimpleStringLiteral;
- if (_and(_isEqualTokens(node.literal, toNode.literal),
- node.value == toNode.value)) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitStringInterpolation(StringInterpolation node) {
- StringInterpolation toNode = this._toNode as StringInterpolation;
- if (_isEqualNodeLists(node.elements, toNode.elements)) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitSuperConstructorInvocation(SuperConstructorInvocation node) {
- SuperConstructorInvocation toNode =
- this._toNode as SuperConstructorInvocation;
- if (_and(
- _isEqualTokens(node.superKeyword, toNode.superKeyword),
- _isEqualTokens(node.period, toNode.period),
- _isEqualNodes(node.constructorName, toNode.constructorName),
- _isEqualNodes(node.argumentList, toNode.argumentList))) {
- toNode.staticElement = node.staticElement;
- return true;
- }
- return false;
- }
-
- @override
- bool visitSuperExpression(SuperExpression node) {
- SuperExpression toNode = this._toNode as SuperExpression;
- if (_isEqualTokens(node.superKeyword, toNode.superKeyword)) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitSwitchCase(SwitchCase node) {
- SwitchCase toNode = this._toNode as SwitchCase;
- return _and(
- _isEqualNodeLists(node.labels, toNode.labels),
- _isEqualTokens(node.keyword, toNode.keyword),
- _isEqualNodes(node.expression, toNode.expression),
- _isEqualTokens(node.colon, toNode.colon),
- _isEqualNodeLists(node.statements, toNode.statements));
- }
-
- @override
- bool visitSwitchDefault(SwitchDefault node) {
- SwitchDefault toNode = this._toNode as SwitchDefault;
- return _and(
- _isEqualNodeLists(node.labels, toNode.labels),
- _isEqualTokens(node.keyword, toNode.keyword),
- _isEqualTokens(node.colon, toNode.colon),
- _isEqualNodeLists(node.statements, toNode.statements));
- }
-
- @override
- bool visitSwitchStatement(SwitchStatement node) {
- SwitchStatement toNode = this._toNode as SwitchStatement;
- return _and(
- _isEqualTokens(node.switchKeyword, toNode.switchKeyword),
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodes(node.expression, toNode.expression),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
- _isEqualTokens(node.leftBracket, toNode.leftBracket),
- _isEqualNodeLists(node.members, toNode.members),
- _isEqualTokens(node.rightBracket, toNode.rightBracket));
- }
-
- @override
- bool visitSymbolLiteral(SymbolLiteral node) {
- SymbolLiteral toNode = this._toNode as SymbolLiteral;
- if (_and(_isEqualTokens(node.poundSign, toNode.poundSign),
- _isEqualTokenLists(node.components, toNode.components))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitThisExpression(ThisExpression node) {
- ThisExpression toNode = this._toNode as ThisExpression;
- if (_isEqualTokens(node.thisKeyword, toNode.thisKeyword)) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitThrowExpression(ThrowExpression node) {
- ThrowExpression toNode = this._toNode as ThrowExpression;
- if (_and(_isEqualTokens(node.throwKeyword, toNode.throwKeyword),
- _isEqualNodes(node.expression, toNode.expression))) {
- toNode.propagatedType = node.propagatedType;
- toNode.staticType = node.staticType;
- return true;
- }
- return false;
- }
-
- @override
- bool visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- TopLevelVariableDeclaration toNode =
- this._toNode as TopLevelVariableDeclaration;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualNodes(node.variables, toNode.variables),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitTryStatement(TryStatement node) {
- TryStatement toNode = this._toNode as TryStatement;
- return _and(
- _isEqualTokens(node.tryKeyword, toNode.tryKeyword),
- _isEqualNodes(node.body, toNode.body),
- _isEqualNodeLists(node.catchClauses, toNode.catchClauses),
- _isEqualTokens(node.finallyKeyword, toNode.finallyKeyword),
- _isEqualNodes(node.finallyBlock, toNode.finallyBlock));
- }
-
- @override
- bool visitTypeArgumentList(TypeArgumentList node) {
- TypeArgumentList toNode = this._toNode as TypeArgumentList;
- return _and(
- _isEqualTokens(node.leftBracket, toNode.leftBracket),
- _isEqualNodeLists(node.arguments, toNode.arguments),
- _isEqualTokens(node.rightBracket, toNode.rightBracket));
- }
-
- @override
- bool visitTypeName(TypeName node) {
- TypeName toNode = this._toNode as TypeName;
- if (_and(_isEqualNodes(node.name, toNode.name),
- _isEqualNodes(node.typeArguments, toNode.typeArguments))) {
- toNode.type = node.type;
- return true;
- }
- return false;
- }
-
- @override
- bool visitTypeParameter(TypeParameter node) {
- TypeParameter toNode = this._toNode as TypeParameter;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualNodes(node.name, toNode.name),
- _isEqualTokens(node.extendsKeyword, toNode.extendsKeyword),
- _isEqualNodes(node.bound, toNode.bound));
- }
-
- @override
- bool visitTypeParameterList(TypeParameterList node) {
- TypeParameterList toNode = this._toNode as TypeParameterList;
- return _and(
- _isEqualTokens(node.leftBracket, toNode.leftBracket),
- _isEqualNodeLists(node.typeParameters, toNode.typeParameters),
- _isEqualTokens(node.rightBracket, toNode.rightBracket));
- }
-
- @override
- bool visitVariableDeclaration(VariableDeclaration node) {
- VariableDeclaration toNode = this._toNode as VariableDeclaration;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualNodes(node.name, toNode.name),
- _isEqualTokens(node.equals, toNode.equals),
- _isEqualNodes(node.initializer, toNode.initializer));
- }
-
- @override
- bool visitVariableDeclarationList(VariableDeclarationList node) {
- VariableDeclarationList toNode = this._toNode as VariableDeclarationList;
- return _and(
- _isEqualNodes(node.documentationComment, toNode.documentationComment),
- _isEqualNodeLists(node.metadata, toNode.metadata),
- _isEqualTokens(node.keyword, toNode.keyword),
- _isEqualNodes(node.type, toNode.type),
- _isEqualNodeLists(node.variables, toNode.variables));
- }
-
- @override
- bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
- VariableDeclarationStatement toNode =
- this._toNode as VariableDeclarationStatement;
- return _and(_isEqualNodes(node.variables, toNode.variables),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- @override
- bool visitWhileStatement(WhileStatement node) {
- WhileStatement toNode = this._toNode as WhileStatement;
- return _and(
- _isEqualTokens(node.whileKeyword, toNode.whileKeyword),
- _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
- _isEqualNodes(node.condition, toNode.condition),
- _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
- _isEqualNodes(node.body, toNode.body));
- }
-
- @override
- bool visitWithClause(WithClause node) {
- WithClause toNode = this._toNode as WithClause;
- return _and(_isEqualTokens(node.withKeyword, toNode.withKeyword),
- _isEqualNodeLists(node.mixinTypes, toNode.mixinTypes));
- }
-
- @override
- bool visitYieldStatement(YieldStatement node) {
- YieldStatement toNode = this._toNode as YieldStatement;
- return _and(
- _isEqualTokens(node.yieldKeyword, toNode.yieldKeyword),
- _isEqualNodes(node.expression, toNode.expression),
- _isEqualTokens(node.semicolon, toNode.semicolon));
- }
-
- /**
- * Return `true` if all of the parameters are `true`.
- */
- bool _and(bool b1, bool b2,
- [bool b3 = true,
- bool b4 = true,
- bool b5 = true,
- bool b6 = true,
- bool b7 = true,
- bool b8 = true,
- bool b9 = true,
- bool b10 = true,
- bool b11 = true,
- bool b12 = true,
- bool b13 = true]) {
- // TODO(brianwilkerson) Inline this method.
- return b1 &&
- b2 &&
- b3 &&
- b4 &&
- b5 &&
- b6 &&
- b7 &&
- b8 &&
- b9 &&
- b10 &&
- b11 &&
- b12 &&
- b13;
- }
-
- /**
- * Return `true` if the [first] and [second] lists of AST nodes have the same
- * size and corresponding elements are equal.
- */
- bool _isEqualNodeLists(NodeList first, NodeList second) {
- if (first == null) {
- return second == null;
- } else if (second == null) {
- return false;
- }
- int size = first.length;
- if (second.length != size) {
- return false;
- }
- bool equal = true;
- for (int i = 0; i < size; i++) {
- if (!_isEqualNodes(first[i], second[i])) {
- equal = false;
- }
- }
- return equal;
- }
-
- /**
- * Return `true` if the [fromNode] and [toNode] have the same structure. As a
- * side-effect, if the nodes do have the same structure, any resolution data
- * from the first node will be copied to the second node.
- */
- bool _isEqualNodes(AstNode fromNode, AstNode toNode) {
- if (fromNode == null) {
- return toNode == null;
- } else if (toNode == null) {
- return false;
- } else if (fromNode.runtimeType == toNode.runtimeType) {
- this._toNode = toNode;
- return fromNode.accept(this);
- }
- //
- // Check for a simple transformation caused by entering a period.
- //
- if (toNode is PrefixedIdentifier) {
- SimpleIdentifier prefix = toNode.prefix;
- if (fromNode.runtimeType == prefix.runtimeType) {
- this._toNode = prefix;
- return fromNode.accept(this);
- }
- } else if (toNode is PropertyAccess) {
- Expression target = toNode.target;
- if (fromNode.runtimeType == target.runtimeType) {
- this._toNode = target;
- return fromNode.accept(this);
- }
- }
- return false;
- }
-
- /**
- * Return `true` if the [first] and [second] arrays of tokens have the same
- * length and corresponding elements are equal.
- */
- bool _isEqualTokenLists(List<Token> first, List<Token> second) {
- int length = first.length;
- if (second.length != length) {
- return false;
- }
- for (int i = 0; i < length; i++) {
- if (!_isEqualTokens(first[i], second[i])) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Return `true` if the [first] and [second] tokens have the same structure.
- */
- bool _isEqualTokens(Token first, Token second) {
- if (first == null) {
- return second == null;
- } else if (second == null) {
- return false;
- }
- return first.lexeme == second.lexeme;
- }
-
- /**
- * Copy resolution data from the [fromNode] to the [toNode].
- */
- static void copyResolutionData(AstNode fromNode, AstNode toNode) {
- ResolutionCopier copier = new ResolutionCopier();
- copier._isEqualNodes(fromNode, toNode);
- }
-}
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index dce4507..92814ba 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -73,6 +73,12 @@
ClassElement _enclosingClass;
/**
+ * A flag indicating whether a surrounding member (compilation unit or class)
+ * is deprecated.
+ */
+ bool inDeprecatedMember = false;
+
+ /**
* The error reporter by which errors will be reported.
*/
final ErrorReporter _errorReporter;
@@ -138,13 +144,19 @@
@override
Object visitClassDeclaration(ClassDeclaration node) {
ClassElement outerClass = _enclosingClass;
+ bool wasInDeprecatedMember = inDeprecatedMember;
+ ClassElement element = node.element;
+ if (element != null && element.isDeprecated) {
+ inDeprecatedMember = true;
+ }
try {
- _enclosingClass = node.element;
+ _enclosingClass = element;
// Commented out until we decide that we want this hint in the analyzer
// checkForOverrideEqualsButNotHashCode(node);
return super.visitClassDeclaration(node);
} finally {
_enclosingClass = outerClass;
+ inDeprecatedMember = wasInDeprecatedMember;
}
}
@@ -174,8 +186,17 @@
@override
Object visitFunctionDeclaration(FunctionDeclaration node) {
- _checkForMissingReturn(node.returnType, node.functionExpression.body);
- return super.visitFunctionDeclaration(node);
+ bool wasInDeprecatedMember = inDeprecatedMember;
+ ExecutableElement element = node.element;
+ if (element != null && element.isDeprecated) {
+ inDeprecatedMember = true;
+ }
+ try {
+ _checkForMissingReturn(node.returnType, node.functionExpression.body);
+ return super.visitFunctionDeclaration(node);
+ } finally {
+ inDeprecatedMember = wasInDeprecatedMember;
+ }
}
@override
@@ -216,11 +237,20 @@
@override
Object visitMethodDeclaration(MethodDeclaration node) {
- // This was determined to not be a good hint, see: dartbug.com/16029
- //checkForOverridingPrivateMember(node);
- _checkForMissingReturn(node.returnType, node.body);
- _checkForUnnecessaryNoSuchMethod(node);
- return super.visitMethodDeclaration(node);
+ bool wasInDeprecatedMember = inDeprecatedMember;
+ ExecutableElement element = node.element;
+ if (element != null && element.isDeprecated) {
+ inDeprecatedMember = true;
+ }
+ try {
+ // This was determined to not be a good hint, see: dartbug.com/16029
+ //checkForOverridingPrivateMember(node);
+ _checkForMissingReturn(node.returnType, node.body);
+ _checkForUnnecessaryNoSuchMethod(node);
+ return super.visitMethodDeclaration(node);
+ } finally {
+ inDeprecatedMember = wasInDeprecatedMember;
+ }
}
@override
@@ -504,8 +534,19 @@
* @return `true` if and only if a hint code is generated on the passed node
* See [HintCode.DEPRECATED_MEMBER_USE].
*/
- bool _checkForDeprecatedMemberUse(Element element, AstNode node) {
- if (element != null && element.isDeprecated) {
+ void _checkForDeprecatedMemberUse(Element element, AstNode node) {
+ bool isDeprecated(Element element) {
+ if (element == null) {
+ return false;
+ } else if (element is PropertyAccessorElement && element.isSynthetic) {
+ element = (element as PropertyAccessorElement).variable;
+ if (element == null) {
+ return false;
+ }
+ }
+ return element.isDeprecated;
+ }
+ if (!inDeprecatedMember && isDeprecated(element)) {
String displayName = element.displayName;
if (element is ConstructorElement) {
// TODO(jwren) We should modify ConstructorElement.getDisplayName(),
@@ -519,9 +560,7 @@
}
_errorReporter.reportErrorForNode(
HintCode.DEPRECATED_MEMBER_USE, node, [displayName]);
- return true;
}
- return false;
}
/**
@@ -538,9 +577,9 @@
* @return `true` if and only if a hint code is generated on the passed node
* See [HintCode.DEPRECATED_MEMBER_USE].
*/
- bool _checkForDeprecatedMemberUseAtIdentifier(SimpleIdentifier identifier) {
+ void _checkForDeprecatedMemberUseAtIdentifier(SimpleIdentifier identifier) {
if (identifier.inDeclarationContext()) {
- return false;
+ return;
}
AstNode parent = identifier.parent;
if ((parent is ConstructorName && identical(identifier, parent.name)) ||
@@ -549,9 +588,9 @@
(parent is SuperConstructorInvocation &&
identical(identifier, parent.constructorName)) ||
parent is HideCombinator) {
- return false;
+ return;
}
- return _checkForDeprecatedMemberUse(identifier.bestElement, identifier);
+ _checkForDeprecatedMemberUse(identifier.bestElement, identifier);
}
/**
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index ff70e89..84f2eb7 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -206,6 +206,18 @@
return false;
}
+ // Don't allow a non-generic function where a generic one is expected. The
+ // former wouldn't know how to handle type arguments being passed to it.
+ // TODO(rnystrom): This same check also exists in FunctionTypeImpl.relate()
+ // but we don't always reliably go through that code path. This should be
+ // cleaned up to avoid the redundancy.
+ if (fromType is FunctionType &&
+ toType is FunctionType &&
+ fromType.typeFormals.isEmpty &&
+ toType.typeFormals.isNotEmpty) {
+ return false;
+ }
+
// If the subtype relation goes the other way, allow the implicit downcast.
// TODO(leafp): Emit warnings and hints for these in some way.
// TODO(leafp): Consider adding a flag to disable these? Or just rely on
diff --git a/pkg/analyzer/lib/src/generated/utilities_dart.dart b/pkg/analyzer/lib/src/generated/utilities_dart.dart
index 695f75e..41b7d7c 100644
--- a/pkg/analyzer/lib/src/generated/utilities_dart.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_dart.dart
@@ -6,7 +6,7 @@
import 'package:analyzer/dart/ast/ast.dart' show AnnotatedNode, Comment;
import 'package:analyzer/dart/ast/token.dart' show Token;
-import 'package:analyzer/src/generated/element.dart' show ElementImpl;
+import 'package:analyzer/src/dart/element/element.dart' show ElementImpl;
import 'package:analyzer/src/generated/java_core.dart';
/**
diff --git a/pkg/analyzer/lib/src/services/lint.dart b/pkg/analyzer/lib/src/services/lint.dart
index af20f59..3eea1b7 100644
--- a/pkg/analyzer/lib/src/services/lint.dart
+++ b/pkg/analyzer/lib/src/services/lint.dart
@@ -4,11 +4,11 @@
library analyzer.src.services.lint;
+import 'dart:collection';
+
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/model.dart';
import 'package:analyzer/task/model.dart';
@@ -19,6 +19,9 @@
final ResultDescriptor<List<Linter>> CONFIGURED_LINTS_KEY =
new ResultDescriptorImpl('configured.lints', _noLints);
+/// Shared lint registry.
+LintRegistry lintRegistry = new LintRegistry();
+
/// Return lints associated with this [context], or an empty list if there are
/// none.
List<Linter> getLints(AnalysisContext context) =>
@@ -35,41 +38,22 @@
/// NOTE: this is set by the framework before visit begins.
ErrorReporter reporter;
+ /// Linter name.
+ String get name;
+
/// Return a visitor to be passed to compilation units to perform lint
/// analysis.
/// Lint errors are reported via this [Linter]'s error [reporter].
AstVisitor getVisitor();
}
-/// Traverses a library's worth of dart code at a time to generate lint warnings
-/// over the set of sources.
-///
-/// See [LintCode].
-class LintGenerator {
- static const List<Linter> _noLints = const <Linter>[];
+/// Manages lint timing.
+class LintRegistry {
+ /// Dictionary mapping lints (by name) to timers.
+ final Map<String, Stopwatch> timers = new HashMap<String, Stopwatch>();
- final Iterable<CompilationUnit> _compilationUnits;
- final AnalysisErrorListener _errorListener;
- final Iterable<Linter> _linters;
-
- LintGenerator(this._compilationUnits, this._errorListener,
- [Iterable<Linter> linters])
- : _linters = linters ?? _noLints;
-
- void generate() {
- PerformanceStatistics.lint.makeCurrentWhile(() {
- _compilationUnits.forEach((cu) {
- if (cu.element != null) {
- _generate(cu, cu.element.source);
- }
- });
- });
- }
-
- void _generate(CompilationUnit unit, Source source) {
- ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
- _linters.forEach((l) => l.reporter = errorReporter);
- Iterable<AstVisitor> visitors = _linters.map((l) => l.getVisitor());
- unit.accept(new DelegatingAstVisitor(visitors.where((v) => v != null)));
- }
+ /// Get a timer associated with the given lint rule (or create one if none
+ /// exists).
+ Stopwatch getTimer(Linter linter) =>
+ timers.putIfAbsent(linter.name, () => new Stopwatch());
}
diff --git a/pkg/analyzer/lib/src/summary/flat_buffers.dart b/pkg/analyzer/lib/src/summary/flat_buffers.dart
index 0464127..410d9d4 100644
--- a/pkg/analyzer/lib/src/summary/flat_buffers.dart
+++ b/pkg/analyzer/lib/src/summary/flat_buffers.dart
@@ -720,6 +720,21 @@
}
/**
+ * Reader of lists of unsigned 8-bit integer values.
+ *
+ * The returned unmodifiable lists lazily read values on access.
+ */
+class Uint8ListReader extends Reader<List<int>> {
+ const Uint8ListReader();
+
+ @override
+ int get size => 4;
+
+ @override
+ List<int> read(BufferPointer bp) => new _FbUint8List(bp.derefObject());
+}
+
+/**
* The reader of unsigned 8-bit integers.
*/
class Uint8Reader extends Reader<int> {
@@ -840,6 +855,18 @@
}
/**
+ * List backed by 8-bit unsigned integers.
+ */
+class _FbUint8List extends _FbList<int> {
+ _FbUint8List(BufferPointer bp) : super(bp);
+
+ @override
+ int operator [](int i) {
+ return bp._getUint8(4 + i);
+ }
+}
+
+/**
* Class that describes the structure of a table.
*/
class _VTable {
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 7228a00..bf4a78a 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -1908,6 +1908,7 @@
List<idl.IndexRelationKind> _usedNameKinds;
List<int> _usedNameOffsets;
List<int> _usedNames;
+ List<bool> _usedNameIsQualifiedFlags;
@override
List<idl.IndexNameKind> get definedNameKinds => _definedNameKinds ??= <idl.IndexNameKind>[];
@@ -2061,7 +2062,19 @@
_usedNames = _value;
}
- UnitIndexBuilder({List<idl.IndexNameKind> definedNameKinds, List<int> definedNameOffsets, List<int> definedNames, int unit, List<bool> usedElementIsQualifiedFlags, List<idl.IndexRelationKind> usedElementKinds, List<int> usedElementLengths, List<int> usedElementOffsets, List<int> usedElements, List<idl.IndexRelationKind> usedNameKinds, List<int> usedNameOffsets, List<int> usedNames})
+ @override
+ List<bool> get usedNameIsQualifiedFlags => _usedNameIsQualifiedFlags ??= <bool>[];
+
+ /**
+ * Each item of this list is the `true` if the corresponding name usage
+ * is qualified with some prefix.
+ */
+ void set usedNameIsQualifiedFlags(List<bool> _value) {
+ assert(!_finished);
+ _usedNameIsQualifiedFlags = _value;
+ }
+
+ UnitIndexBuilder({List<idl.IndexNameKind> definedNameKinds, List<int> definedNameOffsets, List<int> definedNames, int unit, List<bool> usedElementIsQualifiedFlags, List<idl.IndexRelationKind> usedElementKinds, List<int> usedElementLengths, List<int> usedElementOffsets, List<int> usedElements, List<idl.IndexRelationKind> usedNameKinds, List<int> usedNameOffsets, List<int> usedNames, List<bool> usedNameIsQualifiedFlags})
: _definedNameKinds = definedNameKinds,
_definedNameOffsets = definedNameOffsets,
_definedNames = definedNames,
@@ -2073,7 +2086,8 @@
_usedElements = usedElements,
_usedNameKinds = usedNameKinds,
_usedNameOffsets = usedNameOffsets,
- _usedNames = usedNames;
+ _usedNames = usedNames,
+ _usedNameIsQualifiedFlags = usedNameIsQualifiedFlags;
fb.Offset finish(fb.Builder fbBuilder) {
assert(!_finished);
@@ -2089,6 +2103,7 @@
fb.Offset offset_usedNameKinds;
fb.Offset offset_usedNameOffsets;
fb.Offset offset_usedNames;
+ fb.Offset offset_usedNameIsQualifiedFlags;
if (!(_definedNameKinds == null || _definedNameKinds.isEmpty)) {
offset_definedNameKinds = fbBuilder.writeListUint8(_definedNameKinds.map((b) => b.index).toList());
}
@@ -2122,6 +2137,9 @@
if (!(_usedNames == null || _usedNames.isEmpty)) {
offset_usedNames = fbBuilder.writeListUint32(_usedNames);
}
+ if (!(_usedNameIsQualifiedFlags == null || _usedNameIsQualifiedFlags.isEmpty)) {
+ offset_usedNameIsQualifiedFlags = fbBuilder.writeListBool(_usedNameIsQualifiedFlags);
+ }
fbBuilder.startTable();
if (offset_definedNameKinds != null) {
fbBuilder.addOffset(6, offset_definedNameKinds);
@@ -2159,6 +2177,9 @@
if (offset_usedNames != null) {
fbBuilder.addOffset(8, offset_usedNames);
}
+ if (offset_usedNameIsQualifiedFlags != null) {
+ fbBuilder.addOffset(12, offset_usedNameIsQualifiedFlags);
+ }
return fbBuilder.endTable();
}
}
@@ -2187,6 +2208,7 @@
List<idl.IndexRelationKind> _usedNameKinds;
List<int> _usedNameOffsets;
List<int> _usedNames;
+ List<bool> _usedNameIsQualifiedFlags;
@override
List<idl.IndexNameKind> get definedNameKinds {
@@ -2259,6 +2281,12 @@
_usedNames ??= const fb.Uint32ListReader().vTableGet(_bp, 8, const <int>[]);
return _usedNames;
}
+
+ @override
+ List<bool> get usedNameIsQualifiedFlags {
+ _usedNameIsQualifiedFlags ??= const fb.BoolListReader().vTableGet(_bp, 12, const <bool>[]);
+ return _usedNameIsQualifiedFlags;
+ }
}
abstract class _UnitIndexMixin implements idl.UnitIndex {
@@ -2277,6 +2305,7 @@
if (usedNameKinds.isNotEmpty) _result["usedNameKinds"] = usedNameKinds.map((_value) => _value.toString().split('.')[1]).toList();
if (usedNameOffsets.isNotEmpty) _result["usedNameOffsets"] = usedNameOffsets;
if (usedNames.isNotEmpty) _result["usedNames"] = usedNames;
+ if (usedNameIsQualifiedFlags.isNotEmpty) _result["usedNameIsQualifiedFlags"] = usedNameIsQualifiedFlags;
return _result;
}
@@ -2294,6 +2323,7 @@
"usedNameKinds": usedNameKinds,
"usedNameOffsets": usedNameOffsets,
"usedNames": usedNames,
+ "usedNameIsQualifiedFlags": usedNameIsQualifiedFlags,
};
@override
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 7114161..a653a52 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -65,7 +65,28 @@
* Is referenced (and not invoked, read/written) at.
* Right: location.
*/
- IS_REFERENCED_BY
+ IS_REFERENCED_BY,
+
+ /**
+ * Left: unresolved member name.
+ * Is read at.
+ * Right: location.
+ */
+ IS_READ_BY,
+
+ /**
+ * Left: unresolved member name.
+ * Is both read and written at.
+ * Right: location.
+ */
+ IS_READ_WRITTEN_BY,
+
+ /**
+ * Left: unresolved member name.
+ * Is written at.
+ * Right: location.
+ */
+ IS_WRITTEN_BY
}
/**
@@ -92,7 +113,27 @@
/**
* The synthetic setter of a property introducing element.
*/
- setter
+ setter,
+
+ /**
+ * The synthetic top-level variable element.
+ */
+ topLevelVariable,
+
+ /**
+ * The synthetic `loadLibrary` element.
+ */
+ loadLibrary,
+
+ /**
+ * The synthetic `index` getter of an enum.
+ */
+ enumIndex,
+
+ /**
+ * The synthetic `values` getter of an enum.
+ */
+ enumValues
}
/**
@@ -992,6 +1033,12 @@
* quickly find name uses in this [UnitIndex].
*/
usedNames:[uint] (id: 8);
+
+ /**
+ * Each item of this list is the `true` if the corresponding name usage
+ * is qualified with some prefix.
+ */
+ usedNameIsQualifiedFlags:[ubyte] (id: 12);
}
/**
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 0df5ab3..f15ba03 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -224,7 +224,28 @@
* Is referenced (and not invoked, read/written) at.
* Right: location.
*/
- IS_REFERENCED_BY
+ IS_REFERENCED_BY,
+
+ /**
+ * Left: unresolved member name.
+ * Is read at.
+ * Right: location.
+ */
+ IS_READ_BY,
+
+ /**
+ * Left: unresolved member name.
+ * Is both read and written at.
+ * Right: location.
+ */
+ IS_READ_WRITTEN_BY,
+
+ /**
+ * Left: unresolved member name.
+ * Is written at.
+ * Right: location.
+ */
+ IS_WRITTEN_BY
}
/**
@@ -251,7 +272,27 @@
/**
* The synthetic setter of a property introducing element.
*/
- setter
+ setter,
+
+ /**
+ * The synthetic top-level variable element.
+ */
+ topLevelVariable,
+
+ /**
+ * The synthetic `loadLibrary` element.
+ */
+ loadLibrary,
+
+ /**
+ * The synthetic `index` getter of an enum.
+ */
+ enumIndex,
+
+ /**
+ * The synthetic `values` getter of an enum.
+ */
+ enumValues
}
/**
@@ -751,6 +792,13 @@
*/
@Id(8)
List<int> get usedNames;
+
+ /**
+ * Each item of this list is the `true` if the corresponding name usage
+ * is qualified with some prefix.
+ */
+ @Id(12)
+ List<bool> get usedNameIsQualifiedFlags;
}
/**
diff --git a/pkg/analyzer/lib/src/summary/index_unit.dart b/pkg/analyzer/lib/src/summary/index_unit.dart
index ca57e80..a29c88b 100644
--- a/pkg/analyzer/lib/src/summary/index_unit.dart
+++ b/pkg/analyzer/lib/src/summary/index_unit.dart
@@ -13,6 +13,41 @@
import 'package:analyzer/src/summary/idl.dart';
/**
+ * TODO(scheglov) add to the `meta` package.
+ */
+const visibleForTesting = const Object();
+
+/**
+ * Information about an element referenced in index.
+ */
+class ElementInfo {
+ /**
+ * The identifier of the [CompilationUnitElement] containing this element.
+ */
+ final int unitId;
+
+ /**
+ * The name offset of the element.
+ */
+ final int offset;
+
+ /**
+ * The kind of the element.
+ */
+ final IndexSyntheticElementKind kind;
+
+ /**
+ * The unique id of the element. It is set after indexing of the whole
+ * package is done and we are assembling the full package index.
+ */
+ int id;
+
+ ElementInfo(this.unitId, this.offset, this.kind) {
+ assert(offset >= 0);
+ }
+}
+
+/**
* Object that gathers information about the whole package index and then uses
* it to assemble a new [PackageIndexBuilder]. Call [index] on each compilation
* unit to be indexed, then call [assemble] to retrieve the complete index for
@@ -20,9 +55,9 @@
*/
class PackageIndexAssembler {
/**
- * Map associating referenced elements with their [_ElementInfo]s.
+ * Map associating referenced elements with their [ElementInfo]s.
*/
- final Map<Element, _ElementInfo> _elementMap = <Element, _ElementInfo>{};
+ final Map<Element, ElementInfo> _elementMap = <Element, ElementInfo>{};
/**
* Map associating [CompilationUnitElement]s with their identifiers, which
@@ -67,7 +102,7 @@
stringInfoList[i].id = i;
}
// sort elements and set IDs
- List<_ElementInfo> elementInfoList = _elementMap.values.toList();
+ List<ElementInfo> elementInfoList = _elementMap.values.toList();
elementInfoList.sort((a, b) {
return a.offset - b.offset;
});
@@ -95,22 +130,17 @@
}
/**
- * Return the unique [_ElementInfo] corresponding the [element]. The field
- * [_ElementInfo.id] is filled by [assemble] during final sorting.
+ * Return the unique [ElementInfo] corresponding the [element]. The field
+ * [ElementInfo.id] is filled by [assemble] during final sorting.
*/
- _ElementInfo _getElementInfo(Element element) {
+ ElementInfo _getElementInfo(Element element) {
if (element is Member) {
element = (element as Member).baseElement;
}
return _elementMap.putIfAbsent(element, () {
CompilationUnitElement unitElement = getUnitElement(element);
int unitId = _getUnitId(unitElement);
- int offset = element.nameOffset;
- if (element is LibraryElement || element is CompilationUnitElement) {
- offset = 0;
- }
- IndexSyntheticElementKind kind = getIndexElementKind(element);
- return new _ElementInfo(unitId, offset, kind);
+ return newElementInfo(unitId, element);
});
}
@@ -149,23 +179,6 @@
}
/**
- * Return the kind of the given [element].
- */
- static IndexSyntheticElementKind getIndexElementKind(Element element) {
- if (element.isSynthetic) {
- if (element is ConstructorElement) {
- return IndexSyntheticElementKind.constructor;
- }
- if (element is PropertyAccessorElement) {
- return element.isGetter
- ? IndexSyntheticElementKind.getter
- : IndexSyntheticElementKind.setter;
- }
- }
- return IndexSyntheticElementKind.notSynthetic;
- }
-
- /**
* Return the [CompilationUnitElement] that should be used for [element].
* Throw [StateError] if the [element] is not linked into a unit.
*/
@@ -180,6 +193,52 @@
}
throw new StateError(element.toString());
}
+
+ /**
+ * Return a new [ElementInfo] for the given [element] in the given [unitId].
+ * This method is static, so it cannot add any information to the index.
+ */
+ static ElementInfo newElementInfo(int unitId, Element element) {
+ IndexSyntheticElementKind kind = IndexSyntheticElementKind.notSynthetic;
+ if (element.isSynthetic) {
+ if (element is ConstructorElement) {
+ kind = IndexSyntheticElementKind.constructor;
+ element = element.enclosingElement;
+ } else if (element is FunctionElement && element.name == 'loadLibrary') {
+ kind = IndexSyntheticElementKind.loadLibrary;
+ element = element.library;
+ } else if (element is PropertyAccessorElement) {
+ PropertyAccessorElement accessor = element;
+ Element enclosing = element.enclosingElement;
+ bool isEnumGetter = enclosing is ClassElement && enclosing.isEnum;
+ if (isEnumGetter && accessor.name == 'index') {
+ kind = IndexSyntheticElementKind.enumIndex;
+ element = enclosing;
+ } else if (isEnumGetter && accessor.name == 'values') {
+ kind = IndexSyntheticElementKind.enumValues;
+ element = enclosing;
+ } else {
+ kind = accessor.isGetter
+ ? IndexSyntheticElementKind.getter
+ : IndexSyntheticElementKind.setter;
+ element = accessor.variable;
+ }
+ } else if (element is TopLevelVariableElement) {
+ TopLevelVariableElement property = element;
+ kind = IndexSyntheticElementKind.topLevelVariable;
+ element = property.getter;
+ element ??= property.setter;
+ } else {
+ throw new ArgumentError(
+ 'Unsupported synthetic element ${element.runtimeType}');
+ }
+ }
+ int offset = element.nameOffset;
+ if (element is LibraryElement || element is CompilationUnitElement) {
+ offset = 0;
+ }
+ return new ElementInfo(unitId, offset, kind);
+ }
}
/**
@@ -208,59 +267,13 @@
}
/**
- * Information about an element referenced in index.
- */
-class _ElementInfo {
- /**
- * The identifier of the [CompilationUnitElement] containing this element.
- */
- final int unitId;
-
- /**
- * The name offset of the element.
- */
- final int offset;
-
- /**
- * The kind of the element.
- */
- final IndexSyntheticElementKind kind;
-
- /**
- * The unique id of the element. It is set after indexing of the whole
- * package is done and we are assembling the full package index.
- */
- int id;
-
- _ElementInfo(this.unitId, this.offset, this.kind);
-}
-
-/**
- * Information about a string referenced in the index.
- */
-class _StringInfo {
- /**
- * The value of the string.
- */
- final String value;
-
- /**
- * The unique id of the string. It is set after indexing of the whole
- * package is done and we are assembling the full package index.
- */
- int id;
-
- _StringInfo(this.value);
-}
-
-/**
* Information about a single relation. Any [_ElementRelationInfo] is always
* part of a [_UnitIndexAssembler], so [offset] and [length] should be
* understood within the context of the compilation unit pointed to by the
* [_UnitIndexAssembler].
*/
class _ElementRelationInfo {
- final _ElementInfo elementInfo;
+ final ElementInfo elementInfo;
final IndexRelationKind kind;
final int offset;
final int length;
@@ -301,9 +314,10 @@
/**
* Record that the name [node] has a relation of the given [kind].
*/
- void recordNameRelation(SimpleIdentifier node, IndexRelationKind kind) {
+ void recordNameRelation(
+ SimpleIdentifier node, IndexRelationKind kind, bool isQualified) {
if (node != null) {
- assembler.addNameRelation(node.name, kind, node.offset);
+ assembler.addNameRelation(node.name, kind, node.offset, isQualified);
}
}
@@ -337,15 +351,20 @@
void recordRelationOffset(Element element, IndexRelationKind kind, int offset,
int length, bool isQualified) {
// Ignore elements that can't be referenced outside of the unit.
- if (element == null ||
- element is FunctionElement &&
+ ElementKind elementKind = element?.kind;
+ if (elementKind == null ||
+ elementKind == ElementKind.DYNAMIC ||
+ elementKind == ElementKind.LABEL ||
+ elementKind == ElementKind.LOCAL_VARIABLE ||
+ elementKind == ElementKind.PREFIX ||
+ elementKind == ElementKind.TYPE_PARAMETER ||
+ elementKind == ElementKind.FUNCTION &&
+ element is FunctionElement &&
element.enclosingElement is ExecutableElement ||
- element is LabelElement ||
- element is LocalVariableElement ||
- element is ParameterElement &&
+ elementKind == ElementKind.PARAMETER &&
+ element is ParameterElement &&
element.parameterKind != ParameterKind.NAMED ||
- element is PrefixElement ||
- element is TypeParameterElement) {
+ false) {
return;
}
// Add the relation.
@@ -425,8 +444,7 @@
SimpleIdentifier fieldName = node.fieldName;
if (fieldName != null) {
Element element = fieldName.staticElement;
- recordRelation(
- element, IndexRelationKind.IS_REFERENCED_BY, fieldName, true);
+ recordRelation(element, IndexRelationKind.IS_WRITTEN_BY, fieldName, true);
}
node.expression?.accept(this);
}
@@ -489,10 +507,10 @@
visitMethodInvocation(MethodInvocation node) {
SimpleIdentifier name = node.methodName;
Element element = name.bestElement;
- // qualified unresolved name invocation
+ // unresolved name invocation
bool isQualified = node.realTarget != null;
- if (isQualified && element == null) {
- recordNameRelation(name, IndexRelationKind.IS_INVOKED_BY);
+ if (element == null) {
+ recordNameRelation(name, IndexRelationKind.IS_INVOKED_BY, isQualified);
}
// element invocation
IndexRelationKind kind = element is ClassElement
@@ -546,15 +564,29 @@
recordDefinedElement(element);
return;
}
- // record qualified unresolved name reference
+ // record unresolved name reference
bool isQualified = _isQualified(node);
- if (isQualified && element == null) {
- recordNameRelation(node, IndexRelationKind.IS_REFERENCED_BY);
+ if (element == null) {
+ bool inGetterContext = node.inGetterContext();
+ bool inSetterContext = node.inSetterContext();
+ IndexRelationKind kind;
+ if (inGetterContext && inSetterContext) {
+ kind = IndexRelationKind.IS_READ_WRITTEN_BY;
+ } else if (inGetterContext) {
+ kind = IndexRelationKind.IS_READ_BY;
+ } else {
+ kind = IndexRelationKind.IS_WRITTEN_BY;
+ }
+ recordNameRelation(node, kind, isQualified);
}
// this.field parameter
if (element is FieldFormalParameterElement) {
- recordRelation(
- element.field, IndexRelationKind.IS_REFERENCED_BY, node, true);
+ AstNode parent = node.parent;
+ IndexRelationKind kind =
+ parent is FieldFormalParameter && parent.identifier == node
+ ? IndexRelationKind.IS_WRITTEN_BY
+ : IndexRelationKind.IS_REFERENCED_BY;
+ recordRelation(element.field, kind, node, true);
return;
}
// ignore a local reference to a parameter
@@ -579,7 +611,7 @@
recordRelationOffset(
element, IndexRelationKind.IS_REFERENCED_BY, offset, 0, true);
}
- super.visitSuperConstructorInvocation(node);
+ node.argumentList?.accept(this);
}
@override
@@ -676,8 +708,27 @@
final _StringInfo nameInfo;
final IndexRelationKind kind;
final int offset;
+ final bool isQualified;
- _NameRelationInfo(this.nameInfo, this.kind, this.offset);
+ _NameRelationInfo(this.nameInfo, this.kind, this.offset, this.isQualified);
+}
+
+/**
+ * Information about a string referenced in the index.
+ */
+class _StringInfo {
+ /**
+ * The value of the string.
+ */
+ final String value;
+
+ /**
+ * The unique id of the string. It is set after indexing of the whole
+ * package is done and we are assembling the full package index.
+ */
+ int id;
+
+ _StringInfo(this.value);
}
/**
@@ -688,7 +739,7 @@
* compilation unit.
* - Call [addNameRelation] for each name relation found in the
* compilation unit.
- * - Assign ids to all the [_ElementInfo] objects reachable from
+ * - Assign ids to all the [ElementInfo] objects reachable from
* [elementRelations].
* - Call [assemble] to produce the final unit index.
*/
@@ -704,15 +755,16 @@
void addElementRelation(Element element, IndexRelationKind kind, int offset,
int length, bool isQualified) {
try {
- _ElementInfo elementInfo = pkg._getElementInfo(element);
+ ElementInfo elementInfo = pkg._getElementInfo(element);
elementRelations.add(new _ElementRelationInfo(
elementInfo, kind, offset, length, isQualified));
} on StateError {}
}
- void addNameRelation(String name, IndexRelationKind kind, int offset) {
+ void addNameRelation(
+ String name, IndexRelationKind kind, int offset, bool isQualified) {
_StringInfo nameId = pkg._getStringInfo(name);
- nameRelations.add(new _NameRelationInfo(nameId, kind, offset));
+ nameRelations.add(new _NameRelationInfo(nameId, kind, offset, isQualified));
}
/**
@@ -742,7 +794,9 @@
elementRelations.map((r) => r.isQualified).toList(),
usedNames: nameRelations.map((r) => r.nameInfo.id).toList(),
usedNameKinds: nameRelations.map((r) => r.kind).toList(),
- usedNameOffsets: nameRelations.map((r) => r.offset).toList());
+ usedNameOffsets: nameRelations.map((r) => r.offset).toList(),
+ usedNameIsQualifiedFlags:
+ nameRelations.map((r) => r.isQualified).toList());
}
void defineName(String name, IndexNameKind kind, int offset) {
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 8c9869f..59117e1 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -11,10 +11,10 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element_handle.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 9e63ff8..faaa1f4 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -4,8 +4,8 @@
library serialization.summarize_const_expr;
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 212bb9d..798c152 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -6,12 +6,12 @@
import 'dart:convert';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.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/ast.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -590,7 +590,8 @@
CodeRangeBuilder serializeCodeRange(Element element) {
if (element is ElementImpl && element.codeOffset != null) {
- return new CodeRangeBuilder(offset: element.codeOffset, length: element.codeLength);
+ return new CodeRangeBuilder(
+ offset: element.codeOffset, length: element.codeLength);
}
return null;
}
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 11a704d..408db9e 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -2813,10 +2813,20 @@
//
// Generate lints.
//
+ List<AstVisitor> visitors = <AstVisitor>[];
+
List<Linter> linters = getLints(context);
- linters.forEach((l) => l.reporter = errorReporter);
- Iterable<AstVisitor> visitors = linters.map((l) => l.getVisitor()).toList();
- unit.accept(new DelegatingAstVisitor(visitors.where((v) => v != null)));
+ for (Linter linter in linters) {
+ AstVisitor visitor = linter.getVisitor();
+ if (visitor != null) {
+ linter.reporter = errorReporter;
+ visitors
+ .add(new TimedAstVisitor(visitor, lintRegistry.getTimer(linter)));
+ }
+ }
+
+ DelegatingAstVisitor dv = new DelegatingAstVisitor(visitors);
+ unit.accept(dv);
//
// Record outputs.
@@ -2952,12 +2962,33 @@
VariableDeclaration getDeclaration(CompilationUnit unit) {
VariableElement variable = target;
AstNode node = new NodeLocator2(variable.nameOffset).searchWithin(unit);
+ if (node == null) {
+ Source variableSource = variable.source;
+ Source unitSource = unit.element.source;
+ if (variableSource != unitSource) {
+ throw new AnalysisException(
+ "Failed to find the AST node for the variable "
+ "${variable.displayName} in $variableSource "
+ "because we were looking in $unitSource");
+ }
+ throw new AnalysisException(
+ "Failed to find the AST node for the variable "
+ "${variable.displayName} in $variableSource");
+ }
VariableDeclaration declaration =
node.getAncestor((AstNode ancestor) => ancestor is VariableDeclaration);
if (declaration == null || declaration.name != node) {
+ Source variableSource = variable.source;
+ Source unitSource = unit.element.source;
+ if (variableSource != unitSource) {
+ throw new AnalysisException(
+ "Failed to find the declaration of the variable "
+ "${variable.displayName} in $variableSource"
+ "because we were looking in $unitSource");
+ }
throw new AnalysisException(
"Failed to find the declaration of the variable "
- "${variable.displayName} in ${variable.source}");
+ "${variable.displayName} in $variableSource");
}
return declaration;
}
@@ -3911,6 +3942,15 @@
*/
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
VariableElement variable = target;
+ if (variable.library == null) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write(
+ 'PropagateVariableTypeTask building inputs for a variable with no library. Variable name = "');
+ buffer.write(variable.name);
+ buffer.write('". Path = ');
+ (variable as ElementImpl).appendPathTo(buffer);
+ throw new AnalysisException(buffer.toString());
+ }
LibrarySpecificUnit unit =
new LibrarySpecificUnit(variable.library.source, variable.source);
return <String, TaskInput>{
@@ -5119,6 +5159,11 @@
CompilationUnit unit = getRequiredInput(UNIT_INPUT);
CompilationUnitElement unitElement = unit.element;
LibraryElement libraryElement = unitElement.library;
+ if (libraryElement == null) {
+ throw new AnalysisException(
+ 'VerifyUnitTask verifying a unit with no library: '
+ '${unitElement.source.fullName}');
+ }
//
// Validate the directives.
//
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index b729a2b..cb4da98 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -501,10 +501,36 @@
* Initialize a newly created exception to represent a failed attempt to
* perform the given [task] due to the given [dependencyCycle].
*/
- InfiniteTaskLoopException(AnalysisTask task, this.dependencyCycle,
- [this.cyclicPath])
- : super(
- 'Infinite loop while performing task ${task.descriptor.name} for ${task.target}');
+ InfiniteTaskLoopException(AnalysisTask task, List<WorkItem> dependencyCycle,
+ [List<TargetedResult> cyclicPath])
+ : this.dependencyCycle = dependencyCycle,
+ this.cyclicPath = cyclicPath,
+ super(_composeMessage(task, dependencyCycle, cyclicPath));
+
+ /**
+ * Compose an error message based on the data we have available.
+ */
+ static String _composeMessage(AnalysisTask task,
+ List<WorkItem> dependencyCycle, List<TargetedResult> cyclicPath) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write('Infinite loop while performing task ');
+ buffer.write(task.descriptor.name);
+ buffer.write(' for ');
+ buffer.writeln(task.target);
+ buffer.writeln(' Dependency Cycle:');
+ for (WorkItem item in dependencyCycle) {
+ buffer.write(' ');
+ buffer.writeln(item);
+ }
+ if (cyclicPath != null) {
+ buffer.writeln(' Cyclic Path:');
+ for (TargetedResult result in cyclicPath) {
+ buffer.write(' ');
+ buffer.writeln(result);
+ }
+ }
+ return buffer.toString();
+ }
}
/**
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index e598910..8c6980b 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -46,6 +46,7 @@
static const String analyzer = 'analyzer';
static const String enableAsync = 'enableAsync';
static const String enableGenericMethods = 'enableGenericMethods';
+ static const String enableStrictCallChecks = 'enableStrictCallChecks';
static const String enableSuperMixins = 'enableSuperMixins';
static const String enableConditionalDirectives =
"enableConditionalDirectives";
@@ -80,9 +81,10 @@
/// Supported `analyzer` language configuration options.
static const List<String> languageOptions = const [
enableAsync,
- enableGenericMethods,
- enableSuperMixins,
enableConditionalDirectives,
+ enableGenericMethods,
+ enableStrictCallChecks,
+ enableSuperMixins
];
}
@@ -477,6 +479,14 @@
context.analysisOptions = options;
}
}
+ if (feature == AnalyzerOptions.enableStrictCallChecks) {
+ if (isTrue(value)) {
+ AnalysisOptionsImpl options =
+ new AnalysisOptionsImpl.from(context.analysisOptions);
+ options.enableStrictCallChecks = true;
+ context.analysisOptions = options;
+ }
+ }
if (feature == AnalyzerOptions.enableSuperMixins) {
if (isTrue(value)) {
AnalysisOptionsImpl options =
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 9831fb6..53164a3 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -145,7 +145,7 @@
if (expr is ParenthesizedExpression) {
checkAssignment(expr.expression, type);
} else {
- _recordMessage(_checkAssignment(expr, type));
+ _checkDowncast(expr, type);
}
}
@@ -565,25 +565,15 @@
node.visitChildren(this);
}
- StaticInfo _checkAssignment(Expression expr, DartType toT) {
- final fromT = _getStaticType(expr);
- final Coercion c = _coerceTo(fromT, toT);
- if (c is Identity) return null;
- if (c is CoercionError) return new StaticTypeError(rules, expr, toT);
- if (c is Cast) return DownCast.create(rules, expr, c);
- assert(false);
- return null;
- }
-
void _checkCompoundAssignment(AssignmentExpression expr) {
var op = expr.operator.type;
assert(op.isAssignmentOperator && op != TokenType.EQ);
var methodElement = expr.staticElement;
if (methodElement == null) {
- // Dynamic invocation
+ // Dynamic invocation.
_recordDynamicInvoke(expr, expr.leftHandSide);
} else {
- // Sanity check the operator
+ // Sanity check the operator.
assert(methodElement.isOperator);
var functionType = methodElement.type;
var paramTypes = functionType.normalParameterTypes;
@@ -591,7 +581,7 @@
assert(functionType.namedParameterTypes.isEmpty);
assert(functionType.optionalParameterTypes.isEmpty);
- // Check the lhs type
+ // Check the LHS type.
var staticInfo;
var rhsType = _getStaticType(expr.rightHandSide);
var lhsType = _getStaticType(expr.leftHandSide);
@@ -606,10 +596,9 @@
// This is also slightly different from spec, but allows us to keep
// compound operators in the int += num and num += dynamic cases.
staticInfo = DownCast.create(
- rules, expr.rightHandSide, Coercion.cast(rhsType, lhsType));
+ rules, expr.rightHandSide, rhsType, lhsType);
rhsType = lhsType;
} else {
- // Static type error
staticInfo = new StaticTypeError(rules, expr, lhsType);
}
_recordMessage(staticInfo);
@@ -618,8 +607,7 @@
// Check the rhs type
if (staticInfo is! CoercionInfo) {
var paramType = paramTypes.first;
- staticInfo = _checkAssignment(expr.rightHandSide, paramType);
- _recordMessage(staticInfo);
+ _checkDowncast(expr.rightHandSide, paramType);
}
}
}
@@ -675,12 +663,18 @@
}
}
- Coercion _coerceTo(DartType fromT, DartType toT) {
- // We can use anything as void
- if (toT.isVoid) return Coercion.identity(toT);
+ /// Records a [DownCast] of [expr] to [toT], if there is one.
+ ///
+ /// If [expr] does not require a downcast because it is not related to [toT]
+ /// or is already a subtype of it, does nothing.
+ void _checkDowncast(Expression expr, DartType toT) {
+ DartType fromT = _getStaticType(expr);
- // fromT <: toT, no coercion needed
- if (rules.isSubtypeOf(fromT, toT)) return Coercion.identity(toT);
+ // We can use anything as void.
+ if (toT.isVoid) return;
+
+ // fromT <: toT, no coercion needed.
+ if (rules.isSubtypeOf(fromT, toT)) return;
// TODO(vsm): We can get rid of the second clause if we disallow
// all sideways casts - see TODO below.
@@ -690,11 +684,14 @@
// well for consistency.
if ((fromT is FunctionType && rules.getCallMethodType(toT) != null) ||
(toT is FunctionType && rules.getCallMethodType(fromT) != null)) {
- return Coercion.error();
+ return;
}
// Downcast if toT <: fromT
- if (rules.isSubtypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
+ if (rules.isSubtypeOf(toT, fromT)) {
+ _recordMessage(DownCast.create(rules, expr, fromT, toT));
+ return;
+ }
// TODO(vsm): Once we have generic methods, we should delete this
// workaround. These sideways casts are always ones we warn about
@@ -707,10 +704,8 @@
// Iterable<T> for some concrete T (e.g. Object). These are unrelated
// in the restricted system, but List<dynamic> <: Iterable<T> in dart.
if (fromT.isAssignableTo(toT)) {
- return Coercion.cast(fromT, toT);
+ _recordMessage(DownCast.create(rules, expr, fromT, toT));
}
-
- return Coercion.error();
}
// Produce a coercion which coerces something of type fromT
diff --git a/pkg/analyzer/lib/src/task/strong/info.dart b/pkg/analyzer/lib/src/task/strong/info.dart
index 6169815..2aaa4c6 100644
--- a/pkg/analyzer/lib/src/task/strong/info.dart
+++ b/pkg/analyzer/lib/src/task/strong/info.dart
@@ -15,13 +15,16 @@
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/type_system.dart';
-// A down cast due to a variable declaration to a ground type. E.g.,
-// T x = expr;
-// where T is ground. We exclude non-ground types as these behave differently
-// compared to standard Dart.
+/// A down cast due to a variable declaration to a ground type:
+///
+/// T x = expr;
+///
+/// where `T` is ground. We exclude non-ground types as these behave
+/// differently compared to standard Dart.
class AssignmentCast extends DownCast {
- AssignmentCast(TypeSystem rules, Expression expression, Cast cast)
- : super._internal(rules, expression, cast);
+ AssignmentCast(TypeSystem rules, Expression expression, DartType fromType,
+ DartType toType)
+ : super._internal(rules, expression, fromType, toType);
@override
String get name => 'STRONG_MODE_ASSIGNMENT_CAST';
@@ -29,30 +32,6 @@
toErrorCode() => new HintCode(name, message);
}
-// Coercion which casts one type to another
-class Cast extends Coercion {
- Cast(DartType fromType, DartType toType) : super(fromType, toType);
-}
-
-// The abstract type of coercions mapping one type to another.
-// This class also exposes static builder functions which
-// check for errors and reduce redundant coercions to the identity.
-abstract class Coercion {
- final DartType fromType;
- final DartType toType;
- Coercion(this.fromType, this.toType);
- static Coercion cast(DartType fromT, DartType toT) => new Cast(fromT, toT);
- static Coercion error() => new CoercionError();
- static Coercion identity(DartType type) => new Identity(type);
-}
-
-// The error coercion. This coercion signals that a coercion
-// could not be generated. The code generator should not see
-// these.
-class CoercionError extends Coercion {
- CoercionError() : super(null, null);
-}
-
/// Implicitly injected expression conversion.
abstract class CoercionInfo extends StaticInfo {
static const String _propertyName = 'dev_compiler.src.info.CoercionInfo';
@@ -81,52 +60,49 @@
}
}
-// Base class for all casts from base type to sub type.
+/// Base class for all casts from base type to sub type.
abstract class DownCast extends CoercionInfo {
- Cast _cast;
+ final DartType _fromType;
+ final DartType _toType;
- DownCast._internal(TypeSystem rules, Expression expression, this._cast)
+ DownCast._internal(
+ TypeSystem rules, Expression expression, this._fromType, this._toType)
: super(rules, expression) {
- assert(_cast.toType != baseType &&
- _cast.fromType == baseType &&
+ assert(_toType != baseType &&
+ _fromType == baseType &&
(baseType.isDynamic ||
- // Call methods make the following non-redundant
- _cast.toType.isSubtypeOf(baseType) ||
- baseType.isAssignableTo(_cast.toType)));
+ // Call methods make the following non-redundant.
+ _toType.isSubtypeOf(baseType) ||
+ baseType.isAssignableTo(_toType)));
}
@override
List<Object> get arguments => [baseType, convertedType];
- Cast get cast => _cast;
-
- DartType get convertedType => _cast.toType;
+ DartType get convertedType => _toType;
@override
String get message => 'Unsound implicit cast from {0} to {1}';
// Factory to create correct DownCast variant.
- static StaticInfo create(
- StrongTypeSystemImpl rules, Expression expression, Cast cast) {
- final fromT = cast.fromType;
- final toT = cast.toType;
-
+ static StaticInfo create(StrongTypeSystemImpl rules, Expression expression,
+ DartType fromType, DartType toType) {
// toT <:_R fromT => to <: fromT
// NB: classes with call methods are subtypes of function
// types, but the function type is not assignable to the class
- assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT));
+ assert(toType.isSubtypeOf(fromType) || fromType.isAssignableTo(toType));
// Handle null call specially.
if (expression is NullLiteral) {
// TODO(vsm): Create a NullCast for this once we revisit nonnullability.
- return new DownCastImplicit(rules, expression, cast);
+ return new DownCastImplicit(rules, expression, fromType, toType);
}
// Inference "casts":
if (expression is Literal || expression is FunctionExpression) {
// fromT should be an exact type - this will almost certainly fail at
// runtime.
- return new StaticTypeError(rules, expression, toT);
+ return new StaticTypeError(rules, expression, toType);
}
if (expression is InstanceCreationExpression) {
@@ -134,62 +110,62 @@
if (e == null || !e.isFactory) {
// fromT should be an exact type - this will almost certainly fail at
// runtime.
- return new StaticTypeError(rules, expression, toT);
+ return new StaticTypeError(rules, expression, toType);
}
}
if (StaticInfo.isKnownFunction(expression)) {
- return new StaticTypeError(rules, expression, toT);
+ return new StaticTypeError(rules, expression, toType);
}
// TODO(vsm): Change this to an assert when we have generic methods and
// fix TypeRules._coerceTo to disallow implicit sideways casts.
- if (!rules.isSubtypeOf(toT, fromT)) {
- assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT));
- return new DownCastComposite(rules, expression, cast);
+ if (!rules.isSubtypeOf(toType, fromType)) {
+ assert(toType.isSubtypeOf(fromType) || fromType.isAssignableTo(toType));
+ return new DownCastComposite(rules, expression, fromType, toType);
}
// Composite cast: these are more likely to fail.
- if (!rules.isGroundType(toT)) {
+ if (!rules.isGroundType(toType)) {
// This cast is (probably) due to our different treatment of dynamic.
// It may be more likely to fail at runtime.
- if (fromT is InterfaceType) {
+ if (fromType is InterfaceType) {
// For class types, we'd like to allow non-generic down casts, e.g.,
// Iterable<T> to List<T>. The intuition here is that raw (generic)
// casts are problematic, and we should complain about those.
- var typeArgs = fromT.typeArguments;
+ var typeArgs = fromType.typeArguments;
if (typeArgs.isEmpty || typeArgs.any((t) => t.isDynamic)) {
- return new DownCastComposite(rules, expression, cast);
+ return new DownCastComposite(rules, expression, fromType, toType);
}
} else {
- return new DownCastComposite(rules, expression, cast);
+ return new DownCastComposite(rules, expression, fromType, toType);
}
}
// Dynamic cast
- if (fromT.isDynamic) {
- return new DynamicCast(rules, expression, cast);
+ if (fromType.isDynamic) {
+ return new DynamicCast(rules, expression, fromType, toType);
}
// Assignment cast
var parent = expression.parent;
if (parent is VariableDeclaration && (parent.initializer == expression)) {
- return new AssignmentCast(rules, expression, cast);
+ return new AssignmentCast(rules, expression, fromType, toType);
}
// Other casts
- return new DownCastImplicit(rules, expression, cast);
+ return new DownCastImplicit(rules, expression, fromType, toType);
}
}
-//
-// Implicit down casts. These are only injected by the compiler by flag.
-//
-// A down cast to a non-ground type. These behave differently from standard
-// Dart and may be more likely to fail at runtime.
+/// Implicit down casts. These are only injected by the compiler by flag.
+///
+/// A down cast to a non-ground type. These behave differently from standard
+/// Dart and may be more likely to fail at runtime.
class DownCastComposite extends DownCast {
- DownCastComposite(TypeSystem rules, Expression expression, Cast cast)
- : super._internal(rules, expression, cast);
+ DownCastComposite(TypeSystem rules, Expression expression, DartType fromType,
+ DartType toType)
+ : super._internal(rules, expression, fromType, toType);
@override
String get name => 'STRONG_MODE_DOWN_CAST_COMPOSITE';
@@ -197,11 +173,12 @@
toErrorCode() => new StaticTypeWarningCode(name, message);
}
-// A down cast to a non-ground type. These behave differently from standard
-// Dart and may be more likely to fail at runtime.
+/// A down cast to a non-ground type. These behave differently from standard
+/// Dart and may be more likely to fail at runtime.
class DownCastImplicit extends DownCast {
- DownCastImplicit(TypeSystem rules, Expression expression, Cast cast)
- : super._internal(rules, expression, cast);
+ DownCastImplicit(TypeSystem rules, Expression expression, DartType fromType,
+ DartType toType)
+ : super._internal(rules, expression, fromType, toType);
@override
String get name => 'STRONG_MODE_DOWN_CAST_IMPLICIT';
@@ -209,10 +186,11 @@
toErrorCode() => new HintCode(name, message);
}
-// A down cast from dynamic to T.
+/// A down cast from dynamic to T.
class DynamicCast extends DownCast {
- DynamicCast(TypeSystem rules, Expression expression, Cast cast)
- : super._internal(rules, expression, cast);
+ DynamicCast(TypeSystem rules, Expression expression, DartType fromType,
+ DartType toType)
+ : super._internal(rules, expression, fromType, toType);
@override
String get name => 'STRONG_MODE_DYNAMIC_CAST';
@@ -248,12 +226,7 @@
}
}
-// The identity coercion
-class Identity extends Coercion {
- Identity(DartType fromType) : super(fromType, fromType);
-}
-
-// Standard / unspecialized inferred type
+/// Standard / unspecialized inferred type.
class InferredType extends InferredTypeBase {
InferredType(TypeSystem rules, Expression expression, DartType type)
: super._internal(rules, expression, type);
@@ -261,7 +234,7 @@
@override
String get name => 'STRONG_MODE_INFERRED_TYPE';
- // Factory to create correct InferredType variant.
+ /// Factory to create correct InferredType variant.
static InferredTypeBase create(
TypeSystem rules, Expression expression, DartType type) {
// Specialized inference:
@@ -278,7 +251,7 @@
}
}
-// An inferred type for a non-literal allocation site.
+/// An inferred type for a non-literal allocation site.
class InferredTypeAllocation extends InferredTypeBase {
InferredTypeAllocation(TypeSystem rules, Expression expression, DartType type)
: super._internal(rules, expression, type);
@@ -287,8 +260,8 @@
String get name => 'STRONG_MODE_INFERRED_TYPE_ALLOCATION';
}
-// An inferred type for the wrapped expression, which may need to be
-// reified into the term
+/// An inferred type for the wrapped expression, which may need to be
+/// reified into the term.
abstract class InferredTypeBase extends CoercionInfo {
final DartType _type;
@@ -306,7 +279,7 @@
toErrorCode() => new HintCode(name, message);
}
-// An inferred type for a closure expression
+/// An inferred type for a closure expression.
class InferredTypeClosure extends InferredTypeBase {
InferredTypeClosure(TypeSystem rules, Expression expression, DartType type)
: super._internal(rules, expression, type);
@@ -315,7 +288,7 @@
String get name => 'STRONG_MODE_INFERRED_TYPE_CLOSURE';
}
-// An inferred type for a literal expression.
+/// An inferred type for a literal expression.
class InferredTypeLiteral extends InferredTypeBase {
InferredTypeLiteral(TypeSystem rules, Expression expression, DartType type)
: super._internal(rules, expression, type);
@@ -336,8 +309,8 @@
String get name => 'STRONG_MODE_INVALID_FIELD_OVERRIDE';
}
-// Invalid override due to incompatible type. I.e., the overridden signature
-// is not compatible with the original.
+/// Invalid override due to incompatible type. I.e., the overridden signature
+/// is not compatible with the original.
class InvalidMethodOverride extends InvalidOverride {
InvalidMethodOverride(AstNode node, ExecutableElement element,
InterfaceType base, FunctionType subType, FunctionType baseType)
@@ -349,7 +322,7 @@
String get name => 'STRONG_MODE_INVALID_METHOD_OVERRIDE';
}
-// Invalid override of an instance member of a class.
+/// Invalid override of an instance member of a class.
abstract class InvalidOverride extends StaticError {
/// Member declaration with the invalid override.
final ExecutableElement element;
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index b7ed4b3..33db261 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -35,7 +35,7 @@
import '../reflective_tests.dart';
import '../utils.dart';
import 'parser_test.dart';
-import 'resolver_test.dart';
+import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
@@ -1480,9 +1480,7 @@
expect(parameter.isFinal, isFalse);
expect(parameter.isSynthetic, isFalse);
expect(parameter.parameterKind, ParameterKind.REQUIRED);
- SourceRange visibleRange = parameter.visibleRange;
- expect(100, visibleRange.offset);
- expect(110, visibleRange.end);
+ _assertVisibleRange(parameter, 100, 110);
}
void test_visitFunctionTypedFormalParameter_withTypeParameters() {
@@ -1505,9 +1503,7 @@
expect(parameter.isSynthetic, isFalse);
expect(parameter.parameterKind, ParameterKind.REQUIRED);
expect(parameter.typeParameters, hasLength(1));
- SourceRange visibleRange = parameter.visibleRange;
- expect(100, visibleRange.offset);
- expect(110, visibleRange.end);
+ _assertVisibleRange(parameter, 100, 110);
}
void test_visitLabeledStatement() {
@@ -2051,11 +2047,7 @@
expect(parameter.isFinal, isFalse);
expect(parameter.isSynthetic, isFalse);
expect(parameter.parameterKind, ParameterKind.NAMED);
- {
- SourceRange visibleRange = parameter.visibleRange;
- expect(100, visibleRange.offset);
- expect(110, visibleRange.end);
- }
+ _assertVisibleRange(parameter, 100, 110);
expect(parameter.defaultValueCode, "42");
FunctionElement initializer = parameter.initializer;
expect(initializer, isNotNull);
@@ -2083,11 +2075,7 @@
expect(parameter.isSynthetic, isFalse);
expect(parameter.name, parameterName);
expect(parameter.parameterKind, ParameterKind.REQUIRED);
- {
- SourceRange visibleRange = parameter.visibleRange;
- expect(100, visibleRange.offset);
- expect(110, visibleRange.end);
- }
+ _assertVisibleRange(parameter, 100, 110);
}
void test_visitSimpleFormalParameter_type() {
@@ -2110,11 +2098,7 @@
expect(parameter.isSynthetic, isFalse);
expect(parameter.name, parameterName);
expect(parameter.parameterKind, ParameterKind.REQUIRED);
- {
- SourceRange visibleRange = parameter.visibleRange;
- expect(100, visibleRange.offset);
- expect(110, visibleRange.end);
- }
+ _assertVisibleRange(parameter, 100, 110);
}
void test_visitTypeAlias_minimal() {
@@ -2233,6 +2217,7 @@
AstFactory.blockFunctionBody2([statement]));
statement.beginToken.offset = 50;
statement.endToken.offset = 80;
+ _setBlockBodySourceRange(constructor.body, 100, 110);
constructor.accept(builder);
List<ConstructorElement> constructors = holder.constructors;
@@ -2244,6 +2229,73 @@
_assertHasCodeRange(variableElement, 50, 31);
expect(variableElement.hasImplicitType, isTrue);
expect(variableElement.name, variableName);
+ _assertVisibleRange(variableElement, 100, 110);
+ }
+
+ void test_visitVariableDeclaration_inForEachStatement() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = _makeBuilder(holder);
+ //
+ // m() { for (var v in []) }
+ //
+ String variableName = "v";
+ Statement statement = AstFactory.forEachStatement(
+ AstFactory.declaredIdentifier3('v'),
+ AstFactory.listLiteral(),
+ AstFactory.block());
+ _setNodeSourceRange(statement, 100, 110);
+ MethodDeclaration method = AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ null,
+ AstFactory.identifier3("m"),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2([statement]));
+ _setBlockBodySourceRange(method.body, 200, 220);
+ method.accept(builder);
+
+ List<MethodElement> methods = holder.methods;
+ expect(methods, hasLength(1));
+ List<LocalVariableElement> variableElements = methods[0].localVariables;
+ expect(variableElements, hasLength(1));
+ LocalVariableElement variableElement = variableElements[0];
+ expect(variableElement.name, variableName);
+ _assertVisibleRange(variableElement, 100, 110);
+ }
+
+ void test_visitVariableDeclaration_inForStatement() {
+ ElementHolder holder = new ElementHolder();
+ ElementBuilder builder = _makeBuilder(holder);
+ //
+ // m() { for (T v;;) }
+ //
+ String variableName = "v";
+ ForStatement statement = AstFactory.forStatement2(
+ AstFactory.variableDeclarationList(null, AstFactory.typeName4('T'),
+ [AstFactory.variableDeclaration('v')]),
+ null,
+ null,
+ AstFactory.block());
+ _setNodeSourceRange(statement, 100, 110);
+ MethodDeclaration method = AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ null,
+ AstFactory.identifier3("m"),
+ AstFactory.formalParameterList(),
+ AstFactory.blockFunctionBody2([statement]));
+ _setBlockBodySourceRange(method.body, 200, 220);
+ method.accept(builder);
+
+ List<MethodElement> methods = holder.methods;
+ expect(methods, hasLength(1));
+ List<LocalVariableElement> variableElements = methods[0].localVariables;
+ expect(variableElements, hasLength(1));
+ LocalVariableElement variableElement = variableElements[0];
+ expect(variableElement.name, variableName);
+ _assertVisibleRange(variableElement, 100, 110);
}
void test_visitVariableDeclaration_inMethod() {
@@ -2265,6 +2317,7 @@
AstFactory.identifier3("m"),
AstFactory.formalParameterList(),
AstFactory.blockFunctionBody2([statement]));
+ _setBlockBodySourceRange(method.body, 100, 110);
method.accept(builder);
List<MethodElement> methods = holder.methods;
@@ -2274,6 +2327,7 @@
LocalVariableElement variableElement = variableElements[0];
expect(variableElement.hasImplicitType, isFalse);
expect(variableElement.name, variableName);
+ _assertVisibleRange(variableElement, 100, 110);
}
void test_visitVariableDeclaration_localNestedInFunction() {
@@ -2435,9 +2489,25 @@
expect(docRange.length, expectedLength);
}
+ void _assertVisibleRange(LocalElement element, int offset, int end) {
+ SourceRange visibleRange = element.visibleRange;
+ expect(visibleRange.offset, offset);
+ expect(visibleRange.end, end);
+ }
+
ElementBuilder _makeBuilder(ElementHolder holder) =>
new ElementBuilder(holder, new CompilationUnitElementImpl('test.dart'));
+ void _setBlockBodySourceRange(BlockFunctionBody body, int offset, int end) {
+ _setNodeSourceRange(body.block, offset, end);
+ }
+
+ void _setNodeSourceRange(AstNode node, int offset, int end) {
+ node.beginToken.offset = offset;
+ Token endToken = node.endToken;
+ endToken.offset = end - endToken.length;
+ }
+
void _useParameterInMethod(
FormalParameter formalParameter, int blockOffset, int blockEnd) {
Block block = AstFactory.block();
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
new file mode 100644
index 0000000..ad6f418
--- /dev/null
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -0,0 +1,562 @@
+// 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 analyzer.test.generated.analysis_context_factory;
+
+import 'dart:collection';
+
+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/context/context.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/string_source.dart';
+import 'package:unittest/unittest.dart';
+
+/**
+ * The class `AnalysisContextFactory` defines utility methods used to create analysis contexts
+ * for testing purposes.
+ */
+class AnalysisContextFactory {
+ static String _DART_MATH = "dart:math";
+
+ static String _DART_INTERCEPTORS = "dart:_interceptors";
+
+ static String _DART_JS_HELPER = "dart:_js_helper";
+
+ /**
+ * Create an analysis context that has a fake core library already resolved.
+ * Return the context that was created.
+ */
+ static InternalAnalysisContext contextWithCore() {
+ AnalysisContextForTests context = new AnalysisContextForTests();
+ return initContextWithCore(context);
+ }
+
+ /**
+ * Create an analysis context that uses the given [options] and has a fake
+ * core library already resolved. Return the context that was created.
+ */
+ static InternalAnalysisContext contextWithCoreAndOptions(
+ AnalysisOptions options) {
+ AnalysisContextForTests context = new AnalysisContextForTests();
+ context._internalSetAnalysisOptions(options);
+ return initContextWithCore(context);
+ }
+
+ static InternalAnalysisContext contextWithCoreAndPackages(
+ Map<String, String> packages) {
+ AnalysisContextForTests context = new AnalysisContextForTests();
+ return initContextWithCore(context, new TestPackageUriResolver(packages));
+ }
+
+ /**
+ * Initialize the given analysis context with a fake core library already resolved.
+ *
+ * @param context the context to be initialized (not `null`)
+ * @return the analysis context that was created
+ */
+ static InternalAnalysisContext initContextWithCore(
+ InternalAnalysisContext context,
+ [UriResolver contributedResolver]) {
+ DirectoryBasedDartSdk sdk = new _AnalysisContextFactory_initContextWithCore(
+ new JavaFile("/fake/sdk"),
+ enableAsync: context.analysisOptions.enableAsync);
+ List<UriResolver> resolvers = <UriResolver>[
+ new DartUriResolver(sdk),
+ new FileUriResolver()
+ ];
+ if (contributedResolver != null) {
+ resolvers.add(contributedResolver);
+ }
+ SourceFactory sourceFactory = new SourceFactory(resolvers);
+ context.sourceFactory = sourceFactory;
+ AnalysisContext coreContext = sdk.context;
+ (coreContext.analysisOptions as AnalysisOptionsImpl).strongMode =
+ context.analysisOptions.strongMode;
+ //
+ // dart:core
+ //
+ TestTypeProvider provider = new TestTypeProvider();
+ CompilationUnitElementImpl coreUnit =
+ new CompilationUnitElementImpl("core.dart");
+ Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
+ coreContext.setContents(coreSource, "");
+ coreUnit.librarySource = coreUnit.source = coreSource;
+ ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy");
+ proxyClassElement.constructors = <ConstructorElement>[
+ ElementFactory.constructorElement(proxyClassElement, '', true)
+ ..isCycleFree = true
+ ..constantInitializers = <ConstructorInitializer>[]
+ ];
+ ClassElement objectClassElement = provider.objectType.element;
+ coreUnit.types = <ClassElement>[
+ provider.boolType.element,
+ provider.deprecatedType.element,
+ provider.doubleType.element,
+ provider.functionType.element,
+ provider.intType.element,
+ provider.iterableType.element,
+ provider.iteratorType.element,
+ provider.listType.element,
+ provider.mapType.element,
+ provider.nullType.element,
+ provider.numType.element,
+ objectClassElement,
+ proxyClassElement,
+ provider.stackTraceType.element,
+ provider.stringType.element,
+ provider.symbolType.element,
+ provider.typeType.element
+ ];
+ coreUnit.functions = <FunctionElement>[
+ ElementFactory.functionElement3("identical", provider.boolType.element,
+ <ClassElement>[objectClassElement, objectClassElement], null),
+ ElementFactory.functionElement3("print", VoidTypeImpl.instance.element,
+ <ClassElement>[objectClassElement], null)
+ ];
+ TopLevelVariableElement proxyTopLevelVariableElt = ElementFactory
+ .topLevelVariableElement3("proxy", true, false, proxyClassElement.type);
+ ConstTopLevelVariableElementImpl deprecatedTopLevelVariableElt =
+ ElementFactory.topLevelVariableElement3(
+ "deprecated", true, false, provider.deprecatedType);
+ {
+ ClassElement deprecatedElement = provider.deprecatedType.element;
+ InstanceCreationExpression initializer = AstFactory
+ .instanceCreationExpression2(
+ Keyword.CONST,
+ AstFactory.typeName(deprecatedElement),
+ [AstFactory.string2('next release')]);
+ ConstructorElement constructor = deprecatedElement.constructors.single;
+ initializer.staticElement = constructor;
+ initializer.constructorName.staticElement = constructor;
+ deprecatedTopLevelVariableElt.constantInitializer = initializer;
+ }
+ coreUnit.accessors = <PropertyAccessorElement>[
+ proxyTopLevelVariableElt.getter,
+ deprecatedTopLevelVariableElt.getter
+ ];
+ coreUnit.topLevelVariables = <TopLevelVariableElement>[
+ proxyTopLevelVariableElt,
+ deprecatedTopLevelVariableElt
+ ];
+ LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
+ coreContext, AstFactory.libraryIdentifier2(["dart", "core"]));
+ coreLibrary.definingCompilationUnit = coreUnit;
+ //
+ // dart:async
+ //
+ Source asyncSource;
+ LibraryElementImpl asyncLibrary;
+ if (context.analysisOptions.enableAsync) {
+ asyncLibrary = new LibraryElementImpl.forNode(
+ coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
+ CompilationUnitElementImpl asyncUnit =
+ new CompilationUnitElementImpl("async.dart");
+ asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
+ coreContext.setContents(asyncSource, "");
+ asyncUnit.librarySource = asyncUnit.source = asyncSource;
+ asyncLibrary.definingCompilationUnit = asyncUnit;
+ // Future
+ ClassElementImpl futureElement =
+ ElementFactory.classElement2("Future", ["T"]);
+ futureElement.enclosingElement = asyncUnit;
+ // factory Future.value([value])
+ ConstructorElementImpl futureConstructor =
+ ElementFactory.constructorElement2(futureElement, "value");
+ futureConstructor.parameters = <ParameterElement>[
+ ElementFactory.positionalParameter2("value", provider.dynamicType)
+ ];
+ futureConstructor.factory = true;
+ futureElement.constructors = <ConstructorElement>[futureConstructor];
+ // Future then(onValue(T value), { Function onError });
+ TypeDefiningElement futureThenR = DynamicElementImpl.instance;
+ if (context.analysisOptions.strongMode) {
+ futureThenR = ElementFactory.typeParameterWithType('R');
+ }
+ FunctionElementImpl thenOnValue = ElementFactory.functionElement3(
+ 'onValue', futureThenR, [futureElement.typeParameters[0]], null);
+ thenOnValue.synthetic = true;
+
+ DartType futureRType = futureElement.type.instantiate([futureThenR.type]);
+ MethodElementImpl thenMethod = ElementFactory
+ .methodElementWithParameters(futureElement, "then", futureRType, [
+ ElementFactory.requiredParameter2("onValue", thenOnValue.type),
+ ElementFactory.namedParameter2("onError", provider.functionType)
+ ]);
+ if (!futureThenR.type.isDynamic) {
+ thenMethod.typeParameters = [futureThenR];
+ }
+ thenOnValue.enclosingElement = thenMethod;
+ thenOnValue.type = new FunctionTypeImpl(thenOnValue);
+ (thenMethod.parameters[0] as ParameterElementImpl).type =
+ thenOnValue.type;
+ thenMethod.type = new FunctionTypeImpl(thenMethod);
+
+ futureElement.methods = <MethodElement>[thenMethod];
+ // Completer
+ ClassElementImpl completerElement =
+ ElementFactory.classElement2("Completer", ["T"]);
+ ConstructorElementImpl completerConstructor =
+ ElementFactory.constructorElement2(completerElement, null);
+ completerElement.constructors = <ConstructorElement>[
+ completerConstructor
+ ];
+ // StreamSubscription
+ ClassElementImpl streamSubscriptionElement =
+ ElementFactory.classElement2("StreamSubscription", ["T"]);
+ // Stream
+ ClassElementImpl streamElement =
+ ElementFactory.classElement2("Stream", ["T"]);
+ streamElement.constructors = <ConstructorElement>[
+ ElementFactory.constructorElement2(streamElement, null)
+ ];
+ DartType returnType = streamSubscriptionElement.type
+ .instantiate(streamElement.type.typeArguments);
+ FunctionElementImpl listenOnData = ElementFactory.functionElement3(
+ 'onData',
+ VoidTypeImpl.instance.element,
+ <TypeDefiningElement>[streamElement.typeParameters[0]],
+ null);
+ listenOnData.synthetic = true;
+ List<DartType> parameterTypes = <DartType>[listenOnData.type,];
+ // TODO(brianwilkerson) This is missing the optional parameters.
+ MethodElementImpl listenMethod =
+ ElementFactory.methodElement('listen', returnType, parameterTypes);
+ streamElement.methods = <MethodElement>[listenMethod];
+ listenMethod.type = new FunctionTypeImpl(listenMethod);
+
+ FunctionElementImpl listenParamFunction = parameterTypes[0].element;
+ listenParamFunction.enclosingElement = listenMethod;
+ listenParamFunction.type = new FunctionTypeImpl(listenParamFunction);
+ ParameterElementImpl listenParam = listenMethod.parameters[0];
+ listenParam.type = listenParamFunction.type;
+
+ asyncUnit.types = <ClassElement>[
+ completerElement,
+ futureElement,
+ streamElement,
+ streamSubscriptionElement
+ ];
+ }
+ //
+ // dart:html
+ //
+ CompilationUnitElementImpl htmlUnit =
+ new CompilationUnitElementImpl("html_dartium.dart");
+ Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
+ coreContext.setContents(htmlSource, "");
+ htmlUnit.librarySource = htmlUnit.source = htmlSource;
+ ClassElementImpl elementElement = ElementFactory.classElement2("Element");
+ InterfaceType elementType = elementElement.type;
+ ClassElementImpl canvasElement =
+ ElementFactory.classElement("CanvasElement", elementType);
+ ClassElementImpl contextElement =
+ ElementFactory.classElement2("CanvasRenderingContext");
+ InterfaceType contextElementType = contextElement.type;
+ ClassElementImpl context2dElement = ElementFactory.classElement(
+ "CanvasRenderingContext2D", contextElementType);
+ canvasElement.methods = <MethodElement>[
+ ElementFactory.methodElement(
+ "getContext", contextElementType, [provider.stringType])
+ ];
+ canvasElement.accessors = <PropertyAccessorElement>[
+ ElementFactory.getterElement("context2D", false, context2dElement.type)
+ ];
+ canvasElement.fields = canvasElement.accessors
+ .map((PropertyAccessorElement accessor) => accessor.variable)
+ .toList();
+ ClassElementImpl documentElement =
+ ElementFactory.classElement("Document", elementType);
+ ClassElementImpl htmlDocumentElement =
+ ElementFactory.classElement("HtmlDocument", documentElement.type);
+ htmlDocumentElement.methods = <MethodElement>[
+ ElementFactory
+ .methodElement("query", elementType, <DartType>[provider.stringType])
+ ];
+ htmlUnit.types = <ClassElement>[
+ ElementFactory.classElement("AnchorElement", elementType),
+ ElementFactory.classElement("BodyElement", elementType),
+ ElementFactory.classElement("ButtonElement", elementType),
+ canvasElement,
+ contextElement,
+ context2dElement,
+ ElementFactory.classElement("DivElement", elementType),
+ documentElement,
+ elementElement,
+ htmlDocumentElement,
+ ElementFactory.classElement("InputElement", elementType),
+ ElementFactory.classElement("SelectElement", elementType)
+ ];
+ htmlUnit.functions = <FunctionElement>[
+ ElementFactory.functionElement3("query", elementElement,
+ <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST)
+ ];
+ TopLevelVariableElementImpl document =
+ ElementFactory.topLevelVariableElement3(
+ "document", false, true, htmlDocumentElement.type);
+ htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
+ htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
+ LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode(
+ coreContext, AstFactory.libraryIdentifier2(["dart", "dom", "html"]));
+ htmlLibrary.definingCompilationUnit = htmlUnit;
+ //
+ // dart:math
+ //
+ CompilationUnitElementImpl mathUnit =
+ new CompilationUnitElementImpl("math.dart");
+ Source mathSource = sourceFactory.forUri(_DART_MATH);
+ coreContext.setContents(mathSource, "");
+ mathUnit.librarySource = mathUnit.source = mathSource;
+ FunctionElement cosElement = ElementFactory.functionElement3(
+ "cos",
+ provider.doubleType.element,
+ <ClassElement>[provider.numType.element],
+ ClassElement.EMPTY_LIST);
+ TopLevelVariableElement ln10Element = ElementFactory
+ .topLevelVariableElement3("LN10", true, false, provider.doubleType);
+ TypeParameterElement maxT =
+ ElementFactory.typeParameterWithType('T', provider.numType);
+ FunctionElementImpl maxElement = ElementFactory.functionElement3(
+ "max", maxT, [maxT, maxT], ClassElement.EMPTY_LIST);
+ maxElement.typeParameters = [maxT];
+ maxElement.type = new FunctionTypeImpl(maxElement);
+ TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3(
+ "PI", true, false, provider.doubleType);
+ ClassElementImpl randomElement = ElementFactory.classElement2("Random");
+ randomElement.abstract = true;
+ ConstructorElementImpl randomConstructor =
+ ElementFactory.constructorElement2(randomElement, null);
+ randomConstructor.factory = true;
+ ParameterElementImpl seedParam = new ParameterElementImpl("seed", 0);
+ seedParam.parameterKind = ParameterKind.POSITIONAL;
+ seedParam.type = provider.intType;
+ randomConstructor.parameters = <ParameterElement>[seedParam];
+ randomElement.constructors = <ConstructorElement>[randomConstructor];
+ FunctionElement sinElement = ElementFactory.functionElement3(
+ "sin",
+ provider.doubleType.element,
+ <ClassElement>[provider.numType.element],
+ ClassElement.EMPTY_LIST);
+ FunctionElement sqrtElement = ElementFactory.functionElement3(
+ "sqrt",
+ provider.doubleType.element,
+ <ClassElement>[provider.numType.element],
+ ClassElement.EMPTY_LIST);
+ mathUnit.accessors = <PropertyAccessorElement>[
+ ln10Element.getter,
+ piElement.getter
+ ];
+ mathUnit.functions = <FunctionElement>[
+ cosElement,
+ maxElement,
+ sinElement,
+ sqrtElement
+ ];
+ mathUnit.topLevelVariables = <TopLevelVariableElement>[
+ ln10Element,
+ piElement
+ ];
+ mathUnit.types = <ClassElement>[randomElement];
+ LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode(
+ coreContext, AstFactory.libraryIdentifier2(["dart", "math"]));
+ mathLibrary.definingCompilationUnit = mathUnit;
+ //
+ // Set empty sources for the rest of the libraries.
+ //
+ Source source = sourceFactory.forUri(_DART_INTERCEPTORS);
+ coreContext.setContents(source, "");
+ source = sourceFactory.forUri(_DART_JS_HELPER);
+ coreContext.setContents(source, "");
+ //
+ // Record the elements.
+ //
+ HashMap<Source, LibraryElement> elementMap =
+ new HashMap<Source, LibraryElement>();
+ elementMap[coreSource] = coreLibrary;
+ if (asyncSource != null) {
+ elementMap[asyncSource] = asyncLibrary;
+ }
+ elementMap[htmlSource] = htmlLibrary;
+ elementMap[mathSource] = mathLibrary;
+ //
+ // Set the public and export namespaces. We don't use exports in the fake
+ // core library so public and export namespaces are the same.
+ //
+ for (LibraryElementImpl library in elementMap.values) {
+ Namespace namespace =
+ new NamespaceBuilder().createPublicNamespaceForLibrary(library);
+ library.exportNamespace = namespace;
+ library.publicNamespace = namespace;
+ }
+ context.recordLibraryElements(elementMap);
+ // Create the synthetic element for `loadLibrary`.
+ for (LibraryElementImpl library in elementMap.values) {
+ library.createLoadLibraryFunction(context.typeProvider);
+ }
+ return context;
+ }
+}
+
+/**
+ * An analysis context that has a fake SDK that is much smaller and faster for
+ * testing purposes.
+ */
+class AnalysisContextForTests extends AnalysisContextImpl {
+ @override
+ void set analysisOptions(AnalysisOptions options) {
+ AnalysisOptions currentOptions = analysisOptions;
+ bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate !=
+ options.analyzeFunctionBodiesPredicate ||
+ currentOptions.generateImplicitErrors !=
+ options.generateImplicitErrors ||
+ currentOptions.generateSdkErrors != options.generateSdkErrors ||
+ currentOptions.dart2jsHint != options.dart2jsHint ||
+ (currentOptions.hint && !options.hint) ||
+ currentOptions.preserveComments != options.preserveComments ||
+ currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
+ if (needsRecompute) {
+ fail(
+ "Cannot set options that cause the sources to be reanalyzed in a test context");
+ }
+ super.analysisOptions = options;
+ }
+
+ @override
+ bool exists(Source source) =>
+ super.exists(source) || sourceFactory.dartSdk.context.exists(source);
+
+ @override
+ TimestampedData<String> getContents(Source source) {
+ if (source.isInSystemLibrary) {
+ return sourceFactory.dartSdk.context.getContents(source);
+ }
+ return super.getContents(source);
+ }
+
+ @override
+ int getModificationStamp(Source source) {
+ if (source.isInSystemLibrary) {
+ return sourceFactory.dartSdk.context.getModificationStamp(source);
+ }
+ return super.getModificationStamp(source);
+ }
+
+ /**
+ * Set the analysis options, even if they would force re-analysis. This method should only be
+ * invoked before the fake SDK is initialized.
+ *
+ * @param options the analysis options to be set
+ */
+ void _internalSetAnalysisOptions(AnalysisOptions options) {
+ super.analysisOptions = options;
+ }
+}
+
+/**
+ * Helper for creating and managing single [AnalysisContext].
+ */
+class AnalysisContextHelper {
+ AnalysisContext context;
+
+ /**
+ * Creates new [AnalysisContext] using [AnalysisContextFactory].
+ */
+ AnalysisContextHelper([AnalysisOptionsImpl options]) {
+ if (options == null) {
+ options = new AnalysisOptionsImpl();
+ }
+ options.cacheSize = 256;
+ context = AnalysisContextFactory.contextWithCoreAndOptions(options);
+ }
+
+ Source addSource(String path, String code) {
+ Source source = new FileBasedSource(FileUtilities2.createFile(path));
+ if (path.endsWith(".dart") || path.endsWith(".html")) {
+ ChangeSet changeSet = new ChangeSet();
+ changeSet.addedSource(source);
+ context.applyChanges(changeSet);
+ }
+ context.setContents(source, code);
+ return source;
+ }
+
+ CompilationUnitElement getDefiningUnitElement(Source source) =>
+ context.getCompilationUnitElement(source, source);
+
+ CompilationUnit resolveDefiningUnit(Source source) {
+ LibraryElement libraryElement = context.computeLibraryElement(source);
+ return context.resolveCompilationUnit(source, libraryElement);
+ }
+
+ void runTasks() {
+ AnalysisResult result = context.performAnalysisTask();
+ while (result.changeNotices != null) {
+ result = context.performAnalysisTask();
+ }
+ }
+}
+
+class TestPackageUriResolver extends UriResolver {
+ Map<Uri, Source> sourceMap = new HashMap<Uri, Source>();
+
+ TestPackageUriResolver(Map<String, String> map) {
+ map.forEach((String uri, String contents) {
+ sourceMap[Uri.parse(uri)] =
+ new StringSource(contents, '/test_pkg_source.dart');
+ });
+ }
+
+ @override
+ Source resolveAbsolute(Uri uri, [Uri actualUri]) => sourceMap[uri];
+
+ @override
+ Uri restoreAbsolute(Source source) => throw new UnimplementedError();
+}
+
+class _AnalysisContextFactory_initContextWithCore
+ extends DirectoryBasedDartSdk {
+ final bool enableAsync;
+ _AnalysisContextFactory_initContextWithCore(JavaFile arg0,
+ {this.enableAsync: true})
+ : super(arg0);
+
+ @override
+ LibraryMap initialLibraryMap(bool useDart2jsPaths) {
+ LibraryMap map = new LibraryMap();
+ if (enableAsync) {
+ _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart");
+ }
+ _addLibrary(map, DartSdk.DART_CORE, false, "core.dart");
+ _addLibrary(map, DartSdk.DART_HTML, false, "html_dartium.dart");
+ _addLibrary(map, AnalysisContextFactory._DART_MATH, false, "math.dart");
+ _addLibrary(map, AnalysisContextFactory._DART_INTERCEPTORS, true,
+ "_interceptors.dart");
+ _addLibrary(
+ map, AnalysisContextFactory._DART_JS_HELPER, true, "_js_helper.dart");
+ return map;
+ }
+
+ void _addLibrary(LibraryMap map, String uri, bool isInternal, String path) {
+ SdkLibraryImpl library = new SdkLibraryImpl(uri);
+ if (isInternal) {
+ library.category = "Internal";
+ }
+ library.path = path;
+ map.setLibrary(uri, library);
+ }
+}
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
new file mode 100644
index 0000000..e3eaeaf
--- /dev/null
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -0,0 +1,619 @@
+// 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 analyzer.test.generated.checked_mode_compile_time_error_code_test;
+
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'resolver_test_case.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(CheckedModeCompileTimeErrorCodeTest);
+}
+
+@reflectiveTest
+class CheckedModeCompileTimeErrorCodeTest extends ResolverTestCase {
+ void test_fieldFormalParameterAssignableToField_extends() {
+ // According to checked-mode type checking rules, a value of type B is
+ // assignable to a field of type A, because B extends A (and hence is a
+ // subtype of A).
+ Source source = addSource(r'''
+class A {
+ const A();
+}
+class B extends A {
+ const B();
+}
+class C {
+ final A a;
+ const C(this.a);
+}
+var v = const C(const B());''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() {
+ // Null always passes runtime type checks, even when the type is
+ // unresolved.
+ Source source = addSource(r'''
+class A {
+ final Unresolved x;
+ const A(String this.x);
+}
+var v = const A(null);''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_implements() {
+ // According to checked-mode type checking rules, a value of type B is
+ // assignable to a field of type A, because B implements A (and hence is a
+ // subtype of A).
+ Source source = addSource(r'''
+class A {}
+class B implements A {
+ const B();
+}
+class C {
+ final A a;
+ const C(this.a);
+}
+var v = const C(const B());''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_list_dynamic() {
+ // [1, 2, 3] has type List<dynamic>, which is a subtype of List<int>.
+ Source source = addSource(r'''
+class A {
+ const A(List<int> x);
+}
+var x = const A(const [1, 2, 3]);''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_list_nonDynamic() {
+ // <int>[1, 2, 3] has type List<int>, which is a subtype of List<num>.
+ Source source = addSource(r'''
+class A {
+ const A(List<num> x);
+}
+var x = const A(const <int>[1, 2, 3]);''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_map_dynamic() {
+ // {1: 2} has type Map<dynamic, dynamic>, which is a subtype of
+ // Map<int, int>.
+ Source source = addSource(r'''
+class A {
+ const A(Map<int, int> x);
+}
+var x = const A(const {1: 2});''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_map_keyDifferent() {
+ // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
+ // Map<num, int>.
+ Source source = addSource(r'''
+class A {
+ const A(Map<num, int> x);
+}
+var x = const A(const <int, int>{1: 2});''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_map_valueDifferent() {
+ // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
+ // Map<int, num>.
+ Source source = addSource(r'''
+class A {
+ const A(Map<int, num> x);
+}
+var x = const A(const <int, int>{1: 2});''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_notype() {
+ // If a field is declared without a type, then any value may be assigned to
+ // it.
+ Source source = addSource(r'''
+class A {
+ final x;
+ const A(this.x);
+}
+var v = const A(5);''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_null() {
+ // Null is assignable to anything.
+ Source source = addSource(r'''
+class A {
+ final int x;
+ const A(this.x);
+}
+var v = const A(null);''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_typedef() {
+ // foo has the runtime type dynamic -> dynamic, so it should be assignable
+ // to A.f.
+ Source source = addSource(r'''
+typedef String Int2String(int x);
+class A {
+ final Int2String f;
+ const A(this.f);
+}
+foo(x) => 1;
+var v = const A(foo);''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterAssignableToField_typeSubstitution() {
+ // foo has the runtime type dynamic -> dynamic, so it should be assignable
+ // to A.f.
+ Source source = addSource(r'''
+class A<T> {
+ final T x;
+ const A(this.x);
+}
+var v = const A<int>(3);''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterNotAssignableToField() {
+ Source source = addSource(r'''
+class A {
+ final int x;
+ const A(this.x);
+}
+var v = const A('foo');''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterNotAssignableToField_extends() {
+ // According to checked-mode type checking rules, a value of type A is not
+ // assignable to a field of type B, because B extends A (the subtyping
+ // relationship is in the wrong direction).
+ Source source = addSource(r'''
+class A {
+ const A();
+}
+class B extends A {
+ const B();
+}
+class C {
+ final B b;
+ const C(this.b);
+}
+var v = const C(const A());''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterNotAssignableToField_fieldType() {
+ Source source = addSource(r'''
+class A {
+ final int x;
+ const A(String this.x);
+}
+var v = const A('foo');''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+ StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() {
+ Source source = addSource(r'''
+class A {
+ final Unresolved x;
+ const A(String this.x);
+}
+var v = const A('foo');''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+ StaticWarningCode.UNDEFINED_CLASS
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterNotAssignableToField_implements() {
+ // According to checked-mode type checking rules, a value of type A is not
+ // assignable to a field of type B, because B implements A (the subtyping
+ // relationship is in the wrong direction).
+ Source source = addSource(r'''
+class A {
+ const A();
+}
+class B implements A {}
+class C {
+ final B b;
+ const C(this.b);
+}
+var v = const C(const A());''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterNotAssignableToField_list() {
+ // <num>[1, 2, 3] has type List<num>, which is not a subtype of List<int>.
+ Source source = addSource(r'''
+class A {
+ const A(List<int> x);
+}
+var x = const A(const <num>[1, 2, 3]);''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterNotAssignableToField_map_keyMismatch() {
+ // <num, int>{1: 2} has type Map<num, int>, which is not a subtype of
+ // Map<int, int>.
+ Source source = addSource(r'''
+class A {
+ const A(Map<int, int> x);
+}
+var x = const A(const <num, int>{1: 2});''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterNotAssignableToField_map_valueMismatch() {
+ // <int, num>{1: 2} has type Map<int, num>, which is not a subtype of
+ // Map<int, int>.
+ Source source = addSource(r'''
+class A {
+ const A(Map<int, int> x);
+}
+var x = const A(const <int, num>{1: 2});''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterNotAssignableToField_optional() {
+ Source source = addSource(r'''
+class A {
+ final int x;
+ const A([this.x = 'foo']);
+}
+var v = const A();''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+ StaticTypeWarningCode.INVALID_ASSIGNMENT
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameterNotAssignableToField_typedef() {
+ // foo has the runtime type String -> int, so it should not be assignable
+ // to A.f (A.f requires it to be int -> String).
+ Source source = addSource(r'''
+typedef String Int2String(int x);
+class A {
+ final Int2String f;
+ const A(this.f);
+}
+int foo(String x) => 1;
+var v = const A(foo);''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldInitializerNotAssignable() {
+ Source source = addSource(r'''
+class A {
+ final int x;
+ const A() : x = '';
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
+ StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldTypeMismatch() {
+ Source source = addSource(r'''
+class A {
+ const A(x) : y = x;
+ final int y;
+}
+var v = const A('foo');''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldTypeMismatch_generic() {
+ Source source = addSource(r'''
+class C<T> {
+ final T x = y;
+ const C();
+}
+const int y = 1;
+var v = const C<String>();
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+ StaticTypeWarningCode.INVALID_ASSIGNMENT
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldTypeMismatch_unresolved() {
+ Source source = addSource(r'''
+class A {
+ const A(x) : y = x;
+ final Unresolved y;
+}
+var v = const A('foo');''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+ StaticWarningCode.UNDEFINED_CLASS
+ ]);
+ verify([source]);
+ }
+
+ void test_fieldTypeOk_generic() {
+ Source source = addSource(r'''
+class C<T> {
+ final T x = y;
+ const C();
+}
+const int y = 1;
+var v = const C<int>();
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ verify([source]);
+ }
+
+ void test_fieldTypeOk_null() {
+ Source source = addSource(r'''
+class A {
+ const A(x) : y = x;
+ final int y;
+}
+var v = const A(null);''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldTypeOk_unresolved_null() {
+ // Null always passes runtime type checks, even when the type is
+ // unresolved.
+ Source source = addSource(r'''
+class A {
+ const A(x) : y = x;
+ final Unresolved y;
+}
+var v = const A(null);''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
+ verify([source]);
+ }
+
+ void test_listElementTypeNotAssignable() {
+ Source source = addSource("var v = const <String> [42];");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
+ StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+ ]);
+ verify([source]);
+ }
+
+ void test_mapKeyTypeNotAssignable() {
+ Source source = addSource("var v = const <String, int > {1 : 2};");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+ StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE
+ ]);
+ verify([source]);
+ }
+
+ void test_mapValueTypeNotAssignable() {
+ Source source = addSource("var v = const <String, String> {'a' : 2};");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+ StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE
+ ]);
+ verify([source]);
+ }
+
+ void test_parameterAssignable_null() {
+ // Null is assignable to anything.
+ Source source = addSource(r'''
+class A {
+ const A(int x);
+}
+var v = const A(null);''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_parameterAssignable_typeSubstitution() {
+ Source source = addSource(r'''
+class A<T> {
+ const A(T x);
+}
+var v = const A<int>(3);''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_parameterAssignable_undefined_null() {
+ // Null always passes runtime type checks, even when the type is
+ // unresolved.
+ Source source = addSource(r'''
+class A {
+ const A(Unresolved x);
+}
+var v = const A(null);''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
+ verify([source]);
+ }
+
+ void test_parameterNotAssignable() {
+ Source source = addSource(r'''
+class A {
+ const A(int x);
+}
+var v = const A('foo');''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ ]);
+ verify([source]);
+ }
+
+ void test_parameterNotAssignable_typeSubstitution() {
+ Source source = addSource(r'''
+class A<T> {
+ const A(T x);
+}
+var v = const A<int>('foo');''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ ]);
+ verify([source]);
+ }
+
+ void test_parameterNotAssignable_undefined() {
+ Source source = addSource(r'''
+class A {
+ const A(Unresolved x);
+}
+var v = const A('foo');''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+ StaticWarningCode.UNDEFINED_CLASS
+ ]);
+ verify([source]);
+ }
+
+ void test_redirectingConstructor_paramTypeMismatch() {
+ Source source = addSource(r'''
+class A {
+ const A.a1(x) : this.a2(x);
+ const A.a2(String x);
+}
+var v = const A.a1(0);''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+ ]);
+ verify([source]);
+ }
+
+ void test_topLevelVarAssignable_null() {
+ Source source = addSource("const int x = null;");
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_topLevelVarAssignable_undefined_null() {
+ // Null always passes runtime type checks, even when the type is
+ // unresolved.
+ Source source = addSource("const Unresolved x = null;");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
+ verify([source]);
+ }
+
+ void test_topLevelVarNotAssignable() {
+ Source source = addSource("const int x = 'foo';");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
+ StaticTypeWarningCode.INVALID_ASSIGNMENT
+ ]);
+ verify([source]);
+ }
+
+ void test_topLevelVarNotAssignable_undefined() {
+ Source source = addSource("const Unresolved x = 'foo';");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
+ StaticWarningCode.UNDEFINED_CLASS
+ ]);
+ verify([source]);
+ }
+}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 6327745..6231930 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -12,7 +12,7 @@
import '../reflective_tests.dart';
import '../utils.dart';
-import 'resolver_test.dart';
+import 'resolver_test_case.dart';
main() {
initializeTestEnvironment();
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index bb9ba02..dc95b3a 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -27,7 +27,7 @@
import '../reflective_tests.dart';
import '../utils.dart';
import 'engine_test.dart';
-import 'resolver_test.dart';
+import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index 35eda15..fc3a4c3 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -17,7 +17,7 @@
import '../reflective_tests.dart';
import '../utils.dart';
-import 'resolver_test.dart';
+import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
@@ -267,7 +267,7 @@
analysisContext.computeResult(source, LIBRARY_ELEMENT1);
CompilationUnit unit =
analysisContext.computeResult(target, RESOLVED_UNIT1);
- CompilationUnit unit2 = _cloneResolveUnit(unit);
+ _cloneResolveUnit(unit);
}
void test_functionDeclaration_getter() {
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
new file mode 100644
index 0000000..a4cd97e
--- /dev/null
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -0,0 +1,1011 @@
+// 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 analyzer.test.generated.element_resolver_test;
+
+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/element/element.dart';
+import 'package:analyzer/src/generated/element_resolver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'analysis_context_factory.dart';
+import 'test_support.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(ElementResolverTest);
+}
+
+@reflectiveTest
+class ElementResolverTest extends EngineTestCase {
+ /**
+ * The error listener to which errors will be reported.
+ */
+ GatheringErrorListener _listener;
+
+ /**
+ * The type provider used to access the types.
+ */
+ TestTypeProvider _typeProvider;
+
+ /**
+ * The library containing the code being resolved.
+ */
+ LibraryElementImpl _definingLibrary;
+
+ /**
+ * The resolver visitor that maintains the state for the resolver.
+ */
+ ResolverVisitor _visitor;
+
+ /**
+ * The resolver being used to resolve the test cases.
+ */
+ ElementResolver _resolver;
+
+ void fail_visitExportDirective_combinators() {
+ fail("Not yet tested");
+ // Need to set up the exported library so that the identifier can be
+ // resolved.
+ ExportDirective directive = AstFactory.exportDirective2(null, [
+ AstFactory.hideCombinator2(["A"])
+ ]);
+ _resolveNode(directive);
+ _listener.assertNoErrors();
+ }
+
+ void fail_visitFunctionExpressionInvocation() {
+ fail("Not yet tested");
+ _listener.assertNoErrors();
+ }
+
+ void fail_visitImportDirective_combinators_noPrefix() {
+ fail("Not yet tested");
+ // Need to set up the imported library so that the identifier can be
+ // resolved.
+ ImportDirective directive = AstFactory.importDirective3(null, null, [
+ AstFactory.showCombinator2(["A"])
+ ]);
+ _resolveNode(directive);
+ _listener.assertNoErrors();
+ }
+
+ void fail_visitImportDirective_combinators_prefix() {
+ fail("Not yet tested");
+ // Need to set up the imported library so that the identifiers can be
+ // resolved.
+ String prefixName = "p";
+ _definingLibrary.imports = <ImportElement>[
+ ElementFactory.importFor(null, ElementFactory.prefix(prefixName))
+ ];
+ ImportDirective directive = AstFactory.importDirective3(null, prefixName, [
+ AstFactory.showCombinator2(["A"]),
+ AstFactory.hideCombinator2(["B"])
+ ]);
+ _resolveNode(directive);
+ _listener.assertNoErrors();
+ }
+
+ void fail_visitRedirectingConstructorInvocation() {
+ fail("Not yet tested");
+ _listener.assertNoErrors();
+ }
+
+ @override
+ void setUp() {
+ super.setUp();
+ _listener = new GatheringErrorListener();
+ _typeProvider = new TestTypeProvider();
+ _resolver = _createResolver();
+ }
+
+ void test_lookUpMethodInInterfaces() {
+ InterfaceType intType = _typeProvider.intType;
+ //
+ // abstract class A { int operator[](int index); }
+ //
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ MethodElement operator =
+ ElementFactory.methodElement("[]", intType, [intType]);
+ classA.methods = <MethodElement>[operator];
+ //
+ // class B implements A {}
+ //
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.interfaces = <InterfaceType>[classA.type];
+ //
+ // class C extends Object with B {}
+ //
+ ClassElementImpl classC = ElementFactory.classElement2("C");
+ classC.mixins = <InterfaceType>[classB.type];
+ //
+ // class D extends C {}
+ //
+ ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
+ //
+ // D a;
+ // a[i];
+ //
+ SimpleIdentifier array = AstFactory.identifier3("a");
+ array.staticType = classD.type;
+ IndexExpression expression =
+ AstFactory.indexExpression(array, AstFactory.identifier3("i"));
+ expect(_resolveIndexExpression(expression), same(operator));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitAssignmentExpression_compound() {
+ InterfaceType intType = _typeProvider.intType;
+ SimpleIdentifier leftHandSide = AstFactory.identifier3("a");
+ leftHandSide.staticType = intType;
+ AssignmentExpression assignment = AstFactory.assignmentExpression(
+ leftHandSide, TokenType.PLUS_EQ, AstFactory.integer(1));
+ _resolveNode(assignment);
+ expect(
+ assignment.staticElement, same(getMethod(_typeProvider.numType, "+")));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitAssignmentExpression_simple() {
+ AssignmentExpression expression = AstFactory.assignmentExpression(
+ AstFactory.identifier3("x"), TokenType.EQ, AstFactory.integer(0));
+ _resolveNode(expression);
+ expect(expression.staticElement, isNull);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_bangEq() {
+ // String i;
+ // var j;
+ // i == j
+ InterfaceType stringType = _typeProvider.stringType;
+ SimpleIdentifier left = AstFactory.identifier3("i");
+ left.staticType = stringType;
+ BinaryExpression expression = AstFactory.binaryExpression(
+ left, TokenType.BANG_EQ, AstFactory.identifier3("j"));
+ _resolveNode(expression);
+ var stringElement = stringType.element;
+ expect(expression.staticElement, isNotNull);
+ expect(
+ expression.staticElement,
+ stringElement.lookUpMethod(
+ TokenType.EQ_EQ.lexeme, stringElement.library));
+ expect(expression.propagatedElement, isNull);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_eq() {
+ // String i;
+ // var j;
+ // i == j
+ InterfaceType stringType = _typeProvider.stringType;
+ SimpleIdentifier left = AstFactory.identifier3("i");
+ left.staticType = stringType;
+ BinaryExpression expression = AstFactory.binaryExpression(
+ left, TokenType.EQ_EQ, AstFactory.identifier3("j"));
+ _resolveNode(expression);
+ var stringElement = stringType.element;
+ expect(
+ expression.staticElement,
+ stringElement.lookUpMethod(
+ TokenType.EQ_EQ.lexeme, stringElement.library));
+ expect(expression.propagatedElement, isNull);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_plus() {
+ // num i;
+ // var j;
+ // i + j
+ InterfaceType numType = _typeProvider.numType;
+ SimpleIdentifier left = AstFactory.identifier3("i");
+ left.staticType = numType;
+ BinaryExpression expression = AstFactory.binaryExpression(
+ left, TokenType.PLUS, AstFactory.identifier3("j"));
+ _resolveNode(expression);
+ expect(expression.staticElement, getMethod(numType, "+"));
+ expect(expression.propagatedElement, isNull);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_plus_propagatedElement() {
+ // var i = 1;
+ // var j;
+ // i + j
+ InterfaceType numType = _typeProvider.numType;
+ SimpleIdentifier left = AstFactory.identifier3("i");
+ left.propagatedType = numType;
+ BinaryExpression expression = AstFactory.binaryExpression(
+ left, TokenType.PLUS, AstFactory.identifier3("j"));
+ _resolveNode(expression);
+ expect(expression.staticElement, isNull);
+ expect(expression.propagatedElement, getMethod(numType, "+"));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBreakStatement_withLabel() {
+ // loop: while (true) {
+ // break loop;
+ // }
+ String label = "loop";
+ LabelElementImpl labelElement = new LabelElementImpl.forNode(
+ AstFactory.identifier3(label), false, false);
+ BreakStatement breakStatement = AstFactory.breakStatement2(label);
+ Expression condition = AstFactory.booleanLiteral(true);
+ WhileStatement whileStatement =
+ AstFactory.whileStatement(condition, breakStatement);
+ expect(_resolveBreak(breakStatement, labelElement, whileStatement),
+ same(labelElement));
+ expect(breakStatement.target, same(whileStatement));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBreakStatement_withoutLabel() {
+ BreakStatement statement = AstFactory.breakStatement();
+ _resolveStatement(statement, null, null);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitCommentReference_prefixedIdentifier_class_getter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ // set accessors
+ String propName = "p";
+ PropertyAccessorElement getter =
+ ElementFactory.getterElement(propName, false, _typeProvider.intType);
+ PropertyAccessorElement setter =
+ ElementFactory.setterElement(propName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getter, setter];
+ // set name scope
+ _visitor.nameScope = new EnclosedScope(null)
+ ..defineNameWithoutChecking('A', classA);
+ // prepare "A.p"
+ PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'p');
+ CommentReference commentReference = new CommentReference(null, prefixed);
+ // resolve
+ _resolveNode(commentReference);
+ expect(prefixed.prefix.staticElement, classA);
+ expect(prefixed.identifier.staticElement, getter);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitCommentReference_prefixedIdentifier_class_method() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ // set method
+ MethodElement method =
+ ElementFactory.methodElement("m", _typeProvider.intType);
+ classA.methods = <MethodElement>[method];
+ // set name scope
+ _visitor.nameScope = new EnclosedScope(null)
+ ..defineNameWithoutChecking('A', classA);
+ // prepare "A.m"
+ PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'm');
+ CommentReference commentReference = new CommentReference(null, prefixed);
+ // resolve
+ _resolveNode(commentReference);
+ expect(prefixed.prefix.staticElement, classA);
+ expect(prefixed.identifier.staticElement, method);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitConstructorName_named() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String constructorName = "a";
+ ConstructorElement constructor =
+ ElementFactory.constructorElement2(classA, constructorName);
+ classA.constructors = <ConstructorElement>[constructor];
+ ConstructorName name = AstFactory.constructorName(
+ AstFactory.typeName(classA), constructorName);
+ _resolveNode(name);
+ expect(name.staticElement, same(constructor));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitConstructorName_unnamed() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String constructorName = null;
+ ConstructorElement constructor =
+ ElementFactory.constructorElement2(classA, constructorName);
+ classA.constructors = <ConstructorElement>[constructor];
+ ConstructorName name = AstFactory.constructorName(
+ AstFactory.typeName(classA), constructorName);
+ _resolveNode(name);
+ expect(name.staticElement, same(constructor));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitContinueStatement_withLabel() {
+ // loop: while (true) {
+ // continue loop;
+ // }
+ String label = "loop";
+ LabelElementImpl labelElement = new LabelElementImpl.forNode(
+ AstFactory.identifier3(label), false, false);
+ ContinueStatement continueStatement = AstFactory.continueStatement(label);
+ Expression condition = AstFactory.booleanLiteral(true);
+ WhileStatement whileStatement =
+ AstFactory.whileStatement(condition, continueStatement);
+ expect(_resolveContinue(continueStatement, labelElement, whileStatement),
+ same(labelElement));
+ expect(continueStatement.target, same(whileStatement));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitContinueStatement_withoutLabel() {
+ ContinueStatement statement = AstFactory.continueStatement();
+ _resolveStatement(statement, null, null);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitEnumDeclaration() {
+ CompilationUnitElementImpl compilationUnitElement =
+ ElementFactory.compilationUnit('foo.dart');
+ ClassElementImpl enumElement =
+ ElementFactory.enumElement(_typeProvider, ('E'));
+ compilationUnitElement.enums = <ClassElement>[enumElement];
+ EnumDeclaration enumNode = AstFactory.enumDeclaration2('E', []);
+ Annotation annotationNode =
+ AstFactory.annotation(AstFactory.identifier3('a'));
+ annotationNode.element = ElementFactory.classElement2('A');
+ annotationNode.elementAnnotation =
+ new ElementAnnotationImpl(compilationUnitElement);
+ enumNode.metadata.add(annotationNode);
+ enumNode.name.staticElement = enumElement;
+ List<ElementAnnotation> metadata = <ElementAnnotation>[
+ annotationNode.elementAnnotation
+ ];
+ _resolveNode(enumNode);
+ expect(metadata[0].element, annotationNode.element);
+ }
+
+ void test_visitExportDirective_noCombinators() {
+ ExportDirective directive = AstFactory.exportDirective2(null);
+ directive.element = ElementFactory
+ .exportFor(ElementFactory.library(_definingLibrary.context, "lib"));
+ _resolveNode(directive);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFieldFormalParameter() {
+ String fieldName = "f";
+ InterfaceType intType = _typeProvider.intType;
+ FieldElementImpl fieldElement =
+ ElementFactory.fieldElement(fieldName, false, false, false, intType);
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.fields = <FieldElement>[fieldElement];
+ FieldFormalParameter parameter =
+ AstFactory.fieldFormalParameter2(fieldName);
+ FieldFormalParameterElementImpl parameterElement =
+ ElementFactory.fieldFormalParameter(parameter.identifier);
+ parameterElement.field = fieldElement;
+ parameterElement.type = intType;
+ parameter.identifier.staticElement = parameterElement;
+ _resolveInClass(parameter, classA);
+ expect(parameter.element.type, same(intType));
+ }
+
+ void test_visitImportDirective_noCombinators_noPrefix() {
+ ImportDirective directive = AstFactory.importDirective3(null, null);
+ directive.element = ElementFactory.importFor(
+ ElementFactory.library(_definingLibrary.context, "lib"), null);
+ _resolveNode(directive);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitImportDirective_noCombinators_prefix() {
+ String prefixName = "p";
+ ImportElement importElement = ElementFactory.importFor(
+ ElementFactory.library(_definingLibrary.context, "lib"),
+ ElementFactory.prefix(prefixName));
+ _definingLibrary.imports = <ImportElement>[importElement];
+ ImportDirective directive = AstFactory.importDirective3(null, prefixName);
+ directive.element = importElement;
+ _resolveNode(directive);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitImportDirective_withCombinators() {
+ ShowCombinator combinator = AstFactory.showCombinator2(["A", "B", "C"]);
+ ImportDirective directive =
+ AstFactory.importDirective3(null, null, [combinator]);
+ LibraryElementImpl library =
+ ElementFactory.library(_definingLibrary.context, "lib");
+ TopLevelVariableElementImpl varA =
+ ElementFactory.topLevelVariableElement2("A");
+ TopLevelVariableElementImpl varB =
+ ElementFactory.topLevelVariableElement2("B");
+ TopLevelVariableElementImpl varC =
+ ElementFactory.topLevelVariableElement2("C");
+ CompilationUnitElementImpl unit =
+ library.definingCompilationUnit as CompilationUnitElementImpl;
+ unit.accessors = <PropertyAccessorElement>[
+ varA.getter,
+ varA.setter,
+ varB.getter,
+ varC.setter
+ ];
+ unit.topLevelVariables = <TopLevelVariableElement>[varA, varB, varC];
+ directive.element = ElementFactory.importFor(library, null);
+ _resolveNode(directive);
+ expect(combinator.shownNames[0].staticElement, same(varA));
+ expect(combinator.shownNames[1].staticElement, same(varB));
+ expect(combinator.shownNames[2].staticElement, same(varC));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitIndexExpression_get() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ InterfaceType intType = _typeProvider.intType;
+ MethodElement getter =
+ ElementFactory.methodElement("[]", intType, [intType]);
+ classA.methods = <MethodElement>[getter];
+ SimpleIdentifier array = AstFactory.identifier3("a");
+ array.staticType = classA.type;
+ IndexExpression expression =
+ AstFactory.indexExpression(array, AstFactory.identifier3("i"));
+ expect(_resolveIndexExpression(expression), same(getter));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitIndexExpression_set() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ InterfaceType intType = _typeProvider.intType;
+ MethodElement setter =
+ ElementFactory.methodElement("[]=", intType, [intType]);
+ classA.methods = <MethodElement>[setter];
+ SimpleIdentifier array = AstFactory.identifier3("a");
+ array.staticType = classA.type;
+ IndexExpression expression =
+ AstFactory.indexExpression(array, AstFactory.identifier3("i"));
+ AstFactory.assignmentExpression(
+ expression, TokenType.EQ, AstFactory.integer(0));
+ expect(_resolveIndexExpression(expression), same(setter));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitInstanceCreationExpression_named() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String constructorName = "a";
+ ConstructorElement constructor =
+ ElementFactory.constructorElement2(classA, constructorName);
+ classA.constructors = <ConstructorElement>[constructor];
+ ConstructorName name = AstFactory.constructorName(
+ AstFactory.typeName(classA), constructorName);
+ name.staticElement = constructor;
+ InstanceCreationExpression creation =
+ AstFactory.instanceCreationExpression(Keyword.NEW, name);
+ _resolveNode(creation);
+ expect(creation.staticElement, same(constructor));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitInstanceCreationExpression_unnamed() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String constructorName = null;
+ ConstructorElement constructor =
+ ElementFactory.constructorElement2(classA, constructorName);
+ classA.constructors = <ConstructorElement>[constructor];
+ ConstructorName name = AstFactory.constructorName(
+ AstFactory.typeName(classA), constructorName);
+ name.staticElement = constructor;
+ InstanceCreationExpression creation =
+ AstFactory.instanceCreationExpression(Keyword.NEW, name);
+ _resolveNode(creation);
+ expect(creation.staticElement, same(constructor));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitInstanceCreationExpression_unnamed_namedParameter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String constructorName = null;
+ ConstructorElementImpl constructor =
+ ElementFactory.constructorElement2(classA, constructorName);
+ String parameterName = "a";
+ ParameterElement parameter = ElementFactory.namedParameter(parameterName);
+ constructor.parameters = <ParameterElement>[parameter];
+ classA.constructors = <ConstructorElement>[constructor];
+ ConstructorName name = AstFactory.constructorName(
+ AstFactory.typeName(classA), constructorName);
+ name.staticElement = constructor;
+ InstanceCreationExpression creation = AstFactory.instanceCreationExpression(
+ Keyword.NEW,
+ name,
+ [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
+ _resolveNode(creation);
+ expect(creation.staticElement, same(constructor));
+ expect(
+ (creation.argumentList.arguments[0] as NamedExpression)
+ .name
+ .label
+ .staticElement,
+ same(parameter));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitMethodInvocation() {
+ InterfaceType numType = _typeProvider.numType;
+ SimpleIdentifier left = AstFactory.identifier3("i");
+ left.staticType = numType;
+ String methodName = "abs";
+ MethodInvocation invocation = AstFactory.methodInvocation(left, methodName);
+ _resolveNode(invocation);
+ expect(invocation.methodName.staticElement,
+ same(getMethod(numType, methodName)));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitMethodInvocation_namedParameter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ String parameterName = "p";
+ MethodElementImpl method = ElementFactory.methodElement(methodName, null);
+ ParameterElement parameter = ElementFactory.namedParameter(parameterName);
+ method.parameters = <ParameterElement>[parameter];
+ classA.methods = <MethodElement>[method];
+ SimpleIdentifier left = AstFactory.identifier3("i");
+ left.staticType = classA.type;
+ MethodInvocation invocation = AstFactory.methodInvocation(left, methodName,
+ [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
+ _resolveNode(invocation);
+ expect(invocation.methodName.staticElement, same(method));
+ expect(
+ (invocation.argumentList.arguments[0] as NamedExpression)
+ .name
+ .label
+ .staticElement,
+ same(parameter));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPostfixExpression() {
+ InterfaceType numType = _typeProvider.numType;
+ SimpleIdentifier operand = AstFactory.identifier3("i");
+ operand.staticType = numType;
+ PostfixExpression expression =
+ AstFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
+ _resolveNode(expression);
+ expect(expression.staticElement, getMethod(numType, "+"));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixedIdentifier_dynamic() {
+ DartType dynamicType = _typeProvider.dynamicType;
+ SimpleIdentifier target = AstFactory.identifier3("a");
+ VariableElementImpl variable = ElementFactory.localVariableElement(target);
+ variable.type = dynamicType;
+ target.staticElement = variable;
+ target.staticType = dynamicType;
+ PrefixedIdentifier identifier =
+ AstFactory.identifier(target, AstFactory.identifier3("b"));
+ _resolveNode(identifier);
+ expect(identifier.staticElement, isNull);
+ expect(identifier.identifier.staticElement, isNull);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixedIdentifier_nonDynamic() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "b";
+ PropertyAccessorElement getter =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getter];
+ SimpleIdentifier target = AstFactory.identifier3("a");
+ VariableElementImpl variable = ElementFactory.localVariableElement(target);
+ variable.type = classA.type;
+ target.staticElement = variable;
+ target.staticType = classA.type;
+ PrefixedIdentifier identifier =
+ AstFactory.identifier(target, AstFactory.identifier3(getterName));
+ _resolveNode(identifier);
+ expect(identifier.staticElement, same(getter));
+ expect(identifier.identifier.staticElement, same(getter));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixedIdentifier_staticClassMember_getter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ // set accessors
+ String propName = "b";
+ PropertyAccessorElement getter =
+ ElementFactory.getterElement(propName, false, _typeProvider.intType);
+ PropertyAccessorElement setter =
+ ElementFactory.setterElement(propName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getter, setter];
+ // prepare "A.m"
+ SimpleIdentifier target = AstFactory.identifier3("A");
+ target.staticElement = classA;
+ target.staticType = classA.type;
+ PrefixedIdentifier identifier =
+ AstFactory.identifier(target, AstFactory.identifier3(propName));
+ // resolve
+ _resolveNode(identifier);
+ expect(identifier.staticElement, same(getter));
+ expect(identifier.identifier.staticElement, same(getter));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixedIdentifier_staticClassMember_method() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ // set methods
+ String propName = "m";
+ MethodElement method =
+ ElementFactory.methodElement("m", _typeProvider.intType);
+ classA.methods = <MethodElement>[method];
+ // prepare "A.m"
+ SimpleIdentifier target = AstFactory.identifier3("A");
+ target.staticElement = classA;
+ target.staticType = classA.type;
+ PrefixedIdentifier identifier =
+ AstFactory.identifier(target, AstFactory.identifier3(propName));
+ AstFactory.assignmentExpression(
+ identifier, TokenType.EQ, AstFactory.nullLiteral());
+ // resolve
+ _resolveNode(identifier);
+ expect(identifier.staticElement, same(method));
+ expect(identifier.identifier.staticElement, same(method));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixedIdentifier_staticClassMember_setter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ // set accessors
+ String propName = "b";
+ PropertyAccessorElement getter =
+ ElementFactory.getterElement(propName, false, _typeProvider.intType);
+ PropertyAccessorElement setter =
+ ElementFactory.setterElement(propName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getter, setter];
+ // prepare "A.b = null"
+ SimpleIdentifier target = AstFactory.identifier3("A");
+ target.staticElement = classA;
+ target.staticType = classA.type;
+ PrefixedIdentifier identifier =
+ AstFactory.identifier(target, AstFactory.identifier3(propName));
+ AstFactory.assignmentExpression(
+ identifier, TokenType.EQ, AstFactory.nullLiteral());
+ // resolve
+ _resolveNode(identifier);
+ expect(identifier.staticElement, same(setter));
+ expect(identifier.identifier.staticElement, same(setter));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixExpression() {
+ InterfaceType numType = _typeProvider.numType;
+ SimpleIdentifier operand = AstFactory.identifier3("i");
+ operand.staticType = numType;
+ PrefixExpression expression =
+ AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
+ _resolveNode(expression);
+ expect(expression.staticElement, getMethod(numType, "+"));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPropertyAccess_getter_identifier() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "b";
+ PropertyAccessorElement getter =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getter];
+ SimpleIdentifier target = AstFactory.identifier3("a");
+ target.staticType = classA.type;
+ PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
+ _resolveNode(access);
+ expect(access.propertyName.staticElement, same(getter));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPropertyAccess_getter_super() {
+ //
+ // class A {
+ // int get b;
+ // }
+ // class B {
+ // ... super.m ...
+ // }
+ //
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "b";
+ PropertyAccessorElement getter =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getter];
+ SuperExpression target = AstFactory.superExpression();
+ target.staticType = ElementFactory.classElement("B", classA.type).type;
+ PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
+ AstFactory.methodDeclaration2(
+ null,
+ null,
+ null,
+ null,
+ AstFactory.identifier3("m"),
+ AstFactory.formalParameterList(),
+ AstFactory.expressionFunctionBody(access));
+ _resolveNode(access);
+ expect(access.propertyName.staticElement, same(getter));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPropertyAccess_setter_this() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String setterName = "b";
+ PropertyAccessorElement setter =
+ ElementFactory.setterElement(setterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[setter];
+ ThisExpression target = AstFactory.thisExpression();
+ target.staticType = classA.type;
+ PropertyAccess access = AstFactory.propertyAccess2(target, setterName);
+ AstFactory.assignmentExpression(
+ access, TokenType.EQ, AstFactory.integer(0));
+ _resolveNode(access);
+ expect(access.propertyName.staticElement, same(setter));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitSimpleIdentifier_classScope() {
+ InterfaceType doubleType = _typeProvider.doubleType;
+ String fieldName = "NAN";
+ SimpleIdentifier node = AstFactory.identifier3(fieldName);
+ _resolveInClass(node, doubleType.element);
+ expect(node.staticElement, getGetter(doubleType, fieldName));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitSimpleIdentifier_dynamic() {
+ SimpleIdentifier node = AstFactory.identifier3("dynamic");
+ _resolveIdentifier(node);
+ expect(node.staticElement, same(_typeProvider.dynamicType.element));
+ expect(node.staticType, same(_typeProvider.typeType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitSimpleIdentifier_lexicalScope() {
+ SimpleIdentifier node = AstFactory.identifier3("i");
+ VariableElementImpl element = ElementFactory.localVariableElement(node);
+ expect(_resolveIdentifier(node, [element]), same(element));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitSimpleIdentifier_lexicalScope_field_setter() {
+ InterfaceType intType = _typeProvider.intType;
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String fieldName = "a";
+ FieldElement field =
+ ElementFactory.fieldElement(fieldName, false, false, false, intType);
+ classA.fields = <FieldElement>[field];
+ classA.accessors = <PropertyAccessorElement>[field.getter, field.setter];
+ SimpleIdentifier node = AstFactory.identifier3(fieldName);
+ AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
+ _resolveInClass(node, classA);
+ Element element = node.staticElement;
+ EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
+ PropertyAccessorElement, element);
+ expect((element as PropertyAccessorElement).isSetter, isTrue);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitSuperConstructorInvocation() {
+ ClassElementImpl superclass = ElementFactory.classElement2("A");
+ ConstructorElementImpl superConstructor =
+ ElementFactory.constructorElement2(superclass, null);
+ superclass.constructors = <ConstructorElement>[superConstructor];
+ ClassElementImpl subclass =
+ ElementFactory.classElement("B", superclass.type);
+ ConstructorElementImpl subConstructor =
+ ElementFactory.constructorElement2(subclass, null);
+ subclass.constructors = <ConstructorElement>[subConstructor];
+ SuperConstructorInvocation invocation =
+ AstFactory.superConstructorInvocation();
+ _resolveInClass(invocation, subclass);
+ expect(invocation.staticElement, superConstructor);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitSuperConstructorInvocation_namedParameter() {
+ ClassElementImpl superclass = ElementFactory.classElement2("A");
+ ConstructorElementImpl superConstructor =
+ ElementFactory.constructorElement2(superclass, null);
+ String parameterName = "p";
+ ParameterElement parameter = ElementFactory.namedParameter(parameterName);
+ superConstructor.parameters = <ParameterElement>[parameter];
+ superclass.constructors = <ConstructorElement>[superConstructor];
+ ClassElementImpl subclass =
+ ElementFactory.classElement("B", superclass.type);
+ ConstructorElementImpl subConstructor =
+ ElementFactory.constructorElement2(subclass, null);
+ subclass.constructors = <ConstructorElement>[subConstructor];
+ SuperConstructorInvocation invocation = AstFactory
+ .superConstructorInvocation([
+ AstFactory.namedExpression2(parameterName, AstFactory.integer(0))
+ ]);
+ _resolveInClass(invocation, subclass);
+ expect(invocation.staticElement, superConstructor);
+ expect(
+ (invocation.argumentList.arguments[0] as NamedExpression)
+ .name
+ .label
+ .staticElement,
+ same(parameter));
+ _listener.assertNoErrors();
+ }
+
+ /**
+ * Create the resolver used by the tests.
+ *
+ * @return the resolver that was created
+ */
+ ElementResolver _createResolver() {
+ InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
+ FileBasedSource source =
+ new FileBasedSource(FileUtilities2.createFile("/test.dart"));
+ CompilationUnitElementImpl definingCompilationUnit =
+ new CompilationUnitElementImpl("test.dart");
+ definingCompilationUnit.librarySource =
+ definingCompilationUnit.source = source;
+ _definingLibrary = ElementFactory.library(context, "test");
+ _definingLibrary.definingCompilationUnit = definingCompilationUnit;
+ _visitor = new ResolverVisitor(
+ _definingLibrary, source, _typeProvider, _listener,
+ nameScope: new LibraryScope(_definingLibrary, _listener));
+ try {
+ return _visitor.elementResolver;
+ } catch (exception) {
+ throw new IllegalArgumentException(
+ "Could not create resolver", exception);
+ }
+ }
+
+ /**
+ * Return the element associated with the label of [statement] after the
+ * resolver has resolved it. [labelElement] is the label element to be
+ * defined in the statement's label scope, and [labelTarget] is the statement
+ * the label resolves to.
+ */
+ Element _resolveBreak(BreakStatement statement, LabelElementImpl labelElement,
+ Statement labelTarget) {
+ _resolveStatement(statement, labelElement, labelTarget);
+ return statement.label.staticElement;
+ }
+
+ /**
+ * Return the element associated with the label [statement] after the
+ * resolver has resolved it. [labelElement] is the label element to be
+ * defined in the statement's label scope, and [labelTarget] is the AST node
+ * the label resolves to.
+ *
+ * @param statement the statement to be resolved
+ * @param labelElement the label element to be defined in the statement's label scope
+ * @return the element to which the statement's label was resolved
+ */
+ Element _resolveContinue(ContinueStatement statement,
+ LabelElementImpl labelElement, AstNode labelTarget) {
+ _resolveStatement(statement, labelElement, labelTarget);
+ return statement.label.staticElement;
+ }
+
+ /**
+ * Return the element associated with the given identifier after the resolver has resolved the
+ * identifier.
+ *
+ * @param node the expression to be resolved
+ * @param definedElements the elements that are to be defined in the scope in which the element is
+ * being resolved
+ * @return the element to which the expression was resolved
+ */
+ Element _resolveIdentifier(Identifier node, [List<Element> definedElements]) {
+ _resolveNode(node, definedElements);
+ return node.staticElement;
+ }
+
+ /**
+ * Return the element associated with the given identifier after the resolver has resolved the
+ * identifier.
+ *
+ * @param node the expression to be resolved
+ * @param enclosingClass the element representing the class enclosing the identifier
+ * @return the element to which the expression was resolved
+ */
+ void _resolveInClass(AstNode node, ClassElement enclosingClass) {
+ try {
+ Scope outerScope = _visitor.nameScope;
+ try {
+ _visitor.enclosingClass = enclosingClass;
+ EnclosedScope innerScope = new ClassScope(
+ new TypeParameterScope(outerScope, enclosingClass), enclosingClass);
+ _visitor.nameScope = innerScope;
+ node.accept(_resolver);
+ } finally {
+ _visitor.enclosingClass = null;
+ _visitor.nameScope = outerScope;
+ }
+ } catch (exception) {
+ throw new IllegalArgumentException("Could not resolve node", exception);
+ }
+ }
+
+ /**
+ * Return the element associated with the given expression after the resolver has resolved the
+ * expression.
+ *
+ * @param node the expression to be resolved
+ * @param definedElements the elements that are to be defined in the scope in which the element is
+ * being resolved
+ * @return the element to which the expression was resolved
+ */
+ Element _resolveIndexExpression(IndexExpression node,
+ [List<Element> definedElements]) {
+ _resolveNode(node, definedElements);
+ return node.staticElement;
+ }
+
+ /**
+ * Return the element associated with the given identifier after the resolver has resolved the
+ * identifier.
+ *
+ * @param node the expression to be resolved
+ * @param definedElements the elements that are to be defined in the scope in which the element is
+ * being resolved
+ * @return the element to which the expression was resolved
+ */
+ void _resolveNode(AstNode node, [List<Element> definedElements]) {
+ try {
+ Scope outerScope = _visitor.nameScope;
+ try {
+ EnclosedScope innerScope = new EnclosedScope(outerScope);
+ if (definedElements != null) {
+ for (Element element in definedElements) {
+ innerScope.define(element);
+ }
+ }
+ _visitor.nameScope = innerScope;
+ node.accept(_resolver);
+ } finally {
+ _visitor.nameScope = outerScope;
+ }
+ } catch (exception) {
+ throw new IllegalArgumentException("Could not resolve node", exception);
+ }
+ }
+
+ /**
+ * Return the element associated with the label of the given statement after the resolver has
+ * resolved the statement.
+ *
+ * @param statement the statement to be resolved
+ * @param labelElement the label element to be defined in the statement's label scope
+ * @return the element to which the statement's label was resolved
+ */
+ void _resolveStatement(
+ Statement statement, LabelElementImpl labelElement, AstNode labelTarget) {
+ try {
+ LabelScope outerScope = _visitor.labelScope;
+ try {
+ LabelScope innerScope;
+ if (labelElement == null) {
+ innerScope = outerScope;
+ } else {
+ innerScope = new LabelScope(
+ outerScope, labelElement.name, labelTarget, labelElement);
+ }
+ _visitor.labelScope = innerScope;
+ statement.accept(_resolver);
+ } finally {
+ _visitor.labelScope = outerScope;
+ }
+ } catch (exception) {
+ throw new IllegalArgumentException("Could not resolve node", exception);
+ }
+ }
+}
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index da6c49d..c77bb3d 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -8,7 +8,7 @@
import '../reflective_tests.dart';
import '../utils.dart';
-import 'resolver_test.dart';
+import 'resolver_test_case.dart';
main() {
initializeTestEnvironment();
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
new file mode 100644
index 0000000..118b80b
--- /dev/null
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -0,0 +1,2997 @@
+// 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 analyzer.test.generated.hint_code_test;
+
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'analysis_context_factory.dart';
+import 'resolver_test_case.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(HintCodeTest);
+}
+
+@reflectiveTest
+class HintCodeTest extends ResolverTestCase {
+ void fail_deadCode_statementAfterRehrow() {
+ Source source = addSource(r'''
+f() {
+ try {
+ var one = 1;
+ } catch (e) {
+ rethrow;
+ var two = 2;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void fail_deadCode_statementAfterThrow() {
+ Source source = addSource(r'''
+f() {
+ var one = 1;
+ throw 'Stop here';
+ var two = 2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void fail_isInt() {
+ Source source = addSource("var v = 1 is int;");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.IS_INT]);
+ verify([source]);
+ }
+
+ void fail_isNotInt() {
+ Source source = addSource("var v = 1 is! int;");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.IS_NOT_INT]);
+ verify([source]);
+ }
+
+ void fail_overrideEqualsButNotHashCode() {
+ Source source = addSource(r'''
+class A {
+ bool operator ==(x) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
+ verify([source]);
+ }
+
+ void fail_unusedImport_as_equalPrefixes() {
+ // See todo at ImportsVerifier.prefixElementMap.
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart' as one;
+import 'lib2.dart' as one;
+one.A a;''');
+ Source source2 = addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}''');
+ Source source3 = addNamedSource(
+ "/lib2.dart",
+ r'''
+library lib2;
+class B {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_IMPORT]);
+ assertNoErrors(source2);
+ assertNoErrors(source3);
+ verify([source, source2, source3]);
+ }
+
+ @override
+ void reset() {
+ analysisContext2 = AnalysisContextFactory.contextWithCoreAndPackages({
+ 'package:meta/meta.dart': r'''
+library meta;
+
+const _Factory factory = const _Factory();
+const _Literal literal = const _Literal();
+const _MustCallSuper mustCallSuper = const _MustCallSuper();
+const _Override override = const _Override();
+const _Protected protected = const _Protected();
+const _Required required = const _Required();
+
+class _Factory {
+ const _Factory();
+}
+class _Literal {
+ const _Literal();
+}
+class _MustCallSuper {
+ const _MustCallSuper();
+}
+class _Override {
+ const _Override();
+}
+class _Protected {
+ const _Protected();
+}
+class _Required {
+ final String reason;
+ const _Required([this.reason]));
+}
+'''
+ });
+ }
+
+ void test_argumentTypeNotAssignable_functionType() {
+ Source source = addSource(r'''
+m() {
+ var a = new A();
+ a.n(() => 0);
+}
+class A {
+ n(void f(int i)) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ verify([source]);
+ }
+
+ void test_argumentTypeNotAssignable_message() {
+ // The implementation of HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE assumes that
+ // StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE has the same message.
+ expect(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message,
+ HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message);
+ }
+
+ void test_argumentTypeNotAssignable_type() {
+ Source source = addSource(r'''
+m() {
+ var i = '';
+ n(i);
+}
+n(int i) {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ verify([source]);
+ }
+
+ void test_canBeNullAfterNullAware_false_methodInvocation() {
+ Source source = addSource(r'''
+m(x) {
+ x?.a()?.b();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_canBeNullAfterNullAware_false_propertyAccess() {
+ Source source = addSource(r'''
+m(x) {
+ x?.a?.b;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_canBeNullAfterNullAware_methodInvocation() {
+ Source source = addSource(r'''
+m(x) {
+ x?.a.b();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+ verify([source]);
+ }
+
+ void test_canBeNullAfterNullAware_parenthesized() {
+ Source source = addSource(r'''
+m(x) {
+ (x?.a).b;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+ verify([source]);
+ }
+
+ void test_canBeNullAfterNullAware_propertyAccess() {
+ Source source = addSource(r'''
+m(x) {
+ x?.a.b;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_conditionalElse() {
+ Source source = addSource(r'''
+f() {
+ true ? 1 : 2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_conditionalElse_nested() {
+ // test that a dead else-statement can't generate additional violations
+ Source source = addSource(r'''
+f() {
+ true ? true : false && false;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_conditionalIf() {
+ Source source = addSource(r'''
+f() {
+ false ? 1 : 2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_conditionalIf_nested() {
+ // test that a dead then-statement can't generate additional violations
+ Source source = addSource(r'''
+f() {
+ false ? false && false : true;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_else() {
+ Source source = addSource(r'''
+f() {
+ if(true) {} else {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_else_nested() {
+ // test that a dead else-statement can't generate additional violations
+ Source source = addSource(r'''
+f() {
+ if(true) {} else {if (false) {}}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_if() {
+ Source source = addSource(r'''
+f() {
+ if(false) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_if_nested() {
+ // test that a dead then-statement can't generate additional violations
+ Source source = addSource(r'''
+f() {
+ if(false) {if(false) {}}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_while() {
+ Source source = addSource(r'''
+f() {
+ while(false) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_while_nested() {
+ // test that a dead while body can't generate additional violations
+ Source source = addSource(r'''
+f() {
+ while(false) {if(false) {}}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadCatch_catchFollowingCatch() {
+ Source source = addSource(r'''
+class A {}
+f() {
+ try {} catch (e) {} catch (e) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadCatch_catchFollowingCatch_nested() {
+ // test that a dead catch clause can't generate additional violations
+ Source source = addSource(r'''
+class A {}
+f() {
+ try {} catch (e) {} catch (e) {if(false) {}}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadCatch_catchFollowingCatch_object() {
+ Source source = addSource(r'''
+f() {
+ try {} on Object catch (e) {} catch (e) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadCatch_catchFollowingCatch_object_nested() {
+ // test that a dead catch clause can't generate additional violations
+ Source source = addSource(r'''
+f() {
+ try {} on Object catch (e) {} catch (e) {if(false) {}}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadCatch_onCatchSubtype() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {}
+f() {
+ try {} on A catch (e) {} on B catch (e) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadCatch_onCatchSubtype_nested() {
+ // test that a dead catch clause can't generate additional violations
+ Source source = addSource(r'''
+class A {}
+class B extends A {}
+f() {
+ try {} on A catch (e) {} on B catch (e) {if(false) {}}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadOperandLHS_and() {
+ Source source = addSource(r'''
+f() {
+ bool b = false && false;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadOperandLHS_and_nested() {
+ Source source = addSource(r'''
+f() {
+ bool b = false && (false && false);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadOperandLHS_or() {
+ Source source = addSource(r'''
+f() {
+ bool b = true || true;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_deadOperandLHS_or_nested() {
+ Source source = addSource(r'''
+f() {
+ bool b = true || (false && false);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterBreak_inDefaultCase() {
+ Source source = addSource(r'''
+f(v) {
+ switch(v) {
+ case 1:
+ default:
+ break;
+ var a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterBreak_inForEachStatement() {
+ Source source = addSource(r'''
+f() {
+ var list;
+ for(var l in list) {
+ break;
+ var a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterBreak_inForStatement() {
+ Source source = addSource(r'''
+f() {
+ for(;;) {
+ break;
+ var a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterBreak_inSwitchCase() {
+ Source source = addSource(r'''
+f(v) {
+ switch(v) {
+ case 1:
+ break;
+ var a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterBreak_inWhileStatement() {
+ Source source = addSource(r'''
+f(v) {
+ while(v) {
+ break;
+ var a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterContinue_inForEachStatement() {
+ Source source = addSource(r'''
+f() {
+ var list;
+ for(var l in list) {
+ continue;
+ var a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterContinue_inForStatement() {
+ Source source = addSource(r'''
+f() {
+ for(;;) {
+ continue;
+ var a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterContinue_inWhileStatement() {
+ Source source = addSource(r'''
+f(v) {
+ while(v) {
+ continue;
+ var a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterReturn_function() {
+ Source source = addSource(r'''
+f() {
+ var one = 1;
+ return;
+ var two = 2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterReturn_ifStatement() {
+ Source source = addSource(r'''
+f(bool b) {
+ if(b) {
+ var one = 1;
+ return;
+ var two = 2;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterReturn_method() {
+ Source source = addSource(r'''
+class A {
+ m() {
+ var one = 1;
+ return;
+ var two = 2;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterReturn_nested() {
+ Source source = addSource(r'''
+f() {
+ var one = 1;
+ return;
+ if(false) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterReturn_twoReturns() {
+ Source source = addSource(r'''
+f() {
+ var one = 1;
+ return;
+ var two = 2;
+ return;
+ var three = 3;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_assignment() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ A operator+(A a) { return a; }
+}
+f(A a) {
+ A b;
+ a += b;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_deprecated() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ m() {}
+ n() {m();}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_Deprecated() {
+ Source source = addSource(r'''
+class A {
+ @Deprecated('0.9')
+ m() {}
+ n() {m();}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_export() {
+ Source source = addSource("export 'deprecated_library.dart';");
+ addNamedSource(
+ "/deprecated_library.dart",
+ r'''
+@deprecated
+library deprecated_library;
+class A {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_field() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ int x = 1;
+}
+f(A a) {
+ return a.x;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_getter() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ get m => 1;
+}
+f(A a) {
+ return a.m;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_import() {
+ Source source = addSource(r'''
+import 'deprecated_library.dart';
+f(A a) {}''');
+ addNamedSource(
+ "/deprecated_library.dart",
+ r'''
+@deprecated
+library deprecated_library;
+class A {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_indexExpression() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ operator[](int i) {}
+}
+f(A a) {
+ return a[1];
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_instanceCreation() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ A(int i) {}
+}
+f() {
+ A a = new A(1);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_instanceCreation_namedConstructor() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ A.named(int i) {}
+}
+f() {
+ A a = new A.named(1);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_operator() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ operator+(A a) {}
+}
+f(A a) {
+ A b;
+ return a + b;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_setter() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ set s(v) {}
+}
+f(A a) {
+ return a.s = 1;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_superConstructor() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ A() {}
+}
+class B extends A {
+ B() : super() {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_superConstructor_namedConstructor() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ A.named() {}
+}
+class B extends A {
+ B() : super.named() {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_divisionOptimization_double() {
+ Source source = addSource(r'''
+f(double x, double y) {
+ var v = (x / y).toInt();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
+ verify([source]);
+ }
+
+ void test_divisionOptimization_int() {
+ Source source = addSource(r'''
+f(int x, int y) {
+ var v = (x / y).toInt();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
+ verify([source]);
+ }
+
+ void test_divisionOptimization_propagatedType() {
+ // Tests the propagated type information of the '/' method
+ Source source = addSource(r'''
+f(x, y) {
+ x = 1;
+ y = 1;
+ var v = (x / y).toInt();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
+ verify([source]);
+ }
+
+ void test_divisionOptimization_wrappedBinaryExpression() {
+ Source source = addSource(r'''
+f(int x, int y) {
+ var v = (((x / y))).toInt();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
+ verify([source]);
+ }
+
+ void test_duplicateImport() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart';
+A a;''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
+ verify([source]);
+ }
+
+ void test_duplicateImport2() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart';
+import 'lib1.dart';
+A a;''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(
+ source, [HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]);
+ verify([source]);
+ }
+
+ void test_duplicateImport3() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart' as M show A hide B;
+import 'lib1.dart' as M show A hide B;
+M.A a;''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}
+class B {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
+ verify([source]);
+ }
+
+ void test_importDeferredLibraryWithLoadFunction() {
+ resolveWithErrors(<String>[
+ r'''
+library lib1;
+loadLibrary() {}
+f() {}''',
+ r'''
+library root;
+import 'lib1.dart' deferred as lib1;
+main() { lib1.f(); }'''
+ ], <ErrorCode>[
+ HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION
+ ]);
+ }
+
+ void test_invalidAssignment_instanceVariable() {
+ Source source = addSource(r'''
+class A {
+ int x;
+}
+f(var y) {
+ A a;
+ if(y is String) {
+ a.x = y;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+ verify([source]);
+ }
+
+ void test_invalidAssignment_localVariable() {
+ Source source = addSource(r'''
+f(var y) {
+ if(y is String) {
+ int x = y;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+ verify([source]);
+ }
+
+ void test_invalidAssignment_message() {
+ // The implementation of HintCode.INVALID_ASSIGNMENT assumes that
+ // StaticTypeWarningCode.INVALID_ASSIGNMENT has the same message.
+ expect(StaticTypeWarningCode.INVALID_ASSIGNMENT.message,
+ HintCode.INVALID_ASSIGNMENT.message);
+ }
+
+ void test_invalidAssignment_staticVariable() {
+ Source source = addSource(r'''
+class A {
+ static int x;
+}
+f(var y) {
+ if(y is String) {
+ A.x = y;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+ verify([source]);
+ }
+
+ void test_invalidAssignment_variableDeclaration() {
+ // 17971
+ Source source = addSource(r'''
+class Point {
+ final num x, y;
+ Point(this.x, this.y);
+ Point operator +(Point other) {
+ return new Point(x+other.x, y+other.y);
+ }
+}
+main() {
+ var p1 = new Point(0, 0);
+ var p2 = new Point(10, 10);
+ int n = p1 + p2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_field() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ int a;
+}
+abstract class B implements A {
+ int b() => a;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_function() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void a(){ }
+}
+main() {
+ new A().a();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_getter() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ int get a => 42;
+}
+abstract class B implements A {
+ int b() => a;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_message() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void a(){ }
+}
+class B {
+ void b() => new A().a();
+}''');
+ List<AnalysisError> errors = analysisContext2.computeErrors(source);
+ expect(errors, hasLength(1));
+ expect(errors[0].message,
+ "The member 'a' can only be used within instance members of subclasses of 'A'");
+ }
+
+ void test_invalidUseOfProtectedMember_method_1() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void a(){ }
+}
+class B {
+ void b() => new A().a();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_method_2() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void a(){ }
+}
+abstract class B implements A {
+ void b() => a();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_OK_1() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void a(){ }
+}
+class B extends A {
+ void b() => a();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, []);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_OK_2() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void a(){ }
+}
+class B extends Object with A {
+ void b() => a();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, []);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_OK_3() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected m1() {}
+}
+class B extends A {
+ static m2(A a) => a.m1();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, []);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_OK_4() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void a(){ }
+}
+class B extends A {
+ void a() => a();
+}
+main() {
+ new B().a();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, []);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_OK_field() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ int a = 42;
+}
+class B extends A {
+ int b() => a;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, []);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_OK_getter() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ int get a => 42;
+}
+class B extends A {
+ int b() => a;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, []);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_OK_setter() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void set a(int i) { }
+}
+class B extends A {
+ void b(int i) {
+ a = i;
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, []);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_setter() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void set a(int i) { }
+}
+abstract class B implements A {
+ b(int i) {
+ a = i;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_topLevelVariable() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+@protected
+int x = 0;
+main() {
+ print(x);
+}''');
+ computeLibrarySourceErrors(source);
+ // TODO(brianwilkerson) This should produce a hint because the annotation is
+ // being applied to the wrong kind of declaration.
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_isDouble() {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.dart2jsHint = true;
+ resetWithOptions(options);
+ Source source = addSource("var v = 1 is double;");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.IS_DOUBLE]);
+ verify([source]);
+ }
+
+ void test_isNotDouble() {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.dart2jsHint = true;
+ resetWithOptions(options);
+ Source source = addSource("var v = 1 is! double;");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.IS_NOT_DOUBLE]);
+ verify([source]);
+ }
+
+ void test_missingReturn_async() {
+ Source source = addSource('''
+import 'dart:async';
+Future<int> f() async {}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MISSING_RETURN]);
+ verify([source]);
+ }
+
+ void test_missingReturn_function() {
+ Source source = addSource("int f() {}");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MISSING_RETURN]);
+ verify([source]);
+ }
+
+ void test_missingReturn_method() {
+ Source source = addSource(r'''
+class A {
+ int m() {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MISSING_RETURN]);
+ verify([source]);
+ }
+
+ void test_mustCallSuper() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @mustCallSuper
+ void a() {}
+}
+class B extends A {
+ @override
+ void a()
+ {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MUST_CALL_SUPER]);
+ verify([source]);
+ }
+
+ void test_mustCallSuper_indirect() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @mustCallSuper
+ void a() {}
+}
+class C extends A {
+ @override
+ void a() {
+ super.a();
+ }
+}
+class D extends C {
+ @override
+ void a() {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MUST_CALL_SUPER]);
+ verify([source]);
+ }
+
+ void test_mustCallSuper_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @mustCallSuper
+ void a() {}
+}
+class C extends A {
+ @override
+ void a() {
+ super.a(); //OK
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, []);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_assert() {
+ Source source = addSource(r'''
+m(x) {
+ assert (x?.a);
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_conditionalExpression() {
+ Source source = addSource(r'''
+m(x) {
+ return x?.a ? 0 : 1;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_do() {
+ Source source = addSource(r'''
+m(x) {
+ do {} while (x?.a);
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_for() {
+ Source source = addSource(r'''
+m(x) {
+ for (var v = x; v?.a; v = v.next) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_if() {
+ Source source = addSource(r'''
+m(x) {
+ if (x?.a) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_if_conditionalAnd_first() {
+ Source source = addSource(r'''
+m(x) {
+ if (x?.a && x.b) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_if_conditionalAnd_second() {
+ Source source = addSource(r'''
+m(x) {
+ if (x.a && x?.b) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_if_conditionalAnd_third() {
+ Source source = addSource(r'''
+m(x) {
+ if (x.a && x.b && x?.c) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_if_conditionalOr_first() {
+ Source source = addSource(r'''
+m(x) {
+ if (x?.a || x.b) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_if_conditionalOr_second() {
+ Source source = addSource(r'''
+m(x) {
+ if (x.a || x?.b) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_if_conditionalOr_third() {
+ Source source = addSource(r'''
+m(x) {
+ if (x.a || x.b || x?.c) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_if_not() {
+ Source source = addSource(r'''
+m(x) {
+ if (!x?.a) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_if_parenthesized() {
+ Source source = addSource(r'''
+m(x) {
+ if ((x?.a)) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_while() {
+ Source source = addSource(r'''
+m(x) {
+ while (x?.a) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
+ verify([source]);
+ }
+
+ void test_overrideOnNonOverridingGetter_invalid() {
+ Source source = addSource(r'''
+library dart.core;
+const override = null;
+class A {
+}
+class B extends A {
+ @override
+ int get m => 1;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]);
+ verify([source]);
+ }
+
+ void test_overrideOnNonOverridingMethod_invalid() {
+ Source source = addSource(r'''
+library dart.core;
+const override = null;
+class A {
+}
+class B extends A {
+ @override
+ int m() => 1;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]);
+ verify([source]);
+ }
+
+ void test_overrideOnNonOverridingSetter_invalid() {
+ Source source = addSource(r'''
+library dart.core;
+const override = null;
+class A {
+}
+class B extends A {
+ @override
+ set m(int x) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]);
+ verify([source]);
+ }
+
+ void test_typeCheck_type_is_Null() {
+ Source source = addSource(r'''
+m(i) {
+ bool b = i is Null;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.TYPE_CHECK_IS_NULL]);
+ verify([source]);
+ }
+
+ void test_typeCheck_type_not_Null() {
+ Source source = addSource(r'''
+m(i) {
+ bool b = i is! Null;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]);
+ verify([source]);
+ }
+
+ void test_undefinedGetter() {
+ Source source = addSource(r'''
+class A {}
+f(var a) {
+ if(a is A) {
+ return a.m;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNDEFINED_GETTER]);
+ }
+
+ void test_undefinedGetter_message() {
+ // The implementation of HintCode.UNDEFINED_SETTER assumes that
+ // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
+ // same, this verifies that assumption.
+ expect(StaticWarningCode.UNDEFINED_GETTER.message,
+ StaticTypeWarningCode.UNDEFINED_GETTER.message);
+ }
+
+ void test_undefinedMethod() {
+ Source source = addSource(r'''
+f() {
+ var a = 'str';
+ a.notAMethodOnString();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNDEFINED_METHOD]);
+ }
+
+ void test_undefinedMethod_assignmentExpression() {
+ Source source = addSource(r'''
+class A {}
+class B {
+ f(var a, var a2) {
+ a = new A();
+ a2 = new A();
+ a += a2;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNDEFINED_METHOD]);
+ }
+
+ void test_undefinedOperator_binaryExpression() {
+ Source source = addSource(r'''
+class A {}
+f(var a) {
+ if(a is A) {
+ a + 1;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+
+ void test_undefinedOperator_indexBoth() {
+ Source source = addSource(r'''
+class A {}
+f(var a) {
+ if(a is A) {
+ a[0]++;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+
+ void test_undefinedOperator_indexGetter() {
+ Source source = addSource(r'''
+class A {}
+f(var a) {
+ if(a is A) {
+ a[0];
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+
+ void test_undefinedOperator_indexSetter() {
+ Source source = addSource(r'''
+class A {}
+f(var a) {
+ if(a is A) {
+ a[0] = 1;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+
+ void test_undefinedOperator_postfixExpression() {
+ Source source = addSource(r'''
+class A {}
+f(var a) {
+ if(a is A) {
+ a++;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+
+ void test_undefinedOperator_prefixExpression() {
+ Source source = addSource(r'''
+class A {}
+f(var a) {
+ if(a is A) {
+ ++a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
+ }
+
+ void test_undefinedSetter() {
+ Source source = addSource(r'''
+class A {}
+f(var a) {
+ if(a is A) {
+ a.m = 0;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNDEFINED_SETTER]);
+ }
+
+ void test_undefinedSetter_message() {
+ // The implementation of HintCode.UNDEFINED_SETTER assumes that
+ // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
+ // same, this verifies that assumption.
+ expect(StaticWarningCode.UNDEFINED_SETTER.message,
+ StaticTypeWarningCode.UNDEFINED_SETTER.message);
+ }
+
+ void test_unnecessaryCast_type_supertype() {
+ Source source = addSource(r'''
+m(int i) {
+ var b = i as Object;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_CAST]);
+ verify([source]);
+ }
+
+ void test_unnecessaryCast_type_type() {
+ Source source = addSource(r'''
+m(num i) {
+ var b = i as num;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_CAST]);
+ verify([source]);
+ }
+
+ void test_unnecessaryNoSuchMethod_blockBody() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) {
+ return super.noSuchMethod(y);
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
+ verify([source]);
+ }
+
+ void test_unnecessaryNoSuchMethod_expressionBody() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) => super.noSuchMethod(y);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
+ verify([source]);
+ }
+
+ void test_unnecessaryTypeCheck_null_is_Null() {
+ Source source = addSource("bool b = null is Null;");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
+ verify([source]);
+ }
+
+ void test_unnecessaryTypeCheck_null_not_Null() {
+ Source source = addSource("bool b = null is! Null;");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
+ verify([source]);
+ }
+
+ void test_unnecessaryTypeCheck_type_is_dynamic() {
+ Source source = addSource(r'''
+m(i) {
+ bool b = i is dynamic;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
+ verify([source]);
+ }
+
+ void test_unnecessaryTypeCheck_type_is_object() {
+ Source source = addSource(r'''
+m(i) {
+ bool b = i is Object;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
+ verify([source]);
+ }
+
+ void test_unnecessaryTypeCheck_type_not_dynamic() {
+ Source source = addSource(r'''
+m(i) {
+ bool b = i is! dynamic;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
+ verify([source]);
+ }
+
+ void test_unnecessaryTypeCheck_type_not_object() {
+ Source source = addSource(r'''
+m(i) {
+ bool b = i is! Object;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_isUsed_extends() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {}
+class B extends _A {}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_isUsed_fieldDeclaration() {
+ enableUnusedElement = true;
+ var src = r'''
+class Foo {
+ _Bar x;
+}
+
+class _Bar {
+}
+''';
+ Source source = addSource(src);
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_isUsed_implements() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {}
+class B implements _A {}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_isUsed_instanceCreation() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {}
+main() {
+ new _A();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_isUsed_staticFieldAccess() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {
+ static const F = 42;
+}
+main() {
+ _A.F;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_isUsed_staticMethodInvocation() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {
+ static m() {}
+}
+main() {
+ _A.m();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_isUsed_typeArgument() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {}
+main() {
+ var v = new List<_A>();
+ print(v);
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_notUsed_inClassMember() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {
+ static staticMethod() {
+ new _A();
+ }
+ instanceMethod() {
+ new _A();
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_notUsed_inConstructorName() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {
+ _A() {}
+ _A.named() {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_notUsed_isExpression() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {}
+main(p) {
+ if (p is _A) {
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_notUsed_noReference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {}
+main() {
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_class_notUsed_variableDeclaration() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class _A {}
+main() {
+ _A v;
+ print(v);
+}
+print(x) {}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_enum_isUsed_fieldReference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+enum _MyEnum {A, B, C}
+main() {
+ print(_MyEnum.B);
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_enum_notUsed_noReference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+enum _MyEnum {A, B, C}
+main() {
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionLocal_isUsed_closure() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+main() {
+ print(() {});
+}
+print(x) {}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionLocal_isUsed_invocation() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+main() {
+ f() {}
+ f();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionLocal_isUsed_reference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+main() {
+ f() {}
+ print(f);
+}
+print(x) {}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionLocal_notUsed_noReference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+main() {
+ f() {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionLocal_notUsed_referenceFromItself() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+main() {
+ _f(int p) {
+ _f(p - 1);
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionTop_isUsed_invocation() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+_f() {}
+main() {
+ _f();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionTop_isUsed_reference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+_f() {}
+main() {
+ print(_f);
+}
+print(x) {}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionTop_notUsed_noReference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+_f() {}
+main() {
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionTop_notUsed_referenceFromItself() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+_f(int p) {
+ _f(p - 1);
+}
+main() {
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionTypeAlias_isUsed_isExpression() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+typedef _F(a, b);
+main(f) {
+ if (f is _F) {
+ print('F');
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionTypeAlias_isUsed_reference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+typedef _F(a, b);
+main(_F f) {
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionTypeAlias_isUsed_typeArgument() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+typedef _F(a, b);
+main() {
+ var v = new List<_F>();
+ print(v);
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionTypeAlias_isUsed_variableDeclaration() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+typedef _F(a, b);
+class A {
+ _F f;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_functionTypeAlias_notUsed_noReference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+typedef _F(a, b);
+main() {
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_getter_isUsed_invocation_implicitThis() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ get _g => null;
+ useGetter() {
+ var v = _g;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_getter_isUsed_invocation_PrefixedIdentifier() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ get _g => null;
+}
+main(A a) {
+ var v = a._g;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_getter_isUsed_invocation_PropertyAccess() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ get _g => null;
+}
+main() {
+ var v = new A()._g;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_getter_notUsed_noReference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ get _g => null;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_getter_notUsed_referenceFromItself() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ get _g {
+ return _g;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_hasReference_implicitThis() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ _m() {}
+ useMethod() {
+ print(_m);
+ }
+}
+print(x) {}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_hasReference_implicitThis_subclass() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ _m() {}
+ useMethod() {
+ print(_m);
+ }
+}
+class B extends A {
+ _m() {}
+}
+print(x) {}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_hasReference_PrefixedIdentifier() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ _m() {}
+}
+main(A a) {
+ a._m;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_hasReference_PropertyAccess() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ _m() {}
+}
+main() {
+ new A()._m;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_invocation_implicitThis() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ _m() {}
+ useMethod() {
+ _m();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_invocation_implicitThis_subclass() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ _m() {}
+ useMethod() {
+ _m();
+ }
+}
+class B extends A {
+ _m() {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_invocation_MemberElement() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A<T> {
+ _m(T t) {}
+}
+main(A<int> a) {
+ a._m(0);
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_invocation_propagated() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ _m() {}
+}
+main() {
+ var a = new A();
+ a._m();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_invocation_static() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ _m() {}
+}
+main() {
+ A a = new A();
+ a._m();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_invocation_subclass() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ _m() {}
+}
+class B extends A {
+ _m() {}
+}
+main(A a) {
+ a._m();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_notPrivate() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ m() {}
+}
+main() {
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_isUsed_staticInvocation() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ static _m() {}
+}
+main() {
+ A._m();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_notUsed_noReference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ static _m() {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_method_notUsed_referenceFromItself() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ static _m(int p) {
+ _m(p - 1);
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_setter_isUsed_invocation_implicitThis() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ set _s(x) {}
+ useSetter() {
+ _s = 42;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_setter_isUsed_invocation_PrefixedIdentifier() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ set _s(x) {}
+}
+main(A a) {
+ a._s = 42;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_setter_isUsed_invocation_PropertyAccess() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ set _s(x) {}
+}
+main() {
+ new A()._s = 42;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedElement_setter_notUsed_noReference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ set _s(x) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedElement_setter_notUsed_referenceFromItself() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ set _s(int x) {
+ if (x > 5) {
+ _s = x - 1;
+ }
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_ELEMENT]);
+ verify([source]);
+ }
+
+ void test_unusedField_isUsed_argument() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f = 0;
+ main() {
+ print(++_f);
+ }
+}
+print(x) {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedField_isUsed_reference_implicitThis() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+ main() {
+ print(_f);
+ }
+}
+print(x) {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedField_isUsed_reference_implicitThis_expressionFunctionBody() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+ m() => _f;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedField_isUsed_reference_implicitThis_subclass() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+ main() {
+ print(_f);
+ }
+}
+class B extends A {
+ int _f;
+}
+print(x) {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedField_isUsed_reference_qualified_propagatedElement() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+}
+main() {
+ var a = new A();
+ print(a._f);
+}
+print(x) {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedField_isUsed_reference_qualified_staticElement() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+}
+main() {
+ A a = new A();
+ print(a._f);
+}
+print(x) {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedField_isUsed_reference_qualified_unresolved() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+}
+main(a) {
+ print(a._f);
+}
+print(x) {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedField_notUsed_compoundAssign() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+ main() {
+ _f += 2;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_FIELD]);
+ verify([source]);
+ }
+
+ void test_unusedField_notUsed_noReference() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_FIELD]);
+ verify([source]);
+ }
+
+ void test_unusedField_notUsed_postfixExpr() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f = 0;
+ main() {
+ _f++;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_FIELD]);
+ verify([source]);
+ }
+
+ void test_unusedField_notUsed_prefixExpr() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f = 0;
+ main() {
+ ++_f;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_FIELD]);
+ verify([source]);
+ }
+
+ void test_unusedField_notUsed_simpleAssignment() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+ m() {
+ _f = 1;
+ }
+}
+main(A a) {
+ a._f = 2;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_FIELD]);
+ verify([source]);
+ }
+
+ void test_unusedImport() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';''');
+ Source source2 = addNamedSource("/lib1.dart", "library lib1;");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_IMPORT]);
+ assertNoErrors(source2);
+ verify([source, source2]);
+ }
+
+ void test_unusedImport_as() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart' as one;
+one.A a;''');
+ Source source2 = addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_IMPORT]);
+ assertNoErrors(source2);
+ verify([source, source2]);
+ }
+
+ void test_unusedImport_hide() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart' hide A;
+A a;''');
+ Source source2 = addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_IMPORT]);
+ assertNoErrors(source2);
+ verify([source, source2]);
+ }
+
+ void test_unusedImport_show() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart' show A;
+import 'lib1.dart' show B;
+A a;''');
+ Source source2 = addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}
+class B {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_IMPORT]);
+ assertNoErrors(source2);
+ verify([source, source2]);
+ }
+
+ void test_unusedLocalVariable_inCatch_exception() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ try {
+ } on String catch (exception) {
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_CATCH_CLAUSE]);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_inCatch_exception_hasStack() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ try {
+ } catch (exception, stack) {
+ print(stack);
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_inCatch_exception_noOnClause() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ try {
+ } catch (exception) {
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_inCatch_stackTrace() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ try {
+ } catch (exception, stackTrace) {
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_CATCH_STACK]);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_inCatch_stackTrace_used() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ try {
+ } catch (exception, stackTrace) {
+ print('exception at $stackTrace');
+ }
+}
+print(x) {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_inFor_underscore_ignored() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ for (var _ in [1,2,3]) {
+ for (var __ in [4,5,6]) {
+ // do something
+ }
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_inFunction() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ var v = 1;
+ v = 2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_inMethod() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+class A {
+ foo() {
+ var v = 1;
+ v = 2;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_isInvoked() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+typedef Foo();
+main() {
+ Foo foo;
+ foo();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_isRead_notUsed_compoundAssign() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ var v = 1;
+ v += 2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_isRead_notUsed_postfixExpr() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ var v = 1;
+ v++;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_isRead_notUsed_prefixExpr() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ var v = 1;
+ ++v;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_isRead_usedArgument() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+main() {
+ var v = 1;
+ print(++v);
+}
+print(x) {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedLocalVariable_isRead_usedInvocationTarget() {
+ enableUnusedLocalVariable = true;
+ Source source = addSource(r'''
+class A {
+ foo() {}
+}
+main() {
+ var a = new A();
+ a.foo();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source]);
+ }
+
+ void test_useOfVoidResult_assignmentExpression_function() {
+ Source source = addSource(r'''
+void f() {}
+class A {
+ n() {
+ var a;
+ a = f();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
+ verify([source]);
+ }
+
+ void test_useOfVoidResult_assignmentExpression_method() {
+ Source source = addSource(r'''
+class A {
+ void m() {}
+ n() {
+ var a;
+ a = m();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
+ verify([source]);
+ }
+
+ void test_useOfVoidResult_inForLoop() {
+ Source source = addSource(r'''
+class A {
+ void m() {}
+ n() {
+ for(var a = m();;) {}
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
+ verify([source]);
+ }
+
+ void test_useOfVoidResult_variableDeclaration_function() {
+ Source source = addSource(r'''
+void f() {}
+class A {
+ n() {
+ var a = f();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
+ verify([source]);
+ }
+
+ void test_useOfVoidResult_variableDeclaration_method() {
+ Source source = addSource(r'''
+class A {
+ void m() {}
+ n() {
+ var a = m();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
+ verify([source]);
+ }
+
+ void test_useOfVoidResult_variableDeclaration_method2() {
+ Source source = addSource(r'''
+class A {
+ void m() {}
+ n() {
+ var a = m(), b = m();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(
+ source, [HintCode.USE_OF_VOID_RESULT, HintCode.USE_OF_VOID_RESULT]);
+ verify([source]);
+ }
+}
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 80e4264..8800865 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -31,7 +31,8 @@
import 'package:unittest/unittest.dart';
import '../reflective_tests.dart';
-import 'resolver_test.dart';
+import 'analysis_context_factory.dart';
+import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
new file mode 100644
index 0000000..f8afcd0
--- /dev/null
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -0,0 +1,1269 @@
+// 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 analyzer.test.generated.inheritance_manager_test;
+
+import 'dart:collection';
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'analysis_context_factory.dart';
+import 'test_support.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(InheritanceManagerTest);
+}
+
+@reflectiveTest
+class InheritanceManagerTest {
+ /**
+ * The type provider used to access the types.
+ */
+ TestTypeProvider _typeProvider;
+
+ /**
+ * The library containing the code being resolved.
+ */
+ LibraryElementImpl _definingLibrary;
+
+ /**
+ * The inheritance manager being tested.
+ */
+ InheritanceManager _inheritanceManager;
+
+ /**
+ * The number of members that Object implements (as determined by [TestTypeProvider]).
+ */
+ int _numOfMembersInObject = 0;
+
+ void setUp() {
+ _typeProvider = new TestTypeProvider();
+ _inheritanceManager = _createInheritanceManager();
+ InterfaceType objectType = _typeProvider.objectType;
+ _numOfMembersInObject =
+ objectType.methods.length + objectType.accessors.length;
+ }
+
+ void test_getMapOfMembersInheritedFromClasses_accessor_extends() {
+ // class A { int get g; }
+ // class B extends A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject + 1);
+ expect(mapB.get(getterName), same(getterG));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromClasses_accessor_implements() {
+ // class A { int get g; }
+ // class B implements A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.interfaces = <InterfaceType>[classA.type];
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject);
+ expect(mapB.get(getterName), isNull);
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromClasses_accessor_with() {
+ // class A { int get g; }
+ // class B extends Object with A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.mixins = <InterfaceType>[classA.type];
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject + 1);
+ expect(mapB.get(getterName), same(getterG));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromClasses_implicitExtends() {
+ // class A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ _assertNoErrors(classA);
+ }
+
+ void test_getMapOfMembersInheritedFromClasses_method_extends() {
+ // class A { int g(); }
+ // class B extends A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.supertype = classA.type;
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject + 1);
+ expect(mapB.get(methodName), same(methodM));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromClasses_method_implements() {
+ // class A { int g(); }
+ // class B implements A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.interfaces = <InterfaceType>[classA.type];
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject);
+ expect(mapB.get(methodName), isNull);
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromClasses_method_with() {
+ // class A { int g(); }
+ // class B extends Object with A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.mixins = <InterfaceType>[classA.type];
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject + 1);
+ expect(mapB.get(methodName), same(methodM));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromClasses_method_with_two_mixins() {
+ // class A1 { int m(); }
+ // class A2 { int m(); }
+ // class B extends Object with A1, A2 {}
+ ClassElementImpl classA1 = ElementFactory.classElement2("A1");
+ String methodName = "m";
+ MethodElement methodA1M =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA1.methods = <MethodElement>[methodA1M];
+ ClassElementImpl classA2 = ElementFactory.classElement2("A2");
+ MethodElement methodA2M =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA2.methods = <MethodElement>[methodA2M];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.mixins = <InterfaceType>[classA1.type, classA2.type];
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
+ expect(mapB.get(methodName), same(methodA2M));
+ _assertNoErrors(classA1);
+ _assertNoErrors(classA2);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromInterfaces_accessor_extends() {
+ // class A { int get g; }
+ // class B extends A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject + 1);
+ expect(mapB.get(getterName), same(getterG));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromInterfaces_accessor_implements() {
+ // class A { int get g; }
+ // class B implements A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.interfaces = <InterfaceType>[classA.type];
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject + 1);
+ expect(mapB.get(getterName), same(getterG));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromInterfaces_accessor_with() {
+ // class A { int get g; }
+ // class B extends Object with A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.mixins = <InterfaceType>[classA.type];
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject + 1);
+ expect(mapB.get(getterName), same(getterG));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromInterfaces_implicitExtends() {
+ // class A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ _assertNoErrors(classA);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
+ // class I1 { int m(); }
+ // class I2 { int get m; }
+ // class A implements I2, I1 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classI1.methods = <MethodElement>[methodM];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ PropertyAccessorElement getter =
+ ElementFactory.getterElement(methodName, false, _typeProvider.intType);
+ classI2.accessors = <PropertyAccessorElement>[getter];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapA.get(methodName), isNull);
+ _assertErrors(classA,
+ [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
+ // class I1 { int m(); }
+ // class I2 { String m(); }
+ // class A implements I1, I2 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName = "m";
+ MethodElement methodM1 =
+ ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
+ classI1.methods = <MethodElement>[methodM1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ MethodElement methodM2 = ElementFactory
+ .methodElement(methodName, null, [_typeProvider.stringType]);
+ classI2.methods = <MethodElement>[methodM2];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapA.get(methodName), isNull);
+ _assertErrors(
+ classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
+ // class I1 { int m(); }
+ // class I2 { int get m; }
+ // class A implements I1, I2 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classI1.methods = <MethodElement>[methodM];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ PropertyAccessorElement getter =
+ ElementFactory.getterElement(methodName, false, _typeProvider.intType);
+ classI2.accessors = <PropertyAccessorElement>[getter];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapA.get(methodName), isNull);
+ _assertErrors(classA,
+ [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
+ // class I1 { dynamic m(int, [int]); }
+ // class I2 { dynamic m(int, int, int); }
+ // class A implements I1, I2 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName = "m";
+ MethodElementImpl methodM1 =
+ ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
+ ParameterElementImpl parameter1 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
+ parameter1.type = _typeProvider.intType;
+ parameter1.parameterKind = ParameterKind.REQUIRED;
+ ParameterElementImpl parameter2 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
+ parameter2.type = _typeProvider.intType;
+ parameter2.parameterKind = ParameterKind.POSITIONAL;
+ methodM1.parameters = <ParameterElement>[parameter1, parameter2];
+ classI1.methods = <MethodElement>[methodM1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ MethodElementImpl methodM2 =
+ ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
+ ParameterElementImpl parameter3 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
+ parameter3.type = _typeProvider.intType;
+ parameter3.parameterKind = ParameterKind.REQUIRED;
+ ParameterElementImpl parameter4 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a4"));
+ parameter4.type = _typeProvider.intType;
+ parameter4.parameterKind = ParameterKind.REQUIRED;
+ ParameterElementImpl parameter5 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a5"));
+ parameter5.type = _typeProvider.intType;
+ parameter5.parameterKind = ParameterKind.REQUIRED;
+ methodM2.parameters = <ParameterElement>[
+ parameter3,
+ parameter4,
+ parameter5
+ ];
+ classI2.methods = <MethodElement>[methodM2];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapA.get(methodName), isNull);
+ _assertErrors(
+ classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
+ // class I1 { int m(); }
+ // class I2 { String m(); }
+ // class A implements I2, I1 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName = "m";
+ MethodElement methodM1 = ElementFactory
+ .methodElement(methodName, null, [_typeProvider.stringType]);
+ classI1.methods = <MethodElement>[methodM1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ MethodElement methodM2 =
+ ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
+ classI2.methods = <MethodElement>[methodM2];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapA.get(methodName), isNull);
+ _assertErrors(
+ classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
+ }
+
+ void test_getMapOfMembersInheritedFromInterfaces_method_extends() {
+ // class A { int g(); }
+ // class B extends A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject + 1);
+ expect(mapB.get(methodName), same(methodM));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromInterfaces_method_implements() {
+ // class A { int g(); }
+ // class B implements A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.interfaces = <InterfaceType>[classA.type];
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject + 1);
+ expect(mapB.get(methodName), same(methodM));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromInterfaces_method_with() {
+ // class A { int g(); }
+ // class B extends Object with A {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.mixins = <InterfaceType>[classA.type];
+ MemberMap mapB =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject);
+ expect(mapB.size, _numOfMembersInObject + 1);
+ expect(mapB.get(methodName), same(methodM));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_getMapOfMembersInheritedFromInterfaces_union_differentNames() {
+ // class I1 { int m1(); }
+ // class I2 { int m2(); }
+ // class A implements I1, I2 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName1 = "m1";
+ MethodElement methodM1 =
+ ElementFactory.methodElement(methodName1, _typeProvider.intType);
+ classI1.methods = <MethodElement>[methodM1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ String methodName2 = "m2";
+ MethodElement methodM2 =
+ ElementFactory.methodElement(methodName2, _typeProvider.intType);
+ classI2.methods = <MethodElement>[methodM2];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject + 2);
+ expect(mapA.get(methodName1), same(methodM1));
+ expect(mapA.get(methodName2), same(methodM2));
+ _assertNoErrors(classA);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
+ // class I1 { int get g; }
+ // class I2 { num get g; }
+ // class A implements I1, I2 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String accessorName = "g";
+ PropertyAccessorElement getter1 = ElementFactory.getterElement(
+ accessorName, false, _typeProvider.intType);
+ classI1.accessors = <PropertyAccessorElement>[getter1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ PropertyAccessorElement getter2 = ElementFactory.getterElement(
+ accessorName, false, _typeProvider.numType);
+ classI2.accessors = <PropertyAccessorElement>[getter2];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject + 1);
+ PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(
+ accessorName, false, _typeProvider.dynamicType);
+ expect(mapA.get(accessorName).type, syntheticAccessor.type);
+ _assertNoErrors(classA);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
+ // class I1 { dynamic m(int); }
+ // class I2 { dynamic m(num); }
+ // class A implements I1, I2 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName = "m";
+ MethodElementImpl methodM1 =
+ ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
+ ParameterElementImpl parameter1 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
+ parameter1.type = _typeProvider.intType;
+ parameter1.parameterKind = ParameterKind.REQUIRED;
+ methodM1.parameters = <ParameterElement>[parameter1];
+ classI1.methods = <MethodElement>[methodM1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ MethodElementImpl methodM2 =
+ ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
+ ParameterElementImpl parameter2 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
+ parameter2.type = _typeProvider.numType;
+ parameter2.parameterKind = ParameterKind.REQUIRED;
+ methodM2.parameters = <ParameterElement>[parameter2];
+ classI2.methods = <MethodElement>[methodM2];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject + 1);
+ MethodElement syntheticMethod = ElementFactory.methodElement(
+ methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]);
+ expect(mapA.get(methodName).type, syntheticMethod.type);
+ _assertNoErrors(classA);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
+ // class I1 { set s(int); }
+ // class I2 { set s(num); }
+ // class A implements I1, I2 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String accessorName = "s";
+ PropertyAccessorElement setter1 = ElementFactory.setterElement(
+ accessorName, false, _typeProvider.intType);
+ classI1.accessors = <PropertyAccessorElement>[setter1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ PropertyAccessorElement setter2 = ElementFactory.setterElement(
+ accessorName, false, _typeProvider.numType);
+ classI2.accessors = <PropertyAccessorElement>[setter2];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject + 1);
+ PropertyAccessorElementImpl syntheticAccessor = ElementFactory
+ .setterElement(accessorName, false, _typeProvider.dynamicType);
+ syntheticAccessor.returnType = _typeProvider.dynamicType;
+ expect(mapA.get("$accessorName=").type, syntheticAccessor.type);
+ _assertNoErrors(classA);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
+ // class A {}
+ // class B extends A {}
+ // class C extends B {}
+ // class I1 { A get g; }
+ // class I2 { B get g; }
+ // class I3 { C get g; }
+ // class D implements I1, I2, I3 {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String accessorName = "g";
+ PropertyAccessorElement getter1 =
+ ElementFactory.getterElement(accessorName, false, classA.type);
+ classI1.accessors = <PropertyAccessorElement>[getter1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ PropertyAccessorElement getter2 =
+ ElementFactory.getterElement(accessorName, false, classB.type);
+ classI2.accessors = <PropertyAccessorElement>[getter2];
+ ClassElementImpl classI3 = ElementFactory.classElement2("I3");
+ PropertyAccessorElement getter3 =
+ ElementFactory.getterElement(accessorName, false, classC.type);
+ classI3.accessors = <PropertyAccessorElement>[getter3];
+ ClassElementImpl classD = ElementFactory.classElement2("D");
+ classD.interfaces = <InterfaceType>[
+ classI1.type,
+ classI2.type,
+ classI3.type
+ ];
+ MemberMap mapD =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
+ expect(mapD.size, _numOfMembersInObject + 1);
+ PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(
+ accessorName, false, _typeProvider.dynamicType);
+ expect(mapD.get(accessorName).type, syntheticAccessor.type);
+ _assertNoErrors(classD);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
+ // class A {}
+ // class B extends A {}
+ // class C extends B {}
+ // class I1 { dynamic m(A a); }
+ // class I2 { dynamic m(B b); }
+ // class I3 { dynamic m(C c); }
+ // class D implements I1, I2, I3 {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName = "m";
+ MethodElementImpl methodM1 =
+ ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
+ ParameterElementImpl parameter1 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
+ parameter1.type = classA.type;
+ parameter1.parameterKind = ParameterKind.REQUIRED;
+ methodM1.parameters = <ParameterElement>[parameter1];
+ classI1.methods = <MethodElement>[methodM1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ MethodElementImpl methodM2 =
+ ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
+ ParameterElementImpl parameter2 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
+ parameter2.type = classB.type;
+ parameter2.parameterKind = ParameterKind.REQUIRED;
+ methodM2.parameters = <ParameterElement>[parameter2];
+ classI2.methods = <MethodElement>[methodM2];
+ ClassElementImpl classI3 = ElementFactory.classElement2("I3");
+ MethodElementImpl methodM3 =
+ ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
+ ParameterElementImpl parameter3 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
+ parameter3.type = classC.type;
+ parameter3.parameterKind = ParameterKind.REQUIRED;
+ methodM3.parameters = <ParameterElement>[parameter3];
+ classI3.methods = <MethodElement>[methodM3];
+ ClassElementImpl classD = ElementFactory.classElement2("D");
+ classD.interfaces = <InterfaceType>[
+ classI1.type,
+ classI2.type,
+ classI3.type
+ ];
+ MemberMap mapD =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
+ expect(mapD.size, _numOfMembersInObject + 1);
+ MethodElement syntheticMethod = ElementFactory.methodElement(
+ methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]);
+ expect(mapD.get(methodName).type, syntheticMethod.type);
+ _assertNoErrors(classD);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
+ // class A {}
+ // class B extends A {}
+ // class C extends B {}
+ // class I1 { set s(A); }
+ // class I2 { set s(B); }
+ // class I3 { set s(C); }
+ // class D implements I1, I2, I3 {}
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String accessorName = "s";
+ PropertyAccessorElement setter1 =
+ ElementFactory.setterElement(accessorName, false, classA.type);
+ classI1.accessors = <PropertyAccessorElement>[setter1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ PropertyAccessorElement setter2 =
+ ElementFactory.setterElement(accessorName, false, classB.type);
+ classI2.accessors = <PropertyAccessorElement>[setter2];
+ ClassElementImpl classI3 = ElementFactory.classElement2("I3");
+ PropertyAccessorElement setter3 =
+ ElementFactory.setterElement(accessorName, false, classC.type);
+ classI3.accessors = <PropertyAccessorElement>[setter3];
+ ClassElementImpl classD = ElementFactory.classElement2("D");
+ classD.interfaces = <InterfaceType>[
+ classI1.type,
+ classI2.type,
+ classI3.type
+ ];
+ MemberMap mapD =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
+ expect(mapD.size, _numOfMembersInObject + 1);
+ PropertyAccessorElementImpl syntheticAccessor = ElementFactory
+ .setterElement(accessorName, false, _typeProvider.dynamicType);
+ syntheticAccessor.returnType = _typeProvider.dynamicType;
+ expect(mapD.get("$accessorName=").type, syntheticAccessor.type);
+ _assertNoErrors(classD);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
+ // class I1 { int m(); }
+ // class I2 { int m([int]); }
+ // class A implements I1, I2 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName = "m";
+ MethodElement methodM1 =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classI1.methods = <MethodElement>[methodM1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ MethodElementImpl methodM2 =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ ParameterElementImpl parameter1 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
+ parameter1.type = _typeProvider.intType;
+ parameter1.parameterKind = ParameterKind.POSITIONAL;
+ methodM2.parameters = <ParameterElement>[parameter1];
+ classI2.methods = <MethodElement>[methodM2];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject + 1);
+ expect(mapA.get(methodName), same(methodM2));
+ _assertNoErrors(classA);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
+ // class I1 { int m(); }
+ // class I2 { int m([int]); }
+ // class I3 { int m([int, int]); }
+ // class A implements I1, I2, I3 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName = "m";
+ MethodElementImpl methodM1 =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classI1.methods = <MethodElement>[methodM1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ MethodElementImpl methodM2 =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ ParameterElementImpl parameter1 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
+ parameter1.type = _typeProvider.intType;
+ parameter1.parameterKind = ParameterKind.POSITIONAL;
+ methodM1.parameters = <ParameterElement>[parameter1];
+ classI2.methods = <MethodElement>[methodM2];
+ ClassElementImpl classI3 = ElementFactory.classElement2("I3");
+ MethodElementImpl methodM3 =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ ParameterElementImpl parameter2 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
+ parameter2.type = _typeProvider.intType;
+ parameter2.parameterKind = ParameterKind.POSITIONAL;
+ ParameterElementImpl parameter3 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
+ parameter3.type = _typeProvider.intType;
+ parameter3.parameterKind = ParameterKind.POSITIONAL;
+ methodM3.parameters = <ParameterElement>[parameter2, parameter3];
+ classI3.methods = <MethodElement>[methodM3];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[
+ classI1.type,
+ classI2.type,
+ classI3.type
+ ];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject + 1);
+ expect(mapA.get(methodName), same(methodM3));
+ _assertNoErrors(classA);
+ }
+
+ void
+ test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
+ // class I1 { int m(); }
+ // class I2 { int m(); }
+ // class I3 { int m([int]); }
+ // class I4 { int m([int, int]); }
+ // class A implements I1, I2, I3, I4 {}
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName = "m";
+ MethodElement methodM1 =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classI1.methods = <MethodElement>[methodM1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ MethodElement methodM2 =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classI2.methods = <MethodElement>[methodM2];
+ ClassElementImpl classI3 = ElementFactory.classElement2("I3");
+ MethodElementImpl methodM3 =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ ParameterElementImpl parameter1 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
+ parameter1.type = _typeProvider.intType;
+ parameter1.parameterKind = ParameterKind.POSITIONAL;
+ methodM3.parameters = <ParameterElement>[parameter1];
+ classI3.methods = <MethodElement>[methodM3];
+ ClassElementImpl classI4 = ElementFactory.classElement2("I4");
+ MethodElementImpl methodM4 =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ ParameterElementImpl parameter2 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
+ parameter2.type = _typeProvider.intType;
+ parameter2.parameterKind = ParameterKind.POSITIONAL;
+ ParameterElementImpl parameter3 =
+ new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
+ parameter3.type = _typeProvider.intType;
+ parameter3.parameterKind = ParameterKind.POSITIONAL;
+ methodM4.parameters = <ParameterElement>[parameter2, parameter3];
+ classI4.methods = <MethodElement>[methodM4];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[
+ classI1.type,
+ classI2.type,
+ classI3.type,
+ classI4.type
+ ];
+ MemberMap mapA =
+ _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
+ expect(mapA.size, _numOfMembersInObject + 1);
+ expect(mapA.get(methodName), same(methodM4));
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupInheritance_interface_getter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.interfaces = <InterfaceType>[classA.type];
+ expect(_inheritanceManager.lookupInheritance(classB, getterName),
+ same(getterG));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_interface_method() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.interfaces = <InterfaceType>[classA.type];
+ expect(_inheritanceManager.lookupInheritance(classB, methodName),
+ same(methodM));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_interface_setter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String setterName = "s";
+ PropertyAccessorElement setterS =
+ ElementFactory.setterElement(setterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[setterS];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.interfaces = <InterfaceType>[classA.type];
+ expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
+ same(setterS));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_interface_staticMember() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ (methodM as MethodElementImpl).static = true;
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.interfaces = <InterfaceType>[classA.type];
+ expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_interfaces_infiniteLoop() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classA.type];
+ expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupInheritance_interfaces_infiniteLoop2() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classA.interfaces = <InterfaceType>[classB.type];
+ classB.interfaces = <InterfaceType>[classA.type];
+ expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_interfaces_union2() {
+ ClassElementImpl classI1 = ElementFactory.classElement2("I1");
+ String methodName1 = "m1";
+ MethodElement methodM1 =
+ ElementFactory.methodElement(methodName1, _typeProvider.intType);
+ classI1.methods = <MethodElement>[methodM1];
+ ClassElementImpl classI2 = ElementFactory.classElement2("I2");
+ String methodName2 = "m2";
+ MethodElement methodM2 =
+ ElementFactory.methodElement(methodName2, _typeProvider.intType);
+ classI2.methods = <MethodElement>[methodM2];
+ classI2.interfaces = <InterfaceType>[classI1.type];
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.interfaces = <InterfaceType>[classI2.type];
+ expect(_inheritanceManager.lookupInheritance(classA, methodName1),
+ same(methodM1));
+ expect(_inheritanceManager.lookupInheritance(classA, methodName2),
+ same(methodM2));
+ _assertNoErrors(classI1);
+ _assertNoErrors(classI2);
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupInheritance_mixin_getter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.mixins = <InterfaceType>[classA.type];
+ expect(_inheritanceManager.lookupInheritance(classB, getterName),
+ same(getterG));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_mixin_method() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.mixins = <InterfaceType>[classA.type];
+ expect(_inheritanceManager.lookupInheritance(classB, methodName),
+ same(methodM));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_mixin_setter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String setterName = "s";
+ PropertyAccessorElement setterS =
+ ElementFactory.setterElement(setterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[setterS];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.mixins = <InterfaceType>[classA.type];
+ expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
+ same(setterS));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_mixin_staticMember() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ (methodM as MethodElementImpl).static = true;
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.mixins = <InterfaceType>[classA.type];
+ expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_noMember() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ expect(_inheritanceManager.lookupInheritance(classA, "a"), isNull);
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupInheritance_superclass_getter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ expect(_inheritanceManager.lookupInheritance(classB, getterName),
+ same(getterG));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_superclass_infiniteLoop() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ classA.supertype = classA.type;
+ expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupInheritance_superclass_infiniteLoop2() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classA.supertype = classB.type;
+ classB.supertype = classA.type;
+ expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_superclass_method() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ expect(_inheritanceManager.lookupInheritance(classB, methodName),
+ same(methodM));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_superclass_setter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String setterName = "s";
+ PropertyAccessorElement setterS =
+ ElementFactory.setterElement(setterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[setterS];
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
+ same(setterS));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupInheritance_superclass_staticMember() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ (methodM as MethodElementImpl).static = true;
+ classA.methods = <MethodElement>[methodM];
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupMember_getter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ expect(_inheritanceManager.lookupMember(classA, getterName), same(getterG));
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupMember_getter_static() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String getterName = "g";
+ PropertyAccessorElement getterG =
+ ElementFactory.getterElement(getterName, true, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[getterG];
+ expect(_inheritanceManager.lookupMember(classA, getterName), isNull);
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupMember_method() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ expect(_inheritanceManager.lookupMember(classA, methodName), same(methodM));
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupMember_method_static() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElement methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ (methodM as MethodElementImpl).static = true;
+ classA.methods = <MethodElement>[methodM];
+ expect(_inheritanceManager.lookupMember(classA, methodName), isNull);
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupMember_noMember() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ expect(_inheritanceManager.lookupMember(classA, "a"), isNull);
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupMember_setter() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String setterName = "s";
+ PropertyAccessorElement setterS =
+ ElementFactory.setterElement(setterName, false, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[setterS];
+ expect(_inheritanceManager.lookupMember(classA, "$setterName="),
+ same(setterS));
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupMember_setter_static() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String setterName = "s";
+ PropertyAccessorElement setterS =
+ ElementFactory.setterElement(setterName, true, _typeProvider.intType);
+ classA.accessors = <PropertyAccessorElement>[setterS];
+ expect(_inheritanceManager.lookupMember(classA, setterName), isNull);
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupOverrides_noParentClasses() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElementImpl methodM =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodM];
+ expect(
+ _inheritanceManager.lookupOverrides(classA, methodName), hasLength(0));
+ _assertNoErrors(classA);
+ }
+
+ void test_lookupOverrides_overrideBaseClass() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElementImpl methodMinA =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodMinA];
+ ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
+ MethodElementImpl methodMinB =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classB.methods = <MethodElement>[methodMinB];
+ List<ExecutableElement> overrides =
+ _inheritanceManager.lookupOverrides(classB, methodName);
+ expect(overrides, unorderedEquals([methodMinA]));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupOverrides_overrideInterface() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElementImpl methodMinA =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodMinA];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ classB.interfaces = <InterfaceType>[classA.type];
+ MethodElementImpl methodMinB =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classB.methods = <MethodElement>[methodMinB];
+ List<ExecutableElement> overrides =
+ _inheritanceManager.lookupOverrides(classB, methodName);
+ expect(overrides, unorderedEquals([methodMinA]));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ }
+
+ void test_lookupOverrides_overrideTwoInterfaces() {
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ String methodName = "m";
+ MethodElementImpl methodMinA =
+ ElementFactory.methodElement(methodName, _typeProvider.intType);
+ classA.methods = <MethodElement>[methodMinA];
+ ClassElementImpl classB = ElementFactory.classElement2("B");
+ MethodElementImpl methodMinB =
+ ElementFactory.methodElement(methodName, _typeProvider.doubleType);
+ classB.methods = <MethodElement>[methodMinB];
+ ClassElementImpl classC = ElementFactory.classElement2("C");
+ classC.interfaces = <InterfaceType>[classA.type, classB.type];
+ MethodElementImpl methodMinC =
+ ElementFactory.methodElement(methodName, _typeProvider.numType);
+ classC.methods = <MethodElement>[methodMinC];
+ List<ExecutableElement> overrides =
+ _inheritanceManager.lookupOverrides(classC, methodName);
+ expect(overrides, unorderedEquals([methodMinA, methodMinB]));
+ _assertNoErrors(classA);
+ _assertNoErrors(classB);
+ _assertNoErrors(classC);
+ }
+
+ void _assertErrors(ClassElement classElt,
+ [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ HashSet<AnalysisError> actualErrors =
+ _inheritanceManager.getErrors(classElt);
+ if (actualErrors != null) {
+ for (AnalysisError error in actualErrors) {
+ errorListener.onError(error);
+ }
+ }
+ errorListener.assertErrorsWithCodes(expectedErrorCodes);
+ }
+
+ void _assertNoErrors(ClassElement classElt) {
+ _assertErrors(classElt);
+ }
+
+ /**
+ * Create the inheritance manager used by the tests.
+ *
+ * @return the inheritance manager that was created
+ */
+ InheritanceManager _createInheritanceManager() {
+ AnalysisContext context = AnalysisContextFactory.contextWithCore();
+ FileBasedSource source =
+ new FileBasedSource(FileUtilities2.createFile("/test.dart"));
+ CompilationUnitElementImpl definingCompilationUnit =
+ new CompilationUnitElementImpl("test.dart");
+ definingCompilationUnit.librarySource =
+ definingCompilationUnit.source = source;
+ _definingLibrary = ElementFactory.library(context, "test");
+ _definingLibrary.definingCompilationUnit = definingCompilationUnit;
+ return new InheritanceManager(_definingLibrary);
+ }
+}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index de21885..292d016 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -14,7 +14,7 @@
import '../reflective_tests.dart';
import '../utils.dart';
-import 'resolver_test.dart';
+import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
new file mode 100644
index 0000000..8d9c19d
--- /dev/null
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -0,0 +1,1211 @@
+// 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 analyzer.test.generated.non_hint_code_test;
+
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'resolver_test_case.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(NonHintCodeTest);
+}
+
+@reflectiveTest
+class NonHintCodeTest extends ResolverTestCase {
+ void test_deadCode_deadBlock_conditionalElse_debugConst() {
+ Source source = addSource(r'''
+const bool DEBUG = true;
+f() {
+ DEBUG ? 1 : 2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_conditionalIf_debugConst() {
+ Source source = addSource(r'''
+const bool DEBUG = false;
+f() {
+ DEBUG ? 1 : 2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_else() {
+ Source source = addSource(r'''
+const bool DEBUG = true;
+f() {
+ if(DEBUG) {} else {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier() {
+ Source source = addSource(r'''
+class A {
+ static const bool DEBUG = false;
+}
+f() {
+ if(A.DEBUG) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2() {
+ Source source = addSource(r'''
+library L;
+import 'lib2.dart';
+f() {
+ if(A.DEBUG) {}
+}''');
+ addNamedSource(
+ "/lib2.dart",
+ r'''
+library lib2;
+class A {
+ static const bool DEBUG = false;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_if_debugConst_propertyAccessor() {
+ Source source = addSource(r'''
+library L;
+import 'lib2.dart' as LIB;
+f() {
+ if(LIB.A.DEBUG) {}
+}''');
+ addNamedSource(
+ "/lib2.dart",
+ r'''
+library lib2;
+class A {
+ static const bool DEBUG = false;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_if_debugConst_simpleIdentifier() {
+ Source source = addSource(r'''
+const bool DEBUG = false;
+f() {
+ if(DEBUG) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deadCode_deadBlock_while_debugConst() {
+ Source source = addSource(r'''
+const bool DEBUG = false;
+f() {
+ while(DEBUG) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deadCode_deadCatch_onCatchSubtype() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {}
+f() {
+ try {} on B catch (e) {} on A catch (e) {} catch (e) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deadCode_deadOperandLHS_and_debugConst() {
+ Source source = addSource(r'''
+const bool DEBUG = false;
+f() {
+ bool b = DEBUG && false;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deadCode_deadOperandLHS_or_debugConst() {
+ Source source = addSource(r'''
+const bool DEBUG = true;
+f() {
+ bool b = DEBUG || true;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deprecatedMemberUse_inDeprecatedClass() {
+ Source source = addSource(r'''
+@deprecated
+f() {}
+
+@deprecated
+class C {
+ m() {
+ f();
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deprecatedMemberUse_inDeprecatedFunction() {
+ Source source = addSource(r'''
+@deprecated
+f() {}
+
+@deprecated
+g() {
+ f();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deprecatedMemberUse_inDeprecatedMethod() {
+ Source source = addSource(r'''
+@deprecated
+f() {}
+
+class C {
+ @deprecated
+ m() {
+ f();
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_deprecatedMemberUse_inDeprecatedMethod_inDeprecatedClass() {
+ Source source = addSource(r'''
+@deprecated
+f() {}
+
+@deprecated
+class C {
+ @deprecated
+ m() {
+ f();
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_divisionOptimization() {
+ Source source = addSource(r'''
+f(int x, int y) {
+ var v = x / y.toInt();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_divisionOptimization_supressIfDivisionNotDefinedInCore() {
+ Source source = addSource(r'''
+f(x, y) {
+ var v = (x / y).toInt();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_divisionOptimization_supressIfDivisionOverridden() {
+ Source source = addSource(r'''
+class A {
+ num operator /(x) { return x; }
+}
+f(A x, A y) {
+ var v = (x / y).toInt();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_duplicateImport_as() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart' as one;
+A a;
+one.A a2;''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_duplicateImport_hide() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart' hide A;
+A a;
+B b;''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}
+class B {}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_duplicateImport_show() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart' show A;
+A a;
+B b;''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}
+class B {}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_importDeferredLibraryWithLoadFunction() {
+ resolveWithErrors(<String>[
+ r'''
+library lib1;
+f() {}''',
+ r'''
+library root;
+import 'lib1.dart' deferred as lib1;
+main() { lib1.f(); }'''
+ ], ErrorCode.EMPTY_LIST);
+ }
+
+ void test_issue20904BuggyTypePromotionAtIfJoin_1() {
+ // https://code.google.com/p/dart/issues/detail?id=20904
+ Source source = addSource(r'''
+f(var message, var dynamic_) {
+ if (message is Function) {
+ message = dynamic_;
+ }
+ int s = message;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_issue20904BuggyTypePromotionAtIfJoin_3() {
+ // https://code.google.com/p/dart/issues/detail?id=20904
+ Source source = addSource(r'''
+f(var message) {
+ var dynamic_;
+ if (message is Function) {
+ message = dynamic_;
+ } else {
+ return;
+ }
+ int s = message;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_issue20904BuggyTypePromotionAtIfJoin_4() {
+ // https://code.google.com/p/dart/issues/detail?id=20904
+ Source source = addSource(r'''
+f(var message) {
+ if (message is Function) {
+ message = '';
+ } else {
+ return;
+ }
+ String s = message;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_missingReturn_emptyFunctionBody() {
+ Source source = addSource(r'''
+abstract class A {
+ int m();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_missingReturn_expressionFunctionBody() {
+ Source source = addSource("int f() => 0;");
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_missingReturn_noReturnType() {
+ Source source = addSource("f() {}");
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_missingReturn_voidReturnType() {
+ Source source = addSource("void f() {}");
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_for_noCondition() {
+ Source source = addSource(r'''
+m(x) {
+ for (var v = x; ; v++) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_nullAwareInCondition_if_notTopLevel() {
+ Source source = addSource(r'''
+m(x) {
+ if (x?.y == null) {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_overrideEqualsButNotHashCode() {
+ Source source = addSource(r'''
+class A {
+ bool operator ==(x) { return x; }
+ get hashCode => 0;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_overrideOnNonOverridingGetter_inInterface() {
+ Source source = addSource(r'''
+library dart.core;
+const override = null;
+class A {
+ int get m => 0;
+}
+class B implements A {
+ @override
+ int get m => 1;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_overrideOnNonOverridingGetter_inSuperclass() {
+ Source source = addSource(r'''
+library dart.core;
+const override = null;
+class A {
+ int get m => 0;
+}
+class B extends A {
+ @override
+ int get m => 1;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_overrideOnNonOverridingMethod_inInterface() {
+ Source source = addSource(r'''
+library dart.core;
+const override = null;
+class A {
+ int m() => 0;
+}
+class B implements A {
+ @override
+ int m() => 1;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_overrideOnNonOverridingMethod_inSuperclass() {
+ Source source = addSource(r'''
+library dart.core;
+const override = null;
+class A {
+ int m() => 0;
+}
+class B extends A {
+ @override
+ int m() => 1;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_overrideOnNonOverridingSetter_inInterface() {
+ Source source = addSource(r'''
+library dart.core;
+const override = null;
+class A {
+ set m(int x) {}
+}
+class B implements A {
+ @override
+ set m(int x) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_overrideOnNonOverridingSetter_inSuperclass() {
+ Source source = addSource(r'''
+library dart.core;
+const override = null;
+class A {
+ set m(int x) {}
+}
+class B extends A {
+ @override
+ set m(int x) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_propagatedFieldType() {
+ Source source = addSource(r'''
+class A { }
+class X<T> {
+ final x = new List<T>();
+}
+class Z {
+ final X<A> y = new X<A>();
+ foo() {
+ y.x.add(new A());
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_proxy_annotation_prefixed() {
+ Source source = addSource(r'''
+library L;
+@proxy
+class A {}
+f(var a) {
+ a = new A();
+ a.m();
+ var x = a.g;
+ a.s = 1;
+ var y = a + a;
+ a++;
+ ++a;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_proxy_annotation_prefixed2() {
+ Source source = addSource(r'''
+library L;
+@proxy
+class A {}
+class B {
+ f(var a) {
+ a = new A();
+ a.m();
+ var x = a.g;
+ a.s = 1;
+ var y = a + a;
+ a++;
+ ++a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_proxy_annotation_prefixed3() {
+ Source source = addSource(r'''
+library L;
+class B {
+ f(var a) {
+ a = new A();
+ a.m();
+ var x = a.g;
+ a.s = 1;
+ var y = a + a;
+ a++;
+ ++a;
+ }
+}
+@proxy
+class A {}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedGetter_inSubtype() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {
+ get b => 0;
+}
+f(var a) {
+ if(a is A) {
+ return a.b;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedMethod_assignmentExpression_inSubtype() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {
+ operator +(B b) {return new B();}
+}
+f(var a, var a2) {
+ a = new A();
+ a2 = new A();
+ a += a2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedMethod_dynamic() {
+ Source source = addSource(r'''
+class D<T extends dynamic> {
+ fieldAccess(T t) => t.abc;
+ methodAccess(T t) => t.xyz(1, 2, 'three');
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedMethod_inSubtype() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {
+ b() {}
+}
+f() {
+ var a = new A();
+ a.b();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedMethod_unionType_all() {
+ Source source = addSource(r'''
+class A {
+ int m(int x) => 0;
+}
+class B {
+ String m() => '0';
+}
+f(A a, B b) {
+ var ab;
+ if (0 < 1) {
+ ab = a;
+ } else {
+ ab = b;
+ }
+ ab.m();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedMethod_unionType_some() {
+ Source source = addSource(r'''
+class A {
+ int m(int x) => 0;
+}
+class B {}
+f(A a, B b) {
+ var ab;
+ if (0 < 1) {
+ ab = a;
+ } else {
+ ab = b;
+ }
+ ab.m(0);
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedOperator_binaryExpression_inSubtype() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {
+ operator +(B b) {}
+}
+f(var a) {
+ if(a is A) {
+ a + 1;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedOperator_indexBoth_inSubtype() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {
+ operator [](int index) {}
+}
+f(var a) {
+ if(a is A) {
+ a[0]++;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedOperator_indexGetter_inSubtype() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {
+ operator [](int index) {}
+}
+f(var a) {
+ if(a is A) {
+ a[0];
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedOperator_indexSetter_inSubtype() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {
+ operator []=(i, v) {}
+}
+f(var a) {
+ if(a is A) {
+ a[0] = 1;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedOperator_postfixExpression() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {
+ operator +(B b) {return new B();}
+}
+f(var a) {
+ if(a is A) {
+ a++;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedOperator_prefixExpression() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {
+ operator +(B b) {return new B();}
+}
+f(var a) {
+ if(a is A) {
+ ++a;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_undefinedSetter_inSubtype() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {
+ set b(x) {}
+}
+f(var a) {
+ if(a is A) {
+ a.b = 0;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_unnecessaryCast_13855_parameter_A() {
+ // dartbug.com/13855, dartbug.com/13732
+ Source source = addSource(r'''
+class A{
+ a() {}
+}
+class B<E> {
+ E e;
+ m() {
+ (e as A).a();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryCast_conditionalExpression() {
+ Source source = addSource(r'''
+abstract class I {}
+class A implements I {}
+class B implements I {}
+I m(A a, B b) {
+ return a == null ? b as I : a as I;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryCast_dynamic_type() {
+ Source source = addSource(r'''
+m(v) {
+ var b = v as Object;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryCast_generics() {
+ // dartbug.com/18953
+ Source source = addSource(r'''
+import 'dart:async';
+Future<int> f() => new Future.value(0);
+void g(bool c) {
+ (c ? f(): new Future.value(0) as Future<int>).then((int value) {});
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryCast_type_dynamic() {
+ Source source = addSource(r'''
+m(v) {
+ var b = Object as dynamic;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryNoSuchMethod_blockBody_notReturnStatement() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) {
+ print(y);
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryNoSuchMethod_blockBody_notSingleStatement() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) {
+ print(y);
+ return super.noSuchMethod(y);
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryNoSuchMethod_expressionBody_notNoSuchMethod() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) => super.hashCode;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unnecessaryNoSuchMethod_expressionBody_notSuper() {
+ Source source = addSource(r'''
+class A {
+ noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+ mmm();
+ noSuchMethod(y) => 42;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedImport_annotationOnDirective() {
+ Source source = addSource(r'''
+library L;
+@A()
+import 'lib1.dart';''');
+ Source source2 = addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {
+ const A() {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ verify([source, source2]);
+ }
+
+ void test_unusedImport_as_equalPrefixes() {
+ // 18818
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart' as one;
+import 'lib2.dart' as one;
+one.A a;
+one.B b;''');
+ Source source2 = addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}''');
+ Source source3 = addNamedSource(
+ "/lib2.dart",
+ r'''
+library lib2;
+class B {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source);
+ assertNoErrors(source2);
+ assertNoErrors(source3);
+ verify([source, source2, source3]);
+ }
+
+ void test_unusedImport_core_library() {
+ Source source = addSource(r'''
+library L;
+import 'dart:core';''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedImport_export() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+Two two;''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+export 'lib2.dart';
+class One {}''');
+ addNamedSource(
+ "/lib2.dart",
+ r'''
+library lib2;
+class Two {}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedImport_export2() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+Three three;''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+export 'lib2.dart';
+class One {}''');
+ addNamedSource(
+ "/lib2.dart",
+ r'''
+library lib2;
+export 'lib3.dart';
+class Two {}''');
+ addNamedSource(
+ "/lib3.dart",
+ r'''
+library lib3;
+class Three {}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedImport_export_infiniteLoop() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+Two two;''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+export 'lib2.dart';
+class One {}''');
+ addNamedSource(
+ "/lib2.dart",
+ r'''
+library lib2;
+export 'lib3.dart';
+class Two {}''');
+ addNamedSource(
+ "/lib3.dart",
+ r'''
+library lib3;
+export 'lib2.dart';
+class Three {}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedImport_metadata() {
+ Source source = addSource(r'''
+library L;
+@A(x)
+import 'lib1.dart';
+class A {
+ final int value;
+ const A(this.value);
+}''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+const x = 0;''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_unusedImport_prefix_topLevelFunction() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart' hide topLevelFunction;
+import 'lib1.dart' as one show topLevelFunction;
+class A {
+ static void x() {
+ One o;
+ one.topLevelFunction();
+ }
+}''');
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class One {}
+topLevelFunction() {}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_useOfVoidResult_implicitReturnValue() {
+ Source source = addSource(r'''
+f() {}
+class A {
+ n() {
+ var a = f();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_useOfVoidResult_nonVoidReturnValue() {
+ Source source = addSource(r'''
+int f() => 1;
+g() {
+ var a = f();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+}
+
+class PubSuggestionCodeTest extends ResolverTestCase {
+ void test_import_package() {
+ Source source = addSource("import 'package:somepackage/other.dart';");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+ }
+
+ void test_import_packageWithDotDot() {
+ Source source = addSource("import 'package:somepackage/../other.dart';");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+ HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
+ ]);
+ }
+
+ void test_import_packageWithLeadingDotDot() {
+ Source source = addSource("import 'package:../other.dart';");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+ HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
+ ]);
+ }
+
+ void test_import_referenceIntoLibDirectory() {
+ cacheSource("/myproj/pubspec.yaml", "");
+ cacheSource("/myproj/lib/other.dart", "");
+ Source source =
+ addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
+ computeLibrarySourceErrors(source);
+ assertErrors(
+ source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
+ }
+
+ void test_import_referenceIntoLibDirectory_no_pubspec() {
+ cacheSource("/myproj/lib/other.dart", "");
+ Source source =
+ addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_import_referenceOutOfLibDirectory() {
+ cacheSource("/myproj/pubspec.yaml", "");
+ cacheSource("/myproj/web/other.dart", "");
+ Source source =
+ addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
+ computeLibrarySourceErrors(source);
+ assertErrors(
+ source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
+ }
+
+ void test_import_referenceOutOfLibDirectory_no_pubspec() {
+ cacheSource("/myproj/web/other.dart", "");
+ Source source =
+ addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_import_valid_inside_lib1() {
+ cacheSource("/myproj/pubspec.yaml", "");
+ cacheSource("/myproj/lib/other.dart", "");
+ Source source =
+ addNamedSource("/myproj/lib/test.dart", "import 'other.dart';");
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_import_valid_inside_lib2() {
+ cacheSource("/myproj/pubspec.yaml", "");
+ cacheSource("/myproj/lib/bar/other.dart", "");
+ Source source = addNamedSource(
+ "/myproj/lib/foo/test.dart", "import '../bar/other.dart';");
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_import_valid_outside_lib() {
+ cacheSource("/myproj/pubspec.yaml", "");
+ cacheSource("/myproj/web/other.dart", "");
+ Source source =
+ addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';");
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+}
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 19a2a89..ea02857 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -7,11 +7,8 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/engine.dart';
@@ -20,7 +17,6 @@
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart' show Source;
import 'package:analyzer/src/generated/testing/ast_factory.dart';
-import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:unittest/unittest.dart' hide Configuration;
@@ -36,7 +32,6 @@
runReflectiveTests(IncrementalParserTest);
runReflectiveTests(NonErrorParserTest);
runReflectiveTests(RecoveryParserTest);
- runReflectiveTests(ResolutionCopierTest);
runReflectiveTests(SimpleParserTest);
}
@@ -4247,663 +4242,6 @@
}
}
-@reflectiveTest
-class ResolutionCopierTest extends EngineTestCase {
- void test_visitAdjacentStrings() {
- AdjacentStrings createNode() => new AdjacentStrings([
- new SimpleStringLiteral(null, 'hello'),
- new SimpleStringLiteral(null, 'world')
- ]);
-
- AdjacentStrings fromNode = createNode();
- DartType propagatedType = ElementFactory.classElement2("A").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("B").type;
- fromNode.staticType = staticType;
-
- AdjacentStrings toNode = createNode();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitAnnotation() {
- String annotationName = "proxy";
- Annotation fromNode =
- AstFactory.annotation(AstFactory.identifier3(annotationName));
- Element element = ElementFactory.topLevelVariableElement2(annotationName);
- fromNode.element = element;
- Annotation toNode =
- AstFactory.annotation(AstFactory.identifier3(annotationName));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.element, same(element));
- }
-
- void test_visitAsExpression() {
- AsExpression fromNode = AstFactory.asExpression(
- AstFactory.identifier3("x"), AstFactory.typeName4("A"));
- DartType propagatedType = ElementFactory.classElement2("A").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("B").type;
- fromNode.staticType = staticType;
- AsExpression toNode = AstFactory.asExpression(
- AstFactory.identifier3("x"), AstFactory.typeName4("A"));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitAssignmentExpression() {
- AssignmentExpression fromNode = AstFactory.assignmentExpression(
- AstFactory.identifier3("a"),
- TokenType.PLUS_EQ,
- AstFactory.identifier3("b"));
- DartType propagatedType = ElementFactory.classElement2("C").type;
- MethodElement propagatedElement =
- ElementFactory.methodElement("+", propagatedType);
- fromNode.propagatedElement = propagatedElement;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- MethodElement staticElement = ElementFactory.methodElement("+", staticType);
- fromNode.staticElement = staticElement;
- fromNode.staticType = staticType;
- AssignmentExpression toNode = AstFactory.assignmentExpression(
- AstFactory.identifier3("a"),
- TokenType.PLUS_EQ,
- AstFactory.identifier3("b"));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedElement, same(propagatedElement));
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticElement, same(staticElement));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitBinaryExpression() {
- BinaryExpression fromNode = AstFactory.binaryExpression(
- AstFactory.identifier3("a"),
- TokenType.PLUS,
- AstFactory.identifier3("b"));
- DartType propagatedType = ElementFactory.classElement2("C").type;
- MethodElement propagatedElement =
- ElementFactory.methodElement("+", propagatedType);
- fromNode.propagatedElement = propagatedElement;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- MethodElement staticElement = ElementFactory.methodElement("+", staticType);
- fromNode.staticElement = staticElement;
- fromNode.staticType = staticType;
- BinaryExpression toNode = AstFactory.binaryExpression(
- AstFactory.identifier3("a"),
- TokenType.PLUS,
- AstFactory.identifier3("b"));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedElement, same(propagatedElement));
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticElement, same(staticElement));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitBooleanLiteral() {
- BooleanLiteral fromNode = AstFactory.booleanLiteral(true);
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- BooleanLiteral toNode = AstFactory.booleanLiteral(true);
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitCascadeExpression() {
- CascadeExpression fromNode = AstFactory.cascadeExpression(
- AstFactory.identifier3("a"), [AstFactory.identifier3("b")]);
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- CascadeExpression toNode = AstFactory.cascadeExpression(
- AstFactory.identifier3("a"), [AstFactory.identifier3("b")]);
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitCompilationUnit() {
- CompilationUnit fromNode = AstFactory.compilationUnit();
- CompilationUnitElement element =
- new CompilationUnitElementImpl("test.dart");
- fromNode.element = element;
- CompilationUnit toNode = AstFactory.compilationUnit();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.element, same(element));
- }
-
- void test_visitConditionalExpression() {
- ConditionalExpression fromNode = AstFactory.conditionalExpression(
- AstFactory.identifier3("c"),
- AstFactory.identifier3("a"),
- AstFactory.identifier3("b"));
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- ConditionalExpression toNode = AstFactory.conditionalExpression(
- AstFactory.identifier3("c"),
- AstFactory.identifier3("a"),
- AstFactory.identifier3("b"));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitConstructorDeclaration() {
- String className = "A";
- String constructorName = "c";
- ConstructorDeclaration fromNode = AstFactory.constructorDeclaration(
- AstFactory.identifier3(className),
- constructorName,
- AstFactory.formalParameterList(),
- null);
- ConstructorElement element = ElementFactory.constructorElement2(
- ElementFactory.classElement2(className), constructorName);
- fromNode.element = element;
- ConstructorDeclaration toNode = AstFactory.constructorDeclaration(
- AstFactory.identifier3(className),
- constructorName,
- AstFactory.formalParameterList(),
- null);
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.element, same(element));
- }
-
- void test_visitConstructorName() {
- ConstructorName fromNode =
- AstFactory.constructorName(AstFactory.typeName4("A"), "c");
- ConstructorElement staticElement = ElementFactory.constructorElement2(
- ElementFactory.classElement2("A"), "c");
- fromNode.staticElement = staticElement;
- ConstructorName toNode =
- AstFactory.constructorName(AstFactory.typeName4("A"), "c");
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.staticElement, same(staticElement));
- }
-
- void test_visitDoubleLiteral() {
- DoubleLiteral fromNode = AstFactory.doubleLiteral(1.0);
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- DoubleLiteral toNode = AstFactory.doubleLiteral(1.0);
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitExportDirective() {
- ExportDirective fromNode = AstFactory.exportDirective2("dart:uri");
- ExportElement element = new ExportElementImpl(-1);
- fromNode.element = element;
- ExportDirective toNode = AstFactory.exportDirective2("dart:uri");
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.element, same(element));
- }
-
- void test_visitFunctionExpression() {
- FunctionExpression fromNode = AstFactory.functionExpression2(
- AstFactory.formalParameterList(), AstFactory.emptyFunctionBody());
- MethodElement element = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
- fromNode.element = element;
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- FunctionExpression toNode = AstFactory.functionExpression2(
- AstFactory.formalParameterList(), AstFactory.emptyFunctionBody());
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.element, same(element));
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitFunctionExpressionInvocation() {
- FunctionExpressionInvocation fromNode =
- AstFactory.functionExpressionInvocation(AstFactory.identifier3("f"));
- MethodElement propagatedElement = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
- fromNode.propagatedElement = propagatedElement;
- MethodElement staticElement = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
- fromNode.staticElement = staticElement;
- FunctionExpressionInvocation toNode =
- AstFactory.functionExpressionInvocation(AstFactory.identifier3("f"));
-
- _copyAndVerifyInvocation(fromNode, toNode);
-
- expect(toNode.propagatedElement, same(propagatedElement));
- expect(toNode.staticElement, same(staticElement));
- }
-
- void test_visitImportDirective() {
- ImportDirective fromNode = AstFactory.importDirective3("dart:uri", null);
- ImportElement element = new ImportElementImpl(0);
- fromNode.element = element;
- ImportDirective toNode = AstFactory.importDirective3("dart:uri", null);
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.element, same(element));
- }
-
- void test_visitIndexExpression() {
- IndexExpression fromNode = AstFactory.indexExpression(
- AstFactory.identifier3("a"), AstFactory.integer(0));
- MethodElement propagatedElement = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
- MethodElement staticElement = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
- AuxiliaryElements auxiliaryElements =
- new AuxiliaryElements(staticElement, propagatedElement);
- fromNode.auxiliaryElements = auxiliaryElements;
- fromNode.propagatedElement = propagatedElement;
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- fromNode.staticElement = staticElement;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- IndexExpression toNode = AstFactory.indexExpression(
- AstFactory.identifier3("a"), AstFactory.integer(0));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.auxiliaryElements, same(auxiliaryElements));
- expect(toNode.propagatedElement, same(propagatedElement));
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticElement, same(staticElement));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitInstanceCreationExpression() {
- InstanceCreationExpression fromNode = AstFactory
- .instanceCreationExpression2(Keyword.NEW, AstFactory.typeName4("C"));
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- ConstructorElement staticElement = ElementFactory.constructorElement2(
- ElementFactory.classElement2("C"), null);
- fromNode.staticElement = staticElement;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- InstanceCreationExpression toNode = AstFactory.instanceCreationExpression2(
- Keyword.NEW, AstFactory.typeName4("C"));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticElement, same(staticElement));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitIntegerLiteral() {
- IntegerLiteral fromNode = AstFactory.integer(2);
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- IntegerLiteral toNode = AstFactory.integer(2);
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitIsExpression() {
- IsExpression fromNode = AstFactory.isExpression(
- AstFactory.identifier3("x"), false, AstFactory.typeName4("A"));
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- IsExpression toNode = AstFactory.isExpression(
- AstFactory.identifier3("x"), false, AstFactory.typeName4("A"));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitLibraryIdentifier() {
- LibraryIdentifier fromNode =
- AstFactory.libraryIdentifier([AstFactory.identifier3("lib")]);
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- LibraryIdentifier toNode =
- AstFactory.libraryIdentifier([AstFactory.identifier3("lib")]);
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitListLiteral() {
- ListLiteral fromNode = AstFactory.listLiteral();
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- ListLiteral toNode = AstFactory.listLiteral();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitMapLiteral() {
- MapLiteral fromNode = AstFactory.mapLiteral2();
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- MapLiteral toNode = AstFactory.mapLiteral2();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitMethodInvocation() {
- MethodInvocation fromNode = AstFactory.methodInvocation2("m");
- MethodInvocation toNode = AstFactory.methodInvocation2("m");
- _copyAndVerifyInvocation(fromNode, toNode);
- }
-
- void test_visitNamedExpression() {
- NamedExpression fromNode =
- AstFactory.namedExpression2("n", AstFactory.integer(0));
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- NamedExpression toNode =
- AstFactory.namedExpression2("n", AstFactory.integer(0));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitNullLiteral() {
- NullLiteral fromNode = AstFactory.nullLiteral();
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- NullLiteral toNode = AstFactory.nullLiteral();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitParenthesizedExpression() {
- ParenthesizedExpression fromNode =
- AstFactory.parenthesizedExpression(AstFactory.integer(0));
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- ParenthesizedExpression toNode =
- AstFactory.parenthesizedExpression(AstFactory.integer(0));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitPartDirective() {
- PartDirective fromNode = AstFactory.partDirective2("part.dart");
- LibraryElement element = new LibraryElementImpl.forNode(
- null, AstFactory.libraryIdentifier2(["lib"]));
- fromNode.element = element;
- PartDirective toNode = AstFactory.partDirective2("part.dart");
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.element, same(element));
- }
-
- void test_visitPartOfDirective() {
- PartOfDirective fromNode =
- AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["lib"]));
- LibraryElement element = new LibraryElementImpl.forNode(
- null, AstFactory.libraryIdentifier2(["lib"]));
- fromNode.element = element;
- PartOfDirective toNode =
- AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["lib"]));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.element, same(element));
- }
-
- void test_visitPostfixExpression() {
- String variableName = "x";
- PostfixExpression fromNode = AstFactory.postfixExpression(
- AstFactory.identifier3(variableName), TokenType.PLUS_PLUS);
- MethodElement propagatedElement = ElementFactory.methodElement(
- "+", ElementFactory.classElement2("C").type);
- fromNode.propagatedElement = propagatedElement;
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- MethodElement staticElement = ElementFactory.methodElement(
- "+", ElementFactory.classElement2("C").type);
- fromNode.staticElement = staticElement;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- PostfixExpression toNode = AstFactory.postfixExpression(
- AstFactory.identifier3(variableName), TokenType.PLUS_PLUS);
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedElement, same(propagatedElement));
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticElement, same(staticElement));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitPrefixedIdentifier() {
- PrefixedIdentifier fromNode = AstFactory.identifier5("p", "f");
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- PrefixedIdentifier toNode = AstFactory.identifier5("p", "f");
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitPrefixExpression() {
- PrefixExpression fromNode = AstFactory.prefixExpression(
- TokenType.PLUS_PLUS, AstFactory.identifier3("x"));
- MethodElement propagatedElement = ElementFactory.methodElement(
- "+", ElementFactory.classElement2("C").type);
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedElement = propagatedElement;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- MethodElement staticElement = ElementFactory.methodElement(
- "+", ElementFactory.classElement2("C").type);
- fromNode.staticElement = staticElement;
- fromNode.staticType = staticType;
- PrefixExpression toNode = AstFactory.prefixExpression(
- TokenType.PLUS_PLUS, AstFactory.identifier3("x"));
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedElement, same(propagatedElement));
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticElement, same(staticElement));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitPropertyAccess() {
- PropertyAccess fromNode =
- AstFactory.propertyAccess2(AstFactory.identifier3("x"), "y");
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- PropertyAccess toNode =
- AstFactory.propertyAccess2(AstFactory.identifier3("x"), "y");
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitRedirectingConstructorInvocation() {
- RedirectingConstructorInvocation fromNode =
- AstFactory.redirectingConstructorInvocation();
- ConstructorElement staticElement = ElementFactory.constructorElement2(
- ElementFactory.classElement2("C"), null);
- fromNode.staticElement = staticElement;
- RedirectingConstructorInvocation toNode =
- AstFactory.redirectingConstructorInvocation();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.staticElement, same(staticElement));
- }
-
- void test_visitRethrowExpression() {
- RethrowExpression fromNode = AstFactory.rethrowExpression();
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- RethrowExpression toNode = AstFactory.rethrowExpression();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitSimpleIdentifier() {
- SimpleIdentifier fromNode = AstFactory.identifier3("x");
- MethodElement propagatedElement = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
- MethodElement staticElement = ElementFactory.methodElement(
- "m", ElementFactory.classElement2("C").type);
- AuxiliaryElements auxiliaryElements =
- new AuxiliaryElements(staticElement, propagatedElement);
- fromNode.auxiliaryElements = auxiliaryElements;
- fromNode.propagatedElement = propagatedElement;
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- fromNode.staticElement = staticElement;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- SimpleIdentifier toNode = AstFactory.identifier3("x");
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.auxiliaryElements, same(auxiliaryElements));
- expect(toNode.propagatedElement, same(propagatedElement));
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticElement, same(staticElement));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitSimpleStringLiteral() {
- SimpleStringLiteral fromNode = AstFactory.string2("abc");
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- SimpleStringLiteral toNode = AstFactory.string2("abc");
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitStringInterpolation() {
- StringInterpolation fromNode =
- AstFactory.string([AstFactory.interpolationString("a", "'a'")]);
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- StringInterpolation toNode =
- AstFactory.string([AstFactory.interpolationString("a", "'a'")]);
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitSuperConstructorInvocation() {
- SuperConstructorInvocation fromNode =
- AstFactory.superConstructorInvocation();
- ConstructorElement staticElement = ElementFactory.constructorElement2(
- ElementFactory.classElement2("C"), null);
- fromNode.staticElement = staticElement;
- SuperConstructorInvocation toNode = AstFactory.superConstructorInvocation();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.staticElement, same(staticElement));
- }
-
- void test_visitSuperExpression() {
- SuperExpression fromNode = AstFactory.superExpression();
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- SuperExpression toNode = AstFactory.superExpression();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitSymbolLiteral() {
- SymbolLiteral fromNode = AstFactory.symbolLiteral(["s"]);
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- SymbolLiteral toNode = AstFactory.symbolLiteral(["s"]);
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitThisExpression() {
- ThisExpression fromNode = AstFactory.thisExpression();
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- ThisExpression toNode = AstFactory.thisExpression();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitThrowExpression() {
- ThrowExpression fromNode = AstFactory.throwExpression();
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
- ThrowExpression toNode = AstFactory.throwExpression();
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- }
-
- void test_visitTypeName() {
- TypeName fromNode = AstFactory.typeName4("C");
- DartType type = ElementFactory.classElement2("C").type;
- fromNode.type = type;
- TypeName toNode = AstFactory.typeName4("C");
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.type, same(type));
- }
-
- void _copyAndVerifyInvocation(
- InvocationExpression fromNode, InvocationExpression toNode) {
- DartType propagatedType = ElementFactory.classElement2("C").type;
- fromNode.propagatedType = propagatedType;
- DartType staticType = ElementFactory.classElement2("C").type;
- fromNode.staticType = staticType;
-
- DartType propagatedInvokeType = ElementFactory.classElement2("C").type;
- fromNode.propagatedInvokeType = propagatedInvokeType;
- DartType staticInvokeType = ElementFactory.classElement2("C").type;
- fromNode.staticInvokeType = staticInvokeType;
-
- ResolutionCopier.copyResolutionData(fromNode, toNode);
- expect(toNode.propagatedType, same(propagatedType));
- expect(toNode.staticType, same(staticType));
- expect(toNode.propagatedInvokeType, same(propagatedInvokeType));
- expect(toNode.staticInvokeType, same(staticInvokeType));
- }
-}
-
/**
* The class `SimpleParserTest` defines parser tests that test individual parsing method. The
* code fragments should be as minimal as possible in order to test the method, but should not test
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index b51be7f..4fe6516 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -13,56 +13,38 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/context/context.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/element_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_engine_io.dart';
-import 'package:analyzer/src/generated/java_io.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/static_type_analyzer.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
-import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/string_source.dart';
import 'package:unittest/unittest.dart';
import '../reflective_tests.dart';
import '../utils.dart';
+import 'analysis_context_factory.dart';
+import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
initializeTestEnvironment();
runReflectiveTests(AnalysisDeltaTest);
runReflectiveTests(ChangeSetTest);
- runReflectiveTests(CheckedModeCompileTimeErrorCodeTest);
runReflectiveTests(DisableAsyncTestCase);
- runReflectiveTests(ElementResolverTest);
runReflectiveTests(EnclosedScopeTest);
runReflectiveTests(ErrorResolverTest);
- runReflectiveTests(HintCodeTest);
- runReflectiveTests(InheritanceManagerTest);
runReflectiveTests(LibraryImportScopeTest);
runReflectiveTests(LibraryScopeTest);
runReflectiveTests(MemberMapTest);
- runReflectiveTests(NonHintCodeTest);
runReflectiveTests(ScopeTest);
- runReflectiveTests(SimpleResolverTest);
- runReflectiveTests(StaticTypeAnalyzerTest);
- runReflectiveTests(StaticTypeAnalyzer2Test);
runReflectiveTests(StrictModeTest);
- runReflectiveTests(StrongModeDownwardsInferenceTest);
- runReflectiveTests(StrongModeStaticTypeAnalyzer2Test);
- runReflectiveTests(StrongModeTypePropagationTest);
runReflectiveTests(SubtypeManagerTest);
runReflectiveTests(TypeOverrideManagerTest);
runReflectiveTests(TypePropagationTest);
@@ -70,490 +52,6 @@
runReflectiveTests(TypeResolverVisitorTest);
}
-/**
- * The class `AnalysisContextFactory` defines utility methods used to create analysis contexts
- * for testing purposes.
- */
-class AnalysisContextFactory {
- static String _DART_MATH = "dart:math";
-
- static String _DART_INTERCEPTORS = "dart:_interceptors";
-
- static String _DART_JS_HELPER = "dart:_js_helper";
-
- /**
- * Create an analysis context that has a fake core library already resolved.
- * Return the context that was created.
- */
- static InternalAnalysisContext contextWithCore() {
- AnalysisContextForTests context = new AnalysisContextForTests();
- return initContextWithCore(context);
- }
-
- /**
- * Create an analysis context that uses the given [options] and has a fake
- * core library already resolved. Return the context that was created.
- */
- static InternalAnalysisContext contextWithCoreAndOptions(
- AnalysisOptions options) {
- AnalysisContextForTests context = new AnalysisContextForTests();
- context._internalSetAnalysisOptions(options);
- return initContextWithCore(context);
- }
-
- static InternalAnalysisContext contextWithCoreAndPackages(
- Map<String, String> packages) {
- AnalysisContextForTests context = new AnalysisContextForTests();
- return initContextWithCore(context, new TestPackageUriResolver(packages));
- }
-
- /**
- * Initialize the given analysis context with a fake core library already resolved.
- *
- * @param context the context to be initialized (not `null`)
- * @return the analysis context that was created
- */
- static InternalAnalysisContext initContextWithCore(
- InternalAnalysisContext context,
- [UriResolver contributedResolver]) {
- DirectoryBasedDartSdk sdk = new _AnalysisContextFactory_initContextWithCore(
- new JavaFile("/fake/sdk"),
- enableAsync: context.analysisOptions.enableAsync);
- List<UriResolver> resolvers = <UriResolver>[
- new DartUriResolver(sdk),
- new FileUriResolver()
- ];
- if (contributedResolver != null) {
- resolvers.add(contributedResolver);
- }
- SourceFactory sourceFactory = new SourceFactory(resolvers);
- context.sourceFactory = sourceFactory;
- AnalysisContext coreContext = sdk.context;
- (coreContext.analysisOptions as AnalysisOptionsImpl).strongMode =
- context.analysisOptions.strongMode;
- //
- // dart:core
- //
- TestTypeProvider provider = new TestTypeProvider();
- CompilationUnitElementImpl coreUnit =
- new CompilationUnitElementImpl("core.dart");
- Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
- coreContext.setContents(coreSource, "");
- coreUnit.librarySource = coreUnit.source = coreSource;
- ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy");
- proxyClassElement.constructors = <ConstructorElement>[
- ElementFactory.constructorElement(proxyClassElement, '', true)
- ..isCycleFree = true
- ..constantInitializers = <ConstructorInitializer>[]
- ];
- ClassElement objectClassElement = provider.objectType.element;
- coreUnit.types = <ClassElement>[
- provider.boolType.element,
- provider.deprecatedType.element,
- provider.doubleType.element,
- provider.functionType.element,
- provider.intType.element,
- provider.iterableType.element,
- provider.iteratorType.element,
- provider.listType.element,
- provider.mapType.element,
- provider.nullType.element,
- provider.numType.element,
- objectClassElement,
- proxyClassElement,
- provider.stackTraceType.element,
- provider.stringType.element,
- provider.symbolType.element,
- provider.typeType.element
- ];
- coreUnit.functions = <FunctionElement>[
- ElementFactory.functionElement3("identical", provider.boolType.element,
- <ClassElement>[objectClassElement, objectClassElement], null),
- ElementFactory.functionElement3("print", VoidTypeImpl.instance.element,
- <ClassElement>[objectClassElement], null)
- ];
- TopLevelVariableElement proxyTopLevelVariableElt = ElementFactory
- .topLevelVariableElement3("proxy", true, false, proxyClassElement.type);
- ConstTopLevelVariableElementImpl deprecatedTopLevelVariableElt =
- ElementFactory.topLevelVariableElement3(
- "deprecated", true, false, provider.deprecatedType);
- {
- ClassElement deprecatedElement = provider.deprecatedType.element;
- InstanceCreationExpression initializer = AstFactory
- .instanceCreationExpression2(
- Keyword.CONST,
- AstFactory.typeName(deprecatedElement),
- [AstFactory.string2('next release')]);
- ConstructorElement constructor = deprecatedElement.constructors.single;
- initializer.staticElement = constructor;
- initializer.constructorName.staticElement = constructor;
- deprecatedTopLevelVariableElt.constantInitializer = initializer;
- }
- coreUnit.accessors = <PropertyAccessorElement>[
- proxyTopLevelVariableElt.getter,
- deprecatedTopLevelVariableElt.getter
- ];
- coreUnit.topLevelVariables = <TopLevelVariableElement>[
- proxyTopLevelVariableElt,
- deprecatedTopLevelVariableElt
- ];
- LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
- coreContext, AstFactory.libraryIdentifier2(["dart", "core"]));
- coreLibrary.definingCompilationUnit = coreUnit;
- //
- // dart:async
- //
- Source asyncSource;
- LibraryElementImpl asyncLibrary;
- if (context.analysisOptions.enableAsync) {
- asyncLibrary = new LibraryElementImpl.forNode(
- coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
- CompilationUnitElementImpl asyncUnit =
- new CompilationUnitElementImpl("async.dart");
- asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
- coreContext.setContents(asyncSource, "");
- asyncUnit.librarySource = asyncUnit.source = asyncSource;
- asyncLibrary.definingCompilationUnit = asyncUnit;
- // Future
- ClassElementImpl futureElement =
- ElementFactory.classElement2("Future", ["T"]);
- futureElement.enclosingElement = asyncUnit;
- // factory Future.value([value])
- ConstructorElementImpl futureConstructor =
- ElementFactory.constructorElement2(futureElement, "value");
- futureConstructor.parameters = <ParameterElement>[
- ElementFactory.positionalParameter2("value", provider.dynamicType)
- ];
- futureConstructor.factory = true;
- futureElement.constructors = <ConstructorElement>[futureConstructor];
- // Future then(onValue(T value), { Function onError });
- TypeDefiningElement futureThenR = DynamicElementImpl.instance;
- if (context.analysisOptions.strongMode) {
- futureThenR = ElementFactory.typeParameterWithType('R');
- }
- FunctionElementImpl thenOnValue = ElementFactory.functionElement3(
- 'onValue', futureThenR, [futureElement.typeParameters[0]], null);
- thenOnValue.synthetic = true;
-
- DartType futureRType = futureElement.type.instantiate([futureThenR.type]);
- MethodElementImpl thenMethod = ElementFactory
- .methodElementWithParameters(futureElement, "then", futureRType, [
- ElementFactory.requiredParameter2("onValue", thenOnValue.type),
- ElementFactory.namedParameter2("onError", provider.functionType)
- ]);
- if (!futureThenR.type.isDynamic) {
- thenMethod.typeParameters = [futureThenR];
- }
- thenOnValue.enclosingElement = thenMethod;
- thenOnValue.type = new FunctionTypeImpl(thenOnValue);
- (thenMethod.parameters[0] as ParameterElementImpl).type =
- thenOnValue.type;
- thenMethod.type = new FunctionTypeImpl(thenMethod);
-
- futureElement.methods = <MethodElement>[thenMethod];
- // Completer
- ClassElementImpl completerElement =
- ElementFactory.classElement2("Completer", ["T"]);
- ConstructorElementImpl completerConstructor =
- ElementFactory.constructorElement2(completerElement, null);
- completerElement.constructors = <ConstructorElement>[
- completerConstructor
- ];
- // StreamSubscription
- ClassElementImpl streamSubscriptionElement =
- ElementFactory.classElement2("StreamSubscription", ["T"]);
- // Stream
- ClassElementImpl streamElement =
- ElementFactory.classElement2("Stream", ["T"]);
- streamElement.constructors = <ConstructorElement>[
- ElementFactory.constructorElement2(streamElement, null)
- ];
- DartType returnType = streamSubscriptionElement.type
- .instantiate(streamElement.type.typeArguments);
- FunctionElementImpl listenOnData = ElementFactory.functionElement3(
- 'onData',
- VoidTypeImpl.instance.element,
- <TypeDefiningElement>[streamElement.typeParameters[0]],
- null);
- listenOnData.synthetic = true;
- List<DartType> parameterTypes = <DartType>[listenOnData.type,];
- // TODO(brianwilkerson) This is missing the optional parameters.
- MethodElementImpl listenMethod =
- ElementFactory.methodElement('listen', returnType, parameterTypes);
- streamElement.methods = <MethodElement>[listenMethod];
- listenMethod.type = new FunctionTypeImpl(listenMethod);
-
- FunctionElementImpl listenParamFunction = parameterTypes[0].element;
- listenParamFunction.enclosingElement = listenMethod;
- listenParamFunction.type = new FunctionTypeImpl(listenParamFunction);
- ParameterElementImpl listenParam = listenMethod.parameters[0];
- listenParam.type = listenParamFunction.type;
-
- asyncUnit.types = <ClassElement>[
- completerElement,
- futureElement,
- streamElement,
- streamSubscriptionElement
- ];
- }
- //
- // dart:html
- //
- CompilationUnitElementImpl htmlUnit =
- new CompilationUnitElementImpl("html_dartium.dart");
- Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
- coreContext.setContents(htmlSource, "");
- htmlUnit.librarySource = htmlUnit.source = htmlSource;
- ClassElementImpl elementElement = ElementFactory.classElement2("Element");
- InterfaceType elementType = elementElement.type;
- ClassElementImpl canvasElement =
- ElementFactory.classElement("CanvasElement", elementType);
- ClassElementImpl contextElement =
- ElementFactory.classElement2("CanvasRenderingContext");
- InterfaceType contextElementType = contextElement.type;
- ClassElementImpl context2dElement = ElementFactory.classElement(
- "CanvasRenderingContext2D", contextElementType);
- canvasElement.methods = <MethodElement>[
- ElementFactory.methodElement(
- "getContext", contextElementType, [provider.stringType])
- ];
- canvasElement.accessors = <PropertyAccessorElement>[
- ElementFactory.getterElement("context2D", false, context2dElement.type)
- ];
- canvasElement.fields = canvasElement.accessors
- .map((PropertyAccessorElement accessor) => accessor.variable)
- .toList();
- ClassElementImpl documentElement =
- ElementFactory.classElement("Document", elementType);
- ClassElementImpl htmlDocumentElement =
- ElementFactory.classElement("HtmlDocument", documentElement.type);
- htmlDocumentElement.methods = <MethodElement>[
- ElementFactory
- .methodElement("query", elementType, <DartType>[provider.stringType])
- ];
- htmlUnit.types = <ClassElement>[
- ElementFactory.classElement("AnchorElement", elementType),
- ElementFactory.classElement("BodyElement", elementType),
- ElementFactory.classElement("ButtonElement", elementType),
- canvasElement,
- contextElement,
- context2dElement,
- ElementFactory.classElement("DivElement", elementType),
- documentElement,
- elementElement,
- htmlDocumentElement,
- ElementFactory.classElement("InputElement", elementType),
- ElementFactory.classElement("SelectElement", elementType)
- ];
- htmlUnit.functions = <FunctionElement>[
- ElementFactory.functionElement3("query", elementElement,
- <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST)
- ];
- TopLevelVariableElementImpl document =
- ElementFactory.topLevelVariableElement3(
- "document", false, true, htmlDocumentElement.type);
- htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
- htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
- LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode(
- coreContext, AstFactory.libraryIdentifier2(["dart", "dom", "html"]));
- htmlLibrary.definingCompilationUnit = htmlUnit;
- //
- // dart:math
- //
- CompilationUnitElementImpl mathUnit =
- new CompilationUnitElementImpl("math.dart");
- Source mathSource = sourceFactory.forUri(_DART_MATH);
- coreContext.setContents(mathSource, "");
- mathUnit.librarySource = mathUnit.source = mathSource;
- FunctionElement cosElement = ElementFactory.functionElement3(
- "cos",
- provider.doubleType.element,
- <ClassElement>[provider.numType.element],
- ClassElement.EMPTY_LIST);
- TopLevelVariableElement ln10Element = ElementFactory
- .topLevelVariableElement3("LN10", true, false, provider.doubleType);
- TypeParameterElement maxT =
- ElementFactory.typeParameterWithType('T', provider.numType);
- FunctionElementImpl maxElement = ElementFactory.functionElement3(
- "max", maxT, [maxT, maxT], ClassElement.EMPTY_LIST);
- maxElement.typeParameters = [maxT];
- maxElement.type = new FunctionTypeImpl(maxElement);
- TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3(
- "PI", true, false, provider.doubleType);
- ClassElementImpl randomElement = ElementFactory.classElement2("Random");
- randomElement.abstract = true;
- ConstructorElementImpl randomConstructor =
- ElementFactory.constructorElement2(randomElement, null);
- randomConstructor.factory = true;
- ParameterElementImpl seedParam = new ParameterElementImpl("seed", 0);
- seedParam.parameterKind = ParameterKind.POSITIONAL;
- seedParam.type = provider.intType;
- randomConstructor.parameters = <ParameterElement>[seedParam];
- randomElement.constructors = <ConstructorElement>[randomConstructor];
- FunctionElement sinElement = ElementFactory.functionElement3(
- "sin",
- provider.doubleType.element,
- <ClassElement>[provider.numType.element],
- ClassElement.EMPTY_LIST);
- FunctionElement sqrtElement = ElementFactory.functionElement3(
- "sqrt",
- provider.doubleType.element,
- <ClassElement>[provider.numType.element],
- ClassElement.EMPTY_LIST);
- mathUnit.accessors = <PropertyAccessorElement>[
- ln10Element.getter,
- piElement.getter
- ];
- mathUnit.functions = <FunctionElement>[
- cosElement,
- maxElement,
- sinElement,
- sqrtElement
- ];
- mathUnit.topLevelVariables = <TopLevelVariableElement>[
- ln10Element,
- piElement
- ];
- mathUnit.types = <ClassElement>[randomElement];
- LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode(
- coreContext, AstFactory.libraryIdentifier2(["dart", "math"]));
- mathLibrary.definingCompilationUnit = mathUnit;
- //
- // Set empty sources for the rest of the libraries.
- //
- Source source = sourceFactory.forUri(_DART_INTERCEPTORS);
- coreContext.setContents(source, "");
- source = sourceFactory.forUri(_DART_JS_HELPER);
- coreContext.setContents(source, "");
- //
- // Record the elements.
- //
- HashMap<Source, LibraryElement> elementMap =
- new HashMap<Source, LibraryElement>();
- elementMap[coreSource] = coreLibrary;
- if (asyncSource != null) {
- elementMap[asyncSource] = asyncLibrary;
- }
- elementMap[htmlSource] = htmlLibrary;
- elementMap[mathSource] = mathLibrary;
- //
- // Set the public and export namespaces. We don't use exports in the fake
- // core library so public and export namespaces are the same.
- //
- for (LibraryElementImpl library in elementMap.values) {
- Namespace namespace =
- new NamespaceBuilder().createPublicNamespaceForLibrary(library);
- library.exportNamespace = namespace;
- library.publicNamespace = namespace;
- }
- context.recordLibraryElements(elementMap);
- // Create the synthetic element for `loadLibrary`.
- for (LibraryElementImpl library in elementMap.values) {
- library.createLoadLibraryFunction(context.typeProvider);
- }
- return context;
- }
-}
-
-/**
- * An analysis context that has a fake SDK that is much smaller and faster for
- * testing purposes.
- */
-class AnalysisContextForTests extends AnalysisContextImpl {
- @override
- void set analysisOptions(AnalysisOptions options) {
- AnalysisOptions currentOptions = analysisOptions;
- bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate !=
- options.analyzeFunctionBodiesPredicate ||
- currentOptions.generateImplicitErrors !=
- options.generateImplicitErrors ||
- currentOptions.generateSdkErrors != options.generateSdkErrors ||
- currentOptions.dart2jsHint != options.dart2jsHint ||
- (currentOptions.hint && !options.hint) ||
- currentOptions.preserveComments != options.preserveComments ||
- currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
- if (needsRecompute) {
- fail(
- "Cannot set options that cause the sources to be reanalyzed in a test context");
- }
- super.analysisOptions = options;
- }
-
- @override
- bool exists(Source source) =>
- super.exists(source) || sourceFactory.dartSdk.context.exists(source);
-
- @override
- TimestampedData<String> getContents(Source source) {
- if (source.isInSystemLibrary) {
- return sourceFactory.dartSdk.context.getContents(source);
- }
- return super.getContents(source);
- }
-
- @override
- int getModificationStamp(Source source) {
- if (source.isInSystemLibrary) {
- return sourceFactory.dartSdk.context.getModificationStamp(source);
- }
- return super.getModificationStamp(source);
- }
-
- /**
- * Set the analysis options, even if they would force re-analysis. This method should only be
- * invoked before the fake SDK is initialized.
- *
- * @param options the analysis options to be set
- */
- void _internalSetAnalysisOptions(AnalysisOptions options) {
- super.analysisOptions = options;
- }
-}
-
-/**
- * Helper for creating and managing single [AnalysisContext].
- */
-class AnalysisContextHelper {
- AnalysisContext context;
-
- /**
- * Creates new [AnalysisContext] using [AnalysisContextFactory].
- */
- AnalysisContextHelper([AnalysisOptionsImpl options]) {
- if (options == null) {
- options = new AnalysisOptionsImpl();
- }
- options.cacheSize = 256;
- context = AnalysisContextFactory.contextWithCoreAndOptions(options);
- }
-
- Source addSource(String path, String code) {
- Source source = new FileBasedSource(FileUtilities2.createFile(path));
- if (path.endsWith(".dart") || path.endsWith(".html")) {
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- context.applyChanges(changeSet);
- }
- context.setContents(source, code);
- return source;
- }
-
- CompilationUnitElement getDefiningUnitElement(Source source) =>
- context.getCompilationUnitElement(source, source);
-
- CompilationUnit resolveDefiningUnit(Source source) {
- LibraryElement libraryElement = context.computeLibraryElement(source);
- return context.resolveCompilationUnit(source, libraryElement);
- }
-
- void runTasks() {
- AnalysisResult result = context.performAnalysisTask();
- while (result.changeNotices != null) {
- result = context.performAnalysisTask();
- }
- }
-}
-
@reflectiveTest
class AnalysisDeltaTest extends EngineTestCase {
TestSource source1 = new TestSource('/1.dart');
@@ -648,608 +146,6 @@
}
@reflectiveTest
-class CheckedModeCompileTimeErrorCodeTest extends ResolverTestCase {
- void test_fieldFormalParameterAssignableToField_extends() {
- // According to checked-mode type checking rules, a value of type B is
- // assignable to a field of type A, because B extends A (and hence is a
- // subtype of A).
- Source source = addSource(r'''
-class A {
- const A();
-}
-class B extends A {
- const B();
-}
-class C {
- final A a;
- const C(this.a);
-}
-var v = const C(const B());''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() {
- // Null always passes runtime type checks, even when the type is
- // unresolved.
- Source source = addSource(r'''
-class A {
- final Unresolved x;
- const A(String this.x);
-}
-var v = const A(null);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_implements() {
- // According to checked-mode type checking rules, a value of type B is
- // assignable to a field of type A, because B implements A (and hence is a
- // subtype of A).
- Source source = addSource(r'''
-class A {}
-class B implements A {
- const B();
-}
-class C {
- final A a;
- const C(this.a);
-}
-var v = const C(const B());''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_list_dynamic() {
- // [1, 2, 3] has type List<dynamic>, which is a subtype of List<int>.
- Source source = addSource(r'''
-class A {
- const A(List<int> x);
-}
-var x = const A(const [1, 2, 3]);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_list_nonDynamic() {
- // <int>[1, 2, 3] has type List<int>, which is a subtype of List<num>.
- Source source = addSource(r'''
-class A {
- const A(List<num> x);
-}
-var x = const A(const <int>[1, 2, 3]);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_map_dynamic() {
- // {1: 2} has type Map<dynamic, dynamic>, which is a subtype of
- // Map<int, int>.
- Source source = addSource(r'''
-class A {
- const A(Map<int, int> x);
-}
-var x = const A(const {1: 2});''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_map_keyDifferent() {
- // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
- // Map<num, int>.
- Source source = addSource(r'''
-class A {
- const A(Map<num, int> x);
-}
-var x = const A(const <int, int>{1: 2});''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_map_valueDifferent() {
- // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
- // Map<int, num>.
- Source source = addSource(r'''
-class A {
- const A(Map<int, num> x);
-}
-var x = const A(const <int, int>{1: 2});''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_notype() {
- // If a field is declared without a type, then any value may be assigned to
- // it.
- Source source = addSource(r'''
-class A {
- final x;
- const A(this.x);
-}
-var v = const A(5);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_null() {
- // Null is assignable to anything.
- Source source = addSource(r'''
-class A {
- final int x;
- const A(this.x);
-}
-var v = const A(null);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_typedef() {
- // foo has the runtime type dynamic -> dynamic, so it should be assignable
- // to A.f.
- Source source = addSource(r'''
-typedef String Int2String(int x);
-class A {
- final Int2String f;
- const A(this.f);
-}
-foo(x) => 1;
-var v = const A(foo);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterAssignableToField_typeSubstitution() {
- // foo has the runtime type dynamic -> dynamic, so it should be assignable
- // to A.f.
- Source source = addSource(r'''
-class A<T> {
- final T x;
- const A(this.x);
-}
-var v = const A<int>(3);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField() {
- Source source = addSource(r'''
-class A {
- final int x;
- const A(this.x);
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_extends() {
- // According to checked-mode type checking rules, a value of type A is not
- // assignable to a field of type B, because B extends A (the subtyping
- // relationship is in the wrong direction).
- Source source = addSource(r'''
-class A {
- const A();
-}
-class B extends A {
- const B();
-}
-class C {
- final B b;
- const C(this.b);
-}
-var v = const C(const A());''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_fieldType() {
- Source source = addSource(r'''
-class A {
- final int x;
- const A(String this.x);
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() {
- Source source = addSource(r'''
-class A {
- final Unresolved x;
- const A(String this.x);
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.UNDEFINED_CLASS
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_implements() {
- // According to checked-mode type checking rules, a value of type A is not
- // assignable to a field of type B, because B implements A (the subtyping
- // relationship is in the wrong direction).
- Source source = addSource(r'''
-class A {
- const A();
-}
-class B implements A {}
-class C {
- final B b;
- const C(this.b);
-}
-var v = const C(const A());''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_list() {
- // <num>[1, 2, 3] has type List<num>, which is not a subtype of List<int>.
- Source source = addSource(r'''
-class A {
- const A(List<int> x);
-}
-var x = const A(const <num>[1, 2, 3]);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_map_keyMismatch() {
- // <num, int>{1: 2} has type Map<num, int>, which is not a subtype of
- // Map<int, int>.
- Source source = addSource(r'''
-class A {
- const A(Map<int, int> x);
-}
-var x = const A(const <num, int>{1: 2});''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_map_valueMismatch() {
- // <int, num>{1: 2} has type Map<int, num>, which is not a subtype of
- // Map<int, int>.
- Source source = addSource(r'''
-class A {
- const A(Map<int, int> x);
-}
-var x = const A(const <int, num>{1: 2});''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_optional() {
- Source source = addSource(r'''
-class A {
- final int x;
- const A([this.x = 'foo']);
-}
-var v = const A();''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticTypeWarningCode.INVALID_ASSIGNMENT
- ]);
- verify([source]);
- }
-
- void test_fieldFormalParameterNotAssignableToField_typedef() {
- // foo has the runtime type String -> int, so it should not be assignable
- // to A.f (A.f requires it to be int -> String).
- Source source = addSource(r'''
-typedef String Int2String(int x);
-class A {
- final Int2String f;
- const A(this.f);
-}
-int foo(String x) => 1;
-var v = const A(foo);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_fieldInitializerNotAssignable() {
- Source source = addSource(r'''
-class A {
- final int x;
- const A() : x = '';
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
- StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_fieldTypeMismatch() {
- Source source = addSource(r'''
-class A {
- const A(x) : y = x;
- final int y;
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_fieldTypeMismatch_generic() {
- Source source = addSource(r'''
-class C<T> {
- final T x = y;
- const C();
-}
-const int y = 1;
-var v = const C<String>();
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
- StaticTypeWarningCode.INVALID_ASSIGNMENT
- ]);
- verify([source]);
- }
-
- void test_fieldTypeMismatch_unresolved() {
- Source source = addSource(r'''
-class A {
- const A(x) : y = x;
- final Unresolved y;
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
- StaticWarningCode.UNDEFINED_CLASS
- ]);
- verify([source]);
- }
-
- void test_fieldTypeOk_generic() {
- Source source = addSource(r'''
-class C<T> {
- final T x = y;
- const C();
-}
-const int y = 1;
-var v = const C<int>();
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_fieldTypeOk_null() {
- Source source = addSource(r'''
-class A {
- const A(x) : y = x;
- final int y;
-}
-var v = const A(null);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldTypeOk_unresolved_null() {
- // Null always passes runtime type checks, even when the type is
- // unresolved.
- Source source = addSource(r'''
-class A {
- const A(x) : y = x;
- final Unresolved y;
-}
-var v = const A(null);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
- verify([source]);
- }
-
- void test_listElementTypeNotAssignable() {
- Source source = addSource("var v = const <String> [42];");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
- StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_mapKeyTypeNotAssignable() {
- Source source = addSource("var v = const <String, int > {1 : 2};");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
- StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_mapValueTypeNotAssignable() {
- Source source = addSource("var v = const <String, String> {'a' : 2};");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
- StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_parameterAssignable_null() {
- // Null is assignable to anything.
- Source source = addSource(r'''
-class A {
- const A(int x);
-}
-var v = const A(null);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_parameterAssignable_typeSubstitution() {
- Source source = addSource(r'''
-class A<T> {
- const A(T x);
-}
-var v = const A<int>(3);''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_parameterAssignable_undefined_null() {
- // Null always passes runtime type checks, even when the type is
- // unresolved.
- Source source = addSource(r'''
-class A {
- const A(Unresolved x);
-}
-var v = const A(null);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
- verify([source]);
- }
-
- void test_parameterNotAssignable() {
- Source source = addSource(r'''
-class A {
- const A(int x);
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_parameterNotAssignable_typeSubstitution() {
- Source source = addSource(r'''
-class A<T> {
- const A(T x);
-}
-var v = const A<int>('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
- ]);
- verify([source]);
- }
-
- void test_parameterNotAssignable_undefined() {
- Source source = addSource(r'''
-class A {
- const A(Unresolved x);
-}
-var v = const A('foo');''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- StaticWarningCode.UNDEFINED_CLASS
- ]);
- verify([source]);
- }
-
- void test_redirectingConstructor_paramTypeMismatch() {
- Source source = addSource(r'''
-class A {
- const A.a1(x) : this.a2(x);
- const A.a2(String x);
-}
-var v = const A.a1(0);''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
- ]);
- verify([source]);
- }
-
- void test_topLevelVarAssignable_null() {
- Source source = addSource("const int x = null;");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_topLevelVarAssignable_undefined_null() {
- // Null always passes runtime type checks, even when the type is
- // unresolved.
- Source source = addSource("const Unresolved x = null;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
- verify([source]);
- }
-
- void test_topLevelVarNotAssignable() {
- Source source = addSource("const int x = 'foo';");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
- StaticTypeWarningCode.INVALID_ASSIGNMENT
- ]);
- verify([source]);
- }
-
- void test_topLevelVarNotAssignable_undefined() {
- Source source = addSource("const Unresolved x = 'foo';");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
- StaticWarningCode.UNDEFINED_CLASS
- ]);
- verify([source]);
- }
-}
-
-@reflectiveTest
class DisableAsyncTestCase extends ResolverTestCase {
@override
void setUp() {
@@ -1295,986 +191,6 @@
}
@reflectiveTest
-class ElementResolverTest extends EngineTestCase {
- /**
- * The error listener to which errors will be reported.
- */
- GatheringErrorListener _listener;
-
- /**
- * The type provider used to access the types.
- */
- TestTypeProvider _typeProvider;
-
- /**
- * The library containing the code being resolved.
- */
- LibraryElementImpl _definingLibrary;
-
- /**
- * The resolver visitor that maintains the state for the resolver.
- */
- ResolverVisitor _visitor;
-
- /**
- * The resolver being used to resolve the test cases.
- */
- ElementResolver _resolver;
-
- void fail_visitExportDirective_combinators() {
- fail("Not yet tested");
- // Need to set up the exported library so that the identifier can be
- // resolved.
- ExportDirective directive = AstFactory.exportDirective2(null, [
- AstFactory.hideCombinator2(["A"])
- ]);
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void fail_visitFunctionExpressionInvocation() {
- fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- void fail_visitImportDirective_combinators_noPrefix() {
- fail("Not yet tested");
- // Need to set up the imported library so that the identifier can be
- // resolved.
- ImportDirective directive = AstFactory.importDirective3(null, null, [
- AstFactory.showCombinator2(["A"])
- ]);
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void fail_visitImportDirective_combinators_prefix() {
- fail("Not yet tested");
- // Need to set up the imported library so that the identifiers can be
- // resolved.
- String prefixName = "p";
- _definingLibrary.imports = <ImportElement>[
- ElementFactory.importFor(null, ElementFactory.prefix(prefixName))
- ];
- ImportDirective directive = AstFactory.importDirective3(null, prefixName, [
- AstFactory.showCombinator2(["A"]),
- AstFactory.hideCombinator2(["B"])
- ]);
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void fail_visitRedirectingConstructorInvocation() {
- fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- @override
- void setUp() {
- super.setUp();
- _listener = new GatheringErrorListener();
- _typeProvider = new TestTypeProvider();
- _resolver = _createResolver();
- }
-
- void test_lookUpMethodInInterfaces() {
- InterfaceType intType = _typeProvider.intType;
- //
- // abstract class A { int operator[](int index); }
- //
- ClassElementImpl classA = ElementFactory.classElement2("A");
- MethodElement operator =
- ElementFactory.methodElement("[]", intType, [intType]);
- classA.methods = <MethodElement>[operator];
- //
- // class B implements A {}
- //
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- //
- // class C extends Object with B {}
- //
- ClassElementImpl classC = ElementFactory.classElement2("C");
- classC.mixins = <InterfaceType>[classB.type];
- //
- // class D extends C {}
- //
- ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
- //
- // D a;
- // a[i];
- //
- SimpleIdentifier array = AstFactory.identifier3("a");
- array.staticType = classD.type;
- IndexExpression expression =
- AstFactory.indexExpression(array, AstFactory.identifier3("i"));
- expect(_resolveIndexExpression(expression), same(operator));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_compound() {
- InterfaceType intType = _typeProvider.intType;
- SimpleIdentifier leftHandSide = AstFactory.identifier3("a");
- leftHandSide.staticType = intType;
- AssignmentExpression assignment = AstFactory.assignmentExpression(
- leftHandSide, TokenType.PLUS_EQ, AstFactory.integer(1));
- _resolveNode(assignment);
- expect(
- assignment.staticElement, same(getMethod(_typeProvider.numType, "+")));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_simple() {
- AssignmentExpression expression = AstFactory.assignmentExpression(
- AstFactory.identifier3("x"), TokenType.EQ, AstFactory.integer(0));
- _resolveNode(expression);
- expect(expression.staticElement, isNull);
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_bangEq() {
- // String i;
- // var j;
- // i == j
- InterfaceType stringType = _typeProvider.stringType;
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.staticType = stringType;
- BinaryExpression expression = AstFactory.binaryExpression(
- left, TokenType.BANG_EQ, AstFactory.identifier3("j"));
- _resolveNode(expression);
- var stringElement = stringType.element;
- expect(expression.staticElement, isNotNull);
- expect(
- expression.staticElement,
- stringElement.lookUpMethod(
- TokenType.EQ_EQ.lexeme, stringElement.library));
- expect(expression.propagatedElement, isNull);
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_eq() {
- // String i;
- // var j;
- // i == j
- InterfaceType stringType = _typeProvider.stringType;
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.staticType = stringType;
- BinaryExpression expression = AstFactory.binaryExpression(
- left, TokenType.EQ_EQ, AstFactory.identifier3("j"));
- _resolveNode(expression);
- var stringElement = stringType.element;
- expect(
- expression.staticElement,
- stringElement.lookUpMethod(
- TokenType.EQ_EQ.lexeme, stringElement.library));
- expect(expression.propagatedElement, isNull);
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_plus() {
- // num i;
- // var j;
- // i + j
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.staticType = numType;
- BinaryExpression expression = AstFactory.binaryExpression(
- left, TokenType.PLUS, AstFactory.identifier3("j"));
- _resolveNode(expression);
- expect(expression.staticElement, getMethod(numType, "+"));
- expect(expression.propagatedElement, isNull);
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_plus_propagatedElement() {
- // var i = 1;
- // var j;
- // i + j
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.propagatedType = numType;
- BinaryExpression expression = AstFactory.binaryExpression(
- left, TokenType.PLUS, AstFactory.identifier3("j"));
- _resolveNode(expression);
- expect(expression.staticElement, isNull);
- expect(expression.propagatedElement, getMethod(numType, "+"));
- _listener.assertNoErrors();
- }
-
- void test_visitBreakStatement_withLabel() {
- // loop: while (true) {
- // break loop;
- // }
- String label = "loop";
- LabelElementImpl labelElement = new LabelElementImpl.forNode(
- AstFactory.identifier3(label), false, false);
- BreakStatement breakStatement = AstFactory.breakStatement2(label);
- Expression condition = AstFactory.booleanLiteral(true);
- WhileStatement whileStatement =
- AstFactory.whileStatement(condition, breakStatement);
- expect(_resolveBreak(breakStatement, labelElement, whileStatement),
- same(labelElement));
- expect(breakStatement.target, same(whileStatement));
- _listener.assertNoErrors();
- }
-
- void test_visitBreakStatement_withoutLabel() {
- BreakStatement statement = AstFactory.breakStatement();
- _resolveStatement(statement, null, null);
- _listener.assertNoErrors();
- }
-
- void test_visitCommentReference_prefixedIdentifier_class_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- // set accessors
- String propName = "p";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(propName, false, _typeProvider.intType);
- PropertyAccessorElement setter =
- ElementFactory.setterElement(propName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter, setter];
- // set name scope
- _visitor.nameScope = new EnclosedScope(null)
- ..defineNameWithoutChecking('A', classA);
- // prepare "A.p"
- PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'p');
- CommentReference commentReference = new CommentReference(null, prefixed);
- // resolve
- _resolveNode(commentReference);
- expect(prefixed.prefix.staticElement, classA);
- expect(prefixed.identifier.staticElement, getter);
- _listener.assertNoErrors();
- }
-
- void test_visitCommentReference_prefixedIdentifier_class_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- // set method
- MethodElement method =
- ElementFactory.methodElement("m", _typeProvider.intType);
- classA.methods = <MethodElement>[method];
- // set name scope
- _visitor.nameScope = new EnclosedScope(null)
- ..defineNameWithoutChecking('A', classA);
- // prepare "A.m"
- PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'm');
- CommentReference commentReference = new CommentReference(null, prefixed);
- // resolve
- _resolveNode(commentReference);
- expect(prefixed.prefix.staticElement, classA);
- expect(prefixed.identifier.staticElement, method);
- _listener.assertNoErrors();
- }
-
- void test_visitConstructorName_named() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = "a";
- ConstructorElement constructor =
- ElementFactory.constructorElement2(classA, constructorName);
- classA.constructors = <ConstructorElement>[constructor];
- ConstructorName name = AstFactory.constructorName(
- AstFactory.typeName(classA), constructorName);
- _resolveNode(name);
- expect(name.staticElement, same(constructor));
- _listener.assertNoErrors();
- }
-
- void test_visitConstructorName_unnamed() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = null;
- ConstructorElement constructor =
- ElementFactory.constructorElement2(classA, constructorName);
- classA.constructors = <ConstructorElement>[constructor];
- ConstructorName name = AstFactory.constructorName(
- AstFactory.typeName(classA), constructorName);
- _resolveNode(name);
- expect(name.staticElement, same(constructor));
- _listener.assertNoErrors();
- }
-
- void test_visitContinueStatement_withLabel() {
- // loop: while (true) {
- // continue loop;
- // }
- String label = "loop";
- LabelElementImpl labelElement = new LabelElementImpl.forNode(
- AstFactory.identifier3(label), false, false);
- ContinueStatement continueStatement = AstFactory.continueStatement(label);
- Expression condition = AstFactory.booleanLiteral(true);
- WhileStatement whileStatement =
- AstFactory.whileStatement(condition, continueStatement);
- expect(_resolveContinue(continueStatement, labelElement, whileStatement),
- same(labelElement));
- expect(continueStatement.target, same(whileStatement));
- _listener.assertNoErrors();
- }
-
- void test_visitContinueStatement_withoutLabel() {
- ContinueStatement statement = AstFactory.continueStatement();
- _resolveStatement(statement, null, null);
- _listener.assertNoErrors();
- }
-
- void test_visitEnumDeclaration() {
- CompilationUnitElementImpl compilationUnitElement =
- ElementFactory.compilationUnit('foo.dart');
- ClassElementImpl enumElement =
- ElementFactory.enumElement(_typeProvider, ('E'));
- compilationUnitElement.enums = <ClassElement>[enumElement];
- EnumDeclaration enumNode = AstFactory.enumDeclaration2('E', []);
- Annotation annotationNode =
- AstFactory.annotation(AstFactory.identifier3('a'));
- annotationNode.element = ElementFactory.classElement2('A');
- annotationNode.elementAnnotation =
- new ElementAnnotationImpl(compilationUnitElement);
- enumNode.metadata.add(annotationNode);
- enumNode.name.staticElement = enumElement;
- List<ElementAnnotation> metadata = <ElementAnnotation>[
- annotationNode.elementAnnotation
- ];
- _resolveNode(enumNode);
- expect(metadata[0].element, annotationNode.element);
- }
-
- void test_visitExportDirective_noCombinators() {
- ExportDirective directive = AstFactory.exportDirective2(null);
- directive.element = ElementFactory
- .exportFor(ElementFactory.library(_definingLibrary.context, "lib"));
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void test_visitFieldFormalParameter() {
- String fieldName = "f";
- InterfaceType intType = _typeProvider.intType;
- FieldElementImpl fieldElement =
- ElementFactory.fieldElement(fieldName, false, false, false, intType);
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.fields = <FieldElement>[fieldElement];
- FieldFormalParameter parameter =
- AstFactory.fieldFormalParameter2(fieldName);
- FieldFormalParameterElementImpl parameterElement =
- ElementFactory.fieldFormalParameter(parameter.identifier);
- parameterElement.field = fieldElement;
- parameterElement.type = intType;
- parameter.identifier.staticElement = parameterElement;
- _resolveInClass(parameter, classA);
- expect(parameter.element.type, same(intType));
- }
-
- void test_visitImportDirective_noCombinators_noPrefix() {
- ImportDirective directive = AstFactory.importDirective3(null, null);
- directive.element = ElementFactory.importFor(
- ElementFactory.library(_definingLibrary.context, "lib"), null);
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void test_visitImportDirective_noCombinators_prefix() {
- String prefixName = "p";
- ImportElement importElement = ElementFactory.importFor(
- ElementFactory.library(_definingLibrary.context, "lib"),
- ElementFactory.prefix(prefixName));
- _definingLibrary.imports = <ImportElement>[importElement];
- ImportDirective directive = AstFactory.importDirective3(null, prefixName);
- directive.element = importElement;
- _resolveNode(directive);
- _listener.assertNoErrors();
- }
-
- void test_visitImportDirective_withCombinators() {
- ShowCombinator combinator = AstFactory.showCombinator2(["A", "B", "C"]);
- ImportDirective directive =
- AstFactory.importDirective3(null, null, [combinator]);
- LibraryElementImpl library =
- ElementFactory.library(_definingLibrary.context, "lib");
- TopLevelVariableElementImpl varA =
- ElementFactory.topLevelVariableElement2("A");
- TopLevelVariableElementImpl varB =
- ElementFactory.topLevelVariableElement2("B");
- TopLevelVariableElementImpl varC =
- ElementFactory.topLevelVariableElement2("C");
- CompilationUnitElementImpl unit =
- library.definingCompilationUnit as CompilationUnitElementImpl;
- unit.accessors = <PropertyAccessorElement>[
- varA.getter,
- varA.setter,
- varB.getter,
- varC.setter
- ];
- unit.topLevelVariables = <TopLevelVariableElement>[varA, varB, varC];
- directive.element = ElementFactory.importFor(library, null);
- _resolveNode(directive);
- expect(combinator.shownNames[0].staticElement, same(varA));
- expect(combinator.shownNames[1].staticElement, same(varB));
- expect(combinator.shownNames[2].staticElement, same(varC));
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_get() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType intType = _typeProvider.intType;
- MethodElement getter =
- ElementFactory.methodElement("[]", intType, [intType]);
- classA.methods = <MethodElement>[getter];
- SimpleIdentifier array = AstFactory.identifier3("a");
- array.staticType = classA.type;
- IndexExpression expression =
- AstFactory.indexExpression(array, AstFactory.identifier3("i"));
- expect(_resolveIndexExpression(expression), same(getter));
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_set() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType intType = _typeProvider.intType;
- MethodElement setter =
- ElementFactory.methodElement("[]=", intType, [intType]);
- classA.methods = <MethodElement>[setter];
- SimpleIdentifier array = AstFactory.identifier3("a");
- array.staticType = classA.type;
- IndexExpression expression =
- AstFactory.indexExpression(array, AstFactory.identifier3("i"));
- AstFactory.assignmentExpression(
- expression, TokenType.EQ, AstFactory.integer(0));
- expect(_resolveIndexExpression(expression), same(setter));
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_named() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = "a";
- ConstructorElement constructor =
- ElementFactory.constructorElement2(classA, constructorName);
- classA.constructors = <ConstructorElement>[constructor];
- ConstructorName name = AstFactory.constructorName(
- AstFactory.typeName(classA), constructorName);
- name.staticElement = constructor;
- InstanceCreationExpression creation =
- AstFactory.instanceCreationExpression(Keyword.NEW, name);
- _resolveNode(creation);
- expect(creation.staticElement, same(constructor));
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_unnamed() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = null;
- ConstructorElement constructor =
- ElementFactory.constructorElement2(classA, constructorName);
- classA.constructors = <ConstructorElement>[constructor];
- ConstructorName name = AstFactory.constructorName(
- AstFactory.typeName(classA), constructorName);
- name.staticElement = constructor;
- InstanceCreationExpression creation =
- AstFactory.instanceCreationExpression(Keyword.NEW, name);
- _resolveNode(creation);
- expect(creation.staticElement, same(constructor));
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_unnamed_namedParameter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String constructorName = null;
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(classA, constructorName);
- String parameterName = "a";
- ParameterElement parameter = ElementFactory.namedParameter(parameterName);
- constructor.parameters = <ParameterElement>[parameter];
- classA.constructors = <ConstructorElement>[constructor];
- ConstructorName name = AstFactory.constructorName(
- AstFactory.typeName(classA), constructorName);
- name.staticElement = constructor;
- InstanceCreationExpression creation = AstFactory.instanceCreationExpression(
- Keyword.NEW,
- name,
- [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
- _resolveNode(creation);
- expect(creation.staticElement, same(constructor));
- expect(
- (creation.argumentList.arguments[0] as NamedExpression)
- .name
- .label
- .staticElement,
- same(parameter));
- _listener.assertNoErrors();
- }
-
- void test_visitMethodInvocation() {
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.staticType = numType;
- String methodName = "abs";
- MethodInvocation invocation = AstFactory.methodInvocation(left, methodName);
- _resolveNode(invocation);
- expect(invocation.methodName.staticElement,
- same(getMethod(numType, methodName)));
- _listener.assertNoErrors();
- }
-
- void test_visitMethodInvocation_namedParameter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- String parameterName = "p";
- MethodElementImpl method = ElementFactory.methodElement(methodName, null);
- ParameterElement parameter = ElementFactory.namedParameter(parameterName);
- method.parameters = <ParameterElement>[parameter];
- classA.methods = <MethodElement>[method];
- SimpleIdentifier left = AstFactory.identifier3("i");
- left.staticType = classA.type;
- MethodInvocation invocation = AstFactory.methodInvocation(left, methodName,
- [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
- _resolveNode(invocation);
- expect(invocation.methodName.staticElement, same(method));
- expect(
- (invocation.argumentList.arguments[0] as NamedExpression)
- .name
- .label
- .staticElement,
- same(parameter));
- _listener.assertNoErrors();
- }
-
- void test_visitPostfixExpression() {
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier operand = AstFactory.identifier3("i");
- operand.staticType = numType;
- PostfixExpression expression =
- AstFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
- _resolveNode(expression);
- expect(expression.staticElement, getMethod(numType, "+"));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_dynamic() {
- DartType dynamicType = _typeProvider.dynamicType;
- SimpleIdentifier target = AstFactory.identifier3("a");
- VariableElementImpl variable = ElementFactory.localVariableElement(target);
- variable.type = dynamicType;
- target.staticElement = variable;
- target.staticType = dynamicType;
- PrefixedIdentifier identifier =
- AstFactory.identifier(target, AstFactory.identifier3("b"));
- _resolveNode(identifier);
- expect(identifier.staticElement, isNull);
- expect(identifier.identifier.staticElement, isNull);
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_nonDynamic() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "b";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter];
- SimpleIdentifier target = AstFactory.identifier3("a");
- VariableElementImpl variable = ElementFactory.localVariableElement(target);
- variable.type = classA.type;
- target.staticElement = variable;
- target.staticType = classA.type;
- PrefixedIdentifier identifier =
- AstFactory.identifier(target, AstFactory.identifier3(getterName));
- _resolveNode(identifier);
- expect(identifier.staticElement, same(getter));
- expect(identifier.identifier.staticElement, same(getter));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_staticClassMember_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- // set accessors
- String propName = "b";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(propName, false, _typeProvider.intType);
- PropertyAccessorElement setter =
- ElementFactory.setterElement(propName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter, setter];
- // prepare "A.m"
- SimpleIdentifier target = AstFactory.identifier3("A");
- target.staticElement = classA;
- target.staticType = classA.type;
- PrefixedIdentifier identifier =
- AstFactory.identifier(target, AstFactory.identifier3(propName));
- // resolve
- _resolveNode(identifier);
- expect(identifier.staticElement, same(getter));
- expect(identifier.identifier.staticElement, same(getter));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_staticClassMember_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- // set methods
- String propName = "m";
- MethodElement method =
- ElementFactory.methodElement("m", _typeProvider.intType);
- classA.methods = <MethodElement>[method];
- // prepare "A.m"
- SimpleIdentifier target = AstFactory.identifier3("A");
- target.staticElement = classA;
- target.staticType = classA.type;
- PrefixedIdentifier identifier =
- AstFactory.identifier(target, AstFactory.identifier3(propName));
- AstFactory.assignmentExpression(
- identifier, TokenType.EQ, AstFactory.nullLiteral());
- // resolve
- _resolveNode(identifier);
- expect(identifier.staticElement, same(method));
- expect(identifier.identifier.staticElement, same(method));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_staticClassMember_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- // set accessors
- String propName = "b";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(propName, false, _typeProvider.intType);
- PropertyAccessorElement setter =
- ElementFactory.setterElement(propName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter, setter];
- // prepare "A.b = null"
- SimpleIdentifier target = AstFactory.identifier3("A");
- target.staticElement = classA;
- target.staticType = classA.type;
- PrefixedIdentifier identifier =
- AstFactory.identifier(target, AstFactory.identifier3(propName));
- AstFactory.assignmentExpression(
- identifier, TokenType.EQ, AstFactory.nullLiteral());
- // resolve
- _resolveNode(identifier);
- expect(identifier.staticElement, same(setter));
- expect(identifier.identifier.staticElement, same(setter));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression() {
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier operand = AstFactory.identifier3("i");
- operand.staticType = numType;
- PrefixExpression expression =
- AstFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
- _resolveNode(expression);
- expect(expression.staticElement, getMethod(numType, "+"));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_getter_identifier() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "b";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter];
- SimpleIdentifier target = AstFactory.identifier3("a");
- target.staticType = classA.type;
- PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
- _resolveNode(access);
- expect(access.propertyName.staticElement, same(getter));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_getter_super() {
- //
- // class A {
- // int get b;
- // }
- // class B {
- // ... super.m ...
- // }
- //
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "b";
- PropertyAccessorElement getter =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getter];
- SuperExpression target = AstFactory.superExpression();
- target.staticType = ElementFactory.classElement("B", classA.type).type;
- PropertyAccess access = AstFactory.propertyAccess2(target, getterName);
- AstFactory.methodDeclaration2(
- null,
- null,
- null,
- null,
- AstFactory.identifier3("m"),
- AstFactory.formalParameterList(),
- AstFactory.expressionFunctionBody(access));
- _resolveNode(access);
- expect(access.propertyName.staticElement, same(getter));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_setter_this() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "b";
- PropertyAccessorElement setter =
- ElementFactory.setterElement(setterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setter];
- ThisExpression target = AstFactory.thisExpression();
- target.staticType = classA.type;
- PropertyAccess access = AstFactory.propertyAccess2(target, setterName);
- AstFactory.assignmentExpression(
- access, TokenType.EQ, AstFactory.integer(0));
- _resolveNode(access);
- expect(access.propertyName.staticElement, same(setter));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleIdentifier_classScope() {
- InterfaceType doubleType = _typeProvider.doubleType;
- String fieldName = "NAN";
- SimpleIdentifier node = AstFactory.identifier3(fieldName);
- _resolveInClass(node, doubleType.element);
- expect(node.staticElement, getGetter(doubleType, fieldName));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleIdentifier_dynamic() {
- SimpleIdentifier node = AstFactory.identifier3("dynamic");
- _resolveIdentifier(node);
- expect(node.staticElement, same(_typeProvider.dynamicType.element));
- expect(node.staticType, same(_typeProvider.typeType));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleIdentifier_lexicalScope() {
- SimpleIdentifier node = AstFactory.identifier3("i");
- VariableElementImpl element = ElementFactory.localVariableElement(node);
- expect(_resolveIdentifier(node, [element]), same(element));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleIdentifier_lexicalScope_field_setter() {
- InterfaceType intType = _typeProvider.intType;
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String fieldName = "a";
- FieldElement field =
- ElementFactory.fieldElement(fieldName, false, false, false, intType);
- classA.fields = <FieldElement>[field];
- classA.accessors = <PropertyAccessorElement>[field.getter, field.setter];
- SimpleIdentifier node = AstFactory.identifier3(fieldName);
- AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
- _resolveInClass(node, classA);
- Element element = node.staticElement;
- EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
- PropertyAccessorElement, element);
- expect((element as PropertyAccessorElement).isSetter, isTrue);
- _listener.assertNoErrors();
- }
-
- void test_visitSuperConstructorInvocation() {
- ClassElementImpl superclass = ElementFactory.classElement2("A");
- ConstructorElementImpl superConstructor =
- ElementFactory.constructorElement2(superclass, null);
- superclass.constructors = <ConstructorElement>[superConstructor];
- ClassElementImpl subclass =
- ElementFactory.classElement("B", superclass.type);
- ConstructorElementImpl subConstructor =
- ElementFactory.constructorElement2(subclass, null);
- subclass.constructors = <ConstructorElement>[subConstructor];
- SuperConstructorInvocation invocation =
- AstFactory.superConstructorInvocation();
- _resolveInClass(invocation, subclass);
- expect(invocation.staticElement, superConstructor);
- _listener.assertNoErrors();
- }
-
- void test_visitSuperConstructorInvocation_namedParameter() {
- ClassElementImpl superclass = ElementFactory.classElement2("A");
- ConstructorElementImpl superConstructor =
- ElementFactory.constructorElement2(superclass, null);
- String parameterName = "p";
- ParameterElement parameter = ElementFactory.namedParameter(parameterName);
- superConstructor.parameters = <ParameterElement>[parameter];
- superclass.constructors = <ConstructorElement>[superConstructor];
- ClassElementImpl subclass =
- ElementFactory.classElement("B", superclass.type);
- ConstructorElementImpl subConstructor =
- ElementFactory.constructorElement2(subclass, null);
- subclass.constructors = <ConstructorElement>[subConstructor];
- SuperConstructorInvocation invocation = AstFactory
- .superConstructorInvocation([
- AstFactory.namedExpression2(parameterName, AstFactory.integer(0))
- ]);
- _resolveInClass(invocation, subclass);
- expect(invocation.staticElement, superConstructor);
- expect(
- (invocation.argumentList.arguments[0] as NamedExpression)
- .name
- .label
- .staticElement,
- same(parameter));
- _listener.assertNoErrors();
- }
-
- /**
- * Create the resolver used by the tests.
- *
- * @return the resolver that was created
- */
- ElementResolver _createResolver() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- FileBasedSource source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- CompilationUnitElementImpl definingCompilationUnit =
- new CompilationUnitElementImpl("test.dart");
- definingCompilationUnit.librarySource =
- definingCompilationUnit.source = source;
- _definingLibrary = ElementFactory.library(context, "test");
- _definingLibrary.definingCompilationUnit = definingCompilationUnit;
- _visitor = new ResolverVisitor(
- _definingLibrary, source, _typeProvider, _listener,
- nameScope: new LibraryScope(_definingLibrary, _listener));
- try {
- return _visitor.elementResolver;
- } catch (exception) {
- throw new IllegalArgumentException(
- "Could not create resolver", exception);
- }
- }
-
- /**
- * Return the element associated with the label of [statement] after the
- * resolver has resolved it. [labelElement] is the label element to be
- * defined in the statement's label scope, and [labelTarget] is the statement
- * the label resolves to.
- */
- Element _resolveBreak(BreakStatement statement, LabelElementImpl labelElement,
- Statement labelTarget) {
- _resolveStatement(statement, labelElement, labelTarget);
- return statement.label.staticElement;
- }
-
- /**
- * Return the element associated with the label [statement] after the
- * resolver has resolved it. [labelElement] is the label element to be
- * defined in the statement's label scope, and [labelTarget] is the AST node
- * the label resolves to.
- *
- * @param statement the statement to be resolved
- * @param labelElement the label element to be defined in the statement's label scope
- * @return the element to which the statement's label was resolved
- */
- Element _resolveContinue(ContinueStatement statement,
- LabelElementImpl labelElement, AstNode labelTarget) {
- _resolveStatement(statement, labelElement, labelTarget);
- return statement.label.staticElement;
- }
-
- /**
- * Return the element associated with the given identifier after the resolver has resolved the
- * identifier.
- *
- * @param node the expression to be resolved
- * @param definedElements the elements that are to be defined in the scope in which the element is
- * being resolved
- * @return the element to which the expression was resolved
- */
- Element _resolveIdentifier(Identifier node, [List<Element> definedElements]) {
- _resolveNode(node, definedElements);
- return node.staticElement;
- }
-
- /**
- * Return the element associated with the given identifier after the resolver has resolved the
- * identifier.
- *
- * @param node the expression to be resolved
- * @param enclosingClass the element representing the class enclosing the identifier
- * @return the element to which the expression was resolved
- */
- void _resolveInClass(AstNode node, ClassElement enclosingClass) {
- try {
- Scope outerScope = _visitor.nameScope;
- try {
- _visitor.enclosingClass = enclosingClass;
- EnclosedScope innerScope = new ClassScope(
- new TypeParameterScope(outerScope, enclosingClass), enclosingClass);
- _visitor.nameScope = innerScope;
- node.accept(_resolver);
- } finally {
- _visitor.enclosingClass = null;
- _visitor.nameScope = outerScope;
- }
- } catch (exception) {
- throw new IllegalArgumentException("Could not resolve node", exception);
- }
- }
-
- /**
- * Return the element associated with the given expression after the resolver has resolved the
- * expression.
- *
- * @param node the expression to be resolved
- * @param definedElements the elements that are to be defined in the scope in which the element is
- * being resolved
- * @return the element to which the expression was resolved
- */
- Element _resolveIndexExpression(IndexExpression node,
- [List<Element> definedElements]) {
- _resolveNode(node, definedElements);
- return node.staticElement;
- }
-
- /**
- * Return the element associated with the given identifier after the resolver has resolved the
- * identifier.
- *
- * @param node the expression to be resolved
- * @param definedElements the elements that are to be defined in the scope in which the element is
- * being resolved
- * @return the element to which the expression was resolved
- */
- void _resolveNode(AstNode node, [List<Element> definedElements]) {
- try {
- Scope outerScope = _visitor.nameScope;
- try {
- EnclosedScope innerScope = new EnclosedScope(outerScope);
- if (definedElements != null) {
- for (Element element in definedElements) {
- innerScope.define(element);
- }
- }
- _visitor.nameScope = innerScope;
- node.accept(_resolver);
- } finally {
- _visitor.nameScope = outerScope;
- }
- } catch (exception) {
- throw new IllegalArgumentException("Could not resolve node", exception);
- }
- }
-
- /**
- * Return the element associated with the label of the given statement after the resolver has
- * resolved the statement.
- *
- * @param statement the statement to be resolved
- * @param labelElement the label element to be defined in the statement's label scope
- * @return the element to which the statement's label was resolved
- */
- void _resolveStatement(
- Statement statement, LabelElementImpl labelElement, AstNode labelTarget) {
- try {
- LabelScope outerScope = _visitor.labelScope;
- try {
- LabelScope innerScope;
- if (labelElement == null) {
- innerScope = outerScope;
- } else {
- innerScope = new LabelScope(
- outerScope, labelElement.name, labelTarget, labelElement);
- }
- _visitor.labelScope = innerScope;
- statement.accept(_resolver);
- } finally {
- _visitor.labelScope = outerScope;
- }
- } catch (exception) {
- throw new IllegalArgumentException("Could not resolve node", exception);
- }
- }
-}
-
-@reflectiveTest
class EnclosedScopeTest extends ResolverTestCase {
void test_define_duplicate() {
GatheringErrorListener listener = new GatheringErrorListener();
@@ -2372,7 +288,7 @@
* Tests for generic method and function resolution that do not use strong mode.
*/
@reflectiveTest
-class GenericMethodResolverTest extends _StaticTypeAnalyzer2TestShared {
+class GenericMethodResolverTest extends StaticTypeAnalyzer2TestShared {
void setUp() {
super.setUp();
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
@@ -2389,7 +305,7 @@
// therefore discard the propagated type.
//
// So this test does not use strong mode.
- _resolveTestUnit(r'''
+ resolveTestUnit(r'''
abstract class Iter {
List<S> map<S>(S f(x));
}
@@ -2400,4209 +316,7 @@
}
return null;
}''');
- _expectIdentifierType('y = ', 'dynamic', 'List<dynamic>');
- }
-}
-
-@reflectiveTest
-class HintCodeTest extends ResolverTestCase {
- void fail_deadCode_statementAfterRehrow() {
- Source source = addSource(r'''
-f() {
- try {
- var one = 1;
- } catch (e) {
- rethrow;
- var two = 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void fail_deadCode_statementAfterThrow() {
- Source source = addSource(r'''
-f() {
- var one = 1;
- throw 'Stop here';
- var two = 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void fail_isInt() {
- Source source = addSource("var v = 1 is int;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.IS_INT]);
- verify([source]);
- }
-
- void fail_isNotInt() {
- Source source = addSource("var v = 1 is! int;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.IS_NOT_INT]);
- verify([source]);
- }
-
- void fail_overrideEqualsButNotHashCode() {
- Source source = addSource(r'''
-class A {
- bool operator ==(x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
- verify([source]);
- }
-
- void fail_unusedImport_as_equalPrefixes() {
- // See todo at ImportsVerifier.prefixElementMap.
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' as one;
-import 'lib2.dart' as one;
-one.A a;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- Source source3 = addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-class B {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_IMPORT]);
- assertNoErrors(source2);
- assertNoErrors(source3);
- verify([source, source2, source3]);
- }
-
- @override
- void reset() {
- analysisContext2 = AnalysisContextFactory.contextWithCoreAndPackages({
- 'package:meta/meta.dart': r'''
-library meta;
-
-const _Factory factory = const _Factory();
-const _Literal literal = const _Literal();
-const _MustCallSuper mustCallSuper = const _MustCallSuper();
-const _Override override = const _Override();
-const _Protected protected = const _Protected();
-const _Required required = const _Required();
-
-class _Factory {
- const _Factory();
-}
-class _Literal {
- const _Literal();
-}
-class _MustCallSuper {
- const _MustCallSuper();
-}
-class _Override {
- const _Override();
-}
-class _Protected {
- const _Protected();
-}
-class _Required {
- final String reason;
- const _Required([this.reason]));
-}
-'''
- });
- }
-
- void test_argumentTypeNotAssignable_functionType() {
- Source source = addSource(r'''
-m() {
- var a = new A();
- a.n(() => 0);
-}
-class A {
- n(void f(int i)) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- verify([source]);
- }
-
- void test_argumentTypeNotAssignable_message() {
- // The implementation of HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE assumes that
- // StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE has the same message.
- expect(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message,
- HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE.message);
- }
-
- void test_argumentTypeNotAssignable_type() {
- Source source = addSource(r'''
-m() {
- var i = '';
- n(i);
-}
-n(int i) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- verify([source]);
- }
-
- void test_canBeNullAfterNullAware_false_methodInvocation() {
- Source source = addSource(r'''
-m(x) {
- x?.a()?.b();
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_canBeNullAfterNullAware_false_propertyAccess() {
- Source source = addSource(r'''
-m(x) {
- x?.a?.b;
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_canBeNullAfterNullAware_methodInvocation() {
- Source source = addSource(r'''
-m(x) {
- x?.a.b();
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
- verify([source]);
- }
-
- void test_canBeNullAfterNullAware_parenthesized() {
- Source source = addSource(r'''
-m(x) {
- (x?.a).b;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
- verify([source]);
- }
-
- void test_canBeNullAfterNullAware_propertyAccess() {
- Source source = addSource(r'''
-m(x) {
- x?.a.b;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_conditionalElse() {
- Source source = addSource(r'''
-f() {
- true ? 1 : 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_conditionalElse_nested() {
- // test that a dead else-statement can't generate additional violations
- Source source = addSource(r'''
-f() {
- true ? true : false && false;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_conditionalIf() {
- Source source = addSource(r'''
-f() {
- false ? 1 : 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_conditionalIf_nested() {
- // test that a dead then-statement can't generate additional violations
- Source source = addSource(r'''
-f() {
- false ? false && false : true;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_else() {
- Source source = addSource(r'''
-f() {
- if(true) {} else {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_else_nested() {
- // test that a dead else-statement can't generate additional violations
- Source source = addSource(r'''
-f() {
- if(true) {} else {if (false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if() {
- Source source = addSource(r'''
-f() {
- if(false) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if_nested() {
- // test that a dead then-statement can't generate additional violations
- Source source = addSource(r'''
-f() {
- if(false) {if(false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_while() {
- Source source = addSource(r'''
-f() {
- while(false) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_while_nested() {
- // test that a dead while body can't generate additional violations
- Source source = addSource(r'''
-f() {
- while(false) {if(false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_catchFollowingCatch() {
- Source source = addSource(r'''
-class A {}
-f() {
- try {} catch (e) {} catch (e) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_catchFollowingCatch_nested() {
- // test that a dead catch clause can't generate additional violations
- Source source = addSource(r'''
-class A {}
-f() {
- try {} catch (e) {} catch (e) {if(false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_catchFollowingCatch_object() {
- Source source = addSource(r'''
-f() {
- try {} on Object catch (e) {} catch (e) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_catchFollowingCatch_object_nested() {
- // test that a dead catch clause can't generate additional violations
- Source source = addSource(r'''
-f() {
- try {} on Object catch (e) {} catch (e) {if(false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_onCatchSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {}
-f() {
- try {} on A catch (e) {} on B catch (e) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_onCatchSubtype_nested() {
- // test that a dead catch clause can't generate additional violations
- Source source = addSource(r'''
-class A {}
-class B extends A {}
-f() {
- try {} on A catch (e) {} on B catch (e) {if(false) {}}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE_ON_CATCH_SUBTYPE]);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_and() {
- Source source = addSource(r'''
-f() {
- bool b = false && false;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_and_nested() {
- Source source = addSource(r'''
-f() {
- bool b = false && (false && false);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_or() {
- Source source = addSource(r'''
-f() {
- bool b = true || true;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_or_nested() {
- Source source = addSource(r'''
-f() {
- bool b = true || (false && false);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterBreak_inDefaultCase() {
- Source source = addSource(r'''
-f(v) {
- switch(v) {
- case 1:
- default:
- break;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterBreak_inForEachStatement() {
- Source source = addSource(r'''
-f() {
- var list;
- for(var l in list) {
- break;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterBreak_inForStatement() {
- Source source = addSource(r'''
-f() {
- for(;;) {
- break;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterBreak_inSwitchCase() {
- Source source = addSource(r'''
-f(v) {
- switch(v) {
- case 1:
- break;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterBreak_inWhileStatement() {
- Source source = addSource(r'''
-f(v) {
- while(v) {
- break;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterContinue_inForEachStatement() {
- Source source = addSource(r'''
-f() {
- var list;
- for(var l in list) {
- continue;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterContinue_inForStatement() {
- Source source = addSource(r'''
-f() {
- for(;;) {
- continue;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterContinue_inWhileStatement() {
- Source source = addSource(r'''
-f(v) {
- while(v) {
- continue;
- var a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterReturn_function() {
- Source source = addSource(r'''
-f() {
- var one = 1;
- return;
- var two = 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterReturn_ifStatement() {
- Source source = addSource(r'''
-f(bool b) {
- if(b) {
- var one = 1;
- return;
- var two = 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterReturn_method() {
- Source source = addSource(r'''
-class A {
- m() {
- var one = 1;
- return;
- var two = 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterReturn_nested() {
- Source source = addSource(r'''
-f() {
- var one = 1;
- return;
- if(false) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deadCode_statementAfterReturn_twoReturns() {
- Source source = addSource(r'''
-f() {
- var one = 1;
- return;
- var two = 2;
- return;
- var three = 3;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_assignment() {
- Source source = addSource(r'''
-class A {
- @deprecated
- A operator+(A a) { return a; }
-}
-f(A a) {
- A b;
- a += b;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_Deprecated() {
- Source source = addSource(r'''
-class A {
- @Deprecated('0.9')
- m() {}
- n() {m();}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_deprecated() {
- Source source = addSource(r'''
-class A {
- @deprecated
- m() {}
- n() {m();}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_export() {
- Source source = addSource("export 'deprecated_library.dart';");
- addNamedSource(
- "/deprecated_library.dart",
- r'''
-@deprecated
-library deprecated_library;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_getter() {
- Source source = addSource(r'''
-class A {
- @deprecated
- get m => 1;
-}
-f(A a) {
- return a.m;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_import() {
- Source source = addSource(r'''
-import 'deprecated_library.dart';
-f(A a) {}''');
- addNamedSource(
- "/deprecated_library.dart",
- r'''
-@deprecated
-library deprecated_library;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_indexExpression() {
- Source source = addSource(r'''
-class A {
- @deprecated
- operator[](int i) {}
-}
-f(A a) {
- return a[1];
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_instanceCreation() {
- Source source = addSource(r'''
-class A {
- @deprecated
- A(int i) {}
-}
-f() {
- A a = new A(1);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_instanceCreation_namedConstructor() {
- Source source = addSource(r'''
-class A {
- @deprecated
- A.named(int i) {}
-}
-f() {
- A a = new A.named(1);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_operator() {
- Source source = addSource(r'''
-class A {
- @deprecated
- operator+(A a) {}
-}
-f(A a) {
- A b;
- return a + b;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_setter() {
- Source source = addSource(r'''
-class A {
- @deprecated
- set s(v) {}
-}
-f(A a) {
- return a.s = 1;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_superConstructor() {
- Source source = addSource(r'''
-class A {
- @deprecated
- A() {}
-}
-class B extends A {
- B() : super() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_superConstructor_namedConstructor() {
- Source source = addSource(r'''
-class A {
- @deprecated
- A.named() {}
-}
-class B extends A {
- B() : super.named() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
- verify([source]);
- }
-
- void test_divisionOptimization_double() {
- Source source = addSource(r'''
-f(double x, double y) {
- var v = (x / y).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
- verify([source]);
- }
-
- void test_divisionOptimization_int() {
- Source source = addSource(r'''
-f(int x, int y) {
- var v = (x / y).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
- verify([source]);
- }
-
- void test_divisionOptimization_propagatedType() {
- // Tests the propagated type information of the '/' method
- Source source = addSource(r'''
-f(x, y) {
- x = 1;
- y = 1;
- var v = (x / y).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
- verify([source]);
- }
-
- void test_divisionOptimization_wrappedBinaryExpression() {
- Source source = addSource(r'''
-f(int x, int y) {
- var v = (((x / y))).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
- verify([source]);
- }
-
- void test_duplicateImport() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart';
-A a;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
- verify([source]);
- }
-
- void test_duplicateImport2() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart';
-import 'lib1.dart';
-A a;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]);
- verify([source]);
- }
-
- void test_duplicateImport3() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' as M show A hide B;
-import 'lib1.dart' as M show A hide B;
-M.A a;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DUPLICATE_IMPORT]);
- verify([source]);
- }
-
- void test_importDeferredLibraryWithLoadFunction() {
- resolveWithErrors(<String>[
- r'''
-library lib1;
-loadLibrary() {}
-f() {}''',
- r'''
-library root;
-import 'lib1.dart' deferred as lib1;
-main() { lib1.f(); }'''
- ], <ErrorCode>[
- HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION
- ]);
- }
-
- void test_invalidAssignment_instanceVariable() {
- Source source = addSource(r'''
-class A {
- int x;
-}
-f(var y) {
- A a;
- if(y is String) {
- a.x = y;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_invalidAssignment_localVariable() {
- Source source = addSource(r'''
-f(var y) {
- if(y is String) {
- int x = y;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_invalidAssignment_message() {
- // The implementation of HintCode.INVALID_ASSIGNMENT assumes that
- // StaticTypeWarningCode.INVALID_ASSIGNMENT has the same message.
- expect(StaticTypeWarningCode.INVALID_ASSIGNMENT.message,
- HintCode.INVALID_ASSIGNMENT.message);
- }
-
- void test_invalidAssignment_staticVariable() {
- Source source = addSource(r'''
-class A {
- static int x;
-}
-f(var y) {
- if(y is String) {
- A.x = y;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_invalidAssignment_variableDeclaration() {
- // 17971
- Source source = addSource(r'''
-class Point {
- final num x, y;
- Point(this.x, this.y);
- Point operator +(Point other) {
- return new Point(x+other.x, y+other.y);
- }
-}
-main() {
- var p1 = new Point(0, 0);
- var p2 = new Point(10, 10);
- int n = p1 + p2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_field() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- int a;
-}
-abstract class B implements A {
- int b() => a;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_function() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-main() {
- new A().a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_getter() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- int get a => 42;
-}
-abstract class B implements A {
- int b() => a;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_message() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-class B {
- void b() => new A().a();
-}''');
- List<AnalysisError> errors = analysisContext2.computeErrors(source);
- expect(errors, hasLength(1));
- expect(errors[0].message,
- "The member 'a' can only be used within instance members of subclasses of 'A'");
- }
-
- void test_invalidUseOfProtectedMember_method_1() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-class B {
- void b() => new A().a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_method_2() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-abstract class B implements A {
- void b() => a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_1() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-class B extends A {
- void b() => a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_2() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-class B extends Object with A {
- void b() => a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_3() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected m1() {}
-}
-class B extends A {
- static m2(A a) => a.m1();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_4() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void a(){ }
-}
-class B extends A {
- void a() => a();
-}
-main() {
- new B().a();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_field() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- int a = 42;
-}
-class B extends A {
- int b() => a;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_getter() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- int get a => 42;
-}
-class B extends A {
- int b() => a;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_OK_setter() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void set a(int i) { }
-}
-class B extends A {
- void b(int i) {
- a = i;
- }
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_setter() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @protected
- void set a(int i) { }
-}
-abstract class B implements A {
- b(int i) {
- a = i;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
- verify([source]);
- }
-
- void test_invalidUseOfProtectedMember_topLevelVariable() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-@protected
-int x = 0;
-main() {
- print(x);
-}''');
- computeLibrarySourceErrors(source);
- // TODO(brianwilkerson) This should produce a hint because the annotation is
- // being applied to the wrong kind of declaration.
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isDouble() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.dart2jsHint = true;
- resetWithOptions(options);
- Source source = addSource("var v = 1 is double;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.IS_DOUBLE]);
- verify([source]);
- }
-
- void test_isNotDouble() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.dart2jsHint = true;
- resetWithOptions(options);
- Source source = addSource("var v = 1 is! double;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.IS_NOT_DOUBLE]);
- verify([source]);
- }
-
- void test_missingReturn_async() {
- Source source = addSource('''
-import 'dart:async';
-Future<int> f() async {}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MISSING_RETURN]);
- verify([source]);
- }
-
- void test_missingReturn_function() {
- Source source = addSource("int f() {}");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MISSING_RETURN]);
- verify([source]);
- }
-
- void test_missingReturn_method() {
- Source source = addSource(r'''
-class A {
- int m() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MISSING_RETURN]);
- verify([source]);
- }
-
- void test_mustCallSuper() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @mustCallSuper
- void a() {}
-}
-class B extends A {
- @override
- void a()
- {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MUST_CALL_SUPER]);
- verify([source]);
- }
-
- void test_mustCallSuper_indirect() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @mustCallSuper
- void a() {}
-}
-class C extends A {
- @override
- void a() {
- super.a();
- }
-}
-class D extends C {
- @override
- void a() {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MUST_CALL_SUPER]);
- verify([source]);
- }
-
- void test_mustCallSuper_OK() {
- Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
- @mustCallSuper
- void a() {}
-}
-class C extends A {
- @override
- void a() {
- super.a(); //OK
- }
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- verify([source]);
- }
-
- @override
- void test_nullAwareInCondition_assert() {
- Source source = addSource(r'''
-m(x) {
- assert (x?.a);
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_conditionalExpression() {
- Source source = addSource(r'''
-m(x) {
- return x?.a ? 0 : 1;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_do() {
- Source source = addSource(r'''
-m(x) {
- do {} while (x?.a);
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_for() {
- Source source = addSource(r'''
-m(x) {
- for (var v = x; v?.a; v = v.next) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if() {
- Source source = addSource(r'''
-m(x) {
- if (x?.a) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalAnd_first() {
- Source source = addSource(r'''
-m(x) {
- if (x?.a && x.b) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalAnd_second() {
- Source source = addSource(r'''
-m(x) {
- if (x.a && x?.b) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalAnd_third() {
- Source source = addSource(r'''
-m(x) {
- if (x.a && x.b && x?.c) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalOr_first() {
- Source source = addSource(r'''
-m(x) {
- if (x?.a || x.b) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalOr_second() {
- Source source = addSource(r'''
-m(x) {
- if (x.a || x?.b) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_conditionalOr_third() {
- Source source = addSource(r'''
-m(x) {
- if (x.a || x.b || x?.c) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_not() {
- Source source = addSource(r'''
-m(x) {
- if (!x?.a) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_parenthesized() {
- Source source = addSource(r'''
-m(x) {
- if ((x?.a)) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_nullAwareInCondition_while() {
- Source source = addSource(r'''
-m(x) {
- while (x?.a) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.NULL_AWARE_IN_CONDITION]);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingGetter_invalid() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
-}
-class B extends A {
- @override
- int get m => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingMethod_invalid() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
-}
-class B extends A {
- @override
- int m() => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingSetter_invalid() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
-}
-class B extends A {
- @override
- set m(int x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]);
- verify([source]);
- }
-
- void test_typeCheck_type_is_Null() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is Null;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.TYPE_CHECK_IS_NULL]);
- verify([source]);
- }
-
- void test_typeCheck_type_not_Null() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is! Null;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]);
- verify([source]);
- }
-
- void test_undefinedGetter() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- return a.m;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_GETTER]);
- }
-
- void test_undefinedGetter_message() {
- // The implementation of HintCode.UNDEFINED_SETTER assumes that
- // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
- // same, this verifies that assumption.
- expect(StaticWarningCode.UNDEFINED_GETTER.message,
- StaticTypeWarningCode.UNDEFINED_GETTER.message);
- }
-
- void test_undefinedMethod() {
- Source source = addSource(r'''
-f() {
- var a = 'str';
- a.notAMethodOnString();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_METHOD]);
- }
-
- void test_undefinedMethod_assignmentExpression() {
- Source source = addSource(r'''
-class A {}
-class B {
- f(var a, var a2) {
- a = new A();
- a2 = new A();
- a += a2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_METHOD]);
- }
-
- void test_undefinedOperator_binaryExpression() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a + 1;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedOperator_indexBoth() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a[0]++;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedOperator_indexGetter() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a[0];
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedOperator_indexSetter() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a[0] = 1;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedOperator_postfixExpression() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a++;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedOperator_prefixExpression() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- ++a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
-
- void test_undefinedSetter() {
- Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- a.m = 0;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_SETTER]);
- }
-
- void test_undefinedSetter_message() {
- // The implementation of HintCode.UNDEFINED_SETTER assumes that
- // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
- // same, this verifies that assumption.
- expect(StaticWarningCode.UNDEFINED_SETTER.message,
- StaticTypeWarningCode.UNDEFINED_SETTER.message);
- }
-
- void test_unnecessaryCast_type_supertype() {
- Source source = addSource(r'''
-m(int i) {
- var b = i as Object;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_CAST]);
- verify([source]);
- }
-
- void test_unnecessaryCast_type_type() {
- Source source = addSource(r'''
-m(num i) {
- var b = i as num;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_CAST]);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_blockBody() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) {
- return super.noSuchMethod(y);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_expressionBody() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) => super.noSuchMethod(y);
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_null_is_Null() {
- Source source = addSource("bool b = null is Null;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_null_not_Null() {
- Source source = addSource("bool b = null is! Null;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_type_is_dynamic() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is dynamic;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_type_is_object() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is Object;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_type_not_dynamic() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is! dynamic;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
- verify([source]);
- }
-
- void test_unnecessaryTypeCheck_type_not_object() {
- Source source = addSource(r'''
-m(i) {
- bool b = i is! Object;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_extends() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-class B extends _A {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_fieldDeclaration() {
- enableUnusedElement = true;
- var src = r'''
-class Foo {
- _Bar x;
-}
-
-class _Bar {
-}
-''';
- Source source = addSource(src);
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_implements() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-class B implements _A {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_instanceCreation() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-main() {
- new _A();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_staticFieldAccess() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {
- static const F = 42;
-}
-main() {
- _A.F;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_staticMethodInvocation() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {
- static m() {}
-}
-main() {
- _A.m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_isUsed_typeArgument() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-main() {
- var v = new List<_A>();
- print(v);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_class_notUsed_inClassMember() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {
- static staticMethod() {
- new _A();
- }
- instanceMethod() {
- new _A();
- }
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_class_notUsed_inConstructorName() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {
- _A() {}
- _A.named() {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_class_notUsed_isExpression() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-main(p) {
- if (p is _A) {
- }
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_class_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_class_notUsed_variableDeclaration() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class _A {}
-main() {
- _A v;
- print(v);
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_enum_isUsed_fieldReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-enum _MyEnum {A, B, C}
-main() {
- print(_MyEnum.B);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_enum_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-enum _MyEnum {A, B, C}
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_functionLocal_isUsed_closure() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-main() {
- print(() {});
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionLocal_isUsed_invocation() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-main() {
- f() {}
- f();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionLocal_isUsed_reference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-main() {
- f() {}
- print(f);
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionLocal_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-main() {
- f() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_functionLocal_notUsed_referenceFromItself() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-main() {
- _f(int p) {
- _f(p - 1);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_functionTop_isUsed_invocation() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-_f() {}
-main() {
- _f();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTop_isUsed_reference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-_f() {}
-main() {
- print(_f);
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTop_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-_f() {}
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_functionTop_notUsed_referenceFromItself() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-_f(int p) {
- _f(p - 1);
-}
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_functionTypeAlias_isUsed_isExpression() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-typedef _F(a, b);
-main(f) {
- if (f is _F) {
- print('F');
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTypeAlias_isUsed_reference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-typedef _F(a, b);
-main(_F f) {
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTypeAlias_isUsed_typeArgument() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-typedef _F(a, b);
-main() {
- var v = new List<_F>();
- print(v);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTypeAlias_isUsed_variableDeclaration() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-typedef _F(a, b);
-class A {
- _F f;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_functionTypeAlias_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-typedef _F(a, b);
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_getter_isUsed_invocation_implicitThis() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- get _g => null;
- useGetter() {
- var v = _g;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_getter_isUsed_invocation_PrefixedIdentifier() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- get _g => null;
-}
-main(A a) {
- var v = a._g;
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_getter_isUsed_invocation_PropertyAccess() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- get _g => null;
-}
-main() {
- var v = new A()._g;
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_getter_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- get _g => null;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_getter_notUsed_referenceFromItself() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- get _g {
- return _g;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_hasReference_implicitThis() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
- useMethod() {
- print(_m);
- }
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_hasReference_implicitThis_subclass() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
- useMethod() {
- print(_m);
- }
-}
-class B extends A {
- _m() {}
-}
-print(x) {}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_hasReference_PrefixedIdentifier() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
-}
-main(A a) {
- a._m;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_hasReference_PropertyAccess() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
-}
-main() {
- new A()._m;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_implicitThis() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
- useMethod() {
- _m();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_implicitThis_subclass() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
- useMethod() {
- _m();
- }
-}
-class B extends A {
- _m() {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_MemberElement() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A<T> {
- _m(T t) {}
-}
-main(A<int> a) {
- a._m(0);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_propagated() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
-}
-main() {
- var a = new A();
- a._m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_static() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
-}
-main() {
- A a = new A();
- a._m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_invocation_subclass() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- _m() {}
-}
-class B extends A {
- _m() {}
-}
-main(A a) {
- a._m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_notPrivate() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- m() {}
-}
-main() {
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_isUsed_staticInvocation() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- static _m() {}
-}
-main() {
- A._m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_method_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- static _m() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_method_notUsed_referenceFromItself() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- static _m(int p) {
- _m(p - 1);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_setter_isUsed_invocation_implicitThis() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- set _s(x) {}
- useSetter() {
- _s = 42;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_setter_isUsed_invocation_PrefixedIdentifier() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- set _s(x) {}
-}
-main(A a) {
- a._s = 42;
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_setter_isUsed_invocation_PropertyAccess() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- set _s(x) {}
-}
-main() {
- new A()._s = 42;
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedElement_setter_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- set _s(x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedElement_setter_notUsed_referenceFromItself() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- set _s(int x) {
- if (x > 5) {
- _s = x - 1;
- }
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_ELEMENT]);
- verify([source]);
- }
-
- void test_unusedField_isUsed_argument() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f = 0;
- main() {
- print(++_f);
- }
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_implicitThis() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
- main() {
- print(_f);
- }
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_implicitThis_expressionFunctionBody() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
- m() => _f;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_implicitThis_subclass() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
- main() {
- print(_f);
- }
-}
-class B extends A {
- int _f;
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_qualified_propagatedElement() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
-}
-main() {
- var a = new A();
- print(a._f);
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_qualified_staticElement() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
-}
-main() {
- A a = new A();
- print(a._f);
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_isUsed_reference_qualified_unresolved() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
-}
-main(a) {
- print(a._f);
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedField_notUsed_compoundAssign() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
- main() {
- _f += 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_FIELD]);
- verify([source]);
- }
-
- void test_unusedField_notUsed_noReference() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_FIELD]);
- verify([source]);
- }
-
- void test_unusedField_notUsed_postfixExpr() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f = 0;
- main() {
- _f++;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_FIELD]);
- verify([source]);
- }
-
- void test_unusedField_notUsed_prefixExpr() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f = 0;
- main() {
- ++_f;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_FIELD]);
- verify([source]);
- }
-
- void test_unusedField_notUsed_simpleAssignment() {
- enableUnusedElement = true;
- Source source = addSource(r'''
-class A {
- int _f;
- m() {
- _f = 1;
- }
-}
-main(A a) {
- a._f = 2;
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_FIELD]);
- verify([source]);
- }
-
- void test_unusedImport() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';''');
- Source source2 = addNamedSource("/lib1.dart", "library lib1;");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_IMPORT]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedImport_as() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' as one;
-one.A a;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_IMPORT]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedImport_hide() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' hide A;
-A a;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_IMPORT]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedImport_show() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' show A;
-import 'lib1.dart' show B;
-A a;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_IMPORT]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedLocalVariable_inCatch_exception() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- try {
- } on String catch (exception) {
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_CATCH_CLAUSE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inCatch_exception_hasStack() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- try {
- } catch (exception, stack) {
- print(stack);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inCatch_exception_noOnClause() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- try {
- } catch (exception) {
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inCatch_stackTrace() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- try {
- } catch (exception, stackTrace) {
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_CATCH_STACK]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inCatch_stackTrace_used() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- try {
- } catch (exception, stackTrace) {
- print('exception at $stackTrace');
- }
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inFor_underscore_ignored() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- for (var _ in [1,2,3]) {
- for (var __ in [4,5,6]) {
- // do something
- }
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inFunction() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- var v = 1;
- v = 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_inMethod() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-class A {
- foo() {
- var v = 1;
- v = 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isInvoked() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-typedef Foo();
-main() {
- Foo foo;
- foo();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isRead_notUsed_compoundAssign() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- var v = 1;
- v += 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isRead_notUsed_postfixExpr() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- var v = 1;
- v++;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isRead_notUsed_prefixExpr() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- var v = 1;
- ++v;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isRead_usedArgument() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-main() {
- var v = 1;
- print(++v);
-}
-print(x) {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_unusedLocalVariable_isRead_usedInvocationTarget() {
- enableUnusedLocalVariable = true;
- Source source = addSource(r'''
-class A {
- foo() {}
-}
-main() {
- var a = new A();
- a.foo();
-}
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source]);
- }
-
- void test_useOfVoidResult_assignmentExpression_function() {
- Source source = addSource(r'''
-void f() {}
-class A {
- n() {
- var a;
- a = f();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-
- void test_useOfVoidResult_assignmentExpression_method() {
- Source source = addSource(r'''
-class A {
- void m() {}
- n() {
- var a;
- a = m();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-
- void test_useOfVoidResult_inForLoop() {
- Source source = addSource(r'''
-class A {
- void m() {}
- n() {
- for(var a = m();;) {}
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-
- void test_useOfVoidResult_variableDeclaration_function() {
- Source source = addSource(r'''
-void f() {}
-class A {
- n() {
- var a = f();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-
- void test_useOfVoidResult_variableDeclaration_method() {
- Source source = addSource(r'''
-class A {
- void m() {}
- n() {
- var a = m();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-
- void test_useOfVoidResult_variableDeclaration_method2() {
- Source source = addSource(r'''
-class A {
- void m() {}
- n() {
- var a = m(), b = m();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.USE_OF_VOID_RESULT, HintCode.USE_OF_VOID_RESULT]);
- verify([source]);
- }
-}
-
-@reflectiveTest
-class InheritanceManagerTest {
- /**
- * The type provider used to access the types.
- */
- TestTypeProvider _typeProvider;
-
- /**
- * The library containing the code being resolved.
- */
- LibraryElementImpl _definingLibrary;
-
- /**
- * The inheritance manager being tested.
- */
- InheritanceManager _inheritanceManager;
-
- /**
- * The number of members that Object implements (as determined by [TestTypeProvider]).
- */
- int _numOfMembersInObject = 0;
-
- void setUp() {
- _typeProvider = new TestTypeProvider();
- _inheritanceManager = _createInheritanceManager();
- InterfaceType objectType = _typeProvider.objectType;
- _numOfMembersInObject =
- objectType.methods.length + objectType.accessors.length;
- }
-
- void test_getMapOfMembersInheritedFromClasses_accessor_extends() {
- // class A { int get g; }
- // class B extends A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(getterName), same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_accessor_implements() {
- // class A { int get g; }
- // class B implements A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject);
- expect(mapB.get(getterName), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_accessor_with() {
- // class A { int get g; }
- // class B extends Object with A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(getterName), same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_implicitExtends() {
- // class A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- _assertNoErrors(classA);
- }
-
- void test_getMapOfMembersInheritedFromClasses_method_extends() {
- // class A { int g(); }
- // class B extends A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.supertype = classA.type;
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(methodName), same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_method_implements() {
- // class A { int g(); }
- // class B implements A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject);
- expect(mapB.get(methodName), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_method_with() {
- // class A { int g(); }
- // class B extends Object with A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(methodName), same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromClasses_method_with_two_mixins() {
- // class A1 { int m(); }
- // class A2 { int m(); }
- // class B extends Object with A1, A2 {}
- ClassElementImpl classA1 = ElementFactory.classElement2("A1");
- String methodName = "m";
- MethodElement methodA1M =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA1.methods = <MethodElement>[methodA1M];
- ClassElementImpl classA2 = ElementFactory.classElement2("A2");
- MethodElement methodA2M =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA2.methods = <MethodElement>[methodA2M];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA1.type, classA2.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromClasses(classB);
- expect(mapB.get(methodName), same(methodA2M));
- _assertNoErrors(classA1);
- _assertNoErrors(classA2);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_accessor_extends() {
- // class A { int get g; }
- // class B extends A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(getterName), same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_accessor_implements() {
- // class A { int get g; }
- // class B implements A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(getterName), same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_accessor_with() {
- // class A { int get g; }
- // class B extends Object with A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(getterName), same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_implicitExtends() {
- // class A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
- // class I1 { int m(); }
- // class I2 { int get m; }
- // class A implements I2, I1 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement getter =
- ElementFactory.getterElement(methodName, false, _typeProvider.intType);
- classI2.accessors = <PropertyAccessorElement>[getter];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapA.get(methodName), isNull);
- _assertErrors(classA,
- [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
- // class I1 { int m(); }
- // class I2 { String m(); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM1 =
- ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElement methodM2 = ElementFactory
- .methodElement(methodName, null, [_typeProvider.stringType]);
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapA.get(methodName), isNull);
- _assertErrors(
- classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
- // class I1 { int m(); }
- // class I2 { int get m; }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement getter =
- ElementFactory.getterElement(methodName, false, _typeProvider.intType);
- classI2.accessors = <PropertyAccessorElement>[getter];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapA.get(methodName), isNull);
- _assertErrors(classA,
- [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
- // class I1 { dynamic m(int, [int]); }
- // class I2 { dynamic m(int, int, int); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElementImpl methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
- parameter1.type = _typeProvider.intType;
- parameter1.parameterKind = ParameterKind.REQUIRED;
- ParameterElementImpl parameter2 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
- parameter2.type = _typeProvider.intType;
- parameter2.parameterKind = ParameterKind.POSITIONAL;
- methodM1.parameters = <ParameterElement>[parameter1, parameter2];
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElementImpl methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter3 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
- parameter3.type = _typeProvider.intType;
- parameter3.parameterKind = ParameterKind.REQUIRED;
- ParameterElementImpl parameter4 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a4"));
- parameter4.type = _typeProvider.intType;
- parameter4.parameterKind = ParameterKind.REQUIRED;
- ParameterElementImpl parameter5 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a5"));
- parameter5.type = _typeProvider.intType;
- parameter5.parameterKind = ParameterKind.REQUIRED;
- methodM2.parameters = <ParameterElement>[
- parameter3,
- parameter4,
- parameter5
- ];
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapA.get(methodName), isNull);
- _assertErrors(
- classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
- // class I1 { int m(); }
- // class I2 { String m(); }
- // class A implements I2, I1 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM1 = ElementFactory
- .methodElement(methodName, null, [_typeProvider.stringType]);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElement methodM2 =
- ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI2.type, classI1.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapA.get(methodName), isNull);
- _assertErrors(
- classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_method_extends() {
- // class A { int g(); }
- // class B extends A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(methodName), same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_method_implements() {
- // class A { int g(); }
- // class B implements A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(methodName), same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_method_with() {
- // class A { int g(); }
- // class B extends Object with A {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- MemberMap mapB =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classB);
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject);
- expect(mapB.size, _numOfMembersInObject + 1);
- expect(mapB.get(methodName), same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_getMapOfMembersInheritedFromInterfaces_union_differentNames() {
- // class I1 { int m1(); }
- // class I2 { int m2(); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName1 = "m1";
- MethodElement methodM1 =
- ElementFactory.methodElement(methodName1, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- String methodName2 = "m2";
- MethodElement methodM2 =
- ElementFactory.methodElement(methodName2, _typeProvider.intType);
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 2);
- expect(mapA.get(methodName1), same(methodM1));
- expect(mapA.get(methodName2), same(methodM2));
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
- // class I1 { int get g; }
- // class I2 { num get g; }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String accessorName = "g";
- PropertyAccessorElement getter1 = ElementFactory.getterElement(
- accessorName, false, _typeProvider.intType);
- classI1.accessors = <PropertyAccessorElement>[getter1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement getter2 = ElementFactory.getterElement(
- accessorName, false, _typeProvider.numType);
- classI2.accessors = <PropertyAccessorElement>[getter2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(
- accessorName, false, _typeProvider.dynamicType);
- expect(mapA.get(accessorName).type, syntheticAccessor.type);
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
- // class I1 { dynamic m(int); }
- // class I2 { dynamic m(num); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElementImpl methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
- parameter1.type = _typeProvider.intType;
- parameter1.parameterKind = ParameterKind.REQUIRED;
- methodM1.parameters = <ParameterElement>[parameter1];
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElementImpl methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter2 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
- parameter2.type = _typeProvider.numType;
- parameter2.parameterKind = ParameterKind.REQUIRED;
- methodM2.parameters = <ParameterElement>[parameter2];
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- MethodElement syntheticMethod = ElementFactory.methodElement(
- methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]);
- expect(mapA.get(methodName).type, syntheticMethod.type);
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
- // class I1 { set s(int); }
- // class I2 { set s(num); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String accessorName = "s";
- PropertyAccessorElement setter1 = ElementFactory.setterElement(
- accessorName, false, _typeProvider.intType);
- classI1.accessors = <PropertyAccessorElement>[setter1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement setter2 = ElementFactory.setterElement(
- accessorName, false, _typeProvider.numType);
- classI2.accessors = <PropertyAccessorElement>[setter2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- PropertyAccessorElementImpl syntheticAccessor = ElementFactory
- .setterElement(accessorName, false, _typeProvider.dynamicType);
- syntheticAccessor.returnType = _typeProvider.dynamicType;
- expect(mapA.get("$accessorName=").type, syntheticAccessor.type);
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
- // class A {}
- // class B extends A {}
- // class C extends B {}
- // class I1 { A get g; }
- // class I2 { B get g; }
- // class I3 { C get g; }
- // class D implements I1, I2, I3 {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String accessorName = "g";
- PropertyAccessorElement getter1 =
- ElementFactory.getterElement(accessorName, false, classA.type);
- classI1.accessors = <PropertyAccessorElement>[getter1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement getter2 =
- ElementFactory.getterElement(accessorName, false, classB.type);
- classI2.accessors = <PropertyAccessorElement>[getter2];
- ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- PropertyAccessorElement getter3 =
- ElementFactory.getterElement(accessorName, false, classC.type);
- classI3.accessors = <PropertyAccessorElement>[getter3];
- ClassElementImpl classD = ElementFactory.classElement2("D");
- classD.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
- ];
- MemberMap mapD =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
- expect(mapD.size, _numOfMembersInObject + 1);
- PropertyAccessorElement syntheticAccessor = ElementFactory.getterElement(
- accessorName, false, _typeProvider.dynamicType);
- expect(mapD.get(accessorName).type, syntheticAccessor.type);
- _assertNoErrors(classD);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
- // class A {}
- // class B extends A {}
- // class C extends B {}
- // class I1 { dynamic m(A a); }
- // class I2 { dynamic m(B b); }
- // class I3 { dynamic m(C c); }
- // class D implements I1, I2, I3 {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElementImpl methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
- parameter1.type = classA.type;
- parameter1.parameterKind = ParameterKind.REQUIRED;
- methodM1.parameters = <ParameterElement>[parameter1];
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElementImpl methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter2 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
- parameter2.type = classB.type;
- parameter2.parameterKind = ParameterKind.REQUIRED;
- methodM2.parameters = <ParameterElement>[parameter2];
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- MethodElementImpl methodM3 =
- ElementFactory.methodElement(methodName, _typeProvider.dynamicType);
- ParameterElementImpl parameter3 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a0"));
- parameter3.type = classC.type;
- parameter3.parameterKind = ParameterKind.REQUIRED;
- methodM3.parameters = <ParameterElement>[parameter3];
- classI3.methods = <MethodElement>[methodM3];
- ClassElementImpl classD = ElementFactory.classElement2("D");
- classD.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
- ];
- MemberMap mapD =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
- expect(mapD.size, _numOfMembersInObject + 1);
- MethodElement syntheticMethod = ElementFactory.methodElement(
- methodName, _typeProvider.dynamicType, [_typeProvider.dynamicType]);
- expect(mapD.get(methodName).type, syntheticMethod.type);
- _assertNoErrors(classD);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
- // class A {}
- // class B extends A {}
- // class C extends B {}
- // class I1 { set s(A); }
- // class I2 { set s(B); }
- // class I3 { set s(C); }
- // class D implements I1, I2, I3 {}
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String accessorName = "s";
- PropertyAccessorElement setter1 =
- ElementFactory.setterElement(accessorName, false, classA.type);
- classI1.accessors = <PropertyAccessorElement>[setter1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- PropertyAccessorElement setter2 =
- ElementFactory.setterElement(accessorName, false, classB.type);
- classI2.accessors = <PropertyAccessorElement>[setter2];
- ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- PropertyAccessorElement setter3 =
- ElementFactory.setterElement(accessorName, false, classC.type);
- classI3.accessors = <PropertyAccessorElement>[setter3];
- ClassElementImpl classD = ElementFactory.classElement2("D");
- classD.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
- ];
- MemberMap mapD =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classD);
- expect(mapD.size, _numOfMembersInObject + 1);
- PropertyAccessorElementImpl syntheticAccessor = ElementFactory
- .setterElement(accessorName, false, _typeProvider.dynamicType);
- syntheticAccessor.returnType = _typeProvider.dynamicType;
- expect(mapD.get("$accessorName=").type, syntheticAccessor.type);
- _assertNoErrors(classD);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
- // class I1 { int m(); }
- // class I2 { int m([int]); }
- // class A implements I1, I2 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElementImpl methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
- parameter1.type = _typeProvider.intType;
- parameter1.parameterKind = ParameterKind.POSITIONAL;
- methodM2.parameters = <ParameterElement>[parameter1];
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- expect(mapA.get(methodName), same(methodM2));
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
- // class I1 { int m(); }
- // class I2 { int m([int]); }
- // class I3 { int m([int, int]); }
- // class A implements I1, I2, I3 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElementImpl methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElementImpl methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
- parameter1.type = _typeProvider.intType;
- parameter1.parameterKind = ParameterKind.POSITIONAL;
- methodM1.parameters = <ParameterElement>[parameter1];
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- MethodElementImpl methodM3 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- ParameterElementImpl parameter2 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
- parameter2.type = _typeProvider.intType;
- parameter2.parameterKind = ParameterKind.POSITIONAL;
- ParameterElementImpl parameter3 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
- parameter3.type = _typeProvider.intType;
- parameter3.parameterKind = ParameterKind.POSITIONAL;
- methodM3.parameters = <ParameterElement>[parameter2, parameter3];
- classI3.methods = <MethodElement>[methodM3];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type
- ];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- expect(mapA.get(methodName), same(methodM3));
- _assertNoErrors(classA);
- }
-
- void
- test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
- // class I1 { int m(); }
- // class I2 { int m(); }
- // class I3 { int m([int]); }
- // class I4 { int m([int, int]); }
- // class A implements I1, I2, I3, I4 {}
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName = "m";
- MethodElement methodM1 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- MethodElement methodM2 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classI2.methods = <MethodElement>[methodM2];
- ClassElementImpl classI3 = ElementFactory.classElement2("I3");
- MethodElementImpl methodM3 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- ParameterElementImpl parameter1 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a1"));
- parameter1.type = _typeProvider.intType;
- parameter1.parameterKind = ParameterKind.POSITIONAL;
- methodM3.parameters = <ParameterElement>[parameter1];
- classI3.methods = <MethodElement>[methodM3];
- ClassElementImpl classI4 = ElementFactory.classElement2("I4");
- MethodElementImpl methodM4 =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- ParameterElementImpl parameter2 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a2"));
- parameter2.type = _typeProvider.intType;
- parameter2.parameterKind = ParameterKind.POSITIONAL;
- ParameterElementImpl parameter3 =
- new ParameterElementImpl.forNode(AstFactory.identifier3("a3"));
- parameter3.type = _typeProvider.intType;
- parameter3.parameterKind = ParameterKind.POSITIONAL;
- methodM4.parameters = <ParameterElement>[parameter2, parameter3];
- classI4.methods = <MethodElement>[methodM4];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[
- classI1.type,
- classI2.type,
- classI3.type,
- classI4.type
- ];
- MemberMap mapA =
- _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
- expect(mapA.size, _numOfMembersInObject + 1);
- expect(mapA.get(methodName), same(methodM4));
- _assertNoErrors(classA);
- }
-
- void test_lookupInheritance_interface_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, getterName),
- same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_interface_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, methodName),
- same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_interface_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "s";
- PropertyAccessorElement setterS =
- ElementFactory.setterElement(setterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setterS];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
- same(setterS));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_interface_staticMember() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- (methodM as MethodElementImpl).static = true;
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_interfaces_infiniteLoop() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupInheritance_interfaces_infiniteLoop2() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classA.interfaces = <InterfaceType>[classB.type];
- classB.interfaces = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_interfaces_union2() {
- ClassElementImpl classI1 = ElementFactory.classElement2("I1");
- String methodName1 = "m1";
- MethodElement methodM1 =
- ElementFactory.methodElement(methodName1, _typeProvider.intType);
- classI1.methods = <MethodElement>[methodM1];
- ClassElementImpl classI2 = ElementFactory.classElement2("I2");
- String methodName2 = "m2";
- MethodElement methodM2 =
- ElementFactory.methodElement(methodName2, _typeProvider.intType);
- classI2.methods = <MethodElement>[methodM2];
- classI2.interfaces = <InterfaceType>[classI1.type];
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.interfaces = <InterfaceType>[classI2.type];
- expect(_inheritanceManager.lookupInheritance(classA, methodName1),
- same(methodM1));
- expect(_inheritanceManager.lookupInheritance(classA, methodName2),
- same(methodM2));
- _assertNoErrors(classI1);
- _assertNoErrors(classI2);
- _assertNoErrors(classA);
- }
-
- void test_lookupInheritance_mixin_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, getterName),
- same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_mixin_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, methodName),
- same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_mixin_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "s";
- PropertyAccessorElement setterS =
- ElementFactory.setterElement(setterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setterS];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
- same(setterS));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_mixin_staticMember() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- (methodM as MethodElementImpl).static = true;
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.mixins = <InterfaceType>[classA.type];
- expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_noMember() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- expect(_inheritanceManager.lookupInheritance(classA, "a"), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupInheritance_superclass_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- expect(_inheritanceManager.lookupInheritance(classB, getterName),
- same(getterG));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_superclass_infiniteLoop() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- classA.supertype = classA.type;
- expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupInheritance_superclass_infiniteLoop2() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classA.supertype = classB.type;
- classB.supertype = classA.type;
- expect(_inheritanceManager.lookupInheritance(classA, "name"), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_superclass_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- expect(_inheritanceManager.lookupInheritance(classB, methodName),
- same(methodM));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_superclass_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "s";
- PropertyAccessorElement setterS =
- ElementFactory.setterElement(setterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setterS];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- expect(_inheritanceManager.lookupInheritance(classB, "$setterName="),
- same(setterS));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupInheritance_superclass_staticMember() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- (methodM as MethodElementImpl).static = true;
- classA.methods = <MethodElement>[methodM];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- expect(_inheritanceManager.lookupInheritance(classB, methodName), isNull);
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupMember_getter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- expect(_inheritanceManager.lookupMember(classA, getterName), same(getterG));
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_getter_static() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String getterName = "g";
- PropertyAccessorElement getterG =
- ElementFactory.getterElement(getterName, true, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[getterG];
- expect(_inheritanceManager.lookupMember(classA, getterName), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_method() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- expect(_inheritanceManager.lookupMember(classA, methodName), same(methodM));
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_method_static() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElement methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- (methodM as MethodElementImpl).static = true;
- classA.methods = <MethodElement>[methodM];
- expect(_inheritanceManager.lookupMember(classA, methodName), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_noMember() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- expect(_inheritanceManager.lookupMember(classA, "a"), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_setter() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "s";
- PropertyAccessorElement setterS =
- ElementFactory.setterElement(setterName, false, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setterS];
- expect(_inheritanceManager.lookupMember(classA, "$setterName="),
- same(setterS));
- _assertNoErrors(classA);
- }
-
- void test_lookupMember_setter_static() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String setterName = "s";
- PropertyAccessorElement setterS =
- ElementFactory.setterElement(setterName, true, _typeProvider.intType);
- classA.accessors = <PropertyAccessorElement>[setterS];
- expect(_inheritanceManager.lookupMember(classA, setterName), isNull);
- _assertNoErrors(classA);
- }
-
- void test_lookupOverrides_noParentClasses() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElementImpl methodM =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodM];
- expect(
- _inheritanceManager.lookupOverrides(classA, methodName), hasLength(0));
- _assertNoErrors(classA);
- }
-
- void test_lookupOverrides_overrideBaseClass() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElementImpl methodMinA =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodMinA];
- ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
- MethodElementImpl methodMinB =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classB.methods = <MethodElement>[methodMinB];
- List<ExecutableElement> overrides =
- _inheritanceManager.lookupOverrides(classB, methodName);
- expect(overrides, unorderedEquals([methodMinA]));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupOverrides_overrideInterface() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElementImpl methodMinA =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodMinA];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- classB.interfaces = <InterfaceType>[classA.type];
- MethodElementImpl methodMinB =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classB.methods = <MethodElement>[methodMinB];
- List<ExecutableElement> overrides =
- _inheritanceManager.lookupOverrides(classB, methodName);
- expect(overrides, unorderedEquals([methodMinA]));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- }
-
- void test_lookupOverrides_overrideTwoInterfaces() {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- MethodElementImpl methodMinA =
- ElementFactory.methodElement(methodName, _typeProvider.intType);
- classA.methods = <MethodElement>[methodMinA];
- ClassElementImpl classB = ElementFactory.classElement2("B");
- MethodElementImpl methodMinB =
- ElementFactory.methodElement(methodName, _typeProvider.doubleType);
- classB.methods = <MethodElement>[methodMinB];
- ClassElementImpl classC = ElementFactory.classElement2("C");
- classC.interfaces = <InterfaceType>[classA.type, classB.type];
- MethodElementImpl methodMinC =
- ElementFactory.methodElement(methodName, _typeProvider.numType);
- classC.methods = <MethodElement>[methodMinC];
- List<ExecutableElement> overrides =
- _inheritanceManager.lookupOverrides(classC, methodName);
- expect(overrides, unorderedEquals([methodMinA, methodMinB]));
- _assertNoErrors(classA);
- _assertNoErrors(classB);
- _assertNoErrors(classC);
- }
-
- void _assertErrors(ClassElement classElt,
- [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
- GatheringErrorListener errorListener = new GatheringErrorListener();
- HashSet<AnalysisError> actualErrors =
- _inheritanceManager.getErrors(classElt);
- if (actualErrors != null) {
- for (AnalysisError error in actualErrors) {
- errorListener.onError(error);
- }
- }
- errorListener.assertErrorsWithCodes(expectedErrorCodes);
- }
-
- void _assertNoErrors(ClassElement classElt) {
- _assertErrors(classElt);
- }
-
- /**
- * Create the inheritance manager used by the tests.
- *
- * @return the inheritance manager that was created
- */
- InheritanceManager _createInheritanceManager() {
- AnalysisContext context = AnalysisContextFactory.contextWithCore();
- FileBasedSource source =
- new FileBasedSource(FileUtilities2.createFile("/test.dart"));
- CompilationUnitElementImpl definingCompilationUnit =
- new CompilationUnitElementImpl("test.dart");
- definingCompilationUnit.librarySource =
- definingCompilationUnit.source = source;
- _definingLibrary = ElementFactory.library(context, "test");
- _definingLibrary.definingCompilationUnit = definingCompilationUnit;
- return new InheritanceManager(_definingLibrary);
+ expectIdentifierType('y = ', 'dynamic', 'List<dynamic>');
}
}
@@ -6868,1859 +582,6 @@
}
}
-@reflectiveTest
-class NonHintCodeTest extends ResolverTestCase {
- void test_deadCode_deadBlock_conditionalElse_debugConst() {
- Source source = addSource(r'''
-const bool DEBUG = true;
-f() {
- DEBUG ? 1 : 2;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_conditionalIf_debugConst() {
- Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
- DEBUG ? 1 : 2;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_else() {
- Source source = addSource(r'''
-const bool DEBUG = true;
-f() {
- if(DEBUG) {} else {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier() {
- Source source = addSource(r'''
-class A {
- static const bool DEBUG = false;
-}
-f() {
- if(A.DEBUG) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2() {
- Source source = addSource(r'''
-library L;
-import 'lib2.dart';
-f() {
- if(A.DEBUG) {}
-}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-class A {
- static const bool DEBUG = false;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if_debugConst_propertyAccessor() {
- Source source = addSource(r'''
-library L;
-import 'lib2.dart' as LIB;
-f() {
- if(LIB.A.DEBUG) {}
-}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-class A {
- static const bool DEBUG = false;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_if_debugConst_simpleIdentifier() {
- Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
- if(DEBUG) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadBlock_while_debugConst() {
- Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
- while(DEBUG) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadCatch_onCatchSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {}
-f() {
- try {} on B catch (e) {} on A catch (e) {} catch (e) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_and_debugConst() {
- Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
- bool b = DEBUG && false;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deadCode_deadOperandLHS_or_debugConst() {
- Source source = addSource(r'''
-const bool DEBUG = true;
-f() {
- bool b = DEBUG || true;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_deprecatedAnnotationUse_classWithConstructor() {
- Source source = addSource(r'''
-@deprecated
-class C {
- C();
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_divisionOptimization() {
- Source source = addSource(r'''
-f(int x, int y) {
- var v = x / y.toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_divisionOptimization_supressIfDivisionNotDefinedInCore() {
- Source source = addSource(r'''
-f(x, y) {
- var v = (x / y).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_divisionOptimization_supressIfDivisionOverridden() {
- Source source = addSource(r'''
-class A {
- num operator /(x) { return x; }
-}
-f(A x, A y) {
- var v = (x / y).toInt();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_duplicateImport_as() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' as one;
-A a;
-one.A a2;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_duplicateImport_hide() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' hide A;
-A a;
-B b;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_duplicateImport_show() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' show A;
-A a;
-B b;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_importDeferredLibraryWithLoadFunction() {
- resolveWithErrors(<String>[
- r'''
-library lib1;
-f() {}''',
- r'''
-library root;
-import 'lib1.dart' deferred as lib1;
-main() { lib1.f(); }'''
- ], ErrorCode.EMPTY_LIST);
- }
-
- void test_issue20904BuggyTypePromotionAtIfJoin_1() {
- // https://code.google.com/p/dart/issues/detail?id=20904
- Source source = addSource(r'''
-f(var message, var dynamic_) {
- if (message is Function) {
- message = dynamic_;
- }
- int s = message;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_issue20904BuggyTypePromotionAtIfJoin_3() {
- // https://code.google.com/p/dart/issues/detail?id=20904
- Source source = addSource(r'''
-f(var message) {
- var dynamic_;
- if (message is Function) {
- message = dynamic_;
- } else {
- return;
- }
- int s = message;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_issue20904BuggyTypePromotionAtIfJoin_4() {
- // https://code.google.com/p/dart/issues/detail?id=20904
- Source source = addSource(r'''
-f(var message) {
- if (message is Function) {
- message = '';
- } else {
- return;
- }
- String s = message;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_missingReturn_emptyFunctionBody() {
- Source source = addSource(r'''
-abstract class A {
- int m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_missingReturn_expressionFunctionBody() {
- Source source = addSource("int f() => 0;");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_missingReturn_noReturnType() {
- Source source = addSource("f() {}");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_missingReturn_voidReturnType() {
- Source source = addSource("void f() {}");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_nullAwareInCondition_for_noCondition() {
- Source source = addSource(r'''
-m(x) {
- for (var v = x; ; v++) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_nullAwareInCondition_if_notTopLevel() {
- Source source = addSource(r'''
-m(x) {
- if (x?.y == null) {}
-}
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideEqualsButNotHashCode() {
- Source source = addSource(r'''
-class A {
- bool operator ==(x) { return x; }
- get hashCode => 0;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingGetter_inInterface() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- int get m => 0;
-}
-class B implements A {
- @override
- int get m => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingGetter_inSuperclass() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- int get m => 0;
-}
-class B extends A {
- @override
- int get m => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingMethod_inInterface() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- int m() => 0;
-}
-class B implements A {
- @override
- int m() => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingMethod_inSuperclass() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- int m() => 0;
-}
-class B extends A {
- @override
- int m() => 1;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingSetter_inInterface() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- set m(int x) {}
-}
-class B implements A {
- @override
- set m(int x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_overrideOnNonOverridingSetter_inSuperclass() {
- Source source = addSource(r'''
-library dart.core;
-const override = null;
-class A {
- set m(int x) {}
-}
-class B extends A {
- @override
- set m(int x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_propagatedFieldType() {
- Source source = addSource(r'''
-class A { }
-class X<T> {
- final x = new List<T>();
-}
-class Z {
- final X<A> y = new X<A>();
- foo() {
- y.x.add(new A());
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_proxy_annotation_prefixed() {
- Source source = addSource(r'''
-library L;
-@proxy
-class A {}
-f(var a) {
- a = new A();
- a.m();
- var x = a.g;
- a.s = 1;
- var y = a + a;
- a++;
- ++a;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_proxy_annotation_prefixed2() {
- Source source = addSource(r'''
-library L;
-@proxy
-class A {}
-class B {
- f(var a) {
- a = new A();
- a.m();
- var x = a.g;
- a.s = 1;
- var y = a + a;
- a++;
- ++a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_proxy_annotation_prefixed3() {
- Source source = addSource(r'''
-library L;
-class B {
- f(var a) {
- a = new A();
- a.m();
- var x = a.g;
- a.s = 1;
- var y = a + a;
- a++;
- ++a;
- }
-}
-@proxy
-class A {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedGetter_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- get b => 0;
-}
-f(var a) {
- if(a is A) {
- return a.b;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedMethod_assignmentExpression_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator +(B b) {return new B();}
-}
-f(var a, var a2) {
- a = new A();
- a2 = new A();
- a += a2;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedMethod_dynamic() {
- Source source = addSource(r'''
-class D<T extends dynamic> {
- fieldAccess(T t) => t.abc;
- methodAccess(T t) => t.xyz(1, 2, 'three');
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedMethod_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- b() {}
-}
-f() {
- var a = new A();
- a.b();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedMethod_unionType_all() {
- Source source = addSource(r'''
-class A {
- int m(int x) => 0;
-}
-class B {
- String m() => '0';
-}
-f(A a, B b) {
- var ab;
- if (0 < 1) {
- ab = a;
- } else {
- ab = b;
- }
- ab.m();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedMethod_unionType_some() {
- Source source = addSource(r'''
-class A {
- int m(int x) => 0;
-}
-class B {}
-f(A a, B b) {
- var ab;
- if (0 < 1) {
- ab = a;
- } else {
- ab = b;
- }
- ab.m(0);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_binaryExpression_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator +(B b) {}
-}
-f(var a) {
- if(a is A) {
- a + 1;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_indexBoth_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator [](int index) {}
-}
-f(var a) {
- if(a is A) {
- a[0]++;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_indexGetter_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator [](int index) {}
-}
-f(var a) {
- if(a is A) {
- a[0];
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_indexSetter_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator []=(i, v) {}
-}
-f(var a) {
- if(a is A) {
- a[0] = 1;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_postfixExpression() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator +(B b) {return new B();}
-}
-f(var a) {
- if(a is A) {
- a++;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedOperator_prefixExpression() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- operator +(B b) {return new B();}
-}
-f(var a) {
- if(a is A) {
- ++a;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_undefinedSetter_inSubtype() {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- set b(x) {}
-}
-f(var a) {
- if(a is A) {
- a.b = 0;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_unnecessaryCast_13855_parameter_A() {
- // dartbug.com/13855, dartbug.com/13732
- Source source = addSource(r'''
-class A{
- a() {}
-}
-class B<E> {
- E e;
- m() {
- (e as A).a();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryCast_conditionalExpression() {
- Source source = addSource(r'''
-abstract class I {}
-class A implements I {}
-class B implements I {}
-I m(A a, B b) {
- return a == null ? b as I : a as I;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryCast_dynamic_type() {
- Source source = addSource(r'''
-m(v) {
- var b = v as Object;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryCast_generics() {
- // dartbug.com/18953
- Source source = addSource(r'''
-import 'dart:async';
-Future<int> f() => new Future.value(0);
-void g(bool c) {
- (c ? f(): new Future.value(0) as Future<int>).then((int value) {});
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryCast_type_dynamic() {
- Source source = addSource(r'''
-m(v) {
- var b = Object as dynamic;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_blockBody_notReturnStatement() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) {
- print(y);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_blockBody_notSingleStatement() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) {
- print(y);
- return super.noSuchMethod(y);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_expressionBody_notNoSuchMethod() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) => super.hashCode;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unnecessaryNoSuchMethod_expressionBody_notSuper() {
- Source source = addSource(r'''
-class A {
- noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
- mmm();
- noSuchMethod(y) => 42;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_annotationOnDirective() {
- Source source = addSource(r'''
-library L;
-@A()
-import 'lib1.dart';''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {
- const A() {}
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- verify([source, source2]);
- }
-
- void test_unusedImport_as_equalPrefixes() {
- // 18818
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' as one;
-import 'lib2.dart' as one;
-one.A a;
-one.B b;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}''');
- Source source3 = addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-class B {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source);
- assertNoErrors(source2);
- assertNoErrors(source3);
- verify([source, source2, source3]);
- }
-
- void test_unusedImport_core_library() {
- Source source = addSource(r'''
-library L;
-import 'dart:core';''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_export() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-Two two;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-export 'lib2.dart';
-class One {}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-class Two {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_export2() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-Three three;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-export 'lib2.dart';
-class One {}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-export 'lib3.dart';
-class Two {}''');
- addNamedSource(
- "/lib3.dart",
- r'''
-library lib3;
-class Three {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_export_infiniteLoop() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-Two two;''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-export 'lib2.dart';
-class One {}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-export 'lib3.dart';
-class Two {}''');
- addNamedSource(
- "/lib3.dart",
- r'''
-library lib3;
-export 'lib2.dart';
-class Three {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_metadata() {
- Source source = addSource(r'''
-library L;
-@A(x)
-import 'lib1.dart';
-class A {
- final int value;
- const A(this.value);
-}''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-const x = 0;''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_unusedImport_prefix_topLevelFunction() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' hide topLevelFunction;
-import 'lib1.dart' as one show topLevelFunction;
-class A {
- static void x() {
- One o;
- one.topLevelFunction();
- }
-}''');
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class One {}
-topLevelFunction() {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_useOfVoidResult_implicitReturnValue() {
- Source source = addSource(r'''
-f() {}
-class A {
- n() {
- var a = f();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_useOfVoidResult_nonVoidReturnValue() {
- Source source = addSource(r'''
-int f() => 1;
-g() {
- var a = f();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-}
-
-class PubSuggestionCodeTest extends ResolverTestCase {
- void test_import_package() {
- Source source = addSource("import 'package:somepackage/other.dart';");
- computeLibrarySourceErrors(source);
- assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
- }
-
- void test_import_packageWithDotDot() {
- Source source = addSource("import 'package:somepackage/../other.dart';");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CompileTimeErrorCode.URI_DOES_NOT_EXIST,
- HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
- ]);
- }
-
- void test_import_packageWithLeadingDotDot() {
- Source source = addSource("import 'package:../other.dart';");
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- CompileTimeErrorCode.URI_DOES_NOT_EXIST,
- HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
- ]);
- }
-
- void test_import_referenceIntoLibDirectory() {
- cacheSource("/myproj/pubspec.yaml", "");
- cacheSource("/myproj/lib/other.dart", "");
- Source source =
- addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
- }
-
- void test_import_referenceIntoLibDirectory_no_pubspec() {
- cacheSource("/myproj/lib/other.dart", "");
- Source source =
- addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_import_referenceOutOfLibDirectory() {
- cacheSource("/myproj/pubspec.yaml", "");
- cacheSource("/myproj/web/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
- }
-
- void test_import_referenceOutOfLibDirectory_no_pubspec() {
- cacheSource("/myproj/web/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_import_valid_inside_lib1() {
- cacheSource("/myproj/pubspec.yaml", "");
- cacheSource("/myproj/lib/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib/test.dart", "import 'other.dart';");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_import_valid_inside_lib2() {
- cacheSource("/myproj/pubspec.yaml", "");
- cacheSource("/myproj/lib/bar/other.dart", "");
- Source source = addNamedSource(
- "/myproj/lib/foo/test.dart", "import '../bar/other.dart';");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_import_valid_outside_lib() {
- cacheSource("/myproj/pubspec.yaml", "");
- cacheSource("/myproj/web/other.dart", "");
- Source source =
- addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-}
-
-/**
- * An AST visitor used to verify that all of the nodes in an AST structure that
- * should have been resolved were resolved.
- */
-class ResolutionVerifier extends RecursiveAstVisitor<Object> {
- /**
- * A set containing nodes that are known to not be resolvable and should
- * therefore not cause the test to fail.
- */
- final Set<AstNode> _knownExceptions;
-
- /**
- * A list containing all of the AST nodes that were not resolved.
- */
- List<AstNode> _unresolvedNodes = new List<AstNode>();
-
- /**
- * A list containing all of the AST nodes that were resolved to an element of
- * the wrong type.
- */
- List<AstNode> _wrongTypedNodes = new List<AstNode>();
-
- /**
- * Initialize a newly created verifier to verify that all of the identifiers
- * in the visited AST structures that are expected to have been resolved have
- * an element associated with them. Nodes in the set of [_knownExceptions] are
- * not expected to have been resolved, even if they normally would have been
- * expected to have been resolved.
- */
- ResolutionVerifier([this._knownExceptions]);
-
- /**
- * Assert that all of the visited identifiers were resolved.
- */
- void assertResolved() {
- if (!_unresolvedNodes.isEmpty || !_wrongTypedNodes.isEmpty) {
- StringBuffer buffer = new StringBuffer();
- if (!_unresolvedNodes.isEmpty) {
- buffer.write("Failed to resolve ");
- buffer.write(_unresolvedNodes.length);
- buffer.writeln(" nodes:");
- _printNodes(buffer, _unresolvedNodes);
- }
- if (!_wrongTypedNodes.isEmpty) {
- buffer.write("Resolved ");
- buffer.write(_wrongTypedNodes.length);
- buffer.writeln(" to the wrong type of element:");
- _printNodes(buffer, _wrongTypedNodes);
- }
- fail(buffer.toString());
- }
- }
-
- @override
- Object visitAnnotation(Annotation node) {
- node.visitChildren(this);
- ElementAnnotation elementAnnotation = node.elementAnnotation;
- if (elementAnnotation == null) {
- if (_knownExceptions == null || !_knownExceptions.contains(node)) {
- _unresolvedNodes.add(node);
- }
- } else if (elementAnnotation is! ElementAnnotation) {
- _wrongTypedNodes.add(node);
- }
- return null;
- }
-
- @override
- Object visitBinaryExpression(BinaryExpression node) {
- node.visitChildren(this);
- if (!node.operator.isUserDefinableOperator) {
- return null;
- }
- DartType operandType = node.leftOperand.staticType;
- if (operandType == null || operandType.isDynamic) {
- return null;
- }
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
- }
-
- @override
- Object visitCommentReference(CommentReference node) => null;
-
- @override
- Object visitCompilationUnit(CompilationUnit node) {
- node.visitChildren(this);
- return _checkResolved(
- node, node.element, (node) => node is CompilationUnitElement);
- }
-
- @override
- Object visitExportDirective(ExportDirective node) =>
- _checkResolved(node, node.element, (node) => node is ExportElement);
-
- @override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
- node.visitChildren(this);
- if (node.element is LibraryElement) {
- _wrongTypedNodes.add(node);
- }
- return null;
- }
-
- @override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
- node.visitChildren(this);
- // TODO(brianwilkerson) If we start resolving function expressions, then
- // conditionally check to see whether the node was resolved correctly.
- return null;
- //checkResolved(node, node.getElement(), FunctionElement.class);
- }
-
- @override
- Object visitImportDirective(ImportDirective node) {
- // Not sure how to test the combinators given that it isn't an error if the
- // names are not defined.
- _checkResolved(node, node.element, (node) => node is ImportElement);
- SimpleIdentifier prefix = node.prefix;
- if (prefix == null) {
- return null;
- }
- return _checkResolved(
- prefix, prefix.staticElement, (node) => node is PrefixElement);
- }
-
- @override
- Object visitIndexExpression(IndexExpression node) {
- node.visitChildren(this);
- DartType targetType = node.realTarget.staticType;
- if (targetType == null || targetType.isDynamic) {
- return null;
- }
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
- }
-
- @override
- Object visitLibraryDirective(LibraryDirective node) =>
- _checkResolved(node, node.element, (node) => node is LibraryElement);
-
- @override
- Object visitNamedExpression(NamedExpression node) =>
- node.expression.accept(this);
-
- @override
- Object visitPartDirective(PartDirective node) => _checkResolved(
- node, node.element, (node) => node is CompilationUnitElement);
-
- @override
- Object visitPartOfDirective(PartOfDirective node) =>
- _checkResolved(node, node.element, (node) => node is LibraryElement);
-
- @override
- Object visitPostfixExpression(PostfixExpression node) {
- node.visitChildren(this);
- if (!node.operator.isUserDefinableOperator) {
- return null;
- }
- DartType operandType = node.operand.staticType;
- if (operandType == null || operandType.isDynamic) {
- return null;
- }
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
- }
-
- @override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
- SimpleIdentifier prefix = node.prefix;
- prefix.accept(this);
- DartType prefixType = prefix.staticType;
- if (prefixType == null || prefixType.isDynamic) {
- return null;
- }
- return _checkResolved(node, node.staticElement, null);
- }
-
- @override
- Object visitPrefixExpression(PrefixExpression node) {
- node.visitChildren(this);
- if (!node.operator.isUserDefinableOperator) {
- return null;
- }
- DartType operandType = node.operand.staticType;
- if (operandType == null || operandType.isDynamic) {
- return null;
- }
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
- }
-
- @override
- Object visitPropertyAccess(PropertyAccess node) {
- Expression target = node.realTarget;
- target.accept(this);
- DartType targetType = target.staticType;
- if (targetType == null || targetType.isDynamic) {
- return null;
- }
- return node.propertyName.accept(this);
- }
-
- @override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
- if (node.name == "void") {
- return null;
- }
- if (node.staticType != null &&
- node.staticType.isDynamic &&
- node.staticElement == null) {
- return null;
- }
- AstNode parent = node.parent;
- if (parent is MethodInvocation) {
- MethodInvocation invocation = parent;
- if (identical(invocation.methodName, node)) {
- Expression target = invocation.realTarget;
- DartType targetType = target == null ? null : target.staticType;
- if (targetType == null || targetType.isDynamic) {
- return null;
- }
- }
- }
- return _checkResolved(node, node.staticElement, null);
- }
-
- Object _checkResolved(
- AstNode node, Element element, Predicate<Element> predicate) {
- if (element == null) {
- if (_knownExceptions == null || !_knownExceptions.contains(node)) {
- _unresolvedNodes.add(node);
- }
- } else if (predicate != null) {
- if (!predicate(element)) {
- _wrongTypedNodes.add(node);
- }
- }
- return null;
- }
-
- String _getFileName(AstNode node) {
- // TODO (jwren) there are two copies of this method, one here and one in
- // StaticTypeVerifier, they should be resolved into a single method
- if (node != null) {
- AstNode root = node.root;
- if (root is CompilationUnit) {
- CompilationUnit rootCU = root;
- if (rootCU.element != null) {
- return rootCU.element.source.fullName;
- } else {
- return "<unknown file- CompilationUnit.getElement() returned null>";
- }
- } else {
- return "<unknown file- CompilationUnit.getRoot() is not a CompilationUnit>";
- }
- }
- return "<unknown file- ASTNode is null>";
- }
-
- void _printNodes(StringBuffer buffer, List<AstNode> nodes) {
- for (AstNode identifier in nodes) {
- buffer.write(" ");
- buffer.write(identifier.toString());
- buffer.write(" (");
- buffer.write(_getFileName(identifier));
- buffer.write(" : ");
- buffer.write(identifier.offset);
- buffer.writeln(")");
- }
- }
-}
-
-class ResolverTestCase extends EngineTestCase {
- /**
- * The analysis context used to parse the compilation units being resolved.
- */
- InternalAnalysisContext analysisContext2;
-
- /**
- * Specifies if [assertErrors] should check for [HintCode.UNUSED_ELEMENT] and
- * [HintCode.UNUSED_FIELD].
- */
- bool enableUnusedElement = false;
-
- /**
- * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABLE].
- */
- bool enableUnusedLocalVariable = false;
-
- AnalysisContext get analysisContext => analysisContext2;
-
- /**
- * Return a type provider that can be used to test the results of resolution.
- *
- * @return a type provider
- * @throws AnalysisException if dart:core cannot be resolved
- */
- TypeProvider get typeProvider => analysisContext2.typeProvider;
-
- /**
- * Return a type system that can be used to test the results of resolution.
- *
- * @return a type system
- */
- TypeSystem get typeSystem => analysisContext2.typeSystem;
-
- /**
- * Add a source file to the content provider. The file path should be absolute.
- *
- * @param filePath the path of the file being added
- * @param contents the contents to be returned by the content provider for the specified file
- * @return the source object representing the added file
- */
- Source addNamedSource(String filePath, String contents) {
- Source source = cacheSource(filePath, contents);
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- analysisContext2.applyChanges(changeSet);
- return source;
- }
-
- /**
- * Add a source file to the content provider.
- *
- * @param contents the contents to be returned by the content provider for the specified file
- * @return the source object representing the added file
- */
- Source addSource(String contents) => addNamedSource("/test.dart", contents);
-
- /**
- * Assert that the number of errors reported against the given source matches the number of errors
- * that are given and that they have the expected error codes. The order in which the errors were
- * gathered is ignored.
- *
- * @param source the source against which the errors should have been reported
- * @param expectedErrorCodes the error codes of the errors that should have been reported
- * @throws AnalysisException if the reported errors could not be computed
- * @throws AssertionFailedError if a different number of errors have been reported than were
- * expected
- */
- void assertErrors(Source source,
- [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
- GatheringErrorListener errorListener = new GatheringErrorListener();
- for (AnalysisError error in analysisContext2.computeErrors(source)) {
- expect(error.source, source);
- ErrorCode errorCode = error.errorCode;
- if (!enableUnusedElement &&
- (errorCode == HintCode.UNUSED_ELEMENT ||
- errorCode == HintCode.UNUSED_FIELD)) {
- continue;
- }
- if (!enableUnusedLocalVariable &&
- (errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
- errorCode == HintCode.UNUSED_CATCH_STACK ||
- errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) {
- continue;
- }
- errorListener.onError(error);
- }
- errorListener.assertErrorsWithCodes(expectedErrorCodes);
- }
-
- /**
- * Asserts that [code] verifies, but has errors with the given error codes.
- *
- * Like [assertErrors], but takes a string of source code.
- */
- // TODO(rnystrom): Use this in more tests that have the same structure.
- void assertErrorsInCode(String code, List<ErrorCode> errors) {
- Source source = addSource(code);
- computeLibrarySourceErrors(source);
- assertErrors(source, errors);
- verify([source]);
- }
-
- /**
- * Asserts that [code] has errors with the given error codes.
- *
- * Like [assertErrors], but takes a string of source code.
- */
- void assertErrorsInUnverifiedCode(String code, List<ErrorCode> errors) {
- Source source = addSource(code);
- computeLibrarySourceErrors(source);
- assertErrors(source, errors);
- }
-
- /**
- * Assert that no errors have been reported against the given source.
- *
- * @param source the source against which no errors should have been reported
- * @throws AnalysisException if the reported errors could not be computed
- * @throws AssertionFailedError if any errors have been reported
- */
- void assertNoErrors(Source source) {
- assertErrors(source);
- }
-
- /**
- * Asserts that [code] has no errors or warnings.
- */
- // TODO(rnystrom): Use this in more tests that have the same structure.
- void assertNoErrorsInCode(String code) {
- Source source = addSource(code);
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- /**
- * Cache the source file content in the source factory but don't add the source to the analysis
- * context. The file path should be absolute.
- *
- * @param filePath the path of the file being cached
- * @param contents the contents to be returned by the content provider for the specified file
- * @return the source object representing the cached file
- */
- Source cacheSource(String filePath, String contents) {
- Source source = new FileBasedSource(FileUtilities2.createFile(filePath));
- analysisContext2.setContents(source, contents);
- return source;
- }
-
- /**
- * Change the contents of the given [source] to the given [contents].
- */
- void changeSource(Source source, String contents) {
- analysisContext2.setContents(source, contents);
- ChangeSet changeSet = new ChangeSet();
- changeSet.changedSource(source);
- analysisContext2.applyChanges(changeSet);
- }
-
- /**
- * Computes errors for the given [librarySource].
- * This assumes that the given [librarySource] and its parts have already
- * been added to the content provider using the method [addNamedSource].
- */
- void computeLibrarySourceErrors(Source librarySource) {
- analysisContext.computeErrors(librarySource);
- }
-
- /**
- * Create a library element that represents a library named `"test"` containing a single
- * empty compilation unit.
- *
- * @return the library element that was created
- */
- LibraryElementImpl createDefaultTestLibrary() =>
- createTestLibrary(AnalysisContextFactory.contextWithCore(), "test");
-
- /**
- * Create a library element that represents a library with the given name containing a single
- * empty compilation unit.
- *
- * @param libraryName the name of the library to be created
- * @return the library element that was created
- */
- LibraryElementImpl createTestLibrary(
- AnalysisContext context, String libraryName,
- [List<String> typeNames]) {
- String fileName = "$libraryName.dart";
- FileBasedSource definingCompilationUnitSource =
- _createNamedSource(fileName);
- List<CompilationUnitElement> sourcedCompilationUnits;
- if (typeNames == null) {
- sourcedCompilationUnits = CompilationUnitElement.EMPTY_LIST;
- } else {
- int count = typeNames.length;
- sourcedCompilationUnits = new List<CompilationUnitElement>(count);
- for (int i = 0; i < count; i++) {
- String typeName = typeNames[i];
- ClassElementImpl type =
- new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
- String fileName = "$typeName.dart";
- CompilationUnitElementImpl compilationUnit =
- new CompilationUnitElementImpl(fileName);
- compilationUnit.source = _createNamedSource(fileName);
- compilationUnit.librarySource = definingCompilationUnitSource;
- compilationUnit.types = <ClassElement>[type];
- sourcedCompilationUnits[i] = compilationUnit;
- }
- }
- CompilationUnitElementImpl compilationUnit =
- new CompilationUnitElementImpl(fileName);
- compilationUnit.librarySource =
- compilationUnit.source = definingCompilationUnitSource;
- LibraryElementImpl library = new LibraryElementImpl.forNode(
- context, AstFactory.libraryIdentifier2([libraryName]));
- library.definingCompilationUnit = compilationUnit;
- library.parts = sourcedCompilationUnits;
- return library;
- }
-
- Expression findTopLevelConstantExpression(
- CompilationUnit compilationUnit, String name) =>
- findTopLevelDeclaration(compilationUnit, name).initializer;
-
- VariableDeclaration findTopLevelDeclaration(
- CompilationUnit compilationUnit, String name) {
- for (CompilationUnitMember member in compilationUnit.declarations) {
- if (member is TopLevelVariableDeclaration) {
- for (VariableDeclaration variable in member.variables.variables) {
- if (variable.name.name == name) {
- return variable;
- }
- }
- }
- }
- return null;
- // Not found
- }
-
- /**
- * In the rare cases we want to group several tests into single "test_" method, so need a way to
- * reset test instance to reuse it.
- */
- void reset() {
- analysisContext2 = AnalysisContextFactory.contextWithCore();
- }
-
- /**
- * Reset the analysis context to have the given options applied.
- *
- * @param options the analysis options to be applied to the context
- */
- void resetWithOptions(AnalysisOptions options) {
- analysisContext2 =
- AnalysisContextFactory.contextWithCoreAndOptions(options);
- }
-
- /**
- * Given a library and all of its parts, resolve the contents of the library and the contents of
- * the parts. This assumes that the sources for the library and its parts have already been added
- * to the content provider using the method [addNamedSource].
- *
- * @param librarySource the source for the compilation unit that defines the library
- * @return the element representing the resolved library
- * @throws AnalysisException if the analysis could not be performed
- */
- LibraryElement resolve2(Source librarySource) =>
- analysisContext2.computeLibraryElement(librarySource);
-
- /**
- * Return the resolved compilation unit corresponding to the given source in the given library.
- *
- * @param source the source of the compilation unit to be returned
- * @param library the library in which the compilation unit is to be resolved
- * @return the resolved compilation unit
- * @throws Exception if the compilation unit could not be resolved
- */
- CompilationUnit resolveCompilationUnit(
- Source source, LibraryElement library) =>
- analysisContext2.resolveCompilationUnit(source, library);
-
- CompilationUnit resolveSource(String sourceText) =>
- resolveSource2("/test.dart", sourceText);
-
- CompilationUnit resolveSource2(String fileName, String sourceText) {
- Source source = addNamedSource(fileName, sourceText);
- LibraryElement library = analysisContext.computeLibraryElement(source);
- return analysisContext.resolveCompilationUnit(source, library);
- }
-
- Source resolveSources(List<String> sourceTexts) {
- for (int i = 0; i < sourceTexts.length; i++) {
- CompilationUnit unit =
- resolveSource2("/lib${i + 1}.dart", sourceTexts[i]);
- // reference the source if this is the last source
- if (i + 1 == sourceTexts.length) {
- return unit.element.source;
- }
- }
- return null;
- }
-
- void resolveWithAndWithoutExperimental(
- List<String> strSources,
- List<ErrorCode> codesWithoutExperimental,
- List<ErrorCode> codesWithExperimental) {
- // Setup analysis context as non-experimental
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-// options.enableDeferredLoading = false;
- resetWithOptions(options);
- // Analysis and assertions
- Source source = resolveSources(strSources);
- assertErrors(source, codesWithoutExperimental);
- verify([source]);
- // Setup analysis context as experimental
- reset();
- // Analysis and assertions
- source = resolveSources(strSources);
- assertErrors(source, codesWithExperimental);
- verify([source]);
- }
-
- void resolveWithErrors(List<String> strSources, List<ErrorCode> codes) {
- // Analysis and assertions
- Source source = resolveSources(strSources);
- assertErrors(source, codes);
- verify([source]);
- }
-
- @override
- void setUp() {
- ElementFactory.flushStaticState();
- super.setUp();
- reset();
- }
-
- @override
- void tearDown() {
- analysisContext2 = null;
- super.tearDown();
- }
-
- /**
- * Verify that all of the identifiers in the compilation units associated with
- * the given [sources] have been resolved.
- */
- void verify(List<Source> sources) {
- ResolutionVerifier verifier = new ResolutionVerifier();
- for (Source source in sources) {
- List<Source> libraries = analysisContext2.getLibrariesContaining(source);
- for (Source library in libraries) {
- analysisContext2
- .resolveCompilationUnit2(source, library)
- .accept(verifier);
- }
- }
- verifier.assertResolved();
- }
-
- /**
- * @param code the code that assigns the value to the variable "v", no matter how. We check that
- * "v" has expected static and propagated type.
- */
- void _assertPropagatedAssignedType(String code, DartType expectedStaticType,
- DartType expectedPropagatedType) {
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = ");
- expect(identifier.staticType, same(expectedStaticType));
- expect(identifier.propagatedType, same(expectedPropagatedType));
- }
-
- /**
- * @param code the code that iterates using variable "v". We check that
- * "v" has expected static and propagated type.
- */
- void _assertPropagatedIterationType(String code, DartType expectedStaticType,
- DartType expectedPropagatedType) {
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "v in ");
- expect(identifier.staticType, same(expectedStaticType));
- expect(identifier.propagatedType, same(expectedPropagatedType));
- }
-
- /**
- * Check the static and propagated types of the expression marked with "; // marker" comment.
- *
- * @param code source code to analyze, with the expression to check marked with "// marker".
- * @param expectedStaticType if non-null, check actual static type is equal to this.
- * @param expectedPropagatedType if non-null, check actual static type is equal to this.
- * @throws Exception
- */
- void _assertTypeOfMarkedExpression(String code, DartType expectedStaticType,
- DartType expectedPropagatedType) {
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "; // marker");
- if (expectedStaticType != null) {
- expect(identifier.staticType, expectedStaticType);
- }
- expect(identifier.propagatedType, expectedPropagatedType);
- }
-
- /**
- * Create a source object representing a file with the given [fileName] and
- * give it an empty content. Return the source that was created.
- */
- FileBasedSource _createNamedSource(String fileName) {
- FileBasedSource source =
- new FileBasedSource(FileUtilities2.createFile(fileName));
- analysisContext2.setContents(source, "");
- return source;
- }
-
- /**
- * Return the `SimpleIdentifier` marked by `marker`. The source code must have no
- * errors and be verifiable.
- *
- * @param code source code to analyze.
- * @param marker marker identifying sought after expression in source code.
- * @return expression marked by the marker.
- * @throws Exception
- */
- SimpleIdentifier _findMarkedIdentifier(String code, String marker) {
- try {
- Source source = addSource(code);
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = resolveCompilationUnit(source, library);
- // Could generalize this further by making [SimpleIdentifier.class] a
- // parameter.
- return EngineTestCase.findNode(
- unit, code, marker, (node) => node is SimpleIdentifier);
- } catch (exception) {
- // Is there a better exception to throw here? The point is that an
- // assertion failure here should be a failure, in both "test_*" and
- // "fail_*" tests. However, an assertion failure is success for the
- // purpose of "fail_*" tests, so without catching them here "fail_*" tests
- // can succeed by failing for the wrong reason.
- throw new JavaException("Unexexpected assertion failure: $exception");
- }
- }
-}
-
class Scope_EnclosedScopeTest_test_define_duplicate extends Scope {
GatheringErrorListener listener;
@@ -8807,3299 +668,12 @@
localLookup(name, referencingLibrary);
}
-@reflectiveTest
-class SimpleResolverTest extends ResolverTestCase {
- void fail_getter_and_setter_fromMixins_property_access() {
- // TODO(paulberry): it appears that auxiliaryElements isn't properly set on
- // a SimpleIdentifier that's inside a property access. This bug should be
- // fixed.
- Source source = addSource('''
-class B {}
-class M1 {
- get x => null;
- set x(value) {}
-}
-class M2 {
- get x => null;
- set x(value) {}
-}
-class C extends B with M1, M2 {}
-void main() {
- new C().x += 1;
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that both the getter and setter for "x" in "new C().x" refer to
- // the accessors defined in M2.
- FunctionDeclaration main =
- library.definingCompilationUnit.functions[0].computeNode();
- BlockFunctionBody body = main.functionExpression.body;
- ExpressionStatement stmt = body.block.statements[0];
- AssignmentExpression assignment = stmt.expression;
- PropertyAccess propertyAccess = assignment.leftHandSide;
- expect(
- propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
- expect(
- propertyAccess
- .propertyName.auxiliaryElements.staticElement.enclosingElement.name,
- 'M2');
- }
-
- void fail_staticInvocation() {
- Source source = addSource(r'''
-class A {
- static int get g => (a,b) => 0;
-}
-class B {
- f() {
- A.g(1,0);
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_argumentResolution_required_matching() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3);
- }
- void g(a, b, c) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2]);
- }
-
- void test_argumentResolution_required_tooFew() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2);
- }
- void g(a, b, c) {}
-}''');
- _validateArgumentResolution(source, [0, 1]);
- }
-
- void test_argumentResolution_required_tooMany() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3);
- }
- void g(a, b) {}
-}''');
- _validateArgumentResolution(source, [0, 1, -1]);
- }
-
- void test_argumentResolution_requiredAndNamed_extra() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, c: 3, d: 4);
- }
- void g(a, b, {c}) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2, -1]);
- }
-
- void test_argumentResolution_requiredAndNamed_matching() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, c: 3);
- }
- void g(a, b, {c}) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2]);
- }
-
- void test_argumentResolution_requiredAndNamed_missing() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, d: 3);
- }
- void g(a, b, {c, d}) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 3]);
- }
-
- void test_argumentResolution_requiredAndPositional_fewer() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3);
- }
- void g(a, b, [c, d]) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2]);
- }
-
- void test_argumentResolution_requiredAndPositional_matching() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3, 4);
- }
- void g(a, b, [c, d]) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2, 3]);
- }
-
- void test_argumentResolution_requiredAndPositional_more() {
- Source source = addSource(r'''
-class A {
- void f() {
- g(1, 2, 3, 4);
- }
- void g(a, b, [c]) {}
-}''');
- _validateArgumentResolution(source, [0, 1, 2, -1]);
- }
-
- void test_argumentResolution_setter_propagated() {
- Source source = addSource(r'''
-main() {
- var a = new A();
- a.sss = 0;
-}
-class A {
- set sss(x) {}
-}''');
- LibraryElement library = resolve2(source);
- CompilationUnitElement unit = library.definingCompilationUnit;
- // find "a.sss = 0"
- AssignmentExpression assignment;
- {
- FunctionElement mainElement = unit.functions[0];
- FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
- Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
- ExpressionStatement expressionStatement =
- statement as ExpressionStatement;
- assignment = expressionStatement.expression as AssignmentExpression;
- }
- // get parameter
- Expression rhs = assignment.rightHandSide;
- expect(rhs.staticParameterElement, isNull);
- ParameterElement parameter = rhs.propagatedParameterElement;
- expect(parameter, isNotNull);
- expect(parameter.displayName, "x");
- // validate
- ClassElement classA = unit.types[0];
- PropertyAccessorElement setter = classA.accessors[0];
- expect(setter.parameters[0], same(parameter));
- }
-
- void test_argumentResolution_setter_propagated_propertyAccess() {
- Source source = addSource(r'''
-main() {
- var a = new A();
- a.b.sss = 0;
-}
-class A {
- B b = new B();
-}
-class B {
- set sss(x) {}
-}''');
- LibraryElement library = resolve2(source);
- CompilationUnitElement unit = library.definingCompilationUnit;
- // find "a.b.sss = 0"
- AssignmentExpression assignment;
- {
- FunctionElement mainElement = unit.functions[0];
- FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
- Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
- ExpressionStatement expressionStatement =
- statement as ExpressionStatement;
- assignment = expressionStatement.expression as AssignmentExpression;
- }
- // get parameter
- Expression rhs = assignment.rightHandSide;
- expect(rhs.staticParameterElement, isNull);
- ParameterElement parameter = rhs.propagatedParameterElement;
- expect(parameter, isNotNull);
- expect(parameter.displayName, "x");
- // validate
- ClassElement classB = unit.types[1];
- PropertyAccessorElement setter = classB.accessors[0];
- expect(setter.parameters[0], same(parameter));
- }
-
- void test_argumentResolution_setter_static() {
- Source source = addSource(r'''
-main() {
- A a = new A();
- a.sss = 0;
-}
-class A {
- set sss(x) {}
-}''');
- LibraryElement library = resolve2(source);
- CompilationUnitElement unit = library.definingCompilationUnit;
- // find "a.sss = 0"
- AssignmentExpression assignment;
- {
- FunctionElement mainElement = unit.functions[0];
- FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
- Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
- ExpressionStatement expressionStatement =
- statement as ExpressionStatement;
- assignment = expressionStatement.expression as AssignmentExpression;
- }
- // get parameter
- Expression rhs = assignment.rightHandSide;
- ParameterElement parameter = rhs.staticParameterElement;
- expect(parameter, isNotNull);
- expect(parameter.displayName, "x");
- // validate
- ClassElement classA = unit.types[0];
- PropertyAccessorElement setter = classA.accessors[0];
- expect(setter.parameters[0], same(parameter));
- }
-
- void test_argumentResolution_setter_static_propertyAccess() {
- Source source = addSource(r'''
-main() {
- A a = new A();
- a.b.sss = 0;
-}
-class A {
- B b = new B();
-}
-class B {
- set sss(x) {}
-}''');
- LibraryElement library = resolve2(source);
- CompilationUnitElement unit = library.definingCompilationUnit;
- // find "a.b.sss = 0"
- AssignmentExpression assignment;
- {
- FunctionElement mainElement = unit.functions[0];
- FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
- Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
- ExpressionStatement expressionStatement =
- statement as ExpressionStatement;
- assignment = expressionStatement.expression as AssignmentExpression;
- }
- // get parameter
- Expression rhs = assignment.rightHandSide;
- ParameterElement parameter = rhs.staticParameterElement;
- expect(parameter, isNotNull);
- expect(parameter.displayName, "x");
- // validate
- ClassElement classB = unit.types[1];
- PropertyAccessorElement setter = classB.accessors[0];
- expect(setter.parameters[0], same(parameter));
- }
-
- void test_breakTarget_labeled() {
- // Verify that the target of the label is correctly found and is recorded
- // as the unlabeled portion of the statement.
- String text = r'''
-void f() {
- loop1: while (true) {
- loop2: for (int i = 0; i < 10; i++) {
- break loop1;
- break loop2;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- WhileStatement whileStatement = EngineTestCase.findNode(
- unit, text, 'while (true)', (n) => n is WhileStatement);
- ForStatement forStatement =
- EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
- BreakStatement break1 = EngineTestCase.findNode(
- unit, text, 'break loop1', (n) => n is BreakStatement);
- BreakStatement break2 = EngineTestCase.findNode(
- unit, text, 'break loop2', (n) => n is BreakStatement);
- expect(break1.target, same(whileStatement));
- expect(break2.target, same(forStatement));
- }
-
- void test_breakTarget_unlabeledBreakFromDo() {
- String text = r'''
-void f() {
- do {
- break;
- } while (true);
-}
-''';
- CompilationUnit unit = resolveSource(text);
- DoStatement doStatement =
- EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, same(doStatement));
- }
-
- void test_breakTarget_unlabeledBreakFromFor() {
- String text = r'''
-void f() {
- for (int i = 0; i < 10; i++) {
- break;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- ForStatement forStatement =
- EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, same(forStatement));
- }
-
- void test_breakTarget_unlabeledBreakFromForEach() {
- String text = r'''
-void f() {
- for (x in []) {
- break;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- ForEachStatement forStatement = EngineTestCase.findNode(
- unit, text, 'for', (n) => n is ForEachStatement);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, same(forStatement));
- }
-
- void test_breakTarget_unlabeledBreakFromSwitch() {
- String text = r'''
-void f() {
- while (true) {
- switch (0) {
- case 0:
- break;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- SwitchStatement switchStatement = EngineTestCase.findNode(
- unit, text, 'switch', (n) => n is SwitchStatement);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, same(switchStatement));
- }
-
- void test_breakTarget_unlabeledBreakFromWhile() {
- String text = r'''
-void f() {
- while (true) {
- break;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- WhileStatement whileStatement = EngineTestCase.findNode(
- unit, text, 'while', (n) => n is WhileStatement);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, same(whileStatement));
- }
-
- void test_breakTarget_unlabeledBreakToOuterFunction() {
- // Verify that unlabeled break statements can't resolve to loops in an
- // outer function.
- String text = r'''
-void f() {
- while (true) {
- void g() {
- break;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- BreakStatement breakStatement = EngineTestCase.findNode(
- unit, text, 'break', (n) => n is BreakStatement);
- expect(breakStatement.target, isNull);
- }
-
- void test_class_definesCall() {
- Source source = addSource(r'''
-class A {
- int call(int x) { return x; }
-}
-int f(A a) {
- return a(0);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_class_extends_implements() {
- Source source = addSource(r'''
-class A extends B implements C {}
-class B {}
-class C {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_commentReference_class() {
- Source source = addSource(r'''
-f() {}
-/** [A] [new A] [A.n] [new A.n] [m] [f] */
-class A {
- A() {}
- A.n() {}
- m() {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_commentReference_parameter() {
- Source source = addSource(r'''
-class A {
- A() {}
- A.n() {}
- /** [e] [f] */
- m(e, f()) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_commentReference_singleLine() {
- Source source = addSource(r'''
-/// [A]
-class A {}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_continueTarget_labeled() {
- // Verify that the target of the label is correctly found and is recorded
- // as the unlabeled portion of the statement.
- String text = r'''
-void f() {
- loop1: while (true) {
- loop2: for (int i = 0; i < 10; i++) {
- continue loop1;
- continue loop2;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- WhileStatement whileStatement = EngineTestCase.findNode(
- unit, text, 'while (true)', (n) => n is WhileStatement);
- ForStatement forStatement =
- EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
- ContinueStatement continue1 = EngineTestCase.findNode(
- unit, text, 'continue loop1', (n) => n is ContinueStatement);
- ContinueStatement continue2 = EngineTestCase.findNode(
- unit, text, 'continue loop2', (n) => n is ContinueStatement);
- expect(continue1.target, same(whileStatement));
- expect(continue2.target, same(forStatement));
- }
-
- void test_continueTarget_unlabeledContinueFromDo() {
- String text = r'''
-void f() {
- do {
- continue;
- } while (true);
-}
-''';
- CompilationUnit unit = resolveSource(text);
- DoStatement doStatement =
- EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, same(doStatement));
- }
-
- void test_continueTarget_unlabeledContinueFromFor() {
- String text = r'''
-void f() {
- for (int i = 0; i < 10; i++) {
- continue;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- ForStatement forStatement =
- EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, same(forStatement));
- }
-
- void test_continueTarget_unlabeledContinueFromForEach() {
- String text = r'''
-void f() {
- for (x in []) {
- continue;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- ForEachStatement forStatement = EngineTestCase.findNode(
- unit, text, 'for', (n) => n is ForEachStatement);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, same(forStatement));
- }
-
- void test_continueTarget_unlabeledContinueFromWhile() {
- String text = r'''
-void f() {
- while (true) {
- continue;
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- WhileStatement whileStatement = EngineTestCase.findNode(
- unit, text, 'while', (n) => n is WhileStatement);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, same(whileStatement));
- }
-
- void test_continueTarget_unlabeledContinueSkipsSwitch() {
- String text = r'''
-void f() {
- while (true) {
- switch (0) {
- case 0:
- continue;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- WhileStatement whileStatement = EngineTestCase.findNode(
- unit, text, 'while', (n) => n is WhileStatement);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, same(whileStatement));
- }
-
- void test_continueTarget_unlabeledContinueToOuterFunction() {
- // Verify that unlabeled continue statements can't resolve to loops in an
- // outer function.
- String text = r'''
-void f() {
- while (true) {
- void g() {
- continue;
- }
- }
-}
-''';
- CompilationUnit unit = resolveSource(text);
- ContinueStatement continueStatement = EngineTestCase.findNode(
- unit, text, 'continue', (n) => n is ContinueStatement);
- expect(continueStatement.target, isNull);
- }
-
- void test_empty() {
- Source source = addSource("");
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_entryPoint_exported() {
- addNamedSource(
- "/two.dart",
- r'''
-library two;
-main() {}''');
- Source source = addNamedSource(
- "/one.dart",
- r'''
-library one;
-export 'two.dart';''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- FunctionElement main = library.entryPoint;
- expect(main, isNotNull);
- expect(main.library, isNot(same(library)));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_entryPoint_local() {
- Source source = addNamedSource(
- "/one.dart",
- r'''
-library one;
-main() {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- FunctionElement main = library.entryPoint;
- expect(main, isNotNull);
- expect(main.library, same(library));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_entryPoint_none() {
- Source source = addNamedSource("/one.dart", "library one;");
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- expect(library.entryPoint, isNull);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_enum_externalLibrary() {
- addNamedSource(
- "/my_lib.dart",
- r'''
-library my_lib;
-enum EEE {A, B, C}''');
- Source source = addSource(r'''
-import 'my_lib.dart';
-main() {
- EEE e = null;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_extractedMethodAsConstant() {
- Source source = addSource(r'''
-abstract class Comparable<T> {
- int compareTo(T other);
- static int compare(Comparable a, Comparable b) => a.compareTo(b);
-}
-class A {
- void sort([compare = Comparable.compare]) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_fieldFormalParameter() {
- Source source = addSource(r'''
-class A {
- int x;
- A(this.x) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_forEachLoops_nonConflicting() {
- Source source = addSource(r'''
-f() {
- List list = [1,2,3];
- for (int x in list) {}
- for (int x in list) {}
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_forLoops_nonConflicting() {
- Source source = addSource(r'''
-f() {
- for (int i = 0; i < 3; i++) {
- }
- for (int i = 0; i < 3; i++) {
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_functionTypeAlias() {
- Source source = addSource(r'''
-typedef bool P(e);
-class A {
- P p;
- m(e) {
- if (p(e)) {}
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_getter_and_setter_fromMixins_bare_identifier() {
- Source source = addSource('''
-class B {}
-class M1 {
- get x => null;
- set x(value) {}
-}
-class M2 {
- get x => null;
- set x(value) {}
-}
-class C extends B with M1, M2 {
- void f() {
- x += 1;
- }
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that both the getter and setter for "x" in C.f() refer to the
- // accessors defined in M2.
- ClassElement classC = library.definingCompilationUnit.types[3];
- MethodDeclaration f = classC.getMethod('f').computeNode();
- BlockFunctionBody body = f.body;
- ExpressionStatement stmt = body.block.statements[0];
- AssignmentExpression assignment = stmt.expression;
- SimpleIdentifier leftHandSide = assignment.leftHandSide;
- expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
- expect(leftHandSide.auxiliaryElements.staticElement.enclosingElement.name,
- 'M2');
- }
-
- void test_getter_fromMixins_bare_identifier() {
- Source source = addSource('''
-class B {}
-class M1 {
- get x => null;
-}
-class M2 {
- get x => null;
-}
-class C extends B with M1, M2 {
- f() {
- return x;
- }
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the getter for "x" in C.f() refers to the getter defined in
- // M2.
- ClassElement classC = library.definingCompilationUnit.types[3];
- MethodDeclaration f = classC.getMethod('f').computeNode();
- BlockFunctionBody body = f.body;
- ReturnStatement stmt = body.block.statements[0];
- SimpleIdentifier x = stmt.expression;
- expect(x.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_getter_fromMixins_property_access() {
- Source source = addSource('''
-class B {}
-class M1 {
- get x => null;
-}
-class M2 {
- get x => null;
-}
-class C extends B with M1, M2 {}
-void main() {
- var y = new C().x;
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the getter for "x" in "new C().x" refers to the getter
- // defined in M2.
- FunctionDeclaration main =
- library.definingCompilationUnit.functions[0].computeNode();
- BlockFunctionBody body = main.functionExpression.body;
- VariableDeclarationStatement stmt = body.block.statements[0];
- PropertyAccess propertyAccess = stmt.variables.variables[0].initializer;
- expect(
- propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_getterAndSetterWithDifferentTypes() {
- Source source = addSource(r'''
-class A {
- int get f => 0;
- void set f(String s) {}
-}
-g (A a) {
- a.f = a.f.toString();
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
- verify([source]);
- }
-
- void test_hasReferenceToSuper() {
- Source source = addSource(r'''
-class A {}
-class B {toString() => super.toString();}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<ClassElement> classes = unit.types;
- expect(classes, hasLength(2));
- expect(classes[0].hasReferenceToSuper, isFalse);
- expect(classes[1].hasReferenceToSuper, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_import_hide() {
- addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-set foo(value) {}
-class A {}''');
- addNamedSource(
- "/lib2.dart",
- r'''
-library lib2;
-set foo(value) {}''');
- Source source = addNamedSource(
- "/lib3.dart",
- r'''
-import 'lib1.dart' hide foo;
-import 'lib2.dart';
-
-main() {
- foo = 0;
-}
-A a;''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_import_prefix() {
- addNamedSource(
- "/two.dart",
- r'''
-library two;
-f(int x) {
- return x * x;
-}''');
- Source source = addNamedSource(
- "/one.dart",
- r'''
-library one;
-import 'two.dart' as _two;
-main() {
- _two.f(0);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_import_spaceInUri() {
- addNamedSource(
- "/sub folder/lib.dart",
- r'''
-library lib;
-foo() {}''');
- Source source = addNamedSource(
- "/app.dart",
- r'''
-import 'sub folder/lib.dart';
-
-main() {
- foo();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_indexExpression_typeParameters() {
- Source source = addSource(r'''
-f() {
- List<int> a;
- a[0];
- List<List<int>> b;
- b[0][0];
- List<List<List<int>>> c;
- c[0][0][0];
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_indexExpression_typeParameters_invalidAssignmentWarning() {
- Source source = addSource(r'''
-f() {
- List<List<int>> b;
- b[0][0] = 'hi';
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
- verify([source]);
- }
-
- void test_indirectOperatorThroughCall() {
- Source source = addSource(r'''
-class A {
- B call() { return new B(); }
-}
-
-class B {
- int operator [](int i) { return i; }
-}
-
-A f = new A();
-
-g(int x) {}
-
-main() {
- g(f()[0]);
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_invoke_dynamicThroughGetter() {
- Source source = addSource(r'''
-class A {
- List get X => [() => 0];
- m(A a) {
- X.last;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_badSuperclass() {
- Source source = addSource(r'''
-class A extends B {}
-class B {}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isFalse);
- assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
- verify([source]);
- }
-
- void test_isValidMixin_badSuperclass_withSuperMixins() {
- resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
- Source source = addSource(r'''
-class A extends B {}
-class B {}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_constructor() {
- Source source = addSource(r'''
-class A {
- A() {}
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isFalse);
- assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
- verify([source]);
- }
-
- void test_isValidMixin_constructor_withSuperMixins() {
- resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
- Source source = addSource(r'''
-class A {
- A() {}
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isFalse);
- assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
- verify([source]);
- }
-
- void test_isValidMixin_factoryConstructor() {
- Source source = addSource(r'''
-class A {
- factory A() => null;
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_factoryConstructor_withSuperMixins() {
- resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
- Source source = addSource(r'''
-class A {
- factory A() => null;
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_super() {
- Source source = addSource(r'''
-class A {
- toString() {
- return super.toString();
- }
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isFalse);
- assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
- verify([source]);
- }
-
- void test_isValidMixin_super_withSuperMixins() {
- resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
- Source source = addSource(r'''
-class A {
- toString() {
- return super.toString();
- }
-}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_valid() {
- Source source = addSource('''
-class A {}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_isValidMixin_valid_withSuperMixins() {
- resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
- Source source = addSource('''
-class A {}
-class C = Object with A;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- ClassElement a = unit.getType('A');
- expect(a.isValidMixin, isTrue);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_labels_switch() {
- Source source = addSource(r'''
-void doSwitch(int target) {
- switch (target) {
- l0: case 0:
- continue l1;
- l1: case 1:
- continue l0;
- default:
- continue l1;
- }
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_localVariable_types_invoked() {
- Source source = addSource(r'''
-const A = null;
-main() {
- var myVar = (int p) => 'foo';
- myVar(42);
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnit unit =
- analysisContext.resolveCompilationUnit(source, library);
- expect(unit, isNotNull);
- List<bool> found = [false];
- List<CaughtException> thrownException = new List<CaughtException>(1);
- unit.accept(new _SimpleResolverTest_localVariable_types_invoked(
- this, found, thrownException));
- if (thrownException[0] != null) {
- throw new AnalysisException(
- "Exception", new CaughtException(thrownException[0], null));
- }
- expect(found[0], isTrue);
- }
-
- void test_metadata_class() {
- Source source = addSource(r'''
-const A = null;
-@A class C<A> {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unitElement = library.definingCompilationUnit;
- expect(unitElement, isNotNull);
- List<ClassElement> classes = unitElement.types;
- expect(classes, hasLength(1));
- List<ElementAnnotation> annotations = classes[0].metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = resolveCompilationUnit(source, library);
- NodeList<CompilationUnitMember> declarations = unit.declarations;
- expect(declarations, hasLength(2));
- Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
- .variables
- .variables[0]
- .name
- .staticElement;
- EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
- PropertyInducingElement, expectedElement);
- expectedElement = (expectedElement as PropertyInducingElement).getter;
- Element actualElement =
- (declarations[1] as ClassDeclaration).metadata[0].name.staticElement;
- expect(actualElement, same(expectedElement));
- }
-
- void test_metadata_field() {
- Source source = addSource(r'''
-const A = null;
-class C {
- @A int f;
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<ClassElement> classes = unit.types;
- expect(classes, hasLength(1));
- FieldElement field = classes[0].fields[0];
- List<ElementAnnotation> annotations = field.metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_fieldFormalParameter() {
- Source source = addSource(r'''
-const A = null;
-class C {
- int f;
- C(@A this.f);
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<ClassElement> classes = unit.types;
- expect(classes, hasLength(1));
- List<ConstructorElement> constructors = classes[0].constructors;
- expect(constructors, hasLength(1));
- List<ParameterElement> parameters = constructors[0].parameters;
- expect(parameters, hasLength(1));
- List<ElementAnnotation> annotations = parameters[0].metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_function() {
- Source source = addSource(r'''
-const A = null;
-@A f() {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<FunctionElement> functions = unit.functions;
- expect(functions, hasLength(1));
- List<ElementAnnotation> annotations = functions[0].metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_functionTypedParameter() {
- Source source = addSource(r'''
-const A = null;
-f(@A int p(int x)) {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<FunctionElement> functions = unit.functions;
- expect(functions, hasLength(1));
- List<ParameterElement> parameters = functions[0].parameters;
- expect(parameters, hasLength(1));
- List<ElementAnnotation> annotations1 = parameters[0].metadata;
- expect(annotations1, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_libraryDirective() {
- Source source = addSource(r'''
-@A library lib;
-const A = null;''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- List<ElementAnnotation> annotations = library.metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_method() {
- Source source = addSource(r'''
-const A = null;
-class C {
- @A void m() {}
-}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<ClassElement> classes = unit.types;
- expect(classes, hasLength(1));
- MethodElement method = classes[0].methods[0];
- List<ElementAnnotation> annotations = method.metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_namedParameter() {
- Source source = addSource(r'''
-const A = null;
-f({@A int p : 0}) {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<FunctionElement> functions = unit.functions;
- expect(functions, hasLength(1));
- List<ParameterElement> parameters = functions[0].parameters;
- expect(parameters, hasLength(1));
- List<ElementAnnotation> annotations1 = parameters[0].metadata;
- expect(annotations1, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_positionalParameter() {
- Source source = addSource(r'''
-const A = null;
-f([@A int p = 0]) {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<FunctionElement> functions = unit.functions;
- expect(functions, hasLength(1));
- List<ParameterElement> parameters = functions[0].parameters;
- expect(parameters, hasLength(1));
- List<ElementAnnotation> annotations1 = parameters[0].metadata;
- expect(annotations1, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_simpleParameter() {
- Source source = addSource(r'''
-const A = null;
-f(@A p1, @A int p2) {}''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unit = library.definingCompilationUnit;
- expect(unit, isNotNull);
- List<FunctionElement> functions = unit.functions;
- expect(functions, hasLength(1));
- List<ParameterElement> parameters = functions[0].parameters;
- expect(parameters, hasLength(2));
- List<ElementAnnotation> annotations1 = parameters[0].metadata;
- expect(annotations1, hasLength(1));
- List<ElementAnnotation> annotations2 = parameters[1].metadata;
- expect(annotations2, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_metadata_typedef() {
- Source source = addSource(r'''
-const A = null;
-@A typedef F<A>();''');
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- CompilationUnitElement unitElement = library.definingCompilationUnit;
- expect(unitElement, isNotNull);
- List<FunctionTypeAliasElement> aliases = unitElement.functionTypeAliases;
- expect(aliases, hasLength(1));
- List<ElementAnnotation> annotations = aliases[0].metadata;
- expect(annotations, hasLength(1));
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = resolveCompilationUnit(source, library);
- NodeList<CompilationUnitMember> declarations = unit.declarations;
- expect(declarations, hasLength(2));
- Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
- .variables
- .variables[0]
- .name
- .staticElement;
- EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
- PropertyInducingElement, expectedElement);
- expectedElement = (expectedElement as PropertyInducingElement).getter;
- Element actualElement =
- (declarations[1] as FunctionTypeAlias).metadata[0].name.staticElement;
- expect(actualElement, same(expectedElement));
- }
-
- void test_method_fromMixin() {
- Source source = addSource(r'''
-class B {
- bar() => 1;
-}
-class A {
- foo() => 2;
-}
-
-class C extends B with A {
- bar() => super.bar();
- foo() => super.foo();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_method_fromMixins() {
- Source source = addSource('''
-class B {}
-class M1 {
- void f() {}
-}
-class M2 {
- void f() {}
-}
-class C extends B with M1, M2 {}
-void main() {
- new C().f();
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the "f" in "new C().f()" refers to the "f" defined in M2.
- FunctionDeclaration main =
- library.definingCompilationUnit.functions[0].computeNode();
- BlockFunctionBody body = main.functionExpression.body;
- ExpressionStatement stmt = body.block.statements[0];
- MethodInvocation expr = stmt.expression;
- expect(expr.methodName.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_method_fromMixins_bare_identifier() {
- Source source = addSource('''
-class B {}
-class M1 {
- void f() {}
-}
-class M2 {
- void f() {}
-}
-class C extends B with M1, M2 {
- void g() {
- f();
- }
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the call to f() in C.g() refers to the method defined in M2.
- ClassElement classC = library.definingCompilationUnit.types[3];
- MethodDeclaration g = classC.getMethod('g').computeNode();
- BlockFunctionBody body = g.body;
- ExpressionStatement stmt = body.block.statements[0];
- MethodInvocation invocation = stmt.expression;
- SimpleIdentifier methodName = invocation.methodName;
- expect(methodName.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_method_fromMixins_invked_from_outside_class() {
- Source source = addSource('''
-class B {}
-class M1 {
- void f() {}
-}
-class M2 {
- void f() {}
-}
-class C extends B with M1, M2 {}
-void main() {
- new C().f();
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the call to f() in "new C().f()" refers to the method
- // defined in M2.
- FunctionDeclaration main =
- library.definingCompilationUnit.functions[0].computeNode();
- BlockFunctionBody body = main.functionExpression.body;
- ExpressionStatement stmt = body.block.statements[0];
- MethodInvocation invocation = stmt.expression;
- expect(invocation.methodName.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_method_fromSuperclassMixin() {
- Source source = addSource(r'''
-class A {
- void m1() {}
-}
-class B extends Object with A {
-}
-class C extends B {
-}
-f(C c) {
- c.m1();
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_methodCascades() {
- Source source = addSource(r'''
-class A {
- void m1() {}
- void m2() {}
- void m() {
- A a = new A();
- a..m1()
- ..m2();
- }
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_methodCascades_withSetter() {
- Source source = addSource(r'''
-class A {
- String name;
- void m1() {}
- void m2() {}
- void m() {
- A a = new A();
- a..m1()
- ..name = 'name'
- ..m2();
- }
-}''');
- computeLibrarySourceErrors(source);
- // failing with error code: INVOCATION_OF_NON_FUNCTION
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_resolveAgainstNull() {
- Source source = addSource(r'''
-f(var p) {
- return null == p;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- }
-
- void test_setter_fromMixins_bare_identifier() {
- Source source = addSource('''
-class B {}
-class M1 {
- set x(value) {}
-}
-class M2 {
- set x(value) {}
-}
-class C extends B with M1, M2 {
- void f() {
- x = 1;
- }
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the setter for "x" in C.f() refers to the setter defined in
- // M2.
- ClassElement classC = library.definingCompilationUnit.types[3];
- MethodDeclaration f = classC.getMethod('f').computeNode();
- BlockFunctionBody body = f.body;
- ExpressionStatement stmt = body.block.statements[0];
- AssignmentExpression assignment = stmt.expression;
- SimpleIdentifier leftHandSide = assignment.leftHandSide;
- expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_setter_fromMixins_property_access() {
- Source source = addSource('''
-class B {}
-class M1 {
- set x(value) {}
-}
-class M2 {
- set x(value) {}
-}
-class C extends B with M1, M2 {}
-void main() {
- new C().x = 1;
-}
-''');
- LibraryElement library = resolve2(source);
- assertNoErrors(source);
- verify([source]);
- // Verify that the setter for "x" in "new C().x" refers to the setter
- // defined in M2.
- FunctionDeclaration main =
- library.definingCompilationUnit.functions[0].computeNode();
- BlockFunctionBody body = main.functionExpression.body;
- ExpressionStatement stmt = body.block.statements[0];
- AssignmentExpression assignment = stmt.expression;
- PropertyAccess propertyAccess = assignment.leftHandSide;
- expect(
- propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
- }
-
- void test_setter_inherited() {
- Source source = addSource(r'''
-class A {
- int get x => 0;
- set x(int p) {}
-}
-class B extends A {
- int get x => super.x == null ? 0 : super.x;
- int f() => x = 1;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_setter_static() {
- Source source = addSource(r'''
-set s(x) {
-}
-
-main() {
- s = 123;
-}''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- /**
- * Resolve the given source and verify that the arguments in a specific method invocation were
- * correctly resolved.
- *
- * The source is expected to be source for a compilation unit, the first declaration is expected
- * to be a class, the first member of which is expected to be a method with a block body, and the
- * first statement in the body is expected to be an expression statement whose expression is a
- * method invocation. It is the arguments to that method invocation that are tested. The method
- * invocation can contain errors.
- *
- * The arguments were resolved correctly if the number of expressions in the list matches the
- * length of the array of indices and if, for each index in the array of indices, the parameter to
- * which the argument expression was resolved is the parameter in the invoked method's list of
- * parameters at that index. Arguments that should not be resolved to a parameter because of an
- * error can be denoted by including a negative index in the array of indices.
- *
- * @param source the source to be resolved
- * @param indices the array of indices used to associate arguments with parameters
- * @throws Exception if the source could not be resolved or if the structure of the source is not
- * valid
- */
- void _validateArgumentResolution(Source source, List<int> indices) {
- LibraryElement library = resolve2(source);
- expect(library, isNotNull);
- ClassElement classElement = library.definingCompilationUnit.types[0];
- List<ParameterElement> parameters = classElement.methods[1].parameters;
- CompilationUnit unit = resolveCompilationUnit(source, library);
- expect(unit, isNotNull);
- ClassDeclaration classDeclaration =
- unit.declarations[0] as ClassDeclaration;
- MethodDeclaration methodDeclaration =
- classDeclaration.members[0] as MethodDeclaration;
- Block block = (methodDeclaration.body as BlockFunctionBody).block;
- ExpressionStatement statement = block.statements[0] as ExpressionStatement;
- MethodInvocation invocation = statement.expression as MethodInvocation;
- NodeList<Expression> arguments = invocation.argumentList.arguments;
- int argumentCount = arguments.length;
- expect(argumentCount, indices.length);
- for (int i = 0; i < argumentCount; i++) {
- Expression argument = arguments[i];
- ParameterElement element = argument.staticParameterElement;
- int index = indices[i];
- if (index < 0) {
- expect(element, isNull);
- } else {
- expect(element, same(parameters[index]));
- }
- }
- }
-}
-
class SourceContainer_ChangeSetTest_test_toString implements SourceContainer {
@override
bool contains(Source source) => false;
}
/**
- * Like [StaticTypeAnalyzerTest], but as end-to-end tests.
- */
-@reflectiveTest
-class StaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared {
- void test_FunctionExpressionInvocation_block() {
- String code = r'''
-main() {
- var foo = (() { return 1; })();
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'dynamic', isNull);
- }
-
- void test_FunctionExpressionInvocation_curried() {
- String code = r'''
-typedef int F();
-F f() => null;
-main() {
- var foo = f()();
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
-
- void test_FunctionExpressionInvocation_expression() {
- String code = r'''
-main() {
- var foo = (() => 1)();
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
-
- void test_MethodInvocation_nameType_localVariable() {
- String code = r"""
-typedef Foo();
-main() {
- Foo foo;
- foo();
-}
-""";
- _resolveTestUnit(code);
- // "foo" should be resolved to the "Foo" type
- _expectIdentifierType("foo();", new isInstanceOf<FunctionType>());
- }
-
- void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() {
- String code = r"""
-typedef Foo();
-main(Foo foo) {
- foo();
-}
-""";
- _resolveTestUnit(code);
- // "foo" should be resolved to the "Foo" type
- _expectIdentifierType("foo();", new isInstanceOf<FunctionType>());
- }
-
- void test_MethodInvocation_nameType_parameter_propagatedType() {
- String code = r"""
-typedef Foo();
-main(p) {
- if (p is Foo) {
- p();
- }
-}
-""";
- _resolveTestUnit(code);
- _expectIdentifierType("p()", DynamicTypeImpl.instance,
- predicate((type) => type.name == 'Foo'));
- }
-
- void test_staticMethods_classTypeParameters() {
- String code = r'''
-class C<T> {
- static void m() => null;
-}
-main() {
- print(C.m);
-}
-''';
- _resolveTestUnit(code);
- _expectFunctionType('m);', '() → void');
- }
-
- void test_staticMethods_classTypeParameters_genericMethod() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.enableGenericMethods = true;
- resetWithOptions(options);
- String code = r'''
-class C<T> {
- static void m<S>(S s) {
- void f<U>(S s, U u) {}
- print(f);
- }
-}
-main() {
- print(C.m);
-}
-''';
- _resolveTestUnit(code);
- // C - m
- TypeParameterType typeS;
- {
- _expectFunctionType('m);', '<S>(S) → void',
- elementTypeParams: '[S]', typeFormals: '[S]');
-
- FunctionTypeImpl type = _findIdentifier('m);').staticType;
- typeS = type.typeFormals[0].type;
- type = type.instantiate([DynamicTypeImpl.instance]);
- expect(type.toString(), '(dynamic) → void');
- expect(type.typeParameters.toString(), '[S]');
- expect(type.typeArguments, [DynamicTypeImpl.instance]);
- expect(type.typeFormals, isEmpty);
- }
- // C - m - f
- {
- _expectFunctionType('f);', '<U>(S, U) → void',
- elementTypeParams: '[U]',
- typeParams: '[S]',
- typeArgs: '[S]',
- typeFormals: '[U]');
-
- FunctionTypeImpl type = _findIdentifier('f);').staticType;
- type = type.instantiate([DynamicTypeImpl.instance]);
- expect(type.toString(), '(S, dynamic) → void');
- expect(type.typeParameters.toString(), '[S, U]');
- expect(type.typeArguments, [typeS, DynamicTypeImpl.instance]);
- expect(type.typeFormals, isEmpty);
- }
- }
-}
-
-@reflectiveTest
-class StaticTypeAnalyzerTest extends EngineTestCase {
- /**
- * The error listener to which errors will be reported.
- */
- GatheringErrorListener _listener;
-
- /**
- * The resolver visitor used to create the analyzer.
- */
- ResolverVisitor _visitor;
-
- /**
- * The analyzer being used to analyze the test cases.
- */
- StaticTypeAnalyzer _analyzer;
-
- /**
- * The type provider used to access the types.
- */
- TestTypeProvider _typeProvider;
-
- /**
- * The type system used to analyze the test cases.
- */
- TypeSystem get _typeSystem => _visitor.typeSystem;
-
- void fail_visitFunctionExpressionInvocation() {
- fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- void fail_visitMethodInvocation() {
- fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- void fail_visitSimpleIdentifier() {
- fail("Not yet tested");
- _listener.assertNoErrors();
- }
-
- @override
- void setUp() {
- super.setUp();
- _listener = new GatheringErrorListener();
- _analyzer = _createAnalyzer();
- }
-
- void test_flatten_derived() {
- // class Derived<T> extends Future<T> { ... }
- ClassElementImpl derivedClass =
- ElementFactory.classElement2('Derived', ['T']);
- derivedClass.supertype = _typeProvider.futureType
- .instantiate([derivedClass.typeParameters[0].type]);
- InterfaceType intType = _typeProvider.intType;
- DartType dynamicType = _typeProvider.dynamicType;
- InterfaceType derivedIntType = derivedClass.type.instantiate([intType]);
- // flatten(Derived) = dynamic
- InterfaceType derivedDynamicType =
- derivedClass.type.instantiate([dynamicType]);
- expect(_flatten(derivedDynamicType), dynamicType);
- // flatten(Derived<int>) = int
- expect(_flatten(derivedIntType), intType);
- // flatten(Derived<Derived>) = Derived
- expect(_flatten(derivedClass.type.instantiate([derivedDynamicType])),
- derivedDynamicType);
- // flatten(Derived<Derived<int>>) = Derived<int>
- expect(_flatten(derivedClass.type.instantiate([derivedIntType])),
- derivedIntType);
- }
-
- void test_flatten_inhibit_recursion() {
- // class A extends B
- // class B extends A
- ClassElementImpl classA = ElementFactory.classElement2('A', []);
- ClassElementImpl classB = ElementFactory.classElement2('B', []);
- classA.supertype = classB.type;
- classB.supertype = classA.type;
- // flatten(A) = A and flatten(B) = B, since neither class contains Future
- // in its class hierarchy. Even though there is a loop in the class
- // hierarchy, flatten() should terminate.
- expect(_flatten(classA.type), classA.type);
- expect(_flatten(classB.type), classB.type);
- }
-
- void test_flatten_related_derived_types() {
- InterfaceType intType = _typeProvider.intType;
- InterfaceType numType = _typeProvider.numType;
- // class Derived<T> extends Future<T>
- ClassElementImpl derivedClass =
- ElementFactory.classElement2('Derived', ['T']);
- derivedClass.supertype = _typeProvider.futureType
- .instantiate([derivedClass.typeParameters[0].type]);
- InterfaceType derivedType = derivedClass.type;
- // class A extends Derived<int> implements Derived<num> { ... }
- ClassElementImpl classA =
- ElementFactory.classElement('A', derivedType.instantiate([intType]));
- classA.interfaces = <InterfaceType>[
- derivedType.instantiate([numType])
- ];
- // class B extends Future<num> implements Future<int> { ... }
- ClassElementImpl classB =
- ElementFactory.classElement('B', derivedType.instantiate([numType]));
- classB.interfaces = <InterfaceType>[
- derivedType.instantiate([intType])
- ];
- // flatten(A) = flatten(B) = int, since int is more specific than num.
- // The code in flatten() that inhibits infinite recursion shouldn't be
- // fooled by the fact that Derived appears twice in the type hierarchy.
- expect(_flatten(classA.type), intType);
- expect(_flatten(classB.type), intType);
- }
-
- void test_flatten_related_types() {
- InterfaceType futureType = _typeProvider.futureType;
- InterfaceType intType = _typeProvider.intType;
- InterfaceType numType = _typeProvider.numType;
- // class A extends Future<int> implements Future<num> { ... }
- ClassElementImpl classA =
- ElementFactory.classElement('A', futureType.instantiate([intType]));
- classA.interfaces = <InterfaceType>[
- futureType.instantiate([numType])
- ];
- // class B extends Future<num> implements Future<int> { ... }
- ClassElementImpl classB =
- ElementFactory.classElement('B', futureType.instantiate([numType]));
- classB.interfaces = <InterfaceType>[
- futureType.instantiate([intType])
- ];
- // flatten(A) = flatten(B) = int, since int is more specific than num.
- expect(_flatten(classA.type), intType);
- expect(_flatten(classB.type), intType);
- }
-
- void test_flatten_simple() {
- InterfaceType intType = _typeProvider.intType;
- DartType dynamicType = _typeProvider.dynamicType;
- InterfaceType futureDynamicType = _typeProvider.futureDynamicType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate([intType]);
- InterfaceType futureFutureDynamicType =
- _typeProvider.futureType.instantiate([futureDynamicType]);
- InterfaceType futureFutureIntType =
- _typeProvider.futureType.instantiate([futureIntType]);
- // flatten(int) = int
- expect(_flatten(intType), intType);
- // flatten(dynamic) = dynamic
- expect(_flatten(dynamicType), dynamicType);
- // flatten(Future) = dynamic
- expect(_flatten(futureDynamicType), dynamicType);
- // flatten(Future<int>) = int
- expect(_flatten(futureIntType), intType);
- // flatten(Future<Future>) = dynamic
- expect(_flatten(futureFutureDynamicType), dynamicType);
- // flatten(Future<Future<int>>) = int
- expect(_flatten(futureFutureIntType), intType);
- }
-
- void test_flatten_unrelated_types() {
- InterfaceType futureType = _typeProvider.futureType;
- InterfaceType intType = _typeProvider.intType;
- InterfaceType stringType = _typeProvider.stringType;
- // class A extends Future<int> implements Future<String> { ... }
- ClassElementImpl classA =
- ElementFactory.classElement('A', futureType.instantiate([intType]));
- classA.interfaces = <InterfaceType>[
- futureType.instantiate([stringType])
- ];
- // class B extends Future<String> implements Future<int> { ... }
- ClassElementImpl classB =
- ElementFactory.classElement('B', futureType.instantiate([stringType]));
- classB.interfaces = <InterfaceType>[
- futureType.instantiate([intType])
- ];
- // flatten(A) = A and flatten(B) = B, since neither string nor int is more
- // specific than the other.
- expect(_flatten(classA.type), classA.type);
- expect(_flatten(classB.type), classB.type);
- }
-
- void test_visitAdjacentStrings() {
- // "a" "b"
- Expression node = AstFactory
- .adjacentStrings([_resolvedString("a"), _resolvedString("b")]);
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitAsExpression() {
- // class A { ... this as B ... }
- // class B extends A {}
- ClassElement superclass = ElementFactory.classElement2("A");
- InterfaceType superclassType = superclass.type;
- ClassElement subclass = ElementFactory.classElement("B", superclassType);
- Expression node = AstFactory.asExpression(
- AstFactory.thisExpression(), AstFactory.typeName(subclass));
- expect(_analyze3(node, superclassType), same(subclass.type));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_compound() {
- // i += 1
- InterfaceType numType = _typeProvider.numType;
- SimpleIdentifier identifier = _resolvedVariable(_typeProvider.intType, "i");
- AssignmentExpression node = AstFactory.assignmentExpression(
- identifier, TokenType.PLUS_EQ, _resolvedInteger(1));
- MethodElement plusMethod = getMethod(numType, "+");
- node.staticElement = plusMethod;
- expect(_analyze(node), same(numType));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_compoundIfNull_differentTypes() {
- // double d; d ??= 0
- Expression node = AstFactory.assignmentExpression(
- _resolvedVariable(_typeProvider.doubleType, 'd'),
- TokenType.QUESTION_QUESTION_EQ,
- _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.numType));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_compoundIfNull_sameTypes() {
- // int i; i ??= 0
- Expression node = AstFactory.assignmentExpression(
- _resolvedVariable(_typeProvider.intType, 'i'),
- TokenType.QUESTION_QUESTION_EQ,
- _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitAssignmentExpression_simple() {
- // i = 0
- InterfaceType intType = _typeProvider.intType;
- Expression node = AstFactory.assignmentExpression(
- _resolvedVariable(intType, "i"), TokenType.EQ, _resolvedInteger(0));
- expect(_analyze(node), same(intType));
- _listener.assertNoErrors();
- }
-
- void test_visitAwaitExpression_flattened() {
- // await e, where e has type Future<Future<int>>
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
- InterfaceType futureFutureIntType =
- _typeProvider.futureType.instantiate(<DartType>[futureIntType]);
- Expression node =
- AstFactory.awaitExpression(_resolvedVariable(futureFutureIntType, 'e'));
- expect(_analyze(node), same(intType));
- _listener.assertNoErrors();
- }
-
- void test_visitAwaitExpression_simple() {
- // await e, where e has type Future<int>
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
- Expression node =
- AstFactory.awaitExpression(_resolvedVariable(futureIntType, 'e'));
- expect(_analyze(node), same(intType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_equals() {
- // 2 == 3
- Expression node = AstFactory.binaryExpression(
- _resolvedInteger(2), TokenType.EQ_EQ, _resolvedInteger(3));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_ifNull() {
- // 1 ?? 1.5
- Expression node = AstFactory.binaryExpression(
- _resolvedInteger(1), TokenType.QUESTION_QUESTION, _resolvedDouble(1.5));
- expect(_analyze(node), same(_typeProvider.numType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_logicalAnd() {
- // false && true
- Expression node = AstFactory.binaryExpression(
- AstFactory.booleanLiteral(false),
- TokenType.AMPERSAND_AMPERSAND,
- AstFactory.booleanLiteral(true));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_logicalOr() {
- // false || true
- Expression node = AstFactory.binaryExpression(
- AstFactory.booleanLiteral(false),
- TokenType.BAR_BAR,
- AstFactory.booleanLiteral(true));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_minusID_propagated() {
- // a - b
- BinaryExpression node = AstFactory.binaryExpression(
- _propagatedVariable(_typeProvider.intType, 'a'),
- TokenType.MINUS,
- _propagatedVariable(_typeProvider.doubleType, 'b'));
- node.propagatedElement = getMethod(_typeProvider.numType, "+");
- _analyze(node);
- expect(node.propagatedType, same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_notEquals() {
- // 2 != 3
- Expression node = AstFactory.binaryExpression(
- _resolvedInteger(2), TokenType.BANG_EQ, _resolvedInteger(3));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_plusID() {
- // 1 + 2.0
- BinaryExpression node = AstFactory.binaryExpression(
- _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
- node.staticElement = getMethod(_typeProvider.numType, "+");
- expect(_analyze(node), same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_plusII() {
- // 1 + 2
- BinaryExpression node = AstFactory.binaryExpression(
- _resolvedInteger(1), TokenType.PLUS, _resolvedInteger(2));
- node.staticElement = getMethod(_typeProvider.numType, "+");
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_plusII_propagated() {
- // a + b
- BinaryExpression node = AstFactory.binaryExpression(
- _propagatedVariable(_typeProvider.intType, 'a'),
- TokenType.PLUS,
- _propagatedVariable(_typeProvider.intType, 'b'));
- node.propagatedElement = getMethod(_typeProvider.numType, "+");
- _analyze(node);
- expect(node.propagatedType, same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_slash() {
- // 2 / 2
- BinaryExpression node = AstFactory.binaryExpression(
- _resolvedInteger(2), TokenType.SLASH, _resolvedInteger(2));
- node.staticElement = getMethod(_typeProvider.numType, "/");
- expect(_analyze(node), same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_star_notSpecial() {
- // class A {
- // A operator *(double value);
- // }
- // (a as A) * 2.0
- ClassElementImpl classA = ElementFactory.classElement2("A");
- InterfaceType typeA = classA.type;
- MethodElement operator =
- ElementFactory.methodElement("*", typeA, [_typeProvider.doubleType]);
- classA.methods = <MethodElement>[operator];
- BinaryExpression node = AstFactory.binaryExpression(
- AstFactory.asExpression(
- AstFactory.identifier3("a"), AstFactory.typeName(classA)),
- TokenType.PLUS,
- _resolvedDouble(2.0));
- node.staticElement = operator;
- expect(_analyze(node), same(typeA));
- _listener.assertNoErrors();
- }
-
- void test_visitBinaryExpression_starID() {
- // 1 * 2.0
- BinaryExpression node = AstFactory.binaryExpression(
- _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
- node.staticElement = getMethod(_typeProvider.numType, "*");
- expect(_analyze(node), same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
- void test_visitBooleanLiteral_false() {
- // false
- Expression node = AstFactory.booleanLiteral(false);
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitBooleanLiteral_true() {
- // true
- Expression node = AstFactory.booleanLiteral(true);
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitCascadeExpression() {
- // a..length
- Expression node = AstFactory.cascadeExpression(
- _resolvedString("a"), [AstFactory.propertyAccess2(null, "length")]);
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitConditionalExpression_differentTypes() {
- // true ? 1.0 : 0
- Expression node = AstFactory.conditionalExpression(
- AstFactory.booleanLiteral(true),
- _resolvedDouble(1.0),
- _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.numType));
- _listener.assertNoErrors();
- }
-
- void test_visitConditionalExpression_sameTypes() {
- // true ? 1 : 0
- Expression node = AstFactory.conditionalExpression(
- AstFactory.booleanLiteral(true),
- _resolvedInteger(1),
- _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitDoubleLiteral() {
- // 4.33
- Expression node = AstFactory.doubleLiteral(4.33);
- expect(_analyze(node), same(_typeProvider.doubleType));
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_async_block() {
- // () async {}
- BlockFunctionBody body = AstFactory.blockFunctionBody2();
- body.keyword = TokenFactory.tokenFromString('async');
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.futureDynamicType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_async_expression() {
- // () async => e, where e has type int
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
- Expression expression = _resolvedVariable(intType, 'e');
- ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
- body.keyword = TokenFactory.tokenFromString('async');
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(futureIntType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_async_expression_flatten() {
- // () async => e, where e has type Future<int>
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
- Expression expression = _resolvedVariable(futureIntType, 'e');
- ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
- body.keyword = TokenFactory.tokenFromString('async');
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(futureIntType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_async_expression_flatten_twice() {
- // () async => e, where e has type Future<Future<int>>
- InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
- InterfaceType futureFutureIntType =
- _typeProvider.futureType.instantiate(<DartType>[futureIntType]);
- Expression expression = _resolvedVariable(futureFutureIntType, 'e');
- ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
- body.keyword = TokenFactory.tokenFromString('async');
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(futureIntType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_generator_async() {
- // () async* {}
- BlockFunctionBody body = AstFactory.blockFunctionBody2();
- body.keyword = TokenFactory.tokenFromString('async');
- body.star = TokenFactory.tokenFromType(TokenType.STAR);
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.streamDynamicType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_generator_sync() {
- // () sync* {}
- BlockFunctionBody body = AstFactory.blockFunctionBody2();
- body.keyword = TokenFactory.tokenFromString('sync');
- body.star = TokenFactory.tokenFromType(TokenType.STAR);
- FunctionExpression node =
- _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.iterableDynamicType, null, null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_named_block() {
- // ({p1 : 0, p2 : 0}) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.namedFormalParameter(
- AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.namedFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
- expectedNamedTypes["p1"] = dynamicType;
- expectedNamedTypes["p2"] = dynamicType;
- _assertFunctionType(
- dynamicType, null, null, expectedNamedTypes, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_named_expression() {
- // ({p : 0}) -> 0;
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p = AstFactory.namedFormalParameter(
- AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
- _setType(p, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p);
- DartType resultType = _analyze(node);
- Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
- expectedNamedTypes["p"] = dynamicType;
- _assertFunctionType(
- _typeProvider.intType, null, null, expectedNamedTypes, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normal_block() {
- // (p1, p2) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.simpleFormalParameter3("p2");
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- _assertFunctionType(dynamicType, <DartType>[dynamicType, dynamicType], null,
- null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normal_expression() {
- // (p1, p2) -> 0
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p = AstFactory.simpleFormalParameter3("p");
- _setType(p, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.intType, <DartType>[dynamicType], null, null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normalAndNamed_block() {
- // (p1, {p2 : 0}) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.namedFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p2);
- DartType resultType = _analyze(node);
- Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
- expectedNamedTypes["p2"] = dynamicType;
- _assertFunctionType(dynamicType, <DartType>[dynamicType], null,
- expectedNamedTypes, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normalAndNamed_expression() {
- // (p1, {p2 : 0}) -> 0
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.namedFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p2);
- DartType resultType = _analyze(node);
- Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
- expectedNamedTypes["p2"] = dynamicType;
- _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], null,
- expectedNamedTypes, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normalAndPositional_block() {
- // (p1, [p2 = 0]) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.positionalFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- _assertFunctionType(dynamicType, <DartType>[dynamicType],
- <DartType>[dynamicType], null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_normalAndPositional_expression() {
- // (p1, [p2 = 0]) -> 0
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.positionalFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType],
- <DartType>[dynamicType], null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_positional_block() {
- // ([p1 = 0, p2 = 0]) {}
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p1 = AstFactory.positionalFormalParameter(
- AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
- _setType(p1, dynamicType);
- FormalParameter p2 = AstFactory.positionalFormalParameter(
- AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
- _setType(p2, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p1, p2]),
- AstFactory.blockFunctionBody2());
- _analyze5(p1);
- _analyze5(p2);
- DartType resultType = _analyze(node);
- _assertFunctionType(dynamicType, null, <DartType>[dynamicType, dynamicType],
- null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitFunctionExpression_positional_expression() {
- // ([p1 = 0, p2 = 0]) -> 0
- DartType dynamicType = _typeProvider.dynamicType;
- FormalParameter p = AstFactory.positionalFormalParameter(
- AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
- _setType(p, dynamicType);
- FunctionExpression node = _resolvedFunctionExpression(
- AstFactory.formalParameterList([p]),
- AstFactory.expressionFunctionBody(_resolvedInteger(0)));
- _analyze5(p);
- DartType resultType = _analyze(node);
- _assertFunctionType(
- _typeProvider.intType, null, <DartType>[dynamicType], null, resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_getter() {
- // List a;
- // a[2]
- InterfaceType listType = _typeProvider.listType;
- SimpleIdentifier identifier = _resolvedVariable(listType, "a");
- IndexExpression node =
- AstFactory.indexExpression(identifier, _resolvedInteger(2));
- MethodElement indexMethod = listType.element.methods[0];
- node.staticElement = indexMethod;
- expect(_analyze(node), same(listType.typeArguments[0]));
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_setter() {
- // List a;
- // a[2] = 0
- InterfaceType listType = _typeProvider.listType;
- SimpleIdentifier identifier = _resolvedVariable(listType, "a");
- IndexExpression node =
- AstFactory.indexExpression(identifier, _resolvedInteger(2));
- MethodElement indexMethod = listType.element.methods[1];
- node.staticElement = indexMethod;
- AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
- expect(_analyze(node), same(listType.typeArguments[0]));
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_typeParameters() {
- // List<int> list = ...
- // list[0]
- InterfaceType intType = _typeProvider.intType;
- InterfaceType listType = _typeProvider.listType;
- // (int) -> E
- MethodElement methodElement = getMethod(listType, "[]");
- // "list" has type List<int>
- SimpleIdentifier identifier = AstFactory.identifier3("list");
- InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
- identifier.staticType = listOfIntType;
- // list[0] has MethodElement element (int) -> E
- IndexExpression indexExpression =
- AstFactory.indexExpression(identifier, AstFactory.integer(0));
- MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
- indexExpression.staticElement = indexMethod;
- // analyze and assert result of the index expression
- expect(_analyze(indexExpression), same(intType));
- _listener.assertNoErrors();
- }
-
- void test_visitIndexExpression_typeParameters_inSetterContext() {
- // List<int> list = ...
- // list[0] = 0;
- InterfaceType intType = _typeProvider.intType;
- InterfaceType listType = _typeProvider.listType;
- // (int, E) -> void
- MethodElement methodElement = getMethod(listType, "[]=");
- // "list" has type List<int>
- SimpleIdentifier identifier = AstFactory.identifier3("list");
- InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
- identifier.staticType = listOfIntType;
- // list[0] has MethodElement element (int) -> E
- IndexExpression indexExpression =
- AstFactory.indexExpression(identifier, AstFactory.integer(0));
- MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
- indexExpression.staticElement = indexMethod;
- // list[0] should be in a setter context
- AstFactory.assignmentExpression(
- indexExpression, TokenType.EQ, AstFactory.integer(0));
- // analyze and assert result of the index expression
- expect(_analyze(indexExpression), same(intType));
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_named() {
- // new C.m()
- ClassElementImpl classElement = ElementFactory.classElement2("C");
- String constructorName = "m";
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(classElement, constructorName);
- constructor.returnType = classElement.type;
- FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
- constructor.type = constructorType;
- classElement.constructors = <ConstructorElement>[constructor];
- InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
- null,
- AstFactory.typeName(classElement),
- [AstFactory.identifier3(constructorName)]);
- node.staticElement = constructor;
- expect(_analyze(node), same(classElement.type));
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_typeParameters() {
- // new C<I>()
- ClassElementImpl elementC = ElementFactory.classElement2("C", ["E"]);
- ClassElementImpl elementI = ElementFactory.classElement2("I");
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(elementC, null);
- elementC.constructors = <ConstructorElement>[constructor];
- constructor.returnType = elementC.type;
- FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
- constructor.type = constructorType;
- TypeName typeName =
- AstFactory.typeName(elementC, [AstFactory.typeName(elementI)]);
- typeName.type = elementC.type.instantiate(<DartType>[elementI.type]);
- InstanceCreationExpression node =
- AstFactory.instanceCreationExpression2(null, typeName);
- node.staticElement = constructor;
- InterfaceType interfaceType = _analyze(node) as InterfaceType;
- List<DartType> typeArgs = interfaceType.typeArguments;
- expect(typeArgs.length, 1);
- expect(typeArgs[0], elementI.type);
- _listener.assertNoErrors();
- }
-
- void test_visitInstanceCreationExpression_unnamed() {
- // new C()
- ClassElementImpl classElement = ElementFactory.classElement2("C");
- ConstructorElementImpl constructor =
- ElementFactory.constructorElement2(classElement, null);
- constructor.returnType = classElement.type;
- FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
- constructor.type = constructorType;
- classElement.constructors = <ConstructorElement>[constructor];
- InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
- null, AstFactory.typeName(classElement));
- node.staticElement = constructor;
- expect(_analyze(node), same(classElement.type));
- _listener.assertNoErrors();
- }
-
- void test_visitIntegerLiteral() {
- // 42
- Expression node = _resolvedInteger(42);
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitIsExpression_negated() {
- // a is! String
- Expression node = AstFactory.isExpression(
- _resolvedString("a"), true, AstFactory.typeName4("String"));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitIsExpression_notNegated() {
- // a is String
- Expression node = AstFactory.isExpression(
- _resolvedString("a"), false, AstFactory.typeName4("String"));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitListLiteral_empty() {
- // []
- Expression node = AstFactory.listLiteral();
- DartType resultType = _analyze(node);
- _assertType2(
- _typeProvider.listType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitListLiteral_nonEmpty() {
- // [0]
- Expression node = AstFactory.listLiteral([_resolvedInteger(0)]);
- DartType resultType = _analyze(node);
- _assertType2(
- _typeProvider.listType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitMapLiteral_empty() {
- // {}
- Expression node = AstFactory.mapLiteral2();
- DartType resultType = _analyze(node);
- _assertType2(
- _typeProvider.mapType.instantiate(
- <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
- resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitMapLiteral_nonEmpty() {
- // {"k" : 0}
- Expression node = AstFactory
- .mapLiteral2([AstFactory.mapLiteralEntry("k", _resolvedInteger(0))]);
- DartType resultType = _analyze(node);
- _assertType2(
- _typeProvider.mapType.instantiate(
- <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
- resultType);
- _listener.assertNoErrors();
- }
-
- void test_visitMethodInvocation_then() {
- // then()
- Expression node = AstFactory.methodInvocation(null, "then");
- _analyze(node);
- _listener.assertNoErrors();
- }
-
- void test_visitNamedExpression() {
- // n: a
- Expression node = AstFactory.namedExpression2("n", _resolvedString("a"));
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitNullLiteral() {
- // null
- Expression node = AstFactory.nullLiteral();
- expect(_analyze(node), same(_typeProvider.bottomType));
- _listener.assertNoErrors();
- }
-
- void test_visitParenthesizedExpression() {
- // (0)
- Expression node = AstFactory.parenthesizedExpression(_resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPostfixExpression_minusMinus() {
- // 0--
- PostfixExpression node = AstFactory.postfixExpression(
- _resolvedInteger(0), TokenType.MINUS_MINUS);
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPostfixExpression_plusPlus() {
- // 0++
- PostfixExpression node =
- AstFactory.postfixExpression(_resolvedInteger(0), TokenType.PLUS_PLUS);
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_getter() {
- DartType boolType = _typeProvider.boolType;
- PropertyAccessorElementImpl getter =
- ElementFactory.getterElement("b", false, boolType);
- PrefixedIdentifier node = AstFactory.identifier5("a", "b");
- node.identifier.staticElement = getter;
- expect(_analyze(node), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_setter() {
- DartType boolType = _typeProvider.boolType;
- FieldElementImpl field =
- ElementFactory.fieldElement("b", false, false, false, boolType);
- PropertyAccessorElement setter = field.setter;
- PrefixedIdentifier node = AstFactory.identifier5("a", "b");
- node.identifier.staticElement = setter;
- expect(_analyze(node), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixedIdentifier_variable() {
- VariableElementImpl variable = ElementFactory.localVariableElement2("b");
- variable.type = _typeProvider.boolType;
- PrefixedIdentifier node = AstFactory.identifier5("a", "b");
- node.identifier.staticElement = variable;
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_bang() {
- // !0
- PrefixExpression node =
- AstFactory.prefixExpression(TokenType.BANG, _resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_minus() {
- // -0
- PrefixExpression node =
- AstFactory.prefixExpression(TokenType.MINUS, _resolvedInteger(0));
- MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
- node.staticElement = minusMethod;
- expect(_analyze(node), same(_typeProvider.numType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_minusMinus() {
- // --0
- PrefixExpression node =
- AstFactory.prefixExpression(TokenType.MINUS_MINUS, _resolvedInteger(0));
- MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
- node.staticElement = minusMethod;
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_not() {
- // !true
- Expression node = AstFactory.prefixExpression(
- TokenType.BANG, AstFactory.booleanLiteral(true));
- expect(_analyze(node), same(_typeProvider.boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_plusPlus() {
- // ++0
- PrefixExpression node =
- AstFactory.prefixExpression(TokenType.PLUS_PLUS, _resolvedInteger(0));
- MethodElement plusMethod = getMethod(_typeProvider.numType, "+");
- node.staticElement = plusMethod;
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPrefixExpression_tilde() {
- // ~0
- PrefixExpression node =
- AstFactory.prefixExpression(TokenType.TILDE, _resolvedInteger(0));
- MethodElement tildeMethod = getMethod(_typeProvider.intType, "~");
- node.staticElement = tildeMethod;
- expect(_analyze(node), same(_typeProvider.intType));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_propagated_getter() {
- DartType boolType = _typeProvider.boolType;
- PropertyAccessorElementImpl getter =
- ElementFactory.getterElement("b", false, boolType);
- PropertyAccess node =
- AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
- node.propertyName.propagatedElement = getter;
- expect(_analyze2(node, false), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_propagated_setter() {
- DartType boolType = _typeProvider.boolType;
- FieldElementImpl field =
- ElementFactory.fieldElement("b", false, false, false, boolType);
- PropertyAccessorElement setter = field.setter;
- PropertyAccess node =
- AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
- node.propertyName.propagatedElement = setter;
- expect(_analyze2(node, false), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_static_getter() {
- DartType boolType = _typeProvider.boolType;
- PropertyAccessorElementImpl getter =
- ElementFactory.getterElement("b", false, boolType);
- PropertyAccess node =
- AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
- node.propertyName.staticElement = getter;
- expect(_analyze(node), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitPropertyAccess_static_setter() {
- DartType boolType = _typeProvider.boolType;
- FieldElementImpl field =
- ElementFactory.fieldElement("b", false, false, false, boolType);
- PropertyAccessorElement setter = field.setter;
- PropertyAccess node =
- AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
- node.propertyName.staticElement = setter;
- expect(_analyze(node), same(boolType));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleIdentifier_dynamic() {
- // "dynamic"
- SimpleIdentifier identifier = AstFactory.identifier3('dynamic');
- DynamicElementImpl element = DynamicElementImpl.instance;
- identifier.staticElement = element;
- identifier.staticType = _typeProvider.typeType;
- expect(_analyze(identifier), same(_typeProvider.typeType));
- _listener.assertNoErrors();
- }
-
- void test_visitSimpleStringLiteral() {
- // "a"
- Expression node = _resolvedString("a");
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitStringInterpolation() {
- // "a${'b'}c"
- Expression node = AstFactory.string([
- AstFactory.interpolationString("a", "a"),
- AstFactory.interpolationExpression(_resolvedString("b")),
- AstFactory.interpolationString("c", "c")
- ]);
- expect(_analyze(node), same(_typeProvider.stringType));
- _listener.assertNoErrors();
- }
-
- void test_visitSuperExpression() {
- // super
- InterfaceType superType = ElementFactory.classElement2("A").type;
- InterfaceType thisType = ElementFactory.classElement("B", superType).type;
- Expression node = AstFactory.superExpression();
- expect(_analyze3(node, thisType), same(thisType));
- _listener.assertNoErrors();
- }
-
- void test_visitSymbolLiteral() {
- expect(_analyze(AstFactory.symbolLiteral(["a"])),
- same(_typeProvider.symbolType));
- }
-
- void test_visitThisExpression() {
- // this
- InterfaceType thisType = ElementFactory
- .classElement("B", ElementFactory.classElement2("A").type)
- .type;
- Expression node = AstFactory.thisExpression();
- expect(_analyze3(node, thisType), same(thisType));
- _listener.assertNoErrors();
- }
-
- void test_visitThrowExpression_withoutValue() {
- // throw
- Expression node = AstFactory.throwExpression();
- expect(_analyze(node), same(_typeProvider.bottomType));
- _listener.assertNoErrors();
- }
-
- void test_visitThrowExpression_withValue() {
- // throw 0
- Expression node = AstFactory.throwExpression2(_resolvedInteger(0));
- expect(_analyze(node), same(_typeProvider.bottomType));
- _listener.assertNoErrors();
- }
-
- /**
- * Return the type associated with the given expression after the static type analyzer has
- * computed a type for it.
- *
- * @param node the expression with which the type is associated
- * @return the type associated with the expression
- */
- DartType _analyze(Expression node) => _analyze4(node, null, true);
-
- /**
- * Return the type associated with the given expression after the static or propagated type
- * analyzer has computed a type for it.
- *
- * @param node the expression with which the type is associated
- * @param useStaticType `true` if the static type is being requested, and `false` if
- * the propagated type is being requested
- * @return the type associated with the expression
- */
- DartType _analyze2(Expression node, bool useStaticType) =>
- _analyze4(node, null, useStaticType);
-
- /**
- * Return the type associated with the given expression after the static type analyzer has
- * computed a type for it.
- *
- * @param node the expression with which the type is associated
- * @param thisType the type of 'this'
- * @return the type associated with the expression
- */
- DartType _analyze3(Expression node, InterfaceType thisType) =>
- _analyze4(node, thisType, true);
-
- /**
- * Return the type associated with the given expression after the static type analyzer has
- * computed a type for it.
- *
- * @param node the expression with which the type is associated
- * @param thisType the type of 'this'
- * @param useStaticType `true` if the static type is being requested, and `false` if
- * the propagated type is being requested
- * @return the type associated with the expression
- */
- DartType _analyze4(
- Expression node, InterfaceType thisType, bool useStaticType) {
- try {
- _analyzer.thisType = thisType;
- } catch (exception) {
- throw new IllegalArgumentException(
- "Could not set type of 'this'", exception);
- }
- node.accept(_analyzer);
- if (useStaticType) {
- return node.staticType;
- } else {
- return node.propagatedType;
- }
- }
-
- /**
- * Return the type associated with the given parameter after the static type analyzer has computed
- * a type for it.
- *
- * @param node the parameter with which the type is associated
- * @return the type associated with the parameter
- */
- DartType _analyze5(FormalParameter node) {
- node.accept(_analyzer);
- return (node.identifier.staticElement as ParameterElement).type;
- }
-
- /**
- * Assert that the actual type is a function type with the expected characteristics.
- *
- * @param expectedReturnType the expected return type of the function
- * @param expectedNormalTypes the expected types of the normal parameters
- * @param expectedOptionalTypes the expected types of the optional parameters
- * @param expectedNamedTypes the expected types of the named parameters
- * @param actualType the type being tested
- */
- void _assertFunctionType(
- DartType expectedReturnType,
- List<DartType> expectedNormalTypes,
- List<DartType> expectedOptionalTypes,
- Map<String, DartType> expectedNamedTypes,
- DartType actualType) {
- EngineTestCase.assertInstanceOf(
- (obj) => obj is FunctionType, FunctionType, actualType);
- FunctionType functionType = actualType as FunctionType;
- List<DartType> normalTypes = functionType.normalParameterTypes;
- if (expectedNormalTypes == null) {
- expect(normalTypes, hasLength(0));
- } else {
- int expectedCount = expectedNormalTypes.length;
- expect(normalTypes, hasLength(expectedCount));
- for (int i = 0; i < expectedCount; i++) {
- expect(normalTypes[i], same(expectedNormalTypes[i]));
- }
- }
- List<DartType> optionalTypes = functionType.optionalParameterTypes;
- if (expectedOptionalTypes == null) {
- expect(optionalTypes, hasLength(0));
- } else {
- int expectedCount = expectedOptionalTypes.length;
- expect(optionalTypes, hasLength(expectedCount));
- for (int i = 0; i < expectedCount; i++) {
- expect(optionalTypes[i], same(expectedOptionalTypes[i]));
- }
- }
- Map<String, DartType> namedTypes = functionType.namedParameterTypes;
- if (expectedNamedTypes == null) {
- expect(namedTypes, hasLength(0));
- } else {
- expect(namedTypes, hasLength(expectedNamedTypes.length));
- expectedNamedTypes.forEach((String name, DartType type) {
- expect(namedTypes[name], same(type));
- });
- }
- expect(functionType.returnType, equals(expectedReturnType));
- }
-
- void _assertType(
- InterfaceTypeImpl expectedType, InterfaceTypeImpl actualType) {
- expect(actualType.displayName, expectedType.displayName);
- expect(actualType.element, expectedType.element);
- List<DartType> expectedArguments = expectedType.typeArguments;
- int length = expectedArguments.length;
- List<DartType> actualArguments = actualType.typeArguments;
- expect(actualArguments, hasLength(length));
- for (int i = 0; i < length; i++) {
- _assertType2(expectedArguments[i], actualArguments[i]);
- }
- }
-
- void _assertType2(DartType expectedType, DartType actualType) {
- if (expectedType is InterfaceTypeImpl) {
- EngineTestCase.assertInstanceOf(
- (obj) => obj is InterfaceTypeImpl, InterfaceTypeImpl, actualType);
- _assertType(expectedType, actualType as InterfaceTypeImpl);
- }
- // TODO(brianwilkerson) Compare other kinds of types then make this a shared
- // utility method.
- }
-
- /**
- * Create the analyzer used by the tests.
- *
- * @return the analyzer to be used by the tests
- */
- StaticTypeAnalyzer _createAnalyzer() {
- InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
- FileBasedSource source =
- new FileBasedSource(FileUtilities2.createFile("/lib.dart"));
- CompilationUnitElementImpl definingCompilationUnit =
- new CompilationUnitElementImpl("lib.dart");
- definingCompilationUnit.librarySource =
- definingCompilationUnit.source = source;
- LibraryElementImpl definingLibrary =
- new LibraryElementImpl.forNode(context, null);
- definingLibrary.definingCompilationUnit = definingCompilationUnit;
- _typeProvider = new TestTypeProvider(context);
- _visitor = new ResolverVisitor(
- definingLibrary, source, _typeProvider, _listener,
- nameScope: new LibraryScope(definingLibrary, _listener));
- _visitor.overrideManager.enterScope();
- try {
- return _visitor.typeAnalyzer;
- } catch (exception) {
- throw new IllegalArgumentException(
- "Could not create analyzer", exception);
- }
- }
-
- DartType _flatten(DartType type) => type.flattenFutures(_typeSystem);
-
- /**
- * Return a simple identifier that has been resolved to a variable element with the given type.
- *
- * @param type the type of the variable being represented
- * @param variableName the name of the variable
- * @return a simple identifier that has been resolved to a variable element with the given type
- */
- SimpleIdentifier _propagatedVariable(
- InterfaceType type, String variableName) {
- SimpleIdentifier identifier = AstFactory.identifier3(variableName);
- VariableElementImpl element =
- ElementFactory.localVariableElement(identifier);
- element.type = type;
- identifier.staticType = _typeProvider.dynamicType;
- identifier.propagatedElement = element;
- identifier.propagatedType = type;
- return identifier;
- }
-
- /**
- * Return an integer literal that has been resolved to the correct type.
- *
- * @param value the value of the literal
- * @return an integer literal that has been resolved to the correct type
- */
- DoubleLiteral _resolvedDouble(double value) {
- DoubleLiteral literal = AstFactory.doubleLiteral(value);
- literal.staticType = _typeProvider.doubleType;
- return literal;
- }
-
- /**
- * Create a function expression that has an element associated with it, where the element has an
- * incomplete type associated with it (just like the one
- * [ElementBuilder.visitFunctionExpression] would have built if we had
- * run it).
- *
- * @param parameters the parameters to the function
- * @param body the body of the function
- * @return a resolved function expression
- */
- FunctionExpression _resolvedFunctionExpression(
- FormalParameterList parameters, FunctionBody body) {
- List<ParameterElement> parameterElements = new List<ParameterElement>();
- for (FormalParameter parameter in parameters.parameters) {
- ParameterElementImpl element =
- new ParameterElementImpl.forNode(parameter.identifier);
- element.parameterKind = parameter.kind;
- element.type = _typeProvider.dynamicType;
- parameter.identifier.staticElement = element;
- parameterElements.add(element);
- }
- FunctionExpression node = AstFactory.functionExpression2(parameters, body);
- FunctionElementImpl element = new FunctionElementImpl.forNode(null);
- element.parameters = parameterElements;
- element.type = new FunctionTypeImpl(element);
- node.element = element;
- return node;
- }
-
- /**
- * Return an integer literal that has been resolved to the correct type.
- *
- * @param value the value of the literal
- * @return an integer literal that has been resolved to the correct type
- */
- IntegerLiteral _resolvedInteger(int value) {
- IntegerLiteral literal = AstFactory.integer(value);
- literal.staticType = _typeProvider.intType;
- return literal;
- }
-
- /**
- * Return a string literal that has been resolved to the correct type.
- *
- * @param value the value of the literal
- * @return a string literal that has been resolved to the correct type
- */
- SimpleStringLiteral _resolvedString(String value) {
- SimpleStringLiteral string = AstFactory.string2(value);
- string.staticType = _typeProvider.stringType;
- return string;
- }
-
- /**
- * Return a simple identifier that has been resolved to a variable element with the given type.
- *
- * @param type the type of the variable being represented
- * @param variableName the name of the variable
- * @return a simple identifier that has been resolved to a variable element with the given type
- */
- SimpleIdentifier _resolvedVariable(InterfaceType type, String variableName) {
- SimpleIdentifier identifier = AstFactory.identifier3(variableName);
- VariableElementImpl element =
- ElementFactory.localVariableElement(identifier);
- element.type = type;
- identifier.staticElement = element;
- identifier.staticType = type;
- return identifier;
- }
-
- /**
- * Set the type of the given parameter to the given type.
- *
- * @param parameter the parameter whose type is to be set
- * @param type the new type of the given parameter
- */
- void _setType(FormalParameter parameter, DartType type) {
- SimpleIdentifier identifier = parameter.identifier;
- Element element = identifier.staticElement;
- if (element is! ParameterElement) {
- element = new ParameterElementImpl.forNode(identifier);
- identifier.staticElement = element;
- }
- (element as ParameterElementImpl).type = type;
- }
-}
-
-/**
* Instances of the class `StaticTypeVerifier` verify that all of the nodes in an AST
* structure that should have a static type associated with them do have a static type.
*/
@@ -12465,2261 +1039,6 @@
}
}
-/**
- * Strong mode static analyzer downwards inference tests
- */
-@reflectiveTest
-class StrongModeDownwardsInferenceTest extends ResolverTestCase {
- TypeAssertions _assertions;
-
- Asserter<DartType> _isDynamic;
- Asserter<InterfaceType> _isFutureOfDynamic;
- Asserter<InterfaceType> _isFutureOfInt;
- Asserter<DartType> _isInt;
- Asserter<DartType> _isNum;
- Asserter<DartType> _isString;
-
- AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
- _isFunction2Of;
- AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf;
- AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
- _isInstantiationOf;
- AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
- AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType>
- _isMapOf;
- AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isStreamOf;
- AsserterBuilder<DartType, DartType> _isType;
-
- AsserterBuilder<Element, DartType> _hasElement;
- AsserterBuilder<DartType, DartType> _sameElement;
-
- @override
- void setUp() {
- super.setUp();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.strongMode = true;
- resetWithOptions(options);
- _assertions = new TypeAssertions(typeProvider);
- _isType = _assertions.isType;
- _hasElement = _assertions.hasElement;
- _isInstantiationOf = _assertions.isInstantiationOf;
- _isInt = _assertions.isInt;
- _isNum = _assertions.isNum;
- _isString = _assertions.isString;
- _isDynamic = _assertions.isDynamic;
- _isListOf = _assertions.isListOf;
- _isMapOf = _assertions.isMapOf;
- _isFunction2Of = _assertions.isFunction2Of;
- _sameElement = _assertions.sameElement;
- _isFutureOf = _isInstantiationOf(_sameElement(typeProvider.futureType));
- _isFutureOfDynamic = _isFutureOf([_isDynamic]);
- _isFutureOfInt = _isFutureOf([_isInt]);
- _isStreamOf = _isInstantiationOf(_sameElement(typeProvider.streamType));
- }
-
- void test_async_method_propagation() {
- String code = r'''
- import "dart:async";
- class A {
- Future f0() => new Future.value(3);
- Future f1() async => new Future.value(3);
- Future f2() async => await new Future.value(3);
-
- Future<int> f3() => new Future.value(3);
- Future<int> f4() async => new Future.value(3);
- Future<int> f5() async => await new Future.value(3);
-
- Future g0() { return new Future.value(3); }
- Future g1() async { return new Future.value(3); }
- Future g2() async { return await new Future.value(3); }
-
- Future<int> g3() { return new Future.value(3); }
- Future<int> g4() async { return new Future.value(3); }
- Future<int> g5() async { return await new Future.value(3); }
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
- FunctionBody body = test.body;
- Expression returnExp;
- if (body is ExpressionFunctionBody) {
- returnExp = body.expression;
- } else {
- ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
- returnExp = stmt.expression;
- }
- DartType type = returnExp.staticType;
- if (returnExp is AwaitExpression) {
- type = returnExp.expression.staticType;
- }
- typeTest(type);
- }
-
- check("f0", _isFutureOfDynamic);
- check("f1", _isFutureOfDynamic);
- check("f2", _isFutureOfDynamic);
-
- check("f3", _isFutureOfInt);
- // This should be int when we handle the implicit Future<T> | T union
- // https://github.com/dart-lang/sdk/issues/25322
- check("f4", _isFutureOfDynamic);
- check("f5", _isFutureOfInt);
-
- check("g0", _isFutureOfDynamic);
- check("g1", _isFutureOfDynamic);
- check("g2", _isFutureOfDynamic);
-
- check("g3", _isFutureOfInt);
- // This should be int when we handle the implicit Future<T> | T union
- // https://github.com/dart-lang/sdk/issues/25322
- check("g4", _isFutureOfDynamic);
- check("g5", _isFutureOfInt);
- }
-
- void test_async_propagation() {
- String code = r'''
- import "dart:async";
-
- Future f0() => new Future.value(3);
- Future f1() async => new Future.value(3);
- Future f2() async => await new Future.value(3);
-
- Future<int> f3() => new Future.value(3);
- Future<int> f4() async => new Future.value(3);
- Future<int> f5() async => await new Future.value(3);
-
- Future g0() { return new Future.value(3); }
- Future g1() async { return new Future.value(3); }
- Future g2() async { return await new Future.value(3); }
-
- Future<int> g3() { return new Future.value(3); }
- Future<int> g4() async { return new Future.value(3); }
- Future<int> g5() async { return await new Future.value(3); }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
- FunctionBody body = test.functionExpression.body;
- Expression returnExp;
- if (body is ExpressionFunctionBody) {
- returnExp = body.expression;
- } else {
- ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
- returnExp = stmt.expression;
- }
- DartType type = returnExp.staticType;
- if (returnExp is AwaitExpression) {
- type = returnExp.expression.staticType;
- }
- typeTest(type);
- }
-
- check("f0", _isFutureOfDynamic);
- check("f1", _isFutureOfDynamic);
- check("f2", _isFutureOfDynamic);
-
- check("f3", _isFutureOfInt);
- // This should be int when we handle the implicit Future<T> | T union
- // https://github.com/dart-lang/sdk/issues/25322
- check("f4", _isFutureOfDynamic);
- check("f5", _isFutureOfInt);
-
- check("g0", _isFutureOfDynamic);
- check("g1", _isFutureOfDynamic);
- check("g2", _isFutureOfDynamic);
-
- check("g3", _isFutureOfInt);
- // This should be int when we handle the implicit Future<T> | T union
- // https://github.com/dart-lang/sdk/issues/25322
- check("g4", _isFutureOfDynamic);
- check("g5", _isFutureOfInt);
- }
-
- void test_async_star_method_propagation() {
- String code = r'''
- import "dart:async";
- class A {
- Stream g0() async* { yield []; }
- Stream g1() async* { yield* new Stream(); }
-
- Stream<List<int>> g2() async* { yield []; }
- Stream<List<int>> g3() async* { yield* new Stream(); }
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
- BlockFunctionBody body = test.body;
- YieldStatement stmt = body.block.statements[0];
- Expression exp = stmt.expression;
- typeTest(exp.staticType);
- }
-
- check("g0", _isListOf(_isDynamic));
- check("g1", _isStreamOf([_isDynamic]));
-
- check("g2", _isListOf(_isInt));
- check("g3", _isStreamOf([_isListOf(_isInt)]));
- }
-
- void test_async_star_propagation() {
- String code = r'''
- import "dart:async";
-
- Stream g0() async* { yield []; }
- Stream g1() async* { yield* new Stream(); }
-
- Stream<List<int>> g2() async* { yield []; }
- Stream<List<int>> g3() async* { yield* new Stream(); }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
- BlockFunctionBody body = test.functionExpression.body;
- YieldStatement stmt = body.block.statements[0];
- Expression exp = stmt.expression;
- typeTest(exp.staticType);
- }
-
- check("g0", _isListOf(_isDynamic));
- check("g1", _isStreamOf([_isDynamic]));
-
- check("g2", _isListOf(_isInt));
- check("g3", _isStreamOf([_isListOf(_isInt)]));
- }
-
- void test_cascadeExpression() {
- String code = r'''
- class A<T> {
- List<T> map(T a, List<T> mapper(T x)) => mapper(a);
- }
-
- void main () {
- A<int> a = new A()..map(0, (x) => [x]);
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- CascadeExpression fetch(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- CascadeExpression exp = decl.initializer;
- return exp;
- }
- Element elementA = AstFinder.getClass(unit, "A").element;
-
- CascadeExpression cascade = fetch(0);
- _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType);
- MethodInvocation invoke = cascade.cascadeSections[0];
- FunctionExpression function = invoke.argumentList.arguments[1];
- ExecutableElement f0 = function.element;
- _isListOf(_isInt)(f0.type.returnType);
- expect(f0.type.normalParameterTypes[0], typeProvider.intType);
- }
-
- void test_constructorInitializer_propagation() {
- String code = r'''
- class A {
- List<String> x;
- A() : this.x = [];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- ConstructorDeclaration constructor =
- AstFinder.getConstructorInClass(unit, "A", null);
- ConstructorFieldInitializer assignment = constructor.initializers[0];
- Expression exp = assignment.expression;
- _isListOf(_isString)(exp.staticType);
- }
-
- void test_factoryConstructor_propagation() {
- String code = r'''
- class A<T> {
- factory A() { return new B(); }
- }
- class B<S> extends A<S> {}
- ''';
- CompilationUnit unit = resolveSource(code);
-
- ConstructorDeclaration constructor =
- AstFinder.getConstructorInClass(unit, "A", null);
- BlockFunctionBody body = constructor.body;
- ReturnStatement stmt = body.block.statements[0];
- InstanceCreationExpression exp = stmt.expression;
- ClassElement elementB = AstFinder.getClass(unit, "B").element;
- ClassElement elementA = AstFinder.getClass(unit, "A").element;
- expect(exp.constructorName.type.type.element, elementB);
- _isInstantiationOf(_hasElement(elementB))(
- [_isType(elementA.typeParameters[0].type)])(exp.staticType);
- }
-
- void test_fieldDeclaration_propagation() {
- String code = r'''
- class A {
- List<String> f0 = ["hello"];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- VariableDeclaration field = AstFinder.getFieldInClass(unit, "A", "f0");
-
- _isListOf(_isString)(field.initializer.staticType);
- }
-
- void test_functionDeclaration_body_propagation() {
- String code = r'''
- typedef T Function2<S, T>(S x);
-
- List<int> test1() => [];
-
- Function2<int, int> test2 (int x) {
- Function2<String, int> inner() {
- return (x) => x.length;
- }
- return (x) => x;
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
- FunctionDeclaration test1 = AstFinder.getTopLevelFunction(unit, "test1");
- ExpressionFunctionBody body = test1.functionExpression.body;
- assertListOfInt(body.expression.staticType);
-
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test2");
-
- FunctionDeclaration inner =
- (statements[0] as FunctionDeclarationStatement).functionDeclaration;
- BlockFunctionBody body0 = inner.functionExpression.body;
- ReturnStatement return0 = body0.block.statements[0];
- Expression anon0 = return0.expression;
- FunctionType type0 = anon0.staticType;
- expect(type0.returnType, typeProvider.intType);
- expect(type0.normalParameterTypes[0], typeProvider.stringType);
-
- FunctionExpression anon1 = (statements[1] as ReturnStatement).expression;
- FunctionType type1 = anon1.element.type;
- expect(type1.returnType, typeProvider.intType);
- expect(type1.normalParameterTypes[0], typeProvider.intType);
- }
-
- void test_functionLiteral_assignment_typedArguments() {
- String code = r'''
- typedef T Function2<S, T>(S x);
-
- void main () {
- Function2<int, String> l0 = (int x) => null;
- Function2<int, String> l1 = (int x) => "hello";
- Function2<int, String> l2 = (String x) => "hello";
- Function2<int, String> l3 = (int x) => 3;
- Function2<int, String> l4 = (int x) {return 3;};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- FunctionExpression exp = decl.initializer;
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isString, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_assignment_unTypedArguments() {
- String code = r'''
- typedef T Function2<S, T>(S x);
-
- void main () {
- Function2<int, String> l0 = (x) => null;
- Function2<int, String> l1 = (x) => "hello";
- Function2<int, String> l2 = (x) => "hello";
- Function2<int, String> l3 = (x) => 3;
- Function2<int, String> l4 = (x) {return 3;};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- FunctionExpression exp = decl.initializer;
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isInt, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_body_propagation() {
- String code = r'''
- typedef T Function2<S, T>(S x);
-
- void main () {
- Function2<int, List<String>> l0 = (int x) => ["hello"];
- Function2<int, List<String>> l1 = (String x) => ["hello"];
- Function2<int, List<String>> l2 = (int x) => [3];
- Function2<int, List<String>> l3 = (int x) {return [3];};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- Expression functionReturnValue(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- FunctionExpression exp = decl.initializer;
- FunctionBody body = exp.body;
- if (body is ExpressionFunctionBody) {
- return body.expression;
- } else {
- Statement stmt = (body as BlockFunctionBody).block.statements[0];
- return (stmt as ReturnStatement).expression;
- }
- }
- Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
- assertListOfString(functionReturnValue(0).staticType);
- assertListOfString(functionReturnValue(1).staticType);
- assertListOfString(functionReturnValue(2).staticType);
- assertListOfString(functionReturnValue(3).staticType);
- }
-
- void test_functionLiteral_functionExpressionInvocation_typedArguments() {
- String code = r'''
- class Mapper<F, T> {
- T map(T mapper(F x)) => mapper(null);
- }
-
- void main () {
- (new Mapper<int, String>().map)((int x) => null);
- (new Mapper<int, String>().map)((int x) => "hello");
- (new Mapper<int, String>().map)((String x) => "hello");
- (new Mapper<int, String>().map)((int x) => 3);
- (new Mapper<int, String>().map)((int x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- FunctionExpressionInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isString, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_functionExpressionInvocation_unTypedArguments() {
- String code = r'''
- class Mapper<F, T> {
- T map(T mapper(F x)) => mapper(null);
- }
-
- void main () {
- (new Mapper<int, String>().map)((x) => null);
- (new Mapper<int, String>().map)((x) => "hello");
- (new Mapper<int, String>().map)((x) => "hello");
- (new Mapper<int, String>().map)((x) => 3);
- (new Mapper<int, String>().map)((x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- FunctionExpressionInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isInt, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_functionInvocation_typedArguments() {
- String code = r'''
- String map(String mapper(int x)) => mapper(null);
-
- void main () {
- map((int x) => null);
- map((int x) => "hello");
- map((String x) => "hello");
- map((int x) => 3);
- map((int x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- MethodInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isString, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_functionInvocation_unTypedArguments() {
- String code = r'''
- String map(String mapper(int x)) => mapper(null);
-
- void main () {
- map((x) => null);
- map((x) => "hello");
- map((x) => "hello");
- map((x) => 3);
- map((x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- MethodInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isInt, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_methodInvocation_typedArguments() {
- String code = r'''
- class Mapper<F, T> {
- T map(T mapper(F x)) => mapper(null);
- }
-
- void main () {
- new Mapper<int, String>().map((int x) => null);
- new Mapper<int, String>().map((int x) => "hello");
- new Mapper<int, String>().map((String x) => "hello");
- new Mapper<int, String>().map((int x) => 3);
- new Mapper<int, String>().map((int x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- MethodInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isString, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_methodInvocation_unTypedArguments() {
- String code = r'''
- class Mapper<F, T> {
- T map(T mapper(F x)) => mapper(null);
- }
-
- void main () {
- new Mapper<int, String>().map((x) => null);
- new Mapper<int, String>().map((x) => "hello");
- new Mapper<int, String>().map((x) => "hello");
- new Mapper<int, String>().map((x) => 3);
- new Mapper<int, String>().map((x) {return 3;});
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- ExpressionStatement stmt = statements[i];
- MethodInvocation invk = stmt.expression;
- FunctionExpression exp = invk.argumentList.arguments[0];
- return exp.element.type;
- }
- _isFunction2Of(_isInt, _isString)(literal(0));
- _isFunction2Of(_isInt, _isString)(literal(1));
- _isFunction2Of(_isInt, _isString)(literal(2));
- _isFunction2Of(_isInt, _isInt)(literal(3));
- _isFunction2Of(_isInt, _isString)(literal(4));
- }
-
- void test_functionLiteral_unTypedArgument_propagation() {
- String code = r'''
- typedef T Function2<S, T>(S x);
-
- void main () {
- Function2<int, int> l0 = (x) => x;
- Function2<int, int> l1 = (x) => x+1;
- Function2<int, String> l2 = (x) => x;
- Function2<int, String> l3 = (x) => x.toLowerCase();
- Function2<String, String> l4 = (x) => x.toLowerCase();
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- Expression functionReturnValue(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- FunctionExpression exp = decl.initializer;
- FunctionBody body = exp.body;
- if (body is ExpressionFunctionBody) {
- return body.expression;
- } else {
- Statement stmt = (body as BlockFunctionBody).block.statements[0];
- return (stmt as ReturnStatement).expression;
- }
- }
- expect(functionReturnValue(0).staticType, typeProvider.intType);
- expect(functionReturnValue(1).staticType, typeProvider.intType);
- expect(functionReturnValue(2).staticType, typeProvider.intType);
- expect(functionReturnValue(3).staticType, typeProvider.dynamicType);
- expect(functionReturnValue(4).staticType, typeProvider.stringType);
- }
-
- void test_inference_hints() {
- Source source = addSource(r'''
- void main () {
- var x = 3;
- List<int> l0 = [];
- }
- ''');
- resolve2(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_instanceCreation() {
- String code = r'''
- class A<S, T> {
- S x;
- T y;
- A(this.x, this.y);
- A.named(this.x, this.y);
- }
-
- class B<S, T> extends A<T, S> {
- B(S y, T x) : super(x, y);
- B.named(S y, T x) : super.named(x, y);
- }
-
- class C<S> extends B<S, S> {
- C(S a) : super(a, a);
- C.named(S a) : super.named(a, a);
- }
-
- class D<S, T> extends B<T, int> {
- D(T a) : super(a, 3);
- D.named(T a) : super.named(a, 3);
- }
-
- class E<S, T> extends A<C<S>, T> {
- E(T a) : super(null, a);
- }
-
- class F<S, T> extends A<S, T> {
- F(S x, T y, {List<S> a, List<T> b}) : super(x, y);
- F.named(S x, T y, [S a, T b]) : super(a, b);
- }
-
- void test0() {
- A<int, String> a0 = new A(3, "hello");
- A<int, String> a1 = new A.named(3, "hello");
- A<int, String> a2 = new A<int, String>(3, "hello");
- A<int, String> a3 = new A<int, String>.named(3, "hello");
- A<int, String> a4 = new A<int, dynamic>(3, "hello");
- A<int, String> a5 = new A<dynamic, dynamic>.named(3, "hello");
- }
- void test1() {
- A<int, String> a0 = new A("hello", 3);
- A<int, String> a1 = new A.named("hello", 3);
- }
- void test2() {
- A<int, String> a0 = new B("hello", 3);
- A<int, String> a1 = new B.named("hello", 3);
- A<int, String> a2 = new B<String, int>("hello", 3);
- A<int, String> a3 = new B<String, int>.named("hello", 3);
- A<int, String> a4 = new B<String, dynamic>("hello", 3);
- A<int, String> a5 = new B<dynamic, dynamic>.named("hello", 3);
- }
- void test3() {
- A<int, String> a0 = new B(3, "hello");
- A<int, String> a1 = new B.named(3, "hello");
- }
- void test4() {
- A<int, int> a0 = new C(3);
- A<int, int> a1 = new C.named(3);
- A<int, int> a2 = new C<int>(3);
- A<int, int> a3 = new C<int>.named(3);
- A<int, int> a4 = new C<dynamic>(3);
- A<int, int> a5 = new C<dynamic>.named(3);
- }
- void test5() {
- A<int, int> a0 = new C("hello");
- A<int, int> a1 = new C.named("hello");
- }
- void test6() {
- A<int, String> a0 = new D("hello");
- A<int, String> a1 = new D.named("hello");
- A<int, String> a2 = new D<int, String>("hello");
- A<int, String> a3 = new D<String, String>.named("hello");
- A<int, String> a4 = new D<num, dynamic>("hello");
- A<int, String> a5 = new D<dynamic, dynamic>.named("hello");
- }
- void test7() {
- A<int, String> a0 = new D(3);
- A<int, String> a1 = new D.named(3);
- }
- void test8() {
- // Currently we only allow variable constraints. Test that we reject.
- A<C<int>, String> a0 = new E("hello");
- }
- void test9() { // Check named and optional arguments
- A<int, String> a0 = new F(3, "hello", a: [3], b: ["hello"]);
- A<int, String> a1 = new F(3, "hello", a: ["hello"], b:[3]);
- A<int, String> a2 = new F.named(3, "hello", 3, "hello");
- A<int, String> a3 = new F.named(3, "hello");
- A<int, String> a4 = new F.named(3, "hello", "hello", 3);
- A<int, String> a5 = new F.named(3, "hello", "hello");
- }
- }''';
- CompilationUnit unit = resolveSource(code);
-
- Expression rhs(VariableDeclarationStatement stmt) {
- VariableDeclaration decl = stmt.variables.variables[0];
- Expression exp = decl.initializer;
- return exp;
- }
-
- void hasType(Asserter<DartType> assertion, Expression exp) =>
- assertion(exp.staticType);
-
- Element elementA = AstFinder.getClass(unit, "A").element;
- Element elementB = AstFinder.getClass(unit, "B").element;
- Element elementC = AstFinder.getClass(unit, "C").element;
- Element elementD = AstFinder.getClass(unit, "D").element;
- Element elementE = AstFinder.getClass(unit, "E").element;
- Element elementF = AstFinder.getClass(unit, "F").element;
-
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf =
- _isInstantiationOf(_hasElement(elementA));
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf =
- _isInstantiationOf(_hasElement(elementB));
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertCOf =
- _isInstantiationOf(_hasElement(elementC));
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertDOf =
- _isInstantiationOf(_hasElement(elementD));
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf =
- _isInstantiationOf(_hasElement(elementE));
- AsserterBuilder<List<Asserter<DartType>>, DartType> assertFOf =
- _isInstantiationOf(_hasElement(elementF));
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test0");
-
- hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
- hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
- hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
- hasType(assertAOf([_isInt, _isString]), rhs(statements[2]));
- hasType(assertAOf([_isInt, _isString]), rhs(statements[3]));
- hasType(assertAOf([_isInt, _isDynamic]), rhs(statements[4]));
- hasType(assertAOf([_isDynamic, _isDynamic]), rhs(statements[5]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test1");
- hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
- hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test2");
- hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
- hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
- hasType(assertBOf([_isString, _isInt]), rhs(statements[2]));
- hasType(assertBOf([_isString, _isInt]), rhs(statements[3]));
- hasType(assertBOf([_isString, _isDynamic]), rhs(statements[4]));
- hasType(assertBOf([_isDynamic, _isDynamic]), rhs(statements[5]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test3");
- hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
- hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test4");
- hasType(assertCOf([_isInt]), rhs(statements[0]));
- hasType(assertCOf([_isInt]), rhs(statements[1]));
- hasType(assertCOf([_isInt]), rhs(statements[2]));
- hasType(assertCOf([_isInt]), rhs(statements[3]));
- hasType(assertCOf([_isDynamic]), rhs(statements[4]));
- hasType(assertCOf([_isDynamic]), rhs(statements[5]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test5");
- hasType(assertCOf([_isInt]), rhs(statements[0]));
- hasType(assertCOf([_isInt]), rhs(statements[1]));
- }
-
- {
- // The first type parameter is not constrained by the
- // context. We could choose a tighter type, but currently
- // we just use dynamic.
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test6");
- hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
- hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
- hasType(assertDOf([_isInt, _isString]), rhs(statements[2]));
- hasType(assertDOf([_isString, _isString]), rhs(statements[3]));
- hasType(assertDOf([_isNum, _isDynamic]), rhs(statements[4]));
- hasType(assertDOf([_isDynamic, _isDynamic]), rhs(statements[5]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test7");
- hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
- hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test8");
- hasType(assertEOf([_isDynamic, _isDynamic]), rhs(statements[0]));
- }
-
- {
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "test9");
- hasType(assertFOf([_isInt, _isString]), rhs(statements[0]));
- hasType(assertFOf([_isInt, _isString]), rhs(statements[1]));
- hasType(assertFOf([_isInt, _isString]), rhs(statements[2]));
- hasType(assertFOf([_isInt, _isString]), rhs(statements[3]));
- hasType(assertFOf([_isInt, _isString]), rhs(statements[4]));
- hasType(assertFOf([_isInt, _isString]), rhs(statements[5]));
- }
- }
-
- void test_listLiteral_nested() {
- String code = r'''
- void main () {
- List<List<int>> l0 = [[]];
- Iterable<List<int>> l1 = [[3]];
- Iterable<List<int>> l2 = [[3], [4]];
- List<List<int>> l3 = [["hello", 3], []];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- ListLiteral literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- ListLiteral exp = decl.initializer;
- return exp;
- }
-
- Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
- Asserter<InterfaceType> assertListOfListOfInt = _isListOf(assertListOfInt);
-
- assertListOfListOfInt(literal(0).staticType);
- assertListOfListOfInt(literal(1).staticType);
- assertListOfListOfInt(literal(2).staticType);
- assertListOfListOfInt(literal(3).staticType);
-
- assertListOfInt(literal(1).elements[0].staticType);
- assertListOfInt(literal(2).elements[0].staticType);
- assertListOfInt(literal(3).elements[0].staticType);
- }
-
- void test_listLiteral_simple() {
- String code = r'''
- void main () {
- List<int> l0 = [];
- List<int> l1 = [3];
- List<int> l2 = ["hello"];
- List<int> l3 = ["hello", 3];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- ListLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
- assertListOfInt(literal(0));
- assertListOfInt(literal(1));
- assertListOfInt(literal(2));
- assertListOfInt(literal(3));
- }
-
- void test_listLiteral_simple_const() {
- String code = r'''
- void main () {
- const List<int> c0 = const [];
- const List<int> c1 = const [3];
- const List<int> c2 = const ["hello"];
- const List<int> c3 = const ["hello", 3];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- ListLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
- assertListOfInt(literal(0));
- assertListOfInt(literal(1));
- assertListOfInt(literal(2));
- assertListOfInt(literal(3));
- }
-
- void test_listLiteral_simple_disabled() {
- String code = r'''
- void main () {
- List<int> l0 = <num>[];
- List<int> l1 = <num>[3];
- List<int> l2 = <String>["hello"];
- List<int> l3 = <dynamic>["hello", 3];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- ListLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- _isListOf(_isNum)(literal(0));
- _isListOf(_isNum)(literal(1));
- _isListOf(_isString)(literal(2));
- _isListOf(_isDynamic)(literal(3));
- }
-
- void test_listLiteral_simple_subtype() {
- String code = r'''
- void main () {
- Iterable<int> l0 = [];
- Iterable<int> l1 = [3];
- Iterable<int> l2 = ["hello"];
- Iterable<int> l3 = ["hello", 3];
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- ListLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
- assertListOfInt(literal(0));
- assertListOfInt(literal(1));
- assertListOfInt(literal(2));
- assertListOfInt(literal(3));
- }
-
- void test_mapLiteral_nested() {
- String code = r'''
- void main () {
- Map<int, List<String>> l0 = {};
- Map<int, List<String>> l1 = {3: ["hello"]};
- Map<int, List<String>> l2 = {"hello": ["hello"]};
- Map<int, List<String>> l3 = {3: [3]};
- Map<int, List<String>> l4 = {3:["hello"], "hello": [3]};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- MapLiteral literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- MapLiteral exp = decl.initializer;
- return exp;
- }
-
- Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
- Asserter<InterfaceType> assertMapOfIntToListOfString =
- _isMapOf(_isInt, assertListOfString);
-
- assertMapOfIntToListOfString(literal(0).staticType);
- assertMapOfIntToListOfString(literal(1).staticType);
- assertMapOfIntToListOfString(literal(2).staticType);
- assertMapOfIntToListOfString(literal(3).staticType);
- assertMapOfIntToListOfString(literal(4).staticType);
-
- assertListOfString(literal(1).entries[0].value.staticType);
- assertListOfString(literal(2).entries[0].value.staticType);
- assertListOfString(literal(3).entries[0].value.staticType);
- assertListOfString(literal(4).entries[0].value.staticType);
- }
-
- void test_mapLiteral_simple() {
- String code = r'''
- void main () {
- Map<int, String> l0 = {};
- Map<int, String> l1 = {3: "hello"};
- Map<int, String> l2 = {"hello": "hello"};
- Map<int, String> l3 = {3: 3};
- Map<int, String> l4 = {3:"hello", "hello": 3};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- MapLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- Asserter<InterfaceType> assertMapOfIntToString =
- _isMapOf(_isInt, _isString);
-
- assertMapOfIntToString(literal(0));
- assertMapOfIntToString(literal(1));
- assertMapOfIntToString(literal(2));
- assertMapOfIntToString(literal(3));
- }
-
- void test_mapLiteral_simple_disabled() {
- String code = r'''
- void main () {
- Map<int, String> l0 = <int, dynamic>{};
- Map<int, String> l1 = <int, dynamic>{3: "hello"};
- Map<int, String> l2 = <int, dynamic>{"hello": "hello"};
- Map<int, String> l3 = <int, dynamic>{3: 3};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- List<Statement> statements =
- AstFinder.getStatementsInTopLevelFunction(unit, "main");
- DartType literal(int i) {
- VariableDeclarationStatement stmt = statements[i];
- VariableDeclaration decl = stmt.variables.variables[0];
- MapLiteral exp = decl.initializer;
- return exp.staticType;
- }
-
- Asserter<InterfaceType> assertMapOfIntToDynamic =
- _isMapOf(_isInt, _isDynamic);
-
- assertMapOfIntToDynamic(literal(0));
- assertMapOfIntToDynamic(literal(1));
- assertMapOfIntToDynamic(literal(2));
- assertMapOfIntToDynamic(literal(3));
- }
-
- void test_methodDeclaration_body_propagation() {
- String code = r'''
- class A {
- List<String> m0(int x) => ["hello"];
- List<String> m1(int x) {return [3];};
- }
- ''';
- CompilationUnit unit = resolveSource(code);
- Expression methodReturnValue(String methodName) {
- MethodDeclaration method =
- AstFinder.getMethodInClass(unit, "A", methodName);
- FunctionBody body = method.body;
- if (body is ExpressionFunctionBody) {
- return body.expression;
- } else {
- Statement stmt = (body as BlockFunctionBody).block.statements[0];
- return (stmt as ReturnStatement).expression;
- }
- }
- Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
- assertListOfString(methodReturnValue("m0").staticType);
- assertListOfString(methodReturnValue("m1").staticType);
- }
-
- void test_redirectingConstructor_propagation() {
- String code = r'''
- class A {
- A() : this.named([]);
- A.named(List<String> x);
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- ConstructorDeclaration constructor =
- AstFinder.getConstructorInClass(unit, "A", null);
- RedirectingConstructorInvocation invocation = constructor.initializers[0];
- Expression exp = invocation.argumentList.arguments[0];
- _isListOf(_isString)(exp.staticType);
- }
-
- void test_superConstructorInvocation_propagation() {
- String code = r'''
- class B {
- B(List<String>);
- }
- class A extends B {
- A() : super([]);
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- ConstructorDeclaration constructor =
- AstFinder.getConstructorInClass(unit, "A", null);
- SuperConstructorInvocation invocation = constructor.initializers[0];
- Expression exp = invocation.argumentList.arguments[0];
- _isListOf(_isString)(exp.staticType);
- }
-
- void test_sync_star_method_propagation() {
- String code = r'''
- import "dart:async";
- class A {
- Iterable f0() sync* { yield []; }
- Iterable f1() sync* { yield* new List(); }
-
- Iterable<List<int>> f2() sync* { yield []; }
- Iterable<List<int>> f3() sync* { yield* new List(); }
- }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
- BlockFunctionBody body = test.body;
- YieldStatement stmt = body.block.statements[0];
- Expression exp = stmt.expression;
- typeTest(exp.staticType);
- }
-
- check("f0", _isListOf(_isDynamic));
- check("f1", _isListOf(_isDynamic));
-
- check("f2", _isListOf(_isInt));
- check("f3", _isListOf(_isListOf(_isInt)));
- }
-
- void test_sync_star_propagation() {
- String code = r'''
- import "dart:async";
-
- Iterable f0() sync* { yield []; }
- Iterable f1() sync* { yield* new List(); }
-
- Iterable<List<int>> f2() sync* { yield []; }
- Iterable<List<int>> f3() sync* { yield* new List(); }
- ''';
- CompilationUnit unit = resolveSource(code);
-
- void check(String name, Asserter<InterfaceType> typeTest) {
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
- BlockFunctionBody body = test.functionExpression.body;
- YieldStatement stmt = body.block.statements[0];
- Expression exp = stmt.expression;
- typeTest(exp.staticType);
- }
-
- check("f0", _isListOf(_isDynamic));
- check("f1", _isListOf(_isDynamic));
-
- check("f2", _isListOf(_isInt));
- check("f3", _isListOf(_isListOf(_isInt)));
- }
-}
-
-/**
- * Strong mode static analyzer end to end tests
- */
-@reflectiveTest
-class StrongModeStaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared {
- void fail_genericMethod_tearoff_instantiated() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(E e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
- var methodTearOffInst = c.f/*<int>*/;
- var staticTearOffInst = C.g/*<int>*/;
- var staticFieldTearOffInst = C.h/*<int>*/;
- var topFunTearOffInst = topF/*<int>*/;
- var topFieldTearOffInst = topG/*<int>*/;
- var localTearOffInst = lf/*<int>*/;
- var paramTearOffInst = pf/*<int>*/;
-}
-''');
- _expectIdentifierType('methodTearOffInst', "(int) → int");
- _expectIdentifierType('staticTearOffInst', "(int) → int");
- _expectIdentifierType('staticFieldTearOffInst', "(int) → int");
- _expectIdentifierType('topFunTearOffInst', "(int) → int");
- _expectIdentifierType('topFieldTearOffInst', "(int) → int");
- _expectIdentifierType('localTearOffInst', "(int) → int");
- _expectIdentifierType('paramTearOffInst', "(int) → int");
- }
-
- void setUp() {
- super.setUp();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.strongMode = true;
- resetWithOptions(options);
- }
-
- void test_dynamicObjectGetter_hashCode() {
- String code = r'''
-main() {
- dynamic a = null;
- var foo = a.hashCode;
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
-
- void test_dynamicObjectMethod_toString() {
- String code = r'''
-main() {
- dynamic a = null;
- var foo = a.toString();
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'String', isNull);
- }
-
- void test_genericFunction() {
- _resolveTestUnit(r'/*=T*/ f/*<T>*/(/*=T*/ x) => null;');
- _expectFunctionType('f', '<T>(T) → T',
- elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f = _findIdentifier('f');
- FunctionElementImpl e = f.staticElement;
- FunctionType ft = e.type.instantiate([typeProvider.stringType]);
- expect(ft.toString(), '(String) → String');
- }
-
- void test_genericFunction_bounds() {
- _resolveTestUnit(r'/*=T*/ f/*<T extends num>*/(/*=T*/ x) => null;');
- _expectFunctionType('f', '<T extends num>(T) → T',
- elementTypeParams: '[T extends num]', typeFormals: '[T extends num]');
- }
-
- void test_genericFunction_parameter() {
- _resolveTestUnit(r'''
-void g(/*=T*/ f/*<T>*/(/*=T*/ x)) {}
-''');
- _expectFunctionType('f', '<T>(T) → T',
- elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f = _findIdentifier('f');
- ParameterElementImpl e = f.staticElement;
- FunctionType type = e.type;
- FunctionType ft = type.instantiate([typeProvider.stringType]);
- expect(ft.toString(), '(String) → String');
- }
-
- void test_genericFunction_static() {
- _resolveTestUnit(r'''
-class C<E> {
- static /*=T*/ f/*<T>*/(/*=T*/ x) => null;
-}
-''');
- _expectFunctionType('f', '<T>(T) → T',
- elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f = _findIdentifier('f');
- MethodElementImpl e = f.staticElement;
- FunctionType ft = e.type.instantiate([typeProvider.stringType]);
- expect(ft.toString(), '(String) → String');
- }
-
- void test_genericFunction_typedef() {
- String code = r'''
-typedef T F<T>(T x);
-F f0;
-
-class C {
- static F f1;
- F f2;
- void g(F f3) {
- F f4;
- f0(3);
- f1(3);
- f2(3);
- f3(3);
- f4(3);
- }
-}
-
-class D<S> {
- static F f1;
- F f2;
- void g(F f3) {
- F f4;
- f0(3);
- f1(3);
- f2(3);
- f3(3);
- f4(3);
- }
-}
-''';
- _resolveTestUnit(code);
-
- checkBody(String className) {
- List<Statement> statements =
- AstFinder.getStatementsInMethod(testUnit, className, "g");
-
- for (int i = 1; i <= 5; i++) {
- Expression exp = (statements[i] as ExpressionStatement).expression;
- expect(exp.staticType, typeProvider.dynamicType);
- }
- }
-
- checkBody("C");
- checkBody("D");
- }
-
- void test_genericMethod() {
- _resolveTestUnit(r'''
-class C<E> {
- List/*<T>*/ f/*<T>*/(E e) => null;
-}
-main() {
- C<String> cOfString;
-}
-''');
- _expectFunctionType('f', '<T>(E) → List<T>',
- elementTypeParams: '[T]',
- typeParams: '[E]',
- typeArgs: '[E]',
- typeFormals: '[T]');
- SimpleIdentifier c = _findIdentifier('cOfString');
- FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
- expect(ft.toString(), '<T>(String) → List<T>');
- ft = ft.instantiate([typeProvider.intType]);
- expect(ft.toString(), '(String) → List<int>');
- expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
- }
-
- void test_genericMethod_explicitTypeParams() {
- _resolveTestUnit(r'''
-class C<E> {
- List/*<T>*/ f/*<T>*/(E e) => null;
-}
-main() {
- C<String> cOfString;
- var x = cOfString.f/*<int>*/('hi');
-}
-''');
- MethodInvocation f = _findIdentifier('f/*<int>*/').parent;
- FunctionType ft = f.staticInvokeType;
- expect(ft.toString(), '(String) → List<int>');
- expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
-
- SimpleIdentifier x = _findIdentifier('x');
- expect(x.staticType,
- typeProvider.listType.instantiate([typeProvider.intType]));
- }
-
- void test_genericMethod_functionExpressionInvocation_explicit() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(/*=T*/ e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
-
- var lambdaCall = (/*<E>*/(/*=E*/ e) => e)/*<int>*/(3);
- var methodCall = (c.f)/*<int>*/(3);
- var staticCall = (C.g)/*<int>*/(3);
- var staticFieldCall = (C.h)/*<int>*/(3);
- var topFunCall = (topF)/*<int>*/(3);
- var topFieldCall = (topG)/*<int>*/(3);
- var localCall = (lf)/*<int>*/(3);
- var paramCall = (pf)/*<int>*/(3);
-}
-''');
- _expectIdentifierType('methodCall', "int");
- _expectIdentifierType('staticCall', "int");
- _expectIdentifierType('staticFieldCall', "int");
- _expectIdentifierType('topFunCall', "int");
- _expectIdentifierType('topFieldCall', "int");
- _expectIdentifierType('localCall', "int");
- _expectIdentifierType('paramCall', "int");
- _expectIdentifierType('lambdaCall', "int");
- }
-
- void test_genericMethod_functionExpressionInvocation_inferred() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(/*=T*/ e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
-
- var lambdaCall = (/*<E>*/(/*=E*/ e) => e)(3);
- var methodCall = (c.f)(3);
- var staticCall = (C.g)(3);
- var staticFieldCall = (C.h)(3);
- var topFunCall = (topF)(3);
- var topFieldCall = (topG)(3);
- var localCall = (lf)(3);
- var paramCall = (pf)(3);
-}
-''');
- _expectIdentifierType('methodCall', "int");
- _expectIdentifierType('staticCall', "int");
- _expectIdentifierType('staticFieldCall', "int");
- _expectIdentifierType('topFunCall', "int");
- _expectIdentifierType('topFieldCall', "int");
- _expectIdentifierType('localCall', "int");
- _expectIdentifierType('paramCall', "int");
- _expectIdentifierType('lambdaCall', "int");
- }
-
- void test_genericMethod_functionInvocation_explicit() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(/*=T*/ e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
- var methodCall = c.f/*<int>*/(3);
- var staticCall = C.g/*<int>*/(3);
- var staticFieldCall = C.h/*<int>*/(3);
- var topFunCall = topF/*<int>*/(3);
- var topFieldCall = topG/*<int>*/(3);
- var localCall = lf/*<int>*/(3);
- var paramCall = pf/*<int>*/(3);
-}
-''');
- _expectIdentifierType('methodCall', "int");
- _expectIdentifierType('staticCall', "int");
- _expectIdentifierType('staticFieldCall', "int");
- _expectIdentifierType('topFunCall', "int");
- _expectIdentifierType('topFieldCall', "int");
- _expectIdentifierType('localCall', "int");
- _expectIdentifierType('paramCall', "int");
- }
-
- void test_genericMethod_functionInvocation_inferred() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(/*=T*/ e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
- var methodCall = c.f(3);
- var staticCall = C.g(3);
- var staticFieldCall = C.h(3);
- var topFunCall = topF(3);
- var topFieldCall = topG(3);
- var localCall = lf(3);
- var paramCall = pf(3);
-}
-''');
- _expectIdentifierType('methodCall', "int");
- _expectIdentifierType('staticCall', "int");
- _expectIdentifierType('staticFieldCall', "int");
- _expectIdentifierType('topFunCall', "int");
- _expectIdentifierType('topFieldCall', "int");
- _expectIdentifierType('localCall', "int");
- _expectIdentifierType('paramCall', "int");
- }
-
- void test_genericMethod_functionTypedParameter() {
- _resolveTestUnit(r'''
-class C<E> {
- List/*<T>*/ f/*<T>*/(/*=T*/ f(E e)) => null;
-}
-main() {
- C<String> cOfString;
-}
-''');
- _expectFunctionType('f', '<T>((E) → T) → List<T>',
- elementTypeParams: '[T]',
- typeParams: '[E]',
- typeArgs: '[E]',
- typeFormals: '[T]');
-
- SimpleIdentifier c = _findIdentifier('cOfString');
- FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
- expect(ft.toString(), '<T>((String) → T) → List<T>');
- ft = ft.instantiate([typeProvider.intType]);
- expect(ft.toString(), '((String) → int) → List<int>');
- }
-
- void test_genericMethod_implicitDynamic() {
- // Regression test for:
- // https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588
- // These should not cause any hints or warnings.
- _resolveTestUnit(r'''
-class List<E> {
- /*=T*/ map/*<T>*/(/*=T*/ f(E e)) => null;
-}
-void foo() {
- List list = null;
- list.map((e) => e);
- list.map((e) => 3);
-}''');
- _expectIdentifierType('map((e) => e);', '<T>((dynamic) → T) → T', isNull);
- _expectIdentifierType('map((e) => 3);', '<T>((dynamic) → T) → T', isNull);
-
- MethodInvocation m1 = _findIdentifier('map((e) => e);').parent;
- expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
- MethodInvocation m2 = _findIdentifier('map((e) => 3);').parent;
- expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int');
- }
-
- void test_genericMethod_max_doubleDouble() {
- String code = r'''
-import 'dart:math';
-main() {
- var foo = max(1.0, 2.0);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'double', isNull);
- }
-
- void test_genericMethod_max_doubleDouble_prefixed() {
- String code = r'''
-import 'dart:math' as math;
-main() {
- var foo = math.max(1.0, 2.0);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'double', isNull);
- }
-
- void test_genericMethod_max_doubleInt() {
- String code = r'''
-import 'dart:math';
-main() {
- var foo = max(1.0, 2);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'num', isNull);
- }
-
- void test_genericMethod_max_intDouble() {
- String code = r'''
-import 'dart:math';
-main() {
- var foo = max(1, 2.0);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'num', isNull);
- }
-
- void test_genericMethod_max_intInt() {
- String code = r'''
-import 'dart:math';
-main() {
- var foo = max(1, 2);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
-
- void test_genericMethod_nestedBound() {
- String code = r'''
-class Foo<T extends num> {
- void method/*<U extends T>*/(dynamic/*=U*/ u) {
- u.abs();
- }
-}
-''';
- // Just validate that there is no warning on the call to `.abs()`.
- _resolveTestUnit(code);
- }
-
- void test_genericMethod_nestedCapture() {
- _resolveTestUnit(r'''
-class C<T> {
- /*=T*/ f/*<S>*/(/*=S*/ x) {
- new C<S>().f/*<int>*/(3);
- new C<S>().f; // tear-off
- return null;
- }
-}
-''');
- MethodInvocation f = _findIdentifier('f/*<int>*/(3);').parent;
- expect(f.staticInvokeType.toString(), '(int) → S');
- FunctionType ft = f.staticInvokeType;
- expect('${ft.typeArguments}/${ft.typeParameters}', '[S, int]/[T, S]');
-
- _expectIdentifierType('f;', '<Sâ‚€>(Sâ‚€) → S');
- }
-
- void test_genericMethod_nestedFunctions() {
- _resolveTestUnit(r'''
-/*=S*/ f/*<S>*/(/*=S*/ x) {
- g/*<S>*/(/*=S*/ x) => f;
- return null;
-}
-''');
- _expectIdentifierType('f', '<S>(S) → S');
- _expectIdentifierType('g', '<S>(S) → dynamic');
- }
-
- void test_genericMethod_override() {
- _resolveTestUnit(r'''
-class C {
- /*=T*/ f/*<T>*/(/*=T*/ x) => null;
-}
-class D extends C {
- /*=T*/ f/*<T>*/(/*=T*/ x) => null; // from D
-}
-''');
- _expectFunctionType('f/*<T>*/(/*=T*/ x) => null; // from D', '<T>(T) → T',
- elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f =
- _findIdentifier('f/*<T>*/(/*=T*/ x) => null; // from D');
- MethodElementImpl e = f.staticElement;
- FunctionType ft = e.type.instantiate([typeProvider.stringType]);
- expect(ft.toString(), '(String) → String');
- }
-
- void test_genericMethod_override_bounds() {
- _resolveTestUnit(r'''
-class A {}
-class B extends A {}
-class C {
- /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
-}
-class D extends C {
- /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
-}
-''');
- }
-
- void test_genericMethod_override_invalidReturnType() {
- Source source = addSource(r'''
-class C {
- Iterable/*<T>*/ f/*<T>*/(/*=T*/ x) => null;
-}
-class D extends C {
- String f/*<S>*/(/*=S*/ x) => null;
-}''');
- // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
- // from CodeChecker don't have working equality.
- List<AnalysisError> errors = analysisContext2.computeErrors(source);
-
- // Sort errors by name.
- errors.sort((AnalysisError e1, AnalysisError e2) =>
- e1.errorCode.name.compareTo(e2.errorCode.name));
-
- expect(errors.map((e) => e.errorCode.name), [
- 'INVALID_METHOD_OVERRIDE_RETURN_TYPE',
- 'STRONG_MODE_INVALID_METHOD_OVERRIDE'
- ]);
- expect(errors[0].message, contains('Iterable<S>'),
- reason: 'errors should be in terms of the type parameters '
- 'at the error location');
- verify([source]);
- }
-
- void test_genericMethod_override_invalidTypeParamBounds() {
- Source source = addSource(r'''
-class A {}
-class B extends A {}
-class C {
- /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
-}
-class D extends C {
- /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
-}''');
- // TODO(jmesserly): this is modified code from assertErrors, which we can't
- // use directly because STRONG_MODE_* errors don't have working equality.
- List<AnalysisError> errors = analysisContext2.computeErrors(source);
- List errorNames = errors.map((e) => e.errorCode.name).toList();
- expect(errorNames, hasLength(2));
- expect(errorNames, contains('STRONG_MODE_INVALID_METHOD_OVERRIDE'));
- expect(
- errorNames, contains('INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND'));
- verify([source]);
- }
-
- void test_genericMethod_override_invalidTypeParamCount() {
- Source source = addSource(r'''
-class C {
- /*=T*/ f/*<T>*/(/*=T*/ x) => null;
-}
-class D extends C {
- /*=S*/ f/*<T, S>*/(/*=T*/ x) => null;
-}''');
- // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
- // from CodeChecker don't have working equality.
- List<AnalysisError> errors = analysisContext2.computeErrors(source);
- expect(errors.map((e) => e.errorCode.name), [
- 'STRONG_MODE_INVALID_METHOD_OVERRIDE',
- 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS'
- ]);
- verify([source]);
- }
-
- void test_genericMethod_propagatedType_promotion() {
- // Regression test for:
- // https://github.com/dart-lang/sdk/issues/25340
-
- // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
- // example won't work, as we now compute a static type and therefore discard
- // the propagated type. So a new test was created that doesn't run under
- // strong mode.
- _resolveTestUnit(r'''
-abstract class Iter {
- List/*<S>*/ map/*<S>*/(/*=S*/ f(x));
-}
-class C {}
-C toSpan(dynamic element) {
- if (element is Iter) {
- var y = element.map(toSpan);
- }
- return null;
-}''');
- _expectIdentifierType('y = ', 'List<C>', isNull);
- }
-
- void test_genericMethod_tearoff() {
- _resolveTestUnit(r'''
-class C<E> {
- /*=T*/ f/*<T>*/(E e) => null;
- static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
- static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
- var c = new C<int>();
- /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
- var methodTearOff = c.f;
- var staticTearOff = C.g;
- var staticFieldTearOff = C.h;
- var topFunTearOff = topF;
- var topFieldTearOff = topG;
- var localTearOff = lf;
- var paramTearOff = pf;
-}
-''');
- _expectIdentifierType('methodTearOff', "<T>(int) → T");
- _expectIdentifierType('staticTearOff', "<T>(T) → T");
- _expectIdentifierType('staticFieldTearOff', "<T>(T) → T");
- _expectIdentifierType('topFunTearOff', "<T>(T) → T");
- _expectIdentifierType('topFieldTearOff', "<T>(T) → T");
- _expectIdentifierType('localTearOff', "<T>(T) → T");
- _expectIdentifierType('paramTearOff', "<T>(T) → T");
- }
-
- void test_genericMethod_then() {
- String code = r'''
-import 'dart:async';
-String toString(int x) => x.toString();
-main() {
- Future<int> bar = null;
- var foo = bar.then(toString);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'Future<String>', isNull);
- }
-
- void test_genericMethod_then_prefixed() {
- String code = r'''
-import 'dart:async' as async;
-String toString(int x) => x.toString();
-main() {
- async.Future<int> bar = null;
- var foo = bar.then(toString);
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'Future<String>', isNull);
- }
-
- void test_genericMethod_then_propagatedType() {
- // Regression test for https://github.com/dart-lang/sdk/issues/25482.
- String code = r'''
-import 'dart:async';
-void main() {
- Future<String> p;
- var foo = p.then((r) => new Future<String>.value(3));
-}
-''';
- // This should produce no hints or warnings.
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'Future<String>', isNull);
- }
-
- void test_implicitBounds() {
- String code = r'''
-class A<T> {}
-
-class B<T extends num> {}
-
-class C<S extends int, T extends B<S>, U extends B> {}
-
-void test() {
-//
- A ai;
- B bi;
- C ci;
- var aa = new A();
- var bb = new B();
- var cc = new C();
-}
-''';
- _resolveTestUnit(code);
- _expectIdentifierType('ai', "A<dynamic>");
- _expectIdentifierType('bi', "B<num>");
- _expectIdentifierType('ci', "C<int, B<int>, B<num>>");
- _expectIdentifierType('aa', "A<dynamic>");
- _expectIdentifierType('bb', "B<num>");
- _expectIdentifierType('cc', "C<int, B<int>, B<num>>");
- }
-
- void test_setterWithDynamicTypeIsError() {
- Source source = addSource(r'''
-class A {
- dynamic set f(String s) => null;
-}
-dynamic set g(int x) => null;
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
- ]);
- verify([source]);
- }
-
- void test_setterWithExplicitVoidType_returningVoid() {
- Source source = addSource(r'''
-void returnsVoid() {}
-class A {
- void set f(String s) => returnsVoid();
-}
-void set g(int x) => returnsVoid();
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_setterWithNoVoidType() {
- Source source = addSource(r'''
-class A {
- set f(String s) {
- return '42';
- }
-}
-set g(int x) => 42;
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
- StaticTypeWarningCode.RETURN_OF_INVALID_TYPE
- ]);
- verify([source]);
- }
-
- void test_setterWithNoVoidType_returningVoid() {
- Source source = addSource(r'''
-void returnsVoid() {}
-class A {
- set f(String s) => returnsVoid();
-}
-set g(int x) => returnsVoid();
-''');
- computeLibrarySourceErrors(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- void test_setterWithOtherTypeIsError() {
- Source source = addSource(r'''
-class A {
- String set f(String s) => null;
-}
-Object set g(x) => null;
-''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
- ]);
- verify([source]);
- }
-
- void test_ternaryOperator_null_left() {
- String code = r'''
-main() {
- var foo = (true) ? null : 3;
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
-
- void test_ternaryOperator_null_right() {
- String code = r'''
-main() {
- var foo = (true) ? 3 : null;
-}
-''';
- _resolveTestUnit(code);
- _expectInitializerType('foo', 'int', isNull);
- }
-}
-
-@reflectiveTest
-class StrongModeTypePropagationTest extends ResolverTestCase {
- @override
- void setUp() {
- super.setUp();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.strongMode = true;
- resetWithOptions(options);
- }
-
- void test_foreachInference_dynamic_disabled() {
- String code = r'''
-main() {
- var list = <int>[];
- for (dynamic v in list) {
- v; // marker
- }
-}''';
- _assertPropagatedIterationType(
- code, typeProvider.dynamicType, typeProvider.intType);
- _assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
- void test_foreachInference_reusedVar_disabled() {
- String code = r'''
-main() {
- var list = <int>[];
- var v;
- for (v in list) {
- v; // marker
- }
-}''';
- _assertPropagatedIterationType(
- code, typeProvider.dynamicType, typeProvider.intType);
- _assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
- void test_foreachInference_var() {
- String code = r'''
-main() {
- var list = <int>[];
- for (var v in list) {
- v; // marker
- }
-}''';
- _assertPropagatedIterationType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_foreachInference_var_iterable() {
- String code = r'''
-main() {
- Iterable<int> list = <int>[];
- for (var v in list) {
- v; // marker
- }
-}''';
- _assertPropagatedIterationType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_foreachInference_var_stream() {
- String code = r'''
-import 'dart:async';
-main() async {
- Stream<int> stream = null;
- await for (var v in stream) {
- v; // marker
- }
-}''';
- _assertPropagatedIterationType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_bottom_disabled() {
- String code = r'''
-main() {
- var v = null;
- v; // marker
-}''';
- _assertPropagatedAssignedType(code, typeProvider.dynamicType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null);
- }
-
- void test_localVariableInference_constant() {
- String code = r'''
-main() {
- var v = 3;
- v; // marker
-}''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_declaredType_disabled() {
- String code = r'''
-main() {
- dynamic v = 3;
- v; // marker
-}''';
- _assertPropagatedAssignedType(
- code, typeProvider.dynamicType, typeProvider.intType);
- _assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
- void test_localVariableInference_noInitializer_disabled() {
- String code = r'''
-main() {
- var v;
- v = 3;
- v; // marker
-}''';
- _assertPropagatedAssignedType(
- code, typeProvider.dynamicType, typeProvider.intType);
- _assertTypeOfMarkedExpression(
- code, typeProvider.dynamicType, typeProvider.intType);
- }
-
- void test_localVariableInference_transitive_field_inferred_lexical() {
- String code = r'''
-class A {
- final x = 3;
- f() {
- var v = x;
- return v; // marker
- }
-}
-main() {
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_transitive_field_inferred_reversed() {
- String code = r'''
-class A {
- f() {
- var v = x;
- return v; // marker
- }
- final x = 3;
-}
-main() {
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_transitive_field_lexical() {
- String code = r'''
-class A {
- int x = 3;
- f() {
- var v = x;
- return v; // marker
- }
-}
-main() {
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_transitive_field_reversed() {
- String code = r'''
-class A {
- f() {
- var v = x;
- return v; // marker
- }
- int x = 3;
-}
-main() {
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_transitive_list_local() {
- String code = r'''
-main() {
- var x = <int>[3];
- var v = x[0];
- v; // marker
-}''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_transitive_local() {
- String code = r'''
-main() {
- var x = 3;
- var v = x;
- v; // marker
-}''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_transitive_toplevel_inferred_lexical() {
- String code = r'''
-final x = 3;
-main() {
- var v = x;
- v; // marker
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_transitive_toplevel_inferred_reversed() {
- String code = r'''
-main() {
- var v = x;
- v; // marker
-}
-final x = 3;
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_transitive_toplevel_lexical() {
- String code = r'''
-int x = 3;
-main() {
- var v = x;
- v; // marker
-}
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-
- void test_localVariableInference_transitive_toplevel_reversed() {
- String code = r'''
-main() {
- var v = x;
- v; // marker
-}
-int x = 3;
-''';
- _assertPropagatedAssignedType(code, typeProvider.intType, null);
- _assertTypeOfMarkedExpression(code, typeProvider.intType, null);
- }
-}
-
@reflectiveTest
class SubtypeManagerTest {
/**
@@ -14820,23 +1139,6 @@
}
}
-class TestPackageUriResolver extends UriResolver {
- Map<Uri, Source> sourceMap = new HashMap<Uri, Source>();
-
- TestPackageUriResolver(Map<String, String> map) {
- map.forEach((String uri, String contents) {
- sourceMap[Uri.parse(uri)] =
- new StringSource(contents, '/test_pkg_source.dart');
- });
- }
-
- @override
- Source resolveAbsolute(Uri uri, [Uri actualUri]) => sourceMap[uri];
-
- @override
- Uri restoreAbsolute(Source source) => throw new UnimplementedError();
-}
-
@reflectiveTest
class TypeOverrideManagerTest extends EngineTestCase {
void test_exitScope_noScopes() {
@@ -14912,7 +1214,7 @@
class TypePropagationTest extends ResolverTestCase {
void fail_mergePropagatedTypesAtJoinPoint_1() {
// https://code.google.com/p/dart/issues/detail?id=19929
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f1(x) {
var y = [];
@@ -14931,7 +1233,7 @@
void fail_mergePropagatedTypesAtJoinPoint_2() {
// https://code.google.com/p/dart/issues/detail?id=19929
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f2(x) {
var y = [];
@@ -14949,7 +1251,7 @@
void fail_mergePropagatedTypesAtJoinPoint_3() {
// https://code.google.com/p/dart/issues/detail?id=19929
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f4(x) {
var y = [];
@@ -14969,7 +1271,7 @@
void fail_mergePropagatedTypesAtJoinPoint_5() {
// https://code.google.com/p/dart/issues/detail?id=19929
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f6(x,y) {
var z = [];
@@ -15009,7 +1311,7 @@
x; // marker
}
}''';
- DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType;
+ DartType t = findMarkedIdentifier(code, "; // marker").propagatedType;
expect(typeProvider.intType.isSubtypeOf(t), isTrue);
expect(typeProvider.stringType.isSubtypeOf(t), isTrue);
}
@@ -15041,7 +1343,7 @@
}
}
}''';
- DartType t = _findMarkedIdentifier(code, "; // marker").propagatedType;
+ DartType t = findMarkedIdentifier(code, "; // marker").propagatedType;
expect(typeProvider.intType.isSubtypeOf(t), isTrue);
expect(typeProvider.stringType.isSubtypeOf(t), isTrue);
}
@@ -15052,7 +1354,7 @@
main() {
var v = (() {return 42;})();
}''';
- _assertPropagatedAssignedType(
+ assertPropagatedAssignedType(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15206,7 +1508,7 @@
f(A a) {
return a.v; // marker
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15224,7 +1526,7 @@
return v; // marker
}
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15243,7 +1545,7 @@
return p.v; // marker
}
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15255,7 +1557,7 @@
v; // marker
}
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15271,7 +1573,7 @@
f() {
return A.V; // marker
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15282,7 +1584,7 @@
f() {
var v2 = p.V; // marker prefixed
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15293,7 +1595,7 @@
f() {
return V; // marker simple
}''';
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -15730,7 +2032,7 @@
helper.max(10, 10); // marker
}''';
SimpleIdentifier methodName =
- _findMarkedIdentifier(code, "(10, 10); // marker");
+ findMarkedIdentifier(code, "(10, 10); // marker");
MethodInvocation methodInvoke = methodName.parent;
expect(methodInvoke.methodName.staticElement, isNotNull);
expect(methodInvoke.methodName.propagatedElement, isNull);
@@ -16096,8 +2398,8 @@
return a; // marker
}
}''';
- DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType;
- _assertTypeOfMarkedExpression(code, null, tB);
+ DartType tB = findMarkedIdentifier(code, "; // B").propagatedType;
+ assertTypeOfMarkedExpression(code, null, tB);
}
void test_issue20904BuggyTypePromotionAtIfJoin_6() {
@@ -16116,8 +2418,8 @@
return b; // marker
}
}''';
- DartType tB = _findMarkedIdentifier(code, "; // B").propagatedType;
- _assertTypeOfMarkedExpression(code, null, tB);
+ DartType tB = findMarkedIdentifier(code, "; // B").propagatedType;
+ assertTypeOfMarkedExpression(code, null, tB);
}
void test_listLiteral_different() {
@@ -16218,17 +2520,17 @@
return v;
}''';
{
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "v;");
+ SimpleIdentifier identifier = findMarkedIdentifier(code, "v;");
expect(identifier.propagatedType, null);
}
{
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "v = '';");
+ SimpleIdentifier identifier = findMarkedIdentifier(code, "v = '';");
expect(identifier.propagatedType, typeProvider.stringType);
}
}
void test_mergePropagatedTypes_afterIfThen_same() {
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
main() {
var v = 1;
@@ -16242,7 +2544,7 @@
}
void test_mergePropagatedTypes_afterIfThenElse_different() {
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
main() {
var v = 1;
@@ -16258,7 +2560,7 @@
}
void test_mergePropagatedTypes_afterIfThenElse_same() {
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
main() {
var v = 1;
@@ -16275,7 +2577,7 @@
void test_mergePropagatedTypesAtJoinPoint_4() {
// https://code.google.com/p/dart/issues/detail?id=19929
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f5(x) {
var y = [];
@@ -16336,7 +2638,7 @@
helper.$name; // marker
}''';
- SimpleIdentifier id = _findMarkedIdentifier(code, "; // marker");
+ SimpleIdentifier id = findMarkedIdentifier(code, "; // marker");
PrefixedIdentifier prefixedId = id.parent;
expect(id.staticType, typeProvider.dynamicType);
expect(prefixedId.staticType, typeProvider.dynamicType);
@@ -16350,7 +2652,7 @@
$name; // marker
}''';
- SimpleIdentifier getter = _findMarkedIdentifier(code, "; // marker");
+ SimpleIdentifier getter = findMarkedIdentifier(code, "; // marker");
expect(getter.staticType, typeProvider.dynamicType);
}
@@ -16361,7 +2663,7 @@
dynamic obj;
obj..$name..$name; // marker
}''';
- PropertyAccess access = _findMarkedIdentifier(code, "; // marker").parent;
+ PropertyAccess access = findMarkedIdentifier(code, "; // marker").parent;
expect(access.staticType, typeProvider.dynamicType);
expect(access.realTarget.staticType, typeProvider.dynamicType);
}
@@ -16379,7 +2681,7 @@
main() {
helper.$name(); // marker
}''';
- SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker");
+ SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker");
MethodInvocation methodInvoke = methodName.parent;
expect(methodName.staticType, typeProvider.dynamicType);
expect(methodInvoke.staticType, typeProvider.dynamicType);
@@ -16392,10 +2694,10 @@
dynamic $name = () => null;
$name(); // marker
}''';
- SimpleIdentifier identifier = _findMarkedIdentifier(code, "$name = ");
+ SimpleIdentifier identifier = findMarkedIdentifier(code, "$name = ");
expect(identifier.staticType, typeProvider.dynamicType);
- SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker");
+ SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker");
MethodInvocation methodInvoke = methodName.parent;
expect(methodName.staticType, typeProvider.dynamicType);
expect(methodInvoke.staticType, typeProvider.dynamicType);
@@ -16408,7 +2710,7 @@
dynamic obj;
obj..$name()..$name(); // marker
}''';
- SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker");
+ SimpleIdentifier methodName = findMarkedIdentifier(code, "(); // marker");
MethodInvocation methodInvoke = methodName.parent;
expect(methodInvoke.staticType, typeProvider.dynamicType);
@@ -16422,7 +2724,7 @@
// static type of [bool] for [==] comparison and the implementation
// was already consistent with the spec there. But, it's another
// [Object] method, so it's included here.
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f1(x) {
var v = (x == x);
@@ -16434,7 +2736,7 @@
void test_objectMethodOnDynamicExpression_hashCode() {
// https://code.google.com/p/dart/issues/detail?id=20342
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f1(x) {
var v = x.hashCode;
@@ -16446,7 +2748,7 @@
void test_objectMethodOnDynamicExpression_runtimeType() {
// https://code.google.com/p/dart/issues/detail?id=20342
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f1(x) {
var v = x.runtimeType;
@@ -16458,7 +2760,7 @@
void test_objectMethodOnDynamicExpression_toString() {
// https://code.google.com/p/dart/issues/detail?id=20342
- _assertTypeOfMarkedExpression(
+ assertTypeOfMarkedExpression(
r'''
f1(x) {
var v = x.toString();
@@ -16474,7 +2776,7 @@
f() => 42;
var v = f();
}''';
- _assertPropagatedAssignedType(
+ assertPropagatedAssignedType(
code, typeProvider.dynamicType, typeProvider.intType);
}
@@ -17338,70 +3640,6 @@
}
}
-class _AnalysisContextFactory_initContextWithCore
- extends DirectoryBasedDartSdk {
- final bool enableAsync;
- _AnalysisContextFactory_initContextWithCore(JavaFile arg0,
- {this.enableAsync: true})
- : super(arg0);
-
- @override
- LibraryMap initialLibraryMap(bool useDart2jsPaths) {
- LibraryMap map = new LibraryMap();
- if (enableAsync) {
- _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart");
- }
- _addLibrary(map, DartSdk.DART_CORE, false, "core.dart");
- _addLibrary(map, DartSdk.DART_HTML, false, "html_dartium.dart");
- _addLibrary(map, AnalysisContextFactory._DART_MATH, false, "math.dart");
- _addLibrary(map, AnalysisContextFactory._DART_INTERCEPTORS, true,
- "_interceptors.dart");
- _addLibrary(
- map, AnalysisContextFactory._DART_JS_HELPER, true, "_js_helper.dart");
- return map;
- }
-
- void _addLibrary(LibraryMap map, String uri, bool isInternal, String path) {
- SdkLibraryImpl library = new SdkLibraryImpl(uri);
- if (isInternal) {
- library.category = "Internal";
- }
- library.path = path;
- map.setLibrary(uri, library);
- }
-}
-
-class _SimpleResolverTest_localVariable_types_invoked
- extends RecursiveAstVisitor<Object> {
- final SimpleResolverTest test;
-
- List<bool> found;
-
- List<CaughtException> thrownException;
-
- _SimpleResolverTest_localVariable_types_invoked(
- this.test, this.found, this.thrownException)
- : super();
-
- @override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
- if (node.name == "myVar" && node.parent is MethodInvocation) {
- try {
- found[0] = true;
- // check static type
- DartType staticType = node.staticType;
- expect(staticType, same(test.typeProvider.dynamicType));
- // check propagated type
- FunctionType propagatedType = node.propagatedType as FunctionType;
- expect(propagatedType.returnType, test.typeProvider.stringType);
- } on AnalysisException catch (e, stackTrace) {
- thrownException[0] = new CaughtException(e, stackTrace);
- }
- }
- return null;
- }
-}
-
/**
* Represents an element left over from a previous resolver run.
*
@@ -17416,103 +3654,3 @@
@override
accept(_) => throw "_StaleElement shouldn't be visited";
}
-
-/**
- * Shared infrastructure for [StaticTypeAnalyzer2Test] and
- * [StrongModeStaticTypeAnalyzer2Test].
- */
-class _StaticTypeAnalyzer2TestShared extends ResolverTestCase {
- String testCode;
- Source testSource;
- CompilationUnit testUnit;
-
- /**
- * Looks up the identifier with [name] and validates that its type type
- * stringifies to [type] and that its generics match the given stringified
- * output.
- */
- _expectFunctionType(String name, String type,
- {String elementTypeParams: '[]',
- String typeParams: '[]',
- String typeArgs: '[]',
- String typeFormals: '[]'}) {
- SimpleIdentifier identifier = _findIdentifier(name);
- // Element is either ExecutableElement or ParameterElement.
- var element = identifier.staticElement;
- FunctionTypeImpl functionType = identifier.staticType;
- expect(functionType.toString(), type);
- expect(element.typeParameters.toString(), elementTypeParams);
- expect(functionType.typeParameters.toString(), typeParams);
- expect(functionType.typeArguments.toString(), typeArgs);
- expect(functionType.typeFormals.toString(), typeFormals);
- }
-
- /**
- * Looks up the identifier with [name] and validates its static [type].
- *
- * If [type] is a string, validates that the identifier's static type
- * stringifies to that text. Otherwise, [type] is used directly a [Matcher]
- * to match the type.
- *
- * If [propagatedType] is given, also validate's the identifier's propagated
- * type.
- */
- void _expectIdentifierType(String name, type, [propagatedType]) {
- SimpleIdentifier identifier = _findIdentifier(name);
- _expectType(identifier.staticType, type);
- if (propagatedType != null) {
- _expectType(identifier.propagatedType, propagatedType);
- }
- }
-
- /**
- * Looks up the initializer for the declaration containing [identifier] and
- * validates its static [type].
- *
- * If [type] is a string, validates that the identifier's static type
- * stringifies to that text. Otherwise, [type] is used directly a [Matcher]
- * to match the type.
- *
- * If [propagatedType] is given, also validate's the identifier's propagated
- * type.
- */
- void _expectInitializerType(String name, type, [propagatedType]) {
- SimpleIdentifier identifier = _findIdentifier(name);
- VariableDeclaration declaration =
- identifier.getAncestor((node) => node is VariableDeclaration);
- Expression initializer = declaration.initializer;
- _expectType(initializer.staticType, type);
- if (propagatedType != null) {
- _expectType(initializer.propagatedType, propagatedType);
- }
- }
-
- /**
- * Validates that [type] matches [expected].
- *
- * If [expected] is a string, validates that the type stringifies to that
- * text. Otherwise, [expected] is used directly a [Matcher] to match the type.
- */
- _expectType(DartType type, expected) {
- if (expected is String) {
- expect(type.toString(), expected);
- } else {
- expect(type, expected);
- }
- }
-
- SimpleIdentifier _findIdentifier(String search) {
- SimpleIdentifier identifier = EngineTestCase.findNode(
- testUnit, testCode, search, (node) => node is SimpleIdentifier);
- return identifier;
- }
-
- void _resolveTestUnit(String code) {
- testCode = code;
- testSource = addSource(testCode);
- LibraryElement library = resolve2(testSource);
- assertNoErrors(testSource);
- verify([testSource]);
- testUnit = resolveCompilationUnit(testSource, library);
- }
-}
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
new file mode 100644
index 0000000..f6bd1cf
--- /dev/null
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -0,0 +1,839 @@
+// 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 analyzer.test.generated.resolver_test_case;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:unittest/unittest.dart';
+
+import 'analysis_context_factory.dart';
+import 'test_support.dart';
+
+class ResolverTestCase extends EngineTestCase {
+ /**
+ * The analysis context used to parse the compilation units being resolved.
+ */
+ InternalAnalysisContext analysisContext2;
+
+ /**
+ * Specifies if [assertErrors] should check for [HintCode.UNUSED_ELEMENT] and
+ * [HintCode.UNUSED_FIELD].
+ */
+ bool enableUnusedElement = false;
+
+ /**
+ * Specifies if [assertErrors] should check for [HintCode.UNUSED_LOCAL_VARIABLE].
+ */
+ bool enableUnusedLocalVariable = false;
+
+ AnalysisContext get analysisContext => analysisContext2;
+
+ /**
+ * Return a type provider that can be used to test the results of resolution.
+ *
+ * @return a type provider
+ * @throws AnalysisException if dart:core cannot be resolved
+ */
+ TypeProvider get typeProvider => analysisContext2.typeProvider;
+
+ /**
+ * Return a type system that can be used to test the results of resolution.
+ *
+ * @return a type system
+ */
+ TypeSystem get typeSystem => analysisContext2.typeSystem;
+
+ /**
+ * Add a source file to the content provider. The file path should be absolute.
+ *
+ * @param filePath the path of the file being added
+ * @param contents the contents to be returned by the content provider for the specified file
+ * @return the source object representing the added file
+ */
+ Source addNamedSource(String filePath, String contents) {
+ Source source = cacheSource(filePath, contents);
+ ChangeSet changeSet = new ChangeSet();
+ changeSet.addedSource(source);
+ analysisContext2.applyChanges(changeSet);
+ return source;
+ }
+
+ /**
+ * Add a source file to the content provider.
+ *
+ * @param contents the contents to be returned by the content provider for the specified file
+ * @return the source object representing the added file
+ */
+ Source addSource(String contents) => addNamedSource("/test.dart", contents);
+
+ /**
+ * Assert that the number of errors reported against the given source matches the number of errors
+ * that are given and that they have the expected error codes. The order in which the errors were
+ * gathered is ignored.
+ *
+ * @param source the source against which the errors should have been reported
+ * @param expectedErrorCodes the error codes of the errors that should have been reported
+ * @throws AnalysisException if the reported errors could not be computed
+ * @throws AssertionFailedError if a different number of errors have been reported than were
+ * expected
+ */
+ void assertErrors(Source source,
+ [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ for (AnalysisError error in analysisContext2.computeErrors(source)) {
+ expect(error.source, source);
+ ErrorCode errorCode = error.errorCode;
+ if (!enableUnusedElement &&
+ (errorCode == HintCode.UNUSED_ELEMENT ||
+ errorCode == HintCode.UNUSED_FIELD)) {
+ continue;
+ }
+ if (!enableUnusedLocalVariable &&
+ (errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
+ errorCode == HintCode.UNUSED_CATCH_STACK ||
+ errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) {
+ continue;
+ }
+ errorListener.onError(error);
+ }
+ errorListener.assertErrorsWithCodes(expectedErrorCodes);
+ }
+
+ /**
+ * Asserts that [code] verifies, but has errors with the given error codes.
+ *
+ * Like [assertErrors], but takes a string of source code.
+ */
+ // TODO(rnystrom): Use this in more tests that have the same structure.
+ void assertErrorsInCode(String code, List<ErrorCode> errors) {
+ Source source = addSource(code);
+ computeLibrarySourceErrors(source);
+ assertErrors(source, errors);
+ verify([source]);
+ }
+
+ /**
+ * Asserts that [code] has errors with the given error codes.
+ *
+ * Like [assertErrors], but takes a string of source code.
+ */
+ void assertErrorsInUnverifiedCode(String code, List<ErrorCode> errors) {
+ Source source = addSource(code);
+ computeLibrarySourceErrors(source);
+ assertErrors(source, errors);
+ }
+
+ /**
+ * Assert that no errors have been reported against the given source.
+ *
+ * @param source the source against which no errors should have been reported
+ * @throws AnalysisException if the reported errors could not be computed
+ * @throws AssertionFailedError if any errors have been reported
+ */
+ void assertNoErrors(Source source) {
+ assertErrors(source);
+ }
+
+ /**
+ * Asserts that [code] has no errors or warnings.
+ */
+ // TODO(rnystrom): Use this in more tests that have the same structure.
+ void assertNoErrorsInCode(String code) {
+ Source source = addSource(code);
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ /**
+ * Cache the source file content in the source factory but don't add the source to the analysis
+ * context. The file path should be absolute.
+ *
+ * @param filePath the path of the file being cached
+ * @param contents the contents to be returned by the content provider for the specified file
+ * @return the source object representing the cached file
+ */
+ Source cacheSource(String filePath, String contents) {
+ Source source = new FileBasedSource(FileUtilities2.createFile(filePath));
+ analysisContext2.setContents(source, contents);
+ return source;
+ }
+
+ /**
+ * Change the contents of the given [source] to the given [contents].
+ */
+ void changeSource(Source source, String contents) {
+ analysisContext2.setContents(source, contents);
+ ChangeSet changeSet = new ChangeSet();
+ changeSet.changedSource(source);
+ analysisContext2.applyChanges(changeSet);
+ }
+
+ /**
+ * Computes errors for the given [librarySource].
+ * This assumes that the given [librarySource] and its parts have already
+ * been added to the content provider using the method [addNamedSource].
+ */
+ void computeLibrarySourceErrors(Source librarySource) {
+ analysisContext.computeErrors(librarySource);
+ }
+
+ /**
+ * Create a library element that represents a library named `"test"` containing a single
+ * empty compilation unit.
+ *
+ * @return the library element that was created
+ */
+ LibraryElementImpl createDefaultTestLibrary() =>
+ createTestLibrary(AnalysisContextFactory.contextWithCore(), "test");
+
+ /**
+ * Create a library element that represents a library with the given name containing a single
+ * empty compilation unit.
+ *
+ * @param libraryName the name of the library to be created
+ * @return the library element that was created
+ */
+ LibraryElementImpl createTestLibrary(
+ AnalysisContext context, String libraryName,
+ [List<String> typeNames]) {
+ String fileName = "$libraryName.dart";
+ FileBasedSource definingCompilationUnitSource =
+ createNamedSource(fileName);
+ List<CompilationUnitElement> sourcedCompilationUnits;
+ if (typeNames == null) {
+ sourcedCompilationUnits = CompilationUnitElement.EMPTY_LIST;
+ } else {
+ int count = typeNames.length;
+ sourcedCompilationUnits = new List<CompilationUnitElement>(count);
+ for (int i = 0; i < count; i++) {
+ String typeName = typeNames[i];
+ ClassElementImpl type =
+ new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
+ String fileName = "$typeName.dart";
+ CompilationUnitElementImpl compilationUnit =
+ new CompilationUnitElementImpl(fileName);
+ compilationUnit.source = createNamedSource(fileName);
+ compilationUnit.librarySource = definingCompilationUnitSource;
+ compilationUnit.types = <ClassElement>[type];
+ sourcedCompilationUnits[i] = compilationUnit;
+ }
+ }
+ CompilationUnitElementImpl compilationUnit =
+ new CompilationUnitElementImpl(fileName);
+ compilationUnit.librarySource =
+ compilationUnit.source = definingCompilationUnitSource;
+ LibraryElementImpl library = new LibraryElementImpl.forNode(
+ context, AstFactory.libraryIdentifier2([libraryName]));
+ library.definingCompilationUnit = compilationUnit;
+ library.parts = sourcedCompilationUnits;
+ return library;
+ }
+
+ Expression findTopLevelConstantExpression(
+ CompilationUnit compilationUnit, String name) =>
+ findTopLevelDeclaration(compilationUnit, name).initializer;
+
+ VariableDeclaration findTopLevelDeclaration(
+ CompilationUnit compilationUnit, String name) {
+ for (CompilationUnitMember member in compilationUnit.declarations) {
+ if (member is TopLevelVariableDeclaration) {
+ for (VariableDeclaration variable in member.variables.variables) {
+ if (variable.name.name == name) {
+ return variable;
+ }
+ }
+ }
+ }
+ return null;
+ // Not found
+ }
+
+ /**
+ * In the rare cases we want to group several tests into single "test_" method, so need a way to
+ * reset test instance to reuse it.
+ */
+ void reset() {
+ analysisContext2 = AnalysisContextFactory.contextWithCore();
+ }
+
+ /**
+ * Reset the analysis context to have the given options applied.
+ *
+ * @param options the analysis options to be applied to the context
+ */
+ void resetWithOptions(AnalysisOptions options) {
+ analysisContext2 =
+ AnalysisContextFactory.contextWithCoreAndOptions(options);
+ }
+
+ /**
+ * Given a library and all of its parts, resolve the contents of the library and the contents of
+ * the parts. This assumes that the sources for the library and its parts have already been added
+ * to the content provider using the method [addNamedSource].
+ *
+ * @param librarySource the source for the compilation unit that defines the library
+ * @return the element representing the resolved library
+ * @throws AnalysisException if the analysis could not be performed
+ */
+ LibraryElement resolve2(Source librarySource) =>
+ analysisContext2.computeLibraryElement(librarySource);
+
+ /**
+ * Return the resolved compilation unit corresponding to the given source in the given library.
+ *
+ * @param source the source of the compilation unit to be returned
+ * @param library the library in which the compilation unit is to be resolved
+ * @return the resolved compilation unit
+ * @throws Exception if the compilation unit could not be resolved
+ */
+ CompilationUnit resolveCompilationUnit(
+ Source source, LibraryElement library) =>
+ analysisContext2.resolveCompilationUnit(source, library);
+
+ CompilationUnit resolveSource(String sourceText) =>
+ resolveSource2("/test.dart", sourceText);
+
+ CompilationUnit resolveSource2(String fileName, String sourceText) {
+ Source source = addNamedSource(fileName, sourceText);
+ LibraryElement library = analysisContext.computeLibraryElement(source);
+ return analysisContext.resolveCompilationUnit(source, library);
+ }
+
+ Source resolveSources(List<String> sourceTexts) {
+ for (int i = 0; i < sourceTexts.length; i++) {
+ CompilationUnit unit =
+ resolveSource2("/lib${i + 1}.dart", sourceTexts[i]);
+ // reference the source if this is the last source
+ if (i + 1 == sourceTexts.length) {
+ return unit.element.source;
+ }
+ }
+ return null;
+ }
+
+ void resolveWithAndWithoutExperimental(
+ List<String> strSources,
+ List<ErrorCode> codesWithoutExperimental,
+ List<ErrorCode> codesWithExperimental) {
+ // Setup analysis context as non-experimental
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+// options.enableDeferredLoading = false;
+ resetWithOptions(options);
+ // Analysis and assertions
+ Source source = resolveSources(strSources);
+ assertErrors(source, codesWithoutExperimental);
+ verify([source]);
+ // Setup analysis context as experimental
+ reset();
+ // Analysis and assertions
+ source = resolveSources(strSources);
+ assertErrors(source, codesWithExperimental);
+ verify([source]);
+ }
+
+ void resolveWithErrors(List<String> strSources, List<ErrorCode> codes) {
+ // Analysis and assertions
+ Source source = resolveSources(strSources);
+ assertErrors(source, codes);
+ verify([source]);
+ }
+
+ @override
+ void setUp() {
+ ElementFactory.flushStaticState();
+ super.setUp();
+ reset();
+ }
+
+ @override
+ void tearDown() {
+ analysisContext2 = null;
+ super.tearDown();
+ }
+
+ /**
+ * Verify that all of the identifiers in the compilation units associated with
+ * the given [sources] have been resolved.
+ */
+ void verify(List<Source> sources) {
+ ResolutionVerifier verifier = new ResolutionVerifier();
+ for (Source source in sources) {
+ List<Source> libraries = analysisContext2.getLibrariesContaining(source);
+ for (Source library in libraries) {
+ analysisContext2
+ .resolveCompilationUnit2(source, library)
+ .accept(verifier);
+ }
+ }
+ verifier.assertResolved();
+ }
+
+ /**
+ * @param code the code that assigns the value to the variable "v", no matter how. We check that
+ * "v" has expected static and propagated type.
+ */
+ void assertPropagatedAssignedType(String code, DartType expectedStaticType,
+ DartType expectedPropagatedType) {
+ SimpleIdentifier identifier = findMarkedIdentifier(code, "v = ");
+ expect(identifier.staticType, same(expectedStaticType));
+ expect(identifier.propagatedType, same(expectedPropagatedType));
+ }
+
+ /**
+ * @param code the code that iterates using variable "v". We check that
+ * "v" has expected static and propagated type.
+ */
+ void assertPropagatedIterationType(String code, DartType expectedStaticType,
+ DartType expectedPropagatedType) {
+ SimpleIdentifier identifier = findMarkedIdentifier(code, "v in ");
+ expect(identifier.staticType, same(expectedStaticType));
+ expect(identifier.propagatedType, same(expectedPropagatedType));
+ }
+
+ /**
+ * Check the static and propagated types of the expression marked with "; // marker" comment.
+ *
+ * @param code source code to analyze, with the expression to check marked with "// marker".
+ * @param expectedStaticType if non-null, check actual static type is equal to this.
+ * @param expectedPropagatedType if non-null, check actual static type is equal to this.
+ * @throws Exception
+ */
+ void assertTypeOfMarkedExpression(String code, DartType expectedStaticType,
+ DartType expectedPropagatedType) {
+ SimpleIdentifier identifier = findMarkedIdentifier(code, "; // marker");
+ if (expectedStaticType != null) {
+ expect(identifier.staticType, expectedStaticType);
+ }
+ expect(identifier.propagatedType, expectedPropagatedType);
+ }
+
+ /**
+ * Create a source object representing a file with the given [fileName] and
+ * give it an empty content. Return the source that was created.
+ */
+ FileBasedSource createNamedSource(String fileName) {
+ FileBasedSource source =
+ new FileBasedSource(FileUtilities2.createFile(fileName));
+ analysisContext2.setContents(source, "");
+ return source;
+ }
+
+ /**
+ * Return the `SimpleIdentifier` marked by `marker`. The source code must have no
+ * errors and be verifiable.
+ *
+ * @param code source code to analyze.
+ * @param marker marker identifying sought after expression in source code.
+ * @return expression marked by the marker.
+ * @throws Exception
+ */
+ SimpleIdentifier findMarkedIdentifier(String code, String marker) {
+ try {
+ Source source = addSource(code);
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ CompilationUnit unit = resolveCompilationUnit(source, library);
+ // Could generalize this further by making [SimpleIdentifier.class] a
+ // parameter.
+ return EngineTestCase.findNode(
+ unit, code, marker, (node) => node is SimpleIdentifier);
+ } catch (exception) {
+ // Is there a better exception to throw here? The point is that an
+ // assertion failure here should be a failure, in both "test_*" and
+ // "fail_*" tests. However, an assertion failure is success for the
+ // purpose of "fail_*" tests, so without catching them here "fail_*" tests
+ // can succeed by failing for the wrong reason.
+ throw new JavaException("Unexexpected assertion failure: $exception");
+ }
+ }
+}
+
+/**
+ * An AST visitor used to verify that all of the nodes in an AST structure that
+ * should have been resolved were resolved.
+ */
+class ResolutionVerifier extends RecursiveAstVisitor<Object> {
+ /**
+ * A set containing nodes that are known to not be resolvable and should
+ * therefore not cause the test to fail.
+ */
+ final Set<AstNode> _knownExceptions;
+
+ /**
+ * A list containing all of the AST nodes that were not resolved.
+ */
+ List<AstNode> _unresolvedNodes = new List<AstNode>();
+
+ /**
+ * A list containing all of the AST nodes that were resolved to an element of
+ * the wrong type.
+ */
+ List<AstNode> _wrongTypedNodes = new List<AstNode>();
+
+ /**
+ * Initialize a newly created verifier to verify that all of the identifiers
+ * in the visited AST structures that are expected to have been resolved have
+ * an element associated with them. Nodes in the set of [_knownExceptions] are
+ * not expected to have been resolved, even if they normally would have been
+ * expected to have been resolved.
+ */
+ ResolutionVerifier([this._knownExceptions]);
+
+ /**
+ * Assert that all of the visited identifiers were resolved.
+ */
+ void assertResolved() {
+ if (!_unresolvedNodes.isEmpty || !_wrongTypedNodes.isEmpty) {
+ StringBuffer buffer = new StringBuffer();
+ if (!_unresolvedNodes.isEmpty) {
+ buffer.write("Failed to resolve ");
+ buffer.write(_unresolvedNodes.length);
+ buffer.writeln(" nodes:");
+ _printNodes(buffer, _unresolvedNodes);
+ }
+ if (!_wrongTypedNodes.isEmpty) {
+ buffer.write("Resolved ");
+ buffer.write(_wrongTypedNodes.length);
+ buffer.writeln(" to the wrong type of element:");
+ _printNodes(buffer, _wrongTypedNodes);
+ }
+ fail(buffer.toString());
+ }
+ }
+
+ @override
+ Object visitAnnotation(Annotation node) {
+ node.visitChildren(this);
+ ElementAnnotation elementAnnotation = node.elementAnnotation;
+ if (elementAnnotation == null) {
+ if (_knownExceptions == null || !_knownExceptions.contains(node)) {
+ _unresolvedNodes.add(node);
+ }
+ } else if (elementAnnotation is! ElementAnnotation) {
+ _wrongTypedNodes.add(node);
+ }
+ return null;
+ }
+
+ @override
+ Object visitBinaryExpression(BinaryExpression node) {
+ node.visitChildren(this);
+ if (!node.operator.isUserDefinableOperator) {
+ return null;
+ }
+ DartType operandType = node.leftOperand.staticType;
+ if (operandType == null || operandType.isDynamic) {
+ return null;
+ }
+ return _checkResolved(
+ node, node.staticElement, (node) => node is MethodElement);
+ }
+
+ @override
+ Object visitCommentReference(CommentReference node) => null;
+
+ @override
+ Object visitCompilationUnit(CompilationUnit node) {
+ node.visitChildren(this);
+ return _checkResolved(
+ node, node.element, (node) => node is CompilationUnitElement);
+ }
+
+ @override
+ Object visitExportDirective(ExportDirective node) =>
+ _checkResolved(node, node.element, (node) => node is ExportElement);
+
+ @override
+ Object visitFunctionDeclaration(FunctionDeclaration node) {
+ node.visitChildren(this);
+ if (node.element is LibraryElement) {
+ _wrongTypedNodes.add(node);
+ }
+ return null;
+ }
+
+ @override
+ Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ node.visitChildren(this);
+ // TODO(brianwilkerson) If we start resolving function expressions, then
+ // conditionally check to see whether the node was resolved correctly.
+ return null;
+ //checkResolved(node, node.getElement(), FunctionElement.class);
+ }
+
+ @override
+ Object visitImportDirective(ImportDirective node) {
+ // Not sure how to test the combinators given that it isn't an error if the
+ // names are not defined.
+ _checkResolved(node, node.element, (node) => node is ImportElement);
+ SimpleIdentifier prefix = node.prefix;
+ if (prefix == null) {
+ return null;
+ }
+ return _checkResolved(
+ prefix, prefix.staticElement, (node) => node is PrefixElement);
+ }
+
+ @override
+ Object visitIndexExpression(IndexExpression node) {
+ node.visitChildren(this);
+ DartType targetType = node.realTarget.staticType;
+ if (targetType == null || targetType.isDynamic) {
+ return null;
+ }
+ return _checkResolved(
+ node, node.staticElement, (node) => node is MethodElement);
+ }
+
+ @override
+ Object visitLibraryDirective(LibraryDirective node) =>
+ _checkResolved(node, node.element, (node) => node is LibraryElement);
+
+ @override
+ Object visitNamedExpression(NamedExpression node) =>
+ node.expression.accept(this);
+
+ @override
+ Object visitPartDirective(PartDirective node) => _checkResolved(
+ node, node.element, (node) => node is CompilationUnitElement);
+
+ @override
+ Object visitPartOfDirective(PartOfDirective node) =>
+ _checkResolved(node, node.element, (node) => node is LibraryElement);
+
+ @override
+ Object visitPostfixExpression(PostfixExpression node) {
+ node.visitChildren(this);
+ if (!node.operator.isUserDefinableOperator) {
+ return null;
+ }
+ DartType operandType = node.operand.staticType;
+ if (operandType == null || operandType.isDynamic) {
+ return null;
+ }
+ return _checkResolved(
+ node, node.staticElement, (node) => node is MethodElement);
+ }
+
+ @override
+ Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ SimpleIdentifier prefix = node.prefix;
+ prefix.accept(this);
+ DartType prefixType = prefix.staticType;
+ if (prefixType == null || prefixType.isDynamic) {
+ return null;
+ }
+ return _checkResolved(node, node.staticElement, null);
+ }
+
+ @override
+ Object visitPrefixExpression(PrefixExpression node) {
+ node.visitChildren(this);
+ if (!node.operator.isUserDefinableOperator) {
+ return null;
+ }
+ DartType operandType = node.operand.staticType;
+ if (operandType == null || operandType.isDynamic) {
+ return null;
+ }
+ return _checkResolved(
+ node, node.staticElement, (node) => node is MethodElement);
+ }
+
+ @override
+ Object visitPropertyAccess(PropertyAccess node) {
+ Expression target = node.realTarget;
+ target.accept(this);
+ DartType targetType = target.staticType;
+ if (targetType == null || targetType.isDynamic) {
+ return null;
+ }
+ return node.propertyName.accept(this);
+ }
+
+ @override
+ Object visitSimpleIdentifier(SimpleIdentifier node) {
+ if (node.name == "void") {
+ return null;
+ }
+ if (node.staticType != null &&
+ node.staticType.isDynamic &&
+ node.staticElement == null) {
+ return null;
+ }
+ AstNode parent = node.parent;
+ if (parent is MethodInvocation) {
+ MethodInvocation invocation = parent;
+ if (identical(invocation.methodName, node)) {
+ Expression target = invocation.realTarget;
+ DartType targetType = target == null ? null : target.staticType;
+ if (targetType == null || targetType.isDynamic) {
+ return null;
+ }
+ }
+ }
+ return _checkResolved(node, node.staticElement, null);
+ }
+
+ Object _checkResolved(
+ AstNode node, Element element, Predicate<Element> predicate) {
+ if (element == null) {
+ if (_knownExceptions == null || !_knownExceptions.contains(node)) {
+ _unresolvedNodes.add(node);
+ }
+ } else if (predicate != null) {
+ if (!predicate(element)) {
+ _wrongTypedNodes.add(node);
+ }
+ }
+ return null;
+ }
+
+ String _getFileName(AstNode node) {
+ // TODO (jwren) there are two copies of this method, one here and one in
+ // StaticTypeVerifier, they should be resolved into a single method
+ if (node != null) {
+ AstNode root = node.root;
+ if (root is CompilationUnit) {
+ CompilationUnit rootCU = root;
+ if (rootCU.element != null) {
+ return rootCU.element.source.fullName;
+ } else {
+ return "<unknown file- CompilationUnit.getElement() returned null>";
+ }
+ } else {
+ return "<unknown file- CompilationUnit.getRoot() is not a CompilationUnit>";
+ }
+ }
+ return "<unknown file- ASTNode is null>";
+ }
+
+ void _printNodes(StringBuffer buffer, List<AstNode> nodes) {
+ for (AstNode identifier in nodes) {
+ buffer.write(" ");
+ buffer.write(identifier.toString());
+ buffer.write(" (");
+ buffer.write(_getFileName(identifier));
+ buffer.write(" : ");
+ buffer.write(identifier.offset);
+ buffer.writeln(")");
+ }
+ }
+}
+
+/**
+ * Shared infrastructure for [StaticTypeAnalyzer2Test] and
+ * [StrongModeStaticTypeAnalyzer2Test].
+ */
+class StaticTypeAnalyzer2TestShared extends ResolverTestCase {
+ String testCode;
+ Source testSource;
+ CompilationUnit testUnit;
+
+ /**
+ * Looks up the identifier with [name] and validates that its type type
+ * stringifies to [type] and that its generics match the given stringified
+ * output.
+ */
+ expectFunctionType(String name, String type,
+ {String elementTypeParams: '[]',
+ String typeParams: '[]',
+ String typeArgs: '[]',
+ String typeFormals: '[]'}) {
+ SimpleIdentifier identifier = findIdentifier(name);
+ // Element is either ExecutableElement or ParameterElement.
+ var element = identifier.staticElement;
+ FunctionTypeImpl functionType = identifier.staticType;
+ expect(functionType.toString(), type);
+ expect(element.typeParameters.toString(), elementTypeParams);
+ expect(functionType.typeParameters.toString(), typeParams);
+ expect(functionType.typeArguments.toString(), typeArgs);
+ expect(functionType.typeFormals.toString(), typeFormals);
+ }
+
+ /**
+ * Looks up the identifier with [name] and validates its static [type].
+ *
+ * If [type] is a string, validates that the identifier's static type
+ * stringifies to that text. Otherwise, [type] is used directly a [Matcher]
+ * to match the type.
+ *
+ * If [propagatedType] is given, also validate's the identifier's propagated
+ * type.
+ */
+ void expectIdentifierType(String name, type, [propagatedType]) {
+ SimpleIdentifier identifier = findIdentifier(name);
+ _expectType(identifier.staticType, type);
+ if (propagatedType != null) {
+ _expectType(identifier.propagatedType, propagatedType);
+ }
+ }
+
+ /**
+ * Looks up the initializer for the declaration containing [identifier] and
+ * validates its static [type].
+ *
+ * If [type] is a string, validates that the identifier's static type
+ * stringifies to that text. Otherwise, [type] is used directly a [Matcher]
+ * to match the type.
+ *
+ * If [propagatedType] is given, also validate's the identifier's propagated
+ * type.
+ */
+ void expectInitializerType(String name, type, [propagatedType]) {
+ SimpleIdentifier identifier = findIdentifier(name);
+ VariableDeclaration declaration =
+ identifier.getAncestor((node) => node is VariableDeclaration);
+ Expression initializer = declaration.initializer;
+ _expectType(initializer.staticType, type);
+ if (propagatedType != null) {
+ _expectType(initializer.propagatedType, propagatedType);
+ }
+ }
+
+ /**
+ * Validates that [type] matches [expected].
+ *
+ * If [expected] is a string, validates that the type stringifies to that
+ * text. Otherwise, [expected] is used directly a [Matcher] to match the type.
+ */
+ _expectType(DartType type, expected) {
+ if (expected is String) {
+ expect(type.toString(), expected);
+ } else {
+ expect(type, expected);
+ }
+ }
+
+ SimpleIdentifier findIdentifier(String search) {
+ SimpleIdentifier identifier = EngineTestCase.findNode(
+ testUnit, testCode, search, (node) => node is SimpleIdentifier);
+ return identifier;
+ }
+
+ void resolveTestUnit(String code) {
+ testCode = code;
+ testSource = addSource(testCode);
+ LibraryElement library = resolve2(testSource);
+ assertNoErrors(testSource);
+ verify([testSource]);
+ testUnit = resolveCompilationUnit(testSource, library);
+ }
+}
diff --git a/pkg/analyzer/test/generated/simple_resolver_test.dart b/pkg/analyzer/test/generated/simple_resolver_test.dart
new file mode 100644
index 0000000..12fc550
--- /dev/null
+++ b/pkg/analyzer/test/generated/simple_resolver_test.dart
@@ -0,0 +1,1762 @@
+// 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 analyzer.test.generated.simple_resolver_test;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'resolver_test_case.dart';
+import 'test_support.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(SimpleResolverTest);
+}
+
+@reflectiveTest
+class SimpleResolverTest extends ResolverTestCase {
+ void fail_getter_and_setter_fromMixins_property_access() {
+ // TODO(paulberry): it appears that auxiliaryElements isn't properly set on
+ // a SimpleIdentifier that's inside a property access. This bug should be
+ // fixed.
+ Source source = addSource('''
+class B {}
+class M1 {
+ get x => null;
+ set x(value) {}
+}
+class M2 {
+ get x => null;
+ set x(value) {}
+}
+class C extends B with M1, M2 {}
+void main() {
+ new C().x += 1;
+}
+''');
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ // Verify that both the getter and setter for "x" in "new C().x" refer to
+ // the accessors defined in M2.
+ FunctionDeclaration main =
+ library.definingCompilationUnit.functions[0].computeNode();
+ BlockFunctionBody body = main.functionExpression.body;
+ ExpressionStatement stmt = body.block.statements[0];
+ AssignmentExpression assignment = stmt.expression;
+ PropertyAccess propertyAccess = assignment.leftHandSide;
+ expect(
+ propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
+ expect(
+ propertyAccess
+ .propertyName.auxiliaryElements.staticElement.enclosingElement.name,
+ 'M2');
+ }
+
+ void fail_staticInvocation() {
+ Source source = addSource(r'''
+class A {
+ static int get g => (a,b) => 0;
+}
+class B {
+ f() {
+ A.g(1,0);
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_argumentResolution_required_matching() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2, 3);
+ }
+ void g(a, b, c) {}
+}''');
+ _validateArgumentResolution(source, [0, 1, 2]);
+ }
+
+ void test_argumentResolution_required_tooFew() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2);
+ }
+ void g(a, b, c) {}
+}''');
+ _validateArgumentResolution(source, [0, 1]);
+ }
+
+ void test_argumentResolution_required_tooMany() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2, 3);
+ }
+ void g(a, b) {}
+}''');
+ _validateArgumentResolution(source, [0, 1, -1]);
+ }
+
+ void test_argumentResolution_requiredAndNamed_extra() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2, c: 3, d: 4);
+ }
+ void g(a, b, {c}) {}
+}''');
+ _validateArgumentResolution(source, [0, 1, 2, -1]);
+ }
+
+ void test_argumentResolution_requiredAndNamed_matching() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2, c: 3);
+ }
+ void g(a, b, {c}) {}
+}''');
+ _validateArgumentResolution(source, [0, 1, 2]);
+ }
+
+ void test_argumentResolution_requiredAndNamed_missing() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2, d: 3);
+ }
+ void g(a, b, {c, d}) {}
+}''');
+ _validateArgumentResolution(source, [0, 1, 3]);
+ }
+
+ void test_argumentResolution_requiredAndPositional_fewer() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2, 3);
+ }
+ void g(a, b, [c, d]) {}
+}''');
+ _validateArgumentResolution(source, [0, 1, 2]);
+ }
+
+ void test_argumentResolution_requiredAndPositional_matching() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2, 3, 4);
+ }
+ void g(a, b, [c, d]) {}
+}''');
+ _validateArgumentResolution(source, [0, 1, 2, 3]);
+ }
+
+ void test_argumentResolution_requiredAndPositional_more() {
+ Source source = addSource(r'''
+class A {
+ void f() {
+ g(1, 2, 3, 4);
+ }
+ void g(a, b, [c]) {}
+}''');
+ _validateArgumentResolution(source, [0, 1, 2, -1]);
+ }
+
+ void test_argumentResolution_setter_propagated() {
+ Source source = addSource(r'''
+main() {
+ var a = new A();
+ a.sss = 0;
+}
+class A {
+ set sss(x) {}
+}''');
+ LibraryElement library = resolve2(source);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ // find "a.sss = 0"
+ AssignmentExpression assignment;
+ {
+ FunctionElement mainElement = unit.functions[0];
+ FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
+ Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
+ ExpressionStatement expressionStatement =
+ statement as ExpressionStatement;
+ assignment = expressionStatement.expression as AssignmentExpression;
+ }
+ // get parameter
+ Expression rhs = assignment.rightHandSide;
+ expect(rhs.staticParameterElement, isNull);
+ ParameterElement parameter = rhs.propagatedParameterElement;
+ expect(parameter, isNotNull);
+ expect(parameter.displayName, "x");
+ // validate
+ ClassElement classA = unit.types[0];
+ PropertyAccessorElement setter = classA.accessors[0];
+ expect(setter.parameters[0], same(parameter));
+ }
+
+ void test_argumentResolution_setter_propagated_propertyAccess() {
+ Source source = addSource(r'''
+main() {
+ var a = new A();
+ a.b.sss = 0;
+}
+class A {
+ B b = new B();
+}
+class B {
+ set sss(x) {}
+}''');
+ LibraryElement library = resolve2(source);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ // find "a.b.sss = 0"
+ AssignmentExpression assignment;
+ {
+ FunctionElement mainElement = unit.functions[0];
+ FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
+ Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
+ ExpressionStatement expressionStatement =
+ statement as ExpressionStatement;
+ assignment = expressionStatement.expression as AssignmentExpression;
+ }
+ // get parameter
+ Expression rhs = assignment.rightHandSide;
+ expect(rhs.staticParameterElement, isNull);
+ ParameterElement parameter = rhs.propagatedParameterElement;
+ expect(parameter, isNotNull);
+ expect(parameter.displayName, "x");
+ // validate
+ ClassElement classB = unit.types[1];
+ PropertyAccessorElement setter = classB.accessors[0];
+ expect(setter.parameters[0], same(parameter));
+ }
+
+ void test_argumentResolution_setter_static() {
+ Source source = addSource(r'''
+main() {
+ A a = new A();
+ a.sss = 0;
+}
+class A {
+ set sss(x) {}
+}''');
+ LibraryElement library = resolve2(source);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ // find "a.sss = 0"
+ AssignmentExpression assignment;
+ {
+ FunctionElement mainElement = unit.functions[0];
+ FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
+ Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
+ ExpressionStatement expressionStatement =
+ statement as ExpressionStatement;
+ assignment = expressionStatement.expression as AssignmentExpression;
+ }
+ // get parameter
+ Expression rhs = assignment.rightHandSide;
+ ParameterElement parameter = rhs.staticParameterElement;
+ expect(parameter, isNotNull);
+ expect(parameter.displayName, "x");
+ // validate
+ ClassElement classA = unit.types[0];
+ PropertyAccessorElement setter = classA.accessors[0];
+ expect(setter.parameters[0], same(parameter));
+ }
+
+ void test_argumentResolution_setter_static_propertyAccess() {
+ Source source = addSource(r'''
+main() {
+ A a = new A();
+ a.b.sss = 0;
+}
+class A {
+ B b = new B();
+}
+class B {
+ set sss(x) {}
+}''');
+ LibraryElement library = resolve2(source);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ // find "a.b.sss = 0"
+ AssignmentExpression assignment;
+ {
+ FunctionElement mainElement = unit.functions[0];
+ FunctionBody mainBody = mainElement.computeNode().functionExpression.body;
+ Statement statement = (mainBody as BlockFunctionBody).block.statements[1];
+ ExpressionStatement expressionStatement =
+ statement as ExpressionStatement;
+ assignment = expressionStatement.expression as AssignmentExpression;
+ }
+ // get parameter
+ Expression rhs = assignment.rightHandSide;
+ ParameterElement parameter = rhs.staticParameterElement;
+ expect(parameter, isNotNull);
+ expect(parameter.displayName, "x");
+ // validate
+ ClassElement classB = unit.types[1];
+ PropertyAccessorElement setter = classB.accessors[0];
+ expect(setter.parameters[0], same(parameter));
+ }
+
+ void test_breakTarget_labeled() {
+ // Verify that the target of the label is correctly found and is recorded
+ // as the unlabeled portion of the statement.
+ String text = r'''
+void f() {
+ loop1: while (true) {
+ loop2: for (int i = 0; i < 10; i++) {
+ break loop1;
+ break loop2;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ WhileStatement whileStatement = EngineTestCase.findNode(
+ unit, text, 'while (true)', (n) => n is WhileStatement);
+ ForStatement forStatement =
+ EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
+ BreakStatement break1 = EngineTestCase.findNode(
+ unit, text, 'break loop1', (n) => n is BreakStatement);
+ BreakStatement break2 = EngineTestCase.findNode(
+ unit, text, 'break loop2', (n) => n is BreakStatement);
+ expect(break1.target, same(whileStatement));
+ expect(break2.target, same(forStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakFromDo() {
+ String text = r'''
+void f() {
+ do {
+ break;
+ } while (true);
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ DoStatement doStatement =
+ EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
+ BreakStatement breakStatement = EngineTestCase.findNode(
+ unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, same(doStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakFromFor() {
+ String text = r'''
+void f() {
+ for (int i = 0; i < 10; i++) {
+ break;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ ForStatement forStatement =
+ EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
+ BreakStatement breakStatement = EngineTestCase.findNode(
+ unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, same(forStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakFromForEach() {
+ String text = r'''
+void f() {
+ for (x in []) {
+ break;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ ForEachStatement forStatement = EngineTestCase.findNode(
+ unit, text, 'for', (n) => n is ForEachStatement);
+ BreakStatement breakStatement = EngineTestCase.findNode(
+ unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, same(forStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakFromSwitch() {
+ String text = r'''
+void f() {
+ while (true) {
+ switch (0) {
+ case 0:
+ break;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ SwitchStatement switchStatement = EngineTestCase.findNode(
+ unit, text, 'switch', (n) => n is SwitchStatement);
+ BreakStatement breakStatement = EngineTestCase.findNode(
+ unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, same(switchStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakFromWhile() {
+ String text = r'''
+void f() {
+ while (true) {
+ break;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ WhileStatement whileStatement = EngineTestCase.findNode(
+ unit, text, 'while', (n) => n is WhileStatement);
+ BreakStatement breakStatement = EngineTestCase.findNode(
+ unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, same(whileStatement));
+ }
+
+ void test_breakTarget_unlabeledBreakToOuterFunction() {
+ // Verify that unlabeled break statements can't resolve to loops in an
+ // outer function.
+ String text = r'''
+void f() {
+ while (true) {
+ void g() {
+ break;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ BreakStatement breakStatement = EngineTestCase.findNode(
+ unit, text, 'break', (n) => n is BreakStatement);
+ expect(breakStatement.target, isNull);
+ }
+
+ void test_class_definesCall() {
+ Source source = addSource(r'''
+class A {
+ int call(int x) { return x; }
+}
+int f(A a) {
+ return a(0);
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_class_extends_implements() {
+ Source source = addSource(r'''
+class A extends B implements C {}
+class B {}
+class C {}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_commentReference_class() {
+ Source source = addSource(r'''
+f() {}
+/** [A] [new A] [A.n] [new A.n] [m] [f] */
+class A {
+ A() {}
+ A.n() {}
+ m() {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_commentReference_parameter() {
+ Source source = addSource(r'''
+class A {
+ A() {}
+ A.n() {}
+ /** [e] [f] */
+ m(e, f()) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_commentReference_singleLine() {
+ Source source = addSource(r'''
+/// [A]
+class A {}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_continueTarget_labeled() {
+ // Verify that the target of the label is correctly found and is recorded
+ // as the unlabeled portion of the statement.
+ String text = r'''
+void f() {
+ loop1: while (true) {
+ loop2: for (int i = 0; i < 10; i++) {
+ continue loop1;
+ continue loop2;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ WhileStatement whileStatement = EngineTestCase.findNode(
+ unit, text, 'while (true)', (n) => n is WhileStatement);
+ ForStatement forStatement =
+ EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
+ ContinueStatement continue1 = EngineTestCase.findNode(
+ unit, text, 'continue loop1', (n) => n is ContinueStatement);
+ ContinueStatement continue2 = EngineTestCase.findNode(
+ unit, text, 'continue loop2', (n) => n is ContinueStatement);
+ expect(continue1.target, same(whileStatement));
+ expect(continue2.target, same(forStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueFromDo() {
+ String text = r'''
+void f() {
+ do {
+ continue;
+ } while (true);
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ DoStatement doStatement =
+ EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
+ ContinueStatement continueStatement = EngineTestCase.findNode(
+ unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, same(doStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueFromFor() {
+ String text = r'''
+void f() {
+ for (int i = 0; i < 10; i++) {
+ continue;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ ForStatement forStatement =
+ EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
+ ContinueStatement continueStatement = EngineTestCase.findNode(
+ unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, same(forStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueFromForEach() {
+ String text = r'''
+void f() {
+ for (x in []) {
+ continue;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ ForEachStatement forStatement = EngineTestCase.findNode(
+ unit, text, 'for', (n) => n is ForEachStatement);
+ ContinueStatement continueStatement = EngineTestCase.findNode(
+ unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, same(forStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueFromWhile() {
+ String text = r'''
+void f() {
+ while (true) {
+ continue;
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ WhileStatement whileStatement = EngineTestCase.findNode(
+ unit, text, 'while', (n) => n is WhileStatement);
+ ContinueStatement continueStatement = EngineTestCase.findNode(
+ unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, same(whileStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueSkipsSwitch() {
+ String text = r'''
+void f() {
+ while (true) {
+ switch (0) {
+ case 0:
+ continue;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ WhileStatement whileStatement = EngineTestCase.findNode(
+ unit, text, 'while', (n) => n is WhileStatement);
+ ContinueStatement continueStatement = EngineTestCase.findNode(
+ unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, same(whileStatement));
+ }
+
+ void test_continueTarget_unlabeledContinueToOuterFunction() {
+ // Verify that unlabeled continue statements can't resolve to loops in an
+ // outer function.
+ String text = r'''
+void f() {
+ while (true) {
+ void g() {
+ continue;
+ }
+ }
+}
+''';
+ CompilationUnit unit = resolveSource(text);
+ ContinueStatement continueStatement = EngineTestCase.findNode(
+ unit, text, 'continue', (n) => n is ContinueStatement);
+ expect(continueStatement.target, isNull);
+ }
+
+ void test_empty() {
+ Source source = addSource("");
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_entryPoint_exported() {
+ addNamedSource(
+ "/two.dart",
+ r'''
+library two;
+main() {}''');
+ Source source = addNamedSource(
+ "/one.dart",
+ r'''
+library one;
+export 'two.dart';''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ FunctionElement main = library.entryPoint;
+ expect(main, isNotNull);
+ expect(main.library, isNot(same(library)));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_entryPoint_local() {
+ Source source = addNamedSource(
+ "/one.dart",
+ r'''
+library one;
+main() {}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ FunctionElement main = library.entryPoint;
+ expect(main, isNotNull);
+ expect(main.library, same(library));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_entryPoint_none() {
+ Source source = addNamedSource("/one.dart", "library one;");
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ expect(library.entryPoint, isNull);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_enum_externalLibrary() {
+ addNamedSource(
+ "/my_lib.dart",
+ r'''
+library my_lib;
+enum EEE {A, B, C}''');
+ Source source = addSource(r'''
+import 'my_lib.dart';
+main() {
+ EEE e = null;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_extractedMethodAsConstant() {
+ Source source = addSource(r'''
+abstract class Comparable<T> {
+ int compareTo(T other);
+ static int compare(Comparable a, Comparable b) => a.compareTo(b);
+}
+class A {
+ void sort([compare = Comparable.compare]) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_fieldFormalParameter() {
+ Source source = addSource(r'''
+class A {
+ int x;
+ A(this.x) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_forEachLoops_nonConflicting() {
+ Source source = addSource(r'''
+f() {
+ List list = [1,2,3];
+ for (int x in list) {}
+ for (int x in list) {}
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_forLoops_nonConflicting() {
+ Source source = addSource(r'''
+f() {
+ for (int i = 0; i < 3; i++) {
+ }
+ for (int i = 0; i < 3; i++) {
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_functionTypeAlias() {
+ Source source = addSource(r'''
+typedef bool P(e);
+class A {
+ P p;
+ m(e) {
+ if (p(e)) {}
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_getter_and_setter_fromMixins_bare_identifier() {
+ Source source = addSource('''
+class B {}
+class M1 {
+ get x => null;
+ set x(value) {}
+}
+class M2 {
+ get x => null;
+ set x(value) {}
+}
+class C extends B with M1, M2 {
+ void f() {
+ x += 1;
+ }
+}
+''');
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ // Verify that both the getter and setter for "x" in C.f() refer to the
+ // accessors defined in M2.
+ ClassElement classC = library.definingCompilationUnit.types[3];
+ MethodDeclaration f = classC.getMethod('f').computeNode();
+ BlockFunctionBody body = f.body;
+ ExpressionStatement stmt = body.block.statements[0];
+ AssignmentExpression assignment = stmt.expression;
+ SimpleIdentifier leftHandSide = assignment.leftHandSide;
+ expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
+ expect(leftHandSide.auxiliaryElements.staticElement.enclosingElement.name,
+ 'M2');
+ }
+
+ void test_getter_fromMixins_bare_identifier() {
+ Source source = addSource('''
+class B {}
+class M1 {
+ get x => null;
+}
+class M2 {
+ get x => null;
+}
+class C extends B with M1, M2 {
+ f() {
+ return x;
+ }
+}
+''');
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ // Verify that the getter for "x" in C.f() refers to the getter defined in
+ // M2.
+ ClassElement classC = library.definingCompilationUnit.types[3];
+ MethodDeclaration f = classC.getMethod('f').computeNode();
+ BlockFunctionBody body = f.body;
+ ReturnStatement stmt = body.block.statements[0];
+ SimpleIdentifier x = stmt.expression;
+ expect(x.staticElement.enclosingElement.name, 'M2');
+ }
+
+ void test_getter_fromMixins_property_access() {
+ Source source = addSource('''
+class B {}
+class M1 {
+ get x => null;
+}
+class M2 {
+ get x => null;
+}
+class C extends B with M1, M2 {}
+void main() {
+ var y = new C().x;
+}
+''');
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ // Verify that the getter for "x" in "new C().x" refers to the getter
+ // defined in M2.
+ FunctionDeclaration main =
+ library.definingCompilationUnit.functions[0].computeNode();
+ BlockFunctionBody body = main.functionExpression.body;
+ VariableDeclarationStatement stmt = body.block.statements[0];
+ PropertyAccess propertyAccess = stmt.variables.variables[0].initializer;
+ expect(
+ propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
+ }
+
+ void test_getterAndSetterWithDifferentTypes() {
+ Source source = addSource(r'''
+class A {
+ int get f => 0;
+ void set f(String s) {}
+}
+g (A a) {
+ a.f = a.f.toString();
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(
+ source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
+ verify([source]);
+ }
+
+ void test_hasReferenceToSuper() {
+ Source source = addSource(r'''
+class A {}
+class B {toString() => super.toString();}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ List<ClassElement> classes = unit.types;
+ expect(classes, hasLength(2));
+ expect(classes[0].hasReferenceToSuper, isFalse);
+ expect(classes[1].hasReferenceToSuper, isTrue);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_import_hide() {
+ addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+set foo(value) {}
+class A {}''');
+ addNamedSource(
+ "/lib2.dart",
+ r'''
+library lib2;
+set foo(value) {}''');
+ Source source = addNamedSource(
+ "/lib3.dart",
+ r'''
+import 'lib1.dart' hide foo;
+import 'lib2.dart';
+
+main() {
+ foo = 0;
+}
+A a;''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_import_prefix() {
+ addNamedSource(
+ "/two.dart",
+ r'''
+library two;
+f(int x) {
+ return x * x;
+}''');
+ Source source = addNamedSource(
+ "/one.dart",
+ r'''
+library one;
+import 'two.dart' as _two;
+main() {
+ _two.f(0);
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_import_spaceInUri() {
+ addNamedSource(
+ "/sub folder/lib.dart",
+ r'''
+library lib;
+foo() {}''');
+ Source source = addNamedSource(
+ "/app.dart",
+ r'''
+import 'sub folder/lib.dart';
+
+main() {
+ foo();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_indexExpression_typeParameters() {
+ Source source = addSource(r'''
+f() {
+ List<int> a;
+ a[0];
+ List<List<int>> b;
+ b[0][0];
+ List<List<List<int>>> c;
+ c[0][0][0];
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_indexExpression_typeParameters_invalidAssignmentWarning() {
+ Source source = addSource(r'''
+f() {
+ List<List<int>> b;
+ b[0][0] = 'hi';
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+ verify([source]);
+ }
+
+ void test_indirectOperatorThroughCall() {
+ Source source = addSource(r'''
+class A {
+ B call() { return new B(); }
+}
+
+class B {
+ int operator [](int i) { return i; }
+}
+
+A f = new A();
+
+g(int x) {}
+
+main() {
+ g(f()[0]);
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_invoke_dynamicThroughGetter() {
+ Source source = addSource(r'''
+class A {
+ List get X => [() => 0];
+ m(A a) {
+ X.last;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_isValidMixin_badSuperclass() {
+ Source source = addSource(r'''
+class A extends B {}
+class B {}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isFalse);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+ verify([source]);
+ }
+
+ void test_isValidMixin_badSuperclass_withSuperMixins() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class A extends B {}
+class B {}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isTrue);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_isValidMixin_constructor() {
+ Source source = addSource(r'''
+class A {
+ A() {}
+}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isFalse);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
+ verify([source]);
+ }
+
+ void test_isValidMixin_constructor_withSuperMixins() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class A {
+ A() {}
+}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isFalse);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
+ verify([source]);
+ }
+
+ void test_isValidMixin_factoryConstructor() {
+ Source source = addSource(r'''
+class A {
+ factory A() => null;
+}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isTrue);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_isValidMixin_factoryConstructor_withSuperMixins() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class A {
+ factory A() => null;
+}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isTrue);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_isValidMixin_super() {
+ Source source = addSource(r'''
+class A {
+ toString() {
+ return super.toString();
+ }
+}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isFalse);
+ assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
+ verify([source]);
+ }
+
+ void test_isValidMixin_super_withSuperMixins() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class A {
+ toString() {
+ return super.toString();
+ }
+}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isTrue);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_isValidMixin_valid() {
+ Source source = addSource('''
+class A {}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isTrue);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_isValidMixin_valid_withSuperMixins() {
+ resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource('''
+class A {}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isTrue);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_labels_switch() {
+ Source source = addSource(r'''
+void doSwitch(int target) {
+ switch (target) {
+ l0: case 0:
+ continue l1;
+ l1: case 1:
+ continue l0;
+ default:
+ continue l1;
+ }
+}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_localVariable_types_invoked() {
+ Source source = addSource(r'''
+const A = null;
+main() {
+ var myVar = (int p) => 'foo';
+ myVar(42);
+}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnit unit =
+ analysisContext.resolveCompilationUnit(source, library);
+ expect(unit, isNotNull);
+ List<bool> found = [false];
+ List<CaughtException> thrownException = new List<CaughtException>(1);
+ unit.accept(new _SimpleResolverTest_localVariable_types_invoked(
+ this, found, thrownException));
+ if (thrownException[0] != null) {
+ throw new AnalysisException(
+ "Exception", new CaughtException(thrownException[0], null));
+ }
+ expect(found[0], isTrue);
+ }
+
+ void test_metadata_class() {
+ Source source = addSource(r'''
+const A = null;
+@A class C<A> {}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unitElement = library.definingCompilationUnit;
+ expect(unitElement, isNotNull);
+ List<ClassElement> classes = unitElement.types;
+ expect(classes, hasLength(1));
+ List<ElementAnnotation> annotations = classes[0].metadata;
+ expect(annotations, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ CompilationUnit unit = resolveCompilationUnit(source, library);
+ NodeList<CompilationUnitMember> declarations = unit.declarations;
+ expect(declarations, hasLength(2));
+ Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
+ .variables
+ .variables[0]
+ .name
+ .staticElement;
+ EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
+ PropertyInducingElement, expectedElement);
+ expectedElement = (expectedElement as PropertyInducingElement).getter;
+ Element actualElement =
+ (declarations[1] as ClassDeclaration).metadata[0].name.staticElement;
+ expect(actualElement, same(expectedElement));
+ }
+
+ void test_metadata_field() {
+ Source source = addSource(r'''
+const A = null;
+class C {
+ @A int f;
+}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ List<ClassElement> classes = unit.types;
+ expect(classes, hasLength(1));
+ FieldElement field = classes[0].fields[0];
+ List<ElementAnnotation> annotations = field.metadata;
+ expect(annotations, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_metadata_fieldFormalParameter() {
+ Source source = addSource(r'''
+const A = null;
+class C {
+ int f;
+ C(@A this.f);
+}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ List<ClassElement> classes = unit.types;
+ expect(classes, hasLength(1));
+ List<ConstructorElement> constructors = classes[0].constructors;
+ expect(constructors, hasLength(1));
+ List<ParameterElement> parameters = constructors[0].parameters;
+ expect(parameters, hasLength(1));
+ List<ElementAnnotation> annotations = parameters[0].metadata;
+ expect(annotations, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_metadata_function() {
+ Source source = addSource(r'''
+const A = null;
+@A f() {}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ List<FunctionElement> functions = unit.functions;
+ expect(functions, hasLength(1));
+ List<ElementAnnotation> annotations = functions[0].metadata;
+ expect(annotations, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_metadata_functionTypedParameter() {
+ Source source = addSource(r'''
+const A = null;
+f(@A int p(int x)) {}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ List<FunctionElement> functions = unit.functions;
+ expect(functions, hasLength(1));
+ List<ParameterElement> parameters = functions[0].parameters;
+ expect(parameters, hasLength(1));
+ List<ElementAnnotation> annotations1 = parameters[0].metadata;
+ expect(annotations1, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_metadata_libraryDirective() {
+ Source source = addSource(r'''
+@A library lib;
+const A = null;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ List<ElementAnnotation> annotations = library.metadata;
+ expect(annotations, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_metadata_method() {
+ Source source = addSource(r'''
+const A = null;
+class C {
+ @A void m() {}
+}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ List<ClassElement> classes = unit.types;
+ expect(classes, hasLength(1));
+ MethodElement method = classes[0].methods[0];
+ List<ElementAnnotation> annotations = method.metadata;
+ expect(annotations, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_metadata_namedParameter() {
+ Source source = addSource(r'''
+const A = null;
+f({@A int p : 0}) {}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ List<FunctionElement> functions = unit.functions;
+ expect(functions, hasLength(1));
+ List<ParameterElement> parameters = functions[0].parameters;
+ expect(parameters, hasLength(1));
+ List<ElementAnnotation> annotations1 = parameters[0].metadata;
+ expect(annotations1, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_metadata_positionalParameter() {
+ Source source = addSource(r'''
+const A = null;
+f([@A int p = 0]) {}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ List<FunctionElement> functions = unit.functions;
+ expect(functions, hasLength(1));
+ List<ParameterElement> parameters = functions[0].parameters;
+ expect(parameters, hasLength(1));
+ List<ElementAnnotation> annotations1 = parameters[0].metadata;
+ expect(annotations1, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_metadata_simpleParameter() {
+ Source source = addSource(r'''
+const A = null;
+f(@A p1, @A int p2) {}''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ List<FunctionElement> functions = unit.functions;
+ expect(functions, hasLength(1));
+ List<ParameterElement> parameters = functions[0].parameters;
+ expect(parameters, hasLength(2));
+ List<ElementAnnotation> annotations1 = parameters[0].metadata;
+ expect(annotations1, hasLength(1));
+ List<ElementAnnotation> annotations2 = parameters[1].metadata;
+ expect(annotations2, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_metadata_typedef() {
+ Source source = addSource(r'''
+const A = null;
+@A typedef F<A>();''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unitElement = library.definingCompilationUnit;
+ expect(unitElement, isNotNull);
+ List<FunctionTypeAliasElement> aliases = unitElement.functionTypeAliases;
+ expect(aliases, hasLength(1));
+ List<ElementAnnotation> annotations = aliases[0].metadata;
+ expect(annotations, hasLength(1));
+ assertNoErrors(source);
+ verify([source]);
+ CompilationUnit unit = resolveCompilationUnit(source, library);
+ NodeList<CompilationUnitMember> declarations = unit.declarations;
+ expect(declarations, hasLength(2));
+ Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
+ .variables
+ .variables[0]
+ .name
+ .staticElement;
+ EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
+ PropertyInducingElement, expectedElement);
+ expectedElement = (expectedElement as PropertyInducingElement).getter;
+ Element actualElement =
+ (declarations[1] as FunctionTypeAlias).metadata[0].name.staticElement;
+ expect(actualElement, same(expectedElement));
+ }
+
+ void test_method_fromMixin() {
+ Source source = addSource(r'''
+class B {
+ bar() => 1;
+}
+class A {
+ foo() => 2;
+}
+
+class C extends B with A {
+ bar() => super.bar();
+ foo() => super.foo();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_method_fromMixins() {
+ Source source = addSource('''
+class B {}
+class M1 {
+ void f() {}
+}
+class M2 {
+ void f() {}
+}
+class C extends B with M1, M2 {}
+void main() {
+ new C().f();
+}
+''');
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ // Verify that the "f" in "new C().f()" refers to the "f" defined in M2.
+ FunctionDeclaration main =
+ library.definingCompilationUnit.functions[0].computeNode();
+ BlockFunctionBody body = main.functionExpression.body;
+ ExpressionStatement stmt = body.block.statements[0];
+ MethodInvocation expr = stmt.expression;
+ expect(expr.methodName.staticElement.enclosingElement.name, 'M2');
+ }
+
+ void test_method_fromMixins_bare_identifier() {
+ Source source = addSource('''
+class B {}
+class M1 {
+ void f() {}
+}
+class M2 {
+ void f() {}
+}
+class C extends B with M1, M2 {
+ void g() {
+ f();
+ }
+}
+''');
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ // Verify that the call to f() in C.g() refers to the method defined in M2.
+ ClassElement classC = library.definingCompilationUnit.types[3];
+ MethodDeclaration g = classC.getMethod('g').computeNode();
+ BlockFunctionBody body = g.body;
+ ExpressionStatement stmt = body.block.statements[0];
+ MethodInvocation invocation = stmt.expression;
+ SimpleIdentifier methodName = invocation.methodName;
+ expect(methodName.staticElement.enclosingElement.name, 'M2');
+ }
+
+ void test_method_fromMixins_invked_from_outside_class() {
+ Source source = addSource('''
+class B {}
+class M1 {
+ void f() {}
+}
+class M2 {
+ void f() {}
+}
+class C extends B with M1, M2 {}
+void main() {
+ new C().f();
+}
+''');
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ // Verify that the call to f() in "new C().f()" refers to the method
+ // defined in M2.
+ FunctionDeclaration main =
+ library.definingCompilationUnit.functions[0].computeNode();
+ BlockFunctionBody body = main.functionExpression.body;
+ ExpressionStatement stmt = body.block.statements[0];
+ MethodInvocation invocation = stmt.expression;
+ expect(invocation.methodName.staticElement.enclosingElement.name, 'M2');
+ }
+
+ void test_method_fromSuperclassMixin() {
+ Source source = addSource(r'''
+class A {
+ void m1() {}
+}
+class B extends Object with A {
+}
+class C extends B {
+}
+f(C c) {
+ c.m1();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_methodCascades() {
+ Source source = addSource(r'''
+class A {
+ void m1() {}
+ void m2() {}
+ void m() {
+ A a = new A();
+ a..m1()
+ ..m2();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_methodCascades_withSetter() {
+ Source source = addSource(r'''
+class A {
+ String name;
+ void m1() {}
+ void m2() {}
+ void m() {
+ A a = new A();
+ a..m1()
+ ..name = 'name'
+ ..m2();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ // failing with error code: INVOCATION_OF_NON_FUNCTION
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_resolveAgainstNull() {
+ Source source = addSource(r'''
+f(var p) {
+ return null == p;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ }
+
+ void test_setter_fromMixins_bare_identifier() {
+ Source source = addSource('''
+class B {}
+class M1 {
+ set x(value) {}
+}
+class M2 {
+ set x(value) {}
+}
+class C extends B with M1, M2 {
+ void f() {
+ x = 1;
+ }
+}
+''');
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ // Verify that the setter for "x" in C.f() refers to the setter defined in
+ // M2.
+ ClassElement classC = library.definingCompilationUnit.types[3];
+ MethodDeclaration f = classC.getMethod('f').computeNode();
+ BlockFunctionBody body = f.body;
+ ExpressionStatement stmt = body.block.statements[0];
+ AssignmentExpression assignment = stmt.expression;
+ SimpleIdentifier leftHandSide = assignment.leftHandSide;
+ expect(leftHandSide.staticElement.enclosingElement.name, 'M2');
+ }
+
+ void test_setter_fromMixins_property_access() {
+ Source source = addSource('''
+class B {}
+class M1 {
+ set x(value) {}
+}
+class M2 {
+ set x(value) {}
+}
+class C extends B with M1, M2 {}
+void main() {
+ new C().x = 1;
+}
+''');
+ LibraryElement library = resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ // Verify that the setter for "x" in "new C().x" refers to the setter
+ // defined in M2.
+ FunctionDeclaration main =
+ library.definingCompilationUnit.functions[0].computeNode();
+ BlockFunctionBody body = main.functionExpression.body;
+ ExpressionStatement stmt = body.block.statements[0];
+ AssignmentExpression assignment = stmt.expression;
+ PropertyAccess propertyAccess = assignment.leftHandSide;
+ expect(
+ propertyAccess.propertyName.staticElement.enclosingElement.name, 'M2');
+ }
+
+ void test_setter_inherited() {
+ Source source = addSource(r'''
+class A {
+ int get x => 0;
+ set x(int p) {}
+}
+class B extends A {
+ int get x => super.x == null ? 0 : super.x;
+ int f() => x = 1;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_setter_static() {
+ Source source = addSource(r'''
+set s(x) {
+}
+
+main() {
+ s = 123;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ /**
+ * Resolve the given source and verify that the arguments in a specific method invocation were
+ * correctly resolved.
+ *
+ * The source is expected to be source for a compilation unit, the first declaration is expected
+ * to be a class, the first member of which is expected to be a method with a block body, and the
+ * first statement in the body is expected to be an expression statement whose expression is a
+ * method invocation. It is the arguments to that method invocation that are tested. The method
+ * invocation can contain errors.
+ *
+ * The arguments were resolved correctly if the number of expressions in the list matches the
+ * length of the array of indices and if, for each index in the array of indices, the parameter to
+ * which the argument expression was resolved is the parameter in the invoked method's list of
+ * parameters at that index. Arguments that should not be resolved to a parameter because of an
+ * error can be denoted by including a negative index in the array of indices.
+ *
+ * @param source the source to be resolved
+ * @param indices the array of indices used to associate arguments with parameters
+ * @throws Exception if the source could not be resolved or if the structure of the source is not
+ * valid
+ */
+ void _validateArgumentResolution(Source source, List<int> indices) {
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ ClassElement classElement = library.definingCompilationUnit.types[0];
+ List<ParameterElement> parameters = classElement.methods[1].parameters;
+ CompilationUnit unit = resolveCompilationUnit(source, library);
+ expect(unit, isNotNull);
+ ClassDeclaration classDeclaration =
+ unit.declarations[0] as ClassDeclaration;
+ MethodDeclaration methodDeclaration =
+ classDeclaration.members[0] as MethodDeclaration;
+ Block block = (methodDeclaration.body as BlockFunctionBody).block;
+ ExpressionStatement statement = block.statements[0] as ExpressionStatement;
+ MethodInvocation invocation = statement.expression as MethodInvocation;
+ NodeList<Expression> arguments = invocation.argumentList.arguments;
+ int argumentCount = arguments.length;
+ expect(argumentCount, indices.length);
+ for (int i = 0; i < argumentCount; i++) {
+ Expression argument = arguments[i];
+ ParameterElement element = argument.staticParameterElement;
+ int index = indices[i];
+ if (index < 0) {
+ expect(element, isNull);
+ } else {
+ expect(element, same(parameters[index]));
+ }
+ }
+ }
+}
+
+class _SimpleResolverTest_localVariable_types_invoked
+ extends RecursiveAstVisitor<Object> {
+ final SimpleResolverTest test;
+
+ List<bool> found;
+
+ List<CaughtException> thrownException;
+
+ _SimpleResolverTest_localVariable_types_invoked(
+ this.test, this.found, this.thrownException)
+ : super();
+
+ @override
+ Object visitSimpleIdentifier(SimpleIdentifier node) {
+ if (node.name == "myVar" && node.parent is MethodInvocation) {
+ try {
+ found[0] = true;
+ // check static type
+ DartType staticType = node.staticType;
+ expect(staticType, same(test.typeProvider.dynamicType));
+ // check propagated type
+ FunctionType propagatedType = node.propagatedType as FunctionType;
+ expect(propagatedType.returnType, test.typeProvider.stringType);
+ } on AnalysisException catch (e, stackTrace) {
+ thrownException[0] = new CaughtException(e, stackTrace);
+ }
+ }
+ return null;
+ }
+}
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
new file mode 100644
index 0000000..6191020
--- /dev/null
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -0,0 +1,1619 @@
+// 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 analyzer.test.generated.static_type_analyzer_test;
+
+import 'dart:collection';
+
+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/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/static_type_analyzer.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'analysis_context_factory.dart';
+import 'resolver_test_case.dart';
+import 'test_support.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(StaticTypeAnalyzerTest);
+ runReflectiveTests(StaticTypeAnalyzer2Test);
+}
+
+@reflectiveTest
+class StaticTypeAnalyzerTest extends EngineTestCase {
+ /**
+ * The error listener to which errors will be reported.
+ */
+ GatheringErrorListener _listener;
+
+ /**
+ * The resolver visitor used to create the analyzer.
+ */
+ ResolverVisitor _visitor;
+
+ /**
+ * The analyzer being used to analyze the test cases.
+ */
+ StaticTypeAnalyzer _analyzer;
+
+ /**
+ * The type provider used to access the types.
+ */
+ TestTypeProvider _typeProvider;
+
+ /**
+ * The type system used to analyze the test cases.
+ */
+ TypeSystem get _typeSystem => _visitor.typeSystem;
+
+ void fail_visitFunctionExpressionInvocation() {
+ fail("Not yet tested");
+ _listener.assertNoErrors();
+ }
+
+ void fail_visitMethodInvocation() {
+ fail("Not yet tested");
+ _listener.assertNoErrors();
+ }
+
+ void fail_visitSimpleIdentifier() {
+ fail("Not yet tested");
+ _listener.assertNoErrors();
+ }
+
+ @override
+ void setUp() {
+ super.setUp();
+ _listener = new GatheringErrorListener();
+ _analyzer = _createAnalyzer();
+ }
+
+ void test_flatten_derived() {
+ // class Derived<T> extends Future<T> { ... }
+ ClassElementImpl derivedClass =
+ ElementFactory.classElement2('Derived', ['T']);
+ derivedClass.supertype = _typeProvider.futureType
+ .instantiate([derivedClass.typeParameters[0].type]);
+ InterfaceType intType = _typeProvider.intType;
+ DartType dynamicType = _typeProvider.dynamicType;
+ InterfaceType derivedIntType = derivedClass.type.instantiate([intType]);
+ // flatten(Derived) = dynamic
+ InterfaceType derivedDynamicType =
+ derivedClass.type.instantiate([dynamicType]);
+ expect(_flatten(derivedDynamicType), dynamicType);
+ // flatten(Derived<int>) = int
+ expect(_flatten(derivedIntType), intType);
+ // flatten(Derived<Derived>) = Derived
+ expect(_flatten(derivedClass.type.instantiate([derivedDynamicType])),
+ derivedDynamicType);
+ // flatten(Derived<Derived<int>>) = Derived<int>
+ expect(_flatten(derivedClass.type.instantiate([derivedIntType])),
+ derivedIntType);
+ }
+
+ void test_flatten_inhibit_recursion() {
+ // class A extends B
+ // class B extends A
+ ClassElementImpl classA = ElementFactory.classElement2('A', []);
+ ClassElementImpl classB = ElementFactory.classElement2('B', []);
+ classA.supertype = classB.type;
+ classB.supertype = classA.type;
+ // flatten(A) = A and flatten(B) = B, since neither class contains Future
+ // in its class hierarchy. Even though there is a loop in the class
+ // hierarchy, flatten() should terminate.
+ expect(_flatten(classA.type), classA.type);
+ expect(_flatten(classB.type), classB.type);
+ }
+
+ void test_flatten_related_derived_types() {
+ InterfaceType intType = _typeProvider.intType;
+ InterfaceType numType = _typeProvider.numType;
+ // class Derived<T> extends Future<T>
+ ClassElementImpl derivedClass =
+ ElementFactory.classElement2('Derived', ['T']);
+ derivedClass.supertype = _typeProvider.futureType
+ .instantiate([derivedClass.typeParameters[0].type]);
+ InterfaceType derivedType = derivedClass.type;
+ // class A extends Derived<int> implements Derived<num> { ... }
+ ClassElementImpl classA =
+ ElementFactory.classElement('A', derivedType.instantiate([intType]));
+ classA.interfaces = <InterfaceType>[
+ derivedType.instantiate([numType])
+ ];
+ // class B extends Future<num> implements Future<int> { ... }
+ ClassElementImpl classB =
+ ElementFactory.classElement('B', derivedType.instantiate([numType]));
+ classB.interfaces = <InterfaceType>[
+ derivedType.instantiate([intType])
+ ];
+ // flatten(A) = flatten(B) = int, since int is more specific than num.
+ // The code in flatten() that inhibits infinite recursion shouldn't be
+ // fooled by the fact that Derived appears twice in the type hierarchy.
+ expect(_flatten(classA.type), intType);
+ expect(_flatten(classB.type), intType);
+ }
+
+ void test_flatten_related_types() {
+ InterfaceType futureType = _typeProvider.futureType;
+ InterfaceType intType = _typeProvider.intType;
+ InterfaceType numType = _typeProvider.numType;
+ // class A extends Future<int> implements Future<num> { ... }
+ ClassElementImpl classA =
+ ElementFactory.classElement('A', futureType.instantiate([intType]));
+ classA.interfaces = <InterfaceType>[
+ futureType.instantiate([numType])
+ ];
+ // class B extends Future<num> implements Future<int> { ... }
+ ClassElementImpl classB =
+ ElementFactory.classElement('B', futureType.instantiate([numType]));
+ classB.interfaces = <InterfaceType>[
+ futureType.instantiate([intType])
+ ];
+ // flatten(A) = flatten(B) = int, since int is more specific than num.
+ expect(_flatten(classA.type), intType);
+ expect(_flatten(classB.type), intType);
+ }
+
+ void test_flatten_simple() {
+ InterfaceType intType = _typeProvider.intType;
+ DartType dynamicType = _typeProvider.dynamicType;
+ InterfaceType futureDynamicType = _typeProvider.futureDynamicType;
+ InterfaceType futureIntType =
+ _typeProvider.futureType.instantiate([intType]);
+ InterfaceType futureFutureDynamicType =
+ _typeProvider.futureType.instantiate([futureDynamicType]);
+ InterfaceType futureFutureIntType =
+ _typeProvider.futureType.instantiate([futureIntType]);
+ // flatten(int) = int
+ expect(_flatten(intType), intType);
+ // flatten(dynamic) = dynamic
+ expect(_flatten(dynamicType), dynamicType);
+ // flatten(Future) = dynamic
+ expect(_flatten(futureDynamicType), dynamicType);
+ // flatten(Future<int>) = int
+ expect(_flatten(futureIntType), intType);
+ // flatten(Future<Future>) = dynamic
+ expect(_flatten(futureFutureDynamicType), dynamicType);
+ // flatten(Future<Future<int>>) = int
+ expect(_flatten(futureFutureIntType), intType);
+ }
+
+ void test_flatten_unrelated_types() {
+ InterfaceType futureType = _typeProvider.futureType;
+ InterfaceType intType = _typeProvider.intType;
+ InterfaceType stringType = _typeProvider.stringType;
+ // class A extends Future<int> implements Future<String> { ... }
+ ClassElementImpl classA =
+ ElementFactory.classElement('A', futureType.instantiate([intType]));
+ classA.interfaces = <InterfaceType>[
+ futureType.instantiate([stringType])
+ ];
+ // class B extends Future<String> implements Future<int> { ... }
+ ClassElementImpl classB =
+ ElementFactory.classElement('B', futureType.instantiate([stringType]));
+ classB.interfaces = <InterfaceType>[
+ futureType.instantiate([intType])
+ ];
+ // flatten(A) = A and flatten(B) = B, since neither string nor int is more
+ // specific than the other.
+ expect(_flatten(classA.type), classA.type);
+ expect(_flatten(classB.type), classB.type);
+ }
+
+ void test_visitAdjacentStrings() {
+ // "a" "b"
+ Expression node = AstFactory
+ .adjacentStrings([_resolvedString("a"), _resolvedString("b")]);
+ expect(_analyze(node), same(_typeProvider.stringType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitAsExpression() {
+ // class A { ... this as B ... }
+ // class B extends A {}
+ ClassElement superclass = ElementFactory.classElement2("A");
+ InterfaceType superclassType = superclass.type;
+ ClassElement subclass = ElementFactory.classElement("B", superclassType);
+ Expression node = AstFactory.asExpression(
+ AstFactory.thisExpression(), AstFactory.typeName(subclass));
+ expect(_analyze3(node, superclassType), same(subclass.type));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitAssignmentExpression_compound() {
+ // i += 1
+ InterfaceType numType = _typeProvider.numType;
+ SimpleIdentifier identifier = _resolvedVariable(_typeProvider.intType, "i");
+ AssignmentExpression node = AstFactory.assignmentExpression(
+ identifier, TokenType.PLUS_EQ, _resolvedInteger(1));
+ MethodElement plusMethod = getMethod(numType, "+");
+ node.staticElement = plusMethod;
+ expect(_analyze(node), same(numType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitAssignmentExpression_compoundIfNull_differentTypes() {
+ // double d; d ??= 0
+ Expression node = AstFactory.assignmentExpression(
+ _resolvedVariable(_typeProvider.doubleType, 'd'),
+ TokenType.QUESTION_QUESTION_EQ,
+ _resolvedInteger(0));
+ expect(_analyze(node), same(_typeProvider.numType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitAssignmentExpression_compoundIfNull_sameTypes() {
+ // int i; i ??= 0
+ Expression node = AstFactory.assignmentExpression(
+ _resolvedVariable(_typeProvider.intType, 'i'),
+ TokenType.QUESTION_QUESTION_EQ,
+ _resolvedInteger(0));
+ expect(_analyze(node), same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitAssignmentExpression_simple() {
+ // i = 0
+ InterfaceType intType = _typeProvider.intType;
+ Expression node = AstFactory.assignmentExpression(
+ _resolvedVariable(intType, "i"), TokenType.EQ, _resolvedInteger(0));
+ expect(_analyze(node), same(intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitAwaitExpression_flattened() {
+ // await e, where e has type Future<Future<int>>
+ InterfaceType intType = _typeProvider.intType;
+ InterfaceType futureIntType =
+ _typeProvider.futureType.instantiate(<DartType>[intType]);
+ InterfaceType futureFutureIntType =
+ _typeProvider.futureType.instantiate(<DartType>[futureIntType]);
+ Expression node =
+ AstFactory.awaitExpression(_resolvedVariable(futureFutureIntType, 'e'));
+ expect(_analyze(node), same(intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitAwaitExpression_simple() {
+ // await e, where e has type Future<int>
+ InterfaceType intType = _typeProvider.intType;
+ InterfaceType futureIntType =
+ _typeProvider.futureType.instantiate(<DartType>[intType]);
+ Expression node =
+ AstFactory.awaitExpression(_resolvedVariable(futureIntType, 'e'));
+ expect(_analyze(node), same(intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_equals() {
+ // 2 == 3
+ Expression node = AstFactory.binaryExpression(
+ _resolvedInteger(2), TokenType.EQ_EQ, _resolvedInteger(3));
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_ifNull() {
+ // 1 ?? 1.5
+ Expression node = AstFactory.binaryExpression(
+ _resolvedInteger(1), TokenType.QUESTION_QUESTION, _resolvedDouble(1.5));
+ expect(_analyze(node), same(_typeProvider.numType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_logicalAnd() {
+ // false && true
+ Expression node = AstFactory.binaryExpression(
+ AstFactory.booleanLiteral(false),
+ TokenType.AMPERSAND_AMPERSAND,
+ AstFactory.booleanLiteral(true));
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_logicalOr() {
+ // false || true
+ Expression node = AstFactory.binaryExpression(
+ AstFactory.booleanLiteral(false),
+ TokenType.BAR_BAR,
+ AstFactory.booleanLiteral(true));
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_minusID_propagated() {
+ // a - b
+ BinaryExpression node = AstFactory.binaryExpression(
+ _propagatedVariable(_typeProvider.intType, 'a'),
+ TokenType.MINUS,
+ _propagatedVariable(_typeProvider.doubleType, 'b'));
+ node.propagatedElement = getMethod(_typeProvider.numType, "+");
+ _analyze(node);
+ expect(node.propagatedType, same(_typeProvider.doubleType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_notEquals() {
+ // 2 != 3
+ Expression node = AstFactory.binaryExpression(
+ _resolvedInteger(2), TokenType.BANG_EQ, _resolvedInteger(3));
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_plusID() {
+ // 1 + 2.0
+ BinaryExpression node = AstFactory.binaryExpression(
+ _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
+ node.staticElement = getMethod(_typeProvider.numType, "+");
+ expect(_analyze(node), same(_typeProvider.doubleType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_plusII() {
+ // 1 + 2
+ BinaryExpression node = AstFactory.binaryExpression(
+ _resolvedInteger(1), TokenType.PLUS, _resolvedInteger(2));
+ node.staticElement = getMethod(_typeProvider.numType, "+");
+ expect(_analyze(node), same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_plusII_propagated() {
+ // a + b
+ BinaryExpression node = AstFactory.binaryExpression(
+ _propagatedVariable(_typeProvider.intType, 'a'),
+ TokenType.PLUS,
+ _propagatedVariable(_typeProvider.intType, 'b'));
+ node.propagatedElement = getMethod(_typeProvider.numType, "+");
+ _analyze(node);
+ expect(node.propagatedType, same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_slash() {
+ // 2 / 2
+ BinaryExpression node = AstFactory.binaryExpression(
+ _resolvedInteger(2), TokenType.SLASH, _resolvedInteger(2));
+ node.staticElement = getMethod(_typeProvider.numType, "/");
+ expect(_analyze(node), same(_typeProvider.doubleType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_star_notSpecial() {
+ // class A {
+ // A operator *(double value);
+ // }
+ // (a as A) * 2.0
+ ClassElementImpl classA = ElementFactory.classElement2("A");
+ InterfaceType typeA = classA.type;
+ MethodElement operator =
+ ElementFactory.methodElement("*", typeA, [_typeProvider.doubleType]);
+ classA.methods = <MethodElement>[operator];
+ BinaryExpression node = AstFactory.binaryExpression(
+ AstFactory.asExpression(
+ AstFactory.identifier3("a"), AstFactory.typeName(classA)),
+ TokenType.PLUS,
+ _resolvedDouble(2.0));
+ node.staticElement = operator;
+ expect(_analyze(node), same(typeA));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBinaryExpression_starID() {
+ // 1 * 2.0
+ BinaryExpression node = AstFactory.binaryExpression(
+ _resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
+ node.staticElement = getMethod(_typeProvider.numType, "*");
+ expect(_analyze(node), same(_typeProvider.doubleType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBooleanLiteral_false() {
+ // false
+ Expression node = AstFactory.booleanLiteral(false);
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitBooleanLiteral_true() {
+ // true
+ Expression node = AstFactory.booleanLiteral(true);
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitCascadeExpression() {
+ // a..length
+ Expression node = AstFactory.cascadeExpression(
+ _resolvedString("a"), [AstFactory.propertyAccess2(null, "length")]);
+ expect(_analyze(node), same(_typeProvider.stringType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitConditionalExpression_differentTypes() {
+ // true ? 1.0 : 0
+ Expression node = AstFactory.conditionalExpression(
+ AstFactory.booleanLiteral(true),
+ _resolvedDouble(1.0),
+ _resolvedInteger(0));
+ expect(_analyze(node), same(_typeProvider.numType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitConditionalExpression_sameTypes() {
+ // true ? 1 : 0
+ Expression node = AstFactory.conditionalExpression(
+ AstFactory.booleanLiteral(true),
+ _resolvedInteger(1),
+ _resolvedInteger(0));
+ expect(_analyze(node), same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitDoubleLiteral() {
+ // 4.33
+ Expression node = AstFactory.doubleLiteral(4.33);
+ expect(_analyze(node), same(_typeProvider.doubleType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_async_block() {
+ // () async {}
+ BlockFunctionBody body = AstFactory.blockFunctionBody2();
+ body.keyword = TokenFactory.tokenFromString('async');
+ FunctionExpression node =
+ _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(
+ _typeProvider.futureDynamicType, null, null, null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_async_expression() {
+ // () async => e, where e has type int
+ InterfaceType intType = _typeProvider.intType;
+ InterfaceType futureIntType =
+ _typeProvider.futureType.instantiate(<DartType>[intType]);
+ Expression expression = _resolvedVariable(intType, 'e');
+ ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
+ body.keyword = TokenFactory.tokenFromString('async');
+ FunctionExpression node =
+ _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(futureIntType, null, null, null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_async_expression_flatten() {
+ // () async => e, where e has type Future<int>
+ InterfaceType intType = _typeProvider.intType;
+ InterfaceType futureIntType =
+ _typeProvider.futureType.instantiate(<DartType>[intType]);
+ Expression expression = _resolvedVariable(futureIntType, 'e');
+ ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
+ body.keyword = TokenFactory.tokenFromString('async');
+ FunctionExpression node =
+ _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(futureIntType, null, null, null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_async_expression_flatten_twice() {
+ // () async => e, where e has type Future<Future<int>>
+ InterfaceType intType = _typeProvider.intType;
+ InterfaceType futureIntType =
+ _typeProvider.futureType.instantiate(<DartType>[intType]);
+ InterfaceType futureFutureIntType =
+ _typeProvider.futureType.instantiate(<DartType>[futureIntType]);
+ Expression expression = _resolvedVariable(futureFutureIntType, 'e');
+ ExpressionFunctionBody body = AstFactory.expressionFunctionBody(expression);
+ body.keyword = TokenFactory.tokenFromString('async');
+ FunctionExpression node =
+ _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(futureIntType, null, null, null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_generator_async() {
+ // () async* {}
+ BlockFunctionBody body = AstFactory.blockFunctionBody2();
+ body.keyword = TokenFactory.tokenFromString('async');
+ body.star = TokenFactory.tokenFromType(TokenType.STAR);
+ FunctionExpression node =
+ _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(
+ _typeProvider.streamDynamicType, null, null, null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_generator_sync() {
+ // () sync* {}
+ BlockFunctionBody body = AstFactory.blockFunctionBody2();
+ body.keyword = TokenFactory.tokenFromString('sync');
+ body.star = TokenFactory.tokenFromType(TokenType.STAR);
+ FunctionExpression node =
+ _resolvedFunctionExpression(AstFactory.formalParameterList([]), body);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(
+ _typeProvider.iterableDynamicType, null, null, null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_named_block() {
+ // ({p1 : 0, p2 : 0}) {}
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p1 = AstFactory.namedFormalParameter(
+ AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
+ _setType(p1, dynamicType);
+ FormalParameter p2 = AstFactory.namedFormalParameter(
+ AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+ _setType(p2, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p1, p2]),
+ AstFactory.blockFunctionBody2());
+ _analyze5(p1);
+ _analyze5(p2);
+ DartType resultType = _analyze(node);
+ Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
+ expectedNamedTypes["p1"] = dynamicType;
+ expectedNamedTypes["p2"] = dynamicType;
+ _assertFunctionType(
+ dynamicType, null, null, expectedNamedTypes, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_named_expression() {
+ // ({p : 0}) -> 0;
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p = AstFactory.namedFormalParameter(
+ AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
+ _setType(p, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p]),
+ AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+ _analyze5(p);
+ DartType resultType = _analyze(node);
+ Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
+ expectedNamedTypes["p"] = dynamicType;
+ _assertFunctionType(
+ _typeProvider.intType, null, null, expectedNamedTypes, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_normal_block() {
+ // (p1, p2) {}
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+ _setType(p1, dynamicType);
+ FormalParameter p2 = AstFactory.simpleFormalParameter3("p2");
+ _setType(p2, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p1, p2]),
+ AstFactory.blockFunctionBody2());
+ _analyze5(p1);
+ _analyze5(p2);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(dynamicType, <DartType>[dynamicType, dynamicType], null,
+ null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_normal_expression() {
+ // (p1, p2) -> 0
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p = AstFactory.simpleFormalParameter3("p");
+ _setType(p, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p]),
+ AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+ _analyze5(p);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(
+ _typeProvider.intType, <DartType>[dynamicType], null, null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_normalAndNamed_block() {
+ // (p1, {p2 : 0}) {}
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+ _setType(p1, dynamicType);
+ FormalParameter p2 = AstFactory.namedFormalParameter(
+ AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+ _setType(p2, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p1, p2]),
+ AstFactory.blockFunctionBody2());
+ _analyze5(p2);
+ DartType resultType = _analyze(node);
+ Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
+ expectedNamedTypes["p2"] = dynamicType;
+ _assertFunctionType(dynamicType, <DartType>[dynamicType], null,
+ expectedNamedTypes, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_normalAndNamed_expression() {
+ // (p1, {p2 : 0}) -> 0
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+ _setType(p1, dynamicType);
+ FormalParameter p2 = AstFactory.namedFormalParameter(
+ AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+ _setType(p2, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p1, p2]),
+ AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+ _analyze5(p2);
+ DartType resultType = _analyze(node);
+ Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
+ expectedNamedTypes["p2"] = dynamicType;
+ _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], null,
+ expectedNamedTypes, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_normalAndPositional_block() {
+ // (p1, [p2 = 0]) {}
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+ _setType(p1, dynamicType);
+ FormalParameter p2 = AstFactory.positionalFormalParameter(
+ AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+ _setType(p2, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p1, p2]),
+ AstFactory.blockFunctionBody2());
+ _analyze5(p1);
+ _analyze5(p2);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(dynamicType, <DartType>[dynamicType],
+ <DartType>[dynamicType], null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_normalAndPositional_expression() {
+ // (p1, [p2 = 0]) -> 0
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p1 = AstFactory.simpleFormalParameter3("p1");
+ _setType(p1, dynamicType);
+ FormalParameter p2 = AstFactory.positionalFormalParameter(
+ AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+ _setType(p2, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p1, p2]),
+ AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+ _analyze5(p1);
+ _analyze5(p2);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType],
+ <DartType>[dynamicType], null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_positional_block() {
+ // ([p1 = 0, p2 = 0]) {}
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p1 = AstFactory.positionalFormalParameter(
+ AstFactory.simpleFormalParameter3("p1"), _resolvedInteger(0));
+ _setType(p1, dynamicType);
+ FormalParameter p2 = AstFactory.positionalFormalParameter(
+ AstFactory.simpleFormalParameter3("p2"), _resolvedInteger(0));
+ _setType(p2, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p1, p2]),
+ AstFactory.blockFunctionBody2());
+ _analyze5(p1);
+ _analyze5(p2);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(dynamicType, null, <DartType>[dynamicType, dynamicType],
+ null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitFunctionExpression_positional_expression() {
+ // ([p1 = 0, p2 = 0]) -> 0
+ DartType dynamicType = _typeProvider.dynamicType;
+ FormalParameter p = AstFactory.positionalFormalParameter(
+ AstFactory.simpleFormalParameter3("p"), _resolvedInteger(0));
+ _setType(p, dynamicType);
+ FunctionExpression node = _resolvedFunctionExpression(
+ AstFactory.formalParameterList([p]),
+ AstFactory.expressionFunctionBody(_resolvedInteger(0)));
+ _analyze5(p);
+ DartType resultType = _analyze(node);
+ _assertFunctionType(
+ _typeProvider.intType, null, <DartType>[dynamicType], null, resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitIndexExpression_getter() {
+ // List a;
+ // a[2]
+ InterfaceType listType = _typeProvider.listType;
+ SimpleIdentifier identifier = _resolvedVariable(listType, "a");
+ IndexExpression node =
+ AstFactory.indexExpression(identifier, _resolvedInteger(2));
+ MethodElement indexMethod = listType.element.methods[0];
+ node.staticElement = indexMethod;
+ expect(_analyze(node), same(listType.typeArguments[0]));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitIndexExpression_setter() {
+ // List a;
+ // a[2] = 0
+ InterfaceType listType = _typeProvider.listType;
+ SimpleIdentifier identifier = _resolvedVariable(listType, "a");
+ IndexExpression node =
+ AstFactory.indexExpression(identifier, _resolvedInteger(2));
+ MethodElement indexMethod = listType.element.methods[1];
+ node.staticElement = indexMethod;
+ AstFactory.assignmentExpression(node, TokenType.EQ, AstFactory.integer(0));
+ expect(_analyze(node), same(listType.typeArguments[0]));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitIndexExpression_typeParameters() {
+ // List<int> list = ...
+ // list[0]
+ InterfaceType intType = _typeProvider.intType;
+ InterfaceType listType = _typeProvider.listType;
+ // (int) -> E
+ MethodElement methodElement = getMethod(listType, "[]");
+ // "list" has type List<int>
+ SimpleIdentifier identifier = AstFactory.identifier3("list");
+ InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
+ identifier.staticType = listOfIntType;
+ // list[0] has MethodElement element (int) -> E
+ IndexExpression indexExpression =
+ AstFactory.indexExpression(identifier, AstFactory.integer(0));
+ MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
+ indexExpression.staticElement = indexMethod;
+ // analyze and assert result of the index expression
+ expect(_analyze(indexExpression), same(intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitIndexExpression_typeParameters_inSetterContext() {
+ // List<int> list = ...
+ // list[0] = 0;
+ InterfaceType intType = _typeProvider.intType;
+ InterfaceType listType = _typeProvider.listType;
+ // (int, E) -> void
+ MethodElement methodElement = getMethod(listType, "[]=");
+ // "list" has type List<int>
+ SimpleIdentifier identifier = AstFactory.identifier3("list");
+ InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
+ identifier.staticType = listOfIntType;
+ // list[0] has MethodElement element (int) -> E
+ IndexExpression indexExpression =
+ AstFactory.indexExpression(identifier, AstFactory.integer(0));
+ MethodElement indexMethod = MethodMember.from(methodElement, listOfIntType);
+ indexExpression.staticElement = indexMethod;
+ // list[0] should be in a setter context
+ AstFactory.assignmentExpression(
+ indexExpression, TokenType.EQ, AstFactory.integer(0));
+ // analyze and assert result of the index expression
+ expect(_analyze(indexExpression), same(intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitInstanceCreationExpression_named() {
+ // new C.m()
+ ClassElementImpl classElement = ElementFactory.classElement2("C");
+ String constructorName = "m";
+ ConstructorElementImpl constructor =
+ ElementFactory.constructorElement2(classElement, constructorName);
+ constructor.returnType = classElement.type;
+ FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
+ constructor.type = constructorType;
+ classElement.constructors = <ConstructorElement>[constructor];
+ InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
+ null,
+ AstFactory.typeName(classElement),
+ [AstFactory.identifier3(constructorName)]);
+ node.staticElement = constructor;
+ expect(_analyze(node), same(classElement.type));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitInstanceCreationExpression_typeParameters() {
+ // new C<I>()
+ ClassElementImpl elementC = ElementFactory.classElement2("C", ["E"]);
+ ClassElementImpl elementI = ElementFactory.classElement2("I");
+ ConstructorElementImpl constructor =
+ ElementFactory.constructorElement2(elementC, null);
+ elementC.constructors = <ConstructorElement>[constructor];
+ constructor.returnType = elementC.type;
+ FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
+ constructor.type = constructorType;
+ TypeName typeName =
+ AstFactory.typeName(elementC, [AstFactory.typeName(elementI)]);
+ typeName.type = elementC.type.instantiate(<DartType>[elementI.type]);
+ InstanceCreationExpression node =
+ AstFactory.instanceCreationExpression2(null, typeName);
+ node.staticElement = constructor;
+ InterfaceType interfaceType = _analyze(node) as InterfaceType;
+ List<DartType> typeArgs = interfaceType.typeArguments;
+ expect(typeArgs.length, 1);
+ expect(typeArgs[0], elementI.type);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitInstanceCreationExpression_unnamed() {
+ // new C()
+ ClassElementImpl classElement = ElementFactory.classElement2("C");
+ ConstructorElementImpl constructor =
+ ElementFactory.constructorElement2(classElement, null);
+ constructor.returnType = classElement.type;
+ FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
+ constructor.type = constructorType;
+ classElement.constructors = <ConstructorElement>[constructor];
+ InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
+ null, AstFactory.typeName(classElement));
+ node.staticElement = constructor;
+ expect(_analyze(node), same(classElement.type));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitIntegerLiteral() {
+ // 42
+ Expression node = _resolvedInteger(42);
+ expect(_analyze(node), same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitIsExpression_negated() {
+ // a is! String
+ Expression node = AstFactory.isExpression(
+ _resolvedString("a"), true, AstFactory.typeName4("String"));
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitIsExpression_notNegated() {
+ // a is String
+ Expression node = AstFactory.isExpression(
+ _resolvedString("a"), false, AstFactory.typeName4("String"));
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitListLiteral_empty() {
+ // []
+ Expression node = AstFactory.listLiteral();
+ DartType resultType = _analyze(node);
+ _assertType2(
+ _typeProvider.listType
+ .instantiate(<DartType>[_typeProvider.dynamicType]),
+ resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitListLiteral_nonEmpty() {
+ // [0]
+ Expression node = AstFactory.listLiteral([_resolvedInteger(0)]);
+ DartType resultType = _analyze(node);
+ _assertType2(
+ _typeProvider.listType
+ .instantiate(<DartType>[_typeProvider.dynamicType]),
+ resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitMapLiteral_empty() {
+ // {}
+ Expression node = AstFactory.mapLiteral2();
+ DartType resultType = _analyze(node);
+ _assertType2(
+ _typeProvider.mapType.instantiate(
+ <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
+ resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitMapLiteral_nonEmpty() {
+ // {"k" : 0}
+ Expression node = AstFactory
+ .mapLiteral2([AstFactory.mapLiteralEntry("k", _resolvedInteger(0))]);
+ DartType resultType = _analyze(node);
+ _assertType2(
+ _typeProvider.mapType.instantiate(
+ <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
+ resultType);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitMethodInvocation_then() {
+ // then()
+ Expression node = AstFactory.methodInvocation(null, "then");
+ _analyze(node);
+ _listener.assertNoErrors();
+ }
+
+ void test_visitNamedExpression() {
+ // n: a
+ Expression node = AstFactory.namedExpression2("n", _resolvedString("a"));
+ expect(_analyze(node), same(_typeProvider.stringType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitNullLiteral() {
+ // null
+ Expression node = AstFactory.nullLiteral();
+ expect(_analyze(node), same(_typeProvider.bottomType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitParenthesizedExpression() {
+ // (0)
+ Expression node = AstFactory.parenthesizedExpression(_resolvedInteger(0));
+ expect(_analyze(node), same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPostfixExpression_minusMinus() {
+ // 0--
+ PostfixExpression node = AstFactory.postfixExpression(
+ _resolvedInteger(0), TokenType.MINUS_MINUS);
+ expect(_analyze(node), same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPostfixExpression_plusPlus() {
+ // 0++
+ PostfixExpression node =
+ AstFactory.postfixExpression(_resolvedInteger(0), TokenType.PLUS_PLUS);
+ expect(_analyze(node), same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixedIdentifier_getter() {
+ DartType boolType = _typeProvider.boolType;
+ PropertyAccessorElementImpl getter =
+ ElementFactory.getterElement("b", false, boolType);
+ PrefixedIdentifier node = AstFactory.identifier5("a", "b");
+ node.identifier.staticElement = getter;
+ expect(_analyze(node), same(boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixedIdentifier_setter() {
+ DartType boolType = _typeProvider.boolType;
+ FieldElementImpl field =
+ ElementFactory.fieldElement("b", false, false, false, boolType);
+ PropertyAccessorElement setter = field.setter;
+ PrefixedIdentifier node = AstFactory.identifier5("a", "b");
+ node.identifier.staticElement = setter;
+ expect(_analyze(node), same(boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixedIdentifier_variable() {
+ VariableElementImpl variable = ElementFactory.localVariableElement2("b");
+ variable.type = _typeProvider.boolType;
+ PrefixedIdentifier node = AstFactory.identifier5("a", "b");
+ node.identifier.staticElement = variable;
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixExpression_bang() {
+ // !0
+ PrefixExpression node =
+ AstFactory.prefixExpression(TokenType.BANG, _resolvedInteger(0));
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixExpression_minus() {
+ // -0
+ PrefixExpression node =
+ AstFactory.prefixExpression(TokenType.MINUS, _resolvedInteger(0));
+ MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
+ node.staticElement = minusMethod;
+ expect(_analyze(node), same(_typeProvider.numType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixExpression_minusMinus() {
+ // --0
+ PrefixExpression node =
+ AstFactory.prefixExpression(TokenType.MINUS_MINUS, _resolvedInteger(0));
+ MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
+ node.staticElement = minusMethod;
+ expect(_analyze(node), same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixExpression_not() {
+ // !true
+ Expression node = AstFactory.prefixExpression(
+ TokenType.BANG, AstFactory.booleanLiteral(true));
+ expect(_analyze(node), same(_typeProvider.boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixExpression_plusPlus() {
+ // ++0
+ PrefixExpression node =
+ AstFactory.prefixExpression(TokenType.PLUS_PLUS, _resolvedInteger(0));
+ MethodElement plusMethod = getMethod(_typeProvider.numType, "+");
+ node.staticElement = plusMethod;
+ expect(_analyze(node), same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPrefixExpression_tilde() {
+ // ~0
+ PrefixExpression node =
+ AstFactory.prefixExpression(TokenType.TILDE, _resolvedInteger(0));
+ MethodElement tildeMethod = getMethod(_typeProvider.intType, "~");
+ node.staticElement = tildeMethod;
+ expect(_analyze(node), same(_typeProvider.intType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPropertyAccess_propagated_getter() {
+ DartType boolType = _typeProvider.boolType;
+ PropertyAccessorElementImpl getter =
+ ElementFactory.getterElement("b", false, boolType);
+ PropertyAccess node =
+ AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
+ node.propertyName.propagatedElement = getter;
+ expect(_analyze2(node, false), same(boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPropertyAccess_propagated_setter() {
+ DartType boolType = _typeProvider.boolType;
+ FieldElementImpl field =
+ ElementFactory.fieldElement("b", false, false, false, boolType);
+ PropertyAccessorElement setter = field.setter;
+ PropertyAccess node =
+ AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
+ node.propertyName.propagatedElement = setter;
+ expect(_analyze2(node, false), same(boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPropertyAccess_static_getter() {
+ DartType boolType = _typeProvider.boolType;
+ PropertyAccessorElementImpl getter =
+ ElementFactory.getterElement("b", false, boolType);
+ PropertyAccess node =
+ AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
+ node.propertyName.staticElement = getter;
+ expect(_analyze(node), same(boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitPropertyAccess_static_setter() {
+ DartType boolType = _typeProvider.boolType;
+ FieldElementImpl field =
+ ElementFactory.fieldElement("b", false, false, false, boolType);
+ PropertyAccessorElement setter = field.setter;
+ PropertyAccess node =
+ AstFactory.propertyAccess2(AstFactory.identifier3("a"), "b");
+ node.propertyName.staticElement = setter;
+ expect(_analyze(node), same(boolType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitSimpleIdentifier_dynamic() {
+ // "dynamic"
+ SimpleIdentifier identifier = AstFactory.identifier3('dynamic');
+ DynamicElementImpl element = DynamicElementImpl.instance;
+ identifier.staticElement = element;
+ identifier.staticType = _typeProvider.typeType;
+ expect(_analyze(identifier), same(_typeProvider.typeType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitSimpleStringLiteral() {
+ // "a"
+ Expression node = _resolvedString("a");
+ expect(_analyze(node), same(_typeProvider.stringType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitStringInterpolation() {
+ // "a${'b'}c"
+ Expression node = AstFactory.string([
+ AstFactory.interpolationString("a", "a"),
+ AstFactory.interpolationExpression(_resolvedString("b")),
+ AstFactory.interpolationString("c", "c")
+ ]);
+ expect(_analyze(node), same(_typeProvider.stringType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitSuperExpression() {
+ // super
+ InterfaceType superType = ElementFactory.classElement2("A").type;
+ InterfaceType thisType = ElementFactory.classElement("B", superType).type;
+ Expression node = AstFactory.superExpression();
+ expect(_analyze3(node, thisType), same(thisType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitSymbolLiteral() {
+ expect(_analyze(AstFactory.symbolLiteral(["a"])),
+ same(_typeProvider.symbolType));
+ }
+
+ void test_visitThisExpression() {
+ // this
+ InterfaceType thisType = ElementFactory
+ .classElement("B", ElementFactory.classElement2("A").type)
+ .type;
+ Expression node = AstFactory.thisExpression();
+ expect(_analyze3(node, thisType), same(thisType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitThrowExpression_withoutValue() {
+ // throw
+ Expression node = AstFactory.throwExpression();
+ expect(_analyze(node), same(_typeProvider.bottomType));
+ _listener.assertNoErrors();
+ }
+
+ void test_visitThrowExpression_withValue() {
+ // throw 0
+ Expression node = AstFactory.throwExpression2(_resolvedInteger(0));
+ expect(_analyze(node), same(_typeProvider.bottomType));
+ _listener.assertNoErrors();
+ }
+
+ /**
+ * Return the type associated with the given expression after the static type analyzer has
+ * computed a type for it.
+ *
+ * @param node the expression with which the type is associated
+ * @return the type associated with the expression
+ */
+ DartType _analyze(Expression node) => _analyze4(node, null, true);
+
+ /**
+ * Return the type associated with the given expression after the static or propagated type
+ * analyzer has computed a type for it.
+ *
+ * @param node the expression with which the type is associated
+ * @param useStaticType `true` if the static type is being requested, and `false` if
+ * the propagated type is being requested
+ * @return the type associated with the expression
+ */
+ DartType _analyze2(Expression node, bool useStaticType) =>
+ _analyze4(node, null, useStaticType);
+
+ /**
+ * Return the type associated with the given expression after the static type analyzer has
+ * computed a type for it.
+ *
+ * @param node the expression with which the type is associated
+ * @param thisType the type of 'this'
+ * @return the type associated with the expression
+ */
+ DartType _analyze3(Expression node, InterfaceType thisType) =>
+ _analyze4(node, thisType, true);
+
+ /**
+ * Return the type associated with the given expression after the static type analyzer has
+ * computed a type for it.
+ *
+ * @param node the expression with which the type is associated
+ * @param thisType the type of 'this'
+ * @param useStaticType `true` if the static type is being requested, and `false` if
+ * the propagated type is being requested
+ * @return the type associated with the expression
+ */
+ DartType _analyze4(
+ Expression node, InterfaceType thisType, bool useStaticType) {
+ try {
+ _analyzer.thisType = thisType;
+ } catch (exception) {
+ throw new IllegalArgumentException(
+ "Could not set type of 'this'", exception);
+ }
+ node.accept(_analyzer);
+ if (useStaticType) {
+ return node.staticType;
+ } else {
+ return node.propagatedType;
+ }
+ }
+
+ /**
+ * Return the type associated with the given parameter after the static type analyzer has computed
+ * a type for it.
+ *
+ * @param node the parameter with which the type is associated
+ * @return the type associated with the parameter
+ */
+ DartType _analyze5(FormalParameter node) {
+ node.accept(_analyzer);
+ return (node.identifier.staticElement as ParameterElement).type;
+ }
+
+ /**
+ * Assert that the actual type is a function type with the expected characteristics.
+ *
+ * @param expectedReturnType the expected return type of the function
+ * @param expectedNormalTypes the expected types of the normal parameters
+ * @param expectedOptionalTypes the expected types of the optional parameters
+ * @param expectedNamedTypes the expected types of the named parameters
+ * @param actualType the type being tested
+ */
+ void _assertFunctionType(
+ DartType expectedReturnType,
+ List<DartType> expectedNormalTypes,
+ List<DartType> expectedOptionalTypes,
+ Map<String, DartType> expectedNamedTypes,
+ DartType actualType) {
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is FunctionType, FunctionType, actualType);
+ FunctionType functionType = actualType as FunctionType;
+ List<DartType> normalTypes = functionType.normalParameterTypes;
+ if (expectedNormalTypes == null) {
+ expect(normalTypes, hasLength(0));
+ } else {
+ int expectedCount = expectedNormalTypes.length;
+ expect(normalTypes, hasLength(expectedCount));
+ for (int i = 0; i < expectedCount; i++) {
+ expect(normalTypes[i], same(expectedNormalTypes[i]));
+ }
+ }
+ List<DartType> optionalTypes = functionType.optionalParameterTypes;
+ if (expectedOptionalTypes == null) {
+ expect(optionalTypes, hasLength(0));
+ } else {
+ int expectedCount = expectedOptionalTypes.length;
+ expect(optionalTypes, hasLength(expectedCount));
+ for (int i = 0; i < expectedCount; i++) {
+ expect(optionalTypes[i], same(expectedOptionalTypes[i]));
+ }
+ }
+ Map<String, DartType> namedTypes = functionType.namedParameterTypes;
+ if (expectedNamedTypes == null) {
+ expect(namedTypes, hasLength(0));
+ } else {
+ expect(namedTypes, hasLength(expectedNamedTypes.length));
+ expectedNamedTypes.forEach((String name, DartType type) {
+ expect(namedTypes[name], same(type));
+ });
+ }
+ expect(functionType.returnType, equals(expectedReturnType));
+ }
+
+ void _assertType(
+ InterfaceTypeImpl expectedType, InterfaceTypeImpl actualType) {
+ expect(actualType.displayName, expectedType.displayName);
+ expect(actualType.element, expectedType.element);
+ List<DartType> expectedArguments = expectedType.typeArguments;
+ int length = expectedArguments.length;
+ List<DartType> actualArguments = actualType.typeArguments;
+ expect(actualArguments, hasLength(length));
+ for (int i = 0; i < length; i++) {
+ _assertType2(expectedArguments[i], actualArguments[i]);
+ }
+ }
+
+ void _assertType2(DartType expectedType, DartType actualType) {
+ if (expectedType is InterfaceTypeImpl) {
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is InterfaceTypeImpl, InterfaceTypeImpl, actualType);
+ _assertType(expectedType, actualType as InterfaceTypeImpl);
+ }
+ // TODO(brianwilkerson) Compare other kinds of types then make this a shared
+ // utility method.
+ }
+
+ /**
+ * Create the analyzer used by the tests.
+ *
+ * @return the analyzer to be used by the tests
+ */
+ StaticTypeAnalyzer _createAnalyzer() {
+ InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
+ FileBasedSource source =
+ new FileBasedSource(FileUtilities2.createFile("/lib.dart"));
+ CompilationUnitElementImpl definingCompilationUnit =
+ new CompilationUnitElementImpl("lib.dart");
+ definingCompilationUnit.librarySource =
+ definingCompilationUnit.source = source;
+ LibraryElementImpl definingLibrary =
+ new LibraryElementImpl.forNode(context, null);
+ definingLibrary.definingCompilationUnit = definingCompilationUnit;
+ _typeProvider = new TestTypeProvider(context);
+ _visitor = new ResolverVisitor(
+ definingLibrary, source, _typeProvider, _listener,
+ nameScope: new LibraryScope(definingLibrary, _listener));
+ _visitor.overrideManager.enterScope();
+ try {
+ return _visitor.typeAnalyzer;
+ } catch (exception) {
+ throw new IllegalArgumentException(
+ "Could not create analyzer", exception);
+ }
+ }
+
+ DartType _flatten(DartType type) => type.flattenFutures(_typeSystem);
+
+ /**
+ * Return a simple identifier that has been resolved to a variable element with the given type.
+ *
+ * @param type the type of the variable being represented
+ * @param variableName the name of the variable
+ * @return a simple identifier that has been resolved to a variable element with the given type
+ */
+ SimpleIdentifier _propagatedVariable(
+ InterfaceType type, String variableName) {
+ SimpleIdentifier identifier = AstFactory.identifier3(variableName);
+ VariableElementImpl element =
+ ElementFactory.localVariableElement(identifier);
+ element.type = type;
+ identifier.staticType = _typeProvider.dynamicType;
+ identifier.propagatedElement = element;
+ identifier.propagatedType = type;
+ return identifier;
+ }
+
+ /**
+ * Return an integer literal that has been resolved to the correct type.
+ *
+ * @param value the value of the literal
+ * @return an integer literal that has been resolved to the correct type
+ */
+ DoubleLiteral _resolvedDouble(double value) {
+ DoubleLiteral literal = AstFactory.doubleLiteral(value);
+ literal.staticType = _typeProvider.doubleType;
+ return literal;
+ }
+
+ /**
+ * Create a function expression that has an element associated with it, where the element has an
+ * incomplete type associated with it (just like the one
+ * [ElementBuilder.visitFunctionExpression] would have built if we had
+ * run it).
+ *
+ * @param parameters the parameters to the function
+ * @param body the body of the function
+ * @return a resolved function expression
+ */
+ FunctionExpression _resolvedFunctionExpression(
+ FormalParameterList parameters, FunctionBody body) {
+ List<ParameterElement> parameterElements = new List<ParameterElement>();
+ for (FormalParameter parameter in parameters.parameters) {
+ ParameterElementImpl element =
+ new ParameterElementImpl.forNode(parameter.identifier);
+ element.parameterKind = parameter.kind;
+ element.type = _typeProvider.dynamicType;
+ parameter.identifier.staticElement = element;
+ parameterElements.add(element);
+ }
+ FunctionExpression node = AstFactory.functionExpression2(parameters, body);
+ FunctionElementImpl element = new FunctionElementImpl.forNode(null);
+ element.parameters = parameterElements;
+ element.type = new FunctionTypeImpl(element);
+ node.element = element;
+ return node;
+ }
+
+ /**
+ * Return an integer literal that has been resolved to the correct type.
+ *
+ * @param value the value of the literal
+ * @return an integer literal that has been resolved to the correct type
+ */
+ IntegerLiteral _resolvedInteger(int value) {
+ IntegerLiteral literal = AstFactory.integer(value);
+ literal.staticType = _typeProvider.intType;
+ return literal;
+ }
+
+ /**
+ * Return a string literal that has been resolved to the correct type.
+ *
+ * @param value the value of the literal
+ * @return a string literal that has been resolved to the correct type
+ */
+ SimpleStringLiteral _resolvedString(String value) {
+ SimpleStringLiteral string = AstFactory.string2(value);
+ string.staticType = _typeProvider.stringType;
+ return string;
+ }
+
+ /**
+ * Return a simple identifier that has been resolved to a variable element with the given type.
+ *
+ * @param type the type of the variable being represented
+ * @param variableName the name of the variable
+ * @return a simple identifier that has been resolved to a variable element with the given type
+ */
+ SimpleIdentifier _resolvedVariable(InterfaceType type, String variableName) {
+ SimpleIdentifier identifier = AstFactory.identifier3(variableName);
+ VariableElementImpl element =
+ ElementFactory.localVariableElement(identifier);
+ element.type = type;
+ identifier.staticElement = element;
+ identifier.staticType = type;
+ return identifier;
+ }
+
+ /**
+ * Set the type of the given parameter to the given type.
+ *
+ * @param parameter the parameter whose type is to be set
+ * @param type the new type of the given parameter
+ */
+ void _setType(FormalParameter parameter, DartType type) {
+ SimpleIdentifier identifier = parameter.identifier;
+ Element element = identifier.staticElement;
+ if (element is! ParameterElement) {
+ element = new ParameterElementImpl.forNode(identifier);
+ identifier.staticElement = element;
+ }
+ (element as ParameterElementImpl).type = type;
+ }
+}
+
+/**
+ * Like [StaticTypeAnalyzerTest], but as end-to-end tests.
+ */
+@reflectiveTest
+class StaticTypeAnalyzer2Test extends StaticTypeAnalyzer2TestShared {
+ void test_FunctionExpressionInvocation_block() {
+ String code = r'''
+main() {
+ var foo = (() { return 1; })();
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'dynamic', isNull);
+ }
+
+ void test_FunctionExpressionInvocation_curried() {
+ String code = r'''
+typedef int F();
+F f() => null;
+main() {
+ var foo = f()();
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'int', isNull);
+ }
+
+ void test_FunctionExpressionInvocation_expression() {
+ String code = r'''
+main() {
+ var foo = (() => 1)();
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'int', isNull);
+ }
+
+ void test_MethodInvocation_nameType_localVariable() {
+ String code = r"""
+typedef Foo();
+main() {
+ Foo foo;
+ foo();
+}
+""";
+ resolveTestUnit(code);
+ // "foo" should be resolved to the "Foo" type
+ expectIdentifierType("foo();", new isInstanceOf<FunctionType>());
+ }
+
+ void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() {
+ String code = r"""
+typedef Foo();
+main(Foo foo) {
+ foo();
+}
+""";
+ resolveTestUnit(code);
+ // "foo" should be resolved to the "Foo" type
+ expectIdentifierType("foo();", new isInstanceOf<FunctionType>());
+ }
+
+ void test_MethodInvocation_nameType_parameter_propagatedType() {
+ String code = r"""
+typedef Foo();
+main(p) {
+ if (p is Foo) {
+ p();
+ }
+}
+""";
+ resolveTestUnit(code);
+ expectIdentifierType("p()", DynamicTypeImpl.instance,
+ predicate((type) => type.name == 'Foo'));
+ }
+
+ void test_staticMethods_classTypeParameters() {
+ String code = r'''
+class C<T> {
+ static void m() => null;
+}
+main() {
+ print(C.m);
+}
+''';
+ resolveTestUnit(code);
+ expectFunctionType('m);', '() → void');
+ }
+
+ void test_staticMethods_classTypeParameters_genericMethod() {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableGenericMethods = true;
+ resetWithOptions(options);
+ String code = r'''
+class C<T> {
+ static void m<S>(S s) {
+ void f<U>(S s, U u) {}
+ print(f);
+ }
+}
+main() {
+ print(C.m);
+}
+''';
+ resolveTestUnit(code);
+ // C - m
+ TypeParameterType typeS;
+ {
+ expectFunctionType('m);', '<S>(S) → void',
+ elementTypeParams: '[S]', typeFormals: '[S]');
+
+ FunctionTypeImpl type = findIdentifier('m);').staticType;
+ typeS = type.typeFormals[0].type;
+ type = type.instantiate([DynamicTypeImpl.instance]);
+ expect(type.toString(), '(dynamic) → void');
+ expect(type.typeParameters.toString(), '[S]');
+ expect(type.typeArguments, [DynamicTypeImpl.instance]);
+ expect(type.typeFormals, isEmpty);
+ }
+ // C - m - f
+ {
+ expectFunctionType('f);', '<U>(S, U) → void',
+ elementTypeParams: '[U]',
+ typeParams: '[S]',
+ typeArgs: '[S]',
+ typeFormals: '[U]');
+
+ FunctionTypeImpl type = findIdentifier('f);').staticType;
+ type = type.instantiate([DynamicTypeImpl.instance]);
+ expect(type.toString(), '(S, dynamic) → void');
+ expect(type.typeParameters.toString(), '[S, U]');
+ expect(type.typeArguments, [typeS, DynamicTypeImpl.instance]);
+ expect(type.typeFormals, isEmpty);
+ }
+ }
+}
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 0f4f64a..ac762c4b 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -12,7 +12,7 @@
import '../reflective_tests.dart';
import '../utils.dart';
-import 'resolver_test.dart';
+import 'resolver_test_case.dart';
main() {
initializeTestEnvironment();
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index 02c44b8..7e8e4f3 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -10,7 +10,7 @@
import '../reflective_tests.dart';
import '../utils.dart';
-import 'resolver_test.dart';
+import 'resolver_test_case.dart';
main() {
initializeTestEnvironment();
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
new file mode 100644
index 0000000..115d966
--- /dev/null
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -0,0 +1,2280 @@
+// 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 analyzer.test.generated.strong_mode_test;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'resolver_test_case.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(StrongModeDownwardsInferenceTest);
+ runReflectiveTests(StrongModeStaticTypeAnalyzer2Test);
+ runReflectiveTests(StrongModeTypePropagationTest);
+}
+
+/**
+ * Strong mode static analyzer downwards inference tests
+ */
+@reflectiveTest
+class StrongModeDownwardsInferenceTest extends ResolverTestCase {
+ TypeAssertions _assertions;
+
+ Asserter<DartType> _isDynamic;
+ Asserter<InterfaceType> _isFutureOfDynamic;
+ Asserter<InterfaceType> _isFutureOfInt;
+ Asserter<DartType> _isInt;
+ Asserter<DartType> _isNum;
+ Asserter<DartType> _isString;
+
+ AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
+ _isFunction2Of;
+ AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf;
+ AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
+ _isInstantiationOf;
+ AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
+ AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType>
+ _isMapOf;
+ AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isStreamOf;
+ AsserterBuilder<DartType, DartType> _isType;
+
+ AsserterBuilder<Element, DartType> _hasElement;
+ AsserterBuilder<DartType, DartType> _sameElement;
+
+ @override
+ void setUp() {
+ super.setUp();
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.strongMode = true;
+ resetWithOptions(options);
+ _assertions = new TypeAssertions(typeProvider);
+ _isType = _assertions.isType;
+ _hasElement = _assertions.hasElement;
+ _isInstantiationOf = _assertions.isInstantiationOf;
+ _isInt = _assertions.isInt;
+ _isNum = _assertions.isNum;
+ _isString = _assertions.isString;
+ _isDynamic = _assertions.isDynamic;
+ _isListOf = _assertions.isListOf;
+ _isMapOf = _assertions.isMapOf;
+ _isFunction2Of = _assertions.isFunction2Of;
+ _sameElement = _assertions.sameElement;
+ _isFutureOf = _isInstantiationOf(_sameElement(typeProvider.futureType));
+ _isFutureOfDynamic = _isFutureOf([_isDynamic]);
+ _isFutureOfInt = _isFutureOf([_isInt]);
+ _isStreamOf = _isInstantiationOf(_sameElement(typeProvider.streamType));
+ }
+
+ void test_async_method_propagation() {
+ String code = r'''
+ import "dart:async";
+ class A {
+ Future f0() => new Future.value(3);
+ Future f1() async => new Future.value(3);
+ Future f2() async => await new Future.value(3);
+
+ Future<int> f3() => new Future.value(3);
+ Future<int> f4() async => new Future.value(3);
+ Future<int> f5() async => await new Future.value(3);
+
+ Future g0() { return new Future.value(3); }
+ Future g1() async { return new Future.value(3); }
+ Future g2() async { return await new Future.value(3); }
+
+ Future<int> g3() { return new Future.value(3); }
+ Future<int> g4() async { return new Future.value(3); }
+ Future<int> g5() async { return await new Future.value(3); }
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ void check(String name, Asserter<InterfaceType> typeTest) {
+ MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
+ FunctionBody body = test.body;
+ Expression returnExp;
+ if (body is ExpressionFunctionBody) {
+ returnExp = body.expression;
+ } else {
+ ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
+ returnExp = stmt.expression;
+ }
+ DartType type = returnExp.staticType;
+ if (returnExp is AwaitExpression) {
+ type = returnExp.expression.staticType;
+ }
+ typeTest(type);
+ }
+
+ check("f0", _isFutureOfDynamic);
+ check("f1", _isFutureOfDynamic);
+ check("f2", _isFutureOfDynamic);
+
+ check("f3", _isFutureOfInt);
+ // This should be int when we handle the implicit Future<T> | T union
+ // https://github.com/dart-lang/sdk/issues/25322
+ check("f4", _isFutureOfDynamic);
+ check("f5", _isFutureOfInt);
+
+ check("g0", _isFutureOfDynamic);
+ check("g1", _isFutureOfDynamic);
+ check("g2", _isFutureOfDynamic);
+
+ check("g3", _isFutureOfInt);
+ // This should be int when we handle the implicit Future<T> | T union
+ // https://github.com/dart-lang/sdk/issues/25322
+ check("g4", _isFutureOfDynamic);
+ check("g5", _isFutureOfInt);
+ }
+
+ void test_async_propagation() {
+ String code = r'''
+ import "dart:async";
+
+ Future f0() => new Future.value(3);
+ Future f1() async => new Future.value(3);
+ Future f2() async => await new Future.value(3);
+
+ Future<int> f3() => new Future.value(3);
+ Future<int> f4() async => new Future.value(3);
+ Future<int> f5() async => await new Future.value(3);
+
+ Future g0() { return new Future.value(3); }
+ Future g1() async { return new Future.value(3); }
+ Future g2() async { return await new Future.value(3); }
+
+ Future<int> g3() { return new Future.value(3); }
+ Future<int> g4() async { return new Future.value(3); }
+ Future<int> g5() async { return await new Future.value(3); }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ void check(String name, Asserter<InterfaceType> typeTest) {
+ FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
+ FunctionBody body = test.functionExpression.body;
+ Expression returnExp;
+ if (body is ExpressionFunctionBody) {
+ returnExp = body.expression;
+ } else {
+ ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
+ returnExp = stmt.expression;
+ }
+ DartType type = returnExp.staticType;
+ if (returnExp is AwaitExpression) {
+ type = returnExp.expression.staticType;
+ }
+ typeTest(type);
+ }
+
+ check("f0", _isFutureOfDynamic);
+ check("f1", _isFutureOfDynamic);
+ check("f2", _isFutureOfDynamic);
+
+ check("f3", _isFutureOfInt);
+ // This should be int when we handle the implicit Future<T> | T union
+ // https://github.com/dart-lang/sdk/issues/25322
+ check("f4", _isFutureOfDynamic);
+ check("f5", _isFutureOfInt);
+
+ check("g0", _isFutureOfDynamic);
+ check("g1", _isFutureOfDynamic);
+ check("g2", _isFutureOfDynamic);
+
+ check("g3", _isFutureOfInt);
+ // This should be int when we handle the implicit Future<T> | T union
+ // https://github.com/dart-lang/sdk/issues/25322
+ check("g4", _isFutureOfDynamic);
+ check("g5", _isFutureOfInt);
+ }
+
+ void test_async_star_method_propagation() {
+ String code = r'''
+ import "dart:async";
+ class A {
+ Stream g0() async* { yield []; }
+ Stream g1() async* { yield* new Stream(); }
+
+ Stream<List<int>> g2() async* { yield []; }
+ Stream<List<int>> g3() async* { yield* new Stream(); }
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ void check(String name, Asserter<InterfaceType> typeTest) {
+ MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
+ BlockFunctionBody body = test.body;
+ YieldStatement stmt = body.block.statements[0];
+ Expression exp = stmt.expression;
+ typeTest(exp.staticType);
+ }
+
+ check("g0", _isListOf(_isDynamic));
+ check("g1", _isStreamOf([_isDynamic]));
+
+ check("g2", _isListOf(_isInt));
+ check("g3", _isStreamOf([_isListOf(_isInt)]));
+ }
+
+ void test_async_star_propagation() {
+ String code = r'''
+ import "dart:async";
+
+ Stream g0() async* { yield []; }
+ Stream g1() async* { yield* new Stream(); }
+
+ Stream<List<int>> g2() async* { yield []; }
+ Stream<List<int>> g3() async* { yield* new Stream(); }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ void check(String name, Asserter<InterfaceType> typeTest) {
+ FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
+ BlockFunctionBody body = test.functionExpression.body;
+ YieldStatement stmt = body.block.statements[0];
+ Expression exp = stmt.expression;
+ typeTest(exp.staticType);
+ }
+
+ check("g0", _isListOf(_isDynamic));
+ check("g1", _isStreamOf([_isDynamic]));
+
+ check("g2", _isListOf(_isInt));
+ check("g3", _isStreamOf([_isListOf(_isInt)]));
+ }
+
+ void test_cascadeExpression() {
+ String code = r'''
+ class A<T> {
+ List<T> map(T a, List<T> mapper(T x)) => mapper(a);
+ }
+
+ void main () {
+ A<int> a = new A()..map(0, (x) => [x]);
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ CascadeExpression fetch(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ CascadeExpression exp = decl.initializer;
+ return exp;
+ }
+ Element elementA = AstFinder.getClass(unit, "A").element;
+
+ CascadeExpression cascade = fetch(0);
+ _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType);
+ MethodInvocation invoke = cascade.cascadeSections[0];
+ FunctionExpression function = invoke.argumentList.arguments[1];
+ ExecutableElement f0 = function.element;
+ _isListOf(_isInt)(f0.type.returnType);
+ expect(f0.type.normalParameterTypes[0], typeProvider.intType);
+ }
+
+ void test_constructorInitializer_propagation() {
+ String code = r'''
+ class A {
+ List<String> x;
+ A() : this.x = [];
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ ConstructorDeclaration constructor =
+ AstFinder.getConstructorInClass(unit, "A", null);
+ ConstructorFieldInitializer assignment = constructor.initializers[0];
+ Expression exp = assignment.expression;
+ _isListOf(_isString)(exp.staticType);
+ }
+
+ void test_factoryConstructor_propagation() {
+ String code = r'''
+ class A<T> {
+ factory A() { return new B(); }
+ }
+ class B<S> extends A<S> {}
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ ConstructorDeclaration constructor =
+ AstFinder.getConstructorInClass(unit, "A", null);
+ BlockFunctionBody body = constructor.body;
+ ReturnStatement stmt = body.block.statements[0];
+ InstanceCreationExpression exp = stmt.expression;
+ ClassElement elementB = AstFinder.getClass(unit, "B").element;
+ ClassElement elementA = AstFinder.getClass(unit, "A").element;
+ expect(exp.constructorName.type.type.element, elementB);
+ _isInstantiationOf(_hasElement(elementB))(
+ [_isType(elementA.typeParameters[0].type)])(exp.staticType);
+ }
+
+ void test_fieldDeclaration_propagation() {
+ String code = r'''
+ class A {
+ List<String> f0 = ["hello"];
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ VariableDeclaration field = AstFinder.getFieldInClass(unit, "A", "f0");
+
+ _isListOf(_isString)(field.initializer.staticType);
+ }
+
+ void test_functionDeclaration_body_propagation() {
+ String code = r'''
+ typedef T Function2<S, T>(S x);
+
+ List<int> test1() => [];
+
+ Function2<int, int> test2 (int x) {
+ Function2<String, int> inner() {
+ return (x) => x.length;
+ }
+ return (x) => x;
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+ FunctionDeclaration test1 = AstFinder.getTopLevelFunction(unit, "test1");
+ ExpressionFunctionBody body = test1.functionExpression.body;
+ assertListOfInt(body.expression.staticType);
+
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test2");
+
+ FunctionDeclaration inner =
+ (statements[0] as FunctionDeclarationStatement).functionDeclaration;
+ BlockFunctionBody body0 = inner.functionExpression.body;
+ ReturnStatement return0 = body0.block.statements[0];
+ Expression anon0 = return0.expression;
+ FunctionType type0 = anon0.staticType;
+ expect(type0.returnType, typeProvider.intType);
+ expect(type0.normalParameterTypes[0], typeProvider.stringType);
+
+ FunctionExpression anon1 = (statements[1] as ReturnStatement).expression;
+ FunctionType type1 = anon1.element.type;
+ expect(type1.returnType, typeProvider.intType);
+ expect(type1.normalParameterTypes[0], typeProvider.intType);
+ }
+
+ void test_functionLiteral_assignment_typedArguments() {
+ String code = r'''
+ typedef T Function2<S, T>(S x);
+
+ void main () {
+ Function2<int, String> l0 = (int x) => null;
+ Function2<int, String> l1 = (int x) => "hello";
+ Function2<int, String> l2 = (String x) => "hello";
+ Function2<int, String> l3 = (int x) => 3;
+ Function2<int, String> l4 = (int x) {return 3;};
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ FunctionExpression exp = decl.initializer;
+ return exp.element.type;
+ }
+ _isFunction2Of(_isInt, _isString)(literal(0));
+ _isFunction2Of(_isInt, _isString)(literal(1));
+ _isFunction2Of(_isString, _isString)(literal(2));
+ _isFunction2Of(_isInt, _isInt)(literal(3));
+ _isFunction2Of(_isInt, _isString)(literal(4));
+ }
+
+ void test_functionLiteral_assignment_unTypedArguments() {
+ String code = r'''
+ typedef T Function2<S, T>(S x);
+
+ void main () {
+ Function2<int, String> l0 = (x) => null;
+ Function2<int, String> l1 = (x) => "hello";
+ Function2<int, String> l2 = (x) => "hello";
+ Function2<int, String> l3 = (x) => 3;
+ Function2<int, String> l4 = (x) {return 3;};
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ FunctionExpression exp = decl.initializer;
+ return exp.element.type;
+ }
+ _isFunction2Of(_isInt, _isString)(literal(0));
+ _isFunction2Of(_isInt, _isString)(literal(1));
+ _isFunction2Of(_isInt, _isString)(literal(2));
+ _isFunction2Of(_isInt, _isInt)(literal(3));
+ _isFunction2Of(_isInt, _isString)(literal(4));
+ }
+
+ void test_functionLiteral_body_propagation() {
+ String code = r'''
+ typedef T Function2<S, T>(S x);
+
+ void main () {
+ Function2<int, List<String>> l0 = (int x) => ["hello"];
+ Function2<int, List<String>> l1 = (String x) => ["hello"];
+ Function2<int, List<String>> l2 = (int x) => [3];
+ Function2<int, List<String>> l3 = (int x) {return [3];};
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ Expression functionReturnValue(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ FunctionExpression exp = decl.initializer;
+ FunctionBody body = exp.body;
+ if (body is ExpressionFunctionBody) {
+ return body.expression;
+ } else {
+ Statement stmt = (body as BlockFunctionBody).block.statements[0];
+ return (stmt as ReturnStatement).expression;
+ }
+ }
+ Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
+ assertListOfString(functionReturnValue(0).staticType);
+ assertListOfString(functionReturnValue(1).staticType);
+ assertListOfString(functionReturnValue(2).staticType);
+ assertListOfString(functionReturnValue(3).staticType);
+ }
+
+ void test_functionLiteral_functionExpressionInvocation_typedArguments() {
+ String code = r'''
+ class Mapper<F, T> {
+ T map(T mapper(F x)) => mapper(null);
+ }
+
+ void main () {
+ (new Mapper<int, String>().map)((int x) => null);
+ (new Mapper<int, String>().map)((int x) => "hello");
+ (new Mapper<int, String>().map)((String x) => "hello");
+ (new Mapper<int, String>().map)((int x) => 3);
+ (new Mapper<int, String>().map)((int x) {return 3;});
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ ExpressionStatement stmt = statements[i];
+ FunctionExpressionInvocation invk = stmt.expression;
+ FunctionExpression exp = invk.argumentList.arguments[0];
+ return exp.element.type;
+ }
+ _isFunction2Of(_isInt, _isString)(literal(0));
+ _isFunction2Of(_isInt, _isString)(literal(1));
+ _isFunction2Of(_isString, _isString)(literal(2));
+ _isFunction2Of(_isInt, _isInt)(literal(3));
+ _isFunction2Of(_isInt, _isString)(literal(4));
+ }
+
+ void test_functionLiteral_functionExpressionInvocation_unTypedArguments() {
+ String code = r'''
+ class Mapper<F, T> {
+ T map(T mapper(F x)) => mapper(null);
+ }
+
+ void main () {
+ (new Mapper<int, String>().map)((x) => null);
+ (new Mapper<int, String>().map)((x) => "hello");
+ (new Mapper<int, String>().map)((x) => "hello");
+ (new Mapper<int, String>().map)((x) => 3);
+ (new Mapper<int, String>().map)((x) {return 3;});
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ ExpressionStatement stmt = statements[i];
+ FunctionExpressionInvocation invk = stmt.expression;
+ FunctionExpression exp = invk.argumentList.arguments[0];
+ return exp.element.type;
+ }
+ _isFunction2Of(_isInt, _isString)(literal(0));
+ _isFunction2Of(_isInt, _isString)(literal(1));
+ _isFunction2Of(_isInt, _isString)(literal(2));
+ _isFunction2Of(_isInt, _isInt)(literal(3));
+ _isFunction2Of(_isInt, _isString)(literal(4));
+ }
+
+ void test_functionLiteral_functionInvocation_typedArguments() {
+ String code = r'''
+ String map(String mapper(int x)) => mapper(null);
+
+ void main () {
+ map((int x) => null);
+ map((int x) => "hello");
+ map((String x) => "hello");
+ map((int x) => 3);
+ map((int x) {return 3;});
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ ExpressionStatement stmt = statements[i];
+ MethodInvocation invk = stmt.expression;
+ FunctionExpression exp = invk.argumentList.arguments[0];
+ return exp.element.type;
+ }
+ _isFunction2Of(_isInt, _isString)(literal(0));
+ _isFunction2Of(_isInt, _isString)(literal(1));
+ _isFunction2Of(_isString, _isString)(literal(2));
+ _isFunction2Of(_isInt, _isInt)(literal(3));
+ _isFunction2Of(_isInt, _isString)(literal(4));
+ }
+
+ void test_functionLiteral_functionInvocation_unTypedArguments() {
+ String code = r'''
+ String map(String mapper(int x)) => mapper(null);
+
+ void main () {
+ map((x) => null);
+ map((x) => "hello");
+ map((x) => "hello");
+ map((x) => 3);
+ map((x) {return 3;});
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ ExpressionStatement stmt = statements[i];
+ MethodInvocation invk = stmt.expression;
+ FunctionExpression exp = invk.argumentList.arguments[0];
+ return exp.element.type;
+ }
+ _isFunction2Of(_isInt, _isString)(literal(0));
+ _isFunction2Of(_isInt, _isString)(literal(1));
+ _isFunction2Of(_isInt, _isString)(literal(2));
+ _isFunction2Of(_isInt, _isInt)(literal(3));
+ _isFunction2Of(_isInt, _isString)(literal(4));
+ }
+
+ void test_functionLiteral_methodInvocation_typedArguments() {
+ String code = r'''
+ class Mapper<F, T> {
+ T map(T mapper(F x)) => mapper(null);
+ }
+
+ void main () {
+ new Mapper<int, String>().map((int x) => null);
+ new Mapper<int, String>().map((int x) => "hello");
+ new Mapper<int, String>().map((String x) => "hello");
+ new Mapper<int, String>().map((int x) => 3);
+ new Mapper<int, String>().map((int x) {return 3;});
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ ExpressionStatement stmt = statements[i];
+ MethodInvocation invk = stmt.expression;
+ FunctionExpression exp = invk.argumentList.arguments[0];
+ return exp.element.type;
+ }
+ _isFunction2Of(_isInt, _isString)(literal(0));
+ _isFunction2Of(_isInt, _isString)(literal(1));
+ _isFunction2Of(_isString, _isString)(literal(2));
+ _isFunction2Of(_isInt, _isInt)(literal(3));
+ _isFunction2Of(_isInt, _isString)(literal(4));
+ }
+
+ void test_functionLiteral_methodInvocation_unTypedArguments() {
+ String code = r'''
+ class Mapper<F, T> {
+ T map(T mapper(F x)) => mapper(null);
+ }
+
+ void main () {
+ new Mapper<int, String>().map((x) => null);
+ new Mapper<int, String>().map((x) => "hello");
+ new Mapper<int, String>().map((x) => "hello");
+ new Mapper<int, String>().map((x) => 3);
+ new Mapper<int, String>().map((x) {return 3;});
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ ExpressionStatement stmt = statements[i];
+ MethodInvocation invk = stmt.expression;
+ FunctionExpression exp = invk.argumentList.arguments[0];
+ return exp.element.type;
+ }
+ _isFunction2Of(_isInt, _isString)(literal(0));
+ _isFunction2Of(_isInt, _isString)(literal(1));
+ _isFunction2Of(_isInt, _isString)(literal(2));
+ _isFunction2Of(_isInt, _isInt)(literal(3));
+ _isFunction2Of(_isInt, _isString)(literal(4));
+ }
+
+ void test_functionLiteral_unTypedArgument_propagation() {
+ String code = r'''
+ typedef T Function2<S, T>(S x);
+
+ void main () {
+ Function2<int, int> l0 = (x) => x;
+ Function2<int, int> l1 = (x) => x+1;
+ Function2<int, String> l2 = (x) => x;
+ Function2<int, String> l3 = (x) => x.toLowerCase();
+ Function2<String, String> l4 = (x) => x.toLowerCase();
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ Expression functionReturnValue(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ FunctionExpression exp = decl.initializer;
+ FunctionBody body = exp.body;
+ if (body is ExpressionFunctionBody) {
+ return body.expression;
+ } else {
+ Statement stmt = (body as BlockFunctionBody).block.statements[0];
+ return (stmt as ReturnStatement).expression;
+ }
+ }
+ expect(functionReturnValue(0).staticType, typeProvider.intType);
+ expect(functionReturnValue(1).staticType, typeProvider.intType);
+ expect(functionReturnValue(2).staticType, typeProvider.intType);
+ expect(functionReturnValue(3).staticType, typeProvider.dynamicType);
+ expect(functionReturnValue(4).staticType, typeProvider.stringType);
+ }
+
+ void test_inference_hints() {
+ Source source = addSource(r'''
+ void main () {
+ var x = 3;
+ List<int> l0 = [];
+ }
+ ''');
+ resolve2(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_instanceCreation() {
+ String code = r'''
+ class A<S, T> {
+ S x;
+ T y;
+ A(this.x, this.y);
+ A.named(this.x, this.y);
+ }
+
+ class B<S, T> extends A<T, S> {
+ B(S y, T x) : super(x, y);
+ B.named(S y, T x) : super.named(x, y);
+ }
+
+ class C<S> extends B<S, S> {
+ C(S a) : super(a, a);
+ C.named(S a) : super.named(a, a);
+ }
+
+ class D<S, T> extends B<T, int> {
+ D(T a) : super(a, 3);
+ D.named(T a) : super.named(a, 3);
+ }
+
+ class E<S, T> extends A<C<S>, T> {
+ E(T a) : super(null, a);
+ }
+
+ class F<S, T> extends A<S, T> {
+ F(S x, T y, {List<S> a, List<T> b}) : super(x, y);
+ F.named(S x, T y, [S a, T b]) : super(a, b);
+ }
+
+ void test0() {
+ A<int, String> a0 = new A(3, "hello");
+ A<int, String> a1 = new A.named(3, "hello");
+ A<int, String> a2 = new A<int, String>(3, "hello");
+ A<int, String> a3 = new A<int, String>.named(3, "hello");
+ A<int, String> a4 = new A<int, dynamic>(3, "hello");
+ A<int, String> a5 = new A<dynamic, dynamic>.named(3, "hello");
+ }
+ void test1() {
+ A<int, String> a0 = new A("hello", 3);
+ A<int, String> a1 = new A.named("hello", 3);
+ }
+ void test2() {
+ A<int, String> a0 = new B("hello", 3);
+ A<int, String> a1 = new B.named("hello", 3);
+ A<int, String> a2 = new B<String, int>("hello", 3);
+ A<int, String> a3 = new B<String, int>.named("hello", 3);
+ A<int, String> a4 = new B<String, dynamic>("hello", 3);
+ A<int, String> a5 = new B<dynamic, dynamic>.named("hello", 3);
+ }
+ void test3() {
+ A<int, String> a0 = new B(3, "hello");
+ A<int, String> a1 = new B.named(3, "hello");
+ }
+ void test4() {
+ A<int, int> a0 = new C(3);
+ A<int, int> a1 = new C.named(3);
+ A<int, int> a2 = new C<int>(3);
+ A<int, int> a3 = new C<int>.named(3);
+ A<int, int> a4 = new C<dynamic>(3);
+ A<int, int> a5 = new C<dynamic>.named(3);
+ }
+ void test5() {
+ A<int, int> a0 = new C("hello");
+ A<int, int> a1 = new C.named("hello");
+ }
+ void test6() {
+ A<int, String> a0 = new D("hello");
+ A<int, String> a1 = new D.named("hello");
+ A<int, String> a2 = new D<int, String>("hello");
+ A<int, String> a3 = new D<String, String>.named("hello");
+ A<int, String> a4 = new D<num, dynamic>("hello");
+ A<int, String> a5 = new D<dynamic, dynamic>.named("hello");
+ }
+ void test7() {
+ A<int, String> a0 = new D(3);
+ A<int, String> a1 = new D.named(3);
+ }
+ void test8() {
+ // Currently we only allow variable constraints. Test that we reject.
+ A<C<int>, String> a0 = new E("hello");
+ }
+ void test9() { // Check named and optional arguments
+ A<int, String> a0 = new F(3, "hello", a: [3], b: ["hello"]);
+ A<int, String> a1 = new F(3, "hello", a: ["hello"], b:[3]);
+ A<int, String> a2 = new F.named(3, "hello", 3, "hello");
+ A<int, String> a3 = new F.named(3, "hello");
+ A<int, String> a4 = new F.named(3, "hello", "hello", 3);
+ A<int, String> a5 = new F.named(3, "hello", "hello");
+ }
+ }''';
+ CompilationUnit unit = resolveSource(code);
+
+ Expression rhs(VariableDeclarationStatement stmt) {
+ VariableDeclaration decl = stmt.variables.variables[0];
+ Expression exp = decl.initializer;
+ return exp;
+ }
+
+ void hasType(Asserter<DartType> assertion, Expression exp) =>
+ assertion(exp.staticType);
+
+ Element elementA = AstFinder.getClass(unit, "A").element;
+ Element elementB = AstFinder.getClass(unit, "B").element;
+ Element elementC = AstFinder.getClass(unit, "C").element;
+ Element elementD = AstFinder.getClass(unit, "D").element;
+ Element elementE = AstFinder.getClass(unit, "E").element;
+ Element elementF = AstFinder.getClass(unit, "F").element;
+
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf =
+ _isInstantiationOf(_hasElement(elementA));
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf =
+ _isInstantiationOf(_hasElement(elementB));
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertCOf =
+ _isInstantiationOf(_hasElement(elementC));
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertDOf =
+ _isInstantiationOf(_hasElement(elementD));
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf =
+ _isInstantiationOf(_hasElement(elementE));
+ AsserterBuilder<List<Asserter<DartType>>, DartType> assertFOf =
+ _isInstantiationOf(_hasElement(elementF));
+
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test0");
+
+ hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
+ hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
+ hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
+ hasType(assertAOf([_isInt, _isString]), rhs(statements[2]));
+ hasType(assertAOf([_isInt, _isString]), rhs(statements[3]));
+ hasType(assertAOf([_isInt, _isDynamic]), rhs(statements[4]));
+ hasType(assertAOf([_isDynamic, _isDynamic]), rhs(statements[5]));
+ }
+
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test1");
+ hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
+ hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
+ }
+
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test2");
+ hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
+ hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
+ hasType(assertBOf([_isString, _isInt]), rhs(statements[2]));
+ hasType(assertBOf([_isString, _isInt]), rhs(statements[3]));
+ hasType(assertBOf([_isString, _isDynamic]), rhs(statements[4]));
+ hasType(assertBOf([_isDynamic, _isDynamic]), rhs(statements[5]));
+ }
+
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test3");
+ hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
+ hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
+ }
+
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test4");
+ hasType(assertCOf([_isInt]), rhs(statements[0]));
+ hasType(assertCOf([_isInt]), rhs(statements[1]));
+ hasType(assertCOf([_isInt]), rhs(statements[2]));
+ hasType(assertCOf([_isInt]), rhs(statements[3]));
+ hasType(assertCOf([_isDynamic]), rhs(statements[4]));
+ hasType(assertCOf([_isDynamic]), rhs(statements[5]));
+ }
+
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test5");
+ hasType(assertCOf([_isInt]), rhs(statements[0]));
+ hasType(assertCOf([_isInt]), rhs(statements[1]));
+ }
+
+ {
+ // The first type parameter is not constrained by the
+ // context. We could choose a tighter type, but currently
+ // we just use dynamic.
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test6");
+ hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
+ hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
+ hasType(assertDOf([_isInt, _isString]), rhs(statements[2]));
+ hasType(assertDOf([_isString, _isString]), rhs(statements[3]));
+ hasType(assertDOf([_isNum, _isDynamic]), rhs(statements[4]));
+ hasType(assertDOf([_isDynamic, _isDynamic]), rhs(statements[5]));
+ }
+
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test7");
+ hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
+ hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
+ }
+
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test8");
+ hasType(assertEOf([_isDynamic, _isDynamic]), rhs(statements[0]));
+ }
+
+ {
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "test9");
+ hasType(assertFOf([_isInt, _isString]), rhs(statements[0]));
+ hasType(assertFOf([_isInt, _isString]), rhs(statements[1]));
+ hasType(assertFOf([_isInt, _isString]), rhs(statements[2]));
+ hasType(assertFOf([_isInt, _isString]), rhs(statements[3]));
+ hasType(assertFOf([_isInt, _isString]), rhs(statements[4]));
+ hasType(assertFOf([_isInt, _isString]), rhs(statements[5]));
+ }
+ }
+
+ void test_listLiteral_nested() {
+ String code = r'''
+ void main () {
+ List<List<int>> l0 = [[]];
+ Iterable<List<int>> l1 = [[3]];
+ Iterable<List<int>> l2 = [[3], [4]];
+ List<List<int>> l3 = [["hello", 3], []];
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ ListLiteral literal(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ ListLiteral exp = decl.initializer;
+ return exp;
+ }
+
+ Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+ Asserter<InterfaceType> assertListOfListOfInt = _isListOf(assertListOfInt);
+
+ assertListOfListOfInt(literal(0).staticType);
+ assertListOfListOfInt(literal(1).staticType);
+ assertListOfListOfInt(literal(2).staticType);
+ assertListOfListOfInt(literal(3).staticType);
+
+ assertListOfInt(literal(1).elements[0].staticType);
+ assertListOfInt(literal(2).elements[0].staticType);
+ assertListOfInt(literal(3).elements[0].staticType);
+ }
+
+ void test_listLiteral_simple() {
+ String code = r'''
+ void main () {
+ List<int> l0 = [];
+ List<int> l1 = [3];
+ List<int> l2 = ["hello"];
+ List<int> l3 = ["hello", 3];
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ ListLiteral exp = decl.initializer;
+ return exp.staticType;
+ }
+
+ Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+ assertListOfInt(literal(0));
+ assertListOfInt(literal(1));
+ assertListOfInt(literal(2));
+ assertListOfInt(literal(3));
+ }
+
+ void test_listLiteral_simple_const() {
+ String code = r'''
+ void main () {
+ const List<int> c0 = const [];
+ const List<int> c1 = const [3];
+ const List<int> c2 = const ["hello"];
+ const List<int> c3 = const ["hello", 3];
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ ListLiteral exp = decl.initializer;
+ return exp.staticType;
+ }
+
+ Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+ assertListOfInt(literal(0));
+ assertListOfInt(literal(1));
+ assertListOfInt(literal(2));
+ assertListOfInt(literal(3));
+ }
+
+ void test_listLiteral_simple_disabled() {
+ String code = r'''
+ void main () {
+ List<int> l0 = <num>[];
+ List<int> l1 = <num>[3];
+ List<int> l2 = <String>["hello"];
+ List<int> l3 = <dynamic>["hello", 3];
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ ListLiteral exp = decl.initializer;
+ return exp.staticType;
+ }
+
+ _isListOf(_isNum)(literal(0));
+ _isListOf(_isNum)(literal(1));
+ _isListOf(_isString)(literal(2));
+ _isListOf(_isDynamic)(literal(3));
+ }
+
+ void test_listLiteral_simple_subtype() {
+ String code = r'''
+ void main () {
+ Iterable<int> l0 = [];
+ Iterable<int> l1 = [3];
+ Iterable<int> l2 = ["hello"];
+ Iterable<int> l3 = ["hello", 3];
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ ListLiteral exp = decl.initializer;
+ return exp.staticType;
+ }
+
+ Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+ assertListOfInt(literal(0));
+ assertListOfInt(literal(1));
+ assertListOfInt(literal(2));
+ assertListOfInt(literal(3));
+ }
+
+ void test_mapLiteral_nested() {
+ String code = r'''
+ void main () {
+ Map<int, List<String>> l0 = {};
+ Map<int, List<String>> l1 = {3: ["hello"]};
+ Map<int, List<String>> l2 = {"hello": ["hello"]};
+ Map<int, List<String>> l3 = {3: [3]};
+ Map<int, List<String>> l4 = {3:["hello"], "hello": [3]};
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ MapLiteral literal(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ MapLiteral exp = decl.initializer;
+ return exp;
+ }
+
+ Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
+ Asserter<InterfaceType> assertMapOfIntToListOfString =
+ _isMapOf(_isInt, assertListOfString);
+
+ assertMapOfIntToListOfString(literal(0).staticType);
+ assertMapOfIntToListOfString(literal(1).staticType);
+ assertMapOfIntToListOfString(literal(2).staticType);
+ assertMapOfIntToListOfString(literal(3).staticType);
+ assertMapOfIntToListOfString(literal(4).staticType);
+
+ assertListOfString(literal(1).entries[0].value.staticType);
+ assertListOfString(literal(2).entries[0].value.staticType);
+ assertListOfString(literal(3).entries[0].value.staticType);
+ assertListOfString(literal(4).entries[0].value.staticType);
+ }
+
+ void test_mapLiteral_simple() {
+ String code = r'''
+ void main () {
+ Map<int, String> l0 = {};
+ Map<int, String> l1 = {3: "hello"};
+ Map<int, String> l2 = {"hello": "hello"};
+ Map<int, String> l3 = {3: 3};
+ Map<int, String> l4 = {3:"hello", "hello": 3};
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ MapLiteral exp = decl.initializer;
+ return exp.staticType;
+ }
+
+ Asserter<InterfaceType> assertMapOfIntToString =
+ _isMapOf(_isInt, _isString);
+
+ assertMapOfIntToString(literal(0));
+ assertMapOfIntToString(literal(1));
+ assertMapOfIntToString(literal(2));
+ assertMapOfIntToString(literal(3));
+ }
+
+ void test_mapLiteral_simple_disabled() {
+ String code = r'''
+ void main () {
+ Map<int, String> l0 = <int, dynamic>{};
+ Map<int, String> l1 = <int, dynamic>{3: "hello"};
+ Map<int, String> l2 = <int, dynamic>{"hello": "hello"};
+ Map<int, String> l3 = <int, dynamic>{3: 3};
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ List<Statement> statements =
+ AstFinder.getStatementsInTopLevelFunction(unit, "main");
+ DartType literal(int i) {
+ VariableDeclarationStatement stmt = statements[i];
+ VariableDeclaration decl = stmt.variables.variables[0];
+ MapLiteral exp = decl.initializer;
+ return exp.staticType;
+ }
+
+ Asserter<InterfaceType> assertMapOfIntToDynamic =
+ _isMapOf(_isInt, _isDynamic);
+
+ assertMapOfIntToDynamic(literal(0));
+ assertMapOfIntToDynamic(literal(1));
+ assertMapOfIntToDynamic(literal(2));
+ assertMapOfIntToDynamic(literal(3));
+ }
+
+ void test_methodDeclaration_body_propagation() {
+ String code = r'''
+ class A {
+ List<String> m0(int x) => ["hello"];
+ List<String> m1(int x) {return [3];};
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+ Expression methodReturnValue(String methodName) {
+ MethodDeclaration method =
+ AstFinder.getMethodInClass(unit, "A", methodName);
+ FunctionBody body = method.body;
+ if (body is ExpressionFunctionBody) {
+ return body.expression;
+ } else {
+ Statement stmt = (body as BlockFunctionBody).block.statements[0];
+ return (stmt as ReturnStatement).expression;
+ }
+ }
+ Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
+ assertListOfString(methodReturnValue("m0").staticType);
+ assertListOfString(methodReturnValue("m1").staticType);
+ }
+
+ void test_redirectingConstructor_propagation() {
+ String code = r'''
+ class A {
+ A() : this.named([]);
+ A.named(List<String> x);
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ ConstructorDeclaration constructor =
+ AstFinder.getConstructorInClass(unit, "A", null);
+ RedirectingConstructorInvocation invocation = constructor.initializers[0];
+ Expression exp = invocation.argumentList.arguments[0];
+ _isListOf(_isString)(exp.staticType);
+ }
+
+ void test_superConstructorInvocation_propagation() {
+ String code = r'''
+ class B {
+ B(List<String>);
+ }
+ class A extends B {
+ A() : super([]);
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ ConstructorDeclaration constructor =
+ AstFinder.getConstructorInClass(unit, "A", null);
+ SuperConstructorInvocation invocation = constructor.initializers[0];
+ Expression exp = invocation.argumentList.arguments[0];
+ _isListOf(_isString)(exp.staticType);
+ }
+
+ void test_sync_star_method_propagation() {
+ String code = r'''
+ import "dart:async";
+ class A {
+ Iterable f0() sync* { yield []; }
+ Iterable f1() sync* { yield* new List(); }
+
+ Iterable<List<int>> f2() sync* { yield []; }
+ Iterable<List<int>> f3() sync* { yield* new List(); }
+ }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ void check(String name, Asserter<InterfaceType> typeTest) {
+ MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
+ BlockFunctionBody body = test.body;
+ YieldStatement stmt = body.block.statements[0];
+ Expression exp = stmt.expression;
+ typeTest(exp.staticType);
+ }
+
+ check("f0", _isListOf(_isDynamic));
+ check("f1", _isListOf(_isDynamic));
+
+ check("f2", _isListOf(_isInt));
+ check("f3", _isListOf(_isListOf(_isInt)));
+ }
+
+ void test_sync_star_propagation() {
+ String code = r'''
+ import "dart:async";
+
+ Iterable f0() sync* { yield []; }
+ Iterable f1() sync* { yield* new List(); }
+
+ Iterable<List<int>> f2() sync* { yield []; }
+ Iterable<List<int>> f3() sync* { yield* new List(); }
+ ''';
+ CompilationUnit unit = resolveSource(code);
+
+ void check(String name, Asserter<InterfaceType> typeTest) {
+ FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
+ BlockFunctionBody body = test.functionExpression.body;
+ YieldStatement stmt = body.block.statements[0];
+ Expression exp = stmt.expression;
+ typeTest(exp.staticType);
+ }
+
+ check("f0", _isListOf(_isDynamic));
+ check("f1", _isListOf(_isDynamic));
+
+ check("f2", _isListOf(_isInt));
+ check("f3", _isListOf(_isListOf(_isInt)));
+ }
+}
+
+/**
+ * Strong mode static analyzer end to end tests
+ */
+@reflectiveTest
+class StrongModeStaticTypeAnalyzer2Test extends StaticTypeAnalyzer2TestShared {
+ void fail_genericMethod_tearoff_instantiated() {
+ resolveTestUnit(r'''
+class C<E> {
+ /*=T*/ f/*<T>*/(E e) => null;
+ static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+ static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+ var c = new C<int>();
+ /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+ var methodTearOffInst = c.f/*<int>*/;
+ var staticTearOffInst = C.g/*<int>*/;
+ var staticFieldTearOffInst = C.h/*<int>*/;
+ var topFunTearOffInst = topF/*<int>*/;
+ var topFieldTearOffInst = topG/*<int>*/;
+ var localTearOffInst = lf/*<int>*/;
+ var paramTearOffInst = pf/*<int>*/;
+}
+''');
+ expectIdentifierType('methodTearOffInst', "(int) → int");
+ expectIdentifierType('staticTearOffInst', "(int) → int");
+ expectIdentifierType('staticFieldTearOffInst', "(int) → int");
+ expectIdentifierType('topFunTearOffInst', "(int) → int");
+ expectIdentifierType('topFieldTearOffInst', "(int) → int");
+ expectIdentifierType('localTearOffInst', "(int) → int");
+ expectIdentifierType('paramTearOffInst', "(int) → int");
+ }
+
+ void setUp() {
+ super.setUp();
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.strongMode = true;
+ resetWithOptions(options);
+ }
+
+ void test_dynamicObjectGetter_hashCode() {
+ String code = r'''
+main() {
+ dynamic a = null;
+ var foo = a.hashCode;
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'int', isNull);
+ }
+
+ void test_dynamicObjectMethod_toString() {
+ String code = r'''
+main() {
+ dynamic a = null;
+ var foo = a.toString();
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'String', isNull);
+ }
+
+ void test_genericFunction() {
+ resolveTestUnit(r'/*=T*/ f/*<T>*/(/*=T*/ x) => null;');
+ expectFunctionType('f', '<T>(T) → T',
+ elementTypeParams: '[T]', typeFormals: '[T]');
+ SimpleIdentifier f = findIdentifier('f');
+ FunctionElementImpl e = f.staticElement;
+ FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+ expect(ft.toString(), '(String) → String');
+ }
+
+ void test_genericFunction_bounds() {
+ resolveTestUnit(r'/*=T*/ f/*<T extends num>*/(/*=T*/ x) => null;');
+ expectFunctionType('f', '<T extends num>(T) → T',
+ elementTypeParams: '[T extends num]', typeFormals: '[T extends num]');
+ }
+
+ void test_genericFunction_parameter() {
+ resolveTestUnit(r'''
+void g(/*=T*/ f/*<T>*/(/*=T*/ x)) {}
+''');
+ expectFunctionType('f', '<T>(T) → T',
+ elementTypeParams: '[T]', typeFormals: '[T]');
+ SimpleIdentifier f = findIdentifier('f');
+ ParameterElementImpl e = f.staticElement;
+ FunctionType type = e.type;
+ FunctionType ft = type.instantiate([typeProvider.stringType]);
+ expect(ft.toString(), '(String) → String');
+ }
+
+ void test_genericFunction_static() {
+ resolveTestUnit(r'''
+class C<E> {
+ static /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+''');
+ expectFunctionType('f', '<T>(T) → T',
+ elementTypeParams: '[T]', typeFormals: '[T]');
+ SimpleIdentifier f = findIdentifier('f');
+ MethodElementImpl e = f.staticElement;
+ FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+ expect(ft.toString(), '(String) → String');
+ }
+
+ void test_genericFunction_typedef() {
+ String code = r'''
+typedef T F<T>(T x);
+F f0;
+
+class C {
+ static F f1;
+ F f2;
+ void g(F f3) {
+ F f4;
+ f0(3);
+ f1(3);
+ f2(3);
+ f3(3);
+ f4(3);
+ }
+}
+
+class D<S> {
+ static F f1;
+ F f2;
+ void g(F f3) {
+ F f4;
+ f0(3);
+ f1(3);
+ f2(3);
+ f3(3);
+ f4(3);
+ }
+}
+''';
+ resolveTestUnit(code);
+
+ checkBody(String className) {
+ List<Statement> statements =
+ AstFinder.getStatementsInMethod(testUnit, className, "g");
+
+ for (int i = 1; i <= 5; i++) {
+ Expression exp = (statements[i] as ExpressionStatement).expression;
+ expect(exp.staticType, typeProvider.dynamicType);
+ }
+ }
+
+ checkBody("C");
+ checkBody("D");
+ }
+
+ void test_genericMethod() {
+ resolveTestUnit(r'''
+class C<E> {
+ List/*<T>*/ f/*<T>*/(E e) => null;
+}
+main() {
+ C<String> cOfString;
+}
+''');
+ expectFunctionType('f', '<T>(E) → List<T>',
+ elementTypeParams: '[T]',
+ typeParams: '[E]',
+ typeArgs: '[E]',
+ typeFormals: '[T]');
+ SimpleIdentifier c = findIdentifier('cOfString');
+ FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
+ expect(ft.toString(), '<T>(String) → List<T>');
+ ft = ft.instantiate([typeProvider.intType]);
+ expect(ft.toString(), '(String) → List<int>');
+ expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
+ }
+
+ void test_genericMethod_explicitTypeParams() {
+ resolveTestUnit(r'''
+class C<E> {
+ List/*<T>*/ f/*<T>*/(E e) => null;
+}
+main() {
+ C<String> cOfString;
+ var x = cOfString.f/*<int>*/('hi');
+}
+''');
+ MethodInvocation f = findIdentifier('f/*<int>*/').parent;
+ FunctionType ft = f.staticInvokeType;
+ expect(ft.toString(), '(String) → List<int>');
+ expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
+
+ SimpleIdentifier x = findIdentifier('x');
+ expect(x.staticType,
+ typeProvider.listType.instantiate([typeProvider.intType]));
+ }
+
+ void test_genericMethod_functionExpressionInvocation_explicit() {
+ resolveTestUnit(r'''
+class C<E> {
+ /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+ static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+ static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+ var c = new C<int>();
+ /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+
+ var lambdaCall = (/*<E>*/(/*=E*/ e) => e)/*<int>*/(3);
+ var methodCall = (c.f)/*<int>*/(3);
+ var staticCall = (C.g)/*<int>*/(3);
+ var staticFieldCall = (C.h)/*<int>*/(3);
+ var topFunCall = (topF)/*<int>*/(3);
+ var topFieldCall = (topG)/*<int>*/(3);
+ var localCall = (lf)/*<int>*/(3);
+ var paramCall = (pf)/*<int>*/(3);
+}
+''');
+ expectIdentifierType('methodCall', "int");
+ expectIdentifierType('staticCall', "int");
+ expectIdentifierType('staticFieldCall', "int");
+ expectIdentifierType('topFunCall', "int");
+ expectIdentifierType('topFieldCall', "int");
+ expectIdentifierType('localCall', "int");
+ expectIdentifierType('paramCall', "int");
+ expectIdentifierType('lambdaCall', "int");
+ }
+
+ void test_genericMethod_functionExpressionInvocation_inferred() {
+ resolveTestUnit(r'''
+class C<E> {
+ /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+ static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+ static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+ var c = new C<int>();
+ /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+
+ var lambdaCall = (/*<E>*/(/*=E*/ e) => e)(3);
+ var methodCall = (c.f)(3);
+ var staticCall = (C.g)(3);
+ var staticFieldCall = (C.h)(3);
+ var topFunCall = (topF)(3);
+ var topFieldCall = (topG)(3);
+ var localCall = (lf)(3);
+ var paramCall = (pf)(3);
+}
+''');
+ expectIdentifierType('methodCall', "int");
+ expectIdentifierType('staticCall', "int");
+ expectIdentifierType('staticFieldCall', "int");
+ expectIdentifierType('topFunCall', "int");
+ expectIdentifierType('topFieldCall', "int");
+ expectIdentifierType('localCall', "int");
+ expectIdentifierType('paramCall', "int");
+ expectIdentifierType('lambdaCall', "int");
+ }
+
+ void test_genericMethod_functionInvocation_explicit() {
+ resolveTestUnit(r'''
+class C<E> {
+ /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+ static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+ static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+ var c = new C<int>();
+ /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+ var methodCall = c.f/*<int>*/(3);
+ var staticCall = C.g/*<int>*/(3);
+ var staticFieldCall = C.h/*<int>*/(3);
+ var topFunCall = topF/*<int>*/(3);
+ var topFieldCall = topG/*<int>*/(3);
+ var localCall = lf/*<int>*/(3);
+ var paramCall = pf/*<int>*/(3);
+}
+''');
+ expectIdentifierType('methodCall', "int");
+ expectIdentifierType('staticCall', "int");
+ expectIdentifierType('staticFieldCall', "int");
+ expectIdentifierType('topFunCall', "int");
+ expectIdentifierType('topFieldCall', "int");
+ expectIdentifierType('localCall', "int");
+ expectIdentifierType('paramCall', "int");
+ }
+
+ void test_genericMethod_functionInvocation_inferred() {
+ resolveTestUnit(r'''
+class C<E> {
+ /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+ static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+ static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+ var c = new C<int>();
+ /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+ var methodCall = c.f(3);
+ var staticCall = C.g(3);
+ var staticFieldCall = C.h(3);
+ var topFunCall = topF(3);
+ var topFieldCall = topG(3);
+ var localCall = lf(3);
+ var paramCall = pf(3);
+}
+''');
+ expectIdentifierType('methodCall', "int");
+ expectIdentifierType('staticCall', "int");
+ expectIdentifierType('staticFieldCall', "int");
+ expectIdentifierType('topFunCall', "int");
+ expectIdentifierType('topFieldCall', "int");
+ expectIdentifierType('localCall', "int");
+ expectIdentifierType('paramCall', "int");
+ }
+
+ void test_genericMethod_functionTypedParameter() {
+ resolveTestUnit(r'''
+class C<E> {
+ List/*<T>*/ f/*<T>*/(/*=T*/ f(E e)) => null;
+}
+main() {
+ C<String> cOfString;
+}
+''');
+ expectFunctionType('f', '<T>((E) → T) → List<T>',
+ elementTypeParams: '[T]',
+ typeParams: '[E]',
+ typeArgs: '[E]',
+ typeFormals: '[T]');
+
+ SimpleIdentifier c = findIdentifier('cOfString');
+ FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
+ expect(ft.toString(), '<T>((String) → T) → List<T>');
+ ft = ft.instantiate([typeProvider.intType]);
+ expect(ft.toString(), '((String) → int) → List<int>');
+ }
+
+ void test_genericMethod_implicitDynamic() {
+ // Regression test for:
+ // https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588
+ // These should not cause any hints or warnings.
+ resolveTestUnit(r'''
+class List<E> {
+ /*=T*/ map/*<T>*/(/*=T*/ f(E e)) => null;
+}
+void foo() {
+ List list = null;
+ list.map((e) => e);
+ list.map((e) => 3);
+}''');
+ expectIdentifierType('map((e) => e);', '<T>((dynamic) → T) → T', isNull);
+ expectIdentifierType('map((e) => 3);', '<T>((dynamic) → T) → T', isNull);
+
+ MethodInvocation m1 = findIdentifier('map((e) => e);').parent;
+ expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
+ MethodInvocation m2 = findIdentifier('map((e) => 3);').parent;
+ expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int');
+ }
+
+ void test_genericMethod_max_doubleDouble() {
+ String code = r'''
+import 'dart:math';
+main() {
+ var foo = max(1.0, 2.0);
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'double', isNull);
+ }
+
+ void test_genericMethod_max_doubleDouble_prefixed() {
+ String code = r'''
+import 'dart:math' as math;
+main() {
+ var foo = math.max(1.0, 2.0);
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'double', isNull);
+ }
+
+ void test_genericMethod_max_doubleInt() {
+ String code = r'''
+import 'dart:math';
+main() {
+ var foo = max(1.0, 2);
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'num', isNull);
+ }
+
+ void test_genericMethod_max_intDouble() {
+ String code = r'''
+import 'dart:math';
+main() {
+ var foo = max(1, 2.0);
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'num', isNull);
+ }
+
+ void test_genericMethod_max_intInt() {
+ String code = r'''
+import 'dart:math';
+main() {
+ var foo = max(1, 2);
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'int', isNull);
+ }
+
+ void test_genericMethod_nestedBound() {
+ String code = r'''
+class Foo<T extends num> {
+ void method/*<U extends T>*/(dynamic/*=U*/ u) {
+ u.abs();
+ }
+}
+''';
+ // Just validate that there is no warning on the call to `.abs()`.
+ resolveTestUnit(code);
+ }
+
+ void test_genericMethod_nestedCapture() {
+ resolveTestUnit(r'''
+class C<T> {
+ /*=T*/ f/*<S>*/(/*=S*/ x) {
+ new C<S>().f/*<int>*/(3);
+ new C<S>().f; // tear-off
+ return null;
+ }
+}
+''');
+ MethodInvocation f = findIdentifier('f/*<int>*/(3);').parent;
+ expect(f.staticInvokeType.toString(), '(int) → S');
+ FunctionType ft = f.staticInvokeType;
+ expect('${ft.typeArguments}/${ft.typeParameters}', '[S, int]/[T, S]');
+
+ expectIdentifierType('f;', '<Sâ‚€>(Sâ‚€) → S');
+ }
+
+ void test_genericMethod_nestedFunctions() {
+ resolveTestUnit(r'''
+/*=S*/ f/*<S>*/(/*=S*/ x) {
+ g/*<S>*/(/*=S*/ x) => f;
+ return null;
+}
+''');
+ expectIdentifierType('f', '<S>(S) → S');
+ expectIdentifierType('g', '<S>(S) → dynamic');
+ }
+
+ void test_genericMethod_override() {
+ resolveTestUnit(r'''
+class C {
+ /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+ /*=T*/ f/*<T>*/(/*=T*/ x) => null; // from D
+}
+''');
+ expectFunctionType('f/*<T>*/(/*=T*/ x) => null; // from D', '<T>(T) → T',
+ elementTypeParams: '[T]', typeFormals: '[T]');
+ SimpleIdentifier f =
+ findIdentifier('f/*<T>*/(/*=T*/ x) => null; // from D');
+ MethodElementImpl e = f.staticElement;
+ FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+ expect(ft.toString(), '(String) → String');
+ }
+
+ void test_genericMethod_override_bounds() {
+ resolveTestUnit(r'''
+class A {}
+class B extends A {}
+class C {
+ /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
+}
+class D extends C {
+ /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
+}
+''');
+ }
+
+ void test_genericMethod_override_invalidReturnType() {
+ Source source = addSource(r'''
+class C {
+ Iterable/*<T>*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+ String f/*<S>*/(/*=S*/ x) => null;
+}''');
+ // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
+ // from CodeChecker don't have working equality.
+ List<AnalysisError> errors = analysisContext2.computeErrors(source);
+
+ // Sort errors by name.
+ errors.sort((AnalysisError e1, AnalysisError e2) =>
+ e1.errorCode.name.compareTo(e2.errorCode.name));
+
+ expect(errors.map((e) => e.errorCode.name), [
+ 'INVALID_METHOD_OVERRIDE_RETURN_TYPE',
+ 'STRONG_MODE_INVALID_METHOD_OVERRIDE'
+ ]);
+ expect(errors[0].message, contains('Iterable<S>'),
+ reason: 'errors should be in terms of the type parameters '
+ 'at the error location');
+ verify([source]);
+ }
+
+ void test_genericMethod_override_invalidTypeParamBounds() {
+ Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C {
+ /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
+}
+class D extends C {
+ /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
+}''');
+ // TODO(jmesserly): this is modified code from assertErrors, which we can't
+ // use directly because STRONG_MODE_* errors don't have working equality.
+ List<AnalysisError> errors = analysisContext2.computeErrors(source);
+ List errorNames = errors.map((e) => e.errorCode.name).toList();
+ expect(errorNames, hasLength(2));
+ expect(errorNames, contains('STRONG_MODE_INVALID_METHOD_OVERRIDE'));
+ expect(
+ errorNames, contains('INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND'));
+ verify([source]);
+ }
+
+ void test_genericMethod_override_invalidTypeParamCount() {
+ Source source = addSource(r'''
+class C {
+ /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+ /*=S*/ f/*<T, S>*/(/*=T*/ x) => null;
+}''');
+ // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
+ // from CodeChecker don't have working equality.
+ List<AnalysisError> errors = analysisContext2.computeErrors(source);
+ expect(errors.map((e) => e.errorCode.name), [
+ 'STRONG_MODE_INVALID_METHOD_OVERRIDE',
+ 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS'
+ ]);
+ verify([source]);
+ }
+
+ void test_genericMethod_propagatedType_promotion() {
+ // Regression test for:
+ // https://github.com/dart-lang/sdk/issues/25340
+
+ // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
+ // example won't work, as we now compute a static type and therefore discard
+ // the propagated type. So a new test was created that doesn't run under
+ // strong mode.
+ resolveTestUnit(r'''
+abstract class Iter {
+ List/*<S>*/ map/*<S>*/(/*=S*/ f(x));
+}
+class C {}
+C toSpan(dynamic element) {
+ if (element is Iter) {
+ var y = element.map(toSpan);
+ }
+ return null;
+}''');
+ expectIdentifierType('y = ', 'List<C>', isNull);
+ }
+
+ void test_genericMethod_tearoff() {
+ resolveTestUnit(r'''
+class C<E> {
+ /*=T*/ f/*<T>*/(E e) => null;
+ static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+ static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+ var c = new C<int>();
+ /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+ var methodTearOff = c.f;
+ var staticTearOff = C.g;
+ var staticFieldTearOff = C.h;
+ var topFunTearOff = topF;
+ var topFieldTearOff = topG;
+ var localTearOff = lf;
+ var paramTearOff = pf;
+}
+''');
+ expectIdentifierType('methodTearOff', "<T>(int) → T");
+ expectIdentifierType('staticTearOff', "<T>(T) → T");
+ expectIdentifierType('staticFieldTearOff', "<T>(T) → T");
+ expectIdentifierType('topFunTearOff', "<T>(T) → T");
+ expectIdentifierType('topFieldTearOff', "<T>(T) → T");
+ expectIdentifierType('localTearOff', "<T>(T) → T");
+ expectIdentifierType('paramTearOff', "<T>(T) → T");
+ }
+
+ void test_genericMethod_then() {
+ String code = r'''
+import 'dart:async';
+String toString(int x) => x.toString();
+main() {
+ Future<int> bar = null;
+ var foo = bar.then(toString);
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'Future<String>', isNull);
+ }
+
+ void test_genericMethod_then_prefixed() {
+ String code = r'''
+import 'dart:async' as async;
+String toString(int x) => x.toString();
+main() {
+ async.Future<int> bar = null;
+ var foo = bar.then(toString);
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'Future<String>', isNull);
+ }
+
+ void test_genericMethod_then_propagatedType() {
+ // Regression test for https://github.com/dart-lang/sdk/issues/25482.
+ String code = r'''
+import 'dart:async';
+void main() {
+ Future<String> p;
+ var foo = p.then((r) => new Future<String>.value(3));
+}
+''';
+ // This should produce no hints or warnings.
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'Future<String>', isNull);
+ }
+
+ void test_implicitBounds() {
+ String code = r'''
+class A<T> {}
+
+class B<T extends num> {}
+
+class C<S extends int, T extends B<S>, U extends B> {}
+
+void test() {
+//
+ A ai;
+ B bi;
+ C ci;
+ var aa = new A();
+ var bb = new B();
+ var cc = new C();
+}
+''';
+ resolveTestUnit(code);
+ expectIdentifierType('ai', "A<dynamic>");
+ expectIdentifierType('bi', "B<num>");
+ expectIdentifierType('ci', "C<int, B<int>, B<num>>");
+ expectIdentifierType('aa', "A<dynamic>");
+ expectIdentifierType('bb', "B<num>");
+ expectIdentifierType('cc', "C<int, B<int>, B<num>>");
+ }
+
+ void test_setterWithDynamicTypeIsError() {
+ Source source = addSource(r'''
+class A {
+ dynamic set f(String s) => null;
+}
+dynamic set g(int x) => null;
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
+ StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
+ ]);
+ verify([source]);
+ }
+
+ void test_setterWithExplicitVoidType_returningVoid() {
+ Source source = addSource(r'''
+void returnsVoid() {}
+class A {
+ void set f(String s) => returnsVoid();
+}
+void set g(int x) => returnsVoid();
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_setterWithNoVoidType() {
+ Source source = addSource(r'''
+class A {
+ set f(String s) {
+ return '42';
+ }
+}
+set g(int x) => 42;
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+ StaticTypeWarningCode.RETURN_OF_INVALID_TYPE
+ ]);
+ verify([source]);
+ }
+
+ void test_setterWithNoVoidType_returningVoid() {
+ Source source = addSource(r'''
+void returnsVoid() {}
+class A {
+ set f(String s) => returnsVoid();
+}
+set g(int x) => returnsVoid();
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_setterWithOtherTypeIsError() {
+ Source source = addSource(r'''
+class A {
+ String set f(String s) => null;
+}
+Object set g(x) => null;
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [
+ StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
+ StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
+ ]);
+ verify([source]);
+ }
+
+ void test_ternaryOperator_null_left() {
+ String code = r'''
+main() {
+ var foo = (true) ? null : 3;
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'int', isNull);
+ }
+
+ void test_ternaryOperator_null_right() {
+ String code = r'''
+main() {
+ var foo = (true) ? 3 : null;
+}
+''';
+ resolveTestUnit(code);
+ expectInitializerType('foo', 'int', isNull);
+ }
+}
+
+@reflectiveTest
+class StrongModeTypePropagationTest extends ResolverTestCase {
+ @override
+ void setUp() {
+ super.setUp();
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.strongMode = true;
+ resetWithOptions(options);
+ }
+
+ void test_foreachInference_dynamic_disabled() {
+ String code = r'''
+main() {
+ var list = <int>[];
+ for (dynamic v in list) {
+ v; // marker
+ }
+}''';
+ assertPropagatedIterationType(
+ code, typeProvider.dynamicType, typeProvider.intType);
+ assertTypeOfMarkedExpression(
+ code, typeProvider.dynamicType, typeProvider.intType);
+ }
+
+ void test_foreachInference_reusedVar_disabled() {
+ String code = r'''
+main() {
+ var list = <int>[];
+ var v;
+ for (v in list) {
+ v; // marker
+ }
+}''';
+ assertPropagatedIterationType(
+ code, typeProvider.dynamicType, typeProvider.intType);
+ assertTypeOfMarkedExpression(
+ code, typeProvider.dynamicType, typeProvider.intType);
+ }
+
+ void test_foreachInference_var() {
+ String code = r'''
+main() {
+ var list = <int>[];
+ for (var v in list) {
+ v; // marker
+ }
+}''';
+ assertPropagatedIterationType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_foreachInference_var_iterable() {
+ String code = r'''
+main() {
+ Iterable<int> list = <int>[];
+ for (var v in list) {
+ v; // marker
+ }
+}''';
+ assertPropagatedIterationType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_foreachInference_var_stream() {
+ String code = r'''
+import 'dart:async';
+main() async {
+ Stream<int> stream = null;
+ await for (var v in stream) {
+ v; // marker
+ }
+}''';
+ assertPropagatedIterationType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_bottom_disabled() {
+ String code = r'''
+main() {
+ var v = null;
+ v; // marker
+}''';
+ assertPropagatedAssignedType(code, typeProvider.dynamicType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null);
+ }
+
+ void test_localVariableInference_constant() {
+ String code = r'''
+main() {
+ var v = 3;
+ v; // marker
+}''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_declaredType_disabled() {
+ String code = r'''
+main() {
+ dynamic v = 3;
+ v; // marker
+}''';
+ assertPropagatedAssignedType(
+ code, typeProvider.dynamicType, typeProvider.intType);
+ assertTypeOfMarkedExpression(
+ code, typeProvider.dynamicType, typeProvider.intType);
+ }
+
+ void test_localVariableInference_noInitializer_disabled() {
+ String code = r'''
+main() {
+ var v;
+ v = 3;
+ v; // marker
+}''';
+ assertPropagatedAssignedType(
+ code, typeProvider.dynamicType, typeProvider.intType);
+ assertTypeOfMarkedExpression(
+ code, typeProvider.dynamicType, typeProvider.intType);
+ }
+
+ void test_localVariableInference_transitive_field_inferred_lexical() {
+ String code = r'''
+class A {
+ final x = 3;
+ f() {
+ var v = x;
+ return v; // marker
+ }
+}
+main() {
+}
+''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_transitive_field_inferred_reversed() {
+ String code = r'''
+class A {
+ f() {
+ var v = x;
+ return v; // marker
+ }
+ final x = 3;
+}
+main() {
+}
+''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_transitive_field_lexical() {
+ String code = r'''
+class A {
+ int x = 3;
+ f() {
+ var v = x;
+ return v; // marker
+ }
+}
+main() {
+}
+''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_transitive_field_reversed() {
+ String code = r'''
+class A {
+ f() {
+ var v = x;
+ return v; // marker
+ }
+ int x = 3;
+}
+main() {
+}
+''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_transitive_list_local() {
+ String code = r'''
+main() {
+ var x = <int>[3];
+ var v = x[0];
+ v; // marker
+}''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_transitive_local() {
+ String code = r'''
+main() {
+ var x = 3;
+ var v = x;
+ v; // marker
+}''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_transitive_toplevel_inferred_lexical() {
+ String code = r'''
+final x = 3;
+main() {
+ var v = x;
+ v; // marker
+}
+''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_transitive_toplevel_inferred_reversed() {
+ String code = r'''
+main() {
+ var v = x;
+ v; // marker
+}
+final x = 3;
+''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_transitive_toplevel_lexical() {
+ String code = r'''
+int x = 3;
+main() {
+ var v = x;
+ v; // marker
+}
+''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+
+ void test_localVariableInference_transitive_toplevel_reversed() {
+ String code = r'''
+main() {
+ var v = x;
+ v; // marker
+}
+int x = 3;
+''';
+ assertPropagatedAssignedType(code, typeProvider.intType, null);
+ assertTypeOfMarkedExpression(code, typeProvider.intType, null);
+ }
+}
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 239c42b..803ff8c 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -19,7 +19,7 @@
import 'package:plugin/plugin.dart';
import 'package:unittest/unittest.dart';
-import 'resolver_test.dart';
+import 'analysis_context_factory.dart';
/**
* The class `EngineTestCase` defines utility methods for making assertions.
diff --git a/pkg/analyzer/test/resource_utils.dart b/pkg/analyzer/test/resource_utils.dart
new file mode 100644
index 0000000..fdf1e5a
--- /dev/null
+++ b/pkg/analyzer/test/resource_utils.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.resource_utils;
+
+import 'dart:core' hide Resource;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/util/absolute_path.dart';
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+
+bool get isWindows => path.Style.platform == path.Style.windows;
+
+/**
+ * Assert that the given path is posix and absolute.
+ */
+void expectAbsolutePosixPath(String posixPath) {
+ expect(posixPath, startsWith('/'),
+ reason: 'Expected absolute posix path, but found $posixPath');
+}
+
+/**
+ * Assert that the given path is posix.
+ */
+void expectPosixPath(String posixPath) {
+ expect(posixPath.indexOf('\\'), -1,
+ reason: 'Expected posix path, but found $posixPath');
+}
+
+/**
+ * Translate the given posixPath to a path appropriate for the
+ * platform on which the tests are executing.
+ */
+String posixToOSPath(String posixPath) {
+ expectPosixPath(posixPath);
+ if (isWindows) {
+ String windowsPath = posixPath.replaceAll('/', '\\');
+ if (posixPath.startsWith('/')) {
+ return 'C:$windowsPath';
+ }
+ return windowsPath;
+ }
+ return posixPath;
+}
+
+/**
+ * Translate the given posixPath to a file URI appropriate for the
+ * platform on which the tests are executing.
+ */
+String posixToOSFileUri(String posixPath) {
+ expectPosixPath(posixPath);
+ return isWindows ? 'file:///C:$posixPath' : 'file://$posixPath';
+}
+
+/**
+ * A convenience utility for setting up a test [MemoryResourceProvider].
+ * All supplied paths are assumed to be in [path.posix] format
+ * and are automatically translated to [path.context].
+ *
+ * This class intentionally does not implement [ResourceProvider]
+ * directly or indirectly so that it cannot be used as a resource provider.
+ * We do not want functionality under test to interact with a resource provider
+ * that automatically translates paths.
+ */
+class TestPathTranslator {
+ final MemoryResourceProvider _provider;
+
+ TestPathTranslator(this._provider);
+
+ Resource getResource(String posixPath) =>
+ _provider.getResource(posixToOSPath(posixPath));
+
+ File newFile(String posixPath, String content) =>
+ _provider.newFile(posixToOSPath(posixPath), content);
+
+ Folder newFolder(String posixPath) =>
+ _provider.newFolder(posixToOSPath(posixPath));
+}
+
+/**
+ * A resource provider for testing that asserts that any supplied paths
+ * are appropriate for the OS platform on which the tests are running.
+ */
+class TestResourceProvider implements ResourceProvider {
+ final ResourceProvider _provider;
+
+ TestResourceProvider(this._provider) {
+ expect(_provider.absolutePathContext.separator, isWindows ? '\\' : '/');
+ }
+
+ @override
+ AbsolutePathContext get absolutePathContext => _provider.absolutePathContext;
+
+ @override
+ File getFile(String path) => _provider.getFile(_assertPath(path));
+
+ @override
+ Folder getFolder(String path) => _provider.getFolder(_assertPath(path));
+
+ @override
+ Resource getResource(String path) => _provider.getResource(_assertPath(path));
+
+ @override
+ Folder getStateLocation(String pluginId) =>
+ _provider.getStateLocation(pluginId);
+
+ @override
+ path.Context get pathContext => _provider.pathContext;
+
+ /**
+ * Assert that the given path is valid for the OS platform on which the
+ * tests are running.
+ */
+ String _assertPath(String path) {
+ if (isWindows) {
+ if (path.contains('/')) {
+ fail('Expected windows path, but found: $path');
+ }
+ } else {
+ if (path.contains('\\')) {
+ fail('Expected posix path, but found: $path');
+ }
+ }
+ return path;
+ }
+}
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index d71304b..0b00a6d 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -4,16 +4,15 @@
library analyzer.test.source.analysis_options_provider_test;
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:unittest/unittest.dart';
import 'package:yaml/yaml.dart';
-import '../utils.dart';
+import '../resource_utils.dart';
main() {
- initializeTestEnvironment();
-
group('AnalysisOptionsProvider', () {
void expectMergesTo(String defaults, String overrides, String expected) {
var optionsProvider = new AnalysisOptionsProvider();
@@ -77,7 +76,7 @@
test('test_simple', () {
var optionsProvider = new AnalysisOptionsProvider();
Map<String, YamlNode> options =
- optionsProvider.getOptions(resourceProvider.getFolder('/'));
+ optionsProvider.getOptions(pathTranslator.getResource('/'));
expect(options, hasLength(1));
expect(options['analyzer'], isNotNull);
YamlMap analyzer = options['analyzer'];
@@ -91,7 +90,7 @@
test('test_doesnotexist', () {
var optionsProvider = new AnalysisOptionsProvider();
Map<String, YamlNode> options =
- optionsProvider.getOptions(resourceProvider.getFolder('/empty'));
+ optionsProvider.getOptions(pathTranslator.getResource('/empty'));
expect(options, isEmpty);
});
});
@@ -105,7 +104,7 @@
test('test_empty', () {
var optionsProvider = new AnalysisOptionsProvider();
Map<String, YamlNode> options =
- optionsProvider.getOptions(resourceProvider.getFolder('/'));
+ optionsProvider.getOptions(pathTranslator.getResource('/'));
expect(options, isNotNull);
});
});
@@ -121,7 +120,7 @@
bool exceptionCaught = false;
try {
Map<String, YamlNode> options =
- optionsProvider.getOptions(resourceProvider.getFolder('/'));
+ optionsProvider.getOptions(pathTranslator.getResource('/'));
expect(options, isNotNull);
} catch (e) {
exceptionCaught = true;
@@ -156,19 +155,22 @@
});
}
-MemoryResourceProvider resourceProvider;
+ResourceProvider resourceProvider;
+TestPathTranslator pathTranslator;
buildResourceProvider(
{bool emptyAnalysisOptions: false, bool badAnalysisOptions: false}) {
- resourceProvider = new MemoryResourceProvider();
- resourceProvider.newFolder('/empty');
- resourceProvider.newFolder('/tmp');
+ var rawProvider = new MemoryResourceProvider(isWindows: isWindows);
+ resourceProvider = new TestResourceProvider(rawProvider);
+ pathTranslator = new TestPathTranslator(rawProvider)
+ ..newFolder('/empty')
+ ..newFolder('/tmp');
if (badAnalysisOptions) {
- resourceProvider.newFile('/.analysis_options', r''':''');
+ pathTranslator.newFile('/.analysis_options', r''':''');
} else if (emptyAnalysisOptions) {
- resourceProvider.newFile('/.analysis_options', r'''#empty''');
+ pathTranslator.newFile('/.analysis_options', r'''#empty''');
} else {
- resourceProvider.newFile(
+ pathTranslator.newFile(
'/.analysis_options',
r'''
analyzer:
@@ -182,7 +184,3 @@
clearResourceProvider() {
resourceProvider = null;
}
-
-emptyResourceProvider() {
- resourceProvider = new MemoryResourceProvider();
-}
diff --git a/pkg/analyzer/test/source/embedder_test.dart b/pkg/analyzer/test/source/embedder_test.dart
index eecb818..448fdb0 100644
--- a/pkg/analyzer/test/source/embedder_test.dart
+++ b/pkg/analyzer/test/source/embedder_test.dart
@@ -10,10 +10,10 @@
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/embedder.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/util/absolute_path.dart';
import 'package:path/path.dart' as path;
import 'package:unittest/unittest.dart';
+import '../resource_utils.dart';
import '../utils.dart';
main() {
@@ -163,115 +163,3 @@
resourceProvider = null;
pathTranslator = null;
}
-
-// TODO(danrubel) if this approach works well for running tests
-// in a platform specific way, then move all of the following functionality
-// into a separate test utility library.
-
-bool get isWindows => path.Style.platform == path.Style.windows;
-
-/**
- * Assert that the given path is posix.
- */
-void expectAbsolutePosixPath(String posixPath) {
- expect(posixPath, startsWith('/'),
- reason: 'Expected absolute posix path, but found $posixPath');
-}
-
-/**
- * Translate the given posixPath to a path appropriate for the
- * platform on which the tests are executing.
- */
-String posixToOSPath(String posixPath) {
- expectAbsolutePosixPath(posixPath);
- if (isWindows) {
- String windowsPath = posixPath.replaceAll('/', '\\');
- if (posixPath.startsWith('/')) {
- return 'C:$windowsPath';
- }
- return windowsPath;
- }
- return posixPath;
-}
-
-/**
- * Translate the given posixPath to a file URI appropriate for the
- * platform on which the tests are executing.
- */
-String posixToOSFileUri(String posixPath) {
- expectAbsolutePosixPath(posixPath);
- return isWindows ? 'file:///C:$posixPath' : 'file://$posixPath';
-}
-
-/**
- * A convenience utility for setting up a test [MemoryResourceProvider].
- * All supplied paths are assumed to be in [path.posix] format
- * and are automatically translated to [path.context].
- *
- * This class intentionally does not implement [ResourceProvider]
- * directly or indirectly so that it cannot be used as a resource provider.
- * We do not want functionality under test to interact with a resource provider
- * that automatically translates paths.
- */
-class TestPathTranslator {
- final MemoryResourceProvider _provider;
-
- TestPathTranslator(this._provider);
-
- Resource getResource(String posixPath) =>
- _provider.getResource(posixToOSPath(posixPath));
-
- File newFile(String posixPath, String content) =>
- _provider.newFile(posixToOSPath(posixPath), content);
-
- Folder newFolder(String posixPath) =>
- _provider.newFolder(posixToOSPath(posixPath));
-}
-
-/**
- * A resource provider for testing that asserts that any supplied paths
- * are appropriate for the OS platform on which the tests are running.
- */
-class TestResourceProvider implements ResourceProvider {
- final ResourceProvider _provider;
-
- TestResourceProvider(this._provider) {
- expect(_provider.absolutePathContext.separator, isWindows ? '\\' : '/');
- }
-
- @override
- AbsolutePathContext get absolutePathContext => _provider.absolutePathContext;
-
- @override
- File getFile(String path) => _provider.getFile(_assertPath(path));
-
- @override
- Folder getFolder(String path) => _provider.getFolder(_assertPath(path));
-
- @override
- Resource getResource(String path) => _provider.getResource(_assertPath(path));
-
- @override
- Folder getStateLocation(String pluginId) =>
- _provider.getStateLocation(pluginId);
-
- @override
- path.Context get pathContext => _provider.pathContext;
-
- /**
- * Assert that the given path is valid for the OS platform on which the
- * tests are running.
- */
- String _assertPath(String path) {
- if (isWindows) {
- if (path.contains('/')) {
- fail('Expected windows path, but found: $path');
- }
- } else {
- if (path.contains('\\')) {
- fail('Expected posix path, but found: $path');
- }
- }
- return path;
- }
-}
diff --git a/pkg/analyzer/test/source/error_processor_test.dart b/pkg/analyzer/test/source/error_processor_test.dart
index 3c3facb..864bbf8 100644
--- a/pkg/analyzer/test/source/error_processor_test.dart
+++ b/pkg/analyzer/test/source/error_processor_test.dart
@@ -16,7 +16,6 @@
import 'package:yaml/src/yaml_node.dart';
import '../generated/test_support.dart';
-import '../utils.dart';
main() {
AnalysisError invalid_assignment =
@@ -40,14 +39,13 @@
['x']
]);
- initializeTestEnvironment();
oneTimeSetup();
setUp(() {
context = new TestContext();
});
- group('ErrorProcessorTest', () {
+ group('ErrorProcessor', () {
test('configureOptions', () {
configureOptions('''
analyzer:
@@ -62,9 +60,17 @@
expect(getProcessor(unused_local_variable), isNull);
expect(getProcessor(use_of_void_result), isNull);
});
+
+ test('upgrades static type warnings to errors in strong mode', () {
+ configureOptions('''
+analyzer:
+ strong-mode: true
+''');
+ expect(getProcessor(invalid_assignment).severity, ErrorSeverity.ERROR);
+ });
});
- group('ErrorConfigTest', () {
+ group('ErrorConfig', () {
var config = '''
analyzer:
errors:
diff --git a/pkg/analyzer/test/src/abstract_single_unit.dart b/pkg/analyzer/test/src/abstract_single_unit.dart
index 48ba251..1955d6e 100644
--- a/pkg/analyzer/test/src/abstract_single_unit.dart
+++ b/pkg/analyzer/test/src/abstract_single_unit.dart
@@ -4,8 +4,9 @@
library test.services.src.index.abstract_single_file;
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index 5466949..715ad1c 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -151,18 +151,19 @@
/*=R*/ combine(/*=R*/ previousValue, E element));
}
-abstract class List<E> implements Iterable<E> {
- void add(E value);
- E operator [](int index);
- void operator []=(int index, E value);
+class List<E> implements Iterable<E> {
+ List();
+ void add(E value) {}
+ E operator [](int index) => null;
+ void operator []=(int index, E value) {}
Iterator<E> get iterator => null;
- void clear();
+ void clear() {}
}
-abstract class Map<K, V> extends Object {
- Iterable<K> get keys;
- V operator [](K key);
- void operator []=(K key, V value);
+class Map<K, V> extends Object {
+ Iterable<K> get keys => null;
+ V operator [](K key) => null;
+ void operator []=(K key, V value) {}
}
external bool identical(Object a, Object b);
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index f3a0e4c..77a68eb 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -6,11 +6,15 @@
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/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart' show Predicate;
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:unittest/unittest.dart';
@@ -24,6 +28,7 @@
runReflectiveTests(ConstantEvaluatorTest);
runReflectiveTests(NodeLocatorTest);
runReflectiveTests(NodeLocator2Test);
+ runReflectiveTests(ResolutionCopierTest);
runReflectiveTests(ToSourceVisitorTest);
}
@@ -428,6 +433,663 @@
}
@reflectiveTest
+class ResolutionCopierTest extends EngineTestCase {
+ void test_visitAdjacentStrings() {
+ AdjacentStrings createNode() => new AdjacentStrings([
+ new SimpleStringLiteral(null, 'hello'),
+ new SimpleStringLiteral(null, 'world')
+ ]);
+
+ AdjacentStrings fromNode = createNode();
+ DartType propagatedType = ElementFactory.classElement2("A").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("B").type;
+ fromNode.staticType = staticType;
+
+ AdjacentStrings toNode = createNode();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitAnnotation() {
+ String annotationName = "proxy";
+ Annotation fromNode =
+ AstFactory.annotation(AstFactory.identifier3(annotationName));
+ Element element = ElementFactory.topLevelVariableElement2(annotationName);
+ fromNode.element = element;
+ Annotation toNode =
+ AstFactory.annotation(AstFactory.identifier3(annotationName));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.element, same(element));
+ }
+
+ void test_visitAsExpression() {
+ AsExpression fromNode = AstFactory.asExpression(
+ AstFactory.identifier3("x"), AstFactory.typeName4("A"));
+ DartType propagatedType = ElementFactory.classElement2("A").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("B").type;
+ fromNode.staticType = staticType;
+ AsExpression toNode = AstFactory.asExpression(
+ AstFactory.identifier3("x"), AstFactory.typeName4("A"));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitAssignmentExpression() {
+ AssignmentExpression fromNode = AstFactory.assignmentExpression(
+ AstFactory.identifier3("a"),
+ TokenType.PLUS_EQ,
+ AstFactory.identifier3("b"));
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ MethodElement propagatedElement =
+ ElementFactory.methodElement("+", propagatedType);
+ fromNode.propagatedElement = propagatedElement;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ MethodElement staticElement = ElementFactory.methodElement("+", staticType);
+ fromNode.staticElement = staticElement;
+ fromNode.staticType = staticType;
+ AssignmentExpression toNode = AstFactory.assignmentExpression(
+ AstFactory.identifier3("a"),
+ TokenType.PLUS_EQ,
+ AstFactory.identifier3("b"));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedElement, same(propagatedElement));
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticElement, same(staticElement));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitBinaryExpression() {
+ BinaryExpression fromNode = AstFactory.binaryExpression(
+ AstFactory.identifier3("a"),
+ TokenType.PLUS,
+ AstFactory.identifier3("b"));
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ MethodElement propagatedElement =
+ ElementFactory.methodElement("+", propagatedType);
+ fromNode.propagatedElement = propagatedElement;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ MethodElement staticElement = ElementFactory.methodElement("+", staticType);
+ fromNode.staticElement = staticElement;
+ fromNode.staticType = staticType;
+ BinaryExpression toNode = AstFactory.binaryExpression(
+ AstFactory.identifier3("a"),
+ TokenType.PLUS,
+ AstFactory.identifier3("b"));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedElement, same(propagatedElement));
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticElement, same(staticElement));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitBooleanLiteral() {
+ BooleanLiteral fromNode = AstFactory.booleanLiteral(true);
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ BooleanLiteral toNode = AstFactory.booleanLiteral(true);
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitCascadeExpression() {
+ CascadeExpression fromNode = AstFactory.cascadeExpression(
+ AstFactory.identifier3("a"), [AstFactory.identifier3("b")]);
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ CascadeExpression toNode = AstFactory.cascadeExpression(
+ AstFactory.identifier3("a"), [AstFactory.identifier3("b")]);
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitCompilationUnit() {
+ CompilationUnit fromNode = AstFactory.compilationUnit();
+ CompilationUnitElement element =
+ new CompilationUnitElementImpl("test.dart");
+ fromNode.element = element;
+ CompilationUnit toNode = AstFactory.compilationUnit();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.element, same(element));
+ }
+
+ void test_visitConditionalExpression() {
+ ConditionalExpression fromNode = AstFactory.conditionalExpression(
+ AstFactory.identifier3("c"),
+ AstFactory.identifier3("a"),
+ AstFactory.identifier3("b"));
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ ConditionalExpression toNode = AstFactory.conditionalExpression(
+ AstFactory.identifier3("c"),
+ AstFactory.identifier3("a"),
+ AstFactory.identifier3("b"));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitConstructorDeclaration() {
+ String className = "A";
+ String constructorName = "c";
+ ConstructorDeclaration fromNode = AstFactory.constructorDeclaration(
+ AstFactory.identifier3(className),
+ constructorName,
+ AstFactory.formalParameterList(),
+ null);
+ ConstructorElement element = ElementFactory.constructorElement2(
+ ElementFactory.classElement2(className), constructorName);
+ fromNode.element = element;
+ ConstructorDeclaration toNode = AstFactory.constructorDeclaration(
+ AstFactory.identifier3(className),
+ constructorName,
+ AstFactory.formalParameterList(),
+ null);
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.element, same(element));
+ }
+
+ void test_visitConstructorName() {
+ ConstructorName fromNode =
+ AstFactory.constructorName(AstFactory.typeName4("A"), "c");
+ ConstructorElement staticElement = ElementFactory.constructorElement2(
+ ElementFactory.classElement2("A"), "c");
+ fromNode.staticElement = staticElement;
+ ConstructorName toNode =
+ AstFactory.constructorName(AstFactory.typeName4("A"), "c");
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.staticElement, same(staticElement));
+ }
+
+ void test_visitDoubleLiteral() {
+ DoubleLiteral fromNode = AstFactory.doubleLiteral(1.0);
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ DoubleLiteral toNode = AstFactory.doubleLiteral(1.0);
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitExportDirective() {
+ ExportDirective fromNode = AstFactory.exportDirective2("dart:uri");
+ ExportElement element = new ExportElementImpl(-1);
+ fromNode.element = element;
+ ExportDirective toNode = AstFactory.exportDirective2("dart:uri");
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.element, same(element));
+ }
+
+ void test_visitFunctionExpression() {
+ FunctionExpression fromNode = AstFactory.functionExpression2(
+ AstFactory.formalParameterList(), AstFactory.emptyFunctionBody());
+ MethodElement element = ElementFactory.methodElement(
+ "m", ElementFactory.classElement2("C").type);
+ fromNode.element = element;
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ FunctionExpression toNode = AstFactory.functionExpression2(
+ AstFactory.formalParameterList(), AstFactory.emptyFunctionBody());
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.element, same(element));
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitFunctionExpressionInvocation() {
+ FunctionExpressionInvocation fromNode =
+ AstFactory.functionExpressionInvocation(AstFactory.identifier3("f"));
+ MethodElement propagatedElement = ElementFactory.methodElement(
+ "m", ElementFactory.classElement2("C").type);
+ fromNode.propagatedElement = propagatedElement;
+ MethodElement staticElement = ElementFactory.methodElement(
+ "m", ElementFactory.classElement2("C").type);
+ fromNode.staticElement = staticElement;
+ FunctionExpressionInvocation toNode =
+ AstFactory.functionExpressionInvocation(AstFactory.identifier3("f"));
+
+ _copyAndVerifyInvocation(fromNode, toNode);
+
+ expect(toNode.propagatedElement, same(propagatedElement));
+ expect(toNode.staticElement, same(staticElement));
+ }
+
+ void test_visitImportDirective() {
+ ImportDirective fromNode = AstFactory.importDirective3("dart:uri", null);
+ ImportElement element = new ImportElementImpl(0);
+ fromNode.element = element;
+ ImportDirective toNode = AstFactory.importDirective3("dart:uri", null);
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.element, same(element));
+ }
+
+ void test_visitIndexExpression() {
+ IndexExpression fromNode = AstFactory.indexExpression(
+ AstFactory.identifier3("a"), AstFactory.integer(0));
+ MethodElement propagatedElement = ElementFactory.methodElement(
+ "m", ElementFactory.classElement2("C").type);
+ MethodElement staticElement = ElementFactory.methodElement(
+ "m", ElementFactory.classElement2("C").type);
+ AuxiliaryElements auxiliaryElements =
+ new AuxiliaryElements(staticElement, propagatedElement);
+ fromNode.auxiliaryElements = auxiliaryElements;
+ fromNode.propagatedElement = propagatedElement;
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ fromNode.staticElement = staticElement;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ IndexExpression toNode = AstFactory.indexExpression(
+ AstFactory.identifier3("a"), AstFactory.integer(0));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.auxiliaryElements, same(auxiliaryElements));
+ expect(toNode.propagatedElement, same(propagatedElement));
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticElement, same(staticElement));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitInstanceCreationExpression() {
+ InstanceCreationExpression fromNode = AstFactory
+ .instanceCreationExpression2(Keyword.NEW, AstFactory.typeName4("C"));
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ ConstructorElement staticElement = ElementFactory.constructorElement2(
+ ElementFactory.classElement2("C"), null);
+ fromNode.staticElement = staticElement;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ InstanceCreationExpression toNode = AstFactory.instanceCreationExpression2(
+ Keyword.NEW, AstFactory.typeName4("C"));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticElement, same(staticElement));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitIntegerLiteral() {
+ IntegerLiteral fromNode = AstFactory.integer(2);
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ IntegerLiteral toNode = AstFactory.integer(2);
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitIsExpression() {
+ IsExpression fromNode = AstFactory.isExpression(
+ AstFactory.identifier3("x"), false, AstFactory.typeName4("A"));
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ IsExpression toNode = AstFactory.isExpression(
+ AstFactory.identifier3("x"), false, AstFactory.typeName4("A"));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitLibraryIdentifier() {
+ LibraryIdentifier fromNode =
+ AstFactory.libraryIdentifier([AstFactory.identifier3("lib")]);
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ LibraryIdentifier toNode =
+ AstFactory.libraryIdentifier([AstFactory.identifier3("lib")]);
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitListLiteral() {
+ ListLiteral fromNode = AstFactory.listLiteral();
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ ListLiteral toNode = AstFactory.listLiteral();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitMapLiteral() {
+ MapLiteral fromNode = AstFactory.mapLiteral2();
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ MapLiteral toNode = AstFactory.mapLiteral2();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitMethodInvocation() {
+ MethodInvocation fromNode = AstFactory.methodInvocation2("m");
+ MethodInvocation toNode = AstFactory.methodInvocation2("m");
+ _copyAndVerifyInvocation(fromNode, toNode);
+ }
+
+ void test_visitNamedExpression() {
+ NamedExpression fromNode =
+ AstFactory.namedExpression2("n", AstFactory.integer(0));
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ NamedExpression toNode =
+ AstFactory.namedExpression2("n", AstFactory.integer(0));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitNullLiteral() {
+ NullLiteral fromNode = AstFactory.nullLiteral();
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ NullLiteral toNode = AstFactory.nullLiteral();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitParenthesizedExpression() {
+ ParenthesizedExpression fromNode =
+ AstFactory.parenthesizedExpression(AstFactory.integer(0));
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ ParenthesizedExpression toNode =
+ AstFactory.parenthesizedExpression(AstFactory.integer(0));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitPartDirective() {
+ PartDirective fromNode = AstFactory.partDirective2("part.dart");
+ LibraryElement element = new LibraryElementImpl.forNode(
+ null, AstFactory.libraryIdentifier2(["lib"]));
+ fromNode.element = element;
+ PartDirective toNode = AstFactory.partDirective2("part.dart");
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.element, same(element));
+ }
+
+ void test_visitPartOfDirective() {
+ PartOfDirective fromNode =
+ AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["lib"]));
+ LibraryElement element = new LibraryElementImpl.forNode(
+ null, AstFactory.libraryIdentifier2(["lib"]));
+ fromNode.element = element;
+ PartOfDirective toNode =
+ AstFactory.partOfDirective(AstFactory.libraryIdentifier2(["lib"]));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.element, same(element));
+ }
+
+ void test_visitPostfixExpression() {
+ String variableName = "x";
+ PostfixExpression fromNode = AstFactory.postfixExpression(
+ AstFactory.identifier3(variableName), TokenType.PLUS_PLUS);
+ MethodElement propagatedElement = ElementFactory.methodElement(
+ "+", ElementFactory.classElement2("C").type);
+ fromNode.propagatedElement = propagatedElement;
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ MethodElement staticElement = ElementFactory.methodElement(
+ "+", ElementFactory.classElement2("C").type);
+ fromNode.staticElement = staticElement;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ PostfixExpression toNode = AstFactory.postfixExpression(
+ AstFactory.identifier3(variableName), TokenType.PLUS_PLUS);
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedElement, same(propagatedElement));
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticElement, same(staticElement));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitPrefixedIdentifier() {
+ PrefixedIdentifier fromNode = AstFactory.identifier5("p", "f");
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ PrefixedIdentifier toNode = AstFactory.identifier5("p", "f");
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitPrefixExpression() {
+ PrefixExpression fromNode = AstFactory.prefixExpression(
+ TokenType.PLUS_PLUS, AstFactory.identifier3("x"));
+ MethodElement propagatedElement = ElementFactory.methodElement(
+ "+", ElementFactory.classElement2("C").type);
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedElement = propagatedElement;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ MethodElement staticElement = ElementFactory.methodElement(
+ "+", ElementFactory.classElement2("C").type);
+ fromNode.staticElement = staticElement;
+ fromNode.staticType = staticType;
+ PrefixExpression toNode = AstFactory.prefixExpression(
+ TokenType.PLUS_PLUS, AstFactory.identifier3("x"));
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedElement, same(propagatedElement));
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticElement, same(staticElement));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitPropertyAccess() {
+ PropertyAccess fromNode =
+ AstFactory.propertyAccess2(AstFactory.identifier3("x"), "y");
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ PropertyAccess toNode =
+ AstFactory.propertyAccess2(AstFactory.identifier3("x"), "y");
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitRedirectingConstructorInvocation() {
+ RedirectingConstructorInvocation fromNode =
+ AstFactory.redirectingConstructorInvocation();
+ ConstructorElement staticElement = ElementFactory.constructorElement2(
+ ElementFactory.classElement2("C"), null);
+ fromNode.staticElement = staticElement;
+ RedirectingConstructorInvocation toNode =
+ AstFactory.redirectingConstructorInvocation();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.staticElement, same(staticElement));
+ }
+
+ void test_visitRethrowExpression() {
+ RethrowExpression fromNode = AstFactory.rethrowExpression();
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ RethrowExpression toNode = AstFactory.rethrowExpression();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitSimpleIdentifier() {
+ SimpleIdentifier fromNode = AstFactory.identifier3("x");
+ MethodElement propagatedElement = ElementFactory.methodElement(
+ "m", ElementFactory.classElement2("C").type);
+ MethodElement staticElement = ElementFactory.methodElement(
+ "m", ElementFactory.classElement2("C").type);
+ AuxiliaryElements auxiliaryElements =
+ new AuxiliaryElements(staticElement, propagatedElement);
+ fromNode.auxiliaryElements = auxiliaryElements;
+ fromNode.propagatedElement = propagatedElement;
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ fromNode.staticElement = staticElement;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ SimpleIdentifier toNode = AstFactory.identifier3("x");
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.auxiliaryElements, same(auxiliaryElements));
+ expect(toNode.propagatedElement, same(propagatedElement));
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticElement, same(staticElement));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitSimpleStringLiteral() {
+ SimpleStringLiteral fromNode = AstFactory.string2("abc");
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ SimpleStringLiteral toNode = AstFactory.string2("abc");
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitStringInterpolation() {
+ StringInterpolation fromNode =
+ AstFactory.string([AstFactory.interpolationString("a", "'a'")]);
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ StringInterpolation toNode =
+ AstFactory.string([AstFactory.interpolationString("a", "'a'")]);
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitSuperConstructorInvocation() {
+ SuperConstructorInvocation fromNode =
+ AstFactory.superConstructorInvocation();
+ ConstructorElement staticElement = ElementFactory.constructorElement2(
+ ElementFactory.classElement2("C"), null);
+ fromNode.staticElement = staticElement;
+ SuperConstructorInvocation toNode = AstFactory.superConstructorInvocation();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.staticElement, same(staticElement));
+ }
+
+ void test_visitSuperExpression() {
+ SuperExpression fromNode = AstFactory.superExpression();
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ SuperExpression toNode = AstFactory.superExpression();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitSymbolLiteral() {
+ SymbolLiteral fromNode = AstFactory.symbolLiteral(["s"]);
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ SymbolLiteral toNode = AstFactory.symbolLiteral(["s"]);
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitThisExpression() {
+ ThisExpression fromNode = AstFactory.thisExpression();
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ ThisExpression toNode = AstFactory.thisExpression();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitThrowExpression() {
+ ThrowExpression fromNode = AstFactory.throwExpression();
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+ ThrowExpression toNode = AstFactory.throwExpression();
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ }
+
+ void test_visitTypeName() {
+ TypeName fromNode = AstFactory.typeName4("C");
+ DartType type = ElementFactory.classElement2("C").type;
+ fromNode.type = type;
+ TypeName toNode = AstFactory.typeName4("C");
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.type, same(type));
+ }
+
+ void _copyAndVerifyInvocation(
+ InvocationExpression fromNode, InvocationExpression toNode) {
+ DartType propagatedType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedType = propagatedType;
+ DartType staticType = ElementFactory.classElement2("C").type;
+ fromNode.staticType = staticType;
+
+ DartType propagatedInvokeType = ElementFactory.classElement2("C").type;
+ fromNode.propagatedInvokeType = propagatedInvokeType;
+ DartType staticInvokeType = ElementFactory.classElement2("C").type;
+ fromNode.staticInvokeType = staticInvokeType;
+
+ ResolutionCopier.copyResolutionData(fromNode, toNode);
+ expect(toNode.propagatedType, same(propagatedType));
+ expect(toNode.staticType, same(staticType));
+ expect(toNode.propagatedInvokeType, same(propagatedInvokeType));
+ expect(toNode.staticInvokeType, same(staticInvokeType));
+ }
+}
+
+@reflectiveTest
class ToSourceVisitorTest extends EngineTestCase {
void test_visitAdjacentStrings() {
_assertSource(
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 080c544..c097cff 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -18,8 +18,8 @@
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:unittest/unittest.dart';
-import '../../../generated/resolver_test.dart'
- show TestTypeProvider, AnalysisContextHelper;
+import '../../../generated/analysis_context_factory.dart'
+ show AnalysisContextHelper;
import '../../../generated/test_support.dart';
import '../../../reflective_tests.dart';
import '../../../utils.dart';
@@ -1299,20 +1299,110 @@
expect(type.element, typeElement);
}
- void test_getNamedParameterTypes() {
- FunctionTypeImpl type = new FunctionTypeImpl(
- new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
+ void test_getNamedParameterTypes_namedParameters() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ FunctionElement element = ElementFactory
+ .functionElementWithParameters('f', VoidTypeImpl.instance, [
+ ElementFactory.requiredParameter2('a', typeProvider.intType),
+ ElementFactory.requiredParameter('b'),
+ ElementFactory.namedParameter2('c', typeProvider.stringType),
+ ElementFactory.namedParameter('d')
+ ]);
+ FunctionTypeImpl type = element.type;
+ Map<String, DartType> types = type.namedParameterTypes;
+ expect(types, hasLength(2));
+ expect(types['c'], typeProvider.stringType);
+ expect(types['d'], DynamicTypeImpl.instance);
+ }
+
+ void test_getNamedParameterTypes_noNamedParameters() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ FunctionElement element = ElementFactory
+ .functionElementWithParameters('f', VoidTypeImpl.instance, [
+ ElementFactory.requiredParameter2('a', typeProvider.intType),
+ ElementFactory.requiredParameter('b'),
+ ElementFactory.positionalParameter2('c', typeProvider.stringType)
+ ]);
+ FunctionTypeImpl type = element.type;
Map<String, DartType> types = type.namedParameterTypes;
expect(types, hasLength(0));
}
- void test_getNormalParameterTypes() {
- FunctionTypeImpl type = new FunctionTypeImpl(
- new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
+ void test_getNamedParameterTypes_noParameters() {
+ FunctionTypeImpl type = ElementFactory.functionElement('f').type;
+ Map<String, DartType> types = type.namedParameterTypes;
+ expect(types, hasLength(0));
+ }
+
+ void test_getNormalParameterTypes_noNormalParameters() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ FunctionElement element = ElementFactory
+ .functionElementWithParameters('f', VoidTypeImpl.instance, [
+ ElementFactory.positionalParameter2('c', typeProvider.stringType),
+ ElementFactory.positionalParameter('d')
+ ]);
+ FunctionTypeImpl type = element.type;
List<DartType> types = type.normalParameterTypes;
expect(types, hasLength(0));
}
+ void test_getNormalParameterTypes_noParameters() {
+ FunctionTypeImpl type = ElementFactory.functionElement('f').type;
+ List<DartType> types = type.normalParameterTypes;
+ expect(types, hasLength(0));
+ }
+
+ void test_getNormalParameterTypes_normalParameters() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ FunctionElement element = ElementFactory
+ .functionElementWithParameters('f', VoidTypeImpl.instance, [
+ ElementFactory.requiredParameter2('a', typeProvider.intType),
+ ElementFactory.requiredParameter('b'),
+ ElementFactory.positionalParameter2('c', typeProvider.stringType)
+ ]);
+ FunctionTypeImpl type = element.type;
+ List<DartType> types = type.normalParameterTypes;
+ expect(types, hasLength(2));
+ expect(types[0], typeProvider.intType);
+ expect(types[1], DynamicTypeImpl.instance);
+ }
+
+ void test_getOptionalParameterTypes_noOptionalParameters() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ FunctionElement element = ElementFactory
+ .functionElementWithParameters('f', VoidTypeImpl.instance, [
+ ElementFactory.requiredParameter2('a', typeProvider.intType),
+ ElementFactory.requiredParameter('b'),
+ ElementFactory.namedParameter2('c', typeProvider.stringType),
+ ElementFactory.namedParameter('d')
+ ]);
+ FunctionTypeImpl type = element.type;
+ List<DartType> types = type.optionalParameterTypes;
+ expect(types, hasLength(0));
+ }
+
+ void test_getOptionalParameterTypes_noParameters() {
+ FunctionTypeImpl type = ElementFactory.functionElement('f').type;
+ List<DartType> types = type.optionalParameterTypes;
+ expect(types, hasLength(0));
+ }
+
+ void test_getOptionalParameterTypes_optionalParameters() {
+ TestTypeProvider typeProvider = new TestTypeProvider();
+ FunctionElement element = ElementFactory
+ .functionElementWithParameters('f', VoidTypeImpl.instance, [
+ ElementFactory.requiredParameter2('a', typeProvider.intType),
+ ElementFactory.requiredParameter('b'),
+ ElementFactory.positionalParameter2('c', typeProvider.stringType),
+ ElementFactory.positionalParameter('d')
+ ]);
+ FunctionTypeImpl type = element.type;
+ List<DartType> types = type.optionalParameterTypes;
+ expect(types, hasLength(2));
+ expect(types[0], typeProvider.stringType);
+ expect(types[1], DynamicTypeImpl.instance);
+ }
+
void test_getReturnType() {
DartType expectedReturnType = VoidTypeImpl.instance;
FunctionElementImpl functionElement =
@@ -3952,14 +4042,6 @@
expect(typeParameterTypeT.isMoreSpecificThan(classS.type), isTrue);
}
- void test_resolveToBound_unbound() {
- TypeParameterTypeImpl type = new TypeParameterTypeImpl(
- new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
- // Returns whatever type is passed to resolveToBound().
- expect(type.resolveToBound(VoidTypeImpl.instance),
- same(VoidTypeImpl.instance));
- }
-
void test_resolveToBound_bound() {
ClassElementImpl classS = ElementFactory.classElement2("A");
TypeParameterElementImpl element =
@@ -3982,6 +4064,14 @@
expect(typeF.resolveToBound(null), same(classS.type));
}
+ void test_resolveToBound_unbound() {
+ TypeParameterTypeImpl type = new TypeParameterTypeImpl(
+ new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
+ // Returns whatever type is passed to resolveToBound().
+ expect(type.resolveToBound(VoidTypeImpl.instance),
+ same(VoidTypeImpl.instance));
+ }
+
void test_substitute_equal() {
TypeParameterElementImpl element =
new TypeParameterElementImpl.forNode(AstFactory.identifier3("E"));
diff --git a/pkg/analyzer/test/src/summary/flat_buffers_test.dart b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
index 076df23..b17dc14 100644
--- a/pkg/analyzer/test/src/summary/flat_buffers_test.dart
+++ b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
@@ -345,7 +345,7 @@
}
// read and verify
BufferPointer root = new BufferPointer.fromBytes(byteList);
- List<int> items = const ListReader<int>(const Uint32Reader()).read(root);
+ List<int> items = const Uint32ListReader().read(root);
expect(items, hasLength(3));
expect(items, orderedEquals(<int>[1, 2, 0x9ABCDEF0]));
}
@@ -354,14 +354,14 @@
List<int> byteList;
{
Builder builder = new Builder(initialSize: 0);
- Offset offset = builder.writeListUint8(<int>[1, 2, 0x9A]);
+ Offset offset = builder.writeListUint8(<int>[1, 2, 3, 4, 0x9A]);
byteList = builder.finish(offset);
}
// read and verify
BufferPointer root = new BufferPointer.fromBytes(byteList);
- List<int> items = const ListReader<int>(const Uint8Reader()).read(root);
- expect(items, hasLength(3));
- expect(items, orderedEquals(<int>[1, 2, 0x9A]));
+ List<int> items = const Uint8ListReader().read(root);
+ expect(items, hasLength(5));
+ expect(items, orderedEquals(<int>[1, 2, 3, 4, 0x9A]));
}
}
diff --git a/pkg/analyzer/test/src/summary/index_unit_test.dart b/pkg/analyzer/test/src/summary/index_unit_test.dart
index 83da4c2..a8a3f4f 100644
--- a/pkg/analyzer/test/src/summary/index_unit_test.dart
+++ b/pkg/analyzer/test/src/summary/index_unit_test.dart
@@ -41,7 +41,8 @@
UnitIndex unitIndex;
_ElementIndexAssert assertThat(Element element) {
- return new _ElementIndexAssert(this, element);
+ List<_Relation> relations = _getElementRelations(element);
+ return new _ElementIndexAssert(this, element, relations);
}
_NameIndexAssert assertThatName(String name) {
@@ -313,6 +314,21 @@
..isInvokedAt('foo(); // nq', false);
}
+ void test_isInvokedBy_FunctionElement_synthetic_loadLibrary() {
+ verifyNoTestUnitErrors = false;
+ _indexTestUnit('''
+import 'dart:math' deferred as math;
+main() {
+ math.loadLibrary(); // 1
+ math.loadLibrary(); // 2
+}
+''');
+ LibraryElement mathLib = testLibraryElement.imports[0].importedLibrary;
+ FunctionElement element = mathLib.loadLibraryFunction;
+ assertThat(element).isInvokedAt('loadLibrary(); // 1', true);
+ assertThat(element).isInvokedAt('loadLibrary(); // 2', true);
+ }
+
void test_isInvokedBy_MethodElement() {
_indexTestUnit('''
class A {
@@ -392,6 +408,21 @@
assertThat(element).isInvokedAt('~a', true, length: 1);
}
+ void test_isInvokedBy_PropertyAccessorElement_getter() {
+ _indexTestUnit('''
+class A {
+ get ggg => null;
+ main() {
+ this.ggg(); // q
+ ggg(); // nq
+ }
+}''');
+ PropertyAccessorElement element = findElement('ggg', ElementKind.GETTER);
+ assertThat(element)
+ ..isInvokedAt('ggg(); // q', true)
+ ..isInvokedAt('ggg(); // nq', false);
+ }
+
void test_isMixedInBy_ClassDeclaration() {
_indexTestUnit('''
class A {} // 1
@@ -545,10 +576,12 @@
ConstructorElement constA_foo = classA.constructors[1];
// A()
assertThat(constA)
+ ..hasRelationCount(2)
..isReferencedAt('(); // 1', true, length: 0)
..isReferencedAt('(); // 4', true, length: 0);
// A.foo()
assertThat(constA_foo)
+ ..hasRelationCount(3)
..isReferencedAt('.foo(); // 2', true, length: 4)
..isReferencedAt('.foo; // 3', true, length: 4)
..isReferencedAt('.foo(); // 5', true, length: 4);
@@ -625,15 +658,24 @@
assertThat(constA_bar).isReferencedAt('.bar(); // 1', true, length: 4);
}
- void test_isReferencedBy_ConstructorFieldInitializer() {
+ void test_isReferencedBy_ConstructorElement_synthetic() {
_indexTestUnit('''
-class A {
- int field;
- A() : field = 5;
+class A {}
+main() {
+ new A(); // 1
}
''');
- FieldElement element = findElement('field');
- assertThat(element).isReferencedAt('field = 5', true);
+ ClassElement classA = findElement('A');
+ ConstructorElement constA = classA.constructors[0];
+ // A()
+ assertThat(constA)..isReferencedAt('(); // 1', true, length: 0);
+ }
+
+ void test_isReferencedBy_DynamicElement() {
+ _indexTestUnit('''
+dynamic f() {
+}''');
+ expect(unitIndex.usedElementOffsets, isEmpty);
}
void test_isReferencedBy_FieldElement() {
@@ -642,28 +684,83 @@
var field;
A({this.field});
m() {
- field = 1; // nq
+ field = 2; // nq
print(field); // nq
}
}
main(A a) {
- a.field = 2; // q
+ a.field = 3; // q
print(a.field); // q
- new A(field: 3);
+ new A(field: 4);
}
''');
FieldElement field = findElement('field');
PropertyAccessorElement getter = field.getter;
PropertyAccessorElement setter = field.setter;
// A()
- assertThat(field)..isReferencedAt('field});', true);
+ assertThat(field)..isWrittenAt('field});', true);
// m()
- assertThat(setter)..isReferencedAt('field = 1; // nq', false);
+ assertThat(setter)..isReferencedAt('field = 2; // nq', false);
assertThat(getter)..isReferencedAt('field); // nq', false);
// main()
- assertThat(setter)..isReferencedAt('field = 2; // q', true);
+ assertThat(setter)..isReferencedAt('field = 3; // q', true);
assertThat(getter)..isReferencedAt('field); // q', true);
- assertThat(field)..isReferencedAt('field: 3', true);
+ assertThat(field)..isReferencedAt('field: 4', true);
+ }
+
+ void test_isReferencedBy_FieldElement_multiple() {
+ _indexTestUnit('''
+class A {
+ var aaa;
+ var bbb;
+ A(this.aaa, this.bbb) {}
+ m() {
+ print(aaa);
+ aaa = 1;
+ print(bbb);
+ bbb = 2;
+ }
+}
+''');
+ // aaa
+ {
+ FieldElement field = findElement('aaa');
+ PropertyAccessorElement getter = field.getter;
+ PropertyAccessorElement setter = field.setter;
+ assertThat(field)..isWrittenAt('aaa, ', true);
+ assertThat(getter)..isReferencedAt('aaa);', false);
+ assertThat(setter)..isReferencedAt('aaa = 1;', false);
+ }
+ // bbb
+ {
+ FieldElement field = findElement('bbb');
+ PropertyAccessorElement getter = field.getter;
+ PropertyAccessorElement setter = field.setter;
+ assertThat(field)..isWrittenAt('bbb) {}', true);
+ assertThat(getter)..isReferencedAt('bbb);', false);
+ assertThat(setter)..isReferencedAt('bbb = 2;', false);
+ }
+ }
+
+ void test_isReferencedBy_FieldElement_ofEnum() {
+ verifyNoTestUnitErrors = false;
+ _indexTestUnit('''
+enum MyEnum {
+ A, B, C
+}
+main() {
+ print(MyEnum.values);
+ print(MyEnum.A.index);
+ print(MyEnum.A);
+ print(MyEnum.B);
+}
+''');
+ ClassElement enumElement = findElement('MyEnum');
+ assertThat(enumElement.getGetter('values'))
+ ..isReferencedAt('values);', true);
+ assertThat(enumElement.getGetter('index'))..isReferencedAt('index);', true);
+ assertThat(enumElement.getGetter('A'))..isReferencedAt('A);', true);
+ assertThat(enumElement.getGetter('B'))..isReferencedAt('B);', true);
}
void test_isReferencedBy_FunctionElement() {
@@ -759,6 +856,35 @@
..isReferencedAt('V = 5; // nq', false);
}
+ void test_isReferencedBy_TopLevelVariableElement_synthetic_hasGetterSetter() {
+ verifyNoTestUnitErrors = false;
+ addSource(
+ '/lib.dart',
+ '''
+int get V => 0;
+void set V(_) {}
+''');
+ _indexTestUnit('''
+import 'lib.dart' show V;
+''');
+ TopLevelVariableElement element = importedUnit().topLevelVariables[0];
+ assertThat(element).isReferencedAt('V;', true);
+ }
+
+ void test_isReferencedBy_TopLevelVariableElement_synthetic_hasSetter() {
+ verifyNoTestUnitErrors = false;
+ addSource(
+ '/lib.dart',
+ '''
+void set V(_) {}
+''');
+ _indexTestUnit('''
+import 'lib.dart' show V;
+''');
+ TopLevelVariableElement element = importedUnit().topLevelVariables[0];
+ assertThat(element).isReferencedAt('V;', true);
+ }
+
void test_isReferencedBy_typeInVariableList() {
_indexTestUnit('''
class A {}
@@ -768,46 +894,92 @@
assertThat(element).isReferencedAt('A myVariable', false);
}
- void test_usedName_isInvokedBy() {
- verifyNoTestUnitErrors = false;
+ void test_isWrittenBy_FieldElement() {
_indexTestUnit('''
-class C {
- x() {}
-}
-main(C c) {
- x(); // nq
- c.x(); // q
- y(); // nq
- c.y(); // q
+class A {
+ int field;
+ A.foo({this.field});
+ A.bar() : field = 5;
}
''');
- assertThatName('x')
- ..isNotInvokedAt('x(); // nq')
- ..isNotInvokedAt('x(); // q');
- assertThatName('y')
- ..isNotInvokedAt('y(); // nq')
- ..isInvokedAt('y(); // q');
+ FieldElement element = findElement('field');
+ assertThat(element)
+ ..isWrittenAt('field})', true)
+ ..isWrittenAt('field = 5', true);
}
- void test_usedName_isReferencedBy() {
+ void test_usedName_qualified_resolved() {
verifyNoTestUnitErrors = false;
_indexTestUnit('''
class C {
- int x;
+ var x;
}
main(C c) {
- x; // nq
- c.x; // q
- y; // nq
- c.y; // q
+ c.x;
+ c.x = 1;
+ c.x += 2;
+ c.x();
}
''');
assertThatName('x')
- ..isNotReferencedAt('x; // nq')
- ..isNotReferencedAt('x; // q');
- assertThatName('y')
- ..isNotReferencedAt('y; // nq')
- ..isReferencedAt('y; // q');
+ ..isNotUsed('x;', IndexRelationKind.IS_READ_BY)
+ ..isNotUsed('x = 1;', IndexRelationKind.IS_WRITTEN_BY)
+ ..isNotUsed('x += 2;', IndexRelationKind.IS_READ_WRITTEN_BY)
+ ..isNotUsed('x();', IndexRelationKind.IS_INVOKED_BY);
+ }
+
+ void test_usedName_qualified_unresolved() {
+ verifyNoTestUnitErrors = false;
+ _indexTestUnit('''
+main(p) {
+ p.x;
+ p.x = 1;
+ p.x += 2;
+ p.x();
+}
+''');
+ assertThatName('x')
+ ..isUsedQ('x;', IndexRelationKind.IS_READ_BY)
+ ..isUsedQ('x = 1;', IndexRelationKind.IS_WRITTEN_BY)
+ ..isUsedQ('x += 2;', IndexRelationKind.IS_READ_WRITTEN_BY)
+ ..isUsedQ('x();', IndexRelationKind.IS_INVOKED_BY);
+ }
+
+ void test_usedName_unqualified_resolved() {
+ verifyNoTestUnitErrors = false;
+ _indexTestUnit('''
+class C {
+ var x;
+ m() {
+ x;
+ x = 1;
+ x += 2;
+ x();
+ }
+}
+''');
+ assertThatName('x')
+ ..isNotUsed('x;', IndexRelationKind.IS_READ_BY)
+ ..isNotUsed('x = 1;', IndexRelationKind.IS_WRITTEN_BY)
+ ..isNotUsed('x += 2;', IndexRelationKind.IS_READ_WRITTEN_BY)
+ ..isNotUsed('x();', IndexRelationKind.IS_INVOKED_BY);
+ }
+
+ void test_usedName_unqualified_unresolved() {
+ verifyNoTestUnitErrors = false;
+ _indexTestUnit('''
+main() {
+ x;
+ x = 1;
+ x += 2;
+ x();
+}
+''');
+ assertThatName('x')
+ ..isUsed('x;', IndexRelationKind.IS_READ_BY)
+ ..isUsed('x = 1;', IndexRelationKind.IS_WRITTEN_BY)
+ ..isUsed('x += 2;', IndexRelationKind.IS_READ_WRITTEN_BY)
+ ..isUsed('x();', IndexRelationKind.IS_INVOKED_BY);
}
void _assertDefinedName(String name, IndexNameKind kind, String search) {
@@ -828,16 +1000,14 @@
*/
void _assertHasRelation(
Element element,
+ List<_Relation> relations,
IndexRelationKind expectedRelationKind,
ExpectedLocation expectedLocation) {
- int elementId = _findElementId(element);
- for (int i = 0; i < unitIndex.usedElementOffsets.length; i++) {
- if (unitIndex.usedElements[i] == elementId &&
- unitIndex.usedElementKinds[i] == expectedRelationKind &&
- unitIndex.usedElementOffsets[i] == expectedLocation.offset &&
- unitIndex.usedElementLengths[i] == expectedLocation.length &&
- unitIndex.usedElementIsQualifiedFlags[i] ==
- expectedLocation.isQualified) {
+ for (_Relation relation in relations) {
+ if (relation.kind == expectedRelationKind &&
+ relation.offset == expectedLocation.offset &&
+ relation.length == expectedLocation.length &&
+ relation.isQualified == expectedLocation.isQualified) {
return;
}
}
@@ -851,7 +1021,9 @@
for (int i = 0; i < unitIndex.usedNames.length; i++) {
if (unitIndex.usedNames[i] == nameId &&
unitIndex.usedNameKinds[i] == kind &&
- unitIndex.usedNameOffsets[i] == expectedLocation.offset) {
+ unitIndex.usedNameOffsets[i] == expectedLocation.offset &&
+ unitIndex.usedNameIsQualifiedFlags[i] ==
+ expectedLocation.isQualified) {
if (isNot) {
_failWithIndexDump('Unexpected $name $kind at $expectedLocation');
}
@@ -884,18 +1056,13 @@
*/
int _findElementId(Element element) {
int unitId = _getUnitId(element);
- int offset = element.nameOffset;
- if (element is LibraryElement || element is CompilationUnitElement) {
- offset = 0;
- }
- IndexSyntheticElementKind kind =
- PackageIndexAssembler.getIndexElementKind(element);
+ ElementInfo info = PackageIndexAssembler.newElementInfo(unitId, element);
for (int elementId = 0;
elementId < packageIndex.elementUnits.length;
elementId++) {
if (packageIndex.elementUnits[elementId] == unitId &&
- packageIndex.elementOffsets[elementId] == offset &&
- packageIndex.elementKinds[elementId] == kind) {
+ packageIndex.elementOffsets[elementId] == info.offset &&
+ packageIndex.elementKinds[elementId] == info.kind) {
return elementId;
}
}
@@ -903,6 +1070,24 @@
return 0;
}
+ /**
+ * Return all relations with [element] in [unitIndex].
+ */
+ List<_Relation> _getElementRelations(Element element) {
+ int elementId = _findElementId(element);
+ List<_Relation> relations = <_Relation>[];
+ for (int i = 0; i < unitIndex.usedElementOffsets.length; i++) {
+ if (unitIndex.usedElements[i] == elementId) {
+ relations.add(new _Relation(
+ unitIndex.usedElementKinds[i],
+ unitIndex.usedElementOffsets[i],
+ unitIndex.usedElementLengths[i],
+ unitIndex.usedElementIsQualifiedFlags[i]));
+ }
+ }
+ return relations;
+ }
+
int _getStringId(String str) {
int id = packageIndex.strings.indexOf(str);
expect(id, isNonNegative);
@@ -949,36 +1134,61 @@
class _ElementIndexAssert {
final PackageIndexAssemblerTest test;
final Element element;
+ final List<_Relation> relations;
- _ElementIndexAssert(this.test, this.element);
+ _ElementIndexAssert(this.test, this.element, this.relations);
+
+ void hasRelationCount(int expectedCount) {
+ expect(relations, hasLength(expectedCount));
+ }
void isAncestorOf(String search, {int length}) {
- test._assertHasRelation(element, IndexRelationKind.IS_ANCESTOR_OF,
+ test._assertHasRelation(
+ element,
+ relations,
+ IndexRelationKind.IS_ANCESTOR_OF,
test._expectedLocation(search, false, length: length));
}
void isExtendedAt(String search, bool isQualified, {int length}) {
- test._assertHasRelation(element, IndexRelationKind.IS_EXTENDED_BY,
+ test._assertHasRelation(
+ element,
+ relations,
+ IndexRelationKind.IS_EXTENDED_BY,
test._expectedLocation(search, isQualified, length: length));
}
void isImplementedAt(String search, bool isQualified, {int length}) {
- test._assertHasRelation(element, IndexRelationKind.IS_IMPLEMENTED_BY,
+ test._assertHasRelation(
+ element,
+ relations,
+ IndexRelationKind.IS_IMPLEMENTED_BY,
test._expectedLocation(search, isQualified, length: length));
}
void isInvokedAt(String search, bool isQualified, {int length}) {
- test._assertHasRelation(element, IndexRelationKind.IS_INVOKED_BY,
+ test._assertHasRelation(element, relations, IndexRelationKind.IS_INVOKED_BY,
test._expectedLocation(search, isQualified, length: length));
}
void isMixedInAt(String search, bool isQualified, {int length}) {
- test._assertHasRelation(element, IndexRelationKind.IS_MIXED_IN_BY,
+ test._assertHasRelation(
+ element,
+ relations,
+ IndexRelationKind.IS_MIXED_IN_BY,
test._expectedLocation(search, isQualified, length: length));
}
void isReferencedAt(String search, bool isQualified, {int length}) {
- test._assertHasRelation(element, IndexRelationKind.IS_REFERENCED_BY,
+ test._assertHasRelation(
+ element,
+ relations,
+ IndexRelationKind.IS_REFERENCED_BY,
+ test._expectedLocation(search, isQualified, length: length));
+ }
+
+ void isWrittenAt(String search, bool isQualified, {int length}) {
+ test._assertHasRelation(element, relations, IndexRelationKind.IS_WRITTEN_BY,
test._expectedLocation(search, isQualified, length: length));
}
}
@@ -989,23 +1199,33 @@
_NameIndexAssert(this.test, this.name);
- void isInvokedAt(String search, {int length}) {
- test._assertUsedName(name, IndexRelationKind.IS_INVOKED_BY,
- test._expectedLocation(search, true, length: length), false);
+ void isNotUsed(String search, IndexRelationKind kind) {
+ test._assertUsedName(
+ name, kind, test._expectedLocation(search, true), true);
}
- void isNotInvokedAt(String search, {int length}) {
- test._assertUsedName(name, IndexRelationKind.IS_INVOKED_BY,
- test._expectedLocation(search, true, length: length), true);
+ void isUsed(String search, IndexRelationKind kind) {
+ test._assertUsedName(
+ name, kind, test._expectedLocation(search, false), false);
}
- void isNotReferencedAt(String search, {int length}) {
- test._assertUsedName(name, IndexRelationKind.IS_REFERENCED_BY,
- test._expectedLocation(search, true, length: length), true);
+ void isUsedQ(String search, IndexRelationKind kind) {
+ test._assertUsedName(
+ name, kind, test._expectedLocation(search, true), false);
}
+}
- void isReferencedAt(String search, {int length}) {
- test._assertUsedName(name, IndexRelationKind.IS_REFERENCED_BY,
- test._expectedLocation(search, true, length: length), false);
+class _Relation {
+ final IndexRelationKind kind;
+ final int offset;
+ final int length;
+ final bool isQualified;
+
+ _Relation(this.kind, this.offset, this.length, this.isQualified);
+
+ @override
+ String toString() {
+ return '_Relation{kind: $kind, offset: $offset, length: $length, '
+ 'isQualified: $isQualified}';
}
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index d8951a3..d1f2b88 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -11,10 +11,10 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart' show DartObject;
-import 'package:analyzer/src/generated/element_handle.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart'
show Namespace, TypeProvider;
@@ -25,7 +25,7 @@
import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:unittest/unittest.dart';
-import '../../generated/resolver_test.dart';
+import '../../generated/resolver_test_case.dart';
import '../../reflective_tests.dart';
import 'summary_common.dart' show canonicalize;
diff --git a/pkg/analyzer/test/src/summary/summarize_elements_test.dart b/pkg/analyzer/test/src/summary/summarize_elements_test.dart
index b854d31..539bbaf 100644
--- a/pkg/analyzer/test/src/summary/summarize_elements_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_elements_test.dart
@@ -16,7 +16,7 @@
as summarize_elements;
import 'package:unittest/unittest.dart';
-import '../../generated/resolver_test.dart';
+import '../../generated/resolver_test_case.dart';
import '../../reflective_tests.dart';
import 'summary_common.dart';
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 23b0a29..ae3d8ec 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -23,7 +23,7 @@
as summarize_elements;
import 'package:unittest/unittest.dart';
-import '../../generated/resolver_test.dart';
+import '../../generated/analysis_context_factory.dart';
/**
* The public namespaces of the sdk are computed once so that we don't bog
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 9bf0050..205dc90 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -27,7 +27,7 @@
import 'package:analyzer/task/model.dart';
import 'package:unittest/unittest.dart';
-import '../../generated/resolver_test.dart';
+import '../../generated/resolver_test_case.dart';
import '../../generated/test_support.dart';
import '../../reflective_tests.dart';
import '../../utils.dart';
@@ -2651,6 +2651,9 @@
class GenerateLintsTaskTest_TestLinter extends Linter {
@override
+ String get name => 'GenerateLintsTaskTest_TestLinter';
+
+ @override
AstVisitor getVisitor() => new GenerateLintsTaskTest_AstVisitor(this);
}
@@ -4760,10 +4763,9 @@
AnalysisTarget source = newSource(
'/test.dart',
'''
-int topLevel = 3;
-class C {
- String field = topLevel;
-}
+class A {}
+class B extends A {}
+B b = new A();
''');
computeResult(new LibrarySpecificUnit(source, source), STRONG_MODE_ERRORS);
// validate
@@ -4794,6 +4796,42 @@
]);
}
+ test_perform_ConstantValidator_declaredIdentifier() {
+ Source source = newSource(
+ '/test.dart',
+ '''
+void main() {
+ for (const foo in []) {
+ print(foo);
+ }
+}
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
+ // validate
+ _fillErrorListener(VERIFY_ERRORS);
+ errorListener.assertNoErrors();
+ }
+
+ test_perform_ConstantValidator_dependencyCycle() {
+ Source source = newSource(
+ '/test.dart',
+ '''
+const int a = b;
+const int b = c;
+const int c = a;
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
+ // validate
+ _fillErrorListener(VERIFY_ERRORS);
+ errorListener.assertErrorsWithCodes(<ErrorCode>[
+ CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+ CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+ CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT
+ ]);
+ }
+
test_perform_ConstantValidator_duplicateFields() {
Source source = newSource(
'/test.dart',
@@ -4815,6 +4853,38 @@
errorListener.assertNoErrors();
}
+ test_perform_ConstantValidator_noInitializer() {
+ Source source = newSource(
+ '/test.dart',
+ '''
+const x;
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
+ // validate
+ _fillErrorListener(VERIFY_ERRORS);
+ errorListener.assertErrorsWithCodes(
+ <ErrorCode>[CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
+ }
+
+ test_perform_ConstantValidator_unknownValue() {
+ Source source = newSource(
+ '/test.dart',
+ '''
+import 'no-such-file.dart' as p;
+
+const int x = p.y;
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
+ // validate
+ _fillErrorListener(VERIFY_ERRORS);
+ errorListener.assertErrorsWithCodes(<ErrorCode>[
+ CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+ CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+ ]);
+ }
+
test_perform_directiveError() {
Source source = newSource(
'/test.dart',
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 105ed8b..03a2579 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -96,6 +96,15 @@
expect(analysisOptions.enableSuperMixins, true);
}
+ test_configure_enableStrictCallChecks() {
+ configureContext('''
+analyzer:
+ language:
+ enableStrictCallChecks: true
+''');
+ expect(analysisOptions.enableStrictCallChecks, true);
+ }
+
test_configure_error_processors() {
configureContext('''
analyzer:
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index a87577c..09738bd 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -49,7 +49,7 @@
int i = 42;
// Check the boolean conversion of the condition.
- print((/*severe:STATIC_TYPE_ERROR*/i) ? false : true);
+ print(/*warning:NON_BOOL_CONDITION*/i ? false : true);
print((/*info:DOWN_CAST_IMPLICIT*/obj) ? false : true);
print((/*info:DYNAMIC_CAST*/dyn) ? false : true);
}
@@ -67,29 +67,28 @@
if (b) {}
if (/*info:DYNAMIC_CAST*/dyn) {}
if (/*info:DOWN_CAST_IMPLICIT*/obj) {}
- if (/*severe:STATIC_TYPE_ERROR*/i) {}
+ if (/*warning:NON_BOOL_CONDITION*/i) {}
while (b) {}
while (/*info:DYNAMIC_CAST*/dyn) {}
while (/*info:DOWN_CAST_IMPLICIT*/obj) {}
- while (/*severe:STATIC_TYPE_ERROR*/i) {}
+ while (/*warning:NON_BOOL_CONDITION*/i) {}
do {} while (b);
do {} while (/*info:DYNAMIC_CAST*/dyn);
do {} while (/*info:DOWN_CAST_IMPLICIT*/obj);
- do {} while (/*severe:STATIC_TYPE_ERROR*/i);
+ do {} while (/*warning:NON_BOOL_CONDITION*/i);
for (;b;) {}
for (;/*info:DYNAMIC_CAST*/dyn;) {}
for (;/*info:DOWN_CAST_IMPLICIT*/obj;) {}
- for (;/*severe:STATIC_TYPE_ERROR*/i;) {}
+ for (;/*warning:NON_BOOL_CONDITION*/i;) {}
}
''');
});
test('dynamic invocation', () {
checkFile('''
-
class A {
dynamic call(dynamic x) => x;
}
@@ -103,22 +102,24 @@
int x;
double y;
x = f(3);
- x = /*severe:STATIC_TYPE_ERROR*/f.col(3.0);
- y = /*severe:STATIC_TYPE_ERROR*/f(3);
+ x = /*warning:INVALID_ASSIGNMENT*/f.col(3.0);
+ y = /*warning:INVALID_ASSIGNMENT*/f(3);
y = f.col(3.0);
- f(/*severe:STATIC_TYPE_ERROR*/3.0);
- f.col(/*severe:STATIC_TYPE_ERROR*/3);
+ f(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3.0);
+ f.col(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
{
Function f = new B();
int x;
double y;
x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
- x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f.col(3.0);
+ x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE, info:INVALID_ASSIGNMENT*/f.col(3.0);
y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f.col(3.0);
- (/*info:DYNAMIC_INVOKE*/f(3.0));
- (/*info:DYNAMIC_INVOKE*/f.col(3));
+ /*info:DYNAMIC_INVOKE*/f(3.0);
+ // Through type propagation, we know f is actually a B, hence the
+ // hint.
+ /*info:DYNAMIC_INVOKE*/f.col(/*info:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
{
A f = new B();
@@ -126,19 +127,19 @@
double y;
x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
- (/*info:DYNAMIC_INVOKE*/f(3.0));
+ /*info:DYNAMIC_INVOKE*/f(3.0);
}
{
dynamic g = new B();
- (/*info:DYNAMIC_INVOKE*/g.call(32.0));
- (/*info:DYNAMIC_INVOKE*/g.col(42.0));
- (/*info:DYNAMIC_INVOKE*/g.foo(42.0));
- (/*info:DYNAMIC_INVOKE*/g./*info:UNDEFINED_GETTER*/x);
+ /*info:DYNAMIC_INVOKE*/g.call(/*info:ARGUMENT_TYPE_NOT_ASSIGNABLE*/32.0);
+ /*info:DYNAMIC_INVOKE*/g.col(42.0);
+ /*info:DYNAMIC_INVOKE*/g.foo(42.0);
+ /*info:DYNAMIC_INVOKE*/g./*info:UNDEFINED_GETTER*/x;
A f = new B();
- f.call(32.0);
- (/*info:DYNAMIC_INVOKE*/f.col(42.0));
- (/*info:DYNAMIC_INVOKE*/f.foo(42.0));
- (/*info:DYNAMIC_INVOKE*/f./*warning:UNDEFINED_GETTER*/x);
+ f.call(/*info:ARGUMENT_TYPE_NOT_ASSIGNABLE*/32.0);
+ /*info:DYNAMIC_INVOKE*/f.col(42.0);
+ /*info:DYNAMIC_INVOKE*/f.foo(42.0);
+ /*info:DYNAMIC_INVOKE*/f./*warning:UNDEFINED_GETTER*/x;
}
}
''');
@@ -157,7 +158,7 @@
class A {
String x = "hello world";
- void baz1(y) => x + /*info:DYNAMIC_CAST*/y;
+ void baz1(y) { x + /*info:DYNAMIC_CAST*/y; }
static baz2(y) => /*info:DYNAMIC_INVOKE*/y + y;
}
@@ -235,7 +236,7 @@
int x;
String y;
- A(this.x) : this.y = /*severe:STATIC_TYPE_ERROR*/42;
+ A(this.x) : this.y = /*warning:FIELD_INITIALIZER_NOT_ASSIGNABLE*/42;
A.c1(p): this.x = /*info:DOWN_CAST_IMPLICIT*/z, this.y = /*info:DYNAMIC_CAST*/p;
@@ -245,17 +246,17 @@
}
class B extends A {
- B() : super(/*severe:STATIC_TYPE_ERROR*/"hello");
+ B() : super(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
- B.c2(int x, String y) : super.c2(/*severe:STATIC_TYPE_ERROR*/y,
- /*severe:STATIC_TYPE_ERROR*/x);
+ B.c2(int x, String y) : super.c2(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y,
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/x);
B.c3(num x, Object y) : super.c3(x, /*info:DOWN_CAST_IMPLICIT*/y);
}
void main() {
- A a = new A.c2(/*info:DOWN_CAST_IMPLICIT*/z, /*severe:STATIC_TYPE_ERROR*/z);
- var b = new B.c2(/*severe:STATIC_TYPE_ERROR*/"hello", /*info:DOWN_CAST_IMPLICIT*/obj);
+ A a = new A.c2(/*info:DOWN_CAST_IMPLICIT*/z, /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z);
+ var b = new B.c2(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*info:DOWN_CAST_IMPLICIT*/obj);
}
''');
});
@@ -282,7 +283,7 @@
typedef int Foo();
void foo() {}
void main () {
- Foo x = /*severe:STATIC_TYPE_ERROR*/foo();
+ Foo x = /*warning:INVALID_ASSIGNMENT,info:USE_OF_VOID_RESULT*/foo();
}
''');
});
@@ -352,9 +353,9 @@
B b;
y = a;
o = a;
- i = /*severe:STATIC_TYPE_ERROR*/a;
- d = /*severe:STATIC_TYPE_ERROR*/a;
- n = /*severe:STATIC_TYPE_ERROR*/a;
+ i = /*warning:INVALID_ASSIGNMENT*/a;
+ d = /*warning:INVALID_ASSIGNMENT*/a;
+ n = /*warning:INVALID_ASSIGNMENT*/a;
a = a;
b = /*info:DOWN_CAST_IMPLICIT*/a;
}
@@ -379,12 +380,12 @@
C c;
y = b;
o = b;
- i = /*severe:STATIC_TYPE_ERROR*/b;
- d = /*severe:STATIC_TYPE_ERROR*/b;
- n = /*severe:STATIC_TYPE_ERROR*/b;
+ i = /*warning:INVALID_ASSIGNMENT*/b;
+ d = /*warning:INVALID_ASSIGNMENT*/b;
+ n = /*warning:INVALID_ASSIGNMENT*/b;
a = b;
b = b;
- c = /*severe:STATIC_TYPE_ERROR*/b;
+ c = /*warning:INVALID_ASSIGNMENT*/b;
}
''');
});
@@ -411,12 +412,12 @@
{
left = /*info:DOWN_CAST_IMPLICIT*/top;
left = left;
- left = /*severe:STATIC_TYPE_ERROR*/right;
+ left = /*warning:INVALID_ASSIGNMENT*/right;
left = bot;
}
{
right = /*info:DOWN_CAST_IMPLICIT*/top;
- right = /*severe:STATIC_TYPE_ERROR*/left;
+ right = /*warning:INVALID_ASSIGNMENT*/left;
right = right;
right = bot;
}
@@ -444,7 +445,7 @@
Object globalTop(int x) => x;
int globalLeft(int x) => x;
Object globalRight(Object x) => x;
- int _bot(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
+ int bot_(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
int globalBot(Object x) => x as int;
void main() {
@@ -504,7 +505,7 @@
typedef B Bot(A x); // Bottom of the lattice
B left(B x) => x;
- B _bot(A x) => /*info:DOWN_CAST_IMPLICIT*/x;
+ B bot_(A x) => /*info:DOWN_CAST_IMPLICIT*/x;
B bot(A x) => x as B;
A top(B x) => x;
A right(A x) => x;
@@ -866,7 +867,7 @@
BToA top(AToB f) => f;
AToB left(AToB f) => f;
BToA right(BToA f) => f;
- AToB _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
+ AToB bot_(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
AToB bot(BToA f) => f as AToB;
void main() {
@@ -916,7 +917,7 @@
Function2<B, A> top(AToB f) => f;
Function2<A, B> left(AToB f) => f;
Function2<B, A> right(BToA f) => f;
- Function2<A, B> _bot(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
+ Function2<A, B> bot_(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
Function2<A, B> bot(BToA f) => f as Function2<A, B>;
void main() {
@@ -966,7 +967,7 @@
BToA top(Function2<A, B> f) => f;
AToB left(Function2<A, B> f) => f;
BToA right(Function2<B, A> f) => f;
- AToB _bot(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f;
+ AToB bot_(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f;
AToB bot(Function2<B, A> f) => f as AToB;
void main() {
@@ -1071,91 +1072,91 @@
r = r;
r = o;
- r = /*severe:STATIC_TYPE_ERROR*/n;
- r = /*severe:STATIC_TYPE_ERROR*/rr;
+ r = /*warning:INVALID_ASSIGNMENT*/n;
+ r = /*warning:INVALID_ASSIGNMENT*/rr;
r = ro;
r = rn;
r = oo;
- r = /*severe:STATIC_TYPE_ERROR*/nn;
- r = /*severe:STATIC_TYPE_ERROR*/nnn;
+ r = /*warning:INVALID_ASSIGNMENT*/nn;
+ r = /*warning:INVALID_ASSIGNMENT*/nnn;
o = /*warning:DOWN_CAST_COMPOSITE*/r;
o = o;
- o = /*severe:STATIC_TYPE_ERROR*/n;
- o = /*severe:STATIC_TYPE_ERROR*/rr;
- o = /*severe:STATIC_TYPE_ERROR*/ro;
- o = /*severe:STATIC_TYPE_ERROR*/rn;
+ o = /*warning:INVALID_ASSIGNMENT*/n;
+ o = /*warning:INVALID_ASSIGNMENT*/rr;
+ o = /*warning:INVALID_ASSIGNMENT*/ro;
+ o = /*warning:INVALID_ASSIGNMENT*/rn;
o = oo;
- o = /*severe:STATIC_TYPE_ERROR*/nn;
- o = /*severe:STATIC_TYPE_ERROR*/nnn;
+ o = /*warning:INVALID_ASSIGNMENT*/nn;
+ o = /*warning:INVALID_ASSIGNMENT*/nnn;
- n = /*severe:STATIC_TYPE_ERROR*/r;
- n = /*severe:STATIC_TYPE_ERROR*/o;
+ n = /*warning:INVALID_ASSIGNMENT*/r;
+ n = /*warning:INVALID_ASSIGNMENT*/o;
n = n;
- n = /*severe:STATIC_TYPE_ERROR*/rr;
- n = /*severe:STATIC_TYPE_ERROR*/ro;
- n = /*severe:STATIC_TYPE_ERROR*/rn;
- n = /*severe:STATIC_TYPE_ERROR*/oo;
+ n = /*warning:INVALID_ASSIGNMENT*/rr;
+ n = /*warning:INVALID_ASSIGNMENT*/ro;
+ n = /*warning:INVALID_ASSIGNMENT*/rn;
+ n = /*warning:INVALID_ASSIGNMENT*/oo;
n = nn;
n = nnn;
- rr = /*severe:STATIC_TYPE_ERROR*/r;
- rr = /*severe:STATIC_TYPE_ERROR*/o;
- rr = /*severe:STATIC_TYPE_ERROR*/n;
+ rr = /*warning:INVALID_ASSIGNMENT*/r;
+ rr = /*warning:INVALID_ASSIGNMENT*/o;
+ rr = /*warning:INVALID_ASSIGNMENT*/n;
rr = rr;
rr = ro;
- rr = /*severe:STATIC_TYPE_ERROR*/rn;
+ rr = /*warning:INVALID_ASSIGNMENT*/rn;
rr = oo;
- rr = /*severe:STATIC_TYPE_ERROR*/nn;
- rr = /*severe:STATIC_TYPE_ERROR*/nnn;
+ rr = /*warning:INVALID_ASSIGNMENT*/nn;
+ rr = /*warning:INVALID_ASSIGNMENT*/nnn;
ro = /*warning:DOWN_CAST_COMPOSITE*/r;
- ro = /*severe:STATIC_TYPE_ERROR*/o;
- ro = /*severe:STATIC_TYPE_ERROR*/n;
+ ro = /*warning:INVALID_ASSIGNMENT*/o;
+ ro = /*warning:INVALID_ASSIGNMENT*/n;
ro = /*warning:DOWN_CAST_COMPOSITE*/rr;
ro = ro;
- ro = /*severe:STATIC_TYPE_ERROR*/rn;
+ ro = /*warning:INVALID_ASSIGNMENT*/rn;
ro = oo;
- ro = /*severe:STATIC_TYPE_ERROR*/nn;
- ro = /*severe:STATIC_TYPE_ERROR*/nnn;
+ ro = /*warning:INVALID_ASSIGNMENT*/nn;
+ ro = /*warning:INVALID_ASSIGNMENT*/nnn;
rn = /*warning:DOWN_CAST_COMPOSITE*/r;
- rn = /*severe:STATIC_TYPE_ERROR*/o;
- rn = /*severe:STATIC_TYPE_ERROR*/n;
- rn = /*severe:STATIC_TYPE_ERROR*/rr;
- rn = /*severe:STATIC_TYPE_ERROR*/ro;
+ rn = /*warning:INVALID_ASSIGNMENT*/o;
+ rn = /*warning:INVALID_ASSIGNMENT*/n;
+ rn = /*warning:INVALID_ASSIGNMENT*/rr;
+ rn = /*warning:INVALID_ASSIGNMENT*/ro;
rn = rn;
- rn = /*severe:STATIC_TYPE_ERROR*/oo;
- rn = /*severe:STATIC_TYPE_ERROR*/nn;
- rn = /*severe:STATIC_TYPE_ERROR*/nnn;
+ rn = /*warning:INVALID_ASSIGNMENT*/oo;
+ rn = /*warning:INVALID_ASSIGNMENT*/nn;
+ rn = /*warning:INVALID_ASSIGNMENT*/nnn;
oo = /*warning:DOWN_CAST_COMPOSITE*/r;
oo = /*warning:DOWN_CAST_COMPOSITE*/o;
- oo = /*severe:STATIC_TYPE_ERROR*/n;
+ oo = /*warning:INVALID_ASSIGNMENT*/n;
oo = /*warning:DOWN_CAST_COMPOSITE*/rr;
oo = /*warning:DOWN_CAST_COMPOSITE*/ro;
- oo = /*severe:STATIC_TYPE_ERROR*/rn;
+ oo = /*warning:INVALID_ASSIGNMENT*/rn;
oo = oo;
- oo = /*severe:STATIC_TYPE_ERROR*/nn;
- oo = /*severe:STATIC_TYPE_ERROR*/nnn;
+ oo = /*warning:INVALID_ASSIGNMENT*/nn;
+ oo = /*warning:INVALID_ASSIGNMENT*/nnn;
- nn = /*severe:STATIC_TYPE_ERROR*/r;
- nn = /*severe:STATIC_TYPE_ERROR*/o;
+ nn = /*warning:INVALID_ASSIGNMENT*/r;
+ nn = /*warning:INVALID_ASSIGNMENT*/o;
nn = /*warning:DOWN_CAST_COMPOSITE*/n;
- nn = /*severe:STATIC_TYPE_ERROR*/rr;
- nn = /*severe:STATIC_TYPE_ERROR*/ro;
- nn = /*severe:STATIC_TYPE_ERROR*/rn;
- nn = /*severe:STATIC_TYPE_ERROR*/oo;
+ nn = /*warning:INVALID_ASSIGNMENT*/rr;
+ nn = /*warning:INVALID_ASSIGNMENT*/ro;
+ nn = /*warning:INVALID_ASSIGNMENT*/rn;
+ nn = /*warning:INVALID_ASSIGNMENT*/oo;
nn = nn;
nn = nnn;
- nnn = /*severe:STATIC_TYPE_ERROR*/r;
- nnn = /*severe:STATIC_TYPE_ERROR*/o;
+ nnn = /*warning:INVALID_ASSIGNMENT*/r;
+ nnn = /*warning:INVALID_ASSIGNMENT*/o;
nnn = /*warning:DOWN_CAST_COMPOSITE*/n;
- nnn = /*severe:STATIC_TYPE_ERROR*/rr;
- nnn = /*severe:STATIC_TYPE_ERROR*/ro;
- nnn = /*severe:STATIC_TYPE_ERROR*/rn;
- nnn = /*severe:STATIC_TYPE_ERROR*/oo;
+ nnn = /*warning:INVALID_ASSIGNMENT*/rr;
+ nnn = /*warning:INVALID_ASSIGNMENT*/ro;
+ nnn = /*warning:INVALID_ASSIGNMENT*/rn;
+ nnn = /*warning:INVALID_ASSIGNMENT*/oo;
nnn = /*warning:DOWN_CAST_COMPOSITE*/nn;
nnn = nnn;
}
@@ -1179,7 +1180,7 @@
{
I2I f;
f = new A();
- f = /*severe:STATIC_TYPE_ERROR*/new B();
+ f = /*warning:INVALID_ASSIGNMENT*/new B();
f = i2i;
f = /*severe:STATIC_TYPE_ERROR*/n2n;
f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
@@ -1187,7 +1188,7 @@
}
{
N2N f;
- f = /*severe:STATIC_TYPE_ERROR*/new A();
+ f = /*warning:INVALID_ASSIGNMENT*/new A();
f = new B();
f = /*severe:STATIC_TYPE_ERROR*/i2i;
f = n2n;
@@ -1197,18 +1198,18 @@
{
A f;
f = new A();
- f = /*severe:STATIC_TYPE_ERROR*/new B();
- f = /*severe:STATIC_TYPE_ERROR*/i2i;
- f = /*severe:STATIC_TYPE_ERROR*/n2n;
+ f = /*warning:INVALID_ASSIGNMENT*/new B();
+ f = /*warning:INVALID_ASSIGNMENT*/i2i;
+ f = /*warning:INVALID_ASSIGNMENT*/n2n;
f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
}
{
B f;
- f = /*severe:STATIC_TYPE_ERROR*/new A();
+ f = /*warning:INVALID_ASSIGNMENT*/new A();
f = new B();
- f = /*severe:STATIC_TYPE_ERROR*/i2i;
- f = /*severe:STATIC_TYPE_ERROR*/n2n;
+ f = /*warning:INVALID_ASSIGNMENT*/i2i;
+ f = /*warning:INVALID_ASSIGNMENT*/n2n;
f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
}
@@ -1230,7 +1231,7 @@
class A {
void bar() => null;
- void foo() => bar; // allowed
+ void foo() => bar(); // allowed
}
''');
});
@@ -1257,8 +1258,8 @@
local = g; // valid
// Non-generic function cannot subtype a generic one.
- local = /*severe:STATIC_TYPE_ERROR*/(x) => null;
- local = /*severe:STATIC_TYPE_ERROR*/nonGenericFn;
+ local = /*severe:STATIC_TYPE_ERROR, warning:INVALID_ASSIGNMENT*/(x) => null;
+ local = /*warning:INVALID_ASSIGNMENT*/nonGenericFn;
}
{
Iterable/*<R>*/ f/*<P, R>*/(List/*<P>*/ p) => null;
@@ -1273,8 +1274,8 @@
local2 = /*warning:DOWN_CAST_COMPOSITE*/local;
// Non-generic function cannot subtype a generic one.
- local = /*severe:STATIC_TYPE_ERROR*/(x) => null;
- local = /*severe:STATIC_TYPE_ERROR*/nonGenericFn;
+ local = /*severe:STATIC_TYPE_ERROR, warning:INVALID_ASSIGNMENT*/(x) => null;
+ local = /*warning:INVALID_ASSIGNMENT*/nonGenericFn;
}
}
''');
@@ -1313,6 +1314,7 @@
lOfDs = lOfDs;
lOfDs = lOfOs;
lOfDs = lOfAs;
+ lOfDs = new L(); // Reset type propagation.
}
{
lOfOs = mOfDs;
@@ -1321,14 +1323,16 @@
lOfOs = lOfDs;
lOfOs = lOfOs;
lOfOs = lOfAs;
+ lOfOs = new L<Object>(); // Reset type propagation.
}
{
lOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
- lOfAs = /*severe:STATIC_TYPE_ERROR*/mOfOs;
+ lOfAs = /*warning:INVALID_ASSIGNMENT*/mOfOs;
lOfAs = mOfAs;
lOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
lOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
lOfAs = lOfAs;
+ lOfAs = new L<A>(); // Reset type propagation.
}
{
mOfDs = mOfDs;
@@ -1337,6 +1341,7 @@
mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
mOfDs = /*warning:DOWN_CAST_COMPOSITE*/lOfAs;
+ mOfDs = new M(); // Reset type propagation.
}
{
mOfOs = mOfDs;
@@ -1344,7 +1349,8 @@
mOfOs = mOfAs;
mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
- mOfOs = /*severe:STATIC_TYPE_ERROR*/lOfAs;
+ mOfOs = /*warning:INVALID_ASSIGNMENT*/lOfAs;
+ mOfOs = new M<Object>(); // Reset type propagation.
}
{
mOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
@@ -1354,7 +1360,6 @@
mOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
mOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfAs;
}
-
}
''');
});
@@ -1367,9 +1372,9 @@
String s = "hello";
{
List<int> l = <int>[i];
- l = <int>[/*severe:STATIC_TYPE_ERROR*/s];
+ l = <int>[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
l = <int>[/*info:DOWN_CAST_IMPLICIT*/n];
- l = <int>[i, /*info:DOWN_CAST_IMPLICIT*/n, /*severe:STATIC_TYPE_ERROR*/s];
+ l = <int>[i, /*info:DOWN_CAST_IMPLICIT*/n, /*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
}
{
List l = [i];
@@ -1379,11 +1384,11 @@
}
{
Map<String, int> m = <String, int>{s: i};
- m = <String, int>{s: /*severe:STATIC_TYPE_ERROR*/s};
+ m = <String, int>{s: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
m = <String, int>{s: /*info:DOWN_CAST_IMPLICIT*/n};
m = <String, int>{s: i,
s: /*info:DOWN_CAST_IMPLICIT*/n,
- s: /*severe:STATIC_TYPE_ERROR*/s};
+ s: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
}
// TODO(leafp): We can't currently test for key errors since the
// error marker binds to the entire entry.
@@ -1406,7 +1411,9 @@
checkFile('''
class A {
static const num n = 3.0;
- static const int i = /*info:ASSIGNMENT_CAST*/n;
+ // The severe error is from constant evaluation where we know the
+ // concrete type.
+ static const int /*severe:VARIABLE_TYPE_MISMATCH*/i = /*info:ASSIGNMENT_CAST*/n;
final int fi;
const A(num a) : this.fi = /*info:DOWN_CAST_IMPLICIT*/a;
}
@@ -1414,7 +1421,7 @@
const B(Object a) : super(/*info:DOWN_CAST_IMPLICIT*/a);
}
void foo(Object o) {
- var a = const A(/*info:DOWN_CAST_IMPLICIT*/o);
+ var a = const A(/*info:DOWN_CAST_IMPLICIT, severe:CONST_WITH_NON_CONSTANT_ARGUMENT, severe:INVALID_CONSTANT*/o);
}
''');
});
@@ -1435,7 +1442,7 @@
test('unbound redirecting constructor', () {
checkFile('''
class Foo {
- Foo() : this.init();
+ Foo() : /*severe:REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR*/this.init();
}
''');
});
@@ -1444,7 +1451,7 @@
checkFile('''
class A {
A(A x) {}
- A.two() : this(/*severe:STATIC_TYPE_ERROR*/3);
+ A.two() : this(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
''');
});
@@ -1453,7 +1460,7 @@
checkFile('''
class A { A(A x) {} }
class B extends A {
- B() : super(/*severe:STATIC_TYPE_ERROR*/3);
+ B() : super(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
''');
});
@@ -1513,7 +1520,7 @@
var _f3;
get _f4 => null;
- int _m1();
+ int _m1() => null;
}
class GrandChild extends main.Child {
@@ -1521,7 +1528,8 @@
/*severe:INVALID_FIELD_OVERRIDE*/var _f3;
var _f4;
- /*severe:INVALID_METHOD_OVERRIDE*/String _m1();
+ /*severe:INVALID_METHOD_OVERRIDE*/String
+ /*warning:INVALID_METHOD_OVERRIDE_RETURN_TYPE*/_m1() => null;
}
''',
name: '/helper.dart');
@@ -1533,7 +1541,7 @@
var _f2;
var _f4;
- String _m1();
+ String _m1() => null;
}
''');
});
@@ -1580,7 +1588,7 @@
/*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
}
- class Child2 implements Base {
+ class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR*/Child2 implements Base {
/*severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
C get f2 => null;
get f3 => null;
@@ -1664,21 +1672,21 @@
class C extends B {}
class Base {
- B m1(B a);
- B m2(B a);
- B m3(B a);
- B m4(B a);
- B m5(B a);
- B m6(B a);
+ B m1(B a) => null;
+ B m2(B a) => null;
+ B m3(B a) => null;
+ B m4(B a) => null;
+ B m5(B a) => null;
+ B m6(B a) => null;
}
class Child extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/A m1(A value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/C m2(C value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/A m3(C value) {}
- C m4(A value) {}
- m5(value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/dynamic m6(dynamic value) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/A m1(A value) => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/C m2(C value) => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/A m3(C value) => null;
+ C m4(A value) => null;
+ m5(value) => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/dynamic m6(dynamic value) => null;
}
''');
});
@@ -1693,7 +1701,8 @@
}
class Derived<S extends A> extends Base<B> {
- /*severe:INVALID_METHOD_OVERRIDE*/S foo() => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/S
+ /*warning:INVALID_METHOD_OVERRIDE_RETURN_TYPE*/foo() => null;
}
class Derived2<S extends B> extends Base<B> {
@@ -1758,14 +1767,14 @@
dynamic x;
if (x is int) {
int y = x;
- String z = /*severe:STATIC_TYPE_ERROR*/x;
+ String z = /*warning:INVALID_ASSIGNMENT*/x;
}
}
g() {
Object x;
if (x is int) {
int y = x;
- String z = /*severe:STATIC_TYPE_ERROR*/x;
+ String z = /*warning:INVALID_ASSIGNMENT*/x;
}
}
''');
@@ -1774,10 +1783,10 @@
test('unary operators', () {
checkFile('''
class A {
- A operator ~() {}
- A operator +(int x) {}
- A operator -(int x) {}
- A operator -() {}
+ A operator ~() => null;
+ A operator +(int x) => null;
+ A operator -(int x) => null;
+ A operator -() => null;
}
foo() => new A();
@@ -1790,7 +1799,7 @@
~a;
(/*info:DYNAMIC_INVOKE*/~d);
- !/*severe:STATIC_TYPE_ERROR*/a;
+ !/*warning:NON_BOOL_NEGATION_EXPRESSION*/a;
!/*info:DYNAMIC_CAST*/d;
-a;
@@ -1811,22 +1820,22 @@
test('binary and index operators', () {
checkFile('''
class A {
- A operator *(B b) {}
- A operator /(B b) {}
- A operator ~/(B b) {}
- A operator %(B b) {}
- A operator +(B b) {}
- A operator -(B b) {}
- A operator <<(B b) {}
- A operator >>(B b) {}
- A operator &(B b) {}
- A operator ^(B b) {}
- A operator |(B b) {}
- A operator[](B b) {}
+ A operator *(B b) => null;
+ A operator /(B b) => null;
+ A operator ~/(B b) => null;
+ A operator %(B b) => null;
+ A operator +(B b) => null;
+ A operator -(B b) => null;
+ A operator <<(B b) => null;
+ A operator >>(B b) => null;
+ A operator &(B b) => null;
+ A operator ^(B b) => null;
+ A operator |(B b) => null;
+ A operator[](B b) => null;
}
class B {
- A operator -(B b) {}
+ A operator -(B b) => null;
}
foo() => new A();
@@ -1841,9 +1850,9 @@
a = a ~/ b;
a = a % b;
a = a + b;
- a = a + /*severe:STATIC_TYPE_ERROR*/a;
+ a = a + /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
a = a - b;
- b = /*severe:STATIC_TYPE_ERROR*/b - b;
+ b = /*warning:INVALID_ASSIGNMENT*/b - b;
a = a << b;
a = a >> b;
a = a & b;
@@ -1855,20 +1864,20 @@
int y = 42;
x = x + x;
x = x + /*info:DYNAMIC_CAST*/c;
- x = x + /*severe:STATIC_TYPE_ERROR*/y;
+ x = x + /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y;
bool p = true;
p = p && p;
p = p && /*info:DYNAMIC_CAST*/c;
p = (/*info:DYNAMIC_CAST*/c) && p;
p = (/*info:DYNAMIC_CAST*/c) && /*info:DYNAMIC_CAST*/c;
- p = (/*severe:STATIC_TYPE_ERROR*/y) && p;
+ p = /*warning:NON_BOOL_OPERAND*/y && p;
p = c == y;
a = a[b];
a = a[/*info:DYNAMIC_CAST*/c];
c = (/*info:DYNAMIC_INVOKE*/c[b]);
- a[/*severe:STATIC_TYPE_ERROR*/y];
+ a[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y];
}
''');
});
@@ -1893,27 +1902,27 @@
test('compound assignments', () {
checkFile('''
class A {
- A operator *(B b) {}
- A operator /(B b) {}
- A operator ~/(B b) {}
- A operator %(B b) {}
- A operator +(B b) {}
- A operator -(B b) {}
- A operator <<(B b) {}
- A operator >>(B b) {}
- A operator &(B b) {}
- A operator ^(B b) {}
- A operator |(B b) {}
- D operator [](B index) {}
- void operator []=(B index, D value) {}
+ A operator *(B b) => null;
+ A operator /(B b) => null;
+ A operator ~/(B b) => null;
+ A operator %(B b) => null;
+ A operator +(B b) => null;
+ A operator -(B b) => null;
+ A operator <<(B b) => null;
+ A operator >>(B b) => null;
+ A operator &(B b) => null;
+ A operator ^(B b) => null;
+ A operator |(B b) => null;
+ D operator [](B index) => null;
+ void operator []=(B index, D value) => null;
}
class B {
- A operator -(B b) {}
+ A operator -(B b) => null;
}
class D {
- D operator +(D d) {}
+ D operator +(D d) => null;
}
foo() => new A();
@@ -1921,7 +1930,7 @@
test() {
int x = 0;
x += 5;
- (/*severe:STATIC_TYPE_ERROR*/x += 3.14);
+ /*severe:STATIC_TYPE_ERROR*/x += 3.14;
double y = 0.0;
y += 5;
@@ -1951,22 +1960,22 @@
a ~/= b;
a %= b;
a += b;
- a += /*severe:STATIC_TYPE_ERROR*/a;
+ a += /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
a -= b;
- (/*severe:STATIC_TYPE_ERROR*/b -= b);
+ /*severe:STATIC_TYPE_ERROR*/b -= /*warning:INVALID_ASSIGNMENT*/b;
a <<= b;
a >>= b;
a &= b;
a ^= b;
a |= b;
- (/*info:DYNAMIC_INVOKE*/c += b);
+ /*info:DYNAMIC_INVOKE*/c += b;
var d = new D();
a[b] += d;
a[/*info:DYNAMIC_CAST*/c] += d;
- a[/*severe:STATIC_TYPE_ERROR*/z] += d;
+ a[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z] += d;
a[b] += /*info:DYNAMIC_CAST*/c;
- a[b] += /*severe:STATIC_TYPE_ERROR*/z;
+ a[b] += /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z;
/*info:DYNAMIC_INVOKE,info:DYNAMIC_INVOKE*/c[b] += d;
}
''');
@@ -2011,7 +2020,7 @@
checkFile('''
foo() {
for (int i = 0; i < 10; i++) {
- i = /*severe:STATIC_TYPE_ERROR*/"hi";
+ i = /*warning:INVALID_ASSIGNMENT*/"hi";
}
}
bar() {
@@ -2043,35 +2052,43 @@
}
class T1 extends Base {
- /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_FIELD_OVERRIDE*/B get f => null;
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B get
+ /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f => null;
}
class T2 extends Base {
- /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_FIELD_OVERRIDE*/set f(B b) => null;
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/set f(
+ /*warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/B b) => null;
}
class T3 extends Base {
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/final B f;
+ /*severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/final B
+ /*warning:FINAL_NOT_INITIALIZED, warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f;
}
class T4 extends Base {
// two: one for the getter one for the setter.
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/B f;
+ /*severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B
+ /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE, warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/f;
}
- class T5 implements Base {
- /*severe:INVALID_METHOD_OVERRIDE*/B get f => null;
+ class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T5 implements Base {
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_METHOD_OVERRIDE*/B get
+ /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f => null;
}
- class T6 implements Base {
- /*severe:INVALID_METHOD_OVERRIDE*/set f(B b) => null;
+ class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T6 implements Base {
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_METHOD_OVERRIDE*/set f(
+ /*warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/B b) => null;
}
- class T7 implements Base {
- /*severe:INVALID_METHOD_OVERRIDE*/final B f;
+ class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T7 implements Base {
+ /*severe:INVALID_METHOD_OVERRIDE*/final B
+ /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f = null;
}
class T8 implements Base {
// two: one for the getter one for the setter.
- /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/B f;
+ /*severe:INVALID_METHOD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B
+ /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE, warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/f;
}
''');
});
@@ -2086,7 +2103,8 @@
}
class Test extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
});
@@ -2103,7 +2121,8 @@
}
class Test extends Parent {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
/*severe:INVALID_FIELD_OVERRIDE*/int x;
}
''');
@@ -2123,7 +2142,8 @@
class Test extends Parent {
// Reported only once
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
});
@@ -2137,7 +2157,8 @@
m(A a) {}
}
class Parent extends Grandparent {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
class Test extends Parent {
@@ -2164,9 +2185,12 @@
int x;
}
- class T1 extends Base with /*severe:INVALID_METHOD_OVERRIDE*/M1 {}
- class T2 extends Base with /*severe:INVALID_METHOD_OVERRIDE*/M1, /*severe:INVALID_FIELD_OVERRIDE*/M2 {}
- class T3 extends Base with /*severe:INVALID_FIELD_OVERRIDE*/M2, /*severe:INVALID_METHOD_OVERRIDE*/M1 {}
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with /*severe:INVALID_METHOD_OVERRIDE*/M1 {}
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2 extends Base
+ with /*severe:INVALID_METHOD_OVERRIDE*/M1, /*severe:INVALID_FIELD_OVERRIDE*/M2 {}
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T3 extends Base
+ with /*severe:INVALID_FIELD_OVERRIDE*/M2, /*severe:INVALID_METHOD_OVERRIDE*/M1 {}
''');
});
@@ -2188,7 +2212,9 @@
int x;
}
- class T1 extends Base with M1, /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_FIELD_OVERRIDE*/M2 {}
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with M1,
+ /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_FIELD_OVERRIDE*/M2 {}
''');
});
@@ -2216,7 +2242,7 @@
m(B a) {}
}
- class T1 extends Base
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
with M1, /*severe:INVALID_METHOD_OVERRIDE*/M2, M3 {}
''');
});
@@ -2231,7 +2257,8 @@
}
class T1 implements I {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
});
@@ -2249,9 +2276,8 @@
m(B a) {}
}
-
- class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base implements I {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base implements I {}
''');
});
@@ -2268,8 +2294,9 @@
m(B a) {}
}
- class T1 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I {}
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I {}
''');
});
@@ -2288,14 +2315,16 @@
m(B a) {}
}
- class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base
implements I1 {}
class T2 extends Base implements I1 {
/*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/m(a) {}
}
- class T3 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/Base
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T3
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/Base
implements I1 {}
class T4 extends Object with Base implements I1 {
@@ -2317,7 +2346,8 @@
abstract class I2 implements I1 {}
class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
});
@@ -2332,7 +2362,8 @@
abstract class I2 extends I1 {}
class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
});
@@ -2347,7 +2378,8 @@
abstract class I2 extends Object with M1 {}
class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
});
@@ -2362,7 +2394,8 @@
abstract class Base implements I1 {}
class T1 extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
});
@@ -2375,15 +2408,14 @@
m(A a);
}
- // See issue #25
- /*pass should be warning:AnalyzerError*/class Base implements I1 {
- }
+ class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
+ implements I1 {}
class T1 extends Base {
// not reported technically because if the class is concrete,
// it should implement all its interfaces and hence it is
// sufficient to check overrides against it.
- m(B a) {}
+ m(/*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
});
@@ -2404,9 +2436,9 @@
m(B a) {}
}
- class T1 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I2 {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I2 {}
''');
});
test('superclass of interface of child', () {
@@ -2423,9 +2455,9 @@
m(B a) {}
}
- class T1 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I2 {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I2 {}
''');
});
test('mixin of interface of child', () {
@@ -2442,9 +2474,9 @@
m(B a) {}
}
- class T1 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I2 {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I2 {}
''');
});
test('interface of abstract superclass', () {
@@ -2461,8 +2493,8 @@
m(B a) {}
}
- class T1 extends Base with /*severe:INVALID_METHOD_OVERRIDE*/M {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with /*severe:INVALID_METHOD_OVERRIDE*/M {}
''');
});
test('interface of concrete superclass', () {
@@ -2474,16 +2506,15 @@
m(A a);
}
- // See issue #25
- /*pass should be warning:AnalyzerError*/class Base implements I1 {
- }
+ class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
+ implements I1 {}
class M {
m(B a) {}
}
- class T1 extends Base with M {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with M {}
''');
});
});
@@ -2503,9 +2534,8 @@
m(B a) {}
}
- class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
- implements I2 {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base implements I2 {}
''');
});
test('superclass of interface of child', () {
@@ -2522,9 +2552,9 @@
m(B a) {}
}
- class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
- implements I2 {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+ implements I2 {}
''');
});
test('mixin of interface of child', () {
@@ -2541,9 +2571,9 @@
m(B a) {}
}
- class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
- implements I2 {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+ implements I2 {}
''');
});
test('interface of abstract superclass', () {
@@ -2556,7 +2586,8 @@
}
abstract class Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
class T1 extends Base {
@@ -2579,7 +2610,8 @@
}
class Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
class T1 extends Base {
@@ -2602,11 +2634,11 @@
m(A a);
}
- class Base {
- }
+ class Base {}
class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
''');
});
@@ -2621,20 +2653,21 @@
}
class Base {
- m(B a);
+ m(B a) {}
}
// Note: no error reported in `extends Base` to avoid duplicating
// the error in T1.
class T1 extends Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
// If there is no error in the class, we do report the error at
// the base class:
- class T2 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
- implements I1 {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+ implements I1 {}
''');
});
@@ -2648,16 +2681,17 @@
}
class M {
- m(B a);
+ m(B a) {}
}
class T1 extends Object with M implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
}
- class T2 extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I1 {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I1 {}
''');
});
@@ -2677,16 +2711,15 @@
class Parent1 extends Grandparent {
m(B a) {}
}
- class Parent2 extends Grandparent {
- }
+ class Parent2 extends Grandparent {}
// Note: otherwise both errors would be reported on this line
- class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Parent1
- implements I1 {
- }
- class T2 /*severe:INVALID_METHOD_OVERRIDE*/extends Parent2
- implements I1 {
- }
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Parent1
+ implements I1 {}
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Parent2
+ implements I1 {}
''');
});
@@ -2710,11 +2743,10 @@
// Here we want to report both, because the error location is
// different.
// TODO(sigmund): should we merge these as well?
- class T1 extends Object
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Object
with /*severe:INVALID_METHOD_OVERRIDE*/M1,
/*severe:INVALID_METHOD_OVERRIDE*/M2
- implements I1 {
- }
+ implements I1 {}
''');
});
@@ -2738,10 +2770,10 @@
// Here we want to report both, because the error location is
// different.
// TODO(sigmund): should we merge these as well?
- class T1 /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+ class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base
with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I1 {
- }
+ implements I1 {}
''');
});
});
@@ -2810,24 +2842,27 @@
foo1() async => x;
Future foo2() async => x;
- Future<int> foo3() async => (/*info:DYNAMIC_CAST*/x);
- Future<int> foo4() async => (new Future<int>.value(/*info:DYNAMIC_CAST*/x));
- Future<int> foo5() async => (/*severe:STATIC_TYPE_ERROR*/new Future<String>.value(/*info:DYNAMIC_CAST*/x));
+ Future<int> foo3() async => /*info:DYNAMIC_CAST*/x;
+ Future<int> foo4() async => new Future<int>.value(/*info:DYNAMIC_CAST*/x);
+ Future<int> foo5() async =>
+ /*warning:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
bar1() async { return x; }
Future bar2() async { return x; }
- Future<int> bar3() async { return (/*info:DYNAMIC_CAST*/x); }
- Future<int> bar4() async { return (new Future<int>.value(/*info:DYNAMIC_CAST*/x)); }
- Future<int> bar5() async { return (/*severe:STATIC_TYPE_ERROR*/new Future<String>.value(/*info:DYNAMIC_CAST*/x)); }
+ Future<int> bar3() async { return /*info:DYNAMIC_CAST*/x; }
+ Future<int> bar4() async { return new Future<int>.value(/*info:DYNAMIC_CAST*/x); }
+ Future<int> bar5() async {
+ return /*warning:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
+ }
int y;
Future<int> z;
- void baz() async {
+ baz() async {
int a = /*info:DYNAMIC_CAST*/await x;
int b = await y;
int c = await z;
- String d = /*severe:STATIC_TYPE_ERROR*/await z;
+ String d = /*warning:INVALID_ASSIGNMENT*/await z;
}
Future<bool> get issue_264 async {
@@ -2849,33 +2884,31 @@
bar1() async* { yield x; }
Stream bar2() async* { yield x; }
- Stream<int> bar3() async* { yield (/*info:DYNAMIC_CAST*/x); }
- Stream<int> bar4() async* { yield (/*severe:STATIC_TYPE_ERROR*/new Stream<int>()); }
+ Stream<int> bar3() async* { yield /*info:DYNAMIC_CAST*/x; }
+ Stream<int> bar4() async* { yield /*warning:YIELD_OF_INVALID_TYPE*/new Stream<int>(); }
- baz1() async* { yield* (/*info:DYNAMIC_CAST*/x); }
- Stream baz2() async* { yield* (/*info:DYNAMIC_CAST*/x); }
- Stream<int> baz3() async* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x); }
+ baz1() async* { yield* /*info:DYNAMIC_CAST*/x; }
+ Stream baz2() async* { yield* /*info:DYNAMIC_CAST*/x; }
+ Stream<int> baz3() async* { yield* /*warning:DOWN_CAST_COMPOSITE*/x; }
Stream<int> baz4() async* { yield* new Stream<int>(); }
- Stream<int> baz5() async* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/new Stream()); }
+ Stream<int> baz5() async* { yield* /*info:INFERRED_TYPE_ALLOCATION*/new Stream(); }
''');
});
test('sync*', () {
checkFile('''
- import 'dart:async';
-
dynamic x;
bar1() sync* { yield x; }
Iterable bar2() sync* { yield x; }
- Iterable<int> bar3() sync* { yield (/*info:DYNAMIC_CAST*/x); }
- Iterable<int> bar4() sync* { yield (/*severe:STATIC_TYPE_ERROR*/new Iterable<int>()); }
+ Iterable<int> bar3() sync* { yield /*info:DYNAMIC_CAST*/x; }
+ Iterable<int> bar4() sync* { yield /*warning:YIELD_OF_INVALID_TYPE*/bar3(); }
- baz1() sync* { yield* (/*info:DYNAMIC_CAST*/x); }
- Iterable baz2() sync* { yield* (/*info:DYNAMIC_CAST*/x); }
- Iterable<int> baz3() sync* { yield* (/*warning:DOWN_CAST_COMPOSITE*/x); }
- Iterable<int> baz4() sync* { yield* new Iterable<int>(); }
- Iterable<int> baz5() sync* { yield* (/*info:INFERRED_TYPE_ALLOCATION*/new Iterable()); }
+ baz1() sync* { yield* /*info:DYNAMIC_CAST*/x; }
+ Iterable baz2() sync* { yield* /*info:DYNAMIC_CAST*/x; }
+ Iterable<int> baz3() sync* { yield* /*warning:DOWN_CAST_COMPOSITE*/x; }
+ Iterable<int> baz4() sync* { yield* bar3(); }
+ Iterable<int> baz5() sync* { yield* /*info:INFERRED_TYPE_ALLOCATION*/new List(); }
''');
});
});
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 9f75d5d..3290d9b 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -19,7 +19,7 @@
checkFile('''
test1() {
int x = 3;
- x = /*severe:STATIC_TYPE_ERROR*/"hi";
+ x = /*warning:INVALID_ASSIGNMENT*/"hi";
}
''');
});
@@ -29,7 +29,7 @@
checkFile('''
test2() {
var x = 3;
- x = /*severe:STATIC_TYPE_ERROR*/"hi";
+ x = /*warning:INVALID_ASSIGNMENT*/"hi";
}
''');
});
@@ -69,13 +69,13 @@
test1() {
var a = x;
- a = /*severe:STATIC_TYPE_ERROR*/"hi";
+ a = /*warning:INVALID_ASSIGNMENT*/"hi";
a = 3;
var b = y;
- b = /*severe:STATIC_TYPE_ERROR*/"hi";
+ b = /*warning:INVALID_ASSIGNMENT*/"hi";
b = 4;
var c = z;
- c = /*severe:STATIC_TYPE_ERROR*/"hi";
+ c = /*warning:INVALID_ASSIGNMENT*/"hi";
c = 4;
}
@@ -91,13 +91,13 @@
test1() {
var a = x;
- a = /*severe:STATIC_TYPE_ERROR*/"hi";
+ a = /*warning:INVALID_ASSIGNMENT*/"hi";
a = 3;
var b = y;
- b = /*severe:STATIC_TYPE_ERROR*/"hi";
+ b = /*warning:INVALID_ASSIGNMENT*/"hi";
b = 4;
var c = z;
- c = /*severe:STATIC_TYPE_ERROR*/"hi";
+ c = /*warning:INVALID_ASSIGNMENT*/"hi";
c = 4;
}
@@ -120,11 +120,11 @@
test() {
x = "hi";
- y = /*severe:STATIC_TYPE_ERROR*/"hi";
+ y = /*warning:INVALID_ASSIGNMENT*/"hi";
A.x = "hi";
- A.y = /*severe:STATIC_TYPE_ERROR*/"hi";
+ A.y = /*warning:INVALID_ASSIGNMENT*/"hi";
new A().x2 = "hi";
- new A().y2 = /*severe:STATIC_TYPE_ERROR*/"hi";
+ new A().y2 = /*warning:INVALID_ASSIGNMENT*/"hi";
}
''');
});
@@ -140,8 +140,8 @@
var y = x;
test1() {
- x = /*severe:STATIC_TYPE_ERROR*/"hi";
- y = /*severe:STATIC_TYPE_ERROR*/"hi";
+ x = /*warning:INVALID_ASSIGNMENT*/"hi";
+ y = /*warning:INVALID_ASSIGNMENT*/"hi";
}
''');
});
@@ -157,8 +157,8 @@
class B { static var y = A.x; }
test1() {
- A.x = /*severe:STATIC_TYPE_ERROR*/"hi";
- B.y = /*severe:STATIC_TYPE_ERROR*/"hi";
+ A.x = /*warning:INVALID_ASSIGNMENT*/"hi";
+ B.y = /*warning:INVALID_ASSIGNMENT*/"hi";
}
''');
});
@@ -332,7 +332,7 @@
test('infer from complex expressions if the outer-most value is precise', () {
checkFile('''
- class A { int x; B operator+(other) {} }
+ class A { int x; B operator+(other) => null; }
class B extends A { B(ignore); }
var a = new A();
// Note: it doesn't matter that some of these refer to 'x'.
@@ -350,28 +350,28 @@
var j = null as B;
test1() {
- a = /*severe:STATIC_TYPE_ERROR*/"hi";
+ a = /*warning:INVALID_ASSIGNMENT*/"hi";
a = new B(3);
- b = /*severe:STATIC_TYPE_ERROR*/"hi";
+ b = /*warning:INVALID_ASSIGNMENT*/"hi";
b = new B(3);
c1 = [];
- c1 = /*severe:STATIC_TYPE_ERROR*/{};
+ c1 = /*warning:INVALID_ASSIGNMENT*/{};
c2 = [];
- c2 = /*severe:STATIC_TYPE_ERROR*/{};
+ c2 = /*warning:INVALID_ASSIGNMENT*/{};
d = {};
- d = /*severe:STATIC_TYPE_ERROR*/3;
+ d = /*warning:INVALID_ASSIGNMENT*/3;
e = new A();
- e = /*severe:STATIC_TYPE_ERROR*/{};
+ e = /*warning:INVALID_ASSIGNMENT*/{};
f = 3;
- f = /*severe:STATIC_TYPE_ERROR*/false;
+ f = /*warning:INVALID_ASSIGNMENT*/false;
g = 1;
- g = /*severe:STATIC_TYPE_ERROR*/false;
- h = /*severe:STATIC_TYPE_ERROR*/false;
+ g = /*warning:INVALID_ASSIGNMENT*/false;
+ h = /*warning:INVALID_ASSIGNMENT*/false;
h = new B('b');
i = false;
j = new B('b');
- j = /*severe:STATIC_TYPE_ERROR*/false;
- j = /*severe:STATIC_TYPE_ERROR*/[];
+ j = /*warning:INVALID_ASSIGNMENT*/false;
+ j = /*warning:INVALID_ASSIGNMENT*/[];
}
''');
});
@@ -448,7 +448,7 @@
class Bar<T extends Iterable<String>> {
void foo(T t) {
for (var i in t) {
- int x = /*severe:STATIC_TYPE_ERROR*/i;
+ int x = /*warning:INVALID_ASSIGNMENT*/i;
}
}
}
@@ -456,7 +456,7 @@
class Baz<T, E extends Iterable<T>, S extends E> {
void foo(S t) {
for (var i in t) {
- int x = /*severe:STATIC_TYPE_ERROR*/i;
+ int x = /*warning:INVALID_ASSIGNMENT*/i;
T y = i;
}
}
@@ -465,20 +465,22 @@
test() {
var list = <Foo>[];
for (var x in list) {
- String y = /*severe:STATIC_TYPE_ERROR*/x;
+ String y = /*warning:INVALID_ASSIGNMENT*/x;
}
for (dynamic x in list) {
- String y = /*info:DYNAMIC_CAST*/x;
+ // The INVALID_ASSIGNMENT hint is because type propagation knows x is
+ // a Foo.
+ String y = /*info:DYNAMIC_CAST,info:INVALID_ASSIGNMENT*/x;
}
- for (String x in /*severe:STATIC_TYPE_ERROR*/list) {
+ for (String x in /*warning:FOR_IN_OF_INVALID_ELEMENT_TYPE*/list) {
String y = x;
}
var z;
for(z in list) {
- String y = /*info:DYNAMIC_CAST*/z;
+ String y = /*info:DYNAMIC_CAST,info:INVALID_ASSIGNMENT*/z;
}
Iterable iter = list;
@@ -493,7 +495,7 @@
var map = <String, Foo>{};
// Error: map must be an Iterable.
- for (var x in /*severe:STATIC_TYPE_ERROR*/map) {
+ for (var x in /*warning:FOR_IN_OF_INVALID_TYPE*/map) {
String y = /*info:DYNAMIC_CAST*/x;
}
@@ -555,10 +557,10 @@
test5() {
var a1 = new A();
- a1.x = /*severe:STATIC_TYPE_ERROR*/"hi";
+ a1.x = /*warning:INVALID_ASSIGNMENT*/"hi";
A a2 = new A();
- a2.x = /*severe:STATIC_TYPE_ERROR*/"hi";
+ a2.x = /*warning:INVALID_ASSIGNMENT*/"hi";
}
''');
});
@@ -603,7 +605,7 @@
}
foo() {
- String y = /*severe:STATIC_TYPE_ERROR*/new B().x;
+ String y = /*warning:INVALID_ASSIGNMENT*/new B().x;
int z = new B().x;
}
''');
@@ -612,7 +614,7 @@
test('4', () {
checkFile('''
class A {
- int x = 2;
+ final int x = 2;
}
class B implements A {
@@ -620,7 +622,7 @@
}
foo() {
- String y = /*severe:STATIC_TYPE_ERROR*/new B().x;
+ String y = /*warning:INVALID_ASSIGNMENT*/new B().x;
int z = new B().x;
}
''');
@@ -631,7 +633,7 @@
test('infer', () {
checkFile('''
class A<T> {
- T x;
+ final T x = null;
}
class B implements A<int> {
@@ -648,17 +650,17 @@
test('3', () {
checkFile('''
class A<T> {
- T x;
- T w;
+ final T x = null;
+ final T w = null;
}
class B implements A<int> {
get x => 3;
- get w => /*severe:STATIC_TYPE_ERROR*/"hello";
+ get w => /*warning:RETURN_OF_INVALID_TYPE*/"hello";
}
foo() {
- String y = /*severe:STATIC_TYPE_ERROR*/new B().x;
+ String y = /*warning:INVALID_ASSIGNMENT*/new B().x;
int z = new B().x;
}
''');
@@ -676,7 +678,7 @@
}
foo() {
- int y = /*severe:STATIC_TYPE_ERROR*/new B<String>().x;
+ int y = /*warning:INVALID_ASSIGNMENT*/new B<String>().x;
String z = new B<String>().x;
}
''');
@@ -694,7 +696,7 @@
}
abstract class M {
- int y;
+ final int y = 0;
}
class B<E> extends A<E> implements M {
@@ -705,7 +707,7 @@
}
foo () {
- int y = /*severe:STATIC_TYPE_ERROR*/new B().m(null, null);
+ int y = /*warning:INVALID_ASSIGNMENT*/new B().m(null, null);
String z = new B().m(null, null);
}
''');
@@ -723,14 +725,14 @@
checkFile('''
import 'b.dart';
class C extends B {
- get x;
+ get x => null;
}
class A {
- int get x;
+ int get x => 0;
}
- foo () {
+ foo() {
int y = new C().x;
- String z = /*severe:STATIC_TYPE_ERROR*/new C().x;
+ String z = /*warning:INVALID_ASSIGNMENT*/new C().x;
}
''');
});
@@ -753,11 +755,11 @@
abstract class A<E> implements I<E> {
const A();
- E value;
+ final E value = null;
}
abstract class M {
- int y;
+ final int y = 0;
}
class B<E> extends A<E> implements M {
@@ -768,7 +770,7 @@
}
foo () {
- int y = /*severe:STATIC_TYPE_ERROR*/new B<String>().m(null, null).value;
+ int y = /*warning:INVALID_ASSIGNMENT*/new B<String>().m(null, null).value;
String z = new B<String>().m(null, null).value;
}
''');
@@ -778,7 +780,7 @@
test('infer', () {
checkFile('''
class A {
- int x = 2;
+ final int x = 2;
}
class B implements A {
@@ -803,11 +805,11 @@
}
class A {
- final I1 a;
+ final I1 a = null;
}
class B {
- final I2 a;
+ final I2 a = null;
}
class C1 implements A, B {
@@ -836,11 +838,11 @@
}
class A {
- final I1 a;
+ final I1 a = null;
}
class B {
- final I2 a;
+ final I2 a = null;
}
class C1 implements A, B {
@@ -873,7 +875,7 @@
test('infer from RHS only if it wont conflict with overridden fields 2', () {
checkFile('''
class A {
- final x;
+ final x = null;
}
class B implements A {
@@ -881,7 +883,7 @@
}
foo() {
- String y = /*severe:STATIC_TYPE_ERROR*/new B().x;
+ String y = /*warning:INVALID_ASSIGNMENT*/new B().x;
int z = new B().x;
}
''');
@@ -902,13 +904,13 @@
int i;
s = /*info:DYNAMIC_CAST*/new B().x;
- s = /*severe:STATIC_TYPE_ERROR*/new B().y;
+ s = /*warning:INVALID_ASSIGNMENT*/new B().y;
s = new B().z;
- s = /*severe:STATIC_TYPE_ERROR*/new B().w;
+ s = /*warning:INVALID_ASSIGNMENT*/new B().w;
i = /*info:DYNAMIC_CAST*/new B().x;
i = new B().y;
- i = /*severe:STATIC_TYPE_ERROR*/new B().z;
+ i = /*warning:INVALID_ASSIGNMENT*/new B().z;
i = new B().w;
}
''');
@@ -1046,7 +1048,7 @@
f(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/{y: x}]);
}
{
- int f(int x) {};
+ int f(int x) => 0;
A<int> a = /*info:INFERRED_TYPE_ALLOCATION*/new A(f);
}
}
@@ -1097,8 +1099,12 @@
A<int, String> a5 = /*severe:STATIC_TYPE_ERROR*/new A<dynamic, dynamic>.named(3, "hello");
}
{
- A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new A(/*severe:STATIC_TYPE_ERROR*/"hello", /*severe:STATIC_TYPE_ERROR*/3);
- A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new A.named(/*severe:STATIC_TYPE_ERROR*/"hello", /*severe:STATIC_TYPE_ERROR*/3);
+ A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new A(
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello",
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new A.named(
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello",
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
{
A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new B("hello", 3);
@@ -1109,8 +1115,12 @@
A<int, String> a5 = /*severe:STATIC_TYPE_ERROR*/new B<dynamic, dynamic>.named("hello", 3);
}
{
- A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new B(/*severe:STATIC_TYPE_ERROR*/3, /*severe:STATIC_TYPE_ERROR*/"hello");
- A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new B.named(/*severe:STATIC_TYPE_ERROR*/3, /*severe:STATIC_TYPE_ERROR*/"hello");
+ A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new B(
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3,
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
+ A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new B.named(
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3,
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
}
{
A<int, int> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new C(3);
@@ -1121,8 +1131,10 @@
A<int, int> a5 = /*severe:STATIC_TYPE_ERROR*/new C<dynamic>.named(3);
}
{
- A<int, int> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new C(/*severe:STATIC_TYPE_ERROR*/"hello");
- A<int, int> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new C.named(/*severe:STATIC_TYPE_ERROR*/"hello");
+ A<int, int> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new C(
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
+ A<int, int> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new C.named(
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
}
{
A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new D("hello");
@@ -1133,19 +1145,27 @@
A<int, String> a5 = /*severe:STATIC_TYPE_ERROR*/new D<dynamic, dynamic>.named("hello");
}
{
- A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new D(/*severe:STATIC_TYPE_ERROR*/3);
- A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new D.named(/*severe:STATIC_TYPE_ERROR*/3);
+ A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new D(
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new D.named(
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
}
{ // Currently we only allow variable constraints. Test that we reject.
A<C<int>, String> a0 = /*severe:STATIC_TYPE_ERROR*/new E("hello");
}
{ // Check named and optional arguments
- A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new F(3, "hello", a: /*info:INFERRED_TYPE_LITERAL*/[3], b: /*info:INFERRED_TYPE_LITERAL*/["hello"]);
- A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new F(3, "hello", a: /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"], b: /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/3]);
+ A<int, String> a0 = /*info:INFERRED_TYPE_ALLOCATION*/new F(3, "hello",
+ a: /*info:INFERRED_TYPE_LITERAL*/[3],
+ b: /*info:INFERRED_TYPE_LITERAL*/["hello"]);
+ A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new F(3, "hello",
+ a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
+ b: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3]);
A<int, String> a2 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello", 3, "hello");
A<int, String> a3 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello");
- A<int, String> a4 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello", /*severe:STATIC_TYPE_ERROR*/"hello", /*severe:STATIC_TYPE_ERROR*/3);
- A<int, String> a5 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello", /*severe:STATIC_TYPE_ERROR*/"hello");
+ A<int, String> a4 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello",
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ A<int, String> a5 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello",
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
}
}
''');
@@ -1156,15 +1176,15 @@
test('infer downwards', () {
checkFile('''
void foo([List<String> list1 = /*info:INFERRED_TYPE_LITERAL*/const [],
- List<String> list2 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:STATIC_TYPE_ERROR*/42]]) {
+ List<String> list2 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]]) {
}
void main() {
{
List<int> l0 = /*info:INFERRED_TYPE_LITERAL*/[];
List<int> l1 = /*info:INFERRED_TYPE_LITERAL*/[3];
- List<int> l2 = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"];
- List<int> l3 = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3];
+ List<int> l2 = /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
+ List<int> l3 = /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
{
List<dynamic> l0 = [];
@@ -1175,20 +1195,20 @@
{
List<int> l0 = /*severe:STATIC_TYPE_ERROR*/<num>[];
List<int> l1 = /*severe:STATIC_TYPE_ERROR*/<num>[3];
- List<int> l2 = /*severe:STATIC_TYPE_ERROR*/<num>[/*severe:STATIC_TYPE_ERROR*/"hello"];
- List<int> l3 = /*severe:STATIC_TYPE_ERROR*/<num>[/*severe:STATIC_TYPE_ERROR*/"hello", 3];
+ List<int> l2 = /*severe:STATIC_TYPE_ERROR*/<num>[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
+ List<int> l3 = /*severe:STATIC_TYPE_ERROR*/<num>[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
{
Iterable<int> i0 = /*info:INFERRED_TYPE_LITERAL*/[];
Iterable<int> i1 = /*info:INFERRED_TYPE_LITERAL*/[3];
- Iterable<int> i2 = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"];
- Iterable<int> i3 = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3];
+ Iterable<int> i2 = /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
+ Iterable<int> i3 = /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
{
const List<int> c0 = /*info:INFERRED_TYPE_LITERAL*/const [];
const List<int> c1 = /*info:INFERRED_TYPE_LITERAL*/const [3];
- const List<int> c2 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:STATIC_TYPE_ERROR*/"hello"];
- const List<int> c3 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:STATIC_TYPE_ERROR*/"hello", 3];
+ const List<int> c2 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
+ const List<int> c3 = /*info:INFERRED_TYPE_LITERAL*/const [/*severe:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
}
''');
@@ -1265,28 +1285,28 @@
void main() {
f0(/*info:INFERRED_TYPE_LITERAL*/[]);
f0(/*info:INFERRED_TYPE_LITERAL*/[3]);
- f0(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
- f0(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+ f0(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ f0(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f1(a: /*info:INFERRED_TYPE_LITERAL*/[]);
f1(a: /*info:INFERRED_TYPE_LITERAL*/[3]);
- f1(a: /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
- f1(a: /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+ f1(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ f1(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f2(/*info:INFERRED_TYPE_LITERAL*/[]);
f2(/*info:INFERRED_TYPE_LITERAL*/[3]);
- f2(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
- f2(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+ f2(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ f2(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f3(/*info:INFERRED_TYPE_LITERAL*/[]);
f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
- f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
+ f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
f4(a: /*info:INFERRED_TYPE_LITERAL*/[]);
f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
- f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
+ f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
}
''');
});
@@ -1313,30 +1333,30 @@
void main() {
new F0(/*info:INFERRED_TYPE_LITERAL*/[]);
new F0(/*info:INFERRED_TYPE_LITERAL*/[3]);
- new F0(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
- new F0(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello",
+ new F0(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F0(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello",
3]);
new F1(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F1(a: /*info:INFERRED_TYPE_LITERAL*/[3]);
- new F1(a: /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
- new F1(a: /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+ new F1(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F1(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F2(/*info:INFERRED_TYPE_LITERAL*/[]);
new F2(/*info:INFERRED_TYPE_LITERAL*/[3]);
- new F2(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
- new F2(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+ new F2(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F2(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
- new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"],
+ new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
- new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"],
+ new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
}
''');
@@ -1364,30 +1384,30 @@
void main() {
new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[]);
new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[3]);
- new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
- new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello",
+ new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello",
3]);
new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[3]);
- new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
- new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+ new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[]);
new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[3]);
- new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]);
- new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello", 3]);
+ new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
+ new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[]);
new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
- new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"],
+ new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
- new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"]]);
- new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"],
+ new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
+ new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[]);
@@ -1408,15 +1428,28 @@
test('infer downwards', () {
checkFile('''
void foo([Map<int, String> m1 = /*info:INFERRED_TYPE_LITERAL*/const {1: "hello"},
- Map<int, String> m2 = /*info:INFERRED_TYPE_LITERAL*/const {(/*severe:STATIC_TYPE_ERROR*/"hello"): "world"}]) {
+ Map<int, String> m2 = /*info:INFERRED_TYPE_LITERAL*/const {
+ // The warning is the type error, and the severe is the compile time
+ // error from const evaluation.
+ /*severe:MAP_KEY_TYPE_NOT_ASSIGNABLE,warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
+ "world"
+ }]) {
}
void main() {
{
Map<int, String> l0 = /*info:INFERRED_TYPE_LITERAL*/{};
Map<int, String> l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"};
- Map<int, String> l2 = /*info:INFERRED_TYPE_LITERAL*/{(/*severe:STATIC_TYPE_ERROR*/"hello"): "hello"};
- Map<int, String> l3 = /*info:INFERRED_TYPE_LITERAL*/{3: /*severe:STATIC_TYPE_ERROR*/3};
- Map<int, String> l4 = /*info:INFERRED_TYPE_LITERAL*/{3:"hello", (/*severe:STATIC_TYPE_ERROR*/"hello"): /*severe:STATIC_TYPE_ERROR*/3};
+ Map<int, String> l2 = /*info:INFERRED_TYPE_LITERAL*/{
+ /*warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": "hello"
+ };
+ Map<int, String> l3 = /*info:INFERRED_TYPE_LITERAL*/{
+ 3: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ };
+ Map<int, String> l4 = /*info:INFERRED_TYPE_LITERAL*/{
+ 3: "hello",
+ /*warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
+ /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ };
}
{
Map<dynamic, dynamic> l0 = {};
@@ -1429,15 +1462,25 @@
Map<dynamic, String> l0 = /*info:INFERRED_TYPE_LITERAL*/{};
Map<dynamic, String> l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"};
Map<dynamic, String> l2 = /*info:INFERRED_TYPE_LITERAL*/{"hello": "hello"};
- Map<dynamic, String> l3 = /*info:INFERRED_TYPE_LITERAL*/{3: /*severe:STATIC_TYPE_ERROR*/3};
- Map<dynamic, String> l4 = /*info:INFERRED_TYPE_LITERAL*/{3:"hello", "hello": /*severe:STATIC_TYPE_ERROR*/3};
+ Map<dynamic, String> l3 = /*info:INFERRED_TYPE_LITERAL*/{
+ 3: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ };
+ Map<dynamic, String> l4 = /*info:INFERRED_TYPE_LITERAL*/{
+ 3: "hello",
+ "hello": /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ };
}
{
Map<int, dynamic> l0 = /*info:INFERRED_TYPE_LITERAL*/{};
Map<int, dynamic> l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"};
- Map<int, dynamic> l2 = /*info:INFERRED_TYPE_LITERAL*/{(/*severe:STATIC_TYPE_ERROR*/"hello"): "hello"};
+ Map<int, dynamic> l2 = /*info:INFERRED_TYPE_LITERAL*/{
+ /*warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": "hello"
+ };
Map<int, dynamic> l3 = /*info:INFERRED_TYPE_LITERAL*/{3: 3};
- Map<int, dynamic> l4 = /*info:INFERRED_TYPE_LITERAL*/{3:"hello", (/*severe:STATIC_TYPE_ERROR*/"hello"): 3};
+ Map<int, dynamic> l4 = /*info:INFERRED_TYPE_LITERAL*/{
+ 3:"hello",
+ /*warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": 3
+ };
}
{
Map<int, String> l0 = /*severe:STATIC_TYPE_ERROR*/<num, dynamic>{};
@@ -1447,9 +1490,18 @@
{
const Map<int, String> l0 = /*info:INFERRED_TYPE_LITERAL*/const {};
const Map<int, String> l1 = /*info:INFERRED_TYPE_LITERAL*/const {3: "hello"};
- const Map<int, String> l2 = /*info:INFERRED_TYPE_LITERAL*/const {(/*severe:STATIC_TYPE_ERROR*/"hello"): "hello"};
- const Map<int, String> l3 = /*info:INFERRED_TYPE_LITERAL*/const {3: /*severe:STATIC_TYPE_ERROR*/3};
- const Map<int, String> l4 = /*info:INFERRED_TYPE_LITERAL*/const {3:"hello", (/*severe:STATIC_TYPE_ERROR*/"hello"): /*severe:STATIC_TYPE_ERROR*/3};
+ const Map<int, String> l2 = /*info:INFERRED_TYPE_LITERAL*/const {
+ /*severe:MAP_KEY_TYPE_NOT_ASSIGNABLE,warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
+ "hello"
+ };
+ const Map<int, String> l3 = /*info:INFERRED_TYPE_LITERAL*/const {
+ 3: /*severe:MAP_VALUE_TYPE_NOT_ASSIGNABLE,warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ };
+ const Map<int, String> l4 = /*info:INFERRED_TYPE_LITERAL*/const {
+ 3:"hello",
+ /*severe:MAP_KEY_TYPE_NOT_ASSIGNABLE,warning:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
+ /*severe:MAP_VALUE_TYPE_NOT_ASSIGNABLE,warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
+ };
}
}
''');
@@ -1464,28 +1516,28 @@
{
Function2<int, String> l0 = /*info:INFERRED_TYPE_CLOSURE*/(int x) => null;
Function2<int, String> l1 = (int x) => "hello";
- Function2<int, String> l2 = /*severe:STATIC_TYPE_ERROR*/(String x) => "hello";
- Function2<int, String> l3 = /*severe:STATIC_TYPE_ERROR*/(int x) => 3;
- Function2<int, String> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*severe:STATIC_TYPE_ERROR*/3;};
+ Function2<int, String> l2 = /*warning:INVALID_ASSIGNMENT*/(String x) => "hello";
+ Function2<int, String> l3 = /*warning:INVALID_ASSIGNMENT*/(int x) => 3;
+ Function2<int, String> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*warning:RETURN_OF_INVALID_TYPE*/3;};
}
{
Function2<int, String> l0 = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/(x) => null;
Function2<int, String> l1 = /*info:INFERRED_TYPE_CLOSURE*/(x) => "hello";
- Function2<int, String> l2 = /*info:INFERRED_TYPE_CLOSURE, severe:STATIC_TYPE_ERROR*/(x) => 3;
- Function2<int, String> l3 = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/(x) {return /*severe:STATIC_TYPE_ERROR*/3;};
- Function2<int, String> l4 = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/(x) {return /*severe:STATIC_TYPE_ERROR*/x;};
+ Function2<int, String> l2 = /*info:INFERRED_TYPE_CLOSURE, warning:INVALID_ASSIGNMENT*/(x) => 3;
+ Function2<int, String> l3 = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/(x) {return /*warning:RETURN_OF_INVALID_TYPE*/3;};
+ Function2<int, String> l4 = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/(x) {return /*warning:RETURN_OF_INVALID_TYPE*/x;};
}
{
Function2<int, List<String>> l0 = /*info:INFERRED_TYPE_CLOSURE*/(int x) => null;
Function2<int, List<String>> l1 = (int x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
- Function2<int, List<String>> l2 = /*severe:STATIC_TYPE_ERROR*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
- Function2<int, List<String>> l3 = (int x) => /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/3];
- Function2<int, List<String>> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/3];};
+ Function2<int, List<String>> l2 = /*warning:INVALID_ASSIGNMENT*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
+ Function2<int, List<String>> l3 = (int x) => /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
+ Function2<int, List<String>> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
}
{
Function2<int, int> l0 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x;
Function2<int, int> l1 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x+1;
- Function2<int, String> l2 = /*info:INFERRED_TYPE_CLOSURE, severe:STATIC_TYPE_ERROR*/(x) => x;
+ Function2<int, String> l2 = /*info:INFERRED_TYPE_CLOSURE, warning:INVALID_ASSIGNMENT*/(x) => x;
Function2<int, String> l3 = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*/(x) => /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/x.substring(3);
Function2<String, String> l4 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x.substring(3);
}
@@ -1501,27 +1553,27 @@
var v = f;
v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) => null;
v = /*<T>*/(int x) => "hello";
- v = /*severe:STATIC_TYPE_ERROR*//*<T>*/(String x) => "hello";
- v = /*severe:STATIC_TYPE_ERROR*//*<T>*/(int x) => 3;
- v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) {return /*severe:STATIC_TYPE_ERROR*/3;};
+ v = /*warning:INVALID_ASSIGNMENT*//*<T>*/(String x) => "hello";
+ v = /*warning:INVALID_ASSIGNMENT*//*<T>*/(int x) => 3;
+ v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) {return /*warning:RETURN_OF_INVALID_TYPE*/3;};
}
{
String f/*<S>*/(int x) => null;
var v = f;
v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => null;
v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => "hello";
- v = /*info:INFERRED_TYPE_CLOSURE, severe:STATIC_TYPE_ERROR*//*<T>*/(x) => 3;
- v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) {return /*severe:STATIC_TYPE_ERROR*/3;};
- v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) {return /*severe:STATIC_TYPE_ERROR*/x;};
+ v = /*info:INFERRED_TYPE_CLOSURE, warning:INVALID_ASSIGNMENT*//*<T>*/(x) => 3;
+ v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) {return /*warning:RETURN_OF_INVALID_TYPE*/3;};
+ v = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) {return /*warning:RETURN_OF_INVALID_TYPE*/x;};
}
{
List<String> f/*<S>*/(int x) => null;
var v = f;
v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) => null;
v = /*<T>*/(int x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
- v = /*severe:STATIC_TYPE_ERROR*//*<T>*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
- v = /*<T>*/(int x) => /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/3];
- v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/3];};
+ v = /*warning:INVALID_ASSIGNMENT*//*<T>*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
+ v = /*<T>*/(int x) => /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
+ v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
}
{
int int2int/*<S>*/(int x) => null;
@@ -1531,7 +1583,7 @@
x = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => x;
x = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => x+1;
var y = int2String;
- y = /*info:INFERRED_TYPE_CLOSURE, severe:STATIC_TYPE_ERROR*//*<T>*/(x) => x;
+ y = /*info:INFERRED_TYPE_CLOSURE, warning:INVALID_ASSIGNMENT*//*<T>*/(x) => x;
y = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => /*info:DYNAMIC_INVOKE, info:DYNAMIC_CAST*/x.substring(3);
var z = string2String;
z = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => x.substring(3);
@@ -1579,7 +1631,7 @@
test('downwards inference async/await', () {
checkFile('''
import 'dart:async';
- Future<int> test() async {
+ Future test() async {
dynamic d;
List<int> l0 = /*warning:DOWN_CAST_COMPOSITE should be pass*/await /*pass should be info:INFERRED_TYPE_LITERAL*/[d];
List<int> l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL*/[/*info:DYNAMIC_CAST*/d]);
@@ -1591,10 +1643,8 @@
checkFile('''
import 'dart:async';
Future main() async {
- for(int x in /*info:INFERRED_TYPE_LITERAL*/[1, 2, 3]) {
- }
- await for(int x in /*info:INFERRED_TYPE_ALLOCATION*/new Stream()) {
- }
+ for(int x in /*info:INFERRED_TYPE_LITERAL*/[1, 2, 3]) {}
+ await for(int x in /*info:INFERRED_TYPE_ALLOCATION*/new Stream()) {}
}
''');
});
@@ -1604,15 +1654,15 @@
import 'dart:async';
Stream<List<int>> foo() async* {
yield /*info:INFERRED_TYPE_LITERAL*/[];
- yield /*severe:STATIC_TYPE_ERROR*/new Stream();
- yield* /*severe:STATIC_TYPE_ERROR*/[];
+ yield /*warning:YIELD_OF_INVALID_TYPE*/new Stream();
+ yield* /*warning:YIELD_OF_INVALID_TYPE*/[];
yield* /*info:INFERRED_TYPE_ALLOCATION*/new Stream();
}
Iterable<Map<int, int>> bar() sync* {
yield /*info:INFERRED_TYPE_LITERAL*/{};
- yield /*severe:STATIC_TYPE_ERROR*/new List();
- yield* /*severe:STATIC_TYPE_ERROR*/{};
+ yield /*warning:YIELD_OF_INVALID_TYPE*/new List();
+ yield* /*warning:YIELD_OF_INVALID_TYPE*/{};
yield* /*info:INFERRED_TYPE_ALLOCATION*/new List();
}
''');
@@ -1635,7 +1685,7 @@
checkFile('''
void main() {
List<int> l;
- l = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"];
+ l = /*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
l = (l = /*info:INFERRED_TYPE_LITERAL*/[1]);
}
''');
@@ -1645,7 +1695,7 @@
checkFile('''
class Foo {
var x = 1;
- Foo([this.x = /*severe:STATIC_TYPE_ERROR*/"1"]);
+ Foo([this.x = /*warning:INVALID_ASSIGNMENT*/"1"]);
}''');
});
@@ -1679,8 +1729,8 @@
// Types other than int and double are not accepted.
printInt(
/*info:DOWN_CAST_IMPLICIT*/min(
- /*severe:STATIC_TYPE_ERROR*/"hi",
- /*severe:STATIC_TYPE_ERROR*/"there"));
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hi",
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"there"));
}
''');
});
@@ -1706,10 +1756,10 @@
checkFile('''
import 'dart:_foreign_helper' show JS;
main() {
- String x = /*severe:STATIC_TYPE_ERROR*/JS('int', '42');
+ String x = /*warning:INVALID_ASSIGNMENT*/JS('int', '42');
var y = JS('String', '"hello"');
y = "world";
- y = /*severe:STATIC_TYPE_ERROR*/42;
+ y = /*warning:INVALID_ASSIGNMENT*/42;
}
''');
});
@@ -1734,11 +1784,11 @@
takeIIO(math.max);
takeDDO(math.max);
- takeOOI(/*severe:STATIC_TYPE_ERROR*/math.max);
- takeIDI(/*severe:STATIC_TYPE_ERROR*/math.max);
- takeDID(/*severe:STATIC_TYPE_ERROR*/math.max);
- takeOON(/*severe:STATIC_TYPE_ERROR*/math.max);
- takeOOO(/*severe:STATIC_TYPE_ERROR*/math.max);
+ takeOOI(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+ takeIDI(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+ takeDID(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+ takeOON(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
+ takeOOO(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max);
// Also test SimpleIdentifier
takeIII(min);
@@ -1751,11 +1801,11 @@
takeIIO(min);
takeDDO(min);
- takeOOI(/*severe:STATIC_TYPE_ERROR*/min);
- takeIDI(/*severe:STATIC_TYPE_ERROR*/min);
- takeDID(/*severe:STATIC_TYPE_ERROR*/min);
- takeOON(/*severe:STATIC_TYPE_ERROR*/min);
- takeOOO(/*severe:STATIC_TYPE_ERROR*/min);
+ takeOOI(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+ takeIDI(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+ takeDID(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+ takeOON(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
+ takeOOO(/*severe:STATIC_TYPE_ERROR,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min);
// Also PropertyAccess
takeIII(new C().m);
@@ -1777,14 +1827,14 @@
//
// That's legal because we're loosening parameter types.
//
- takeOON(/*warning:DOWN_CAST_COMPOSITE*/new C().m);
- takeOOO(/*warning:DOWN_CAST_COMPOSITE*/new C().m);
+ takeOON(/*warning:DOWN_CAST_COMPOSITE,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+ takeOOO(/*warning:DOWN_CAST_COMPOSITE,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
// Note: this is a warning because a downcast of a method tear-off could work
// in "normal" Dart, due to bivariance.
- takeOOI(/*warning:DOWN_CAST_COMPOSITE*/new C().m);
- takeIDI(/*warning:DOWN_CAST_COMPOSITE*/new C().m);
- takeDID(/*warning:DOWN_CAST_COMPOSITE*/new C().m);
+ takeOOI(/*warning:DOWN_CAST_COMPOSITE,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+ takeIDI(/*warning:DOWN_CAST_COMPOSITE,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
+ takeDID(/*warning:DOWN_CAST_COMPOSITE,warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m);
}
void takeIII(int fn(int a, int b)) {}
@@ -1864,7 +1914,7 @@
new Foo<String>().method("str");
new Foo().method("str");
- new Foo<String>().method(/*severe:STATIC_TYPE_ERROR*/42);
+ new Foo<String>().method(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/42);
}
''');
});
@@ -1884,7 +1934,7 @@
/*=T*/ f/*<T>*/(List/*<T>*/ s) => null;
main() {
String x = f(/*info:INFERRED_TYPE_LITERAL*/['hi']);
- String y = f(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/42]);
+ String y = f(/*info:INFERRED_TYPE_LITERAL*/[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]);
}
''');
});
@@ -1939,14 +1989,14 @@
checkFile(r'''
test1() {
var x = [1, 2, 3];
- x.add(/*severe:STATIC_TYPE_ERROR*/'hi');
- x.add(/*severe:STATIC_TYPE_ERROR*/4.0);
+ x.add(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
+ x.add(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/4.0);
x.add(4);
List<num> y = x;
}
test2() {
var x = [1, 2.0, 3];
- x.add(/*severe:STATIC_TYPE_ERROR*/'hi');
+ x.add(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi');
x.add(4.0);
List<int> y = /*info:ASSIGNMENT_CAST*/x;
}
@@ -1969,18 +2019,18 @@
test1() {
var x = { 1: 'x', 2: 'y' };
x[3] = 'z';
- x[/*severe:STATIC_TYPE_ERROR*/'hi'] = 'w';
- x[/*severe:STATIC_TYPE_ERROR*/4.0] = 'u';
- x[3] = /*severe:STATIC_TYPE_ERROR*/42;
+ x[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'] = 'w';
+ x[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/4.0] = 'u';
+ x[3] = /*warning:INVALID_ASSIGNMENT*/42;
Map<num, String> y = x;
}
test2() {
var x = { 1: 'x', 2: 'y', 3.0: new RegExp('.') };
x[3] = 'z';
- x[/*severe:STATIC_TYPE_ERROR*/'hi'] = 'w';
+ x[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/'hi'] = 'w';
x[4.0] = 'u';
- x[3] = /*severe:STATIC_TYPE_ERROR*/42;
+ x[3] = /*warning:INVALID_ASSIGNMENT*/42;
Pattern p = null;
x[2] = p;
Map<int, String> y = /*info:ASSIGNMENT_CAST*/x;
@@ -2208,7 +2258,7 @@
main() {
String f() => null;
var g = f;
- g = /*info:INFERRED_TYPE_CLOSURE*/() { return /*severe:STATIC_TYPE_ERROR*/1; };
+ g = /*info:INFERRED_TYPE_CLOSURE*/() { return /*warning:RETURN_OF_INVALID_TYPE*/1; };
}
''');
var f = mainUnit.element.functions[0].localVariables[0];
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index e04fb30..e91033e 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -87,11 +87,17 @@
var librarySource = context.getLibrariesContaining(source).single;
var resolved = context.resolveCompilationUnit2(source, librarySource);
- errors.addAll(context.getErrors(source).errors.where((e) =>
- e.errorCode != HintCode.UNUSED_LOCAL_VARIABLE &&
- // TODO(jmesserly): these are usually intentional dynamic calls.
- e.errorCode.name != 'UNDEFINED_METHOD'));
+ errors.addAll(context.computeErrors(source).where((e) =>
+ // TODO(jmesserly): these are usually intentional dynamic calls.
+ e.errorCode.name != 'UNDEFINED_METHOD' &&
+ // We don't care about any of these:
+ e.errorCode != HintCode.UNNECESSARY_CAST &&
+ e.errorCode != HintCode.UNUSED_ELEMENT &&
+ e.errorCode != HintCode.UNUSED_FIELD &&
+ e.errorCode != HintCode.UNUSED_IMPORT &&
+ e.errorCode != HintCode.UNUSED_LOCAL_VARIABLE &&
+ e.errorCode != TodoCode.TODO));
_expectErrors(resolved, errors);
}
}
diff --git a/pkg/analyzer/tool/summary/build_sdk_summaries.dart b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
index 29f49db..4f5db1e 100644
--- a/pkg/analyzer/tool/summary/build_sdk_summaries.dart
+++ b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
@@ -7,47 +7,93 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/sdk_io.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/flat_buffers.dart' as fb;
import 'package:analyzer/src/summary/index_unit.dart';
import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:path/path.dart';
main(List<String> args) {
- if (args.length < 1 || args.length > 2) {
+ if (args.length < 1) {
_printUsage();
exitCode = 1;
return;
}
- //
- // Prepare output file path.
- //
- String outputDirectoryPath = args[0];
- if (!FileSystemEntity.isDirectorySync(outputDirectoryPath)) {
- print("'$outputDirectoryPath' is not a directory.");
- _printUsage();
- exitCode = 1;
- return;
- }
- //
- // Prepare SDK path.
- //
- String sdkPath;
- if (args.length == 2) {
- sdkPath = args[1];
- if (!FileSystemEntity.isDirectorySync('$sdkPath/lib')) {
- print("'$sdkPath/lib' does not exist.");
+ String command = args[0];
+ if (command == 'multiple-outputs' && args.length >= 2 && args.length <= 3) {
+ //
+ // Prepare the output path.
+ //
+ String outputDirectoryPath = args[1];
+ if (!FileSystemEntity.isDirectorySync(outputDirectoryPath)) {
+ print("'$outputDirectoryPath' is not a directory.");
_printUsage();
exitCode = 1;
return;
}
+ //
+ // Prepare results.
+ //
+ String sdkPath = args.length > 2 ? args[2] : null;
+ _Output output = _buildMultipleOutputs(sdkPath);
+ if (output == null) {
+ exitCode = 1;
+ return;
+ }
+ //
+ // Write results.
+ //
+ output.spec.writeMultiple(outputDirectoryPath, 'spec');
+ output.strong.writeMultiple(outputDirectoryPath, 'strong');
+ } else if (command == 'single-output' &&
+ args.length >= 2 &&
+ args.length <= 3) {
+ String outputPath = args[1];
+ String sdkPath = args.length > 2 ? args[2] : null;
+ //
+ // Prepare results.
+ //
+ _Output output = _buildMultipleOutputs(sdkPath);
+ if (output == null) {
+ exitCode = 1;
+ return;
+ }
+ //
+ // Write results.
+ //
+ fb.Builder builder = new fb.Builder();
+ fb.Offset specSumOffset = builder.writeListUint8(output.spec.sum);
+ fb.Offset specIndexOffset = builder.writeListUint8(output.spec.index);
+ fb.Offset strongSumOffset = builder.writeListUint8(output.strong.sum);
+ fb.Offset strongIndexOffset = builder.writeListUint8(output.strong.index);
+ builder.startTable();
+ builder.addOffset(_FIELD_SPEC_SUM, specSumOffset);
+ builder.addOffset(_FIELD_SPEC_INDEX, specIndexOffset);
+ builder.addOffset(_FIELD_STRONG_SUM, strongSumOffset);
+ builder.addOffset(_FIELD_STRONG_INDEX, strongIndexOffset);
+ fb.Offset offset = builder.endTable();
+ new File(outputPath)
+ .writeAsBytesSync(builder.finish(offset), mode: FileMode.WRITE_ONLY);
+ } else if (command == 'extract-spec-sum' && args.length == 3) {
+ String inputPath = args[1];
+ String outputPath = args[2];
+ _extractSingleOutput(inputPath, _FIELD_SPEC_SUM, outputPath);
+ } else if (command == 'extract-spec-index' && args.length == 3) {
+ String inputPath = args[1];
+ String outputPath = args[2];
+ _extractSingleOutput(inputPath, _FIELD_SPEC_INDEX, outputPath);
+ } else if (command == 'extract-strong-sum' && args.length == 3) {
+ String inputPath = args[1];
+ String outputPath = args[2];
+ _extractSingleOutput(inputPath, _FIELD_STRONG_SUM, outputPath);
+ } else if (command == 'extract-strong-index' && args.length == 3) {
+ String inputPath = args[1];
+ String outputPath = args[2];
+ _extractSingleOutput(inputPath, _FIELD_STRONG_INDEX, outputPath);
} else {
- sdkPath = DirectoryBasedDartSdk.defaultSdkDirectory.getAbsolutePath();
+ _printUsage();
+ exitCode = 1;
+ return;
}
- //
- // Build spec and strong summaries.
- //
- new _Builder(sdkPath, outputDirectoryPath, false).build();
- new _Builder(sdkPath, outputDirectoryPath, true).build();
}
/**
@@ -55,17 +101,67 @@
*/
const BINARY_NAME = "build_sdk_summaries";
+const int _FIELD_SPEC_INDEX = 1;
+const int _FIELD_SPEC_SUM = 0;
+const int _FIELD_STRONG_INDEX = 3;
+const int _FIELD_STRONG_SUM = 2;
+
+_Output _buildMultipleOutputs(String sdkPath) {
+ //
+ // Validate the SDK path.
+ //
+ if (sdkPath != null) {
+ if (!FileSystemEntity.isDirectorySync('$sdkPath/lib')) {
+ print("'$sdkPath/lib' does not exist.");
+ _printUsage();
+ return null;
+ }
+ } else {
+ sdkPath = DirectoryBasedDartSdk.defaultSdkDirectory.getAbsolutePath();
+ }
+ //
+ // Build spec and strong outputs.
+ //
+ _BuilderOutput spec = new _Builder(sdkPath, false).build();
+ _BuilderOutput strong = new _Builder(sdkPath, true).build();
+ return new _Output(spec, strong);
+}
+
+/**
+ * Open the flat buffer in [inputPath] and extract the byte array in the [field]
+ * into the [outputPath] file.
+ */
+void _extractSingleOutput(String inputPath, int field, String outputPath) {
+ List<int> bytes = new File(inputPath).readAsBytesSync();
+ fb.BufferPointer root = new fb.BufferPointer.fromBytes(bytes);
+ fb.BufferPointer table = root.derefObject();
+ List<int> fieldBytes = const fb.Uint8ListReader().vTableGet(table, field);
+ new File(outputPath).writeAsBytesSync(fieldBytes, mode: FileMode.WRITE_ONLY);
+}
+
/**
* Print information about how to use the SDK summaries builder.
*/
void _printUsage() {
- print('Usage: $BINARY_NAME output_directory_path [sdk_path]');
- print('Build files spec.sum and strong.sum in the output directory.');
+// print('Usage: $BINARY_NAME command output_directory_path [sdk_path]');
+ print('Usage: $BINARY_NAME command arguments');
+ print('Where command can be one of the following:');
+ print(' multiple-outputs output_directory_path [sdk_path]');
+ print(' Generate separate summary and index files.');
+ print(' single-output output_file_path [sdk_path]');
+ print(' Generate a single file with summary and index.');
+ print(' extract-spec-sum input_file output_file');
+ print(' Extract the spec-mode summary file.');
+ print(' extract-strong-sum input_file output_file');
+ print(' Extract the strong-mode summary file.');
+ print(' extract-spec-index input_file output_file');
+ print(' Extract the spec-mode index file.');
+ print(' extract-strong-index input_file output_file');
+ print(' Extract the strong-mode index file.');
}
class _Builder {
final String sdkPath;
- final String outputDirectoryPath;
final bool strongMode;
AnalysisContext context;
@@ -74,12 +170,12 @@
final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler();
final PackageIndexAssembler indexAssembler = new PackageIndexAssembler();
- _Builder(this.sdkPath, this.outputDirectoryPath, this.strongMode);
+ _Builder(this.sdkPath, this.strongMode);
/**
* Build a strong or spec mode summary for the Dart SDK at [sdkPath].
*/
- void build() {
+ _BuilderOutput build() {
String modeName = strongMode ? 'strong' : 'spec';
print('Generating $modeName mode summary and index.');
Stopwatch sw = new Stopwatch()..start();
@@ -107,27 +203,12 @@
_serializeLibrary(libSource);
}
//
- // Write the whole SDK bundle.
+ // Assemble the output.
//
- {
- PackageBundleBuilder bundle = bundleAssembler.assemble();
- String outputPath = join(outputDirectoryPath, '$modeName.sum');
- File file = new File(outputPath);
- file.writeAsBytesSync(bundle.toBuffer(), mode: FileMode.WRITE_ONLY);
- }
- //
- // Write the whole SDK index.
- //
- {
- PackageIndexBuilder index = indexAssembler.assemble();
- String outputPath = join(outputDirectoryPath, '$modeName.index');
- File file = new File(outputPath);
- file.writeAsBytesSync(index.toBuffer(), mode: FileMode.WRITE_ONLY);
- }
- //
- // Done.
- //
+ List<int> sumBytes = bundleAssembler.assemble().toBuffer();
+ List<int> indexBytes = indexAssembler.assemble().toBuffer();
print('\tDone in ${sw.elapsedMilliseconds} ms.');
+ return new _BuilderOutput(sumBytes, indexBytes);
}
/**
@@ -151,3 +232,32 @@
}
}
}
+
+class _BuilderOutput {
+ final List<int> sum;
+ final List<int> index;
+
+ _BuilderOutput(this.sum, this.index);
+
+ void writeMultiple(String outputDirectoryPath, String modeName) {
+ // Write summary.
+ {
+ String outputPath = join(outputDirectoryPath, '$modeName.sum');
+ File file = new File(outputPath);
+ file.writeAsBytesSync(sum, mode: FileMode.WRITE_ONLY);
+ }
+ // Write index.
+ {
+ String outputPath = join(outputDirectoryPath, '$modeName.index');
+ File file = new File(outputPath);
+ file.writeAsBytesSync(index, mode: FileMode.WRITE_ONLY);
+ }
+ }
+}
+
+class _Output {
+ final _BuilderOutput spec;
+ final _BuilderOutput strong;
+
+ _Output(this.spec, this.strong);
+}
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 79ff968..9bfb7eb 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -109,7 +109,7 @@
SerializationTask;
import 'script.dart' show
Script;
-import 'ssa/ssa.dart' show
+import 'ssa/nodes.dart' show
HInstruction;
import 'tracer.dart' show
Tracer;
diff --git a/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart b/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
index 41bb65e..4a018ef 100644
--- a/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
+++ b/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
@@ -2,8 +2,6 @@
import 'cps_ir_nodes.dart';
import 'optimizers.dart';
-import '../common/names.dart';
-import '../universe/selector.dart';
import 'type_mask_system.dart';
import 'cps_fragment.dart';
diff --git a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
index 1197012..faaf93e 100644
--- a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
+++ b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
@@ -12,7 +12,6 @@
import 'type_mask_system.dart';
import '../types/types.dart';
import '../world.dart';
-import '../elements/elements.dart';
import 'loop_effects.dart';
import 'effects.dart';
diff --git a/pkg/compiler/lib/src/cps_ir/cps_fragment.dart b/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
index c84e9a9..903b672 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
@@ -200,7 +200,8 @@
Continuation trueCont = new Continuation(<Parameter>[]);
Continuation falseCont = new Continuation(<Parameter>[]);
put(new LetCont.two(trueCont, falseCont,
- new Branch(condition, trueCont, falseCont, strict: strict)));
+ new Branch(condition, trueCont, falseCont,
+ sourceInformation, strict: strict)));
if (negate) {
context = trueCont;
return new CpsFragment(sourceInformation, falseCont);
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index 3bc7032..b7d7cdf 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -695,7 +695,7 @@
assert(!element.isInstanceMember);
assert(isOpen);
if (program.isJsInterop(element)) {
- return buildInvokeJsInteropMember(element, arguments);
+ return buildInvokeJsInteropMember(element, arguments, sourceInformation);
}
return addPrimitive(
new ir.InvokeStatic(element, selector, arguments, sourceInformation));
@@ -726,21 +726,24 @@
CallStructure callStructure,
TypeMask mask,
List<ir.Definition> arguments,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
Selector selector = callStructure.callSelector;
return _buildInvokeDynamic(
target, selector, mask, arguments, sourceInformation);
}
- ir.Primitive buildStaticNoSuchMethod(Selector selector,
- List<ir.Primitive> arguments) {
+ ir.Primitive buildStaticNoSuchMethod(
+ Selector selector,
+ List<ir.Primitive> arguments,
+ SourceInformation sourceInformation) {
ir.Primitive receiver = buildStringConstant('');
ir.Primitive name = buildStringConstant(selector.name);
ir.Primitive argumentList = buildListLiteral(null, arguments);
ir.Primitive expectedArgumentNames = buildNullConstant();
return buildStaticFunctionInvocation(
program.throwNoSuchMethod,
- <ir.Primitive>[receiver, name, argumentList, expectedArgumentNames]);
+ <ir.Primitive>[receiver, name, argumentList, expectedArgumentNames],
+ sourceInformation);
}
/// Create a [ir.Constant] from [value] and add it to the CPS term.
@@ -798,7 +801,8 @@
ir.Primitive buildConditional(
ir.Primitive condition,
ir.Primitive buildThenExpression(IrBuilder builder),
- ir.Primitive buildElseExpression(IrBuilder builder)) {
+ ir.Primitive buildElseExpression(IrBuilder builder),
+ SourceInformation sourceInformation) {
assert(isOpen);
// The then and else expressions are delimited.
@@ -832,7 +836,8 @@
new ir.LetCont.two(thenContinuation, elseContinuation,
new ir.Branch.strict(condition,
thenContinuation,
- elseContinuation))));
+ elseContinuation,
+ sourceInformation))));
environment = join.environment;
return environment.discard(1);
}
@@ -874,7 +879,7 @@
MethodElement method,
CallStructure callStructure,
List<ir.Primitive> arguments,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
// TODO(johnniwinther): This shouldn't be necessary.
SelectorKind kind = Elements.isOperatorName(method.name)
? SelectorKind.OPERATOR : SelectorKind.CALL;
@@ -886,7 +891,7 @@
/// Create a read access of the [method] on the super class, i.e. a
/// closurization of [method].
ir.Primitive buildSuperMethodGet(MethodElement method,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
// TODO(johnniwinther): This should have its own ir node.
return _buildInvokeSuper(
method,
@@ -910,7 +915,7 @@
/// [value].
ir.Primitive buildSuperSetterSet(MethodElement setter,
ir.Primitive value,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
// TODO(johnniwinther): This should have its own ir node.
_buildInvokeSuper(
setter,
@@ -924,7 +929,7 @@
/// the provided [index].
ir.Primitive buildSuperIndex(MethodElement method,
ir.Primitive index,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
return _buildInvokeSuper(
method, new Selector.index(), <ir.Primitive>[index],
sourceInformation);
@@ -935,7 +940,7 @@
ir.Primitive buildSuperIndexSet(MethodElement method,
ir.Primitive index,
ir.Primitive value,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
_buildInvokeSuper(method, new Selector.indexSet(),
<ir.Primitive>[index, value], sourceInformation);
return value;
@@ -948,7 +953,7 @@
Selector selector,
TypeMask mask,
List<ir.Primitive> arguments,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
return _buildInvokeDynamic(
receiver, selector, mask, arguments, sourceInformation);
}
@@ -964,7 +969,7 @@
if (field != null) {
// If the world says this resolves to a unique field, then it MUST be
// treated as a field access, since the getter might not be emitted.
- return buildFieldGet(receiver, field);
+ return buildFieldGet(receiver, field, sourceInformation);
} else {
return _buildInvokeDynamic(
receiver, selector, mask, const <ir.Primitive>[], sourceInformation);
@@ -977,13 +982,13 @@
Selector selector,
TypeMask mask,
ir.Primitive value,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
assert(selector.isSetter);
FieldElement field = program.locateSingleField(selector, mask);
if (field != null) {
// If the world says this resolves to a unique field, then it MUST be
// treated as a field access, since the setter might not be emitted.
- buildFieldSet(receiver, field, value);
+ buildFieldSet(receiver, field, value, sourceInformation);
} else {
_buildInvokeDynamic(receiver, selector, mask, <ir.Primitive>[value],
sourceInformation);
@@ -997,7 +1002,7 @@
TypeMask mask,
ir.Primitive index,
ir.Primitive value,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
_buildInvokeDynamic(
receiver, new Selector.indexSet(), mask, <ir.Primitive>[index, value],
sourceInformation);
@@ -1015,7 +1020,7 @@
// TODO(johnniwinther): Maybe this should have its own ir node.
return buildCallInvocation(
buildLocalGet(function), callStructure, arguments,
- sourceInformation: sourceInformation);
+ sourceInformation);
}
/// Create a static invocation of [function].
@@ -1024,7 +1029,7 @@
ir.Primitive buildStaticFunctionInvocation(
MethodElement function,
List<ir.Primitive> arguments,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
Selector selector = new Selector.call(
function.memberName, new CallStructure(arguments.length));
return buildInvokeStatic(function, selector, arguments, sourceInformation);
@@ -1041,7 +1046,7 @@
/// Create a write access to the static [field] with the [value].
ir.Primitive buildStaticFieldSet(FieldElement field,
ir.Primitive value,
- [SourceInformation sourceInformation]) {
+ SourceInformation sourceInformation) {
addPrimitive(new ir.SetStatic(field, value, sourceInformation));
return value;
}
@@ -1049,7 +1054,7 @@
/// Create a setter invocation of the static [setter] with the [value].
ir.Primitive buildStaticSetterSet(MethodElement setter,
ir.Primitive value,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
Selector selector = new Selector.setter(setter.memberName);
buildInvokeStatic(
setter, selector, <ir.Primitive>[value], sourceInformation);
@@ -1062,14 +1067,15 @@
ir.Primitive buildErroneousInvocation(
Element element,
Selector selector,
- List<ir.Primitive> arguments) {
+ List<ir.Primitive> arguments,
+ SourceInformation sourceInformation) {
// TODO(johnniwinther): This should have its own ir node.
- return buildInvokeStatic(element, selector, arguments, null);
+ return buildInvokeStatic(element, selector, arguments, sourceInformation);
}
/// Concatenate string values. The arguments must be strings.
ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
assert(isOpen);
return addPrimitive(new ir.ApplyBuiltinOperator(
ir.BuiltinOperator.StringConcatenate,
@@ -1084,9 +1090,9 @@
ir.Primitive functionExpression,
CallStructure callStructure,
List<ir.Definition> arguments,
- {SourceInformation sourceInformation}) {
- return _buildInvokeCall(functionExpression, callStructure, null, arguments,
- sourceInformation: sourceInformation);
+ SourceInformation sourceInformation) {
+ return _buildInvokeCall(
+ functionExpression, callStructure, null, arguments, sourceInformation);
}
/// Creates an if-then-else statement with the provided [condition] where the
@@ -1098,7 +1104,8 @@
// [_buildLogicalOperator].
void buildIf(ir.Primitive condition,
void buildThenPart(IrBuilder builder),
- void buildElsePart(IrBuilder builder)) {
+ void buildElsePart(IrBuilder builder),
+ SourceInformation sourceInformation) {
assert(isOpen);
// The then and else parts are delimited.
@@ -1126,7 +1133,8 @@
new ir.LetCont.many(arms,
new ir.Branch.strict(condition,
thenContinuation,
- elseContinuation));
+ elseContinuation,
+ sourceInformation));
JumpCollector join; // Null if there is no join.
if (thenBuilder.isOpen && elseBuilder.isOpen) {
@@ -1194,6 +1202,7 @@
/// initializer.
void buildFor({SubbuildFunction buildInitializer,
SubbuildFunction buildCondition,
+ SourceInformation conditionSourceInformation,
SubbuildFunction buildBody,
SubbuildFunction buildUpdate,
JumpTarget target,
@@ -1298,7 +1307,8 @@
new ir.LetCont.two(exitContinuation, bodyContinuation,
new ir.Branch.strict(condition,
bodyContinuation,
- exitContinuation));
+ exitContinuation,
+ conditionSourceInformation));
// If there are breaks in the body, then there must be a join-point
// continuation for the normal exit and the breaks. Otherwise, the
// successor is translated in the hole in the exit continuation.
@@ -1337,12 +1347,17 @@
Element variableElement,
Selector variableSelector,
TypeMask variableMask,
+ SourceInformation variableSetSourceInformation,
TypeMask currentMask,
+ SourceInformation currentSourceInformation,
TypeMask iteratorMask,
+ SourceInformation iteratorSourceInformation,
TypeMask moveNextMask,
+ SourceInformation moveNextSourceInformation,
SubbuildFunction buildBody,
JumpTarget target,
- ClosureScope closureScope}) {
+ ClosureScope closureScope,
+ SourceInformation conditionSourceInformation}) {
// The for-in loop
//
// for (a in e) s;
@@ -1400,10 +1415,14 @@
iterator,
Selectors.current,
currentMask,
- emptyArguments));
+ emptyArguments,
+ sourceInformation: currentSourceInformation));
// TODO(johnniwinther): Extract this as a provided strategy.
if (Elements.isLocal(variableElement)) {
- bodyBuilder.buildLocalVariableSet(variableElement, currentValue);
+ bodyBuilder.buildLocalVariableSet(
+ variableElement,
+ currentValue,
+ variableSetSourceInformation);
} else if (Elements.isError(variableElement) ||
Elements.isMalformed(variableElement)) {
Selector selector = new Selector.setter(
@@ -1412,22 +1431,27 @@
// Note the comparison below. It can be the case that an element isError
// and isMalformed.
if (Elements.isError(variableElement)) {
- bodyBuilder.buildStaticNoSuchMethod(selector, value);
+ bodyBuilder.buildStaticNoSuchMethod(selector, value,
+ variableSetSourceInformation);
} else {
- bodyBuilder.buildErroneousInvocation(variableElement, selector, value);
+ bodyBuilder.buildErroneousInvocation(
+ variableElement, selector, value, variableSetSourceInformation);
}
} else if (Elements.isStaticOrTopLevel(variableElement)) {
if (variableElement.isField) {
bodyBuilder.addPrimitive(
- new ir.SetStatic(variableElement, currentValue));
+ new ir.SetStatic(
+ variableElement, currentValue, variableSetSourceInformation));
} else {
- bodyBuilder.buildStaticSetterSet(variableElement, currentValue);
+ bodyBuilder.buildStaticSetterSet(
+ variableElement, currentValue, variableSetSourceInformation);
}
} else {
ir.Primitive receiver = bodyBuilder.buildThis();
assert(receiver != null);
bodyBuilder.buildDynamicSet(
- receiver, variableSelector, variableMask, currentValue);
+ receiver, variableSelector, variableMask, currentValue,
+ variableSetSourceInformation);
}
// Translate the body in the hole in the delimited term above, and add
@@ -1457,7 +1481,8 @@
new ir.LetCont.two(exitContinuation, bodyContinuation,
new ir.Branch.strict(condition,
bodyContinuation,
- exitContinuation));
+ exitContinuation,
+ conditionSourceInformation));
// If there are breaks in the body, then there must be a join-point
// continuation for the normal exit and the breaks. Otherwise, the
// successor is translated in the hole in the exit continuation.
@@ -1483,7 +1508,8 @@
void buildWhile({SubbuildFunction buildCondition,
SubbuildFunction buildBody,
JumpTarget target,
- ClosureScope closureScope}) {
+ ClosureScope closureScope,
+ SourceInformation sourceInformation}) {
assert(isOpen);
// While loops use four named continuations: the entry to the body, the
// loop exit, the loop back edge (continue), and the loop exit (break).
@@ -1532,7 +1558,8 @@
new ir.LetCont.two(exitContinuation, bodyContinuation,
new ir.Branch.strict(condition,
bodyContinuation,
- exitContinuation));
+ exitContinuation,
+ sourceInformation));
// If there are breaks in the body, then there must be a join-point
// continuation for the normal exit and the breaks. Otherwise, the
// successor is translated in the hole in the exit continuation.
@@ -1561,7 +1588,8 @@
void buildDoWhile({SubbuildFunction buildBody,
SubbuildFunction buildCondition,
JumpTarget target,
- ClosureScope closureScope}) {
+ ClosureScope closureScope,
+ SourceInformation sourceInformation}) {
assert(isOpen);
// The CPS translation of [[do body; while (condition); successor]] is:
//
@@ -1618,7 +1646,8 @@
new ir.LetCont.two(exitContinuation, repeatContinuation,
new ir.Branch.strict(condition,
repeatContinuation,
- exitContinuation)));
+ exitContinuation,
+ sourceInformation)));
continueCollector.continuation.body = continueBuilder.root;
// Construct the loop continuation (i.e., the body and condition).
@@ -1653,7 +1682,8 @@
new ir.LetCont.two(elseContinuation, thenContinuation,
new ir.Branch.strict(condition,
thenContinuation,
- elseContinuation)));
+ elseContinuation,
+ caseInfo.sourceInformation)));
}
if (buildDefaultBody == null) {
@@ -1857,11 +1887,13 @@
ir.Primitive typeMatches =
checkBuilder.buildTypeOperator(exceptionParameter,
clause.type,
+ clause.sourceInformation,
isTypeTest: true);
checkBuilder.add(new ir.LetCont.two(thenContinuation, elseContinuation,
new ir.Branch.strict(typeMatches,
thenContinuation,
- elseContinuation)));
+ elseContinuation,
+ clause.sourceInformation)));
catchBody = checkBuilder.root;
}
builder.add(catchBody);
@@ -2009,8 +2041,10 @@
/// Generate the body for a native function [function] that is annotated with
/// an implementation in JavaScript (provided as string in [javaScriptCode]).
- void buildNativeFunctionBody(FunctionElement function,
- String javaScriptCode) {
+ void buildNativeFunctionBody(
+ FunctionElement function,
+ String javaScriptCode,
+ SourceInformation sourceInformation) {
NativeBehavior behavior = new NativeBehavior();
behavior.sideEffects.setAllSideEffects();
// Generate a [ForeignCode] statement from the given native code.
@@ -2018,7 +2052,8 @@
js.js.statementTemplateYielding(
new js.LiteralStatement(javaScriptCode)),
<ir.Primitive>[],
- behavior);
+ behavior,
+ sourceInformation);
}
/// Generate the body for a native function that redirects to a native
@@ -2029,7 +2064,7 @@
/// be the JavaScript implementation of a function, getter, or setter.
void buildRedirectingNativeFunctionBody(FunctionElement function,
String name,
- SourceInformation source) {
+ SourceInformation sourceInformation) {
List<ir.Primitive> arguments = <ir.Primitive>[];
NativeBehavior behavior = new NativeBehavior();
behavior.sideEffects.setAllSideEffects();
@@ -2050,7 +2085,8 @@
// typedef(s).
ir.Constant arity = buildIntegerConstant(type.computeArity());
input = buildStaticFunctionInvocation(
- program.closureConverter, <ir.Primitive>[input, arity]);
+ program.closureConverter, <ir.Primitive>[input, arity],
+ sourceInformation);
}
arguments.add(input);
argumentTemplates.add('#');
@@ -2070,16 +2106,19 @@
js.js.uncachedExpressionTemplate(code),
arguments,
behavior,
+ sourceInformation,
type: program.getTypeMaskForNativeFunction(function));
- buildReturn(value: value, sourceInformation: source);
+ buildReturn(value: value, sourceInformation: sourceInformation);
}
static _isNotNull(ir.Primitive value) =>
!(value is ir.Constant && value.value.isNull);
/// Builds a call to a resolved js-interop element.
- ir.Primitive buildInvokeJsInteropMember(FunctionElement element,
- List<ir.Primitive> arguments) {
+ ir.Primitive buildInvokeJsInteropMember(
+ FunctionElement element,
+ List<ir.Primitive> arguments,
+ SourceInformation sourceInformation) {
program.addNativeMethod(element);
String target = program.getJsInteropTargetPath(element);
// Strip off trailing arguments that were not specified.
@@ -2119,14 +2158,17 @@
var args = new List.filled(inputs.length, '#').join(',');
code = element.isConstructor ? "new $target($args)" : "$target($args)";
}
- return buildForeignCode(js.js.parseForeignJS(code), inputs, behavior);
+ return buildForeignCode(js.js.parseForeignJS(code),
+ inputs, behavior, sourceInformation);
// TODO(sigmund): should we record the source-information here?
}
/// Builds an object literal that results from invoking a factory constructor
/// of a js-interop anonymous type.
- ir.Primitive buildJsInteropObjectLiteral(ConstructorElement constructor,
- List<ir.Primitive> arguments, {SourceInformation source}) {
+ ir.Primitive buildJsInteropObjectLiteral(
+ ConstructorElement constructor,
+ List<ir.Primitive> arguments,
+ SourceInformation sourceInformation) {
assert(program.isJsInteropAnonymous(constructor));
program.addNativeMethod(constructor);
FunctionSignature params = constructor.functionSignature;
@@ -2150,8 +2192,8 @@
behavior.typesReturned.add(constructor.enclosingClass.thisType);
}
- // TODO(sigmund): should we record the source-information here?
- return buildForeignCode(code, filteredArguments, behavior);
+ return buildForeignCode(
+ code, filteredArguments, behavior, sourceInformation);
}
/// Create a blocks of [statements] by applying [build] to all reachable
@@ -2248,7 +2290,9 @@
}
/// Create a negation of [condition].
- ir.Primitive buildNegation(ir.Primitive condition) {
+ ir.Primitive buildNegation(
+ ir.Primitive condition,
+ SourceInformation sourceInformation) {
// ! e is translated as e ? false : true
// Add a continuation parameter for the result of the expression.
@@ -2274,7 +2318,8 @@
new ir.LetCont.two(thenContinuation, elseContinuation,
new ir.Branch.strict(condition,
thenContinuation,
- elseContinuation))));
+ elseContinuation,
+ sourceInformation))));
return resultParameter;
}
@@ -2284,6 +2329,7 @@
ir.Primitive buildLogicalOperator(
ir.Primitive leftValue,
ir.Primitive buildRightValue(IrBuilder builder),
+ SourceInformation sourceInformation,
{bool isLazyOr: false}) {
// e0 && e1 is translated as if e0 ? (e1 == true) : false.
// e0 || e1 is translated as if e0 ? true : (e1 == true).
@@ -2334,7 +2380,8 @@
new ir.LetCont.two(rightTrueContinuation, rightFalseContinuation,
new ir.Branch.strict(rightValue,
rightTrueContinuation,
- rightFalseContinuation)));
+ rightFalseContinuation,
+ sourceInformation)));
// Depending on the operator, the left subexpression's continuations are
// either the right subexpression or an invocation of the join-point
// continuation.
@@ -2350,7 +2397,8 @@
new ir.LetCont.two(leftTrueContinuation, leftFalseContinuation,
new ir.Branch.strict(leftValue,
leftTrueContinuation,
- leftFalseContinuation))));
+ leftFalseContinuation,
+ sourceInformation))));
environment = join.environment;
return environment.discard(1);
}
@@ -2503,16 +2551,23 @@
}
/// Create a read access of [local] function, variable, or parameter.
- ir.Primitive buildLocalGet(LocalElement local) {
+ // TODO(johnniwinther): Make [sourceInformation] mandatory.
+ ir.Primitive buildLocalGet(
+ LocalElement local,
+ {SourceInformation sourceInformation}) {
assert(isOpen);
ClosureLocation location = state.boxedVariables[local];
if (location != null) {
- ir.Primitive result = new ir.GetField(environment.lookup(location.box),
- location.field);
+ ir.Primitive result = new ir.GetField(
+ environment.lookup(location.box),
+ location.field,
+ sourceInformation: sourceInformation);
result.useElementAsHint(local);
return addPrimitive(result);
} else if (isInMutableVariable(local)) {
- return addPrimitive(new ir.GetMutable(getMutableVariable(local)));
+ return addPrimitive(
+ new ir.GetMutable(
+ getMutableVariable(local), sourceInformation: sourceInformation));
} else {
return environment.lookup(local);
}
@@ -2520,17 +2575,23 @@
/// Create a write access to [local] variable or parameter with the provided
/// [value].
- ir.Primitive buildLocalVariableSet(LocalElement local, ir.Primitive value) {
+ ir.Primitive buildLocalVariableSet(
+ LocalElement local,
+ ir.Primitive value,
+ SourceInformation sourceInformation) {
assert(isOpen);
ClosureLocation location = state.boxedVariables[local];
if (location != null) {
addPrimitive(new ir.SetField(
environment.lookup(location.box),
location.field,
- value));
+ value,
+ sourceInformation: sourceInformation));
} else if (isInMutableVariable(local)) {
addPrimitive(new ir.SetMutable(
- getMutableVariable(local), value));
+ getMutableVariable(local),
+ value,
+ sourceInformation: sourceInformation));
} else {
value.useElementAsHint(local);
environment.update(local, value);
@@ -2589,23 +2650,38 @@
return state.thisParameter;
}
- ir.Primitive buildFieldGet(ir.Primitive receiver, FieldElement target) {
+ ir.Primitive buildFieldGet(
+ ir.Primitive receiver,
+ FieldElement target,
+ SourceInformation sourceInformation) {
return addPrimitive(new ir.GetField(receiver, target,
+ sourceInformation: sourceInformation,
isFinal: program.fieldNeverChanges(target)));
}
void buildFieldSet(ir.Primitive receiver,
FieldElement target,
- ir.Primitive value) {
- addPrimitive(new ir.SetField(receiver, target, value));
+ ir.Primitive value,
+ SourceInformation sourceInformation) {
+ addPrimitive(new ir.SetField(
+ receiver, target, value, sourceInformation: sourceInformation));
}
- ir.Primitive buildSuperFieldGet(FieldElement target) {
- return addPrimitive(new ir.GetField(buildThis(), target));
+ ir.Primitive buildSuperFieldGet(
+ FieldElement target,
+ SourceInformation sourceInformation) {
+ return addPrimitive(
+ new ir.GetField(
+ buildThis(), target, sourceInformation: sourceInformation));
}
- ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) {
- addPrimitive(new ir.SetField(buildThis(), target, value));
+ ir.Primitive buildSuperFieldSet(
+ FieldElement target,
+ ir.Primitive value,
+ SourceInformation sourceInformation) {
+ addPrimitive(
+ new ir.SetField(
+ buildThis(), target, value, sourceInformation: sourceInformation));
return value;
}
@@ -2642,10 +2718,10 @@
ClassElement cls = element.enclosingClass;
if (program.isJsInterop(element)) {
if (program.isJsInteropAnonymous(element)) {
- return buildJsInteropObjectLiteral(element, arguments,
- source: sourceInformation);
+ return buildJsInteropObjectLiteral(
+ element, arguments, sourceInformation);
}
- return buildInvokeJsInteropMember(element, arguments);
+ return buildInvokeJsInteropMember(element, arguments, sourceInformation);
}
if (program.requiresRuntimeTypesFor(cls)) {
InterfaceType interface = type;
@@ -2731,6 +2807,7 @@
ir.Primitive buildForeignCode(js.Template codeTemplate,
List<ir.Primitive> arguments,
NativeBehavior behavior,
+ SourceInformation sourceInformation,
{Element dependency,
TypeMask type}) {
assert(behavior != null);
@@ -2749,6 +2826,7 @@
type,
arguments,
behavior,
+ sourceInformation,
dependency: dependency));
if (!codeTemplate.isExpression) {
// Close the term if this is a "throw" expression or native body.
@@ -2761,6 +2839,7 @@
/// Creates a type test or type cast of [value] against [type].
ir.Primitive buildTypeOperator(ir.Primitive value,
DartType type,
+ SourceInformation sourceInformation,
{bool isTypeTest}) {
assert(isOpen);
assert(isTypeTest != null);
@@ -2772,7 +2851,8 @@
ir.Primitive message = buildStringConstant(element.message);
return buildStaticFunctionInvocation(
program.throwTypeErrorHelper,
- <ir.Primitive>[message]);
+ <ir.Primitive>[message],
+ sourceInformation);
}
List<ir.Primitive> typeArguments = const <ir.Primitive>[];
@@ -2795,7 +2875,7 @@
}
if (type is InterfaceType && type.element == program.nullClass) {
// `x is Null` is true if and only if x is null.
- return _buildCheckNull(value);
+ return _buildCheckNull(value, sourceInformation);
}
return addPrimitive(new ir.TypeTest(value, type, typeArguments));
} else {
@@ -2813,10 +2893,11 @@
/// evaluated to produce the `right` value.
ir.Primitive buildIfNull(ir.Primitive value,
ir.Primitive buildRight(IrBuilder builder),
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
ir.Primitive condition =
- _buildCheckNull(value, sourceInformation: sourceInformation);
- return buildConditional(condition, buildRight, (_) => value);
+ _buildCheckNull(value, sourceInformation);
+ return buildConditional(
+ condition, buildRight, (_) => value, sourceInformation);
}
/// Create a conditional send. This is equivalent to a conditional expression
@@ -2824,15 +2905,16 @@
/// evaluates the [buildSend] expression.
ir.Primitive buildIfNotNullSend(ir.Primitive receiver,
ir.Primitive buildSend(IrBuilder builder),
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
ir.Primitive condition =
- _buildCheckNull(receiver, sourceInformation: sourceInformation);
- return buildConditional(condition, (_) => receiver, buildSend);
+ _buildCheckNull(receiver, sourceInformation);
+ return buildConditional(
+ condition, (_) => receiver, buildSend, sourceInformation);
}
/// Creates a type test checking whether [value] is null.
ir.Primitive _buildCheckNull(ir.Primitive value,
- {SourceInformation sourceInformation}) {
+ SourceInformation sourceInformation) {
assert(isOpen);
return buildIdentical(value, buildNullConstant(),
sourceInformation: sourceInformation);
@@ -2933,16 +3015,19 @@
final LocalVariableElement exceptionVariable;
final LocalVariableElement stackTraceVariable;
final SubbuildFunction buildCatchBlock;
+ final SourceInformation sourceInformation;
CatchClauseInfo({this.type,
this.exceptionVariable,
this.stackTraceVariable,
- this.buildCatchBlock});
+ this.buildCatchBlock,
+ this.sourceInformation});
}
class SwitchCaseInfo {
final SubbuildFunction buildCondition;
final SubbuildFunction buildBody;
+ final SourceInformation sourceInformation;
- SwitchCaseInfo(this.buildCondition, this.buildBody);
+ SwitchCaseInfo(this.buildCondition, this.buildBody, this.sourceInformation);
}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index 6b19607..6957274 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -48,7 +48,7 @@
// TODO(karlklose): remove.
import '../js/js.dart' as js show js, Template, Expression, Name;
-import '../ssa/ssa.dart' show TypeMaskFactory;
+import '../ssa/types.dart' show TypeMaskFactory;
import '../util/util.dart';
import 'package:js_runtime/shared/embedded_names.dart'
@@ -59,6 +59,15 @@
typedef void IrBuilderCallback(Element element, ir.FunctionDefinition irNode);
+class ExplicitReceiverParameter implements Local {
+ final ExecutableElement executableContext;
+
+ ExplicitReceiverParameter(this.executableContext);
+
+ String get name => 'receiver';
+ String toString() => 'ExplicitReceiverParameter($executableContext)';
+}
+
/// This task provides the interface to build IR nodes from [ast.Node]s, which
/// is used from the [CpsFunctionCompiler] to generate code.
///
@@ -308,8 +317,8 @@
if (constructor.isSynthesized) return null;
ast.FunctionExpression node = constructor.node;
// If we know the body doesn't have any code, we don't generate it.
- if (!node.hasBody()) return null;
- if (node.hasEmptyBody()) return null;
+ if (!node.hasBody) return null;
+ if (node.hasEmptyBody) return null;
ClassElement classElement = constructor.enclosingClass;
ConstructorBodyElement bodyElement;
classElement.forEachBackendMember((Element backendMember) {
@@ -388,6 +397,10 @@
return withBuilder(builder, () {
// Setup parameters and create a box if anything is captured.
List<Local> parameters = <Local>[];
+ if (constructor.isGenerativeConstructor &&
+ backend.isNativeOrExtendsNative(classElement)) {
+ parameters.add(new ExplicitReceiverParameter(constructor));
+ }
constructor.functionSignature.orderedForEachParameter(
(ParameterElement p) => parameters.add(p));
@@ -446,9 +459,11 @@
// --- Create the object ---
// Get the initial field values in the canonical order.
List<ir.Primitive> instanceArguments = <ir.Primitive>[];
+ List<FieldElement> fields = <FieldElement>[];
classElement.forEachInstanceField((ClassElement c, FieldElement field) {
ir.Primitive value = fieldValues[field];
if (value != null) {
+ fields.add(field);
instanceArguments.add(value);
} else {
assert(backend.isNativeOrExtendsNative(c));
@@ -456,16 +471,30 @@
}
}, includeSuperAndInjectedMembers: true);
- ir.Primitive instance = new ir.CreateInstance(
+ ir.Primitive instance;
+ if (constructor.isGenerativeConstructor &&
+ backend.isNativeOrExtendsNative(classElement)) {
+ instance = irParameters.first;
+ instance.type =
+ new TypeMask.exact(classElement, typeMaskSystem.classWorld);
+ irBuilder.addPrimitive(new ir.ReceiverCheck.nullCheck(
+ instance, Selectors.toString_, null));
+ for (int i = 0; i < fields.length; i++) {
+ irBuilder.addPrimitive(
+ new ir.SetField(instance, fields[i], instanceArguments[i]));
+ }
+ } else {
+ instance = new ir.CreateInstance(
classElement,
instanceArguments,
typeInformation,
constructor.hasNode
? sourceInformationBuilder.buildCreate(constructor.node)
- // TODO(johnniwinther): Provide source information for creation
- // through synthetic constructors.
+ // TODO(johnniwinther): Provide source information for creation
+ // through synthetic constructors.
: null);
- irBuilder.add(new ir.LetPrim(instance));
+ irBuilder.add(new ir.LetPrim(instance));
+ }
// --- Call constructor bodies ---
for (ConstructorElement target in constructorList) {
@@ -1090,7 +1119,8 @@
irBuilder.buildIf(
build(node.condition),
subbuild(node.thenPart),
- subbuild(node.elsePart));
+ subbuild(node.elsePart),
+ sourceInformationBuilder.buildIf(node));
}
visitLabeledStatement(ast.LabeledStatement node) {
@@ -1154,7 +1184,8 @@
iterator,
Selectors.moveNext,
elements.getMoveNextTypeMask(node),
- <ir.Primitive>[]);
+ <ir.Primitive>[],
+ sourceInformationBuilder.buildForInMoveNext(node));
return builder.addPrimitive(new ir.Await(moveNext));
}
@@ -1164,13 +1195,17 @@
iterator,
Selectors.current,
elements.getCurrentTypeMask(node),
- <ir.Primitive>[]);
+ <ir.Primitive>[],
+ sourceInformationBuilder.buildForInCurrent(node));
Element variable = elements.getForInVariable(node);
+ SourceInformation sourceInformation =
+ sourceInformationBuilder.buildForInSet(node);
if (Elements.isLocal(variable)) {
if (node.declaredIdentifier.asVariableDefinitions() != null) {
irBuilder.declareLocalVariable(variable);
}
- irBuilder.buildLocalVariableSet(variable, current);
+ irBuilder.buildLocalVariableSet(
+ variable, current, sourceInformation);
} else if (Elements.isError(variable) ||
Elements.isMalformed(variable)) {
Selector selector =
@@ -1179,15 +1214,18 @@
// Note the comparison below. It can be the case that an element
// isError and isMalformed.
if (Elements.isError(variable)) {
- irBuilder.buildStaticNoSuchMethod(selector, args);
+ irBuilder.buildStaticNoSuchMethod(
+ selector, args, sourceInformation);
} else {
- irBuilder.buildErroneousInvocation(variable, selector, args);
+ irBuilder.buildErroneousInvocation(
+ variable, selector, args, sourceInformation);
}
} else if (Elements.isStaticOrTopLevel(variable)) {
if (variable.isField) {
irBuilder.addPrimitive(new ir.SetStatic(variable, current));
} else {
- irBuilder.buildStaticSetterSet(variable, current);
+ irBuilder.buildStaticSetterSet(
+ variable, current, sourceInformation);
}
} else {
ir.Primitive receiver = irBuilder.buildThis();
@@ -1196,7 +1234,8 @@
receiver,
elements.getSelector(identifier),
elements.getTypeMask(identifier),
- current);
+ current,
+ sourceInformation);
}
visit(node.body);
});
@@ -1215,7 +1254,7 @@
Selectors.cancel,
backend.dynamicType,
<ir.Primitive>[],
- sourceInformation: sourceInformationBuilder.buildGeneric(node));
+ sourceInformationBuilder.buildGeneric(node));
return builder.addPrimitive(new ir.Await(cancellation));
}
@@ -1251,9 +1290,17 @@
variableElement: variableElement,
variableSelector: selector,
variableMask: elements.getTypeMask(identifier),
+ variableSetSourceInformation:
+ sourceInformationBuilder.buildForInSet(node),
currentMask: elements.getCurrentTypeMask(node),
+ currentSourceInformation:
+ sourceInformationBuilder.buildForInCurrent(node),
moveNextMask: elements.getMoveNextTypeMask(node),
+ moveNextSourceInformation:
+ sourceInformationBuilder.buildForInMoveNext(node),
iteratorMask: elements.getIteratorTypeMask(node),
+ iteratorSourceInformation:
+ sourceInformationBuilder.buildForInIterator(node),
buildBody: subbuild(node.body),
target: elements.getTargetDefinition(node),
closureScope: getClosureScopeForNode(node));
@@ -1318,7 +1365,8 @@
function.functionSignature.parameterCount == 0,
message: 'native "..." syntax is restricted to '
'functions with zero parameters.'));
- irBuilder.buildNativeFunctionBody(function, javaScriptCode);
+ irBuilder.buildNativeFunctionBody(function, javaScriptCode,
+ sourceInformationBuilder.buildForeignCode(node));
} else {
String name = backend.getFixedBackendName(function);
irBuilder.buildRedirectingNativeFunctionBody(function, name, source);
@@ -1475,7 +1523,9 @@
condition = buildComparison();
} else {
condition = irBuilder.buildLogicalOperator(condition,
- nested(buildComparison), isLazyOr: true);
+ nested(buildComparison),
+ sourceInformationBuilder.buildSwitchCase(switchCase),
+ isLazyOr: true);
}
}
}
@@ -1516,7 +1566,8 @@
};
}
- cases.add(new SwitchCaseInfo(buildCondition, buildBody));
+ cases.add(new SwitchCaseInfo(buildCondition, buildBody,
+ sourceInformationBuilder.buildSwitchCase(switchCase)));
}
irBuilder.buildSimpleSwitch(join, cases, buildDefaultBody);
@@ -1570,7 +1621,8 @@
return null;
}
- cases.add(new SwitchCaseInfo(buildCondition, buildBody));
+ cases.add(new SwitchCaseInfo(buildCondition, buildBody,
+ sourceInformationBuilder.buildSwitch(node)));
}
// A loop with a simple switch in the body.
@@ -1579,7 +1631,8 @@
buildCondition: (IrBuilder builder) {
ir.Primitive condition = builder.buildIdentical(
builder.environment.index2value[stateIndex], initial);
- return builder.buildNegation(condition);
+ return builder.buildNegation(condition,
+ sourceInformationBuilder.buildSwitch(node));
},
buildBody: (IrBuilder builder) {
builder.buildSimpleSwitch(loop, cases, null);
@@ -1616,7 +1669,8 @@
type: type,
exceptionVariable: exceptionVariable,
stackTraceVariable: stackTraceVariable,
- buildCatchBlock: subbuild(catchClause.block)));
+ buildCatchBlock: subbuild(catchClause.block),
+ sourceInformation: sourceInformationBuilder.buildCatch(catchClause)));
}
assert(!node.catchBlocks.isEmpty || node.finallyBlock != null);
@@ -1649,7 +1703,8 @@
return irBuilder.buildConditional(
build(node.condition),
subbuild(node.thenExpression),
- subbuild(node.elseExpression));
+ subbuild(node.elseExpression),
+ sourceInformationBuilder.buildIf(node));
}
// For all simple literals:
@@ -1744,7 +1799,7 @@
return irBuilder.buildStaticFunctionInvocation(
helpers.mapLiteralUntypedEmptyMaker,
<ir.Primitive>[],
- sourceInformation: sourceInformationBuilder.buildNew(node));
+ sourceInformationBuilder.buildNew(node));
} else {
ConstructorElement constructor = helpers.mapLiteralConstructorEmpty;
return irBuilder.buildConstructorInvocation(
@@ -1768,7 +1823,7 @@
return irBuilder.buildStaticFunctionInvocation(
helpers.mapLiteralUntypedMaker,
<ir.Primitive>[keysAndValuesList],
- sourceInformation: sourceInformationBuilder.buildNew(node));
+ sourceInformationBuilder.buildNew(node));
} else {
ConstructorElement constructor = helpers.mapLiteralConstructor;
return irBuilder.buildConstructorInvocation(
@@ -1842,7 +1897,7 @@
return irBuilder.buildStaticFunctionInvocation(
helpers.checkDeferredIsLoaded,
<ir.Primitive>[name, uri],
- sourceInformation: sourceInformation);
+ sourceInformation);
}
ir.Primitive visitNamedArgument(ast.NamedArgument node) {
@@ -1859,8 +1914,7 @@
List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
callStructure = normalizeDynamicArguments(callStructure, arguments);
return irBuilder.buildCallInvocation(receiver, callStructure, arguments,
- sourceInformation:
- sourceInformationBuilder.buildCall(node, argumentsNode));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
/// Returns `true` if [node] is a super call.
@@ -1909,7 +1963,8 @@
target,
new Selector.getter(name),
elements.getTypeMask(node),
- sourceInformationBuilder.buildGet(node))));
+ sourceInformationBuilder.buildGet(node))),
+ sourceInformationBuilder.buildIf(node));
}
@override
@@ -1952,15 +2007,17 @@
ast.Send node,
FunctionElement getter,
_) {
- return buildStaticGetterGet(getter, node);
+ return buildStaticGetterGet(
+ getter, node, sourceInformationBuilder.buildGet(node));
}
/// Create a getter invocation of the static getter [getter]. This also
/// handles the special case where [getter] is the `loadLibrary`
/// pseudo-function on library prefixes of deferred imports.
- ir.Primitive buildStaticGetterGet(MethodElement getter, ast.Send node) {
- SourceInformation sourceInformation =
- sourceInformationBuilder.buildGet(node);
+ ir.Primitive buildStaticGetterGet(
+ MethodElement getter,
+ ast.Send node,
+ SourceInformation sourceInformation) {
if (getter.isDeferredLoaderGetter) {
PrefixElement prefix = getter.enclosingElement;
ir.Primitive loadId = irBuilder.buildStringConstant(
@@ -1968,7 +2025,7 @@
return irBuilder.buildStaticFunctionInvocation(
compiler.loadLibraryFunction,
<ir.Primitive>[loadId],
- sourceInformation: sourceInformation);
+ sourceInformation);
} else {
return irBuilder.buildStaticGetterGet(getter, sourceInformation);
}
@@ -1979,7 +2036,8 @@
ast.Send node,
FieldElement field,
_) {
- return irBuilder.buildSuperFieldGet(field);
+ return irBuilder.buildSuperFieldGet(
+ field, sourceInformationBuilder.buildGet(node));
}
@override
@@ -1996,7 +2054,8 @@
ast.Send node,
MethodElement method,
_) {
- return irBuilder.buildSuperMethodGet(method);
+ return irBuilder.buildSuperMethodGet(
+ method, sourceInformationBuilder.buildGet(node));
}
@override
@@ -2004,7 +2063,8 @@
ast.Send node,
Element element, _) {
return buildSuperNoSuchMethod(
- elements.getSelector(node), elements.getTypeMask(node), []);
+ elements.getSelector(node), elements.getTypeMask(node), [],
+ sourceInformationBuilder.buildGet(node));
}
@override
@@ -2013,7 +2073,8 @@
Element element,
ast.Node rhs, _) {
return buildSuperNoSuchMethod(
- elements.getSelector(node), elements.getTypeMask(node), [visit(rhs)]);
+ elements.getSelector(node), elements.getTypeMask(node), [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -2042,6 +2103,7 @@
ir.Primitive translateLogicalOperator(ast.Expression left,
ast.Expression right,
+ SourceInformation sourceInformation,
{bool isLazyOr}) {
ir.Primitive leftValue = visit(left);
@@ -2050,25 +2112,28 @@
}
return irBuilder.buildLogicalOperator(
- leftValue, buildRightValue, isLazyOr: isLazyOr);
+ leftValue, buildRightValue, sourceInformation, isLazyOr: isLazyOr);
}
@override
ir.Primitive visitIfNull(
ast.Send node, ast.Node left, ast.Node right, _) {
- return irBuilder.buildIfNull(build(left), subbuild(right));
+ return irBuilder.buildIfNull(build(left), subbuild(right),
+ sourceInformationBuilder.buildIf(node));
}
@override
ir.Primitive visitLogicalAnd(
ast.Send node, ast.Node left, ast.Node right, _) {
- return translateLogicalOperator(left, right, isLazyOr: false);
+ return translateLogicalOperator(left, right,
+ sourceInformationBuilder.buildIf(node), isLazyOr: false);
}
@override
ir.Primitive visitLogicalOr(
ast.Send node, ast.Node left, ast.Node right, _) {
- return translateLogicalOperator(left, right, isLazyOr: true);
+ return translateLogicalOperator(left, right,
+ sourceInformationBuilder.buildIf(node), isLazyOr: true);
}
@override
@@ -2078,7 +2143,11 @@
DartType type,
_) {
ir.Primitive receiver = visit(expression);
- return irBuilder.buildTypeOperator(receiver, type, isTypeTest: false);
+ return irBuilder.buildTypeOperator(
+ receiver,
+ type,
+ sourceInformationBuilder.buildAs(node),
+ isTypeTest: false);
}
@override
@@ -2088,7 +2157,11 @@
DartType type,
_) {
ir.Primitive value = visit(expression);
- return irBuilder.buildTypeOperator(value, type, isTypeTest: true);
+ return irBuilder.buildTypeOperator(
+ value,
+ type,
+ sourceInformationBuilder.buildIs(node),
+ isTypeTest: true);
}
@override
@@ -2096,8 +2169,12 @@
ast.Node expression, DartType type, _) {
ir.Primitive value = visit(expression);
ir.Primitive check = irBuilder.buildTypeOperator(
- value, type, isTypeTest: true);
- return irBuilder.buildNegation(check);
+ value,
+ type,
+ sourceInformationBuilder.buildIs(node),
+ isTypeTest: true);
+ return irBuilder.buildNegation(check,
+ sourceInformationBuilder.buildIf(node));
}
ir.Primitive translateBinary(ast.Send node,
@@ -2114,8 +2191,7 @@
new Selector(selector.kind, selector.memberName, callStructure),
elements.getTypeMask(node),
arguments,
- sourceInformation:
- sourceInformationBuilder.buildCall(node, node.selector));
+ sourceInformationBuilder.buildCall(node, node.selector));
}
@override
@@ -2140,16 +2216,16 @@
new Selector(selector.kind, selector.memberName, callStructure),
elements.getTypeMask(node),
arguments,
- sourceInformation:
- sourceInformationBuilder.buildCall(receiver, node.selector));
+ sourceInformationBuilder.buildCall(receiver, node.selector));
}
ir.Primitive translateSuperBinary(FunctionElement function,
op.BinaryOperator operator,
- ast.Node argument) {
+ ast.Node argument,
+ SourceInformation sourceInformation) {
List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)];
return irBuilder.buildSuperMethodInvocation(function,
- CallStructure.ONE_ARG, arguments);
+ CallStructure.ONE_ARG, arguments, sourceInformation);
}
@override
@@ -2159,7 +2235,8 @@
op.BinaryOperator operator,
ast.Node argument,
_) {
- return translateSuperBinary(function, operator, argument);
+ return translateSuperBinary(function, operator, argument,
+ sourceInformationBuilder.buildBinary(node));
}
@override
@@ -2168,7 +2245,8 @@
FunctionElement function,
ast.Node index,
_) {
- return irBuilder.buildSuperIndex(function, visit(index));
+ return irBuilder.buildSuperIndex(function, visit(index),
+ sourceInformationBuilder.buildIndex(node));
}
@override
@@ -2186,7 +2264,8 @@
FunctionElement function,
ast.Node argument,
_) {
- return translateSuperBinary(function, op.BinaryOperator.EQ, argument);
+ return translateSuperBinary(function, op.BinaryOperator.EQ, argument,
+ sourceInformationBuilder.buildBinary(node));
}
@override
@@ -2194,7 +2273,8 @@
ast.Send node,
ast.Node expression,
_) {
- return irBuilder.buildNegation(visit(expression));
+ return irBuilder.buildNegation(visit(expression),
+ sourceInformationBuilder.buildIf(node));
}
@override
@@ -2204,7 +2284,8 @@
ast.Node right,
_) {
return irBuilder.buildNegation(
- translateBinary(node, left, op.BinaryOperator.NOT_EQ, right));
+ translateBinary(node, left, op.BinaryOperator.NOT_EQ, right),
+ sourceInformationBuilder.buildIf(node));
}
@override
@@ -2214,7 +2295,9 @@
ast.Node argument,
_) {
return irBuilder.buildNegation(
- translateSuperBinary(function, op.BinaryOperator.NOT_EQ, argument));
+ translateSuperBinary(function, op.BinaryOperator.NOT_EQ, argument,
+ sourceInformationBuilder.buildBinary(node)),
+ sourceInformationBuilder.buildIf(node));
}
@override
@@ -2225,8 +2308,7 @@
ir.Primitive receiver = translateReceiver(expression);
return irBuilder.buildDynamicInvocation(
receiver, selector, elements.getTypeMask(node), const [],
- sourceInformation: sourceInformationBuilder.buildCall(
- expression, node));
+ sourceInformationBuilder.buildCall(expression, node));
}
@override
@@ -2236,7 +2318,8 @@
FunctionElement function,
_) {
return irBuilder.buildSuperMethodInvocation(
- function, CallStructure.NO_ARGS, const []);
+ function, CallStructure.NO_ARGS, const [],
+ sourceInformationBuilder.buildCall(node, node));
}
// TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
@@ -2267,8 +2350,8 @@
List<ir.Primitive> arguments = <ir.Primitive>[];
callStructure =
translateDynamicArguments(argumentsNode, callStructure, arguments);
- return irBuilder.buildCallInvocation(target, callStructure, arguments,
- sourceInformation: sourceInformation);
+ return irBuilder.buildCallInvocation(
+ target, callStructure, arguments, sourceInformation);
}
@override
@@ -2315,6 +2398,10 @@
}
List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
+ if (constructor.isGenerativeConstructor &&
+ backend.isNativeOrExtendsNative(constructor.enclosingClass)) {
+ arguments.insert(0, irBuilder.buildNullConstant());
+ }
// Use default values from the effective target, not the immediate target.
ConstructorElement target;
if (constructor == compiler.symbolConstructor) {
@@ -2366,8 +2453,7 @@
new Selector(selector.kind, selector.memberName, callStructure),
elements.getTypeMask(node),
arguments,
- sourceInformation:
- sourceInformationBuilder.buildCall(node, node.selector));
+ sourceInformationBuilder.buildCall(node, node.selector));
}
@override
@@ -2388,8 +2474,10 @@
target,
new Selector(selector.kind, selector.memberName, callStructure),
elements.getTypeMask(node),
- arguments);
- }));
+ arguments,
+ sourceInformationBuilder.buildCall(node, node.selector));
+ }),
+ sourceInformationBuilder.buildIf(node));
}
ir.Primitive handleLocalInvoke(
@@ -2403,8 +2491,7 @@
callStructure =
translateDynamicArguments(argumentsNode, callStructure, arguments);
return irBuilder.buildCallInvocation(function, callStructure, arguments,
- sourceInformation:
- sourceInformationBuilder.buildCall(node, argumentsNode));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
@@ -2428,8 +2515,7 @@
target,
callStructure,
arguments,
- sourceInformation:
- sourceInformationBuilder.buildCall(node, argumentsNode));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
@@ -2439,7 +2525,11 @@
CallStructure callStructure,
_) {
if (compiler.backend.isForeign(function)) {
- return handleForeignCode(node, function, argumentsNode, callStructure);
+ return handleForeignCode(
+ node,
+ function,
+ argumentsNode,
+ callStructure);
} else {
List<ir.Primitive> arguments = <ir.Primitive>[];
callStructure = translateStaticArguments(argumentsNode, function,
@@ -2458,7 +2548,8 @@
CallStructure callStructure, _) {
return irBuilder.buildStaticNoSuchMethod(
elements.getSelector(node),
- arguments.nodes.mapToList(visit));
+ arguments.nodes.mapToList(visit),
+ sourceInformationBuilder.buildCall(node, node.selector));
}
@override
@@ -2468,7 +2559,8 @@
ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
- ir.Primitive target = buildStaticGetterGet(getter, node);
+ ir.Primitive target = buildStaticGetterGet(
+ getter, node, sourceInformationBuilder.buildGet(node));
List<ir.Primitive> arguments = <ir.Primitive>[];
callStructure =
translateDynamicArguments(argumentsNode, callStructure, arguments);
@@ -2476,8 +2568,7 @@
target,
callStructure,
arguments,
- sourceInformation:
- sourceInformationBuilder.buildCall(node, argumentsNode));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
@@ -2487,7 +2578,8 @@
ast.NodeList argumentsNode,
CallStructure callStructure,
_) {
- ir.Primitive target = irBuilder.buildSuperFieldGet(field);
+ ir.Primitive target = irBuilder.buildSuperFieldGet(
+ field, sourceInformationBuilder.buildGet(node));
List<ir.Primitive> arguments = <ir.Primitive>[];
callStructure =
translateDynamicArguments(argumentsNode, callStructure, arguments);
@@ -2495,8 +2587,7 @@
target,
callStructure,
arguments,
- sourceInformation:
- sourceInformationBuilder.buildCall(node, argumentsNode));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
@@ -2515,8 +2606,7 @@
target,
callStructure,
arguments,
- sourceInformation:
- sourceInformationBuilder.buildCall(node, argumentsNode));
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
@@ -2533,8 +2623,7 @@
method,
callStructure,
arguments,
- sourceInformation:
- sourceInformationBuilder.buildCall(node, node.selector));
+ sourceInformationBuilder.buildCall(node, node.selector));
}
@override
@@ -2549,7 +2638,8 @@
return buildSuperNoSuchMethod(
new Selector.call(method.memberName, normalizedCallStructure),
elements.getTypeMask(node),
- normalizedArguments);
+ normalizedArguments,
+ sourceInformationBuilder.buildCall(node, arguments));
}
@override
@@ -2566,7 +2656,8 @@
return buildSuperNoSuchMethod(
new Selector.call(elements.getSelector(node).memberName, callStructure),
elements.getTypeMask(node),
- arguments);
+ arguments,
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
@@ -2605,7 +2696,11 @@
ast.Node rhs,
_) {
return irBuilder.buildDynamicIndexSet(
- visit(receiver), elements.getTypeMask(node), visit(index), visit(rhs));
+ visit(receiver),
+ elements.getTypeMask(node),
+ visit(index),
+ visit(rhs),
+ sourceInformationBuilder.buildIndexSet(node));
}
@override
@@ -2615,7 +2710,11 @@
ast.Node index,
ast.Node rhs,
_) {
- return irBuilder.buildSuperIndexSet(function, visit(index), visit(rhs));
+ return irBuilder.buildSuperIndexSet(
+ function,
+ visit(index),
+ visit(rhs),
+ sourceInformationBuilder.buildIndexSet(node));
}
ir.Primitive translateCompounds(
@@ -2632,7 +2731,8 @@
ir.Primitive newValue = build(rhs.rhs);
setValue(newValue);
return newValue;
- }));
+ }),
+ sourceInformationBuilder.buildIf(node));
}
Selector operatorSelector =
@@ -2656,7 +2756,7 @@
callStructure),
operatorTypeMask,
arguments,
- sourceInformation: operatorSourceInformation);
+ operatorSourceInformation);
setValue(result);
return rhs.kind == CompoundKind.POSTFIX ? value : result;
}
@@ -2673,7 +2773,8 @@
ir.Primitive newValue = build(rhs);
setValue(newValue);
return newValue;
- }));
+ }),
+ sourceInformationBuilder.buildIf(node));
}
@override
@@ -2687,7 +2788,8 @@
translateReceiver(receiver),
new Selector.setter(name),
elements.getTypeMask(node),
- visit(rhs));
+ visit(rhs),
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -2704,7 +2806,9 @@
target,
new Selector.setter(name),
elements.getTypeMask(node),
- visit(rhs))));
+ visit(rhs),
+ sourceInformationBuilder.buildAssignment(node))),
+ sourceInformationBuilder.buildIf(node));
}
@override
@@ -2715,7 +2819,8 @@
_) {
ir.Primitive value = visit(rhs);
value = checkTypeVsElement(value, element);
- return irBuilder.buildLocalVariableSet(element, value);
+ return irBuilder.buildLocalVariableSet(element, value,
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -2725,7 +2830,8 @@
ast.Node rhs,
_) {
ir.Primitive value = visit(rhs);
- irBuilder.addPrimitive(new ir.SetStatic(field, value));
+ irBuilder.addPrimitive(new ir.SetStatic(field, value,
+ sourceInformationBuilder.buildAssignment(node)));
return value;
}
@@ -2735,7 +2841,8 @@
FieldElement field,
ast.Node rhs,
_) {
- return irBuilder.buildSuperFieldSet(field, visit(rhs));
+ return irBuilder.buildSuperFieldSet(field, visit(rhs),
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -2744,7 +2851,8 @@
FunctionElement setter,
ast.Node rhs,
_) {
- return irBuilder.buildSuperSetterSet(setter, visit(rhs));
+ return irBuilder.buildSuperSetterSet(setter, visit(rhs),
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -2763,7 +2871,8 @@
FunctionElement setter,
ast.Node rhs,
_) {
- return irBuilder.buildStaticSetterSet(setter, visit(rhs));
+ return irBuilder.buildStaticSetterSet(setter, visit(rhs),
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -2811,11 +2920,13 @@
target,
new Selector.setter(name),
elements.getTypeMask(node),
- result);
+ result,
+ sourceInformationBuilder.buildAssignment(node));
});
}
return node.isConditional
- ? irBuilder.buildIfNotNullSend(target, nested(helper))
+ ? irBuilder.buildIfNotNullSend(
+ target, nested(helper), sourceInformationBuilder.buildIf(node))
: helper();
}
@@ -2839,18 +2950,24 @@
target,
new Selector.setter(name),
elements.getTypeMask(node),
- result);
+ result,
+ sourceInformationBuilder.buildAssignment(node));
});
}
return node.isConditional
- ? irBuilder.buildIfNotNullSend(target, nested(helper))
+ ? irBuilder.buildIfNotNullSend(
+ target, nested(helper), sourceInformationBuilder.buildIf(node))
: helper();
}
- ir.Primitive buildLocalNoSuchSetter(LocalElement local, ir.Primitive value) {
+ ir.Primitive buildLocalNoSuchSetter(
+ LocalElement local,
+ ir.Primitive value,
+ SourceInformation sourceInformation) {
Selector selector = new Selector.setter(
new Name(local.name, local.library, isSetter: true));
- return irBuilder.buildStaticNoSuchMethod(selector, [value]);
+ return irBuilder.buildStaticNoSuchMethod(
+ selector, [value], sourceInformation);
}
@override
@@ -2864,11 +2981,15 @@
return irBuilder.buildLocalGet(local);
}, rhs, (ir.Primitive result) {
if (isSetterValid) {
- irBuilder.buildLocalVariableSet(local, result);
+ irBuilder.buildLocalVariableSet(
+ local, result,
+ sourceInformationBuilder.buildAssignment(node));
} else {
Selector selector = new Selector.setter(
new Name(local.name, local.library, isSetter: true));
- irBuilder.buildStaticNoSuchMethod(selector, <ir.Primitive>[result]);
+ irBuilder.buildStaticNoSuchMethod(
+ selector, <ir.Primitive>[result],
+ sourceInformationBuilder.buildAssignment(node));
}
});
}
@@ -2881,14 +3002,19 @@
_,
{bool isSetterValid}) {
return translateSetIfNull(node, () {
- return irBuilder.buildLocalGet(local);
+ return irBuilder.buildLocalGet(
+ local, sourceInformation: sourceInformationBuilder.buildGet(node));
}, rhs, (ir.Primitive result) {
+ SourceInformation sourceInformation =
+ sourceInformationBuilder.buildAssignment(node);
if (isSetterValid) {
- irBuilder.buildLocalVariableSet(local, result);
+ irBuilder.buildLocalVariableSet(
+ local, result, sourceInformation);
} else {
Selector selector = new Selector.setter(
new Name(local.name, local.library, isSetter: true));
- irBuilder.buildStaticNoSuchMethod(selector, <ir.Primitive>[result]);
+ irBuilder.buildStaticNoSuchMethod(
+ selector, <ir.Primitive>[result], sourceInformation);
}
});
}
@@ -2903,32 +3029,38 @@
CompoundRhs rhs,
arg) {
return translateCompounds(node, () {
+ SourceInformation sourceInformation =
+ sourceInformationBuilder.buildGet(node);
switch (getterKind) {
case CompoundGetter.FIELD:
- SourceInformation src = sourceInformationBuilder.buildGet(node);
- return buildStaticFieldGet(getter, src);
+ return buildStaticFieldGet(getter, sourceInformation);
case CompoundGetter.GETTER:
- return buildStaticGetterGet(getter, node);
+ return buildStaticGetterGet(getter, node, sourceInformation);
case CompoundGetter.METHOD:
return irBuilder.addPrimitive(new ir.GetStatic(getter,
- isFinal: true));
+ sourceInformation: sourceInformation, isFinal: true));
case CompoundGetter.UNRESOLVED:
return irBuilder.buildStaticNoSuchMethod(
new Selector.getter(new Name(getter.name, getter.library)),
- <ir.Primitive>[]);
+ <ir.Primitive>[],
+ sourceInformation);
}
}, rhs, (ir.Primitive result) {
+ SourceInformation sourceInformation =
+ sourceInformationBuilder.buildAssignment(node);
switch (setterKind) {
case CompoundSetter.FIELD:
- irBuilder.addPrimitive(new ir.SetStatic(setter, result));
+ irBuilder.addPrimitive(
+ new ir.SetStatic(setter, result, sourceInformation));
return;
case CompoundSetter.SETTER:
- irBuilder.buildStaticSetterSet(setter, result);
+ irBuilder.buildStaticSetterSet(setter, result, sourceInformation);
return;
case CompoundSetter.INVALID:
irBuilder.buildStaticNoSuchMethod(
new Selector.setter(new Name(setter.name, setter.library)),
- <ir.Primitive>[result]);
+ <ir.Primitive>[result],
+ sourceInformation);
return;
}
});
@@ -2944,51 +3076,65 @@
ast.Node rhs,
_) {
return translateSetIfNull(node, () {
+ SourceInformation sourceInformation =
+ sourceInformationBuilder.buildGet(node);
switch (getterKind) {
case CompoundGetter.FIELD:
- SourceInformation src = sourceInformationBuilder.buildGet(node);
- return buildStaticFieldGet(getter, src);
+ return buildStaticFieldGet(getter, sourceInformation);
case CompoundGetter.GETTER:
- return buildStaticGetterGet(getter, node);
+ return buildStaticGetterGet(getter, node, sourceInformation);
case CompoundGetter.METHOD:
return irBuilder.addPrimitive(new ir.GetStatic(getter,
+ sourceInformation: sourceInformation,
isFinal: true));
case CompoundGetter.UNRESOLVED:
return irBuilder.buildStaticNoSuchMethod(
new Selector.getter(new Name(getter.name, getter.library)),
- <ir.Primitive>[]);
+ <ir.Primitive>[],
+ sourceInformation);
}
}, rhs, (ir.Primitive result) {
+ SourceInformation sourceInformation =
+ sourceInformationBuilder.buildAssignment(node);
switch (setterKind) {
case CompoundSetter.FIELD:
- irBuilder.addPrimitive(new ir.SetStatic(setter, result));
+ irBuilder.addPrimitive(new ir.SetStatic(
+ setter, result, sourceInformation));
return;
case CompoundSetter.SETTER:
- irBuilder.buildStaticSetterSet(setter, result);
+ irBuilder.buildStaticSetterSet(setter, result, sourceInformation);
return;
case CompoundSetter.INVALID:
irBuilder.buildStaticNoSuchMethod(
new Selector.setter(new Name(setter.name, setter.library)),
- <ir.Primitive>[result]);
+ <ir.Primitive>[result],
+ sourceInformation);
return;
}
});
}
- ir.Primitive buildSuperNoSuchGetter(Element element, TypeMask mask) {
+ ir.Primitive buildSuperNoSuchGetter(
+ Element element,
+ TypeMask mask,
+ SourceInformation sourceInformation) {
return buildSuperNoSuchMethod(
new Selector.getter(new Name(element.name, element.library)),
mask,
- const <ir.Primitive>[]);
+ const <ir.Primitive>[],
+ sourceInformation);
}
- ir.Primitive buildSuperNoSuchSetter(Element element,
- TypeMask mask,
- ir.Primitive value) {
+ ir.Primitive buildSuperNoSuchSetter(
+ Element element,
+ TypeMask mask,
+ ir.Primitive value,
+ SourceInformation sourceInformation) {
return buildSuperNoSuchMethod(
new Selector.setter(new Name(element.name, element.library)),
mask,
- <ir.Primitive>[value]);
+ <ir.Primitive>[value],
+ sourceInformation);
}
@override
@@ -3003,27 +3149,33 @@
return translateCompounds(node, () {
switch (getterKind) {
case CompoundGetter.FIELD:
- return irBuilder.buildSuperFieldGet(getter);
+ return irBuilder.buildSuperFieldGet(
+ getter, sourceInformationBuilder.buildGet(node));
case CompoundGetter.GETTER:
return irBuilder.buildSuperGetterGet(
getter, sourceInformationBuilder.buildGet(node));
case CompoundGetter.METHOD:
- return irBuilder.buildSuperMethodGet(getter);
+ return irBuilder.buildSuperMethodGet(
+ getter, sourceInformationBuilder.buildGet(node));
case CompoundGetter.UNRESOLVED:
return buildSuperNoSuchGetter(
- getter, elements.getGetterTypeMaskInComplexSendSet(node));
+ getter, elements.getGetterTypeMaskInComplexSendSet(node),
+ sourceInformationBuilder.buildGet(node));
}
}, rhs, (ir.Primitive result) {
switch (setterKind) {
case CompoundSetter.FIELD:
- irBuilder.buildSuperFieldSet(setter, result);
+ irBuilder.buildSuperFieldSet(setter, result,
+ sourceInformationBuilder.buildAssignment(node));
return;
case CompoundSetter.SETTER:
- irBuilder.buildSuperSetterSet(setter, result);
+ irBuilder.buildSuperSetterSet(setter, result,
+ sourceInformationBuilder.buildAssignment(node));
return;
case CompoundSetter.INVALID:
buildSuperNoSuchSetter(
- setter, elements.getTypeMask(node), result);
+ setter, elements.getTypeMask(node), result,
+ sourceInformationBuilder.buildAssignment(node));
return;
}
});
@@ -3041,28 +3193,36 @@
return translateSetIfNull(node, () {
switch (getterKind) {
case CompoundGetter.FIELD:
- return irBuilder.buildSuperFieldGet(getter);
+ return irBuilder.buildSuperFieldGet(
+ getter, sourceInformationBuilder.buildGet(node));
case CompoundGetter.GETTER:
return irBuilder.buildSuperGetterGet(
getter, sourceInformationBuilder.buildGet(node));
case CompoundGetter.METHOD:
- return irBuilder.buildSuperMethodGet(getter);
+ return irBuilder.buildSuperMethodGet(
+ getter, sourceInformationBuilder.buildGet(node));
case CompoundGetter.UNRESOLVED:
return buildSuperNoSuchGetter(
getter,
- elements.getGetterTypeMaskInComplexSendSet(node));
+ elements.getGetterTypeMaskInComplexSendSet(node),
+ sourceInformationBuilder.buildGet(node));
}
}, rhs, (ir.Primitive result) {
switch (setterKind) {
case CompoundSetter.FIELD:
- irBuilder.buildSuperFieldSet(setter, result);
+ irBuilder.buildSuperFieldSet(
+ setter, result,
+ sourceInformationBuilder.buildAssignment(node));
return;
case CompoundSetter.SETTER:
- irBuilder.buildSuperSetterSet(setter, result);
+ irBuilder.buildSuperSetterSet(
+ setter, result,
+ sourceInformationBuilder.buildAssignment(node));
return;
case CompoundSetter.INVALID:
buildSuperNoSuchSetter(
- setter, elements.getTypeMask(node), result);
+ setter, elements.getTypeMask(node), result,
+ sourceInformationBuilder.buildAssignment(node));
return;
}
});
@@ -3113,14 +3273,14 @@
new Selector(selector.kind, selector.memberName, callStructure),
elements.getGetterTypeMaskInComplexSendSet(node),
arguments,
- sourceInformation:
sourceInformationBuilder.buildCall(receiver, node));
}, rhs, (ir.Primitive result) {
irBuilder.buildDynamicIndexSet(
target,
elements.getTypeMask(node),
indexValue,
- result);
+ result,
+ sourceInformationBuilder.buildIndexSet(node));
});
}
@@ -3136,20 +3296,28 @@
bool isSetterValid}) {
ir.Primitive indexValue = visit(index);
return translateCompounds(node, () {
- return isGetterValid
- ? irBuilder.buildSuperIndex(indexFunction, indexValue)
- : buildSuperNoSuchMethod(
- new Selector.index(),
- elements.getGetterTypeMaskInComplexSendSet(node),
- <ir.Primitive>[indexValue]);
+ if (isGetterValid) {
+ return irBuilder.buildSuperIndex(
+ indexFunction,
+ indexValue,
+ sourceInformationBuilder.buildIndex(node));
+ } else {
+ return buildSuperNoSuchMethod(
+ new Selector.index(),
+ elements.getGetterTypeMaskInComplexSendSet(node),
+ <ir.Primitive>[indexValue],
+ sourceInformationBuilder.buildIndex(node));
+ }
}, rhs, (ir.Primitive result) {
if (isSetterValid) {
- irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result);
+ irBuilder.buildSuperIndexSet(indexSetFunction, indexValue, result,
+ sourceInformationBuilder.buildIndexSet(node));
} else {
buildSuperNoSuchMethod(
new Selector.indexSet(),
elements.getTypeMask(node),
- <ir.Primitive>[indexValue, result]);
+ <ir.Primitive>[indexValue, result],
+ sourceInformationBuilder.buildIndexSet(node));
}
});
}
@@ -3245,7 +3413,7 @@
}
return irBuilder.buildForeignCode(behavior.codeTemplate, arguments,
- behavior);
+ behavior, sourceInformationBuilder.buildForeignCode(node));
case 'DART_CLOSURE_TO_JS':
// TODO(ahe): This should probably take care to wrap the closure in
@@ -3268,6 +3436,7 @@
backend.emitter.staticFunctionAccess(closure)),
<ir.Primitive>[],
NativeBehavior.PURE,
+ sourceInformationBuilder.buildForeignCode(node),
dependency: closure);
case 'JS_BUILTIN':
@@ -3284,7 +3453,8 @@
js.Template template = backend.emitter.builtinTemplateFor(value);
List<ir.Primitive> arguments =
argumentNodes.skip(2).mapToList(visit, growable: false);
- return irBuilder.buildForeignCode(template, arguments, behavior);
+ return irBuilder.buildForeignCode(template, arguments, behavior,
+ sourceInformationBuilder.buildForeignCode(node));
case 'JS_EMBEDDED_GLOBAL':
validateArgumentCount(exactly: 2);
@@ -3293,7 +3463,8 @@
js.Expression access =
backend.emitter.generateEmbeddedGlobalAccess(name);
js.Template template = js.js.expressionTemplateYielding(access);
- return irBuilder.buildForeignCode(template, <ir.Primitive>[], behavior);
+ return irBuilder.buildForeignCode(template, <ir.Primitive>[], behavior,
+ sourceInformationBuilder.buildForeignCode(node));
case 'JS_INTERCEPTOR_CONSTANT':
validateArgumentCount(exactly: 1);
@@ -3344,7 +3515,8 @@
case 'JS_STRING_CONCAT':
validateArgumentCount(exactly: 2);
List<ir.Primitive> arguments = argumentNodes.mapToList(visit);
- return irBuilder.buildStringConcatenation(arguments);
+ return irBuilder.buildStringConcatenation(arguments,
+ sourceInformationBuilder.buildForeignCode(node));
case 'JS_CURRENT_ISOLATE_CONTEXT':
validateArgumentCount(exactly: 0);
@@ -3363,7 +3535,8 @@
return irBuilder.buildForeignCode(
js.js.parseForeignJS(backend.namer.staticStateHolder),
const <ir.Primitive>[],
- NativeBehavior.DEPENDS_OTHER);
+ NativeBehavior.DEPENDS_OTHER,
+ sourceInformationBuilder.buildForeignCode(node));
case 'JS_SET_STATIC_STATE':
validateArgumentCount(exactly: 1);
@@ -3373,7 +3546,8 @@
return irBuilder.buildForeignCode(
js.js.parseForeignJS("$isolateName = #"),
<ir.Primitive>[value],
- NativeBehavior.CHANGES_OTHER);
+ NativeBehavior.CHANGES_OTHER,
+ sourceInformationBuilder.buildForeignCode(node));
case 'JS_CALL_IN_ISOLATE':
validateArgumentCount(exactly: 2);
@@ -3381,7 +3555,8 @@
if (!compiler.hasIsolateSupport) {
ir.Primitive closure = visit(argumentNodes.tail.head);
return irBuilder.buildCallInvocation(closure, CallStructure.NO_ARGS,
- const <ir.Primitive>[]);
+ const <ir.Primitive>[],
+ sourceInformationBuilder.buildForeignCode(node));
}
return buildIsolateHelperInvocation(helpers.callInIsolate,
CallStructure.TWO_ARGS);
@@ -3415,7 +3590,8 @@
ir.Primitive value = visit(node);
accumulator.add(irBuilder.buildStaticFunctionInvocation(
helpers.stringInterpolationHelper,
- <ir.Primitive>[value]));
+ <ir.Primitive>[value],
+ sourceInformationBuilder.buildStringInterpolation(node)));
}
}
@@ -3423,14 +3599,16 @@
assert(irBuilder.isOpen);
List<ir.Primitive> parts = <ir.Primitive>[];
buildStringParts(node, parts);
- return irBuilder.buildStringConcatenation(parts);
+ return irBuilder.buildStringConcatenation(parts,
+ sourceInformationBuilder.buildStringInterpolation(node));
}
ir.Primitive visitStringInterpolation(ast.StringInterpolation node) {
assert(irBuilder.isOpen);
List<ir.Primitive> parts = <ir.Primitive>[];
buildStringParts(node, parts);
- return irBuilder.buildStringConcatenation(parts);
+ return irBuilder.buildStringConcatenation(parts,
+ sourceInformationBuilder.buildStringInterpolation(node));
}
ir.Primitive translateConstant(ast.Node node) {
@@ -3447,9 +3625,11 @@
return irBuilder.buildNonTailThrow(visit(node.expression));
}
- ir.Primitive buildSuperNoSuchMethod(Selector selector,
+ ir.Primitive buildSuperNoSuchMethod(
+ Selector selector,
TypeMask mask,
- List<ir.Primitive> arguments) {
+ List<ir.Primitive> arguments,
+ SourceInformation sourceInformation) {
ClassElement cls = elements.analyzedElement.enclosingClass;
MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_);
if (!Selectors.noSuchMethod_.signatureApplies(element)) {
@@ -3459,7 +3639,8 @@
return irBuilder.buildSuperMethodInvocation(
element,
Selectors.noSuchMethod_.callStructure,
- [irBuilder.buildInvocationMirror(selector, arguments)]);
+ [irBuilder.buildInvocationMirror(selector, arguments)],
+ sourceInformation);
}
@override
@@ -3468,9 +3649,10 @@
Element element,
op.AssignmentOperator operator,
ast.Node rhs, _) {
- // TODO(asgerf): What is unresolved? The getter and/or the setter?
- // If it was the setter, we must evaluate the right-hand side.
- return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), []);
+ return irBuilder.buildStaticNoSuchMethod(
+ new Selector.getter(new Name(element.name, element.library)),
+ [],
+ sourceInformationBuilder.buildGet(node));
}
@override
@@ -3485,7 +3667,8 @@
irBuilder.buildStringConstant("Unresolved class: '${element.name}'");
return irBuilder.buildStaticFunctionInvocation(
helpers.throwRuntimeError,
- <ir.Primitive>[message]);
+ <ir.Primitive>[message],
+ sourceInformationBuilder.buildNew(node));
}
@override
@@ -3501,7 +3684,8 @@
argumentsNode, selector.callStructure, arguments);
return irBuilder.buildStaticNoSuchMethod(
new Selector(selector.kind, selector.memberName, callStructure),
- arguments);
+ arguments,
+ sourceInformationBuilder.buildNew(node));
}
@override
@@ -3515,14 +3699,17 @@
callStructure =
translateDynamicArguments(argumentsNode, callStructure, arguments);
return irBuilder.buildStaticNoSuchMethod(
- new Selector.call(constructor.memberName, callStructure), arguments);
+ new Selector.call(constructor.memberName, callStructure), arguments,
+ sourceInformationBuilder.buildNew(node));
}
@override
ir.Primitive visitUnresolvedGet(
ast.Send node,
Element element, _) {
- return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), []);
+ return irBuilder.buildStaticNoSuchMethod(
+ elements.getSelector(node), [],
+ sourceInformationBuilder.buildGet(node));
}
@override
@@ -3531,8 +3718,10 @@
Element element,
ast.NodeList arguments,
Selector selector, _) {
- return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node),
- arguments.nodes.mapToList(visit));
+ return irBuilder.buildStaticNoSuchMethod(
+ elements.getSelector(node),
+ arguments.nodes.mapToList(visit),
+ sourceInformationBuilder.buildCall(node, node.selector));
}
@override
@@ -3549,7 +3738,8 @@
translateDynamicArguments(argumentsNode, callStructure, arguments);
return irBuilder.buildStaticNoSuchMethod(
new Selector.call(name, callStructure),
- arguments);
+ arguments,
+ sourceInformationBuilder.buildNew(node));
}
@override
@@ -3558,7 +3748,8 @@
Element element,
ast.Node rhs, _) {
return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node),
- [visit(rhs)]);
+ [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3568,7 +3759,8 @@
ast.Node index, _) {
// Assume the index getter is missing.
return buildSuperNoSuchMethod(
- new Selector.index(), elements.getTypeMask(node), [visit(index)]);
+ new Selector.index(), elements.getTypeMask(node), [visit(index)],
+ sourceInformationBuilder.buildIndex(node));
}
@override
@@ -3580,7 +3772,8 @@
return buildSuperNoSuchMethod(
elements.getSelector(node),
elements.getTypeMask(node),
- [visit(argument)]);
+ [visit(argument)],
+ sourceInformationBuilder.buildCall(node, node.selector));
}
@override
@@ -3589,7 +3782,8 @@
op.UnaryOperator operator,
Element element, _) {
return buildSuperNoSuchMethod(
- elements.getSelector(node), elements.getTypeMask(node), []);
+ elements.getSelector(node), elements.getTypeMask(node), [],
+ sourceInformationBuilder.buildCall(node, node.selector));
}
@override
@@ -3611,7 +3805,8 @@
ClassElement element = type.element;
return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(element.memberName),
- [visit(rhs)]);
+ [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3623,7 +3818,8 @@
TypedefElement element = type.element;
return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(element.memberName),
- [visit(rhs)]);
+ [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3632,7 +3828,8 @@
TypeVariableElement element,
ast.Node rhs, _) {
return irBuilder.buildStaticNoSuchMethod(
- new Selector.setter(element.memberName), [visit(rhs)]);
+ new Selector.setter(element.memberName), [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3641,7 +3838,8 @@
ConstantExpression constant,
ast.Node rhs, _) {
return irBuilder.buildStaticNoSuchMethod(
- new Selector.setter(Names.dynamic_), [visit(rhs)]);
+ new Selector.setter(Names.dynamic_), [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3656,7 +3854,8 @@
irBuilder.buildStringConstant(element.enclosingClass.name);
return irBuilder.buildStaticFunctionInvocation(
helpers.throwAbstractClassInstantiationError,
- <ir.Primitive>[name]);
+ <ir.Primitive>[name],
+ sourceInformationBuilder.buildNew(node));
}
@override
@@ -3667,7 +3866,8 @@
// TODO(asgerf): Include class name somehow for static class members?
return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(field.memberName),
- [visit(rhs)]);
+ [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3678,7 +3878,8 @@
return buildSuperNoSuchMethod(
new Selector.setter(field.memberName),
elements.getTypeMask(node),
- [visit(rhs)]);
+ [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3688,7 +3889,8 @@
ast.Node rhs, _) {
return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(new Name(local.name, local.library)),
- [visit(rhs)]);
+ [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3699,7 +3901,8 @@
_) {
return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(function.memberName),
- [visit(rhs)]);
+ [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3710,7 +3913,8 @@
_) {
return irBuilder.buildStaticNoSuchMethod(
new Selector.setter(getter.memberName),
- [visit(rhs)]);
+ [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3720,7 +3924,8 @@
_) {
return irBuilder.buildStaticNoSuchMethod(
new Selector.getter(setter.memberName),
- []);
+ [],
+ sourceInformationBuilder.buildGet(node));
}
@override
@@ -3733,7 +3938,8 @@
List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
return irBuilder.buildStaticNoSuchMethod(
new Selector.call(setter.memberName, callStructure),
- arguments);
+ arguments,
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
@override
@@ -3745,7 +3951,8 @@
return buildSuperNoSuchMethod(
new Selector.setter(getter.memberName),
elements.getTypeMask(node),
- [visit(rhs)]);
+ [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3757,7 +3964,8 @@
return buildSuperNoSuchMethod(
new Selector.setter(method.memberName),
elements.getTypeMask(node),
- [visit(rhs)]);
+ [visit(rhs)],
+ sourceInformationBuilder.buildAssignment(node));
}
@override
@@ -3765,9 +3973,10 @@
ast.Send node,
SetterElement setter, _) {
return buildSuperNoSuchMethod(
- new Selector.setter(setter.memberName),
+ new Selector.getter(setter.memberName),
elements.getTypeMask(node),
- []);
+ [],
+ sourceInformationBuilder.buildGet(node));
}
@override
@@ -3782,7 +3991,8 @@
return buildSuperNoSuchMethod(
new Selector.call(setter.memberName, callStructure),
elements.getTypeMask(node),
- arguments);
+ arguments,
+ sourceInformationBuilder.buildCall(node, argumentsNode));
}
ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index 9649268..d543cc6 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -12,7 +12,6 @@
import '../io/source_information.dart' show SourceInformation;
import '../types/types.dart' show TypeMask;
import '../universe/selector.dart' show Selector;
-import '../universe/side_effects.dart';
import 'builtin_operator.dart';
export 'builtin_operator.dart';
@@ -1113,10 +1112,11 @@
///
class GetMutable extends Primitive {
final Reference<MutableVariable> variableRef;
+ final SourceInformation sourceInformation;
MutableVariable get variable => variableRef.definition;
- GetMutable(MutableVariable variable)
+ GetMutable(MutableVariable variable, {this.sourceInformation})
: this.variableRef = new Reference<MutableVariable>(variable);
accept(Visitor visitor) => visitor.visitGetMutable(this);
@@ -1139,11 +1139,15 @@
class SetMutable extends Primitive {
final Reference<MutableVariable> variableRef;
final Reference<Primitive> valueRef;
+ final SourceInformation sourceInformation;
MutableVariable get variable => variableRef.definition;
Primitive get value => valueRef.definition;
- SetMutable(MutableVariable variable, Primitive value)
+ SetMutable(
+ MutableVariable variable,
+ Primitive value,
+ {this.sourceInformation})
: this.variableRef = new Reference<MutableVariable>(variable),
this.valueRef = new Reference<Primitive>(value);
@@ -1165,6 +1169,7 @@
class GetField extends Primitive {
final Reference<Primitive> objectRef;
FieldElement field;
+ final SourceInformation sourceInformation;
/// True if the field never changes value.
final bool isFinal;
@@ -1176,7 +1181,11 @@
Primitive get object => objectRef.definition;
- GetField(Primitive object, this.field, {this.isFinal: false})
+ GetField(
+ Primitive object,
+ this.field,
+ {this.sourceInformation,
+ this.isFinal: false})
: this.objectRef = new Reference<Primitive>(object);
accept(Visitor visitor) => visitor.visitGetField(this);
@@ -1199,11 +1208,16 @@
final Reference<Primitive> objectRef;
FieldElement field;
final Reference<Primitive> valueRef;
+ final SourceInformation sourceInformation;
Primitive get object => objectRef.definition;
Primitive get value => valueRef.definition;
- SetField(Primitive object, this.field, Primitive value)
+ SetField(
+ Primitive object,
+ this.field,
+ Primitive value,
+ {this.sourceInformation})
: this.objectRef = new Reference<Primitive>(object),
this.valueRef = new Reference<Primitive>(value);
@@ -1434,7 +1448,7 @@
/// May be `null` to indicate that no type information is needed because the
/// compiler determined that the type information for instances of this class
/// is not needed at runtime.
- final Reference<Primitive> typeInformationRef;
+ Reference<Primitive> typeInformationRef;
final SourceInformation sourceInformation;
@@ -1528,13 +1542,18 @@
final TypeMask storedType;
final List<Reference<Primitive>> argumentRefs;
final native.NativeBehavior nativeBehavior;
+ final SourceInformation sourceInformation;
final FunctionElement dependency;
Primitive argument(int n) => argumentRefs[n].definition;
Iterable<Primitive> get arguments => _dereferenceList(argumentRefs);
- ForeignCode(this.codeTemplate, this.storedType, List<Primitive> arguments,
+ ForeignCode(
+ this.codeTemplate,
+ this.storedType,
+ List<Primitive> arguments,
this.nativeBehavior,
+ this.sourceInformation,
{this.dependency})
: this.argumentRefs = _referenceList(arguments) {
effects = Effects.from(nativeBehavior.sideEffects);
@@ -2052,6 +2071,7 @@
final Reference<Primitive> conditionRef;
final Reference<Continuation> trueContinuationRef;
final Reference<Continuation> falseContinuationRef;
+ final SourceInformation sourceInformation;
Primitive get condition => conditionRef.definition;
Continuation get trueContinuation => trueContinuationRef.definition;
@@ -2064,7 +2084,11 @@
/// boolean.
bool isStrictCheck;
- Branch(Primitive condition, Continuation trueCont, Continuation falseCont,
+ Branch(
+ Primitive condition,
+ Continuation trueCont,
+ Continuation falseCont,
+ this.sourceInformation,
{bool strict})
: this.conditionRef = new Reference<Primitive>(condition),
trueContinuationRef = new Reference<Continuation>(trueCont),
@@ -2074,12 +2098,18 @@
}
Branch.strict(
- Primitive condition, Continuation trueCont, Continuation falseCont)
- : this(condition, trueCont, falseCont, strict: true);
+ Primitive condition,
+ Continuation trueCont,
+ Continuation falseCont,
+ SourceInformation sourceInformation)
+ : this(condition, trueCont, falseCont, sourceInformation, strict: true);
Branch.loose(
- Primitive condition, Continuation trueCont, Continuation falseCont)
- : this(condition, trueCont, falseCont, strict: false);
+ Primitive condition,
+ Continuation trueCont,
+ Continuation falseCont,
+ SourceInformation sourceInformation)
+ : this(condition, trueCont, falseCont, sourceInformation, strict: false);
accept(BlockVisitor visitor) => visitor.visitBranch(this);
@@ -2820,7 +2850,8 @@
}
Definition visitSetMutable(SetMutable node) {
- return new SetMutable(getCopy(node.variableRef), getCopy(node.valueRef));
+ return new SetMutable(getCopy(node.variableRef), getCopy(node.valueRef),
+ sourceInformation: node.sourceInformation);
}
Definition visitSetStatic(SetStatic node) {
@@ -2830,7 +2861,8 @@
Definition visitSetField(SetField node) {
return new SetField(
- getCopy(node.objectRef), node.field, getCopy(node.valueRef));
+ getCopy(node.objectRef), node.field, getCopy(node.valueRef),
+ sourceInformation: node.sourceInformation);
}
Definition visitGetLazyStatic(GetLazyStatic node) {
@@ -2856,7 +2888,8 @@
}
Definition visitGetMutable(GetMutable node) {
- return new GetMutable(getCopy(node.variableRef));
+ return new GetMutable(
+ getCopy(node.variableRef), sourceInformation: node.sourceInformation);
}
Definition visitParameter(Parameter node) {
@@ -2972,6 +3005,7 @@
Definition visitForeignCode(ForeignCode node) {
return new ForeignCode(node.codeTemplate, node.storedType,
getList(node.argumentRefs), node.nativeBehavior,
+ node.sourceInformation,
dependency: node.dependency);
}
}
@@ -3110,7 +3144,8 @@
plug(new Branch.loose(
_definitions.getCopy(node.conditionRef),
_copies[node.trueContinuation],
- _copies[node.falseContinuation])..isStrictCheck = node.isStrictCheck);
+ _copies[node.falseContinuation],
+ node.sourceInformation)..isStrictCheck = node.isStrictCheck);
}
visitUnreachable(Unreachable node) {
diff --git a/pkg/compiler/lib/src/cps_ir/gvn.dart b/pkg/compiler/lib/src/cps_ir/gvn.dart
index 8bf896d..d8eeff0 100644
--- a/pkg/compiler/lib/src/cps_ir/gvn.dart
+++ b/pkg/compiler/lib/src/cps_ir/gvn.dart
@@ -5,7 +5,6 @@
library dart2js.cps_ir.gvn;
import 'cps_ir_nodes.dart';
-import '../universe/side_effects.dart';
import '../elements/elements.dart';
import 'optimizers.dart' show Pass;
import 'loop_hierarchy.dart';
@@ -13,7 +12,6 @@
import '../world.dart';
import '../compiler.dart' show Compiler;
import '../js_backend/js_backend.dart' show JavaScriptBackend;
-import '../constants/values.dart';
import 'type_mask_system.dart';
import 'effects.dart';
@@ -578,7 +576,7 @@
}
processTypeExpression(TypeExpression node) {
- vector = [GvnCode.TYPE_EXPRESSION, node.dartType];
+ vector = [GvnCode.TYPE_EXPRESSION, node.kind.index, node.dartType];
}
processInterceptor(Interceptor node) {
diff --git a/pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart b/pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart
index e7c747f..965a632 100644
--- a/pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart
+++ b/pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart
@@ -7,10 +7,6 @@
import 'optimizers.dart';
import 'cps_fragment.dart';
import '../js_backend/js_backend.dart';
-import '../constants/values.dart';
-import '../elements/elements.dart';
-import '../universe/selector.dart';
-import '../types/types.dart';
import 'type_mask_system.dart';
/// Optimizations based on intraprocedural forward dataflow analysis, taking
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index f665897..41d33f9 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -25,9 +25,7 @@
JavaScriptBackend;
import '../js_backend/codegen/task.dart' show
CpsFunctionCompiler;
-import '../resolution/access_semantics.dart';
import '../resolution/operators.dart';
-import '../resolution/send_structure.dart';
import '../tree/tree.dart' as ast;
import '../types/types.dart';
import '../types/abstract_value_domain.dart' show
@@ -2518,12 +2516,12 @@
TypeExpression typeExpression = instance.typeInformation;
assert(typeExpression.kind == TypeExpressionKind.INSTANCE);
ClassElement context = node.variable.element.enclosingClass;
+ ClassElement createdClass = instance.classElement;
// In the general case, a substitution could generate a large type
// term. Avoid this by restricting to direct indexing.
// TODO(sra): Also include cases that require substitution but the end
// result is the same as some indexing or a simple constant type.
- if (!functionCompiler.glue.needsSubstitutionForTypeVariableAccess(
- context)) {
+ if (backend.rti.isTrivialSubstitution(createdClass, context)) {
int index = functionCompiler.glue.getTypeVariableIndex(node.variable);
if (0 <= index && index < typeExpression.argumentRefs.length) {
node.replaceUsesWith(typeExpression.argument(index));
@@ -2534,6 +2532,16 @@
}
return null;
}
+
+ bool isNullConstant(Primitive prim) => prim is Constant && prim.value.isNull;
+
+ visitCreateInstance(CreateInstance node) {
+ Primitive typeInformation = node.typeInformation;
+ if (typeInformation is TypeExpression &&
+ typeInformation.arguments.every(isNullConstant)) {
+ node..typeInformationRef.unlink()..typeInformationRef = null;
+ }
+ }
}
/**
diff --git a/pkg/compiler/lib/src/cps_ir/use_field_initializers.dart b/pkg/compiler/lib/src/cps_ir/use_field_initializers.dart
index ca510f7..e923a22 100644
--- a/pkg/compiler/lib/src/cps_ir/use_field_initializers.dart
+++ b/pkg/compiler/lib/src/cps_ir/use_field_initializers.dart
@@ -12,7 +12,7 @@
/// the field initializer of a [CreateInstance] instruction.
///
/// This compensates for a somewhat common pattern where fields are initialized
-/// in the constructor body instead of using intializers. For example:
+/// in the constructor body instead of using initializers. For example:
///
/// class Foo {
/// var x, y;
diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart
index db02d23..23080fc 100644
--- a/pkg/compiler/lib/src/dart_types.dart
+++ b/pkg/compiler/lib/src/dart_types.dart
@@ -9,8 +9,6 @@
import 'common.dart';
import 'common/resolution.dart' show
Resolution;
-import 'compiler.dart' show
- Compiler;
import 'core_types.dart';
import 'elements/modelx.dart' show
LibraryElementX,
diff --git a/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart b/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
index 50dc24a..a18ce66 100644
--- a/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
@@ -12,10 +12,10 @@
import '../messages.dart' show MessageKind, MessageTemplate;
const Map<MessageKind, MessageTemplate> TEMPLATES = const <MessageKind, MessageTemplate>{
- MessageKind.CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY: const MessageTemplate(
- MessageKind.CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY,
- "Const constructor or factory can't have a body.",
- howToFix: "Remove the 'const' keyword or the body.",
+ MessageKind.CONST_CONSTRUCTOR_WITH_BODY: const MessageTemplate(
+ MessageKind.CONST_CONSTRUCTOR_WITH_BODY,
+ "Const constructor can't have a body.",
+ howToFix: "Try removing the 'const' keyword or the body.",
examples: const [
r"""
class C {
@@ -23,6 +23,13 @@
}
main() => new C();""",
+ ]
+ ), // Generated. Don't edit.
+ MessageKind.CONST_FACTORY: const MessageTemplate(
+ MessageKind.CONST_FACTORY,
+ "Only redirecting factory constructors can be declared to be 'const'.",
+ howToFix: "Try removing the 'const' keyword or replacing the body with '=' followed by a valid target.",
+ examples: const [
r"""
class C {
const factory C() {}
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 7a80947..d18628c 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -144,10 +144,11 @@
CONSIDER_ANALYZE_ALL,
CONST_CALLS_NON_CONST,
CONST_CALLS_NON_CONST_FOR_IMPLICIT,
- CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY,
+ CONST_CONSTRUCTOR_WITH_BODY,
CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR,
CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD,
+ CONST_FACTORY,
CONST_LOOP_VARIABLE,
CONST_MAP_KEY_OVERRIDES_EQUALS,
CONST_WITHOUT_INITIALIZER,
diff --git a/pkg/compiler/lib/src/helpers/debug_collection.dart b/pkg/compiler/lib/src/helpers/debug_collection.dart
index 8ff4be2..74a3d2e 100644
--- a/pkg/compiler/lib/src/helpers/debug_collection.dart
+++ b/pkg/compiler/lib/src/helpers/debug_collection.dart
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of dart2js.helpers;
typedef void DebugCallback(String methodName, var arg1, var arg2);
@@ -328,4 +327,4 @@
throw '$name: $text$elementType'
'${showObjects ? ' ($element)' : ''}';
}
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/helpers/expensive_map.dart b/pkg/compiler/lib/src/helpers/expensive_map.dart
index 1a6e5e8..68d106e 100644
--- a/pkg/compiler/lib/src/helpers/expensive_map.dart
+++ b/pkg/compiler/lib/src/helpers/expensive_map.dart
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of dart2js.helpers;
/**
* The expensive map is a data structure useful for tracking down
diff --git a/pkg/compiler/lib/src/helpers/expensive_set.dart b/pkg/compiler/lib/src/helpers/expensive_set.dart
index b57db8a..c74588b 100644
--- a/pkg/compiler/lib/src/helpers/expensive_set.dart
+++ b/pkg/compiler/lib/src/helpers/expensive_set.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of dart2js.helpers;
+import 'dart:collection';
/**
* The expensive set is a data structure useful for tracking down
diff --git a/pkg/compiler/lib/src/helpers/helpers.dart b/pkg/compiler/lib/src/helpers/helpers.dart
index f956850..4754edd 100644
--- a/pkg/compiler/lib/src/helpers/helpers.dart
+++ b/pkg/compiler/lib/src/helpers/helpers.dart
@@ -7,25 +7,19 @@
library dart2js.helpers;
-import 'dart:async' show
- EventSink;
-import 'dart:collection';
-import 'dart:convert';
-
-import '../../compiler.dart';
import '../common.dart';
-import '../compiler.dart' show
- Compiler;
import '../diagnostics/invariant.dart' show
DEBUG_MODE;
import '../util/util.dart';
-part 'debug_collection.dart';
-part 'trace.dart';
-part 'expensive_map.dart';
-part 'expensive_set.dart';
-part 'stats.dart';
-part 'track_map.dart';
+import 'trace.dart';
+
+export 'debug_collection.dart';
+export 'trace.dart';
+export 'expensive_map.dart';
+export 'expensive_set.dart';
+export 'stats.dart';
+export 'track_map.dart';
/// Global flag to enable [debugPrint]. This should always be `true` by default
/// and be set to `false` as a means to temporarily turn off all debugging
diff --git a/pkg/compiler/lib/src/helpers/stats.dart b/pkg/compiler/lib/src/helpers/stats.dart
index d7f6b5d..1d5675f 100644
--- a/pkg/compiler/lib/src/helpers/stats.dart
+++ b/pkg/compiler/lib/src/helpers/stats.dart
@@ -2,7 +2,17 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of dart2js.helpers;
+import 'dart:async' show
+ EventSink;
+import 'dart:collection';
+import 'dart:convert';
+
+import '../../compiler.dart';
+import '../common.dart';
+import '../compiler.dart' show
+ Compiler;
+import '../util/util.dart';
+
// Helper methods for statistics.
diff --git a/pkg/compiler/lib/src/helpers/trace.dart b/pkg/compiler/lib/src/helpers/trace.dart
index 0889efd..671d842 100644
--- a/pkg/compiler/lib/src/helpers/trace.dart
+++ b/pkg/compiler/lib/src/helpers/trace.dart
@@ -2,7 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of dart2js.helpers;
+import '../common.dart';
+import '../util/util.dart';
/// Function signature for [trace].
typedef void Trace(String message,
diff --git a/pkg/compiler/lib/src/helpers/track_map.dart b/pkg/compiler/lib/src/helpers/track_map.dart
index 5f827a6..b57be3a 100644
--- a/pkg/compiler/lib/src/helpers/track_map.dart
+++ b/pkg/compiler/lib/src/helpers/track_map.dart
@@ -2,7 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of dart2js.helpers;
/**
* The track map is a simple wrapper around a map that keeps track
diff --git a/pkg/compiler/lib/src/inferrer/debug.dart b/pkg/compiler/lib/src/inferrer/debug.dart
index 502f966..8c29448 100644
--- a/pkg/compiler/lib/src/inferrer/debug.dart
+++ b/pkg/compiler/lib/src/inferrer/debug.dart
@@ -5,7 +5,7 @@
/// Values used only for debugging type inference.
library compiler.src.inferrer.debug;
-bool VERBOSE = false;
-bool PRINT_SUMMARY = false;
-final ANOMALY_WARN = false;
-
+const bool VERBOSE = false;
+const bool PRINT_SUMMARY = false;
+const bool ANOMALY_WARN = false;
+const bool PRINT_GRAPH = false;
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
new file mode 100644
index 0000000..a3520a0
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
@@ -0,0 +1,445 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+library dart2js.inferrer.type_graph_dump;
+
+import 'dart:async';
+import 'type_graph_nodes.dart';
+import 'type_graph_inferrer.dart';
+import '../elements/elements.dart';
+import '../types/types.dart';
+
+/// Dumps the type inference graph in Graphviz Dot format into the `typegraph`
+/// subfolder of the current working directory. Each function body is dumped in
+/// a separate file.
+///
+/// The resulting .dot files must be processed using the Graphviz `dot` command,
+/// which can be obtained from `http://www.graphviz.org`, or installed using
+/// most package managers (search for `graphviz` or `dot`).
+///
+/// Example commands:
+///
+/// dot -Tpng -O typegraph/main.dot
+/// open typegraph/main.dot.png
+///
+/// dot -Tpng -O typegraph/dart._internal.Sort._dualPivotQuicksort.dot
+/// open typegraph/dart._internal.Sort._dualPivotQuicksort.dot.png
+///
+class TypeGraphDump {
+ static const String outputDir = 'typegraph';
+
+ final TypeGraphInferrerEngine inferrer;
+ final Map<TypeInformation, Set<TypeInformation>> assignmentsBeforeAnalysis
+ = <TypeInformation, Set<TypeInformation>>{};
+ final Map<TypeInformation, Set<TypeInformation>> assignmentsBeforeTracing
+ = <TypeInformation, Set<TypeInformation>>{};
+ final Set<String> usedFilenames = new Set<String>();
+
+ TypeGraphDump(this.inferrer);
+
+ /// Take a copy of the assignment set for each node, since that may change
+ /// during the analysis.
+ void beforeAnalysis() {
+ for (TypeInformation node in inferrer.types.allTypes) {
+ Set<TypeInformation> copy = node.assignments.toSet();
+ if (!copy.isEmpty) {
+ assignmentsBeforeAnalysis[node] = copy;
+ }
+ }
+ }
+
+ /// Like [beforeAnalysis], takes a copy of the assignment sets.
+ void beforeTracing() {
+ for (TypeInformation node in inferrer.types.allTypes) {
+ Set<TypeInformation> copy = node.assignments.toSet();
+ if (!copy.isEmpty) {
+ assignmentsBeforeTracing[node] = copy;
+ }
+ }
+ }
+
+ /// Dumps the entire graph.
+ void afterAnalysis() {
+ // Group all the type nodes by their context member.
+ Map<Element, List<TypeInformation>> nodes =
+ <Element, List<TypeInformation>>{};
+ for (TypeInformation node in inferrer.types.allTypes) {
+ if (node.contextMember != null) {
+ nodes.putIfAbsent(node.contextMember, () => <TypeInformation>[])
+ .add(node);
+ }
+ }
+ // Print every group separately.
+ for (Element element in nodes.keys) {
+ EventSink<String> output;
+ try {
+ String name = filenameFromElement(element);
+ output = inferrer.compiler.outputProvider('$outputDir/$name', 'dot');
+ _GraphGenerator visitor = new _GraphGenerator(this, element, output);
+ for (TypeInformation node in nodes[element]) {
+ node.accept(visitor);
+ }
+ visitor.addMissingNodes();
+ visitor.finish();
+ } finally {
+ if (output != null) {
+ output.close();
+ }
+ }
+ }
+ }
+
+ /// Returns the filename (without extension) in which to dump the type
+ /// graph for [element].
+ ///
+ /// Will never return the a given filename more than once, even if called with
+ /// the same element.
+ String filenameFromElement(Element element) {
+ // The toString method of elements include characters that are unsuitable
+ // for URIs and file systems.
+ List<String> parts = <String>[];
+ parts.add(element.library?.libraryName);
+ parts.add(element.enclosingClass?.name);
+ Element namedElement = element is LocalElement
+ ? element.executableContext
+ : element;
+ if (namedElement.isGetter) {
+ parts.add('get-${namedElement.name}');
+ } else if (namedElement.isSetter) {
+ parts.add('set-${namedElement.name}');
+ } else if (namedElement.isConstructor) {
+ if (namedElement.name.isEmpty) {
+ parts.add('-constructor');
+ } else {
+ parts.add(namedElement.name);
+ }
+ } else if (namedElement.isOperator) {
+ parts.add(Elements.operatorNameToIdentifier(namedElement.name)
+ .replaceAll(r'$', '-'));
+ } else {
+ parts.add(namedElement.name);
+ }
+ if (namedElement != element) {
+ if (element.name.isEmpty) {
+ parts.add('anon${element.sourcePosition.begin}');
+ } else {
+ parts.add(element.name);
+ }
+ }
+ String filename = parts.where((x) => x != null && x != '').join('.');
+ if (usedFilenames.add(filename)) return filename;
+ // The filename has already been used by another method. Append a serial
+ // number to ensure we don't overwrite it.
+ int serialNumber = 2;
+ while (!usedFilenames.add('$filename-$serialNumber')) {
+ ++serialNumber;
+ }
+ return '$filename-$serialNumber';
+ }
+}
+
+/// Builds the Graphviz Dot file for one function body.
+class _GraphGenerator extends TypeInformationVisitor {
+ final TypeGraphDump global;
+ final Set<TypeInformation> seen = new Set<TypeInformation>();
+ final List<TypeInformation> worklist = new List<TypeInformation>();
+ final Map<TypeInformation, int> nodeId = <TypeInformation, int>{};
+ int usedIds = 0;
+ final EventSink<String> output;
+ final Element element;
+ TypeInformation returnValue;
+
+ _GraphGenerator(this.global, this.element, this.output) {
+ returnValue = global.inferrer.types.getInferredTypeOf(element);
+ getNode(returnValue); // Ensure return value is part of graph.
+ append('digraph {');
+ }
+
+ void finish() {
+ append('}');
+ }
+
+ /// Ensures that all nodes which have been referenced are generated.
+ ///
+ /// Sometimes an input to a TypeInformation node does not belong to the same
+ /// function body, and the graph looks confusing if they are missing.
+ void addMissingNodes() {
+ while (worklist.isNotEmpty) {
+ TypeInformation node = worklist.removeLast();
+ assert(nodeId.containsKey(node));
+ if (seen.contains(node)) continue;
+ node.accept(this);
+ }
+ }
+
+ void append(String string) {
+ output..add(string)..add('\n');
+ }
+
+ String shorten(String text) {
+ if (text.length > 40) {
+ return text.substring(0, 19) + '...' + text.substring(text.length - 18);
+ }
+ return text;
+ }
+
+ int getFreshId() => ++usedIds;
+
+ /// Obtains a unique ID for the node representing [info].
+ String getNode(TypeInformation info) {
+ int id = nodeId.putIfAbsent(info, () {
+ worklist.add(info); // Ensure that the referenced node is generated.
+ return getFreshId();
+ });
+ return '$id';
+ }
+
+ final RegExp escapeRegexp = new RegExp('["{}<>|]');
+
+ /// Escapes characters in [text] so it can be used as part of a label.
+ String escapeLabel(String text) {
+ return text.replaceAllMapped(escapeRegexp, (m) => '\\${m.group(0)}');
+ }
+
+ /// Creates an edge from [src] to [dst].
+ ///
+ /// If [dst] is a record type node, [port] may refer to one of the fields
+ /// defined in that record (e.g. `obj`, `arg0`, `arg1`, etc)
+ void addEdge(TypeInformation src,
+ TypeInformation dst,
+ {String port,
+ String color: 'black'}) {
+ if (isExternal(src) && isExternal(dst)) {
+ return; // Do not add edges between external nodes.
+ }
+ String dstText = getNode(dst);
+ if (port != null) {
+ dstText += ':$port';
+ }
+ if (src is ConcreteTypeInformation) {
+ // Concrete types can have a huge number of uses which will flood the
+ // graph with very long hard-to-follow edges. Copy the concrete nodes
+ // for every use to enhance readability.
+ int id = getFreshId();
+ String type = escapeLabel('${formatType(src.type)}');
+ String text = 'Concrete';
+ String label = '{$text|<returnType> $type}';
+ append('$id [shape=record,style=dotted,label="$label"]');
+ append('$id -> $dstText [color="$color"]');
+ } else {
+ append('${getNode(src)}:returnType -> $dstText [color="$color"]');
+ }
+ }
+
+ // Some graphs are flooded by a huge number of phi and narrow nodes.
+ // We color the nodes so the "interesting" nodes stand out more.
+ static const String defaultNodeColor = '#eeffee';
+ static const String phiColor = '#eeffff';
+ static const String narrowColor = phiColor;
+ static const String callColor = '#ffffee';
+
+ // Colors for edges based on whether they were added or removed during the
+ // analysis.
+ static const String unchangedEdge = 'black';
+ static const String addedEdge = 'green4';
+ static const String removedEdge = 'red3';
+ static const String temporaryEdge = 'orange'; // Added and then removed again.
+
+ bool isExternal(TypeInformation node) {
+ return node != returnValue && node.contextMember != element;
+ }
+
+ String getStyleForNode(TypeInformation node, String color) {
+ return isExternal(node)
+ ? 'style=dotted'
+ : 'style=filled,fillcolor="$color"';
+ }
+
+ /// Adds details that are not specific to a subclass of [TypeInformation].
+ String appendDetails(TypeInformation node, String text) {
+ if (node == returnValue) {
+ return '$text\n(return value)';
+ }
+ if (node.contextMember != null && node.contextMember != element) {
+ return '$text\n(from ${node.contextMember})';
+ }
+ return text;
+ }
+
+ /// Creates a node for [node] displaying the given [text] in its box.
+ ///
+ /// [inputs] specify named inputs to the node. If omitted, edges will be
+ /// based on [node.assignments].
+ void addNode(TypeInformation node,
+ String text,
+ {String color: defaultNodeColor,
+ Map<String, TypeInformation> inputs}) {
+ seen.add(node);
+ String style = getStyleForNode(node, color);
+ text = appendDetails(node, text);
+ text = escapeLabel(text);
+ String id = getNode(node);
+ String returnType = escapeLabel(formatType(node.type));
+ if (inputs != null) {
+ Iterable<String> keys = inputs.keys.where((key) => inputs[key] != null);
+ String header = keys.map((key) => '<a$key> $key').join('|');
+ String label = '{{$header}|$text|<returnType> $returnType}';
+ append('$id [shape=record,label="$label",$style]');
+ for (String key in keys) {
+ addEdge(inputs[key], node, port: 'a$key');
+ }
+ } else {
+ String label = '{$text|<returnType> $returnType}';
+ append('$id [shape=record,label="$label",$style]');
+ // Add assignment edges. Color the edges based on whether they were
+ // added, removed, temporary, or unchanged.
+ var originalSet = global.assignmentsBeforeAnalysis[node] ?? const [];
+ var tracerSet = global.assignmentsBeforeTracing[node] ?? const [];
+ var currentSet = node.assignments.toSet();
+ for (TypeInformation assignment in currentSet) {
+ String color = originalSet.contains(assignment)
+ ? unchangedEdge
+ : addedEdge;
+ addEdge(assignment, node, color: color);
+ }
+ for (TypeInformation assignment in originalSet) {
+ if (!currentSet.contains(assignment)) {
+ addEdge(assignment, node, color: removedEdge);
+ }
+ }
+ for (TypeInformation assignment in tracerSet) {
+ if (!currentSet.contains(assignment) &&
+ !originalSet.contains(assignment)) {
+ addEdge(assignment, node, color: temporaryEdge);
+ }
+ }
+ }
+ }
+
+ void visitNarrowTypeInformation(NarrowTypeInformation info) {
+ addNode(info, 'Narrow\n${formatType(info.typeAnnotation)}',
+ color: narrowColor);
+ }
+
+ void visitPhiElementTypeInformation(PhiElementTypeInformation info) {
+ addNode(info, 'Phi ${info.variable?.name ?? ''}', color: phiColor);
+ }
+
+ void visitElementInContainerTypeInformation(
+ ElementInContainerTypeInformation info) {
+ addNode(info, 'ElementInContainer');
+ }
+
+ void visitKeyInMapTypeInformation(KeyInMapTypeInformation info) {
+ addNode(info, 'KeyInMap');
+ }
+
+ void visitValueInMapTypeInformation(ValueInMapTypeInformation info) {
+ addNode(info, 'ValueInMap');
+ }
+
+ void visitListTypeInformation(ListTypeInformation info) {
+ addNode(info, 'List');
+ }
+
+ void visitMapTypeInformation(MapTypeInformation info) {
+ addNode(info, 'Map');
+ }
+
+ void visitConcreteTypeInformation(ConcreteTypeInformation info) {
+ addNode(info, 'Concrete');
+ }
+
+ void visitStringLiteralTypeInformation(StringLiteralTypeInformation info) {
+ String text = shorten(info.value.slowToString()).replaceAll('\n','\\n');
+ addNode(info, 'StringLiteral\n"$text"');
+ }
+
+ void visitBoolLiteralTypeInformation(BoolLiteralTypeInformation info) {
+ addNode(info, 'BoolLiteral\n${info.value}');
+ }
+
+ void handleCall(CallSiteTypeInformation info, String text, Map inputs) {
+ String sourceCode = shorten('${info.call}');
+ text = '$text\n$sourceCode';
+ if (info.arguments != null) {
+ for (int i = 0; i < info.arguments.positional.length; ++i) {
+ inputs['arg$i'] = info.arguments.positional[i];
+ }
+ for (String argName in info.arguments.named.keys) {
+ inputs[argName] = info.arguments.named[argName];
+ }
+ }
+ addNode(info, text, color: callColor, inputs: inputs);
+ }
+
+ void visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) {
+ handleCall(info, 'ClosureCallSite', {});
+ }
+
+ void visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
+ handleCall(info, 'StaticCallSite', {});
+ }
+
+ void visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) {
+ handleCall(info, 'DynamicCallSite', {
+ 'obj': info.receiver
+ });
+ }
+
+ void visitMemberTypeInformation(MemberTypeInformation info) {
+ addNode(info, 'Member\n${info.element}');
+ }
+
+ void visitParameterTypeInformation(ParameterTypeInformation info) {
+ addNode(info, 'Parameter ${info.element?.name ?? ''}');
+ }
+
+ void visitClosureTypeInformation(ClosureTypeInformation info) {
+ String text = shorten('${info.node}');
+ addNode(info, 'Closure\n$text');
+ }
+
+ void visitAwaitTypeInformation(AwaitTypeInformation info) {
+ String text = shorten('${info.node}');
+ addNode(info, 'Await\n$text');
+ }
+}
+
+/// Convert the given TypeMask to a compact string format.
+///
+/// The default format is too verbose for the graph format since long strings
+/// create oblong nodes that obstruct the graph layout.
+String formatType(TypeMask type) {
+ if (type is FlatTypeMask) {
+ // TODO(asgerf): Disambiguate classes whose name is not unique. Using the
+ // library name for all classes is not a good idea, since library names
+ // can be really long and mess up the layout.
+ // Capitalize Null to emphasize that it's the null type mask and not
+ // a null value we accidentally printed out.
+ if (type.isEmptyOrNull) return type.isNullable ? 'Null' : 'Empty';
+ String nullFlag = type.isNullable ? '?' : '';
+ String subFlag = type.isExact ? '' : type.isSubclass ? '+' : '*';
+ return '${type.base.name}$nullFlag$subFlag';
+ }
+ if (type is UnionTypeMask) {
+ return type.disjointMasks.map(formatType).join(' | ');
+ }
+ if (type is ContainerTypeMask) {
+ String container = formatType(type.forwardTo);
+ String member = formatType(type.elementType);
+ return '$container<$member>';
+ }
+ if (type is MapTypeMask) {
+ String container = formatType(type.forwardTo);
+ String key = formatType(type.keyType);
+ String value = formatType(type.valueType);
+ return '$container<$key,$value>';
+ }
+ if (type is ValueTypeMask) {
+ String baseType = formatType(type.forwardTo);
+ String value = type.value.toStructuredString();
+ return '$baseType=$value';
+ }
+ return '$type'; // Fall back on toString if not supported here.
+}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 68cf701..14d904a 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -59,6 +59,7 @@
import 'list_tracer.dart';
import 'map_tracer.dart';
import 'type_graph_nodes.dart';
+import 'type_graph_dump.dart';
import 'debug.dart' as debug;
@@ -89,6 +90,14 @@
/// narrowing, phis, and containers).
final List<TypeInformation> allocatedTypes = <TypeInformation>[];
+ Iterable<TypeInformation> get allTypes =>
+ [typeInformations.values,
+ allocatedLists.values,
+ allocatedMaps.values,
+ allocatedClosures,
+ concreteTypes.values,
+ allocatedTypes].expand((x) => x);
+
TypeInformationSystem(Compiler compiler)
: this.compiler = compiler,
this.classWorld = compiler.world {
@@ -715,6 +724,9 @@
});
reporter.log('Added $addedInGraph elements in inferencing graph.');
+ TypeGraphDump dump = debug.PRINT_GRAPH ? new TypeGraphDump(this) : null;
+
+ dump?.beforeAnalysis();
buildWorkQueue();
refine();
@@ -799,6 +811,8 @@
}
});
+ dump?.beforeTracing();
+
// Reset all nodes that use lists/maps that have been inferred, as well
// as nodes that use elements fetched from these lists/maps. The
// workset for a new run of the analysis will be these nodes.
@@ -856,6 +870,7 @@
print('${elem} :: ${type} from ${type.assignments} ');
});
}
+ dump?.afterAnalysis();
reporter.log('Inferred $overallRefineCount types.');
@@ -1287,14 +1302,28 @@
}
void clear() {
+ void cleanup(TypeInformation info) => info.cleanup();
+
+ allocatedCalls.forEach(cleanup);
allocatedCalls.clear();
+
defaultTypeOfParameter.clear();
- types.typeInformations.values.forEach((info) => info.clear());
+
+ types.typeInformations.values.forEach(cleanup);
+
+ types.allocatedTypes.forEach(cleanup);
types.allocatedTypes.clear();
+
types.concreteTypes.clear();
+
+ types.allocatedClosures.forEach(cleanup);
types.allocatedClosures.clear();
+
analyzedElements.clear();
generativeConstructorsExposingThis.clear();
+
+ types.allocatedMaps.values.forEach(cleanup);
+ types.allocatedLists.values.forEach(cleanup);
}
Iterable<Element> getCallersOf(Element element) {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 98a9309..e549d68 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -69,7 +69,7 @@
final MemberTypeInformation context;
/// The element this [TypeInformation] node belongs to.
- MemberElement get contextMember => context == null ? null : context.element;
+ TypedElement get contextMember => context == null ? null : context.element;
Iterable<TypeInformation> get assignments => _assignments;
@@ -237,6 +237,12 @@
abandonInferencing = false;
doNotEnqueue = false;
}
+
+ /// Destroys information not needed after type inference.
+ void cleanup() {
+ users = null;
+ _assignments = null;
+ }
}
abstract class ApplyableTypeInformation implements TypeInformation {
@@ -385,6 +391,10 @@
*/
int closurizedCount = 0;
+ // Strict `bool` value is computed in cleanup(). Also used as a flag to see if
+ // cleanup has been called.
+ bool _isCalledOnce = null;
+
/**
* This map contains the callers of [element]. It stores all unique call sites
* to enable counting the global number of call sites of [element].
@@ -392,18 +402,23 @@
* A call site is either an AST [ast.Node], a [cps_ir.Node] or in the case of
* synthesized calls, an [Element] (see uses of [synthesizeForwardingCall]
* in [SimpleTypeInferrerVisitor]).
+ *
+ * The global information is summarized in [cleanup], after which [_callers]
+ * is set to `null`.
*/
- final Map<Element, Setlet<Spannable>> _callers = new Map<Element, Setlet>();
+ Map<Element, Setlet<Spannable>> _callers;
MemberTypeInformation._internal(Element element)
: super._internal(null, element);
void addCall(Element caller, Spannable node) {
assert(node is ast.Node || node is cps_ir.Node || node is Element);
+ _callers ??= <Element, Setlet>{};
_callers.putIfAbsent(caller, () => new Setlet()).add(node);
}
void removeCall(Element caller, node) {
+ if (_callers == null) return;
Setlet calls = _callers[caller];
if (calls == null) return;
calls.remove(node);
@@ -412,9 +427,27 @@
}
}
- Iterable<Element> get callers => _callers.keys;
+ Iterable<Element> get callers {
+ // TODO(sra): This is called only from an unused API and a test. If it
+ // becomes used, [cleanup] will need to copy `_caller.keys`.
+
+ // `simple_inferrer_callers_test.dart` ensures that cleanup has not
+ // happened.
+ return _callers.keys;
+ }
bool isCalledOnce() {
+ // If this assert fires it means that this MemberTypeInformation for the
+ // element was not part of type inference. This happens for
+ // ConstructorBodyElements, so guard the call with a test for
+ // ConstructorBodyElement. For other elements, investigate why the element
+ // was not present for type inference.
+ assert(_isCalledOnce != null);
+ return _isCalledOnce ?? false;
+ }
+
+ bool _computeIsCalledOnce() {
+ if (_callers == null) return false;
int count = 0;
for (var set in _callers.values) {
count += set.length;
@@ -530,6 +563,14 @@
return super.hasStableType(inferrer);
}
+
+ void cleanup() {
+ // This node is on multiple lists so cleanup() can be called twice.
+ if (_isCalledOnce != null) return;
+ _isCalledOnce = _computeIsCalledOnce();
+ _callers = null;
+ super.cleanup();
+ }
}
/**
@@ -925,28 +966,34 @@
? compiler.world.allFunctions.filter(selector, typeMask)
: targets;
- // Add calls to new targets to the graph.
- targets.where((target) => !oldTargets.contains(target)).forEach((element) {
- MemberTypeInformation callee =
- inferrer.types.getInferredTypeOf(element);
- callee.addCall(caller, call);
- callee.addUser(this);
- inferrer.updateParameterAssignments(
- this, element, arguments, selector, typeMask, remove: false,
- addToQueue: true);
- });
+ // Update the call graph if the targets could have changed.
+ if (!identical(targets, oldTargets)) {
+ // Add calls to new targets to the graph.
+ targets
+ .where((target) => !oldTargets.contains(target))
+ .forEach((element) {
+ MemberTypeInformation callee =
+ inferrer.types.getInferredTypeOf(element);
+ callee.addCall(caller, call);
+ callee.addUser(this);
+ inferrer.updateParameterAssignments(
+ this, element, arguments, selector, typeMask, remove: false,
+ addToQueue: true);
+ });
- // Walk over the old targets, and remove calls that cannot happen
- // anymore.
- oldTargets.where((target) => !targets.contains(target)).forEach((element) {
- MemberTypeInformation callee =
- inferrer.types.getInferredTypeOf(element);
- callee.removeCall(caller, call);
- callee.removeUser(this);
- inferrer.updateParameterAssignments(
- this, element, arguments, selector, typeMask, remove: true,
- addToQueue: true);
- });
+ // Walk over the old targets, and remove calls that cannot happen anymore.
+ oldTargets
+ .where((target) => !targets.contains(target))
+ .forEach((element) {
+ MemberTypeInformation callee =
+ inferrer.types.getInferredTypeOf(element);
+ callee.removeCall(caller, call);
+ callee.removeUser(this);
+ inferrer.updateParameterAssignments(
+ this, element, arguments, selector, typeMask, remove: true,
+ addToQueue: true);
+ });
+ }
// Walk over the found targets, and compute the joined union type mask
// for all these targets.
@@ -1319,6 +1366,12 @@
}
TypeMask safeType(TypeGraphInferrerEngine inferrer) => originalType;
+
+ void cleanup() {
+ super.cleanup();
+ elementType.cleanup();
+ _flowsInto = null;
+ }
}
/**
@@ -1482,6 +1535,16 @@
super.hasStableType(inferrer);
}
+ void cleanup() {
+ super.cleanup();
+ keyType.cleanup();
+ valueType.cleanup();
+ for (TypeInformation info in typeInfoMap.values) {
+ info.cleanup();
+ }
+ _flowsInto = null;
+ }
+
String toString() {
return 'Map $type (K:$keyType, V:$valueType) contents $typeInfoMap';
}
diff --git a/pkg/compiler/lib/src/info/send_info.dart b/pkg/compiler/lib/src/info/send_info.dart
index 96e0e98..0c31114 100644
--- a/pkg/compiler/lib/src/info/send_info.dart
+++ b/pkg/compiler/lib/src/info/send_info.dart
@@ -5,15 +5,11 @@
/// Computes measurements about sends in a function.
library compiler.src.info.send_info;
-import 'dart:convert';
-
import 'package:dart2js_info/src/measurements.dart';
import 'package:dart2js_info/src/util.dart' show
recursiveDiagnosticString;
import '../common.dart';
-import '../common/tasks.dart' show
- CompilerTask;
import '../compiler.dart' show
Compiler;
import '../dart_types.dart';
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 1a561cd..79e58c3 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -222,6 +222,8 @@
sourceFile, right.getBeginToken().charOffset, name));
}
+ // TODO(johnniwinther): Clean up the use of this and [buildBinary],
+ // [buildIndex], etc.
@override
SourceInformation buildCall(Node receiver, Node call) {
return new PositionSourceInformation(
@@ -266,6 +268,48 @@
SourceInformationBuilder forContext(AstElement element) {
return new PositionSourceInformationBuilder(element);
}
+
+ @override
+ SourceInformation buildForeignCode(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildStringInterpolation(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildForInIterator(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildForInMoveNext(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildForInCurrent(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildForInSet(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildIndex(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildIndexSet(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildBinary(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildCatch(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildIs(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildAs(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildSwitch(Node node) => buildBegin(node);
+
+ @override
+ SourceInformation buildSwitchCase(Node node) => buildBegin(node);
}
/// The start, end and closing offsets for a [js.Node].
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index 35d9583..8a24759 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -105,6 +105,48 @@
/// Generate [SourceInformation] for the variable declaration inserted as
/// first statement of a function.
SourceInformation buildVariableDeclaration() => null;
+
+ /// Generate [SourceInformation] for an invocation of a foreign method.
+ SourceInformation buildForeignCode(Node node) => null;
+
+ /// Generate [SourceInformation] for a string interpolation of [node].
+ SourceInformation buildStringInterpolation(Node node) => null;
+
+ /// Generate [SourceInformation] for the for-in `iterator` access in [node].
+ SourceInformation buildForInIterator(Node node) => null;
+
+ /// Generate [SourceInformation] for the for-in `moveNext` call in [node].
+ SourceInformation buildForInMoveNext(Node node) => null;
+
+ /// Generate [SourceInformation] for the for-in `current` access in [node].
+ SourceInformation buildForInCurrent(Node node) => null;
+
+ /// Generate [SourceInformation] for the for-in variable assignment in [node].
+ SourceInformation buildForInSet(Node node) => null;
+
+ /// Generate [SourceInformation] for the operator `[]` access in [node].
+ SourceInformation buildIndex(Node node) => null;
+
+ /// Generate [SourceInformation] for the operator `[]=` assignment in [node].
+ SourceInformation buildIndexSet(Node node) => null;
+
+ /// Generate [SourceInformation] for the binary operation in [node].
+ SourceInformation buildBinary(Node node) => null;
+
+ /// Generate [SourceInformation] for the unary operator in [node].
+ SourceInformation buildCatch(Node node) => null;
+
+ /// Generate [SourceInformation] for the is-test in [node].
+ SourceInformation buildIs(Node node) => null;
+
+ /// Generate [SourceInformation] for the as-cast in [node].
+ SourceInformation buildAs(Node node) => null;
+
+ /// Generate [SourceInformation] for the switch statement [node].
+ SourceInformation buildSwitch(Node node) => null;
+
+ /// Generate [SourceInformation] for the switch case in [node].
+ SourceInformation buildSwitchCase(Node node) => null;
}
/// A location in a source file.
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 29e6743..aae737b 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -4,8 +4,6 @@
library dart2js.js_helpers.impact;
-import '../common/names.dart' show
- Identifiers;
import '../compiler.dart' show
Compiler;
import '../core_types.dart' show
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index 9f1947f..4040656 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -8,7 +8,6 @@
import '../../closure.dart' show
ClosureClassElement;
-import '../../common.dart';
import '../../common/codegen.dart' show
CodegenRegistry;
import '../../constants/values.dart';
@@ -497,7 +496,8 @@
@override
js.Expression visitVariableUse(tree_ir.VariableUse node) {
- return buildVariableAccess(node.variable);
+ return buildVariableAccess(node.variable)
+ .withSourceInformation(node.sourceInformation);
}
js.Expression buildVariableAccess(tree_ir.Variable variable) {
@@ -537,20 +537,25 @@
js.Expression makeAssignment(
js.Expression leftHand,
tree_ir.Expression value,
- {BuiltinOperator compound}) {
+ {SourceInformation sourceInformation,
+ BuiltinOperator compound}) {
if (isOneConstant(value)) {
if (compound == BuiltinOperator.NumAdd) {
- return new js.Prefix('++', leftHand);
+ return new js.Prefix('++', leftHand)
+ .withSourceInformation(sourceInformation);
}
if (compound == BuiltinOperator.NumSubtract) {
- return new js.Prefix('--', leftHand);
+ return new js.Prefix('--', leftHand)
+ .withSourceInformation(sourceInformation);
}
}
if (compound != null) {
return new js.Assignment.compound(leftHand,
- getAsCompoundOperator(compound), visitExpression(value));
+ getAsCompoundOperator(compound), visitExpression(value))
+ .withSourceInformation(sourceInformation);
}
- return new js.Assignment(leftHand, visitExpression(value));
+ return new js.Assignment(leftHand, visitExpression(value))
+ .withSourceInformation(sourceInformation);
}
@override
@@ -561,10 +566,12 @@
tree_ir.Expression left = rhs.arguments[0];
tree_ir.Expression right = rhs.arguments[1];
if (left is tree_ir.VariableUse && left.variable == node.variable) {
- return makeAssignment(variable, right, compound: rhs.operator);
+ return makeAssignment(variable, right, compound: rhs.operator,
+ sourceInformation: node.sourceInformation);
}
}
- return makeAssignment(variable, node.value);
+ return makeAssignment(
+ variable, node.value, sourceInformation: node.sourceInformation);
}
@override
@@ -620,7 +627,9 @@
js.Expression exp = visitExpression(node.expression);
if (node.next is tree_ir.Unreachable && emitUnreachableAsReturn.last) {
// Emit as 'return exp' to assist local analysis in the VM.
- accumulator.add(new js.Return(exp));
+ SourceInformation sourceInformation = node.expression.sourceInformation;
+ accumulator.add(
+ new js.Return(exp).withSourceInformation(sourceInformation));
return null;
} else {
accumulator.add(new js.ExpressionStatement(exp));
@@ -649,12 +658,14 @@
bool thenHasFallthrough = (fallthrough.useCount > usesBefore);
if (thenHasFallthrough) {
js.Statement elseBody = buildBodyStatement(node.elseStatement);
- accumulator.add(new js.If(condition, thenBody, elseBody));
+ accumulator.add(new js.If(condition, thenBody, elseBody)
+ .withSourceInformation(node.sourceInformation));
return null;
} else {
// The 'then' body cannot complete normally, so emit a short 'if'
// and put the 'else' body after it.
- accumulator.add(new js.If.noElse(condition, thenBody));
+ accumulator.add(new js.If.noElse(condition, thenBody)
+ .withSourceInformation(node.sourceInformation));
return node.elseStatement;
}
}
@@ -880,7 +891,8 @@
registry.registerStaticUse(new StaticUse.fieldGet(node.field));
return new js.PropertyAccess(
visitExpression(node.object),
- glue.instanceFieldPropertyName(node.field));
+ glue.instanceFieldPropertyName(node.field))
+ .withSourceInformation(node.sourceInformation);
}
@override
@@ -890,7 +902,8 @@
new js.PropertyAccess(
visitExpression(node.object),
glue.instanceFieldPropertyName(node.field));
- return makeAssignment(field, node.value, compound: node.compound);
+ return makeAssignment(field, node.value, compound: node.compound,
+ sourceInformation: node.sourceInformation);
}
@override
@@ -900,7 +913,8 @@
// Tear off a method.
registry.registerStaticUse(
new StaticUse.staticTearOff(node.element.declaration));
- return glue.isolateStaticClosureAccess(node.element);
+ return glue.isolateStaticClosureAccess(node.element)
+ .withSourceInformation(node.sourceInformation);
}
if (node.useLazyGetter) {
// Read a lazily initialized field.
@@ -913,7 +927,8 @@
// Read an eagerly initialized field.
registry.registerStaticUse(
new StaticUse.staticGet(node.element.declaration));
- return glue.staticFieldAccess(node.element);
+ return glue.staticFieldAccess(node.element)
+ .withSourceInformation(node.sourceInformation);
}
@override
@@ -922,7 +937,8 @@
registry.registerStaticUse(
new StaticUse.staticSet(node.element.declaration));
js.Expression field = glue.staticFieldAccess(node.element);
- return makeAssignment(field, node.value, compound: node.compound);
+ return makeAssignment(field, node.value, compound: node.compound,
+ sourceInformation: node.sourceInformation);
}
@override
@@ -1011,7 +1027,8 @@
}
// TODO(sra,johnniwinther): Should this be in CodegenRegistry?
glue.registerNativeBehavior(node.nativeBehavior, node);
- return node.codeTemplate.instantiate(visitExpressionList(node.arguments));
+ return node.codeTemplate.instantiate(visitExpressionList(node.arguments))
+ .withSourceInformation(node.sourceInformation);
}
@override
@@ -1063,86 +1080,91 @@
@override
js.Expression visitApplyBuiltinOperator(tree_ir.ApplyBuiltinOperator node) {
List<js.Expression> args = visitExpressionList(node.arguments);
- switch (node.operator) {
- case BuiltinOperator.NumAdd:
- return new js.Binary('+', args[0], args[1]);
- case BuiltinOperator.NumSubtract:
- return new js.Binary('-', args[0], args[1]);
- case BuiltinOperator.NumMultiply:
- return new js.Binary('*', args[0], args[1]);
- case BuiltinOperator.NumDivide:
- return new js.Binary('/', args[0], args[1]);
- case BuiltinOperator.NumRemainder:
- return new js.Binary('%', args[0], args[1]);
- case BuiltinOperator.NumTruncatingDivideToSigned32:
- return js.js('(# / #) | 0', args);
- case BuiltinOperator.NumAnd:
- return normalizeBitOp(js.js('# & #', args), node);
- case BuiltinOperator.NumOr:
- return normalizeBitOp(js.js('# | #', args), node);
- case BuiltinOperator.NumXor:
- return normalizeBitOp(js.js('# ^ #', args), node);
- case BuiltinOperator.NumLt:
- return new js.Binary('<', args[0], args[1]);
- case BuiltinOperator.NumLe:
- return new js.Binary('<=', args[0], args[1]);
- case BuiltinOperator.NumGt:
- return new js.Binary('>', args[0], args[1]);
- case BuiltinOperator.NumGe:
- return new js.Binary('>=', args[0], args[1]);
- case BuiltinOperator.NumShl:
- return normalizeBitOp(js.js('# << #', args), node);
- case BuiltinOperator.NumShr:
- // No normalization required since output is always uint32.
- return js.js('# >>> #', args);
- case BuiltinOperator.NumBitNot:
- return js.js('(~#) >>> 0', args);
- case BuiltinOperator.NumNegate:
- return js.js('-#', args);
- case BuiltinOperator.StringConcatenate:
- if (args.isEmpty) return js.string('');
- return args.reduce((e1,e2) => new js.Binary('+', e1, e2));
- case BuiltinOperator.CharCodeAt:
- return js.js('#.charCodeAt(#)', args);
- case BuiltinOperator.Identical:
- registry.registerStaticUse(new StaticUse.staticInvoke(
- glue.identicalFunction, new CallStructure.unnamed(args.length)));
- return buildStaticHelperInvocation(glue.identicalFunction, args);
- case BuiltinOperator.StrictEq:
- return new js.Binary('===', args[0], args[1]);
- case BuiltinOperator.StrictNeq:
- return new js.Binary('!==', args[0], args[1]);
- case BuiltinOperator.LooseEq:
- return new js.Binary('==', args[0], args[1]);
- case BuiltinOperator.LooseNeq:
- return new js.Binary('!=', args[0], args[1]);
- case BuiltinOperator.IsFalsy:
- return new js.Prefix('!', args[0]);
- case BuiltinOperator.IsNumber:
- return js.js('typeof # === "number"', args);
- case BuiltinOperator.IsNotNumber:
- return js.js('typeof # !== "number"', args);
- case BuiltinOperator.IsFloor:
- return js.js('Math.floor(#) === #', args);
- case BuiltinOperator.IsInteger:
- return js.js('typeof # === "number" && Math.floor(#) === #', args);
- case BuiltinOperator.IsNotInteger:
- return js.js('typeof # !== "number" || Math.floor(#) !== #', args);
- case BuiltinOperator.IsUnsigned32BitInteger:
- return js.js('# >>> 0 === #', args);
- case BuiltinOperator.IsNotUnsigned32BitInteger:
- return js.js('# >>> 0 !== #', args);
- case BuiltinOperator.IsFixedLengthJSArray:
- // TODO(sra): Remove boolify (i.e. !!).
- return js.js(r'!!#.fixed$length', args);
- case BuiltinOperator.IsExtendableJSArray:
- return js.js(r'!#.fixed$length', args);
- case BuiltinOperator.IsModifiableJSArray:
- return js.js(r'!#.immutable$list', args);
- case BuiltinOperator.IsUnmodifiableJSArray:
- // TODO(sra): Remove boolify (i.e. !!).
- return js.js(r'!!#.immutable$list', args);
+
+ js.Expression createExpression() {
+ switch (node.operator) {
+ case BuiltinOperator.NumAdd:
+ return new js.Binary('+', args[0], args[1]);
+ case BuiltinOperator.NumSubtract:
+ return new js.Binary('-', args[0], args[1]);
+ case BuiltinOperator.NumMultiply:
+ return new js.Binary('*', args[0], args[1]);
+ case BuiltinOperator.NumDivide:
+ return new js.Binary('/', args[0], args[1]);
+ case BuiltinOperator.NumRemainder:
+ return new js.Binary('%', args[0], args[1]);
+ case BuiltinOperator.NumTruncatingDivideToSigned32:
+ return js.js('(# / #) | 0', args);
+ case BuiltinOperator.NumAnd:
+ return normalizeBitOp(js.js('# & #', args), node);
+ case BuiltinOperator.NumOr:
+ return normalizeBitOp(js.js('# | #', args), node);
+ case BuiltinOperator.NumXor:
+ return normalizeBitOp(js.js('# ^ #', args), node);
+ case BuiltinOperator.NumLt:
+ return new js.Binary('<', args[0], args[1]);
+ case BuiltinOperator.NumLe:
+ return new js.Binary('<=', args[0], args[1]);
+ case BuiltinOperator.NumGt:
+ return new js.Binary('>', args[0], args[1]);
+ case BuiltinOperator.NumGe:
+ return new js.Binary('>=', args[0], args[1]);
+ case BuiltinOperator.NumShl:
+ return normalizeBitOp(js.js('# << #', args), node);
+ case BuiltinOperator.NumShr:
+ // No normalization required since output is always uint32.
+ return js.js('# >>> #', args);
+ case BuiltinOperator.NumBitNot:
+ return js.js('(~#) >>> 0', args);
+ case BuiltinOperator.NumNegate:
+ return js.js('-#', args);
+ case BuiltinOperator.StringConcatenate:
+ if (args.isEmpty) return js.string('');
+ return args.reduce((e1,e2) => new js.Binary('+', e1, e2));
+ case BuiltinOperator.CharCodeAt:
+ return js.js('#.charCodeAt(#)', args);
+ case BuiltinOperator.Identical:
+ registry.registerStaticUse(new StaticUse.staticInvoke(
+ glue.identicalFunction, new CallStructure.unnamed(args.length)));
+ return buildStaticHelperInvocation(glue.identicalFunction, args);
+ case BuiltinOperator.StrictEq:
+ return new js.Binary('===', args[0], args[1]);
+ case BuiltinOperator.StrictNeq:
+ return new js.Binary('!==', args[0], args[1]);
+ case BuiltinOperator.LooseEq:
+ return new js.Binary('==', args[0], args[1]);
+ case BuiltinOperator.LooseNeq:
+ return new js.Binary('!=', args[0], args[1]);
+ case BuiltinOperator.IsFalsy:
+ return new js.Prefix('!', args[0]);
+ case BuiltinOperator.IsNumber:
+ return js.js('typeof # === "number"', args);
+ case BuiltinOperator.IsNotNumber:
+ return js.js('typeof # !== "number"', args);
+ case BuiltinOperator.IsFloor:
+ return js.js('Math.floor(#) === #', args);
+ case BuiltinOperator.IsInteger:
+ return js.js('typeof # === "number" && Math.floor(#) === #', args);
+ case BuiltinOperator.IsNotInteger:
+ return js.js('typeof # !== "number" || Math.floor(#) !== #', args);
+ case BuiltinOperator.IsUnsigned32BitInteger:
+ return js.js('# >>> 0 === #', args);
+ case BuiltinOperator.IsNotUnsigned32BitInteger:
+ return js.js('# >>> 0 !== #', args);
+ case BuiltinOperator.IsFixedLengthJSArray:
+ // TODO(sra): Remove boolify (i.e. !!).
+ return js.js(r'!!#.fixed$length', args);
+ case BuiltinOperator.IsExtendableJSArray:
+ return js.js(r'!#.fixed$length', args);
+ case BuiltinOperator.IsModifiableJSArray:
+ return js.js(r'!#.immutable$list', args);
+ case BuiltinOperator.IsUnmodifiableJSArray:
+ // TODO(sra): Remove boolify (i.e. !!).
+ return js.js(r'!!#.immutable$list', args);
+ }
}
+
+ return createExpression().withSourceInformation(node.sourceInformation);
}
/// Add a uint32 normalization `op >>> 0` to [op] if it is not in 31-bit
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index abbb894..5b3f572 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -9,8 +9,6 @@
import '../js_backend.dart';
import '../../common.dart';
-import '../../common/registry.dart' show
- Registry;
import '../../common/codegen.dart' show
CodegenRegistry;
import '../../compiler.dart' show
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index 297f79f..9a482f0 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -82,7 +82,13 @@
import '../native/native.dart' as native;
import '../resolution/tree_elements.dart' show
TreeElements;
-import '../ssa/ssa.dart';
+import '../ssa/builder.dart' show
+ SsaFunctionCompiler;
+import '../ssa/nodes.dart' show
+ HTypeConversion,
+ HInstruction;
+import '../ssa/codegen.dart' show
+ SsaCodeGenerator;
import '../tree/tree.dart';
import '../types/types.dart';
import '../universe/call_structure.dart' show
diff --git a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
index ad5c04c..fc96572 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -5,8 +5,6 @@
/// Analysis to determine how to generate code for typed JavaScript interop.
library compiler.src.js_backend.js_interop_analysis;
-import '../common/names.dart' show Identifiers;
-import '../compiler.dart' show Compiler;
import '../diagnostics/messages.dart' show MessageKind;
import '../constants/values.dart'
show
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 1501a93..bcede45 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -8,8 +8,8 @@
abstract class TypeChecks {
/// Get the set of checks required for class [element].
Iterable<TypeCheck> operator[](ClassElement element);
- /// Get the iterator for all classes that need type checks.
- Iterator<ClassElement> get iterator;
+ /// Get the iterable for all classes that need type checks.
+ Iterable<ClassElement> get classes;
}
typedef jsAst.Expression OnVariableCallback(TypeVariableType variable);
@@ -478,7 +478,7 @@
TypeChecks checks) {
Set<ClassElement> instantiated = new Set<ClassElement>();
ArgumentCollector collector = new ArgumentCollector(backend);
- for (ClassElement target in checks) {
+ for (ClassElement target in checks.classes) {
instantiated.add(target);
for (TypeCheck check in checks[target]) {
Substitution substitution = check.substitution;
@@ -937,11 +937,11 @@
map[cls].add(new TypeCheck(check, substitution));
}
- Iterator<ClassElement> get iterator => map.keys.iterator;
+ Iterable<ClassElement> get classes => map.keys;
String toString() {
StringBuffer sb = new StringBuffer();
- for (ClassElement holder in this) {
+ for (ClassElement holder in classes) {
for (ClassElement check in [holder]) {
sb.write('${holder.name}.' '${check.name}, ');
}
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
index 8e574c8..462d0e4 100644
--- a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -6,8 +6,6 @@
import '../constants/values.dart';
-import '../common.dart';
-//import '../core_types.dart';
import '../dart_types.dart';
import '../elements/elements.dart'
show Element,
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index f2c1ded..30114a7 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -74,7 +74,6 @@
TypeCheck,
TypeChecks,
TypeVariableHandler;
-import '../../js/js_debug.dart';
import '../../universe/call_structure.dart' show
CallStructure;
import '../../universe/selector.dart' show
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index eb66c1a..be7be0c 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -69,7 +69,6 @@
TypeCheck,
TypeChecks,
TypeVariableHandler;
-import '../native/native.dart' as native;
import '../universe/call_structure.dart' show
CallStructure;
import '../universe/selector.dart' show
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index 29ad8ae..7141627 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -4,7 +4,6 @@
library dart2js.new_js_emitter.model;
-import '../common.dart';
import '../constants/values.dart' show
ConstantValue;
import '../deferred_load.dart' show
diff --git a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
index f329cbf..6f64a81 100644
--- a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
+++ b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
@@ -52,7 +52,7 @@
Set<ClassElement> computeClassesModifiedByEmitRuntimeTypeSupport() {
TypeChecks typeChecks = backend.rti.requiredChecks;
Set<ClassElement> result = new Set<ClassElement>();
- for (ClassElement cls in typeChecks) {
+ for (ClassElement cls in typeChecks.classes) {
if (typeChecks[cls].isNotEmpty) result.add(cls);
}
return result;
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index cd61a71..3921b8e 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -2,7 +2,28 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of native;
+import '../common.dart';
+import '../common/backend_api.dart' show
+ ForeignResolver;
+import '../common/resolution.dart' show
+ Parsing,
+ Resolution;
+import '../compiler.dart' show
+ Compiler;
+import '../constants/values.dart';
+import '../core_types.dart' show
+ CoreTypes;
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../js/js.dart' as js;
+import '../js_backend/js_backend.dart';
+import '../tree/tree.dart';
+import '../universe/side_effects.dart' show
+ SideEffects;
+import '../util/util.dart';
+
+import 'enqueue.dart';
+import 'js.dart';
/// This class is a temporary work-around until we get a more powerful DartType.
class SpecialType {
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index c96f7da..738a304 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -2,7 +2,46 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of native;
+import 'dart:collection' show Queue;
+
+import '../common.dart';
+import '../common/backend_api.dart' show
+ ForeignResolver;
+import '../common/registry.dart' show
+ Registry;
+import '../common/resolution.dart' show
+ Parsing,
+ Resolution;
+import '../compiler.dart' show
+ Compiler;
+import '../constants/values.dart';
+import '../core_types.dart' show
+ CoreTypes;
+import '../dart_types.dart';
+import '../enqueue.dart' show
+ Enqueuer,
+ ResolutionEnqueuer;
+import '../elements/elements.dart';
+import '../elements/modelx.dart' show
+ BaseClassElementX,
+ ElementX,
+ FunctionElementX,
+ LibraryElementX;
+import '../js_backend/backend_helpers.dart' show
+ BackendHelpers;
+import '../js_backend/js_backend.dart';
+import '../js_emitter/js_emitter.dart' show
+ CodeEmitterTask,
+ NativeEmitter;
+import '../tokens/token.dart' show
+ BeginGroupToken,
+ Token;
+import '../tokens/token_constants.dart' as Tokens show
+ EOF_TOKEN,
+ STRING_TOKEN;
+import '../tree/tree.dart';
+
+import 'behavior.dart';
/**
* This could be an abstract class but we use it as a stub for the dart_backend.
diff --git a/pkg/compiler/lib/src/native/js.dart b/pkg/compiler/lib/src/native/js.dart
index 5d1d37b..9108b90 100644
--- a/pkg/compiler/lib/src/native/js.dart
+++ b/pkg/compiler/lib/src/native/js.dart
@@ -2,8 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of native;
+import '../js/js.dart' as js;
+import '../universe/side_effects.dart' show SideEffects;
+import 'behavior.dart';
class HasCapturedPlaceholders extends js.BaseVisitor {
diff --git a/pkg/compiler/lib/src/native/native.dart b/pkg/compiler/lib/src/native/native.dart
index 487832b..4a1a641 100644
--- a/pkg/compiler/lib/src/native/native.dart
+++ b/pkg/compiler/lib/src/native/native.dart
@@ -4,59 +4,14 @@
library native;
-import 'dart:collection' show Queue;
-
-import '../common.dart';
-import '../common/backend_api.dart' show
- ForeignResolver;
-import '../common/registry.dart' show
- Registry;
-import '../common/resolution.dart' show
- Parsing,
- Resolution;
-import '../compiler.dart' show
- Compiler;
-import '../constants/values.dart';
-import '../core_types.dart' show
- CoreTypes;
-import '../dart_types.dart';
-import '../enqueue.dart' show
- Enqueuer,
- ResolutionEnqueuer;
+import '../compiler.dart' show Compiler;
import '../elements/elements.dart';
-import '../elements/modelx.dart' show
- BaseClassElementX,
- ElementX,
- FunctionElementX,
- LibraryElementX;
-import '../js/js.dart' as js;
-import '../js_backend/backend_helpers.dart' show
- BackendHelpers;
-import '../js_backend/js_backend.dart';
-import '../js_emitter/js_emitter.dart' show
- CodeEmitterTask,
- NativeEmitter;
-import '../parser/listener.dart' show
- Listener;
-import '../parser/element_listener.dart' show
- ElementListener;
-import '../ssa/ssa.dart';
-import '../tokens/token.dart' show
- BeginGroupToken,
- Token;
-import '../tokens/token_constants.dart' as Tokens show
- EOF_TOKEN,
- STRING_TOKEN;
-import '../tree/tree.dart';
-import '../universe/side_effects.dart' show
- SideEffects;
-import '../util/util.dart';
-part 'behavior.dart';
-part 'enqueue.dart';
-part 'js.dart';
-part 'scanner.dart';
-part 'ssa.dart';
+export 'behavior.dart';
+export 'enqueue.dart';
+export 'js.dart';
+export 'scanner.dart';
+export 'ssa.dart';
bool maybeEnableNative(Compiler compiler,
LibraryElement library) {
diff --git a/pkg/compiler/lib/src/native/scanner.dart b/pkg/compiler/lib/src/native/scanner.dart
index c18bfa8..c54b937 100644
--- a/pkg/compiler/lib/src/native/scanner.dart
+++ b/pkg/compiler/lib/src/native/scanner.dart
@@ -2,7 +2,17 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of native;
+import '../common.dart';
+import '../parser/listener.dart' show
+ Listener;
+import '../parser/element_listener.dart' show
+ ElementListener;
+import '../tokens/token.dart' show
+ BeginGroupToken,
+ Token;
+import '../tokens/token_constants.dart' as Tokens show
+ EOF_TOKEN,
+ STRING_TOKEN;
void checkAllowedLibrary(ElementListener listener, Token token) {
if (listener.scannerOptions.canUseNative) return;
diff --git a/pkg/compiler/lib/src/native/ssa.dart b/pkg/compiler/lib/src/native/ssa.dart
index b51c64d..7555590 100644
--- a/pkg/compiler/lib/src/native/ssa.dart
+++ b/pkg/compiler/lib/src/native/ssa.dart
@@ -2,7 +2,25 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of native;
+import '../common.dart';
+import '../compiler.dart' show
+ Compiler;
+import '../constants/values.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../js/js.dart' as js;
+import '../js_backend/js_backend.dart';
+import '../js_emitter/js_emitter.dart' show
+ CodeEmitterTask,
+ NativeEmitter;
+import '../ssa/builder.dart' show SsaBuilder;
+import '../ssa/nodes.dart' show
+ HInstruction,
+ HForeignCode,
+ HReturn;
+import '../tree/tree.dart';
+import '../universe/side_effects.dart' show
+ SideEffects;
final RegExp nativeRedirectionRegExp = new RegExp(r'^[a-zA-Z][a-zA-Z_$0-9]*$');
diff --git a/pkg/compiler/lib/src/parser/member_listener.dart b/pkg/compiler/lib/src/parser/member_listener.dart
index 0399d71..36ebc34 100644
--- a/pkg/compiler/lib/src/parser/member_listener.dart
+++ b/pkg/compiler/lib/src/parser/member_listener.dart
@@ -98,7 +98,7 @@
} else {
memberElement = new PartialFunctionElement(
name, beginToken, getOrSet, endToken,
- method.modifiers, enclosingClass, hasBody: method.hasBody());
+ method.modifiers, enclosingClass, hasBody: method.hasBody);
}
addMember(memberElement);
}
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index aa70072..664ac0d 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -406,7 +406,7 @@
// Check that there is no body (Language specification 7.5.1). If the
// constructor is also const, we already reported an error in
// [resolveMethodElement].
- if (functionNode.hasBody() && !constructor.isConst) {
+ if (functionNode.hasBody && !constructor.isConst) {
reporter.reportErrorMessage(
functionNode, MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY);
}
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index ca1d268..b0fc586 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -224,7 +224,7 @@
WorldImpact resolveMethodElementImplementation(
FunctionElement element, FunctionExpression tree) {
return reporter.withCurrentElement(element, () {
- if (element.isExternal && tree.hasBody()) {
+ if (element.isExternal && tree.hasBody) {
reporter.reportErrorMessage(
element,
MessageKind.EXTERNAL_WITH_BODY,
@@ -235,11 +235,14 @@
reporter.reportErrorMessage(
tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
}
- if (element.isConst &&
- tree.hasBody() &&
- !tree.isRedirectingFactory) {
- reporter.reportErrorMessage(
- tree, MessageKind.CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY);
+ if (tree.hasBody && element.isConst) {
+ if (element.isGenerativeConstructor) {
+ reporter.reportErrorMessage(
+ tree, MessageKind.CONST_CONSTRUCTOR_WITH_BODY);
+ } else if (!tree.isRedirectingFactory) {
+ reporter.reportErrorMessage(
+ tree, MessageKind.CONST_FACTORY);
+ }
}
}
diff --git a/pkg/compiler/lib/src/resolution/tree_elements.dart b/pkg/compiler/lib/src/resolution/tree_elements.dart
index a60bb79..1cd1849 100644
--- a/pkg/compiler/lib/src/resolution/tree_elements.dart
+++ b/pkg/compiler/lib/src/resolution/tree_elements.dart
@@ -111,7 +111,10 @@
Map<Spannable, Selector> _selectors;
Map<Spannable, TypeMask> _typeMasks;
Map<Node, DartType> _types;
- Map<Node, DartType> typesCache = <Node, DartType>{};
+
+ Map<Node, DartType> _typesCache;
+ Map<Node, DartType> get typesCache => _typesCache ??= <Node, DartType>{};
+
Setlet<SourceSpan> _superUses;
Map<Node, ConstantExpression> _constants;
Map<VariableElement, List<Node>> _potentiallyMutated;
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index fb979aa..8796e23 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -2,7 +2,71 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import 'dart:collection';
+
+import 'package:js_runtime/shared/embedded_names.dart';
+
+import '../closure.dart';
+import '../common.dart';
+import '../common/codegen.dart' show
+ CodegenRegistry,
+ CodegenWorkItem;
+import '../common/names.dart' show
+ Identifiers,
+ Selectors;
+import '../common/tasks.dart' show
+ CompilerTask;
+import '../compiler.dart' show
+ Compiler;
+import '../constants/constant_system.dart';
+import '../constants/expressions.dart';
+import '../constants/values.dart';
+import '../core_types.dart' show
+ CoreClasses;
+import '../dart_types.dart';
+import '../diagnostics/messages.dart' show
+ Message,
+ MessageTemplate;
+import '../elements/elements.dart';
+import '../elements/modelx.dart' show
+ ConstructorBodyElementX,
+ ElementX,
+ VariableElementX;
+import '../io/source_information.dart';
+import '../js/js.dart' as js;
+import '../js_backend/backend_helpers.dart' show
+ BackendHelpers;
+import '../js_backend/js_backend.dart';
+import '../js_emitter/js_emitter.dart' show
+ CodeEmitterTask,
+ NativeEmitter;
+import '../native/native.dart' as native;
+import '../resolution/operators.dart';
+import '../resolution/semantic_visitor.dart';
+import '../resolution/tree_elements.dart' show
+ TreeElements;
+import '../tree/tree.dart' as ast;
+import '../types/types.dart';
+import '../universe/call_structure.dart' show
+ CallStructure;
+import '../universe/selector.dart' show
+ Selector;
+import '../universe/side_effects.dart' show
+ SideEffects;
+import '../universe/use.dart' show
+ DynamicUse,
+ StaticUse,
+ TypeUse;
+import '../util/util.dart';
+import '../world.dart' show
+ ClassWorld,
+ World;
+import '../dump_info.dart' show InfoReporter;
+
+import 'nodes.dart';
+import 'codegen.dart';
+import 'optimize.dart';
+import 'types.dart';
class SsaFunctionCompiler implements FunctionCompiler {
final SsaCodeGeneratorTask generator;
@@ -1533,12 +1597,19 @@
return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce;
}
- bool isCalledOnce(Element element) {
- if (!allInlinedFunctionsCalledOnce) return false;
+ bool isFunctionCalledOnce(Element element) {
+ if (element is ConstructorBodyElement) {
+ // ConstructorBodyElements are not in the type inference graph.
+ return false;
+ }
TypesInferrer inferrer = compiler.typesTask.typesInferrer;
return inferrer.isCalledOnce(element);
}
+ bool isCalledOnce(Element element) {
+ return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element);
+ }
+
inlinedFrom(Element element, f()) {
assert(element is FunctionElement || element is VariableElement);
return reporter.withCurrentElement(element, () {
@@ -1754,8 +1825,8 @@
if (constructor.isSynthesized) return null;
ast.FunctionExpression node = constructor.node;
// If we know the body doesn't have any code, we don't generate it.
- if (!node.hasBody()) return null;
- if (node.hasEmptyBody()) return null;
+ if (!node.hasBody) return null;
+ if (node.hasEmptyBody) return null;
ClassElement classElement = constructor.enclosingClass;
ConstructorBodyElement bodyElement;
classElement.forEachBackendMember((Element backendMember) {
@@ -2967,7 +3038,7 @@
conditionBlock.postProcessLoopHeader();
HLoopBlockInformation info =
new HLoopBlockInformation(
- HLoopBlockInformation.loopType(loop),
+ _loopKind(loop),
wrapExpressionGraph(initializerGraph),
wrapExpressionGraph(conditionExpression),
wrapStatementGraph(bodyGraph),
@@ -4185,7 +4256,7 @@
if (inputs.length != 2) {
reporter.internalError(node.argumentsNode, 'Two arguments expected.');
}
- push(new HStringConcat(inputs[0], inputs[1], node, backend.stringType));
+ push(new HStringConcat(inputs[0], inputs[1], backend.stringType));
}
void handleForeignJsCurrentIsolateContext(ast.Send node) {
@@ -8526,11 +8597,10 @@
ast.Node _,
List<HInstruction> compiledArguments,
{InterfaceType instanceType}) {
- TypesInferrer inferrer = compiler.typesTask.typesInferrer;
AstInliningState state = new AstInliningState(
function, returnLocal, returnType, elements, stack, localsHandler,
inTryStatement,
- allInlinedFunctionsCalledOnce && inferrer.isCalledOnce(function));
+ allInlinedFunctionsCalledOnce && isFunctionCalledOnce(function));
inliningStack.add(state);
// Setting up the state of the (AST) builder is performed even when the
@@ -8709,14 +8779,14 @@
HInstruction concat(HInstruction left, HInstruction right) {
HInstruction instruction = new HStringConcat(
- left, right, diagnosticNode, builder.backend.stringType);
+ left, right, builder.backend.stringType);
builder.add(instruction);
return instruction;
}
HInstruction stringify(ast.Node node, HInstruction expression) {
HInstruction instruction =
- new HStringify(expression, node, builder.backend.stringType);
+ new HStringify(expression, builder.backend.stringType);
builder.add(instruction);
return instruction;
}
@@ -9244,3 +9314,19 @@
builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
}
}
+
+/// Determine what kind of loop [node] represents. The result is one of the
+/// kinds defined in [HLoopBlockInformation].
+int _loopKind(ast.Node node) => node.accept(const _LoopTypeVisitor());
+
+class _LoopTypeVisitor extends ast.Visitor {
+ const _LoopTypeVisitor();
+ int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
+ int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
+ int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
+ int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
+ int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
+ int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
+ int visitSwitchStatement(ast.SwitchStatement node) =>
+ HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
+}
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index fd2050c..4032c0a 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -2,7 +2,46 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import '../common.dart';
+import '../common/codegen.dart' show
+ CodegenRegistry,
+ CodegenWorkItem;
+import '../common/tasks.dart' show
+ CompilerTask;
+import '../compiler.dart' show
+ Compiler;
+import '../constants/constant_system.dart';
+import '../constants/values.dart';
+import '../core_types.dart' show
+ CoreClasses;
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../io/source_information.dart';
+import '../js/js.dart' as js;
+import '../js_backend/backend_helpers.dart' show
+ BackendHelpers;
+import '../js_backend/js_backend.dart';
+import '../js_emitter/js_emitter.dart' show
+ CodeEmitterTask,
+ NativeEmitter;
+import '../native/native.dart' as native;
+import '../types/types.dart';
+import '../universe/call_structure.dart' show
+ CallStructure;
+import '../universe/selector.dart' show
+ Selector;
+import '../universe/use.dart' show
+ DynamicUse,
+ StaticUse,
+ TypeUse;
+import '../util/util.dart';
+import '../world.dart' show
+ ClassWorld,
+ World;
+
+import 'nodes.dart';
+import 'codegen_helpers.dart';
+import 'variable_allocator.dart';
class SsaCodeGeneratorTask extends CompilerTask {
@@ -413,7 +452,7 @@
if (len == 0) return new js.EmptyStatement();
if (len == 1) {
js.Statement result = block.statements[0];
- if (result is ast.Block) return unwrapStatement(result);
+ if (result is js.Block) return unwrapStatement(result);
return result;
}
return block;
@@ -1417,7 +1456,7 @@
} else {
JumpTarget target = node.target;
if (!tryCallAction(continueAction, target)) {
- if (target.statement is ast.SwitchStatement) {
+ if (target.isSwitch) {
pushStatement(
new js.Continue(backend.namer.implicitContinueLabelName(target))
.withSourceInformation(node.sourceInformation));
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index bafa560..a68f70b 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -2,7 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import '../compiler.dart' show Compiler;
+import '../constants/values.dart';
+import '../elements/elements.dart';
+import '../js_backend/js_backend.dart';
+import '../types/types.dart';
+import '../universe/selector.dart' show Selector;
+
+import 'nodes.dart';
/**
* Replaces some instructions with specialized versions to make codegen easier.
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index b88fc41..c445190 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -2,7 +2,19 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../compiler.dart' show Compiler;
+import '../constants/constant_system.dart';
+import '../constants/values.dart';
+import '../elements/elements.dart';
+import '../js_backend/backend_helpers.dart' show BackendHelpers;
+import '../js_backend/js_backend.dart';
+import '../types/types.dart';
+import '../universe/selector.dart' show Selector;
+import '../world.dart' show ClassWorld, World;
+
+import 'nodes.dart';
+import 'optimize.dart';
/**
* This phase simplifies interceptors in multiple ways:
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index 754ed27..8852d1f 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -2,7 +2,18 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import '../compiler.dart' show Compiler;
+import '../constants/constant_system.dart';
+import '../constants/values.dart';
+import '../elements/elements.dart';
+import '../js_backend/js_backend.dart';
+import '../types/types.dart';
+import '../universe/selector.dart';
+import '../universe/call_structure.dart';
+import '../world.dart' show ClassWorld, World;
+
+import 'nodes.dart';
+import 'types.dart';
/**
* [InvokeDynamicSpecializer] and its subclasses are helpers to
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 28647bd..76a9644 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -2,7 +2,29 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+
+import '../closure.dart';
+import '../common.dart';
+import '../compiler.dart' show Compiler;
+import '../constants/constant_system.dart';
+import '../constants/values.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../io/source_information.dart';
+import '../js/js.dart' as js;
+import '../js_backend/backend_helpers.dart' show BackendHelpers;
+import '../js_backend/js_backend.dart';
+import '../native/native.dart' as native;
+import '../tree/dartstring.dart' as ast;
+import '../types/constants.dart' show computeTypeMask;
+import '../types/types.dart';
+import '../universe/selector.dart' show Selector;
+import '../universe/side_effects.dart' show SideEffects;
+import '../util/util.dart';
+import '../world.dart' show ClassWorld, World;
+
+import 'validate.dart';
+import 'invoke_dynamic_specializers.dart';
abstract class HVisitor<R> {
R visitAdd(HAdd node);
@@ -2893,8 +2915,7 @@
}
class HStringConcat extends HInstruction {
- final ast.Node node;
- HStringConcat(HInstruction left, HInstruction right, this.node, TypeMask type)
+ HStringConcat(HInstruction left, HInstruction right, TypeMask type)
: super(<HInstruction>[left, right], type) {
// TODO(sra): Until Issue 9293 is fixed, this false dependency keeps the
// concats bunched with stringified inputs for much better looking code with
@@ -2914,8 +2935,7 @@
* into a String value.
*/
class HStringify extends HInstruction {
- final ast.Node node;
- HStringify(HInstruction input, this.node, TypeMask type)
+ HStringify(HInstruction input, TypeMask type)
: super(<HInstruction>[input], type) {
sideEffects.setAllSideEffects();
sideEffects.setDependsOnSomething();
@@ -3098,18 +3118,6 @@
visitor.visitLabeledBlockInfo(this);
}
-class LoopTypeVisitor extends ast.Visitor {
- const LoopTypeVisitor();
- int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
- int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
- int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
- int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
- int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
- int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
- int visitSwitchStatement(ast.SwitchStatement node) =>
- HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
-}
-
class HLoopBlockInformation implements HStatementInformation {
static const int WHILE_LOOP = 0;
static const int FOR_LOOP = 1;
@@ -3159,10 +3167,6 @@
return body.end;
}
- static int loopType(ast.Node node) {
- return node.accept(const LoopTypeVisitor());
- }
-
bool accept(HStatementInformationVisitor visitor) =>
visitor.visitLoopInfo(this);
}
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 8d274d7..484a784 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -2,7 +2,41 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import '../common/codegen.dart' show
+ CodegenRegistry,
+ CodegenWorkItem;
+import '../common/tasks.dart' show
+ CompilerTask;
+import '../compiler.dart' show
+ Compiler;
+import '../constants/constant_system.dart';
+import '../constants/values.dart';
+import '../core_types.dart' show
+ CoreClasses;
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../js/js.dart' as js;
+import '../js_backend/backend_helpers.dart' show
+ BackendHelpers;
+import '../js_backend/js_backend.dart';
+import '../native/native.dart' as native;
+import '../tree/tree.dart' as ast;
+import '../types/types.dart';
+import '../universe/selector.dart' show
+ Selector;
+import '../universe/side_effects.dart' show
+ SideEffects;
+import '../util/util.dart';
+import '../world.dart' show
+ ClassWorld,
+ World;
+
+import 'nodes.dart';
+import 'types_propagation.dart';
+import 'types.dart';
+import 'value_range_analyzer.dart';
+import 'value_set.dart';
+import 'interceptor_simplifier.dart';
abstract class OptimizationPhase {
String get name;
@@ -376,8 +410,7 @@
HInstruction argument = node.inputs[2];
if (argument.isString(compiler)
&& !input.canBeNull()) {
- return new HStringConcat(input, argument, null,
- node.instructionType);
+ return new HStringConcat(input, argument, node.instructionType);
}
} else if (applies(helpers.jsStringToString)
&& !input.canBeNull()) {
@@ -962,7 +995,7 @@
leftString.primitiveValue, rightString.primitiveValue)),
compiler);
if (prefix == null) return folded;
- return new HStringConcat(prefix, folded, node.node, backend.stringType);
+ return new HStringConcat(prefix, folded, backend.stringType);
}
HInstruction visitStringify(HStringify node) {
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index 5139e5e..555b82c 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -4,80 +4,4 @@
library ssa;
-import 'dart:collection';
-
-import 'package:js_runtime/shared/embedded_names.dart';
-
-import '../closure.dart';
-import '../common.dart';
-import '../common/codegen.dart' show
- CodegenRegistry,
- CodegenWorkItem;
-import '../common/names.dart' show
- Identifiers,
- Selectors;
-import '../common/tasks.dart' show
- CompilerTask;
-import '../compiler.dart' show
- Compiler;
-import '../constant_system_dart.dart';
-import '../constants/constant_system.dart';
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../core_types.dart' show
- CoreClasses;
-import '../dart_types.dart';
-import '../diagnostics/messages.dart' show
- Message,
- MessageTemplate;
-import '../elements/elements.dart';
-import '../elements/modelx.dart' show
- ConstructorBodyElementX,
- ElementX,
- VariableElementX;
-import '../io/source_information.dart';
-import '../js/js.dart' as js;
-import '../js_backend/backend_helpers.dart' show
- BackendHelpers;
-import '../js_backend/js_backend.dart';
-import '../js_emitter/js_emitter.dart' show
- CodeEmitterTask,
- NativeEmitter;
-import '../native/native.dart' as native;
-import '../resolution/operators.dart';
-import '../resolution/semantic_visitor.dart';
-import '../resolution/tree_elements.dart' show
- TreeElements;
-import '../tree/tree.dart' as ast;
-import '../types/types.dart';
-import '../types/constants.dart' show
- computeTypeMask;
-import '../universe/call_structure.dart' show
- CallStructure;
-import '../universe/selector.dart' show
- Selector;
-import '../universe/side_effects.dart' show
- SideEffects;
-import '../universe/use.dart' show
- DynamicUse,
- StaticUse,
- TypeUse;
-import '../util/util.dart';
-import '../world.dart' show
- ClassWorld,
- World;
-import '../dump_info.dart' show InfoReporter;
-
-part 'builder.dart';
-part 'codegen.dart';
-part 'codegen_helpers.dart';
-part 'interceptor_simplifier.dart';
-part 'invoke_dynamic_specializers.dart';
-part 'nodes.dart';
-part 'optimize.dart';
-part 'types.dart';
-part 'types_propagation.dart';
-part 'validate.dart';
-part 'variable_allocator.dart';
-part 'value_range_analyzer.dart';
-part 'value_set.dart';
+export 'builder.dart' show SsaFunctionCompiler;
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index 841b0a2..4758afd 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -4,18 +4,15 @@
library ssa.tracer;
-import 'dart:async' show
- EventSink;
+import 'dart:async' show EventSink;
-import 'ssa.dart';
-import '../common.dart';
-import '../compiler.dart' show
- Compiler;
-import '../diagnostics/invariant.dart' show
- DEBUG_MODE;
+import '../compiler.dart' show Compiler;
+import '../diagnostics/invariant.dart' show DEBUG_MODE;
import '../js_backend/js_backend.dart';
import '../tracer.dart';
+import 'nodes.dart';
+
/**
* Outputs SSA code in a format readable by Hydra IR.
* Tracing is disabled by default, see ../tracer.dart for how
diff --git a/pkg/compiler/lib/src/ssa/types.dart b/pkg/compiler/lib/src/ssa/types.dart
index 530a968..8119cf2 100644
--- a/pkg/compiler/lib/src/ssa/types.dart
+++ b/pkg/compiler/lib/src/ssa/types.dart
@@ -2,7 +2,15 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import '../compiler.dart' show Compiler;
+import '../core_types.dart' show CoreClasses;
+import '../elements/elements.dart';
+import '../js_backend/js_backend.dart';
+import '../native/native.dart' as native;
+import '../tree/tree.dart' as ast;
+import '../types/types.dart';
+import '../universe/selector.dart' show Selector;
+import '../world.dart' show ClassWorld, World;
class TypeMaskFactory {
static TypeMask fromInferredType(TypeMask mask, Compiler compiler) {
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 00032c6..6355c6a 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -2,7 +2,15 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import '../compiler.dart' show Compiler;
+import '../elements/elements.dart';
+import '../js_backend/js_backend.dart';
+import '../types/types.dart';
+import '../universe/selector.dart' show Selector;
+import '../world.dart' show ClassWorld, World;
+
+import 'nodes.dart';
+import 'optimize.dart';
class SsaTypePropagator extends HBaseVisitor implements OptimizationPhase {
final Map<int, HInstruction> workmap = new Map<int, HInstruction>();
diff --git a/pkg/compiler/lib/src/ssa/validate.dart b/pkg/compiler/lib/src/ssa/validate.dart
index 2858204..1c1e222 100644
--- a/pkg/compiler/lib/src/ssa/validate.dart
+++ b/pkg/compiler/lib/src/ssa/validate.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import 'nodes.dart';
class HValidator extends HInstructionVisitor {
bool isValid = true;
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index 7cd149e..22c127a 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -2,8 +2,15 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../compiler.dart' show Compiler;
+import '../constant_system_dart.dart';
+import '../constants/constant_system.dart';
+import '../constants/values.dart';
+import '../js_backend/js_backend.dart';
+import 'nodes.dart';
+import 'optimize.dart';
class ValueRangeInfo {
final ConstantSystem constantSystem;
diff --git a/pkg/compiler/lib/src/ssa/value_set.dart b/pkg/compiler/lib/src/ssa/value_set.dart
index 07681b6..6d7acc2 100644
--- a/pkg/compiler/lib/src/ssa/value_set.dart
+++ b/pkg/compiler/lib/src/ssa/value_set.dart
@@ -2,7 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import '../universe/side_effects.dart' show SideEffects;
+
+import 'nodes.dart';
+
class ValueSet {
int size = 0;
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index fb35705..280a047 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -2,7 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of ssa;
+import '../common.dart';
+import '../compiler.dart' show Compiler;
+import '../js_backend/js_backend.dart';
+
+import 'nodes.dart';
/**
* The [LiveRange] class covers a range where an instruction is live.
diff --git a/pkg/compiler/lib/src/tracer.dart b/pkg/compiler/lib/src/tracer.dart
index bc50222..723c7ed 100644
--- a/pkg/compiler/lib/src/tracer.dart
+++ b/pkg/compiler/lib/src/tracer.dart
@@ -10,7 +10,8 @@
ItemCompilationContext;
import 'compiler.dart' show
Compiler;
-import 'ssa/ssa.dart' as ssa;
+import 'ssa/nodes.dart' as ssa show
+ HGraph;
import 'ssa/ssa_tracer.dart' show
HTracer;
import 'cps_ir/cps_ir_nodes.dart' as cps_ir;
diff --git a/pkg/compiler/lib/src/tree/dartstring.dart b/pkg/compiler/lib/src/tree/dartstring.dart
index 72d0b0c..7ada1fa 100644
--- a/pkg/compiler/lib/src/tree/dartstring.dart
+++ b/pkg/compiler/lib/src/tree/dartstring.dart
@@ -2,7 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of tree;
+import 'dart:collection';
+import '../util/characters.dart';
/**
* The [DartString] type represents a Dart string value as a sequence of Unicode
@@ -248,4 +249,3 @@
return true;
}
}
-
diff --git a/pkg/compiler/lib/src/tree/nodes.dart b/pkg/compiler/lib/src/tree/nodes.dart
index e95497b..46c5424 100644
--- a/pkg/compiler/lib/src/tree/nodes.dart
+++ b/pkg/compiler/lib/src/tree/nodes.dart
@@ -2,7 +2,19 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of tree;
+import 'dart:collection' show IterableMixin;
+
+import '../common.dart';
+import '../tokens/precedence_constants.dart' as Precedence show FUNCTION_INFO;
+import '../tokens/token.dart' show BeginGroupToken, Token;
+import '../tokens/token_constants.dart' as Tokens show IDENTIFIER_TOKEN, KEYWORD_TOKEN, PLUS_TOKEN;
+import '../util/util.dart';
+import '../util/characters.dart';
+import '../resolution/secret_tree_element.dart' show NullTreeElementMixin, StoredTreeElementMixin;
+import '../elements/elements.dart' show MetadataAnnotation;
+import 'dartstring.dart';
+import 'prettyprint.dart';
+import 'unparser.dart';
abstract class Visitor<R> {
const Visitor();
@@ -572,7 +584,7 @@
Token getEndToken() => send.getEndToken();
}
-class NodeList extends Node {
+class NodeList extends Node with IterableMixin<Node> {
final Link<Node> nodes;
final Token beginToken;
final Token endToken;
@@ -588,6 +600,13 @@
NodeList asNodeList() => this;
+ // Override [IterableMixin.toString] with same code as [Node.toString].
+ toString() => unparse(this);
+
+ get length {
+ throw new UnsupportedError('use slowLength() instead of get:length');
+ }
+
int slowLength() {
int result = 0;
for (Link<Node> cursor = nodes; !cursor.isEmpty; cursor = cursor.tail) {
@@ -840,9 +859,9 @@
if (body != null) body.accept(visitor);
}
- bool hasBody() => body.asEmptyStatement() == null;
+ bool get hasBody => body.asEmptyStatement() == null;
- bool hasEmptyBody() {
+ bool get hasEmptyBody {
Block block = body.asBlock();
if (block == null) return false;
return block.statements.isEmpty;
@@ -2476,8 +2495,8 @@
get initializers => null;
get getOrSet => null;
get isRedirectingFactory => false;
- bool hasBody() => false;
- bool hasEmptyBody() => false;
+ bool get hasBody => false;
+ bool get hasEmptyBody => false;
// VariableDefinitions.
get metadata => null;
diff --git a/pkg/compiler/lib/src/tree/prettyprint.dart b/pkg/compiler/lib/src/tree/prettyprint.dart
index 552747e..1b17b7ab 100644
--- a/pkg/compiler/lib/src/tree/prettyprint.dart
+++ b/pkg/compiler/lib/src/tree/prettyprint.dart
@@ -2,7 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of tree;
+import '../tokens/token.dart' show BeginGroupToken, Token;
+import '../util/util.dart';
+import 'nodes.dart';
/**
* Pretty-prints Node tree in XML-like format.
diff --git a/pkg/compiler/lib/src/tree/tree.dart b/pkg/compiler/lib/src/tree/tree.dart
index 8c65fab..71e9b6d 100644
--- a/pkg/compiler/lib/src/tree/tree.dart
+++ b/pkg/compiler/lib/src/tree/tree.dart
@@ -4,29 +4,7 @@
library tree;
-import 'dart:collection';
-
-import '../common.dart';
-import '../tokens/precedence_constants.dart' as Precedence show
- FUNCTION_INFO;
-import '../tokens/token.dart' show
- BeginGroupToken,
- Token;
-import '../tokens/token_constants.dart' as Tokens show
- IDENTIFIER_TOKEN,
- KEYWORD_TOKEN,
- PLUS_TOKEN;
-import '../util/util.dart';
-import '../util/characters.dart';
-
-import '../resolution/secret_tree_element.dart' show
- NullTreeElementMixin,
- StoredTreeElementMixin;
-
-import '../elements/elements.dart' show
- MetadataAnnotation;
-
-part 'dartstring.dart';
-part 'nodes.dart';
-part 'prettyprint.dart';
-part 'unparser.dart';
+export 'dartstring.dart';
+export 'nodes.dart';
+export 'prettyprint.dart';
+export 'unparser.dart';
diff --git a/pkg/compiler/lib/src/tree/unparser.dart b/pkg/compiler/lib/src/tree/unparser.dart
index 807ea05..b9e6784 100644
--- a/pkg/compiler/lib/src/tree/unparser.dart
+++ b/pkg/compiler/lib/src/tree/unparser.dart
@@ -2,7 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-part of tree;
+import '../tokens/token.dart' show BeginGroupToken, Token;
+import '../tokens/token_constants.dart' as Tokens show IDENTIFIER_TOKEN, KEYWORD_TOKEN, PLUS_TOKEN;
+import '../util/util.dart';
+import 'nodes.dart';
String unparse(Node node, {minify: true}) {
Unparser unparser = new Unparser(minify: minify);
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index 3685137..7996101 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -758,7 +758,10 @@
assert(isCompoundableBuiltin(e));
if (e.arguments.length > 2) {
assert(e.operator == BuiltinOperator.StringConcatenate);
- return new ApplyBuiltinOperator(e.operator, e.arguments.skip(1).toList());
+ return new ApplyBuiltinOperator(
+ e.operator,
+ e.arguments.skip(1).toList(),
+ e.sourceInformation);
} else {
return e.arguments[1];
}
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
index b4ca9ab..99fb099 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -8,7 +8,7 @@
import '../constants/values.dart';
import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
import '../elements/elements.dart';
-import 'package:js_ast/js_ast.dart' as js;
+import '../io/source_information.dart';
import '../js_backend/codegen/glue.dart';
import 'tree_ir_nodes.dart';
@@ -85,9 +85,10 @@
}
VariableUse getMutableVariableUse(
- cps_ir.Reference<cps_ir.MutableVariable> reference) {
+ cps_ir.Reference<cps_ir.MutableVariable> reference,
+ SourceInformation sourceInformation) {
Variable variable = getMutableVariable(reference.definition);
- return new VariableUse(variable);
+ return new VariableUse(variable, sourceInformation: sourceInformation);
}
/// Obtains the variable representing the given primitive. Returns null for
@@ -102,7 +103,8 @@
/// referred to by [reference].
/// This increments the reference count for the given variable, so the
/// returned expression must be used in the tree.
- Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) {
+ Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference,
+ {SourceInformation sourceInformation}) {
cps_ir.Primitive prim = reference.definition.effectiveDefinition;
if (prim is cps_ir.Constant && inlinedConstants.contains(prim)) {
return new Constant(prim.value);
@@ -110,7 +112,8 @@
if (thisParameter != null && prim == thisParameter) {
return new This();
}
- return new VariableUse(getVariable(prim));
+ return new VariableUse(
+ getVariable(prim), sourceInformation: sourceInformation);
}
Expression getVariableUseOrNull(
@@ -448,11 +451,13 @@
/// Translates a branch condition to a tree expression.
Expression translateCondition(cps_ir.Branch branch) {
- Expression value = getVariableUse(branch.conditionRef);
+ Expression value = getVariableUse(
+ branch.conditionRef, sourceInformation: branch.sourceInformation);
if (branch.isStrictCheck) {
return new ApplyBuiltinOperator(
BuiltinOperator.StrictEq,
- <Expression>[value, new Constant(new TrueConstantValue())]);
+ <Expression>[value, new Constant(new TrueConstantValue())],
+ branch.sourceInformation);
} else {
return value;
}
@@ -471,7 +476,8 @@
elseStatement = cont.hasExactlyOneUse
? translateExpression(cont.body)
: new Break(labels[cont]);
- return new If(condition, thenStatement, elseStatement);
+ return new If(
+ condition, thenStatement, elseStatement, node.sourceInformation);
}
@@ -483,7 +489,8 @@
Expression visitSetField(cps_ir.SetField node) {
return new SetField(getVariableUse(node.objectRef),
node.field,
- getVariableUse(node.valueRef));
+ getVariableUse(node.valueRef),
+ node.sourceInformation);
}
Expression visitInterceptor(cps_ir.Interceptor node) {
@@ -502,7 +509,7 @@
Expression visitGetField(cps_ir.GetField node) {
return new GetField(getVariableUse(node.objectRef), node.field,
- objectIsNotNull: !node.object.type.isNullable);
+ node.sourceInformation, objectIsNotNull: !node.object.type.isNullable);
}
Expression visitCreateBox(cps_ir.CreateBox node) {
@@ -516,13 +523,14 @@
}
Expression visitGetMutable(cps_ir.GetMutable node) {
- return getMutableVariableUse(node.variableRef);
+ return getMutableVariableUse(node.variableRef, node.sourceInformation);
}
Expression visitSetMutable(cps_ir.SetMutable node) {
Variable variable = getMutableVariable(node.variable);
Expression value = getVariableUse(node.valueRef);
- return new Assign(variable, value);
+ return new Assign(
+ variable, value, sourceInformation: node.sourceInformation);
}
Expression visitConstant(cps_ir.Constant node) {
@@ -581,8 +589,10 @@
if (node.operator == BuiltinOperator.IsFalsy) {
return new Not(getVariableUse(node.argumentRefs.single));
}
- return new ApplyBuiltinOperator(node.operator,
- translateArguments(node.argumentRefs));
+ return new ApplyBuiltinOperator(
+ node.operator,
+ translateArguments(node.argumentRefs),
+ node.sourceInformation);
}
Expression visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) {
@@ -724,7 +734,8 @@
arguments,
node.nativeBehavior,
nullableArguments,
- node.dependency);
+ node.dependency,
+ node.sourceInformation);
} else {
return (Statement next) {
assert(next is Unreachable); // We are not using the `next` statement.
@@ -734,7 +745,8 @@
arguments,
node.nativeBehavior,
nullableArguments,
- node.dependency);
+ node.dependency,
+ node.sourceInformation);
};
}
}
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
index 5e09254..adeed90 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -56,6 +56,8 @@
abstract class Expression extends Node {
accept(ExpressionVisitor v);
accept1(ExpressionVisitor1 v, arg);
+
+ SourceInformation get sourceInformation => null;
}
abstract class Statement extends Node {
@@ -123,9 +125,10 @@
/// Read the value of a variable.
class VariableUse extends Expression {
Variable variable;
+ SourceInformation sourceInformation;
/// Creates a use of [variable] and updates its `readCount`.
- VariableUse(this.variable) {
+ VariableUse(this.variable, {this.sourceInformation}) {
variable.readCount++;
}
@@ -138,8 +141,9 @@
class Assign extends Expression {
Variable variable;
Expression value;
+ SourceInformation sourceInformation;
- Assign(this.variable, this.value) {
+ Assign(this.variable, this.value, {this.sourceInformation}) {
variable.writeCount++;
}
@@ -345,8 +349,9 @@
class ApplyBuiltinOperator extends Expression {
BuiltinOperator operator;
List<Expression> arguments;
+ SourceInformation sourceInformation;
- ApplyBuiltinOperator(this.operator, this.arguments);
+ ApplyBuiltinOperator(this.operator, this.arguments, this.sourceInformation);
accept(ExpressionVisitor visitor) {
return visitor.visitApplyBuiltinOperator(this);
@@ -598,11 +603,15 @@
Expression condition;
Statement thenStatement;
Statement elseStatement;
+ SourceInformation sourceInformation;
Statement get next => null;
void set next(Statement s) => throw 'UNREACHABLE';
- If(this.condition, this.thenStatement, this.elseStatement);
+ If(this.condition,
+ this.thenStatement,
+ this.elseStatement,
+ this.sourceInformation);
accept(StatementVisitor visitor) => visitor.visitIf(this);
accept1(StatementVisitor1 visitor, arg) => visitor.visitIf(this, arg);
@@ -693,8 +702,13 @@
Expression object;
Element field;
bool objectIsNotNull;
+ SourceInformation sourceInformation;
- GetField(this.object, this.field, {this.objectIsNotNull: false});
+ GetField(
+ this.object,
+ this.field,
+ this.sourceInformation,
+ {this.objectIsNotNull: false});
accept(ExpressionVisitor visitor) => visitor.visitGetField(this);
accept1(ExpressionVisitor1 visitor, arg) => visitor.visitGetField(this, arg);
@@ -704,12 +718,18 @@
Expression object;
Element field;
Expression value;
+ SourceInformation sourceInformation;
/// If non-null, this is a compound assignment to the field, using the given
/// operator. The operator must be a compoundable operator.
BuiltinOperator compound;
- SetField(this.object, this.field, this.value, {this.compound});
+ SetField(
+ this.object,
+ this.field,
+ this.value,
+ this.sourceInformation,
+ {this.compound});
accept(ExpressionVisitor visitor) => visitor.visitSetField(this);
accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetField(this, arg);
@@ -857,9 +877,16 @@
final native.NativeBehavior nativeBehavior;
final List<bool> nullableArguments; // One 'bit' per argument.
final Element dependency;
+ final SourceInformation sourceInformation;
- ForeignCode(this.codeTemplate, this.type, this.arguments, this.nativeBehavior,
- this.nullableArguments, this.dependency) {
+ ForeignCode(
+ this.codeTemplate,
+ this.type,
+ this.arguments,
+ this.nativeBehavior,
+ this.nullableArguments,
+ this.dependency,
+ this.sourceInformation) {
assert(arguments.length == nullableArguments.length);
}
}
@@ -869,9 +896,10 @@
js.Template codeTemplate, types.TypeMask type,
List<Expression> arguments, native.NativeBehavior nativeBehavior,
List<bool> nullableArguments,
- Element dependency)
+ Element dependency,
+ SourceInformation sourceInformation)
: super(codeTemplate, type, arguments, nativeBehavior, nullableArguments,
- dependency);
+ dependency, sourceInformation);
accept(ExpressionVisitor visitor) {
return visitor.visitForeignExpression(this);
@@ -887,9 +915,10 @@
js.Template codeTemplate, types.TypeMask type,
List<Expression> arguments, native.NativeBehavior nativeBehavior,
List<bool> nullableArguments,
- Element dependency)
+ Element dependency,
+ SourceInformation sourceInformation)
: super(codeTemplate, type, arguments, nativeBehavior, nullableArguments,
- dependency);
+ dependency, sourceInformation);
accept(StatementVisitor visitor) {
return visitor.visitForeignStatement(this);
diff --git a/pkg/compiler/lib/src/types/abstract_value_domain.dart b/pkg/compiler/lib/src/types/abstract_value_domain.dart
index 73e8ae4..9adc868 100644
--- a/pkg/compiler/lib/src/types/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/types/abstract_value_domain.dart
@@ -7,12 +7,7 @@
import '../constants/values.dart';
import '../dart_types.dart';
import '../elements/elements.dart';
-import '../native/native.dart' show
- NativeBehavior;
-import '../universe/selector.dart' show
- Selector;
-import '../universe/universe.dart' show
- ReceiverConstraint;
+import '../universe/selector.dart' show Selector;
enum AbstractBool {
True, False, Maybe, Nothing
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index b9e5969..665d144 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -58,9 +58,6 @@
* The types task infers guaranteed types globally.
*/
class TypesTask extends CompilerTask {
- static final bool DUMP_BAD_CPA_RESULTS = false;
- static final bool DUMP_GOOD_CPA_RESULTS = false;
-
final String name = 'Type inference';
final ClassWorld classWorld;
TypesInferrer typesInferrer;
@@ -280,12 +277,6 @@
/** Computes the intersection of [type1] and [type2] */
TypeMask intersection(TypeMask type1, TypeMask type2, element) {
TypeMask result = _intersection(type1, type2);
- if (DUMP_BAD_CPA_RESULTS && better(type1, type2)) {
- print("CPA is worse for $element: $type1 /\\ $type2 = $result");
- }
- if (DUMP_GOOD_CPA_RESULTS && better(type2, type1)) {
- print("CPA is better for $element: $type1 /\\ $type2 = $result");
- }
return result;
}
@@ -307,35 +298,31 @@
void onResolutionComplete(Element mainElement) {
measure(() {
typesInferrer.analyzeMain(mainElement);
+ typesInferrer.clear();
});
- typesInferrer.clear();
}
/**
* Return the (inferred) guaranteed type of [element] or null.
*/
TypeMask getGuaranteedTypeOfElement(Element element) {
- return measure(() {
- // TODO(24489): trust some JsInterop types.
- if (compiler.backend.isJsInterop(element)) {
- return dynamicType;
- }
- TypeMask guaranteedType = typesInferrer.getTypeOfElement(element);
- return guaranteedType;
- });
+ // TODO(24489): trust some JsInterop types.
+ if (compiler.backend.isJsInterop(element)) {
+ return dynamicType;
+ }
+ TypeMask guaranteedType = typesInferrer.getTypeOfElement(element);
+ return guaranteedType;
}
TypeMask getGuaranteedReturnTypeOfElement(Element element) {
- return measure(() {
- // TODO(24489): trust some JsInterop types.
- if (compiler.backend.isJsInterop(element)) {
- return dynamicType;
- }
+ // TODO(24489): trust some JsInterop types.
+ if (compiler.backend.isJsInterop(element)) {
+ return dynamicType;
+ }
- TypeMask guaranteedType =
- typesInferrer.getReturnTypeOfElement(element);
- return guaranteedType;
- });
+ TypeMask guaranteedType =
+ typesInferrer.getReturnTypeOfElement(element);
+ return guaranteedType;
}
/**
@@ -343,20 +330,16 @@
* [node] must be an AST node of [owner].
*/
TypeMask getGuaranteedTypeOfNode(owner, node) {
- return measure(() {
- TypeMask guaranteedType = typesInferrer.getTypeOfNode(owner, node);
- return guaranteedType;
- });
+ TypeMask guaranteedType = typesInferrer.getTypeOfNode(owner, node);
+ return guaranteedType;
}
/**
* Return the (inferred) guaranteed type of [selector] or null.
*/
TypeMask getGuaranteedTypeOfSelector(Selector selector, TypeMask mask) {
- return measure(() {
- TypeMask guaranteedType =
- typesInferrer.getTypeOfSelector(selector, mask);
- return guaranteedType;
- });
+ TypeMask guaranteedType =
+ typesInferrer.getTypeOfSelector(selector, mask);
+ return guaranteedType;
}
}
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index bf2f31c..818a6d7 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -6,7 +6,6 @@
import 'dart:collection' show
IterableBase;
-import '../common.dart';
import '../elements/elements.dart' show
ClassElement;
import '../util/enumset.dart' show
diff --git a/pkg/compiler/lib/src/universe/side_effects.dart b/pkg/compiler/lib/src/universe/side_effects.dart
index f7625e4..a599e09 100644
--- a/pkg/compiler/lib/src/universe/side_effects.dart
+++ b/pkg/compiler/lib/src/universe/side_effects.dart
@@ -4,8 +4,6 @@
library universe.side_effects;
-import '../common.dart';
-
class SideEffects {
// Changes flags.
static const int FLAG_CHANGES_INDEX = 0;
diff --git a/pkg/compiler/lib/src/universe/world_impact.dart b/pkg/compiler/lib/src/universe/world_impact.dart
index 95980a0..f6bc666 100644
--- a/pkg/compiler/lib/src/universe/world_impact.dart
+++ b/pkg/compiler/lib/src/universe/world_impact.dart
@@ -4,9 +4,6 @@
library dart2js.universe.world_impact;
-import '../dart_types.dart' show
- DartType,
- InterfaceType;
import '../elements/elements.dart' show
Element,
LocalFunctionElement,
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart
index 772e231..ed69c6f 100644
--- a/pkg/compiler/lib/src/use_unused_api.dart
+++ b/pkg/compiler/lib/src/use_unused_api.dart
@@ -40,7 +40,7 @@
import 'resolution/operators.dart' as operators;
import 'script.dart';
import 'source_file_provider.dart' as source_file_provider;
-import 'ssa/ssa.dart' as ssa;
+import 'ssa/nodes.dart' as ssa;
import 'tree/tree.dart' as tree;
import 'util/util.dart' as util;
import 'world.dart';
@@ -343,4 +343,4 @@
useDeferred([deferred.DeferredLoadTask task]) {
task.dump();
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/util/link.dart b/pkg/compiler/lib/src/util/link.dart
index 3a9c133..f84c2c8 100644
--- a/pkg/compiler/lib/src/util/link.dart
+++ b/pkg/compiler/lib/src/util/link.dart
@@ -4,7 +4,7 @@
part of dart2js.util;
-class Link<T> {
+class Link<T> implements Iterable<T> {
T get head => throw new StateError("no elements");
Link<T> get tail => null;
@@ -120,6 +120,27 @@
}
Link copyWithout(e) => this;
+
+ //
+ // Unsupported Iterable<T> methods.
+ //
+ bool any(bool f(T e)) => _unsupported('any');
+ T elementAt(int i) => _unsupported('elementAt');
+ Iterable expand(Iterable f(T e)) => _unsupported('expand');
+ T firstWhere(bool f(T e), {T orElse()}) => _unsupported('firstWhere');
+ fold(initialValue, combine(value, T element)) => _unsupported('fold');
+ T get last => _unsupported('get:last');
+ T lastWhere(bool f(T e), {T orElse()}) => _unsupported('lastWhere');
+ String join([separator = '']) => _unsupported('join');
+ T reduce(T combine(T a, T b)) => _unsupported('reduce');
+ T singleWhere(bool f(T e)) => _unsupported('singleWhere');
+ Iterable<T> skipWhile(bool f(T e)) => _unsupported('skipWhile');
+ Iterable<T> take(int n) => _unsupported('take');
+ Iterable<T> takeWhile(bool f(T e)) => _unsupported('takeWhile');
+ Set<T> toSet() => _unsupported('toSet');
+ Iterable<T> where(bool f(T e)) => _unsupported('where');
+
+ _unsupported(String method) => throw new UnsupportedError(method);
}
/// Builder object for creating linked lists using [Link] or fixed-length [List]
diff --git a/pkg/dart_messages/lib/generated/shared_messages.json b/pkg/dart_messages/lib/generated/shared_messages.json
index 7693f4a..f5d61c0 100644
--- a/pkg/dart_messages/lib/generated/shared_messages.json
+++ b/pkg/dart_messages/lib/generated/shared_messages.json
@@ -22,27 +22,9 @@
}
]
},
- "CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY": {
- "id": "LGJGHW",
- "subId": 0,
- "categories": [
- "ParserError"
- ],
- "template": "Const constructor or factory can't have a body.",
- "templateHoleOrder": null,
- "howToFix": "Remove the 'const' keyword or the body.",
- "options": null,
- "usedBy": [
- "Platform.dart2js"
- ],
- "examples": [
- " class C {\n const C() {}\n }\n\n main() => new C();",
- " class C {\n const factory C() {}\n }\n\n main() => new C();"
- ]
- },
"CONST_CONSTRUCTOR_WITH_BODY": {
"id": "LGJGHW",
- "subId": 1,
+ "subId": 0,
"categories": [
"ParserError"
],
@@ -51,7 +33,8 @@
"howToFix": "Try removing the 'const' keyword or the body.",
"options": null,
"usedBy": [
- "Platform.analyzer"
+ "Platform.analyzer",
+ "Platform.dart2js"
],
"examples": [
" class C {\n const C() {}\n }\n\n main() => new C();"
@@ -59,7 +42,7 @@
},
"CONST_FACTORY": {
"id": "LGJGHW",
- "subId": 2,
+ "subId": 1,
"categories": [
"ParserError"
],
@@ -68,7 +51,8 @@
"howToFix": "Try removing the 'const' keyword or replacing the body with '=' followed by a valid target.",
"options": null,
"usedBy": [
- "Platform.analyzer"
+ "Platform.analyzer",
+ "Platform.dart2js"
],
"examples": [
" class C {\n const factory C() {}\n }\n\n main() => new C();"
diff --git a/pkg/dart_messages/lib/shared_messages.dart b/pkg/dart_messages/lib/shared_messages.dart
index 5aa2ced..c2e73c7 100644
--- a/pkg/dart_messages/lib/shared_messages.dart
+++ b/pkg/dart_messages/lib/shared_messages.dart
@@ -191,37 +191,14 @@
}
]),
- // Const constructors (factory or not) may not have a body.
- 'CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY': new Message(
- id: 'LGJGHW',
- subId: 0,
- categories: [Category.parserError],
- template: "Const constructor or factory can't have a body.",
- howToFix: "Remove the 'const' keyword or the body.",
- usedBy: [dart2js],
- examples: const [
- r"""
- class C {
- const C() {}
- }
-
- main() => new C();""",
- r"""
- class C {
- const factory C() {}
- }
-
- main() => new C();"""
- ]),
// Const constructors may not have a body.
'CONST_CONSTRUCTOR_WITH_BODY': new Message(
id: 'LGJGHW',
- subId: 1,
- specializationOf: "CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY",
+ subId: 0,
categories: [Category.parserError],
template: "Const constructor can't have a body.",
howToFix: "Try removing the 'const' keyword or the body.",
- usedBy: [analyzer],
+ usedBy: [analyzer, dart2js],
examples: const [
r"""
class C {
@@ -233,14 +210,13 @@
// Const constructor factories may only redirect (and must not have a body).
'CONST_FACTORY': new Message(
id: 'LGJGHW',
- subId: 2,
- specializationOf: "CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY",
+ subId: 1,
categories: [Category.parserError],
template: "Only redirecting factory constructors can be declared to "
"be 'const'.",
howToFix: "Try removing the 'const' keyword or replacing the body with "
"'=' followed by a valid target.",
- usedBy: [analyzer],
+ usedBy: [analyzer, dart2js],
examples: const [
r"""
class C {
diff --git a/pkg/pkg.status b/pkg/pkg.status
index c44aaea..5cfce7f 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -49,6 +49,8 @@
analyzer/test/dart/ast/utilities_test: Pass, Slow # Issue 19756, 21628
analyzer/test/dart/ast/visitor_test: Pass, Slow # Issue 19756, 21628
analyzer/test/enum_test: Slow, Pass, Fail # Issue 21323
+analyzer/test/non_hint_code_test: Pass, Slow # Issue 21628
+analyzer/test/strong_mode_test: Pass, Slow # Issue 21628
analyzer/test/generated/all_the_rest_test: Pass, Slow # Issue 21628
analyzer/test/generated/ast_test: Pass, Slow # Issue 21628
analyzer/test/generated/compile_time_error_code_test: Pass, Slow
@@ -58,16 +60,22 @@
analyzer/test/generated/element_test: Pass, Slow # Issue 21628
analyzer/test/generated/error_suppression_test: Pass, Slow # Issue 21628
analyzer/test/generated/engine_test: SkipSlow
+analyzer/test/generated/hint_code_test: Pass, Slow # Issue 21628
+analyzer/test/generated/non_hint_code_test: Pass, Slow # Issue 21628
analyzer/test/generated/incremental_resolver_test: Pass, Slow # Issue 21628
analyzer/test/generated/incremental_scanner_test: Pass, Slow # Issue 21628
+analyzer/test/generated/inheritance_manager_test: Pass, Slow # Issue 21628
analyzer/test/generated/non_error_resolver_test: Pass, Slow # Issue 21628
analyzer/test/generated/parser_test: Pass, Slow # Issue 21628
analyzer/test/generated/resolver_test: Pass, Slow # Issue 21628
analyzer/test/generated/scanner_test: Pass, Slow # Issue 21628
+analyzer/test/generated/simple_resolver_test: Pass, Slow # Issue 21628
analyzer/test/generated/source_factory_test: Pass, Slow # Issue 21628
+analyzer/test/generated/static_type_analyzer_test: Pass, Slow # Issue 21628
analyzer/test/generated/static_type_warning_code_test: Pass, Slow
analyzer/test/generated/static_type_warning_code_test: Pass, Slow # Issue 21628
analyzer/test/generated/static_warning_code_test: Pass, Slow # Issue 21628
+analyzer/test/generated/strong_mode_test: Pass, Slow # Issue 21628
analyzer/test/generated/utilities_test: Pass, Slow # Issue 21628
analyzer/test/src/context/cache_test: Pass, Slow # Issue 21628
analyzer/test/src/context/context_test: Pass, Timeout # dartbug.com/23658
@@ -194,20 +202,28 @@
analyzer/test/enum_test: Crash # Issue 24485
analyzer/test/generated/all_the_rest_test: Crash # Issue 24485
analyzer/test/generated/ast_test: Crash # Issue 24485
+analyzer/test/generated/checked_mode_compile_time_error_code_test: Crash # Issue 24485
analyzer/test/generated/compile_time_error_code_test: Crash # Issue 24485
analyzer/test/generated/constant_test: Crash # Issue 24485
analyzer/test/generated/declaration_resolver_test: Crash # Issue 24485
+analyzer/test/generated/element_resolver_test: Crash # Issue 24485
analyzer/test/generated/element_test: Crash # Issue 24485
analyzer/test/generated/error_suppression_test: Crash # Issue 24485
+analyzer/test/generated/hint_code_test: Crash # Issue 24485
analyzer/test/generated/incremental_resolver_test: Crash # Issue 24485
analyzer/test/generated/incremental_scanner_test: Crash # Issue 24485
+analyzer/test/generated/inheritance_manager_test: Crash # Issue 24485
analyzer/test/generated/non_error_resolver_test: Crash # Issue 24485
+analyzer/test/generated/non_hint_code_test: Crash # Issue 24485
analyzer/test/generated/parser_test: Crash # Issue 24485
analyzer/test/generated/resolver_test: Crash # Issue 24485
analyzer/test/generated/scanner_test: Crash # Issue 24485
+analyzer/test/generated/simple_resolver_test: Crash # Issue 24485
analyzer/test/generated/source_factory_test: Crash # Issue 24485
+analyzer/test/generated/static_type_analyzer_test: Crash # Issue 24485
analyzer/test/generated/static_type_warning_code_test: Crash # Issue 24485
analyzer/test/generated/static_warning_code_test: Crash # Issue 24485
+analyzer/test/generated/strong_mode_test: Crash # Issue 24485
analyzer/test/generated/utilities_test: Crash # Issue 24485
analyzer/test/src/context/cache_test: Crash # Issue 24485
analyzer/test/src/context/context_test: Crash # Issue 24485
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 62b69fb..6e987c4 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -171,10 +171,6 @@
"vm/version.h",
"$target_gen_dir/version.cc",
]
- defines = [
- # Using DART_SHARED_LIB to export the Dart API entries.
- "DART_SHARED_LIB",
- ]
}
@@ -203,8 +199,6 @@
"$target_gen_dir/version.cc",
]
defines = [
- # Using DART_SHARED_LIB to export the Dart API entries.
- "DART_SHARED_LIB",
"DART_PRECOMPILED_RUNTIME",
]
}
diff --git a/runtime/bin/crypto.cc b/runtime/bin/crypto.cc
index 6becae8..ec4840f 100644
--- a/runtime/bin/crypto.cc
+++ b/runtime/bin/crypto.cc
@@ -7,7 +7,6 @@
#include "include/dart_api.h"
-
namespace dart {
namespace bin {
@@ -23,23 +22,20 @@
Dart_ThrowException(error);
}
intptr_t count = static_cast<intptr_t>(count64);
- uint8_t* buffer = new uint8_t[count];
+ uint8_t* buffer = Dart_ScopeAllocate(count);
ASSERT(buffer != NULL);
if (!Crypto::GetRandomBytes(count, buffer)) {
- delete[] buffer;
Dart_ThrowException(DartUtils::NewDartOSError());
UNREACHABLE();
}
Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, count);
if (Dart_IsError(result)) {
- delete[] buffer;
Dart_Handle error = DartUtils::NewString("Failed to allocate storage.");
Dart_ThrowException(error);
UNREACHABLE();
}
Dart_ListSetAsBytes(result, 0, buffer, count);
Dart_SetReturnValue(args, result);
- delete[] buffer;
}
} // namespace bin
diff --git a/runtime/bin/crypto.h b/runtime/bin/crypto.h
index 1feaf9c..b82fc4f 100644
--- a/runtime/bin/crypto.h
+++ b/runtime/bin/crypto.h
@@ -8,7 +8,6 @@
#include "bin/builtin.h"
#include "bin/utils.h"
-
namespace dart {
namespace bin {
diff --git a/runtime/bin/crypto_android.cc b/runtime/bin/crypto_android.cc
index 4b55b91..be91d4e 100644
--- a/runtime/bin/crypto_android.cc
+++ b/runtime/bin/crypto_android.cc
@@ -10,10 +10,8 @@
#include "bin/fdutils.h"
#include "bin/crypto.h"
-
#include "platform/signal_blocker.h"
-
namespace dart {
namespace bin {
@@ -21,7 +19,9 @@
ThreadSignalBlocker signal_blocker(SIGPROF);
intptr_t fd = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
open("/dev/urandom", O_RDONLY));
- if (fd < 0) return false;
+ if (fd < 0) {
+ return false;
+ }
intptr_t bytes_read = 0;
do {
int res = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
diff --git a/runtime/bin/crypto_linux.cc b/runtime/bin/crypto_linux.cc
index cf3062d..875ec8e 100644
--- a/runtime/bin/crypto_linux.cc
+++ b/runtime/bin/crypto_linux.cc
@@ -12,7 +12,6 @@
#include "bin/crypto.h"
#include "platform/signal_blocker.h"
-
namespace dart {
namespace bin {
@@ -20,7 +19,9 @@
ThreadSignalBlocker signal_blocker(SIGPROF);
intptr_t fd = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
open("/dev/urandom", O_RDONLY));
- if (fd < 0) return false;
+ if (fd < 0) {
+ return false;
+ }
intptr_t bytes_read = 0;
do {
int res = TEMP_FAILURE_RETRY_NO_SIGNAL_BLOCKER(
diff --git a/runtime/bin/crypto_macos.cc b/runtime/bin/crypto_macos.cc
index 7d98daf..8a27245 100644
--- a/runtime/bin/crypto_macos.cc
+++ b/runtime/bin/crypto_macos.cc
@@ -12,7 +12,6 @@
#include "bin/crypto.h"
#include "platform/signal_blocker.h"
-
namespace dart {
namespace bin {
diff --git a/runtime/bin/crypto_win.cc b/runtime/bin/crypto_win.cc
index 95aead8..0208d95 100644
--- a/runtime/bin/crypto_win.cc
+++ b/runtime/bin/crypto_win.cc
@@ -11,7 +11,6 @@
#include "bin/crypto.h"
-
namespace dart {
namespace bin {
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index f592f2c..09258f7 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -630,10 +630,9 @@
void FUNCTION_NAME(Builtin_GetCurrentDirectory)(Dart_NativeArguments args) {
- char* current = Directory::Current();
+ const char* current = Directory::Current();
if (current != NULL) {
Dart_SetReturnValue(args, DartUtils::NewString(current));
- free(current);
} else {
Dart_Handle err = DartUtils::NewError("Failed to get current directory.");
Dart_PropagateError(err);
@@ -952,7 +951,7 @@
bool DartUtils::SetOriginalWorkingDirectory() {
- original_working_directory = Directory::Current();
+ original_working_directory = Directory::CurrentNoScope();
return original_working_directory != NULL;
}
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 1d18b5f9..adc7d3f 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -165,6 +165,23 @@
strlen(str));
}
+ // Allocate length bytes for a C string with Dart_ScopeAllocate.
+ static char* ScopedCString(intptr_t length) {
+ char* result = NULL;
+ result = reinterpret_cast<char*>(
+ Dart_ScopeAllocate(length * sizeof(*result)));
+ return result;
+ }
+
+ // Copy str into a buffer allocated with Dart_ScopeAllocate.
+ static char* ScopedCopyCString(const char* str) {
+ size_t str_len = strlen(str);
+ char* result = ScopedCString(str_len + 1);
+ memmove(result, str, str_len);
+ result[str_len] = '\0';
+ return result;
+ }
+
// Create a new Dart InternalError object with the provided message.
static Dart_Handle NewError(const char* format, ...);
static Dart_Handle NewInternalError(const char* message);
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index a28b01c..3791197 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -13,10 +13,9 @@
namespace bin {
void FUNCTION_NAME(Directory_Current)(Dart_NativeArguments args) {
- char* current = Directory::Current();
+ const char* current = Directory::Current();
if (current != NULL) {
Dart_SetReturnValue(args, DartUtils::NewString(current));
- free(current);
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
}
@@ -69,9 +68,8 @@
void FUNCTION_NAME(Directory_SystemTemp)(
Dart_NativeArguments args) {
- char* result = Directory::SystemTemp();
+ const char* result = Directory::SystemTemp();
Dart_SetReturnValue(args, DartUtils::NewString(result));
- free(result);
}
@@ -82,10 +80,10 @@
"Prefix argument of CreateSystemTempSync is not a String"));
return;
}
- char* result = Directory::CreateTemp(DartUtils::GetStringValue(path));
+ const char* result =
+ Directory::CreateTemp(DartUtils::GetStringValue(path));
if (result != NULL) {
Dart_SetReturnValue(args, DartUtils::NewString(result));
- free(result);
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
}
@@ -187,10 +185,9 @@
CObject* Directory::CreateTempRequest(const CObjectArray& request) {
if (request.Length() == 1 && request[0]->IsString()) {
CObjectString path(request[0]);
- char* result = Directory::CreateTemp(path.CString());
+ const char* result = Directory::CreateTemp(path.CString());
if (result != NULL) {
CObject* temp_dir = new CObjectString(CObject::NewString(result));
- free(result);
return temp_dir;
} else {
return CObject::NewOSError();
@@ -243,8 +240,7 @@
CObject* Directory::ListNextRequest(const CObjectArray& request) {
- if (request.Length() == 1 &&
- request[0]->IsIntptr()) {
+ if ((request.Length() == 1) && request[0]->IsIntptr()) {
CObjectIntptr ptr(request[0]);
AsyncDirectoryListing* dir_listing =
reinterpret_cast<AsyncDirectoryListing*>(ptr.Value());
@@ -265,7 +261,7 @@
CObject* Directory::ListStopRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsIntptr()) {
+ if ((request.Length() == 1) && request[0]->IsIntptr()) {
CObjectIntptr ptr(request[0]);
AsyncDirectoryListing* dir_listing =
reinterpret_cast<AsyncDirectoryListing*>(ptr.Value());
@@ -283,7 +279,9 @@
CObjectString path(request[0]);
CObjectString new_path(request[1]);
bool completed = Directory::Rename(path.CString(), new_path.CString());
- if (completed) return CObject::True();
+ if (completed) {
+ return CObject::True();
+ }
return CObject::NewOSError();
}
return CObject::IllegalArgumentError();
@@ -291,7 +289,7 @@
bool AsyncDirectoryListing::AddFileSystemEntityToResponse(Response type,
- char* arg) {
+ const char* arg) {
array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(type)));
if (arg != NULL) {
array_->SetAt(index_++, new CObjectString(CObject::NewString(arg)));
@@ -302,37 +300,42 @@
}
-bool AsyncDirectoryListing::HandleDirectory(char* dir_name) {
+bool AsyncDirectoryListing::HandleDirectory(const char* dir_name) {
return AddFileSystemEntityToResponse(kListDirectory, dir_name);
}
-bool AsyncDirectoryListing::HandleFile(char* file_name) {
+bool AsyncDirectoryListing::HandleFile(const char* file_name) {
return AddFileSystemEntityToResponse(kListFile, file_name);
}
-bool AsyncDirectoryListing::HandleLink(char* link_name) {
+bool AsyncDirectoryListing::HandleLink(const char* link_name) {
return AddFileSystemEntityToResponse(kListLink, link_name);
}
+
void AsyncDirectoryListing::HandleDone() {
AddFileSystemEntityToResponse(kListDone, NULL);
}
-bool AsyncDirectoryListing::HandleError(const char* dir_name) {
+bool AsyncDirectoryListing::HandleError() {
CObject* err = CObject::NewOSError();
array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(kListError)));
CObjectArray* response = new CObjectArray(CObject::NewArray(3));
response->SetAt(0, new CObjectInt32(CObject::NewInt32(kListError)));
- response->SetAt(1, new CObjectString(CObject::NewString(dir_name)));
+ // Delay calling CurrentPath() until after CObject::NewOSError() in case
+ // CurrentPath() pollutes the OS error code.
+ response->SetAt(1, new CObjectString(CObject::NewString(
+ error() ? "Invalid path" : CurrentPath())));
response->SetAt(2, err);
array_->SetAt(index_++, response);
return index_ < length_;
}
-bool SyncDirectoryListing::HandleDirectory(char* dir_name) {
+
+bool SyncDirectoryListing::HandleDirectory(const char* dir_name) {
Dart_Handle dir_name_dart = DartUtils::NewString(dir_name);
Dart_Handle dir =
Dart_New(directory_type_, Dart_Null(), 1, &dir_name_dart);
@@ -340,7 +343,8 @@
return true;
}
-bool SyncDirectoryListing::HandleLink(char* link_name) {
+
+bool SyncDirectoryListing::HandleLink(const char* link_name) {
Dart_Handle link_name_dart = DartUtils::NewString(link_name);
Dart_Handle link =
Dart_New(link_type_, Dart_Null(), 1, &link_name_dart);
@@ -348,7 +352,8 @@
return true;
}
-bool SyncDirectoryListing::HandleFile(char* file_name) {
+
+bool SyncDirectoryListing::HandleFile(const char* file_name) {
Dart_Handle file_name_dart = DartUtils::NewString(file_name);
Dart_Handle file =
Dart_New(file_type_, Dart_Null(), 1, &file_name_dart);
@@ -356,11 +361,12 @@
return true;
}
-bool SyncDirectoryListing::HandleError(const char* dir_name) {
+
+bool SyncDirectoryListing::HandleError() {
Dart_Handle dart_os_error = DartUtils::NewDartOSError();
Dart_Handle args[3];
args[0] = DartUtils::NewString("Directory listing failed");
- args[1] = DartUtils::NewString(dir_name);
+ args[1] = DartUtils::NewString(error() ? "Invalid path" : CurrentPath());
args[2] = dart_os_error;
Dart_ThrowException(Dart_New(
DartUtils::GetDartType(DartUtils::kIOLibURL, "FileSystemException"),
@@ -386,7 +392,7 @@
return listing->HandleDirectory(listing->CurrentPath());
case kListError:
- return listing->HandleError(listing->CurrentPath());
+ return listing->HandleError();
case kListDone:
listing->Pop();
@@ -403,9 +409,10 @@
return false;
}
+
void Directory::List(DirectoryListing* listing) {
if (listing->error()) {
- listing->HandleError("Invalid path");
+ listing->HandleError();
listing->HandleDone();
} else {
while (ListNext(listing)) {}
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index 9402031..e37aa76 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -25,9 +25,7 @@
class PathBuffer {
public:
PathBuffer();
- ~PathBuffer() {
- free(data_);
- }
+ ~PathBuffer();
bool Add(const char* name);
bool AddW(const wchar_t* name);
@@ -35,15 +33,18 @@
char* AsString() const;
wchar_t* AsStringW() const;
- void Reset(int new_length);
+ // Makes a scope allocated copy of the string.
+ const char* AsScopedString() const;
- int length() const {
+ void Reset(intptr_t new_length);
+
+ intptr_t length() const {
return length_;
}
private:
void* data_;
- int length_;
+ intptr_t length_;
DISALLOW_COPY_AND_ASSIGN(PathBuffer);
};
@@ -112,10 +113,10 @@
}
}
- virtual bool HandleDirectory(char* dir_name) = 0;
- virtual bool HandleFile(char* file_name) = 0;
- virtual bool HandleLink(char* link_name) = 0;
- virtual bool HandleError(const char* dir_name) = 0;
+ virtual bool HandleDirectory(const char* dir_name) = 0;
+ virtual bool HandleFile(const char* file_name) = 0;
+ virtual bool HandleLink(const char* link_name) = 0;
+ virtual bool HandleError() = 0;
virtual void HandleDone() {}
void Push(DirectoryListingEntry* directory) {
@@ -145,8 +146,8 @@
return follow_links_;
}
- char* CurrentPath() {
- return path_buffer_.AsString();
+ const char* CurrentPath() {
+ return path_buffer_.AsScopedString();
}
PathBuffer& path_buffer() {
@@ -182,10 +183,10 @@
: DirectoryListing(dir_name, recursive, follow_links) {}
virtual ~AsyncDirectoryListing() {}
- virtual bool HandleDirectory(char* dir_name);
- virtual bool HandleFile(char* file_name);
- virtual bool HandleLink(char* file_name);
- virtual bool HandleError(const char* dir_name);
+ virtual bool HandleDirectory(const char* dir_name);
+ virtual bool HandleFile(const char* file_name);
+ virtual bool HandleLink(const char* file_name);
+ virtual bool HandleError();
virtual void HandleDone();
void SetArray(CObjectArray* array, intptr_t length) {
@@ -200,7 +201,7 @@
}
private:
- bool AddFileSystemEntityToResponse(Response response, char* arg);
+ bool AddFileSystemEntityToResponse(Response response, const char* arg);
CObjectArray* array_;
intptr_t index_;
intptr_t length_;
@@ -226,10 +227,10 @@
DartUtils::GetDartType(DartUtils::kIOLibURL, "Link");
}
virtual ~SyncDirectoryListing() {}
- virtual bool HandleDirectory(char* dir_name);
- virtual bool HandleFile(char* file_name);
- virtual bool HandleLink(char* file_name);
- virtual bool HandleError(const char* dir_name);
+ virtual bool HandleDirectory(const char* dir_name);
+ virtual bool HandleFile(const char* file_name);
+ virtual bool HandleLink(const char* file_name);
+ virtual bool HandleError();
private:
Dart_Handle results_;
@@ -252,11 +253,18 @@
static void List(DirectoryListing* listing);
static ExistsResult Exists(const char* path);
- static char* Current();
+
+ // Returns the current working directory. The caller must call
+ // free() on the result.
+ static char* CurrentNoScope();
+
+ // Returns the current working directory. The returned string is allocated
+ // with Dart_ScopeAllocate(). It lasts only as long as the current API scope.
+ static const char* Current();
+ static const char* SystemTemp();
+ static const char* CreateTemp(const char* path);
static bool SetCurrent(const char* path);
static bool Create(const char* path);
- static char* SystemTemp();
- static char* CreateTemp(const char* path);
static bool Delete(const char* path, bool recursive);
static bool Rename(const char* path, const char* new_path);
diff --git a/runtime/bin/directory_android.cc b/runtime/bin/directory_android.cc
index 40bcde3..6571f18 100644
--- a/runtime/bin/directory_android.cc
+++ b/runtime/bin/directory_android.cc
@@ -14,34 +14,46 @@
#include <sys/stat.h> // NOLINT
#include <unistd.h> // NOLINT
+#include "bin/dartutils.h"
#include "bin/file.h"
#include "bin/platform.h"
-
#include "platform/signal_blocker.h"
-
namespace dart {
namespace bin {
-
PathBuffer::PathBuffer() : length_(0) {
- data_ = calloc(PATH_MAX + 1, sizeof(char)); // NOLINT
+ data_ = calloc(PATH_MAX + 1, sizeof(char)); // NOLINT
}
+
+PathBuffer::~PathBuffer() {
+ free(data_);
+}
+
+
bool PathBuffer::AddW(const wchar_t* name) {
UNREACHABLE();
return false;
}
+
char* PathBuffer::AsString() const {
return reinterpret_cast<char*>(data_);
}
+
wchar_t* PathBuffer::AsStringW() const {
UNREACHABLE();
return NULL;
}
+
+const char* PathBuffer::AsScopedString() const {
+ return DartUtils::ScopedCopyCString(AsString());
+}
+
+
bool PathBuffer::Add(const char* name) {
char* data = AsString();
int written = snprintf(data + length_,
@@ -49,9 +61,9 @@
"%s",
name);
data[PATH_MAX] = '\0';
- if (written <= PATH_MAX - length_ &&
- written >= 0 &&
- static_cast<size_t>(written) == strnlen(name, PATH_MAX + 1)) {
+ if ((written <= PATH_MAX - length_) &&
+ (written >= 0) &&
+ (static_cast<size_t>(written) == strnlen(name, PATH_MAX + 1))) {
length_ += written;
return true;
} else {
@@ -60,7 +72,8 @@
}
}
-void PathBuffer::Reset(int new_length) {
+
+void PathBuffer::Reset(intptr_t new_length) {
length_ = new_length;
AsString()[length_] = '\0';
}
@@ -84,7 +97,7 @@
do {
lister_ = reinterpret_cast<intptr_t>(
opendir(listing->path_buffer().AsString()));
- } while (lister_ == 0 && errno == EINTR);
+ } while ((lister_ == 0) && (errno == EINTR));
if (lister_ == 0) {
done_ = true;
@@ -106,18 +119,19 @@
int status = 0;
dirent entry;
dirent* result;
- if ((status = NO_RETRY_EXPECTED(readdir_r(reinterpret_cast<DIR*>(lister_),
- &entry,
- &result))) == 0 &&
- result != NULL) {
+ status = NO_RETRY_EXPECTED(readdir_r(
+ reinterpret_cast<DIR*>(lister_), &entry, &result));
+ if ((status == 0) && (result != NULL)) {
if (!listing->path_buffer().Add(entry.d_name)) {
done_ = true;
return kListError;
}
switch (entry.d_type) {
case DT_DIR:
- if (strcmp(entry.d_name, ".") == 0) return Next(listing);
- if (strcmp(entry.d_name, "..") == 0) return Next(listing);
+ if ((strcmp(entry.d_name, ".") == 0) ||
+ (strcmp(entry.d_name, "..") == 0)) {
+ return Next(listing);
+ }
return kListDirectory;
case DT_REG:
return kListFile;
@@ -146,8 +160,8 @@
link_ };
LinkList* previous = link_;
while (previous != NULL) {
- if (previous->dev == current_link.dev &&
- previous->ino == current_link.ino) {
+ if ((previous->dev == current_link.dev) &&
+ (previous->ino == current_link.ino)) {
// Report the looping link as a link, rather than following it.
return kListLink;
}
@@ -163,14 +177,18 @@
// Recurse into the subdirectory with current_link added to the
// linked list of seen file system links.
link_ = new LinkList(current_link);
- if (strcmp(entry.d_name, ".") == 0) return Next(listing);
- if (strcmp(entry.d_name, "..") == 0) return Next(listing);
+ if ((strcmp(entry.d_name, ".") == 0) ||
+ (strcmp(entry.d_name, "..") == 0)) {
+ return Next(listing);
+ }
return kListDirectory;
}
}
if (S_ISDIR(entry_info.st_mode)) {
- if (strcmp(entry.d_name, ".") == 0) return Next(listing);
- if (strcmp(entry.d_name, "..") == 0) return Next(listing);
+ if ((strcmp(entry.d_name, ".") == 0) ||
+ (strcmp(entry.d_name, "..") == 0)) {
+ return Next(listing);
+ }
return kListDirectory;
} else if (S_ISREG(entry_info.st_mode)) {
return kListFile;
@@ -203,7 +221,7 @@
void DirectoryListingEntry::ResetLink() {
- if (link_ != NULL && (parent_ == NULL || parent_->link_ != link_)) {
+ if ((link_ != NULL) && ((parent_ == NULL) || (parent_->link_ != link_))) {
delete link_;
link_ = NULL;
}
@@ -218,14 +236,15 @@
static bool DeleteFile(char* file_name,
PathBuffer* path) {
- return path->Add(file_name) && unlink(path->AsString()) == 0;
+ return path->Add(file_name) && (unlink(path->AsString()) == 0);
}
static bool DeleteDir(char* dir_name,
PathBuffer* path) {
- if (strcmp(dir_name, ".") == 0) return true;
- if (strcmp(dir_name, "..") == 0) return true;
+ if ((strcmp(dir_name, ".") == 0) || (strcmp(dir_name, "..") == 0)) {
+ return true;
+ }
return path->Add(dir_name) && DeleteRecursively(path);
}
@@ -240,14 +259,16 @@
return (unlink(path->AsString()) == 0);
}
- if (!path->Add(File::PathSeparator())) return false;
+ if (!path->Add(File::PathSeparator())) {
+ return false;
+ }
// Not a link. Attempt to open as a directory and recurse into the
// directory.
DIR* dir_pointer;
do {
dir_pointer = opendir(path->AsString());
- } while (dir_pointer == NULL && errno == EINTR);
+ } while ((dir_pointer == NULL) && (errno == EINTR));
if (dir_pointer == NULL) {
return false;
}
@@ -323,26 +344,26 @@
return DOES_NOT_EXIST;
}
} else {
- if (errno == EACCES ||
- errno == EBADF ||
- errno == EFAULT ||
- errno == ENOMEM ||
- errno == EOVERFLOW) {
+ if ((errno == EACCES) ||
+ (errno == EBADF) ||
+ (errno == EFAULT) ||
+ (errno == ENOMEM) ||
+ (errno == EOVERFLOW)) {
// Search permissions denied for one of the directories in the
// path or a low level error occured. We do not know if the
// directory exists.
return UNKNOWN;
}
- ASSERT(errno == ELOOP ||
- errno == ENAMETOOLONG ||
- errno == ENOENT ||
- errno == ENOTDIR);
+ ASSERT((errno == ELOOP) ||
+ (errno == ENAMETOOLONG) ||
+ (errno == ENOENT) ||
+ (errno == ENOTDIR));
return DOES_NOT_EXIST;
}
}
-char* Directory::Current() {
+char* Directory::CurrentNoScope() {
// Android's getcwd adheres closely to the POSIX standard. It won't
// allocate memory. We need to make our own copy.
@@ -355,6 +376,13 @@
}
+const char* Directory::Current() {
+ char* result = DartUtils::ScopedCString(PATH_MAX);
+ ASSERT(result != NULL);
+ return getcwd(result, PATH_MAX);
+}
+
+
bool Directory::SetCurrent(const char* path) {
int result = NO_RETRY_EXPECTED(chdir(path));
return result == 0;
@@ -366,14 +394,14 @@
// process umask.
int result = NO_RETRY_EXPECTED(mkdir(dir_name, 0777));
// If the directory already exists, treat it as a success.
- if (result == -1 && errno == EEXIST) {
+ if ((result == -1) && (errno == EEXIST)) {
return (Exists(dir_name) == EXISTS);
}
return (result == 0);
}
-char* Directory::SystemTemp() {
+const char* Directory::SystemTemp() {
// Android does not have a /tmp directory. A partial substitute,
// suitable for bring-up work and tests, is to create a tmp
// directory in /data/local/tmp.
@@ -386,17 +414,19 @@
if (stat(ANDROID_TEMP_DIR, &st) != 0) {
mkdir(ANDROID_TEMP_DIR, 0777);
}
- return strdup(ANDROID_TEMP_DIR);
+ return ANDROID_TEMP_DIR;
}
-char* Directory::CreateTemp(const char* prefix) {
+const char* Directory::CreateTemp(const char* prefix) {
// Returns a new, unused directory name, adding characters to the end
// of prefix. Creates the directory with the permissions specified
// by the process umask.
- // The return value must be freed by the caller.
+ // The return value is Dart_ScopeAllocated.
PathBuffer path;
- path.Add(prefix);
+ if (!path.Add(prefix)) {
+ return NULL;
+ }
if (!path.Add("XXXXXX")) {
// Pattern has overflowed.
return NULL;
@@ -404,18 +434,18 @@
char* result;
do {
result = mkdtemp(path.AsString());
- } while (result == NULL && errno == EINTR);
+ } while ((result == NULL) && (errno == EINTR));
if (result == NULL) {
return NULL;
}
- return strdup(result);
+ return path.AsScopedString();
}
bool Directory::Delete(const char* dir_name, bool recursive) {
if (!recursive) {
- if (File::GetType(dir_name, false) == File::kIsLink &&
- File::GetType(dir_name, true) == File::kIsDirectory) {
+ if ((File::GetType(dir_name, false) == File::kIsLink) &&
+ (File::GetType(dir_name, true) == File::kIsDirectory)) {
return (NO_RETRY_EXPECTED(unlink(dir_name)) == 0);
}
return (NO_RETRY_EXPECTED(rmdir(dir_name)) == 0);
@@ -431,7 +461,9 @@
bool Directory::Rename(const char* path, const char* new_path) {
ExistsResult exists = Exists(path);
- if (exists != EXISTS) return false;
+ if (exists != EXISTS) {
+ return false;
+ }
return (NO_RETRY_EXPECTED(rename(path, new_path)) == 0);
}
diff --git a/runtime/bin/directory_linux.cc b/runtime/bin/directory_linux.cc
index d150bf2..8430134 100644
--- a/runtime/bin/directory_linux.cc
+++ b/runtime/bin/directory_linux.cc
@@ -15,33 +15,46 @@
#include <sys/stat.h> // NOLINT
#include <unistd.h> // NOLINT
-#include "platform/signal_blocker.h"
+#include "bin/dartutils.h"
#include "bin/file.h"
#include "bin/platform.h"
-
+#include "platform/signal_blocker.h"
namespace dart {
namespace bin {
-
PathBuffer::PathBuffer() : length_(0) {
- data_ = calloc(PATH_MAX + 1, sizeof(char)); // NOLINT
+ data_ = calloc(PATH_MAX + 1, sizeof(char)); // NOLINT
}
+
+PathBuffer::~PathBuffer() {
+ free(data_);
+}
+
+
bool PathBuffer::AddW(const wchar_t* name) {
UNREACHABLE();
return false;
}
+
char* PathBuffer::AsString() const {
return reinterpret_cast<char*>(data_);
}
+
wchar_t* PathBuffer::AsStringW() const {
UNREACHABLE();
return NULL;
}
+
+const char* PathBuffer::AsScopedString() const {
+ return DartUtils::ScopedCopyCString(AsString());
+}
+
+
bool PathBuffer::Add(const char* name) {
char* data = AsString();
int written = snprintf(data + length_,
@@ -49,9 +62,9 @@
"%s",
name);
data[PATH_MAX] = '\0';
- if (written <= PATH_MAX - length_ &&
- written >= 0 &&
- static_cast<size_t>(written) == strnlen(name, PATH_MAX + 1)) {
+ if ((written <= PATH_MAX - length_) &&
+ (written >= 0) &&
+ (static_cast<size_t>(written) == strnlen(name, PATH_MAX + 1))) {
length_ += written;
return true;
} else {
@@ -60,7 +73,8 @@
}
}
-void PathBuffer::Reset(int new_length) {
+
+void PathBuffer::Reset(intptr_t new_length) {
length_ = new_length;
AsString()[length_] = '\0';
}
@@ -84,7 +98,7 @@
do {
lister_ = reinterpret_cast<intptr_t>(
opendir(listing->path_buffer().AsString()));
- } while (lister_ == 0 && errno == EINTR);
+ } while ((lister_ == 0) && (errno == EINTR));
if (lister_ == 0) {
done_ = true;
@@ -106,18 +120,19 @@
int status = 0;
dirent entry;
dirent* result;
- if ((status = NO_RETRY_EXPECTED(readdir_r(reinterpret_cast<DIR*>(lister_),
- &entry,
- &result))) == 0 &&
- result != NULL) {
+ status = NO_RETRY_EXPECTED(readdir_r(
+ reinterpret_cast<DIR*>(lister_), &entry, &result));
+ if ((status == 0) && (result != NULL)) {
if (!listing->path_buffer().Add(entry.d_name)) {
done_ = true;
return kListError;
}
switch (entry.d_type) {
case DT_DIR:
- if (strcmp(entry.d_name, ".") == 0) return Next(listing);
- if (strcmp(entry.d_name, "..") == 0) return Next(listing);
+ if ((strcmp(entry.d_name, ".") == 0) ||
+ (strcmp(entry.d_name, "..") == 0)) {
+ return Next(listing);
+ }
return kListDirectory;
case DT_REG:
return kListFile;
@@ -146,8 +161,8 @@
link_ };
LinkList* previous = link_;
while (previous != NULL) {
- if (previous->dev == current_link.dev &&
- previous->ino == current_link.ino) {
+ if ((previous->dev == current_link.dev) &&
+ (previous->ino == current_link.ino)) {
// Report the looping link as a link, rather than following it.
return kListLink;
}
@@ -163,14 +178,18 @@
// Recurse into the subdirectory with current_link added to the
// linked list of seen file system links.
link_ = new LinkList(current_link);
- if (strcmp(entry.d_name, ".") == 0) return Next(listing);
- if (strcmp(entry.d_name, "..") == 0) return Next(listing);
+ if ((strcmp(entry.d_name, ".") == 0) ||
+ (strcmp(entry.d_name, "..") == 0)) {
+ return Next(listing);
+ }
return kListDirectory;
}
}
if (S_ISDIR(entry_info.st_mode)) {
- if (strcmp(entry.d_name, ".") == 0) return Next(listing);
- if (strcmp(entry.d_name, "..") == 0) return Next(listing);
+ if ((strcmp(entry.d_name, ".") == 0) ||
+ (strcmp(entry.d_name, "..") == 0)) {
+ return Next(listing);
+ }
return kListDirectory;
} else if (S_ISREG(entry_info.st_mode)) {
return kListFile;
@@ -203,7 +222,7 @@
void DirectoryListingEntry::ResetLink() {
- if (link_ != NULL && (parent_ == NULL || parent_->link_ != link_)) {
+ if ((link_ != NULL) && ((parent_ == NULL) || (parent_->link_ != link_))) {
delete link_;
link_ = NULL;
}
@@ -219,14 +238,15 @@
static bool DeleteFile(char* file_name,
PathBuffer* path) {
return path->Add(file_name) &&
- NO_RETRY_EXPECTED(unlink(path->AsString())) == 0;
+ (NO_RETRY_EXPECTED(unlink(path->AsString())) == 0);
}
static bool DeleteDir(char* dir_name,
PathBuffer* path) {
- if (strcmp(dir_name, ".") == 0) return true;
- if (strcmp(dir_name, "..") == 0) return true;
+ if ((strcmp(dir_name, ".") == 0) || (strcmp(dir_name, "..") == 0)) {
+ return true;
+ }
return path->Add(dir_name) && DeleteRecursively(path);
}
@@ -241,14 +261,16 @@
return (NO_RETRY_EXPECTED(unlink(path->AsString())) == 0);
}
- if (!path->Add(File::PathSeparator())) return false;
+ if (!path->Add(File::PathSeparator())) {
+ return false;
+ }
// Not a link. Attempt to open as a directory and recurse into the
// directory.
DIR* dir_pointer;
do {
dir_pointer = opendir(path->AsString());
- } while (dir_pointer == NULL && errno == EINTR);
+ } while ((dir_pointer == NULL) && (errno == EINTR));
if (dir_pointer == NULL) {
return false;
}
@@ -260,8 +282,8 @@
while (NO_RETRY_EXPECTED(readdir_r(dir_pointer, &entry, &result)) == 0) {
if (result == NULL) {
// End of directory.
- return NO_RETRY_EXPECTED(closedir(dir_pointer)) == 0 &&
- NO_RETRY_EXPECTED(remove(path->AsString())) == 0;
+ return (NO_RETRY_EXPECTED(closedir(dir_pointer)) == 0) &&
+ (NO_RETRY_EXPECTED(remove(path->AsString())) == 0);
}
bool ok = false;
switch (entry.d_type) {
@@ -324,38 +346,40 @@
return DOES_NOT_EXIST;
}
} else {
- if (errno == EACCES ||
- errno == EBADF ||
- errno == EFAULT ||
- errno == ENOMEM ||
- errno == EOVERFLOW) {
+ if ((errno == EACCES) ||
+ (errno == EBADF) ||
+ (errno == EFAULT) ||
+ (errno == ENOMEM) ||
+ (errno == EOVERFLOW)) {
// Search permissions denied for one of the directories in the
// path or a low level error occured. We do not know if the
// directory exists.
return UNKNOWN;
}
- ASSERT(errno == ELOOP ||
- errno == ENAMETOOLONG ||
- errno == ENOENT ||
- errno == ENOTDIR);
+ ASSERT((errno == ELOOP) ||
+ (errno == ENAMETOOLONG) ||
+ (errno == ENOENT) ||
+ (errno == ENOTDIR));
return DOES_NOT_EXIST;
}
}
-char* Directory::Current() {
- size_t size = PATH_MAX;
- char* buffer = NULL;
- for (char* result = NULL; result == NULL; size *= 2) {
- if ((buffer = reinterpret_cast<char*>(realloc(buffer, size))) == NULL) {
- return NULL;
- }
- result = getcwd(buffer, size);
- if (result == NULL && errno != ERANGE) {
- return NULL;
- }
+char* Directory::CurrentNoScope() {
+ char buffer[PATH_MAX];
+ if (getcwd(buffer, PATH_MAX) == NULL) {
+ return NULL;
}
- return buffer;
+ return strdup(buffer);
+}
+
+
+const char* Directory::Current() {
+ char buffer[PATH_MAX];
+ if (getcwd(buffer, PATH_MAX) == NULL) {
+ return NULL;
+ }
+ return DartUtils::ScopedCopyCString(buffer);
}
@@ -369,14 +393,15 @@
// process umask.
int result = NO_RETRY_EXPECTED(mkdir(dir_name, 0777));
// If the directory already exists, treat it as a success.
- if (result == -1 && errno == EEXIST) {
+ if ((result == -1) && (errno == EEXIST)) {
return (Exists(dir_name) == EXISTS);
}
return (result == 0);
}
-char* Directory::SystemTemp() {
+const char* Directory::SystemTemp() {
+ PathBuffer path;
const char* temp_dir = getenv("TMPDIR");
if (temp_dir == NULL) {
temp_dir = getenv("TMP");
@@ -384,23 +409,29 @@
if (temp_dir == NULL) {
temp_dir = "/tmp";
}
- char* result = strdup(temp_dir);
+ if (!path.Add(temp_dir)) {
+ return NULL;
+ }
+
// Remove any trailing slash.
+ char* result = path.AsString();
int length = strlen(result);
- if (length > 1 && result[length - 1] == '/') {
+ if ((length > 1) && (result[length - 1] == '/')) {
result[length - 1] = '\0';
}
- return result;
+ return path.AsScopedString();
}
-char* Directory::CreateTemp(const char* prefix) {
+const char* Directory::CreateTemp(const char* prefix) {
// Returns a new, unused directory name, adding characters to the end
// of prefix. Creates the directory with the permissions specified
// by the process umask.
- // The return value must be freed by the caller.
+ // The return value is Dart_ScopeAllocated.
PathBuffer path;
- path.Add(prefix);
+ if (!path.Add(prefix)) {
+ return NULL;
+ }
if (!path.Add("XXXXXX")) {
// Pattern has overflowed.
return NULL;
@@ -408,18 +439,18 @@
char* result;
do {
result = mkdtemp(path.AsString());
- } while (result == NULL && errno == EINTR);
+ } while ((result == NULL) && (errno == EINTR));
if (result == NULL) {
return NULL;
}
- return strdup(result);
+ return path.AsScopedString();
}
bool Directory::Delete(const char* dir_name, bool recursive) {
if (!recursive) {
- if (File::GetType(dir_name, false) == File::kIsLink &&
- File::GetType(dir_name, true) == File::kIsDirectory) {
+ if ((File::GetType(dir_name, false) == File::kIsLink) &&
+ (File::GetType(dir_name, true) == File::kIsDirectory)) {
return NO_RETRY_EXPECTED(unlink(dir_name)) == 0;
}
return NO_RETRY_EXPECTED(rmdir(dir_name)) == 0;
@@ -435,7 +466,9 @@
bool Directory::Rename(const char* path, const char* new_path) {
ExistsResult exists = Exists(path);
- if (exists != EXISTS) return false;
+ if (exists != EXISTS) {
+ return false;
+ }
return NO_RETRY_EXPECTED(rename(path, new_path)) == 0;
}
diff --git a/runtime/bin/directory_macos.cc b/runtime/bin/directory_macos.cc
index 55994aa..a10b20a 100644
--- a/runtime/bin/directory_macos.cc
+++ b/runtime/bin/directory_macos.cc
@@ -14,34 +14,46 @@
#include <sys/stat.h> // NOLINT
#include <unistd.h> // NOLINT
+#include "bin/dartutils.h"
#include "bin/file.h"
#include "bin/platform.h"
-
#include "platform/signal_blocker.h"
-
namespace dart {
namespace bin {
-
PathBuffer::PathBuffer() : length_(0) {
- data_ = calloc(PATH_MAX + 1, sizeof(char)); // NOLINT
+ data_ = calloc(PATH_MAX + 1, sizeof(char)); // NOLINT
}
+
+PathBuffer::~PathBuffer() {
+ free(data_);
+}
+
+
bool PathBuffer::AddW(const wchar_t* name) {
UNREACHABLE();
return false;
}
+
char* PathBuffer::AsString() const {
return reinterpret_cast<char*>(data_);
}
+
wchar_t* PathBuffer::AsStringW() const {
UNREACHABLE();
return NULL;
}
+
+const char* PathBuffer::AsScopedString() const {
+ return DartUtils::ScopedCopyCString(AsString());
+}
+
+
bool PathBuffer::Add(const char* name) {
char* data = AsString();
int written = snprintf(data + length_,
@@ -49,9 +61,9 @@
"%s",
name);
data[PATH_MAX] = '\0';
- if (written <= PATH_MAX - length_ &&
- written >= 0 &&
- static_cast<size_t>(written) == strlen(name)) {
+ if ((written <= PATH_MAX - length_) &&
+ (written >= 0) &&
+ (static_cast<size_t>(written) == strlen(name))) {
length_ += written;
return true;
} else {
@@ -60,7 +72,8 @@
}
}
-void PathBuffer::Reset(int new_length) {
+
+void PathBuffer::Reset(intptr_t new_length) {
length_ = new_length;
AsString()[length_] = '\0';
}
@@ -84,7 +97,7 @@
do {
lister_ = reinterpret_cast<intptr_t>(
opendir(listing->path_buffer().AsString()));
- } while (lister_ == 0 && errno == EINTR);
+ } while ((lister_ == 0) && (errno == EINTR));
if (lister_ == 0) {
done_ = true;
@@ -106,18 +119,19 @@
int status = 0;
dirent entry;
dirent* result;
- if ((status = NO_RETRY_EXPECTED(readdir_r(reinterpret_cast<DIR*>(lister_),
- &entry,
- &result))) == 0 &&
- result != NULL) {
+ status = NO_RETRY_EXPECTED(readdir_r(
+ reinterpret_cast<DIR*>(lister_), &entry, &result));
+ if ((status == 0) && (result != NULL)) {
if (!listing->path_buffer().Add(entry.d_name)) {
done_ = true;
return kListError;
}
switch (entry.d_type) {
case DT_DIR:
- if (strcmp(entry.d_name, ".") == 0) return Next(listing);
- if (strcmp(entry.d_name, "..") == 0) return Next(listing);
+ if ((strcmp(entry.d_name, ".") == 0) ||
+ (strcmp(entry.d_name, "..") == 0)) {
+ return Next(listing);
+ }
return kListDirectory;
case DT_REG:
return kListFile;
@@ -146,8 +160,8 @@
link_ };
LinkList* previous = link_;
while (previous != NULL) {
- if (previous->dev == current_link.dev &&
- previous->ino == current_link.ino) {
+ if ((previous->dev == current_link.dev) &&
+ (previous->ino == current_link.ino)) {
// Report the looping link as a link, rather than following it.
return kListLink;
}
@@ -163,14 +177,18 @@
// Recurse into the subdirectory with current_link added to the
// linked list of seen file system links.
link_ = new LinkList(current_link);
- if (strcmp(entry.d_name, ".") == 0) return Next(listing);
- if (strcmp(entry.d_name, "..") == 0) return Next(listing);
+ if ((strcmp(entry.d_name, ".") == 0) ||
+ (strcmp(entry.d_name, "..") == 0)) {
+ return Next(listing);
+ }
return kListDirectory;
}
}
if (S_ISDIR(entry_info.st_mode)) {
- if (strcmp(entry.d_name, ".") == 0) return Next(listing);
- if (strcmp(entry.d_name, "..") == 0) return Next(listing);
+ if ((strcmp(entry.d_name, ".") == 0) ||
+ (strcmp(entry.d_name, "..") == 0)) {
+ return Next(listing);
+ }
return kListDirectory;
} else if (S_ISREG(entry_info.st_mode)) {
return kListFile;
@@ -203,7 +221,7 @@
void DirectoryListingEntry::ResetLink() {
- if (link_ != NULL && (parent_ == NULL || parent_->link_ != link_)) {
+ if ((link_ != NULL) && ((parent_ == NULL) || (parent_->link_ != link_))) {
delete link_;
link_ = NULL;
}
@@ -218,14 +236,15 @@
static bool DeleteFile(char* file_name,
PathBuffer* path) {
- return path->Add(file_name) && unlink(path->AsString()) == 0;
+ return path->Add(file_name) && (unlink(path->AsString()) == 0);
}
static bool DeleteDir(char* dir_name,
PathBuffer* path) {
- if (strcmp(dir_name, ".") == 0) return true;
- if (strcmp(dir_name, "..") == 0) return true;
+ if ((strcmp(dir_name, ".") == 0) || (strcmp(dir_name, "..") == 0)) {
+ return true;
+ }
return path->Add(dir_name) && DeleteRecursively(path);
}
@@ -240,14 +259,16 @@
return (unlink(path->AsString()) == 0);
}
- if (!path->Add(File::PathSeparator())) return false;
+ if (!path->Add(File::PathSeparator())) {
+ return false;
+ }
// Not a link. Attempt to open as a directory and recurse into the
// directory.
DIR* dir_pointer;
do {
dir_pointer = opendir(path->AsString());
- } while (dir_pointer == NULL && errno == EINTR);
+ } while ((dir_pointer == NULL) && (errno == EINTR));
if (dir_pointer == NULL) {
return false;
}
@@ -259,8 +280,8 @@
while (NO_RETRY_EXPECTED(readdir_r(dir_pointer, &entry, &result)) == 0) {
if (result == NULL) {
// End of directory.
- return NO_RETRY_EXPECTED(closedir(dir_pointer)) == 0 &&
- NO_RETRY_EXPECTED(remove(path->AsString())) == 0;
+ return (NO_RETRY_EXPECTED(closedir(dir_pointer)) == 0) &&
+ (NO_RETRY_EXPECTED(remove(path->AsString())) == 0);
}
bool ok = false;
switch (entry.d_type) {
@@ -323,30 +344,37 @@
return DOES_NOT_EXIST;
}
} else {
- if (errno == EACCES ||
- errno == EBADF ||
- errno == EFAULT ||
- errno == ENOMEM ||
- errno == EOVERFLOW) {
+ if ((errno == EACCES) ||
+ (errno == EBADF) ||
+ (errno == EFAULT) ||
+ (errno == ENOMEM) ||
+ (errno == EOVERFLOW)) {
// Search permissions denied for one of the directories in the
// path or a low level error occured. We do not know if the
// directory exists.
return UNKNOWN;
}
- ASSERT(errno == ELOOP ||
- errno == ENAMETOOLONG ||
- errno == ENOENT ||
- errno == ENOTDIR);
+ ASSERT((errno == ELOOP) ||
+ (errno == ENAMETOOLONG) ||
+ (errno == ENOENT) ||
+ (errno == ENOTDIR));
return DOES_NOT_EXIST;
}
}
-char* Directory::Current() {
+char* Directory::CurrentNoScope() {
return getcwd(NULL, 0);
}
+const char* Directory::Current() {
+ char* result = DartUtils::ScopedCString(PATH_MAX);
+ ASSERT(result != NULL);
+ return getcwd(result, PATH_MAX);
+}
+
+
bool Directory::SetCurrent(const char* path) {
int result = NO_RETRY_EXPECTED(chdir(path));
return result == 0;
@@ -358,14 +386,15 @@
// process umask.
int result = NO_RETRY_EXPECTED(mkdir(dir_name, 0777));
// If the directory already exists, treat it as a success.
- if (result == -1 && errno == EEXIST) {
+ if ((result == -1) && (errno == EEXIST)) {
return (Exists(dir_name) == EXISTS);
}
return (result == 0);
}
-char* Directory::SystemTemp() {
+const char* Directory::SystemTemp() {
+ PathBuffer path;
const char* temp_dir = getenv("TMPDIR");
if (temp_dir == NULL) {
temp_dir = getenv("TMP");
@@ -373,23 +402,28 @@
if (temp_dir == NULL) {
temp_dir = "/tmp";
}
- char* result = strdup(temp_dir);
+ if (!path.Add(temp_dir)) {
+ return NULL;
+ }
// Remove any trailing slash.
+ char* result = path.AsString();
int length = strlen(result);
- if (length > 1 && result[length - 1] == '/') {
+ if ((length > 1) && (result[length - 1] == '/')) {
result[length - 1] = '\0';
}
- return result;
+ return path.AsScopedString();
}
-char* Directory::CreateTemp(const char* prefix) {
+const char* Directory::CreateTemp(const char* prefix) {
// Returns a new, unused directory name, adding characters to the end
// of prefix. Creates the directory with the permissions specified
// by the process umask.
- // The return value must be freed by the caller.
+ // The return value is Dart_ScopeAllocated.
PathBuffer path;
- path.Add(prefix);
+ if (!path.Add(prefix)) {
+ return NULL;
+ }
if (!path.Add("XXXXXX")) {
// Pattern has overflowed.
return NULL;
@@ -397,18 +431,18 @@
char* result;
do {
result = mkdtemp(path.AsString());
- } while (result == NULL && errno == EINTR);
+ } while ((result == NULL) && (errno == EINTR));
if (result == NULL) {
return NULL;
}
- return strdup(result);
+ return path.AsScopedString();
}
bool Directory::Delete(const char* dir_name, bool recursive) {
if (!recursive) {
- if (File::GetType(dir_name, false) == File::kIsLink &&
- File::GetType(dir_name, true) == File::kIsDirectory) {
+ if ((File::GetType(dir_name, false) == File::kIsLink) &&
+ (File::GetType(dir_name, true) == File::kIsDirectory)) {
return (NO_RETRY_EXPECTED(unlink(dir_name)) == 0);
}
return (NO_RETRY_EXPECTED(rmdir(dir_name)) == 0);
@@ -424,7 +458,9 @@
bool Directory::Rename(const char* path, const char* new_path) {
ExistsResult exists = Exists(path);
- if (exists != EXISTS) return false;
+ if (exists != EXISTS) {
+ return false;
+ }
return (NO_RETRY_EXPECTED(rename(path, new_path)) == 0);
}
diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc
index 40bfb9b..efaaaf9 100644
--- a/runtime/bin/directory_win.cc
+++ b/runtime/bin/directory_win.cc
@@ -13,6 +13,7 @@
#include <errno.h> // NOLINT
#include <sys/stat.h> // NOLINT
+#include "bin/dartutils.h"
#include "bin/log.h"
#undef DeleteFile
@@ -23,24 +24,37 @@
namespace bin {
PathBuffer::PathBuffer() : length_(0) {
- data_ = calloc(MAX_LONG_PATH + 1, sizeof(wchar_t)); // NOLINT
+ data_ = calloc(MAX_LONG_PATH + 1, sizeof(wchar_t)); // NOLINT
}
-char* PathBuffer::AsString() const {
- return StringUtilsWin::WideToUtf8(AsStringW());
+
+PathBuffer::~PathBuffer() {
+ free(data_);
}
+
+char* PathBuffer::AsString() const {
+ UNREACHABLE();
+ return NULL;
+}
+
+
wchar_t* PathBuffer::AsStringW() const {
return reinterpret_cast<wchar_t*>(data_);
}
+
+const char* PathBuffer::AsScopedString() const {
+ return StringUtilsWin::WideToUtf8(AsStringW());
+}
+
+
bool PathBuffer::Add(const char* name) {
const wchar_t* wide_name = StringUtilsWin::Utf8ToWide(name);
- bool success = AddW(wide_name);
- free(const_cast<wchar_t*>(wide_name));
- return success;
+ return AddW(wide_name);
}
+
bool PathBuffer::AddW(const wchar_t* name) {
wchar_t* data = AsStringW();
int written = _snwprintf(data + length_,
@@ -48,9 +62,9 @@
L"%s",
name);
data[MAX_LONG_PATH] = L'\0';
- if (written <= MAX_LONG_PATH - length_ &&
- written >= 0 &&
- static_cast<size_t>(written) == wcsnlen(name, MAX_LONG_PATH + 1)) {
+ if ((written <= MAX_LONG_PATH - length_) &&
+ (written >= 0) &&
+ (static_cast<size_t>(written) == wcsnlen(name, MAX_LONG_PATH + 1))) {
length_ += written;
return true;
} else {
@@ -59,11 +73,13 @@
}
}
-void PathBuffer::Reset(int new_length) {
+
+void PathBuffer::Reset(intptr_t new_length) {
length_ = new_length;
AsStringW()[length_] = L'\0';
}
+
// If link_name points to a link, IsBrokenLink will return true if link_name
// points to an invalid target.
static bool IsBrokenLink(const wchar_t* link_name) {
@@ -83,6 +99,7 @@
}
}
+
// A linked list structure holding a link target's unique file system ID.
// Used to detect loops in the file system when listing recursively.
struct LinkList {
@@ -98,7 +115,7 @@
static ListType HandleFindFile(DirectoryListing* listing,
DirectoryListingEntry* entry,
- WIN32_FIND_DATAW& find_file_data) {
+ const WIN32_FIND_DATAW& find_file_data) {
if (!listing->path_buffer().AddW(find_file_data.cFileName)) {
return kListError;
}
@@ -137,17 +154,17 @@
current_link.next = entry->link();
LinkList* previous = entry->link();
while (previous != NULL) {
- if (previous->volume == current_link.volume &&
- previous->id_low == current_link.id_low &&
- previous->id_high == current_link.id_high) {
+ if ((previous->volume == current_link.volume) &&
+ (previous->id_low == current_link.id_low) &&
+ (previous->id_high == current_link.id_high)) {
// Report the looping link as a link, rather than following it.
return kListLink;
}
previous = previous->next;
}
// Recurse into the directory, adding current link to the seen links list.
- if (wcscmp(find_file_data.cFileName, L".") == 0 ||
- wcscmp(find_file_data.cFileName, L"..") == 0) {
+ if ((wcscmp(find_file_data.cFileName, L".") == 0) ||
+ (wcscmp(find_file_data.cFileName, L"..") == 0)) {
return entry->Next(listing);
}
entry->set_link(new LinkList(current_link));
@@ -155,8 +172,8 @@
}
}
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
- if (wcscmp(find_file_data.cFileName, L".") == 0 ||
- wcscmp(find_file_data.cFileName, L"..") == 0) {
+ if ((wcscmp(find_file_data.cFileName, L".") == 0) ||
+ (wcscmp(find_file_data.cFileName, L"..") == 0)) {
return entry->Next(listing);
}
return kListDirectory;
@@ -165,6 +182,7 @@
}
}
+
ListType DirectoryListingEntry::Next(DirectoryListing* listing) {
if (done_) {
return kListDone;
@@ -223,7 +241,7 @@
void DirectoryListingEntry::ResetLink() {
- if (link_ != NULL && (parent_ == NULL || parent_->link_ != link_)) {
+ if ((link_ != NULL) && ((parent_ == NULL) || (parent_->link_ != link_))) {
delete link_;
link_ = NULL;
}
@@ -234,7 +252,9 @@
static bool DeleteFile(wchar_t* file_name, PathBuffer* path) {
- if (!path->AddW(file_name)) return false;
+ if (!path->AddW(file_name)) {
+ return false;
+ }
if (DeleteFileW(path->AsStringW()) != 0) {
return true;
@@ -265,8 +285,10 @@
static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) {
- if (wcscmp(dir_name, L".") == 0) return true;
- if (wcscmp(dir_name, L"..") == 0) return true;
+ if ((wcscmp(dir_name, L".") == 0) ||
+ (wcscmp(dir_name, L"..") == 0)) {
+ return true;
+ }
return path->AddW(dir_name) && DeleteRecursively(path);
}
@@ -284,7 +306,7 @@
static bool DeleteRecursively(PathBuffer* path) {
DWORD attributes = GetFileAttributesW(path->AsStringW());
- if ((attributes == INVALID_FILE_ATTRIBUTES)) {
+ if (attributes == INVALID_FILE_ATTRIBUTES) {
return false;
}
// If the directory is a junction, it's pointing to some other place in the
@@ -298,7 +320,9 @@
return DeleteFile(L"", path);
}
- if (!path->AddW(L"\\*")) return false;
+ if (!path->AddW(L"\\*")) {
+ return false;
+ }
WIN32_FIND_DATAW find_file_data;
HANDLE find_handle = FindFirstFileW(path->AsStringW(), &find_file_data);
@@ -336,8 +360,8 @@
DWORD attributes = GetFileAttributesW(dir_name);
if (attributes == INVALID_FILE_ATTRIBUTES) {
DWORD last_error = GetLastError();
- if (last_error == ERROR_FILE_NOT_FOUND ||
- last_error == ERROR_PATH_NOT_FOUND) {
+ if ((last_error == ERROR_FILE_NOT_FOUND) ||
+ (last_error == ERROR_PATH_NOT_FOUND)) {
return Directory::DOES_NOT_EXIST;
} else {
// We might not be able to get the file attributes for other
@@ -354,27 +378,42 @@
Directory::ExistsResult Directory::Exists(const char* dir_name) {
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(dir_name);
- Directory::ExistsResult result = ExistsHelper(system_name);
- free(const_cast<wchar_t*>(system_name));
+ return ExistsHelper(system_name);
+}
+
+
+char* Directory::CurrentNoScope() {
+ int length = GetCurrentDirectoryW(0, NULL);
+ if (length == 0) {
+ return NULL;
+ }
+ wchar_t* current = new wchar_t[length + 1];
+ GetCurrentDirectoryW(length + 1, current);
+ int utf8_len = WideCharToMultiByte(
+ CP_UTF8, 0, current, -1, NULL, 0, NULL, NULL);
+ char* result = reinterpret_cast<char*>(malloc(utf8_len));
+ WideCharToMultiByte(CP_UTF8, 0, current, -1, result, utf8_len, NULL, NULL);
+ delete[] current;
return result;
}
-char* Directory::Current() {
+const char* Directory::Current() {
int length = GetCurrentDirectoryW(0, NULL);
- if (length == 0) return NULL;
- wchar_t* current = new wchar_t[length + 1];
+ if (length == 0) {
+ return NULL;
+ }
+ wchar_t* current;
+ current = reinterpret_cast<wchar_t*>(
+ Dart_ScopeAllocate((length + 1) * sizeof(*current)));
GetCurrentDirectoryW(length + 1, current);
- char* result = StringUtilsWin::WideToUtf8(current);
- delete[] current;
- return result;
+ return StringUtilsWin::WideToUtf8(current);
}
bool Directory::SetCurrent(const char* path) {
const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path);
bool result = SetCurrentDirectoryW(system_path) != 0;
- free(const_cast<wchar_t*>(system_path));
return result;
}
@@ -383,35 +422,34 @@
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(dir_name);
int create_status = CreateDirectoryW(system_name, NULL);
// If the directory already existed, treat it as a success.
- if (create_status == 0 &&
- GetLastError() == ERROR_ALREADY_EXISTS &&
- ExistsHelper(system_name) == EXISTS) {
- free(const_cast<wchar_t*>(system_name));
+ if ((create_status == 0) &&
+ (GetLastError() == ERROR_ALREADY_EXISTS) &&
+ (ExistsHelper(system_name) == EXISTS)) {
return true;
}
- free(const_cast<wchar_t*>(system_name));
return (create_status != 0);
}
-char* Directory::SystemTemp() {
+const char* Directory::SystemTemp() {
PathBuffer path;
// Remove \ at end.
path.Reset(GetTempPathW(MAX_LONG_PATH, path.AsStringW()) - 1);
- return path.AsString();
+ return path.AsScopedString();
}
-char* Directory::CreateTemp(const char* prefix) {
+const char* Directory::CreateTemp(const char* prefix) {
// Returns a new, unused directory name, adding characters to the
// end of prefix.
// Creates this directory, with a default security
// descriptor inherited from its parent directory.
- // The return value must be freed by the caller.
+ // The return value is Dart_ScopeAllocated.
PathBuffer path;
const wchar_t* system_prefix = StringUtilsWin::Utf8ToWide(prefix);
- path.AddW(system_prefix);
- free(const_cast<wchar_t*>(system_prefix));
+ if (!path.AddW(system_prefix)) {
+ return NULL;
+ }
// Length of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 36.
if (path.length() > MAX_LONG_PATH - 36) {
@@ -420,7 +458,7 @@
UUID uuid;
RPC_STATUS status = UuidCreateSequential(&uuid);
- if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) {
+ if ((status != RPC_S_OK) && (status != RPC_S_UUID_LOCAL_ONLY)) {
return NULL;
}
RPC_WSTR uuid_string;
@@ -430,13 +468,14 @@
}
// RPC_WSTR is an unsigned short*, so we cast to wchar_t*.
- path.AddW(reinterpret_cast<wchar_t*>(uuid_string));
+ if (!path.AddW(reinterpret_cast<wchar_t*>(uuid_string))) {
+ return NULL;
+ }
RpcStringFreeW(&uuid_string);
if (!CreateDirectoryW(path.AsStringW(), NULL)) {
return NULL;
}
- char* result = path.AsString();
- return result;
+ return path.AsScopedString();
}
@@ -455,7 +494,6 @@
result = DeleteRecursively(&path);
}
}
- free(const_cast<wchar_t*>(system_dir_name));
return result;
}
@@ -464,20 +502,22 @@
const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path);
const wchar_t* system_new_path = StringUtilsWin::Utf8ToWide(new_path);
ExistsResult exists = ExistsHelper(system_path);
- if (exists != EXISTS) return false;
+ if (exists != EXISTS) {
+ return false;
+ }
ExistsResult new_exists = ExistsHelper(system_new_path);
// MoveFile does not allow replacing exising directories. Therefore,
// if the new_path is currently a directory we need to delete it
// first.
if (new_exists == EXISTS) {
bool success = Delete(new_path, true);
- if (!success) return false;
+ if (!success) {
+ return false;
+ }
}
DWORD flags = MOVEFILE_WRITE_THROUGH;
int move_status =
MoveFileExW(system_path, system_new_path, flags);
- free(const_cast<wchar_t*>(system_path));
- free(const_cast<wchar_t*>(system_new_path));
return (move_status != 0);
}
diff --git a/runtime/bin/fdutils_android.cc b/runtime/bin/fdutils_android.cc
index ba28199..83e4913 100644
--- a/runtime/bin/fdutils_android.cc
+++ b/runtime/bin/fdutils_android.cc
@@ -11,7 +11,6 @@
#include <sys/ioctl.h> // NOLINT
#include "bin/fdutils.h"
-
#include "platform/signal_blocker.h"
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index a1efe42..7cc3e71 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -24,7 +24,6 @@
// Are we capturing output from stderr for the VM service?
static bool capture_stderr = false;
-
void SetCaptureStdout(bool value) {
capture_stdout = value;
}
@@ -45,7 +44,6 @@
}
-
// The file pointer has been passed into Dart as an intptr_t and it is safe
// to pull it out of Dart as a 64-bit integer, cast it to an intptr_t and
// from there to a File pointer.
@@ -83,11 +81,11 @@
}
if (capture_stdout || capture_stderr) {
intptr_t fd = GetFD();
- if (fd == STDOUT_FILENO && capture_stdout) {
+ if ((fd == STDOUT_FILENO) && capture_stdout) {
Dart_ServiceSendDataEvent("Stdout", "WriteEvent",
reinterpret_cast<const uint8_t*>(buffer),
num_bytes);
- } else if (fd == STDERR_FILENO && capture_stderr) {
+ } else if ((fd == STDERR_FILENO) && capture_stderr) {
Dart_ServiceSendDataEvent("Stderr", "WriteEvent",
reinterpret_cast<const uint8_t*>(buffer),
num_bytes);
@@ -98,11 +96,11 @@
File::FileOpenMode File::DartModeToFileMode(DartFileOpenMode mode) {
- ASSERT(mode == File::kDartRead ||
- mode == File::kDartWrite ||
- mode == File::kDartAppend ||
- mode == File::kDartWriteOnly ||
- mode == File::kDartWriteOnlyAppend);
+ ASSERT((mode == File::kDartRead) ||
+ (mode == File::kDartWrite) ||
+ (mode == File::kDartAppend) ||
+ (mode == File::kDartWriteOnly) ||
+ (mode == File::kDartWriteOnlyAppend));
if (mode == File::kDartWrite) {
return File::kWriteTruncate;
}
@@ -131,7 +129,7 @@
// files. Directories can be opened for reading using the posix
// 'open' call.
File* file = NULL;
- file = File::Open(filename, file_mode);
+ file = File::ScopedOpen(filename, file_mode);
if (file != NULL) {
Dart_SetReturnValue(args,
Dart_NewInteger(reinterpret_cast<intptr_t>(file)));
@@ -219,7 +217,9 @@
// TODO(sgjesse): Cache the _makeUint8ListView function somewhere.
Dart_Handle io_lib =
Dart_LookupLibrary(DartUtils::NewString("dart:io"));
- if (Dart_IsError(io_lib)) Dart_PropagateError(io_lib);
+ if (Dart_IsError(io_lib)) {
+ Dart_PropagateError(io_lib);
+ }
Dart_Handle array_view =
Dart_Invoke(io_lib,
DartUtils::NewString("_makeUint8ListView"),
@@ -253,9 +253,11 @@
intptr_t length = end - start;
intptr_t array_len = 0;
Dart_Handle result = Dart_ListLength(buffer_obj, &array_len);
- if (Dart_IsError(result)) Dart_PropagateError(result);
+ if (Dart_IsError(result)) {
+ Dart_PropagateError(result);
+ }
ASSERT(end <= array_len);
- uint8_t* buffer = new uint8_t[length];
+ uint8_t* buffer = Dart_ScopeAllocate(length);
int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length);
if (bytes_read >= 0) {
result = Dart_ListSetAsBytes(buffer_obj, start, buffer, bytes_read);
@@ -267,7 +269,6 @@
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
}
- delete[] buffer;
}
@@ -294,7 +295,9 @@
void* buffer = NULL;
Dart_Handle result =
Dart_TypedDataAcquireData(buffer_obj, &type, &buffer, &buffer_len);
- if (Dart_IsError(result)) Dart_PropagateError(result);
+ if (Dart_IsError(result)) {
+ Dart_PropagateError(result);
+ }
ASSERT(type == Dart_TypedData_kUint8 || type == Dart_TypedData_kInt8);
ASSERT(end <= buffer_len);
@@ -305,7 +308,9 @@
// Release the direct pointer acquired above.
result = Dart_TypedDataReleaseData(buffer_obj);
- if (Dart_IsError(result)) Dart_PropagateError(result);
+ if (Dart_IsError(result)) {
+ Dart_PropagateError(result);
+ }
if (!success) {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
@@ -466,12 +471,11 @@
if (Dart_IsString(Dart_GetNativeArgument(args, 0))) {
const char* name =
DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
- char* target = File::LinkTarget(name);
+ const char* target = File::LinkTarget(name);
if (target == NULL) {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
} else {
Dart_SetReturnValue(args, DartUtils::NewString(target));
- free(target);
}
} else {
Dart_Handle err = DartUtils::NewDartArgumentError(
@@ -550,10 +554,9 @@
void FUNCTION_NAME(File_ResolveSymbolicLinks)(Dart_NativeArguments args) {
const char* str =
DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
- char* path = File::GetCanonicalPath(str);
+ const char* path = File::GetCanonicalPath(str);
if (path != NULL) {
Dart_SetReturnValue(args, DartUtils::NewString(path));
- free(path);
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
}
@@ -605,7 +608,9 @@
} else {
Dart_Handle returned_data = Dart_NewTypedData(Dart_TypedData_kInt64,
File::kStatSize);
- if (Dart_IsError(returned_data)) Dart_PropagateError(returned_data);
+ if (Dart_IsError(returned_data)) {
+ Dart_PropagateError(returned_data);
+ }
Dart_TypedData_Type data_type_unused;
void* data_location;
intptr_t data_length_unused;
@@ -613,10 +618,14 @@
&data_type_unused,
&data_location,
&data_length_unused);
- if (Dart_IsError(status)) Dart_PropagateError(status);
+ if (Dart_IsError(status)) {
+ Dart_PropagateError(status);
+ }
memmove(data_location, stat_data, File::kStatSize * sizeof(int64_t));
status = Dart_TypedDataReleaseData(returned_data);
- if (Dart_IsError(status)) Dart_PropagateError(status);
+ if (Dart_IsError(status)) {
+ Dart_PropagateError(status);
+ }
Dart_SetReturnValue(args, returned_data);
}
} else {
@@ -669,7 +678,7 @@
CObject* File::ExistsRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsString()) {
+ if ((request.Length() == 1) && request[0]->IsString()) {
CObjectString filename(request[0]);
bool result = File::Exists(filename.CString());
return CObject::Bool(result);
@@ -679,7 +688,7 @@
CObject* File::CreateRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsString()) {
+ if ((request.Length() == 1) && request[0]->IsString()) {
CObjectString filename(request[0]);
bool result = File::Create(filename.CString());
if (result) {
@@ -691,9 +700,10 @@
return CObject::IllegalArgumentError();
}
+
CObject* File::OpenRequest(const CObjectArray& request) {
File* file = NULL;
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsString() &&
request[1]->IsInt32()) {
CObjectString filename(request[0]);
@@ -701,7 +711,7 @@
File::DartFileOpenMode dart_file_mode =
static_cast<File::DartFileOpenMode>(mode.Value());
File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode);
- file = File::Open(filename.CString(), file_mode);
+ file = File::ScopedOpen(filename.CString(), file_mode);
if (file != NULL) {
return new CObjectIntptr(
CObject::NewIntptr(reinterpret_cast<intptr_t>(file)));
@@ -714,7 +724,7 @@
CObject* File::DeleteRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsString()) {
+ if ((request.Length() == 1) && request[0]->IsString()) {
CObjectString filename(request[0]);
bool result = File::Delete(filename.CString());
if (result) {
@@ -728,13 +738,15 @@
CObject* File::RenameRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsString() &&
request[1]->IsString()) {
CObjectString old_path(request[0]);
CObjectString new_path(request[1]);
bool completed = File::Rename(old_path.CString(), new_path.CString());
- if (completed) return CObject::True();
+ if (completed) {
+ return CObject::True();
+ }
return CObject::NewOSError();
}
return CObject::IllegalArgumentError();
@@ -742,13 +754,15 @@
CObject* File::CopyRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsString() &&
request[1]->IsString()) {
CObjectString old_path(request[0]);
CObjectString new_path(request[1]);
bool completed = File::Copy(old_path.CString(), new_path.CString());
- if (completed) return CObject::True();
+ if (completed) {
+ return CObject::True();
+ }
return CObject::NewOSError();
}
return CObject::IllegalArgumentError();
@@ -756,12 +770,11 @@
CObject* File::ResolveSymbolicLinksRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsString()) {
+ if ((request.Length() == 1) && request[0]->IsString()) {
CObjectString filename(request[0]);
- char* result = File::GetCanonicalPath(filename.CString());
+ const char* result = File::GetCanonicalPath(filename.CString());
if (result != NULL) {
CObject* path = new CObjectString(CObject::NewString(result));
- free(result);
return path;
} else {
return CObject::NewOSError();
@@ -773,7 +786,7 @@
CObject* File::CloseRequest(const CObjectArray& request) {
intptr_t return_value = -1;
- if (request.Length() == 1 && request[0]->IsIntptr()) {
+ if ((request.Length() == 1) && request[0]->IsIntptr()) {
File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
delete file;
@@ -784,7 +797,7 @@
CObject* File::PositionRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsIntptr()) {
+ if ((request.Length() == 1) && request[0]->IsIntptr()) {
File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
@@ -803,7 +816,7 @@
CObject* File::SetPositionRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsIntptr() &&
request[1]->IsInt32OrInt64()) {
File* file = CObjectToFilePointer(request[0]);
@@ -824,7 +837,7 @@
CObject* File::TruncateRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsIntptr() &&
request[1]->IsInt32OrInt64()) {
File* file = CObjectToFilePointer(request[0]);
@@ -845,7 +858,7 @@
CObject* File::LengthRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsIntptr()) {
+ if ((request.Length() == 1) && request[0]->IsIntptr()) {
File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
@@ -864,7 +877,7 @@
CObject* File::LengthFromPathRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsString()) {
+ if ((request.Length() == 1) && request[0]->IsString()) {
CObjectString filepath(request[0]);
int64_t return_value = File::LengthFromPath(filepath.CString());
if (return_value >= 0) {
@@ -878,7 +891,7 @@
CObject* File::LastModifiedRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsString()) {
+ if ((request.Length() == 1) && request[0]->IsString()) {
CObjectString filepath(request[0]);
int64_t return_value = File::LastModified(filepath.CString());
if (return_value >= 0) {
@@ -892,7 +905,7 @@
CObject* File::FlushRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsIntptr()) {
+ if ((request.Length() == 1) && request[0]->IsIntptr()) {
File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
@@ -910,7 +923,7 @@
CObject* File::ReadByteRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsIntptr()) {
+ if ((request.Length() == 1) && request[0]->IsIntptr()) {
File* file = CObjectToFilePointer(request[0]);
ASSERT(file != NULL);
if (!file->IsClosed()) {
@@ -932,7 +945,7 @@
CObject* File::WriteByteRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsIntptr() &&
request[1]->IsInt32OrInt64()) {
File* file = CObjectToFilePointer(request[0]);
@@ -955,7 +968,7 @@
CObject* File::ReadRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsIntptr() &&
request[1]->IsInt32OrInt64()) {
File* file = CObjectToFilePointer(request[0]);
@@ -987,7 +1000,7 @@
CObject* File::ReadIntoRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsIntptr() &&
request[1]->IsInt32OrInt64()) {
File* file = CObjectToFilePointer(request[0]);
@@ -1045,7 +1058,7 @@
CObject* File::WriteFromRequest(const CObjectArray& request) {
- if (request.Length() == 4 &&
+ if ((request.Length() == 4) &&
request[0]->IsIntptr() &&
(request[1]->IsTypedData() || request[1]->IsArray()) &&
request[2]->IsInt32OrInt64() &&
@@ -1064,14 +1077,13 @@
buffer_start = typed_data.Buffer() + start;
} else {
CObjectArray array(request[1]);
- buffer_start = new uint8_t[length];
+ buffer_start = Dart_ScopeAllocate(length);
for (int i = 0; i < length; i++) {
if (array[i + start]->IsInt32OrInt64()) {
int64_t value = CObjectInt32OrInt64ToInt64(array[i + start]);
buffer_start[i] = static_cast<uint8_t>(value & 0xFF);
} else {
// Unsupported type.
- delete[] buffer_start;
return CObject::IllegalArgumentError();
}
}
@@ -1079,9 +1091,6 @@
}
bool success =
file->WriteFully(reinterpret_cast<void*>(buffer_start), length);
- if (!request[1]->IsTypedData()) {
- delete[] buffer_start;
- }
if (success) {
return new CObjectInt64(CObject::NewInt64(length));
} else {
@@ -1096,7 +1105,7 @@
CObject* File::CreateLinkRequest(const CObjectArray& request) {
- if (request.Length() != 2 ||
+ if ((request.Length() != 2) ||
!request[0]->IsString() ||
!request[1]->IsString()) {
return CObject::IllegalArgumentError();
@@ -1112,7 +1121,7 @@
CObject* File::DeleteLinkRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsString()) {
+ if ((request.Length() == 1) && request[0]->IsString()) {
CObjectString link_path(request[0]);
bool result = File::DeleteLink(link_path.CString());
if (result) {
@@ -1126,13 +1135,15 @@
CObject* File::RenameLinkRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsString() &&
request[1]->IsString()) {
CObjectString old_path(request[0]);
CObjectString new_path(request[1]);
bool completed = File::RenameLink(old_path.CString(), new_path.CString());
- if (completed) return CObject::True();
+ if (completed) {
+ return CObject::True();
+ }
return CObject::NewOSError();
}
return CObject::IllegalArgumentError();
@@ -1140,12 +1151,11 @@
CObject* File::LinkTargetRequest(const CObjectArray& request) {
- if (request.Length() == 1 && request[0]->IsString()) {
+ if ((request.Length() == 1) && request[0]->IsString()) {
CObjectString link_path(request[0]);
- char* target = File::LinkTarget(link_path.CString());
+ const char* target = File::LinkTarget(link_path.CString());
if (target != NULL) {
CObject* result = new CObjectString(CObject::NewString(target));
- free(target);
return result;
} else {
return CObject::NewOSError();
@@ -1156,7 +1166,7 @@
CObject* File::TypeRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsString() &&
request[1]->IsBool()) {
CObjectString path(request[0]);
@@ -1169,7 +1179,7 @@
CObject* File::IdenticalRequest(const CObjectArray& request) {
- if (request.Length() == 2 &&
+ if ((request.Length() == 2) &&
request[0]->IsString() &&
request[1]->IsString()) {
CObjectString path1(request[0]);
@@ -1189,8 +1199,7 @@
CObject* File::StatRequest(const CObjectArray& request) {
- if (request.Length() == 1 &&
- request[0]->IsString()) {
+ if ((request.Length() == 1) && request[0]->IsString()) {
int64_t data[File::kStatSize];
CObjectString path(request[0]);
File::Stat(path.CString(), data);
@@ -1212,7 +1221,7 @@
CObject* File::LockRequest(const CObjectArray& request) {
- if (request.Length() == 4 &&
+ if ((request.Length() == 4) &&
request[0]->IsIntptr() &&
request[1]->IsInt32OrInt64() &&
request[2]->IsInt32OrInt64() &&
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 633c006..315ebbe 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -13,7 +13,6 @@
#include "bin/builtin.h"
#include "bin/dartutils.h"
-
namespace dart {
namespace bin {
@@ -129,7 +128,10 @@
// reading. If mode contains kWrite the file is opened for both
// reading and writing. If mode contains kWrite and the file does
// not exist the file is created. The file is truncated to length 0 if
- // mode contains kTruncate.
+ // mode contains kTruncate. Assumes we are in an API scope.
+ static File* ScopedOpen(const char* path, FileOpenMode mode);
+
+ // Like ScopedOpen(), but no API scope is needed.
static File* Open(const char* path, FileOpenMode mode);
// Create a file object for the specified stdio file descriptor
@@ -147,9 +149,9 @@
static int64_t LengthFromPath(const char* path);
static void Stat(const char* path, int64_t* data);
static time_t LastModified(const char* path);
- static char* LinkTarget(const char* pathname);
+ static const char* LinkTarget(const char* pathname);
static bool IsAbsolutePath(const char* path);
- static char* GetCanonicalPath(const char* path);
+ static const char* GetCanonicalPath(const char* path);
static const char* PathSeparator();
static const char* StringEscapedPathSeparator();
static Type GetType(const char* path, bool follow_links);
@@ -191,6 +193,8 @@
explicit File(FileHandle* handle) : handle_(handle) { }
void Close();
+ static File* FileOpenW(const wchar_t* system_name, FileOpenMode mode);
+
static const int kClosedFd = -1;
// FileHandle is an OS specific class which stores data about the file.
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index cc29740..c672914 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -148,7 +148,13 @@
}
-File* File::Open(const char* name, FileOpenMode mode) {
+File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) {
+ UNREACHABLE();
+ return NULL;
+}
+
+
+File* File::ScopedOpen(const char* name, FileOpenMode mode) {
// Report errors for non-regular files.
struct stat st;
if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
@@ -185,8 +191,16 @@
}
+File* File::Open(const char* path, FileOpenMode mode) {
+ // ScopedOpen doesn't actually need a scope.
+ return ScopedOpen(path, mode);
+}
+
+
File* File::OpenStdio(int fd) {
- if (fd < 0 || 2 < fd) return NULL;
+ if ((fd < 0) || (2 < fd)) {
+ return NULL;
+ }
return new File(new FileHandle(fd));
}
@@ -292,7 +306,7 @@
// From sendfile man pages:
// Applications may wish to fall back to read(2)/write(2) in the case
// where sendfile() fails with EINVAL or ENOSYS.
- if (result < 0 && (errno == EINVAL || errno == ENOSYS)) {
+ if ((result < 0) && ((errno == EINVAL) || (errno == ENOSYS))) {
const intptr_t kBufferSize = 8 * KB;
uint8_t buffer[kBufferSize];
while ((result = TEMP_FAILURE_RETRY(
@@ -363,18 +377,20 @@
}
-char* File::LinkTarget(const char* pathname) {
+const char* File::LinkTarget(const char* pathname) {
struct stat link_stats;
- if (lstat(pathname, &link_stats) != 0) return NULL;
+ if (lstat(pathname, &link_stats) != 0) {
+ return NULL;
+ }
if (!S_ISLNK(link_stats.st_mode)) {
errno = ENOENT;
return NULL;
}
size_t target_size = link_stats.st_size;
- char* target_name = reinterpret_cast<char*>(malloc(target_size + 1));
+ char* target_name = DartUtils::ScopedCString(target_size + 1);
+ ASSERT(target_name != NULL);
size_t read_size = readlink(pathname, target_name, target_size + 1);
if (read_size != target_size) {
- free(target_name);
return NULL;
}
target_name[target_size] = '\0';
@@ -387,20 +403,16 @@
}
-char* File::GetCanonicalPath(const char* pathname) {
+const char* File::GetCanonicalPath(const char* pathname) {
char* abs_path = NULL;
if (pathname != NULL) {
- // A null second argument to realpath crashes Android. Fixed in Mar 2013,
- // but not in earlier releases of Android.
- char* resolved = reinterpret_cast<char*>(malloc(PATH_MAX));
- if (resolved == NULL) return NULL;
+ char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1);
+ ASSERT(resolved_path != NULL);
do {
- abs_path = realpath(pathname, resolved);
- } while (abs_path == NULL && errno == EINTR);
- ASSERT(abs_path == NULL || IsAbsolutePath(abs_path));
- if (abs_path != resolved) {
- free(resolved);
- }
+ abs_path = realpath(pathname, resolved_path);
+ } while ((abs_path == NULL) && (errno == EINTR));
+ ASSERT((abs_path == NULL) || IsAbsolutePath(abs_path));
+ ASSERT((abs_path == NULL) || (abs_path == resolved_path));
}
return abs_path;
}
@@ -417,7 +429,7 @@
File::StdioHandleType File::GetStdioHandleType(int fd) {
- ASSERT(0 <= fd && fd <= 2);
+ ASSERT((0 <= fd) && (fd <= 2));
struct stat buf;
int result = fstat(fd, &buf);
if (result == -1) {
@@ -426,10 +438,18 @@
Utils::StrError(errno, error_message, kBufferSize);
FATAL2("Failed stat on file descriptor %d: %s", fd, error_message);
}
- if (S_ISCHR(buf.st_mode)) return kTerminal;
- if (S_ISFIFO(buf.st_mode)) return kPipe;
- if (S_ISSOCK(buf.st_mode)) return kSocket;
- if (S_ISREG(buf.st_mode)) return kFile;
+ if (S_ISCHR(buf.st_mode)) {
+ return kTerminal;
+ }
+ if (S_ISFIFO(buf.st_mode)) {
+ return kPipe;
+ }
+ if (S_ISSOCK(buf.st_mode)) {
+ return kSocket;
+ }
+ if (S_ISREG(buf.st_mode)) {
+ return kFile;
+ }
return kOther;
}
@@ -442,10 +462,18 @@
} else {
stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info));
}
- if (stat_success == -1) return File::kDoesNotExist;
- if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory;
- if (S_ISREG(entry_info.st_mode)) return File::kIsFile;
- if (S_ISLNK(entry_info.st_mode)) return File::kIsLink;
+ if (stat_success == -1) {
+ return File::kDoesNotExist;
+ }
+ if (S_ISDIR(entry_info.st_mode)) {
+ return File::kIsDirectory;
+ }
+ if (S_ISREG(entry_info.st_mode)) {
+ return File::kIsFile;
+ }
+ if (S_ISLNK(entry_info.st_mode)) {
+ return File::kIsLink;
+ }
return File::kDoesNotExist;
}
@@ -453,12 +481,12 @@
File::Identical File::AreIdentical(const char* file_1, const char* file_2) {
struct stat file_1_info;
struct stat file_2_info;
- if (NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1 ||
- NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1) {
+ if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) ||
+ (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) {
return File::kError;
}
- return (file_1_info.st_ino == file_2_info.st_ino &&
- file_1_info.st_dev == file_2_info.st_dev) ?
+ return ((file_1_info.st_ino == file_2_info.st_ino) &&
+ (file_1_info.st_dev == file_2_info.st_dev)) ?
File::kIdentical :
File::kDifferent;
}
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index d289c21..495dacd 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -20,7 +20,6 @@
#include "platform/signal_blocker.h"
#include "platform/utils.h"
-
namespace dart {
namespace bin {
@@ -112,7 +111,7 @@
bool File::Lock(File::LockType lock, int64_t start, int64_t end) {
ASSERT(handle_->fd() >= 0);
- ASSERT(end == -1 || end > start);
+ ASSERT((end == -1) || (end > start));
struct flock fl;
switch (lock) {
case File::kLockUnlock:
@@ -146,7 +145,13 @@
}
-File* File::Open(const char* name, FileOpenMode mode) {
+File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) {
+ UNREACHABLE();
+ return NULL;
+}
+
+
+File* File::ScopedOpen(const char* name, FileOpenMode mode) {
// Report errors for non-regular files.
struct stat64 st;
if (TEMP_FAILURE_RETRY(stat64(name, &st)) == 0) {
@@ -184,8 +189,16 @@
}
+File* File::Open(const char* path, FileOpenMode mode) {
+ // ScopedOpen doesn't actually need a scope.
+ return ScopedOpen(path, mode);
+}
+
+
File* File::OpenStdio(int fd) {
- if (fd < 0 || 2 < fd) return NULL;
+ if ((fd < 0) || (2 < fd)) {
+ return NULL;
+ }
return new File(new FileHandle(fd));
}
@@ -291,7 +304,7 @@
// From sendfile man pages:
// Applications may wish to fall back to read(2)/write(2) in the case
// where sendfile() fails with EINVAL or ENOSYS.
- if (result < 0 && (errno == EINVAL || errno == ENOSYS)) {
+ if ((result < 0) && ((errno == EINVAL) || (errno == ENOSYS))) {
const intptr_t kBufferSize = 8 * KB;
uint8_t buffer[kBufferSize];
while ((result = TEMP_FAILURE_RETRY(
@@ -368,9 +381,11 @@
}
-char* File::LinkTarget(const char* pathname) {
+const char* File::LinkTarget(const char* pathname) {
struct stat64 link_stats;
- if (TEMP_FAILURE_RETRY(lstat64(pathname, &link_stats)) != 0) return NULL;
+ if (TEMP_FAILURE_RETRY(lstat64(pathname, &link_stats)) != 0) {
+ return NULL;
+ }
if (!S_ISLNK(link_stats.st_mode)) {
errno = ENOENT;
return NULL;
@@ -385,10 +400,8 @@
if (target_size <= 0) {
return NULL;
}
- char* target_name = reinterpret_cast<char*>(malloc(target_size + 1));
- if (target_name == NULL) {
- return NULL;
- }
+ char* target_name = DartUtils::ScopedCString(target_size + 1);
+ ASSERT(target_name != NULL);
memmove(target_name, target, target_size);
target_name[target_size] = '\0';
return target_name;
@@ -400,13 +413,16 @@
}
-char* File::GetCanonicalPath(const char* pathname) {
+const char* File::GetCanonicalPath(const char* pathname) {
char* abs_path = NULL;
if (pathname != NULL) {
+ char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1);
+ ASSERT(resolved_path != NULL);
do {
- abs_path = realpath(pathname, NULL);
+ abs_path = realpath(pathname, resolved_path);
} while (abs_path == NULL && errno == EINTR);
ASSERT(abs_path == NULL || IsAbsolutePath(abs_path));
+ ASSERT(abs_path == NULL || (abs_path == resolved_path));
}
return abs_path;
}
@@ -423,7 +439,7 @@
File::StdioHandleType File::GetStdioHandleType(int fd) {
- ASSERT(0 <= fd && fd <= 2);
+ ASSERT((0 <= fd) && (fd <= 2));
struct stat64 buf;
int result = TEMP_FAILURE_RETRY(fstat64(fd, &buf));
if (result == -1) {
@@ -432,10 +448,18 @@
FATAL2("Failed stat on file descriptor %d: %s", fd,
Utils::StrError(errno, error_buf, kBufferSize));
}
- if (S_ISCHR(buf.st_mode)) return kTerminal;
- if (S_ISFIFO(buf.st_mode)) return kPipe;
- if (S_ISSOCK(buf.st_mode)) return kSocket;
- if (S_ISREG(buf.st_mode)) return kFile;
+ if (S_ISCHR(buf.st_mode)) {
+ return kTerminal;
+ }
+ if (S_ISFIFO(buf.st_mode)) {
+ return kPipe;
+ }
+ if (S_ISSOCK(buf.st_mode)) {
+ return kSocket;
+ }
+ if (S_ISREG(buf.st_mode)) {
+ return kFile;
+ }
return kOther;
}
@@ -448,10 +472,18 @@
} else {
stat_success = TEMP_FAILURE_RETRY(lstat64(pathname, &entry_info));
}
- if (stat_success == -1) return File::kDoesNotExist;
- if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory;
- if (S_ISREG(entry_info.st_mode)) return File::kIsFile;
- if (S_ISLNK(entry_info.st_mode)) return File::kIsLink;
+ if (stat_success == -1) {
+ return File::kDoesNotExist;
+ }
+ if (S_ISDIR(entry_info.st_mode)) {
+ return File::kIsDirectory;
+ }
+ if (S_ISREG(entry_info.st_mode)) {
+ return File::kIsFile;
+ }
+ if (S_ISLNK(entry_info.st_mode)) {
+ return File::kIsLink;
+ }
return File::kDoesNotExist;
}
@@ -459,12 +491,12 @@
File::Identical File::AreIdentical(const char* file_1, const char* file_2) {
struct stat64 file_1_info;
struct stat64 file_2_info;
- if (TEMP_FAILURE_RETRY(lstat64(file_1, &file_1_info)) == -1 ||
- TEMP_FAILURE_RETRY(lstat64(file_2, &file_2_info)) == -1) {
+ if ((TEMP_FAILURE_RETRY(lstat64(file_1, &file_1_info)) == -1) ||
+ (TEMP_FAILURE_RETRY(lstat64(file_2, &file_2_info)) == -1)) {
return File::kError;
}
- return (file_1_info.st_ino == file_2_info.st_ino &&
- file_1_info.st_dev == file_2_info.st_dev) ?
+ return ((file_1_info.st_ino == file_2_info.st_ino) &&
+ (file_1_info.st_dev == file_2_info.st_dev)) ?
File::kIdentical :
File::kDifferent;
}
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index 6187e94..1211fad 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -114,7 +114,7 @@
bool File::Lock(File::LockType lock, int64_t start, int64_t end) {
ASSERT(handle_->fd() >= 0);
- ASSERT(end == -1 || end > start);
+ ASSERT((end == -1) || (end > start));
struct flock fl;
switch (lock) {
case File::kLockUnlock:
@@ -148,7 +148,13 @@
}
-File* File::Open(const char* name, FileOpenMode mode) {
+File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) {
+ UNREACHABLE();
+ return NULL;
+}
+
+
+File* File::ScopedOpen(const char* name, FileOpenMode mode) {
// Report errors for non-regular files.
struct stat st;
if (NO_RETRY_EXPECTED(stat(name, &st)) == 0) {
@@ -186,8 +192,16 @@
}
+File* File::Open(const char* path, FileOpenMode mode) {
+ // ScopedOpen doesn't actually need a scope.
+ return ScopedOpen(path, mode);
+}
+
+
File* File::OpenStdio(int fd) {
- if (fd < 0 || 2 < fd) return NULL;
+ if ((fd < 0) || (2 < fd)) {
+ return NULL;
+ }
return new File(new FileHandle(fd));
}
@@ -329,9 +343,11 @@
}
-char* File::LinkTarget(const char* pathname) {
+const char* File::LinkTarget(const char* pathname) {
struct stat link_stats;
- if (lstat(pathname, &link_stats) != 0) return NULL;
+ if (lstat(pathname, &link_stats) != 0) {
+ return NULL;
+ }
if (!S_ISLNK(link_stats.st_mode)) {
errno = ENOENT;
return NULL;
@@ -345,10 +361,8 @@
if (target_size <= 0) {
return NULL;
}
- char* target_name = reinterpret_cast<char*>(malloc(target_size + 1));
- if (target_name == NULL) {
- return NULL;
- }
+ char* target_name = DartUtils::ScopedCString(target_size + 1);
+ ASSERT(target_name != NULL);
memmove(target_name, target, target_size);
target_name[target_size] = '\0';
return target_name;
@@ -360,19 +374,19 @@
}
-char* File::GetCanonicalPath(const char* pathname) {
+const char* File::GetCanonicalPath(const char* pathname) {
char* abs_path = NULL;
if (pathname != NULL) {
// On some older MacOs versions the default behaviour of realpath allocating
// space for the resolved_path when a NULL is passed in does not seem to
- // work, so we explicitly allocate space. The caller is responsible for
- // freeing this space as in a regular realpath call.
- char* resolved_path = reinterpret_cast<char*>(malloc(PATH_MAX + 1));
+ // work, so we explicitly allocate space.
+ char* resolved_path = DartUtils::ScopedCString(PATH_MAX + 1);
ASSERT(resolved_path != NULL);
do {
- abs_path = realpath(pathname, NULL);
- } while (abs_path == NULL && errno == EINTR);
- ASSERT(abs_path == NULL || IsAbsolutePath(abs_path));
+ abs_path = realpath(pathname, resolved_path);
+ } while ((abs_path == NULL) && (errno == EINTR));
+ ASSERT((abs_path == NULL) || IsAbsolutePath(abs_path));
+ ASSERT((abs_path == NULL) || (abs_path == resolved_path));
}
return abs_path;
}
@@ -389,7 +403,7 @@
File::StdioHandleType File::GetStdioHandleType(int fd) {
- ASSERT(0 <= fd && fd <= 2);
+ ASSERT((0 <= fd) && (fd <= 2));
struct stat buf;
int result = fstat(fd, &buf);
if (result == -1) {
@@ -398,10 +412,18 @@
Utils::StrError(errno, error_message, kBufferSize);
FATAL2("Failed stat on file descriptor %d: %s", fd, error_message);
}
- if (S_ISCHR(buf.st_mode)) return kTerminal;
- if (S_ISFIFO(buf.st_mode)) return kPipe;
- if (S_ISSOCK(buf.st_mode)) return kSocket;
- if (S_ISREG(buf.st_mode)) return kFile;
+ if (S_ISCHR(buf.st_mode)) {
+ return kTerminal;
+ }
+ if (S_ISFIFO(buf.st_mode)) {
+ return kPipe;
+ }
+ if (S_ISSOCK(buf.st_mode)) {
+ return kSocket;
+ }
+ if (S_ISREG(buf.st_mode)) {
+ return kFile;
+ }
return kOther;
}
@@ -414,10 +436,18 @@
} else {
stat_success = NO_RETRY_EXPECTED(lstat(pathname, &entry_info));
}
- if (stat_success == -1) return File::kDoesNotExist;
- if (S_ISDIR(entry_info.st_mode)) return File::kIsDirectory;
- if (S_ISREG(entry_info.st_mode)) return File::kIsFile;
- if (S_ISLNK(entry_info.st_mode)) return File::kIsLink;
+ if (stat_success == -1) {
+ return File::kDoesNotExist;
+ }
+ if (S_ISDIR(entry_info.st_mode)) {
+ return File::kIsDirectory;
+ }
+ if (S_ISREG(entry_info.st_mode)) {
+ return File::kIsFile;
+ }
+ if (S_ISLNK(entry_info.st_mode)) {
+ return File::kIsLink;
+ }
return File::kDoesNotExist;
}
@@ -425,12 +455,12 @@
File::Identical File::AreIdentical(const char* file_1, const char* file_2) {
struct stat file_1_info;
struct stat file_2_info;
- if (NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1 ||
- NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1) {
+ if ((NO_RETRY_EXPECTED(lstat(file_1, &file_1_info)) == -1) ||
+ (NO_RETRY_EXPECTED(lstat(file_2, &file_2_info)) == -1)) {
return File::kError;
}
- return (file_1_info.st_ino == file_2_info.st_ino &&
- file_1_info.st_dev == file_2_info.st_dev) ?
+ return ((file_1_info.st_ino == file_2_info.st_ino) &&
+ (file_1_info.st_dev == file_2_info.st_dev)) ?
File::kIdentical :
File::kDifferent;
}
diff --git a/runtime/bin/file_system_watcher_win.cc b/runtime/bin/file_system_watcher_win.cc
index 98642ab..a772c6d 100644
--- a/runtime/bin/file_system_watcher_win.cc
+++ b/runtime/bin/file_system_watcher_win.cc
@@ -49,7 +49,6 @@
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
- free(const_cast<wchar_t*>(name));
if (dir == INVALID_HANDLE_VALUE) {
return -1;
@@ -93,7 +92,7 @@
intptr_t available = dir->Available();
intptr_t max_count = available / kEventSize + 1;
Dart_Handle events = Dart_NewList(max_count);
- uint8_t* buffer = new uint8_t[available];
+ uint8_t* buffer = Dart_ScopeAllocate(available);
intptr_t bytes = dir->Read(buffer, available);
intptr_t offset = 0;
intptr_t i = 0;
@@ -120,7 +119,6 @@
if (e->NextEntryOffset == 0) break;
offset += e->NextEntryOffset;
}
- delete[] buffer;
return events;
}
diff --git a/runtime/bin/file_test.cc b/runtime/bin/file_test.cc
index 20c6bf7..7cc9af3 100644
--- a/runtime/bin/file_test.cc
+++ b/runtime/bin/file_test.cc
@@ -23,7 +23,7 @@
}
-UNIT_TEST_CASE(Read) {
+TEST_CASE(Read) {
const char* kFilename = GetFileName("runtime/bin/file_test.cc");
File* file = File::Open(kFilename, File::kRead);
EXPECT(file != NULL);
@@ -37,7 +37,7 @@
}
-UNIT_TEST_CASE(FileLength) {
+TEST_CASE(FileLength) {
const char* kFilename =
GetFileName("runtime/tests/vm/data/fixed_length_file");
File* file = File::Open(kFilename, File::kRead);
@@ -47,7 +47,7 @@
}
-UNIT_TEST_CASE(FilePosition) {
+TEST_CASE(FilePosition) {
char buf[42];
const char* kFilename =
GetFileName("runtime/tests/vm/data/fixed_length_file");
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index 54cd64d..7c1268f 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -46,7 +46,8 @@
void File::Close() {
ASSERT(handle_->fd() >= 0);
- if (handle_->fd() == _fileno(stdout) || handle_->fd() == _fileno(stderr)) {
+ if ((handle_->fd() == _fileno(stdout)) ||
+ (handle_->fd() == _fileno(stderr))) {
int fd = _open("NUL", _O_WRONLY);
ASSERT(fd >= 0);
_dup2(fd, handle_->fd());
@@ -118,7 +119,9 @@
overlapped.OffsetHigh = Utils::High32Bits(start);
int64_t length = end == -1 ? 0 : end - start;
- if (length == 0) length = kMaxInt64;
+ if (length == 0) {
+ length = kMaxInt64;
+ }
int32_t length_low = Utils::Low32Bits(length);
int32_t length_high = Utils::High32Bits(length);
@@ -155,7 +158,7 @@
}
-File* File::Open(const char* name, FileOpenMode mode) {
+File* File::FileOpenW(const wchar_t* system_name, FileOpenMode mode) {
int flags = O_RDONLY | O_BINARY | O_NOINHERIT;
if ((mode & kWrite) != 0) {
ASSERT((mode & kWriteOnly) == 0);
@@ -168,9 +171,7 @@
if ((mode & kTruncate) != 0) {
flags = flags | O_TRUNC;
}
- const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name);
int fd = _wopen(system_name, flags, 0666);
- free(const_cast<wchar_t*>(system_name));
if (fd < 0) {
return NULL;
}
@@ -185,6 +186,25 @@
}
+File* File::ScopedOpen(const char* name, FileOpenMode mode) {
+ const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name);
+ return FileOpenW(system_name, mode);
+}
+
+
+File* File::Open(const char* path, FileOpenMode mode) {
+ int path_len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
+ wchar_t* system_name = new wchar_t[path_len];
+ if (system_name == NULL) {
+ return NULL;
+ }
+ MultiByteToWideChar(CP_UTF8, 0, path, -1, system_name, path_len);
+ File* file = FileOpenW(system_name, mode);
+ delete[] system_name;
+ return file;
+}
+
+
File* File::OpenStdio(int fd) {
switch (fd) {
case 1:
@@ -205,7 +225,6 @@
struct __stat64 st;
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name);
bool stat_status = _wstat64(system_name, &st);
- free(const_cast<wchar_t*>(system_name));
if (stat_status == 0) {
return ((st.st_mode & S_IFMT) == S_IFREG);
} else {
@@ -217,7 +236,6 @@
bool File::Create(const char* name) {
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name);
int fd = _wopen(system_name, O_RDONLY | O_CREAT, 0666);
- free(const_cast<wchar_t*>(system_name));
if (fd < 0) {
return false;
}
@@ -264,10 +282,9 @@
const wchar_t* name = StringUtilsWin::Utf8ToWide(utf8_name);
int create_status = CreateDirectoryW(name, NULL);
// If the directory already existed, treat it as a success.
- if (create_status == 0 &&
- (GetLastError() != ERROR_ALREADY_EXISTS ||
- (GetFileAttributesW(name) & FILE_ATTRIBUTE_DIRECTORY) != 0)) {
- free(const_cast<wchar_t*>(name));
+ if ((create_status == 0) &&
+ ((GetLastError() != ERROR_ALREADY_EXISTS) ||
+ ((GetFileAttributesW(name) & FILE_ATTRIBUTE_DIRECTORY) != 0))) {
return false;
}
@@ -279,7 +296,6 @@
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
NULL);
- free(const_cast<wchar_t*>(name));
if (dir_handle == INVALID_HANDLE_VALUE) {
return false;
}
@@ -287,7 +303,6 @@
const wchar_t* target = StringUtilsWin::Utf8ToWide(utf8_target);
int target_len = wcslen(target);
if (target_len > MAX_PATH - 1) {
- free(const_cast<wchar_t*>(target));
CloseHandle(dir_handle);
return false;
}
@@ -295,7 +310,8 @@
int reparse_data_buffer_size =
sizeof REPARSE_DATA_BUFFER + 2 * MAX_PATH * sizeof WCHAR;
REPARSE_DATA_BUFFER* reparse_data_buffer =
- static_cast<REPARSE_DATA_BUFFER*>(calloc(reparse_data_buffer_size, 1));
+ reinterpret_cast<REPARSE_DATA_BUFFER*>(Dart_ScopeAllocate(
+ reparse_data_buffer_size));
reparse_data_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer, target);
wcscpy(
@@ -320,9 +336,9 @@
0,
&dummy_received_bytes,
NULL);
- if (CloseHandle(dir_handle) == 0) return false;
- free(const_cast<wchar_t*>(target));
- free(reparse_data_buffer);
+ if (CloseHandle(dir_handle) == 0) {
+ return false;
+ }
return (result != 0);
}
@@ -330,7 +346,6 @@
bool File::Delete(const char* name) {
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name);
int status = _wremove(system_name);
- free(const_cast<wchar_t*>(system_name));
return status != -1;
}
@@ -346,7 +361,6 @@
} else {
SetLastError(ERROR_NOT_A_REPARSE_POINT);
}
- free(const_cast<wchar_t*>(system_name));
return result;
}
@@ -359,8 +373,6 @@
DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING;
int move_status =
MoveFileExW(system_old_path, system_new_path, flags);
- free(const_cast<wchar_t*>(system_old_path));
- free(const_cast<wchar_t*>(system_new_path));
return (move_status != 0);
} else {
SetLastError(ERROR_FILE_NOT_FOUND);
@@ -377,8 +389,6 @@
DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING;
int move_status =
MoveFileExW(system_old_path, system_new_path, flags);
- free(const_cast<wchar_t*>(system_old_path));
- free(const_cast<wchar_t*>(system_new_path));
return (move_status != 0);
} else {
SetLastError(ERROR_FILE_NOT_FOUND);
@@ -398,8 +408,6 @@
NULL,
NULL,
0) != 0;
- free(const_cast<wchar_t*>(system_old_path));
- free(const_cast<wchar_t*>(system_new_path));
return success;
} else {
SetLastError(ERROR_FILE_NOT_FOUND);
@@ -412,7 +420,6 @@
struct __stat64 st;
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name);
int stat_status = _wstat64(system_name, &st);
- free(const_cast<wchar_t*>(system_name));
if (stat_status == 0) {
return st.st_size;
}
@@ -420,7 +427,7 @@
}
-char* File::LinkTarget(const char* pathname) {
+const char* File::LinkTarget(const char* pathname) {
const wchar_t* name = StringUtilsWin::Utf8ToWide(pathname);
HANDLE dir_handle = CreateFileW(
name,
@@ -430,15 +437,14 @@
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
NULL);
- free(const_cast<wchar_t*>(name));
if (dir_handle == INVALID_HANDLE_VALUE) {
return NULL;
}
int buffer_size =
sizeof REPARSE_DATA_BUFFER + 2 * (MAX_PATH + 1) * sizeof WCHAR;
- REPARSE_DATA_BUFFER* buffer =
- static_cast<REPARSE_DATA_BUFFER*>(calloc(buffer_size, 1));
+ REPARSE_DATA_BUFFER* buffer = reinterpret_cast<REPARSE_DATA_BUFFER*>(
+ Dart_ScopeAllocate(buffer_size));
DWORD received_bytes; // Value is not used.
int result = DeviceIoControl(
dir_handle,
@@ -453,11 +459,9 @@
DWORD error = GetLastError();
CloseHandle(dir_handle);
SetLastError(error);
- free(buffer);
return NULL;
}
if (CloseHandle(dir_handle) == 0) {
- free(buffer);
return NULL;
}
@@ -473,7 +477,6 @@
target_offset = buffer->SymbolicLinkReparseBuffer.SubstituteNameOffset;
target_length = buffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
} else { // Not a junction or a symbolic link.
- free(buffer);
SetLastError(ERROR_NOT_A_REPARSE_POINT);
return NULL;
}
@@ -482,7 +485,7 @@
target_length /= sizeof(wchar_t);
target += target_offset;
// Remove "\??\" from beginning of target.
- if (target_length > 4 && wcsncmp(L"\\??\\", target, 4) == 0) {
+ if ((target_length > 4) && (wcsncmp(L"\\??\\", target, 4) == 0)) {
target += 4;
target_length -= 4;
}
@@ -494,7 +497,7 @@
0,
NULL,
NULL);
- char* utf8_target = reinterpret_cast<char*>(malloc(utf8_length + 1));
+ char* utf8_target = DartUtils::ScopedCString(utf8_length + 1);
if (0 == WideCharToMultiByte(CP_UTF8,
0,
target,
@@ -503,12 +506,9 @@
utf8_length,
NULL,
NULL)) {
- free(buffer);
- free(utf8_target);
return NULL;
}
utf8_target[utf8_length] = '\0';
- free(buffer);
return utf8_target;
}
@@ -520,7 +520,6 @@
struct _stat64 st;
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name);
int stat_status = _wstat64(system_name, &st);
- free(const_cast<wchar_t*>(system_name));
if (stat_status == 0) {
data[kCreatedTime] = st.st_ctime * 1000;
data[kModifiedTime] = st.st_mtime * 1000;
@@ -538,7 +537,6 @@
struct __stat64 st;
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(name);
int stat_status = _wstat64(system_name, &st);
- free(const_cast<wchar_t*>(system_name));
if (stat_status == 0) {
return st.st_mtime;
}
@@ -548,14 +546,16 @@
bool File::IsAbsolutePath(const char* pathname) {
// Should we consider network paths?
- if (pathname == NULL) return false;
+ if (pathname == NULL) {
+ return false;
+ }
return (strlen(pathname) > 2) &&
(pathname[1] == ':') &&
(pathname[2] == '\\' || pathname[2] == '/');
}
-char* File::GetCanonicalPath(const char* pathname) {
+const char* File::GetCanonicalPath(const char* pathname) {
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(pathname);
HANDLE file_handle = CreateFileW(
system_name,
@@ -566,7 +566,6 @@
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (file_handle == INVALID_HANDLE_VALUE) {
- free(const_cast<wchar_t*>(system_name));
return NULL;
}
wchar_t dummy_buffer[1];
@@ -575,14 +574,14 @@
0,
VOLUME_NAME_DOS);
if (required_size == 0) {
- free(const_cast<wchar_t*>(system_name));
DWORD error = GetLastError();
CloseHandle(file_handle);
SetLastError(error);
return NULL;
}
- wchar_t* path =
- static_cast<wchar_t*>(malloc(required_size * sizeof(wchar_t)));
+ wchar_t* path;
+ path = reinterpret_cast<wchar_t*>(
+ Dart_ScopeAllocate(required_size * sizeof(*path)));
int result_size = GetFinalPathNameByHandle(file_handle,
path,
required_size,
@@ -590,16 +589,14 @@
ASSERT(result_size <= required_size - 1);
// Remove leading \\?\ if possible, unless input used it.
char* result;
- if (result_size < MAX_PATH - 1 + 4 &&
- result_size > 4 &&
- wcsncmp(path, L"\\\\?\\", 4) == 0 &&
- wcsncmp(system_name, L"\\\\?\\", 4) != 0) {
+ if ((result_size < MAX_PATH - 1 + 4) &&
+ (result_size > 4) &&
+ (wcsncmp(path, L"\\\\?\\", 4) == 0) &&
+ (wcsncmp(system_name, L"\\\\?\\", 4) != 0)) {
result = StringUtilsWin::WideToUtf8(path + 4);
} else {
result = StringUtilsWin::WideToUtf8(path);
}
- free(const_cast<wchar_t*>(system_name));
- free(path);
CloseHandle(file_handle);
return result;
}
@@ -652,7 +649,6 @@
} else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
result = kIsDirectory;
}
- free(const_cast<wchar_t*>(name));
return result;
}
@@ -671,10 +667,8 @@
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
NULL);
if (file_handle == INVALID_HANDLE_VALUE) {
- free(const_cast<wchar_t*>(wide_name));
return File::kError;
}
- free(const_cast<wchar_t*>(wide_name));
int result = GetFileInformationByHandle(file_handle, &file_info[i]);
if (result == 0) {
DWORD error = GetLastError();
@@ -686,9 +680,10 @@
return File::kError;
}
}
- if (file_info[0].dwVolumeSerialNumber == file_info[1].dwVolumeSerialNumber &&
- file_info[0].nFileIndexHigh == file_info[1].nFileIndexHigh &&
- file_info[0].nFileIndexLow == file_info[1].nFileIndexLow) {
+ if ((file_info[0].dwVolumeSerialNumber ==
+ file_info[1].dwVolumeSerialNumber) &&
+ (file_info[0].nFileIndexHigh == file_info[1].nFileIndexHigh) &&
+ (file_info[0].nFileIndexLow == file_info[1].nFileIndexLow)) {
return kIdentical;
} else {
return kDifferent;
diff --git a/runtime/bin/filter.cc b/runtime/bin/filter.cc
index 5e87f62..fb6c74b 100644
--- a/runtime/bin/filter.cc
+++ b/runtime/bin/filter.cc
@@ -16,90 +16,103 @@
static const int kFilterPointerNativeField = 0;
-static Filter* GetFilter(Dart_Handle filter_obj) {
- Filter* filter;
- Dart_Handle result = Filter::GetFilterPointerNativeField(filter_obj, &filter);
- if (Dart_IsError(result)) {
- Dart_PropagateError(result);
+static Dart_Handle GetFilter(Dart_Handle filter_obj, Filter** filter) {
+ ASSERT(filter != NULL);
+ Filter* result;
+ Dart_Handle err = Filter::GetFilterNativeField(filter_obj, &result);
+ if (Dart_IsError(err)) {
+ return err;
}
- if (filter == NULL) {
- Dart_ThrowException(DartUtils::NewInternalError("Filter destroyed"));
+ if (result == NULL) {
+ return Dart_NewApiError("Filter was destroyed");
}
- return filter;
+
+ *filter = result;
+ return Dart_Null();
}
-static void EndFilter(Dart_Handle filter_obj, Filter* filter) {
- Filter::SetFilterPointerNativeField(filter_obj, NULL);
- delete filter;
-}
-static uint8_t* copyDictionary(Dart_Handle dictionary_obj) {
+static Dart_Handle CopyDictionary(Dart_Handle dictionary_obj,
+ uint8_t** dictionary) {
+ ASSERT(dictionary != NULL);
uint8_t* src = NULL;
intptr_t size;
Dart_TypedData_Type type;
- if (Dart_IsError(Dart_ListLength(dictionary_obj, &size))) {
- Dart_ThrowException(DartUtils::NewInternalError(
- "Failed to get the zlib dictionary length"));
+ Dart_Handle err = Dart_ListLength(dictionary_obj, &size);
+ if (Dart_IsError(err)) {
+ return err;
}
- uint8_t* dictionary = new uint8_t[size];
-
- if (dictionary == NULL) {
- Dart_ThrowException(DartUtils::NewInternalError(
- "Failed to allocate buffer for the zlib dictionary"));
+ uint8_t* result = new uint8_t[size];
+ if (result == NULL) {
+ return Dart_NewApiError("Could not allocate new dictionary");
}
- Dart_Handle result = Dart_TypedDataAcquireData(
+ err = Dart_TypedDataAcquireData(
dictionary_obj, &type, reinterpret_cast<void**>(&src), &size);
- if (!Dart_IsError(result)) {
- memmove(dictionary, src, size);
+ if (!Dart_IsError(err)) {
+ memmove(result, src, size);
Dart_TypedDataReleaseData(dictionary_obj);
} else {
- if (Dart_IsError(Dart_ListGetAsBytes(dictionary_obj, 0, dictionary,
- size))) {
- Dart_ThrowException(DartUtils::NewInternalError(
- "Failed to get the zlib dictionary"));
+ err = Dart_ListGetAsBytes(dictionary_obj, 0, result, size);
+ if (Dart_IsError(err)) {
+ delete[] result;
+ return err;
}
}
- return dictionary;
+ *dictionary = result;
+ return Dart_Null();
}
+
void FUNCTION_NAME(Filter_CreateZLibInflate)(Dart_NativeArguments args) {
Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
Dart_Handle window_bits_obj = Dart_GetNativeArgument(args, 1);
int64_t window_bits = DartUtils::GetIntegerValue(window_bits_obj);
Dart_Handle dict_obj = Dart_GetNativeArgument(args, 2);
+ Dart_Handle raw_obj = Dart_GetNativeArgument(args, 3);
+ bool raw = DartUtils::GetBooleanValue(raw_obj);
+
+ Dart_Handle err;
uint8_t* dictionary = NULL;
intptr_t dictionary_length = 0;
if (!Dart_IsNull(dict_obj)) {
- dictionary = copyDictionary(dict_obj);
- if (dictionary != NULL) {
- dictionary_length = 0;
- Dart_ListLength(dict_obj, &dictionary_length);
+ err = CopyDictionary(dict_obj, &dictionary);
+ if (Dart_IsError(err)) {
+ Dart_PropagateError(err);
+ }
+ ASSERT(dictionary != NULL);
+ dictionary_length = 0;
+ err = Dart_ListLength(dict_obj, &dictionary_length);
+ if (Dart_IsError(err)) {
+ delete[] dictionary;
+ Dart_PropagateError(err);
}
}
- Dart_Handle raw_obj = Dart_GetNativeArgument(args, 3);
- bool raw;
- if (Dart_IsError(Dart_BooleanValue(raw_obj, &raw))) {
- Dart_ThrowException(DartUtils::NewInternalError(
- "Failed to get 'raw' parameter"));
+
+ ZLibInflateFilter* filter = new ZLibInflateFilter(
+ static_cast<int32_t>(window_bits), dictionary, dictionary_length, raw);
+ if (filter == NULL) {
+ delete[] dictionary;
+ Dart_PropagateError(Dart_NewApiError(
+ "Could not allocate ZLibInflateFilter"));
}
- Filter* filter = new ZLibInflateFilter(static_cast<int32_t>(window_bits),
- dictionary, dictionary_length, raw);
if (!filter->Init()) {
delete filter;
Dart_ThrowException(DartUtils::NewInternalError(
"Failed to create ZLibInflateFilter"));
}
- Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter);
- if (Dart_IsError(result)) {
+ err = Filter::SetFilterAndCreateFinalizer(
+ filter_obj, filter, sizeof(*filter) + dictionary_length);
+ if (Dart_IsError(err)) {
delete filter;
- Dart_PropagateError(result);
+ Dart_PropagateError(err);
}
}
+
void FUNCTION_NAME(Filter_CreateZLibDeflate)(Dart_NativeArguments args) {
Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
Dart_Handle gzip_obj = Dart_GetNativeArgument(args, 1);
@@ -114,37 +127,54 @@
Dart_Handle strategy_obj = Dart_GetNativeArgument(args, 5);
int64_t strategy = DartUtils::GetIntegerValue(strategy_obj);
Dart_Handle dict_obj = Dart_GetNativeArgument(args, 6);
+ Dart_Handle raw_obj = Dart_GetNativeArgument(args, 7);
+ bool raw = DartUtils::GetBooleanValue(raw_obj);
+
+ Dart_Handle err;
uint8_t* dictionary = NULL;
intptr_t dictionary_length = 0;
if (!Dart_IsNull(dict_obj)) {
- dictionary = copyDictionary(dict_obj);
- if (dictionary != NULL) {
- dictionary_length = 0;
- Dart_ListLength(dict_obj, &dictionary_length);
+ err = CopyDictionary(dict_obj, &dictionary);
+ if (Dart_IsError(err)) {
+ Dart_PropagateError(err);
+ }
+ ASSERT(dictionary != NULL);
+ dictionary_length = 0;
+ err = Dart_ListLength(dict_obj, &dictionary_length);
+ if (Dart_IsError(err)) {
+ delete[] dictionary;
+ Dart_PropagateError(err);
}
}
- Dart_Handle raw_obj = Dart_GetNativeArgument(args, 7);
- bool raw = DartUtils::GetBooleanValue(raw_obj);
- Filter* filter = new ZLibDeflateFilter(gzip, static_cast<int32_t>(level),
- static_cast<int32_t>(window_bits),
- static_cast<int32_t>(mem_level),
- static_cast<int32_t>(strategy),
- dictionary, dictionary_length, raw);
+
+ ZLibDeflateFilter* filter = new ZLibDeflateFilter(
+ gzip,
+ static_cast<int32_t>(level),
+ static_cast<int32_t>(window_bits),
+ static_cast<int32_t>(mem_level),
+ static_cast<int32_t>(strategy),
+ dictionary, dictionary_length, raw);
+ if (filter == NULL) {
+ delete[] dictionary;
+ Dart_PropagateError(Dart_NewApiError(
+ "Could not allocate ZLibDeflateFilter"));
+ }
if (!filter->Init()) {
delete filter;
Dart_ThrowException(DartUtils::NewInternalError(
"Failed to create ZLibDeflateFilter"));
}
- Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter);
+ Dart_Handle result = Filter::SetFilterAndCreateFinalizer(
+ filter_obj, filter, sizeof(*filter) + dictionary_length);
if (Dart_IsError(result)) {
delete filter;
Dart_PropagateError(result);
}
}
+
void FUNCTION_NAME(Filter_Process)(Dart_NativeArguments args) {
Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
- Filter* filter = GetFilter(filter_obj);
Dart_Handle data_obj = Dart_GetNativeArgument(args, 1);
intptr_t start = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
intptr_t end = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
@@ -152,9 +182,15 @@
intptr_t length;
Dart_TypedData_Type type;
uint8_t* buffer = NULL;
+
+ Filter* filter = NULL;
+ Dart_Handle err = GetFilter(filter_obj, &filter);
+ if (Dart_IsError(err)) {
+ Dart_PropagateError(err);
+ }
+
Dart_Handle result = Dart_TypedDataAcquireData(
data_obj, &type, reinterpret_cast<void**>(&buffer), &length);
-
if (!Dart_IsError(result)) {
ASSERT(type == Dart_TypedData_kUint8 || type == Dart_TypedData_kInt8);
if (type != Dart_TypedData_kUint8 && type != Dart_TypedData_kInt8) {
@@ -165,29 +201,30 @@
uint8_t* zlib_buffer = new uint8_t[chunk_length];
if (zlib_buffer == NULL) {
Dart_TypedDataReleaseData(data_obj);
- Dart_ThrowException(DartUtils::NewInternalError(
- "Failed to allocate buffer for zlib"));
+ Dart_PropagateError(Dart_NewApiError("Could not allocate zlib buffer"));
}
+
memmove(zlib_buffer, buffer + start, chunk_length);
Dart_TypedDataReleaseData(data_obj);
buffer = zlib_buffer;
} else {
- if (Dart_IsError(Dart_ListLength(data_obj, &length))) {
- Dart_ThrowException(DartUtils::NewInternalError(
- "Failed to get list length"));
+ err = Dart_ListLength(data_obj, &length);
+ if (Dart_IsError(err)) {
+ Dart_PropagateError(err);
}
buffer = new uint8_t[chunk_length];
- if (Dart_IsError(Dart_ListGetAsBytes(
- data_obj, start, buffer, chunk_length))) {
+ if (buffer == NULL) {
+ Dart_PropagateError(Dart_NewApiError("Could not allocate buffer"));
+ }
+ err = Dart_ListGetAsBytes(data_obj, start, buffer, chunk_length);
+ if (Dart_IsError(err)) {
delete[] buffer;
- Dart_ThrowException(DartUtils::NewInternalError(
- "Failed to get list bytes"));
+ Dart_PropagateError(err);
}
}
// Process will take ownership of buffer, if successful.
if (!filter->Process(buffer, chunk_length)) {
delete[] buffer;
- EndFilter(filter_obj, filter);
Dart_ThrowException(DartUtils::NewInternalError(
"Call to Process while still processing data"));
}
@@ -196,26 +233,22 @@
void FUNCTION_NAME(Filter_Processed)(Dart_NativeArguments args) {
Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
- Filter* filter = GetFilter(filter_obj);
Dart_Handle flush_obj = Dart_GetNativeArgument(args, 1);
- bool flush;
- if (Dart_IsError(Dart_BooleanValue(flush_obj, &flush))) {
- Dart_ThrowException(DartUtils::NewInternalError(
- "Failed to get 'flush' parameter"));
- }
+ bool flush = DartUtils::GetBooleanValue(flush_obj);
Dart_Handle end_obj = Dart_GetNativeArgument(args, 2);
- bool end;
- if (Dart_IsError(Dart_BooleanValue(end_obj, &end))) {
- Dart_ThrowException(DartUtils::NewInternalError(
- "Failed to get 'end' parameter"));
+ bool end = DartUtils::GetBooleanValue(end_obj);
+
+ Filter* filter = NULL;
+ Dart_Handle err = GetFilter(filter_obj, &filter);
+ if (Dart_IsError(err)) {
+ Dart_PropagateError(err);
}
+
intptr_t read = filter->Processed(filter->processed_buffer(),
filter->processed_buffer_size(),
flush,
end);
if (read < 0) {
- // Error, end filter.
- EndFilter(filter_obj, filter);
Dart_ThrowException(DartUtils::NewInternalError(
"Filter error, bad data"));
} else if (read == 0) {
@@ -229,24 +262,35 @@
}
-void FUNCTION_NAME(Filter_End)(Dart_NativeArguments args) {
- Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
- Filter* filter = GetFilter(filter_obj);
- EndFilter(filter_obj, filter);
+static void DeleteFilter(
+ void* isolate_data,
+ Dart_WeakPersistentHandle handle,
+ void* filter_pointer) {
+ Filter* filter = reinterpret_cast<Filter*>(filter_pointer);
+ delete filter;
}
-Dart_Handle Filter::SetFilterPointerNativeField(Dart_Handle filter,
- Filter* filter_pointer) {
- return Dart_SetNativeInstanceField(
+Dart_Handle Filter::SetFilterAndCreateFinalizer(Dart_Handle filter,
+ Filter* filter_pointer,
+ intptr_t size) {
+ Dart_Handle err = Dart_SetNativeInstanceField(
filter,
kFilterPointerNativeField,
reinterpret_cast<intptr_t>(filter_pointer));
+ if (Dart_IsError(err)) {
+ return err;
+ }
+ Dart_NewWeakPersistentHandle(filter,
+ reinterpret_cast<void*>(filter_pointer),
+ size,
+ DeleteFilter);
+ return err;
}
-Dart_Handle Filter::GetFilterPointerNativeField(Dart_Handle filter,
- Filter** filter_pointer) {
+Dart_Handle Filter::GetFilterNativeField(Dart_Handle filter,
+ Filter** filter_pointer) {
return Dart_GetNativeInstanceField(
filter,
kFilterPointerNativeField,
@@ -257,7 +301,9 @@
ZLibDeflateFilter::~ZLibDeflateFilter() {
delete[] dictionary_;
delete[] current_buffer_;
- if (initialized()) deflateEnd(&stream_);
+ if (initialized()) {
+ deflateEnd(&stream_);
+ }
}
@@ -277,7 +323,7 @@
if (result != Z_OK) {
return false;
}
- if (dictionary_ != NULL && !gzip_ && !raw_) {
+ if ((dictionary_ != NULL) && !gzip_ && !raw_) {
result = deflateSetDictionary(&stream_, dictionary_, dictionary_length_);
delete[] dictionary_;
dictionary_ = NULL;
@@ -291,7 +337,9 @@
bool ZLibDeflateFilter::Process(uint8_t* data, intptr_t length) {
- if (current_buffer_ != NULL) return false;
+ if (current_buffer_ != NULL) {
+ return false;
+ }
stream_.avail_in = length;
stream_.next_in = current_buffer_ = data;
return true;
@@ -331,7 +379,9 @@
ZLibInflateFilter::~ZLibInflateFilter() {
delete[] dictionary_;
delete[] current_buffer_;
- if (initialized()) inflateEnd(&stream_);
+ if (initialized()) {
+ inflateEnd(&stream_);
+ }
}
@@ -355,7 +405,9 @@
bool ZLibInflateFilter::Process(uint8_t* data, intptr_t length) {
- if (current_buffer_ != NULL) return false;
+ if (current_buffer_ != NULL) {
+ return false;
+ }
stream_.avail_in = length;
stream_.next_in = current_buffer_ = data;
return true;
diff --git a/runtime/bin/filter.h b/runtime/bin/filter.h
index 2dad3ca..85592ab 100644
--- a/runtime/bin/filter.h
+++ b/runtime/bin/filter.h
@@ -29,10 +29,11 @@
virtual intptr_t Processed(uint8_t* buffer, intptr_t length, bool finish,
bool end) = 0;
- static Dart_Handle SetFilterPointerNativeField(Dart_Handle filter,
- Filter* filter_pointer);
- static Dart_Handle GetFilterPointerNativeField(Dart_Handle filter,
- Filter** filter_pointer);
+ static Dart_Handle SetFilterAndCreateFinalizer(Dart_Handle filter,
+ Filter* filter_pointer,
+ intptr_t filter_size);
+ static Dart_Handle GetFilterNativeField(Dart_Handle filter,
+ Filter** filter_pointer);
bool initialized() const { return initialized_; }
void set_initialized(bool value) { initialized_ = value; }
diff --git a/runtime/bin/filter_patch.dart b/runtime/bin/filter_patch.dart
index 3a32170..a5626bb 100644
--- a/runtime/bin/filter_patch.dart
+++ b/runtime/bin/filter_patch.dart
@@ -8,8 +8,6 @@
List<int> processed({bool flush: true, bool end: false})
native "Filter_Processed";
-
- void end() native "Filter_End";
}
class _ZLibInflateFilter extends _FilterImpl {
diff --git a/runtime/bin/filter_unsupported.cc b/runtime/bin/filter_unsupported.cc
index 1742559..f01b3db 100644
--- a/runtime/bin/filter_unsupported.cc
+++ b/runtime/bin/filter_unsupported.cc
@@ -16,9 +16,11 @@
"ZLibInflater and Deflater not supported on this platform"));
}
+
void FUNCTION_NAME(Filter_CreateZLibDeflate)(Dart_NativeArguments args) {
}
+
void FUNCTION_NAME(Filter_Process)(Dart_NativeArguments args) {
}
@@ -26,9 +28,5 @@
void FUNCTION_NAME(Filter_Processed)(Dart_NativeArguments args) {
}
-
-void FUNCTION_NAME(Filter_End)(Dart_NativeArguments args) {
-}
-
} // namespace bin
} // namespace dart
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 45087b4..20cc410 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -1031,12 +1031,14 @@
// Initialize the Dart VM.
// Note: We don't expect isolates to be created from dart code during
- // snapshot generation.
+ // core library snapshot generation. However for the case when a full
+ // snasphot is generated from a script (app_script_name != NULL) we will
+ // need the service isolate to resolve URI and load code.
char* error = Dart_Initialize(
NULL,
NULL,
NULL,
- CreateServiceIsolate,
+ (app_script_name != NULL) ? CreateServiceIsolate : NULL,
NULL,
NULL,
NULL,
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 51b1d56..91cc1e8 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -72,7 +72,6 @@
V(FileSystemWatcher_WatchPath, 4) \
V(Filter_CreateZLibDeflate, 8) \
V(Filter_CreateZLibInflate, 4) \
- V(Filter_End, 1) \
V(Filter_Process, 4) \
V(Filter_Processed, 3) \
V(InternetAddress_Parse, 1) \
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 33d4ba5..4601588 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1675,7 +1675,9 @@
// Free copied argument strings if converted.
if (argv_converted) {
- for (int i = 0; i < argc; i++) free(argv[i]);
+ for (int i = 0; i < argc; i++) {
+ free(argv[i]);
+ }
}
// Free environment if any.
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index f2f16be..75324f1 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -102,22 +102,18 @@
} else {
Dart_Handle result = Dart_NewList(count);
if (Dart_IsError(result)) {
- Platform::FreeEnvironment(env, count);
Dart_PropagateError(result);
}
for (intptr_t i = 0; i < count; i++) {
Dart_Handle str = DartUtils::NewString(env[i]);
if (Dart_IsError(str)) {
- Platform::FreeEnvironment(env, count);
Dart_PropagateError(str);
}
Dart_Handle error = Dart_ListSetAt(result, i, str);
if (Dart_IsError(error)) {
- Platform::FreeEnvironment(env, count);
Dart_PropagateError(error);
}
}
- Platform::FreeEnvironment(env, count);
Dart_SetReturnValue(args, result);
}
}
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index 4dec601..d4f96bd 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -32,14 +32,12 @@
// Extracts the local hostname.
static bool LocalHostname(char* buffer, intptr_t buffer_length);
- // Extracts the environment variables for the current process. The
- // array of strings returned must be deallocated using
- // FreeEnvironment. The number of elements in the array is returned
- // in the count argument.
+ // Extracts the environment variables for the current process. The array of
+ // strings is Dart_ScopeAllocated. The number of elements in the array is
+ // returned in the count argument.
static char** Environment(intptr_t* count);
- static void FreeEnvironment(char** env, intptr_t count);
- static char* ResolveExecutablePath();
+ static const char* ResolveExecutablePath();
// Stores the executable name.
static void SetExecutableName(const char* executable_name) {
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index 3c44c04..de60960 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -14,7 +14,6 @@
#include "bin/fdutils.h"
-
namespace dart {
namespace bin {
@@ -58,9 +57,12 @@
// provide access to modifying environment variables.
intptr_t i = 0;
char** tmp = environ;
- while (*(tmp++) != NULL) i++;
+ while (*(tmp++) != NULL) {
+ i++;
+ }
*count = i;
- char** result = new char*[i];
+ char** result;
+ result = reinterpret_cast<char**>(Dart_ScopeAllocate(i * sizeof(*result)));
for (intptr_t current = 0; current < i; current++) {
result[current] = environ[current];
}
@@ -68,15 +70,11 @@
}
-void Platform::FreeEnvironment(char** env, intptr_t count) {
- delete[] env;
-}
-
-
-char* Platform::ResolveExecutablePath() {
+const char* Platform::ResolveExecutablePath() {
return File::LinkTarget("/proc/self/exe");
}
+
void Platform::Exit(int exit_code) {
exit(exit_code);
}
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index 24cbfd3..c6dc3cc 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -14,7 +14,6 @@
#include "bin/fdutils.h"
-
namespace dart {
namespace bin {
@@ -58,9 +57,12 @@
// provide access to modifying environment variables.
intptr_t i = 0;
char** tmp = environ;
- while (*(tmp++) != NULL) i++;
+ while (*(tmp++) != NULL) {
+ i++;
+ }
*count = i;
- char** result = new char*[i];
+ char** result;
+ result = reinterpret_cast<char**>(Dart_ScopeAllocate(i * sizeof(*result)));
for (intptr_t current = 0; current < i; current++) {
result[current] = environ[current];
}
@@ -68,15 +70,11 @@
}
-void Platform::FreeEnvironment(char** env, intptr_t count) {
- delete[] env;
-}
-
-
-char* Platform::ResolveExecutablePath() {
+const char* Platform::ResolveExecutablePath() {
return File::LinkTarget("/proc/self/exe");
}
+
void Platform::Exit(int exit_code) {
exit(exit_code);
}
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 0f7c629..b9a1faa 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -89,9 +89,12 @@
char** environ = *(_NSGetEnviron());
intptr_t i = 0;
char** tmp = environ;
- while (*(tmp++) != NULL) i++;
+ while (*(tmp++) != NULL) {
+ i++;
+ }
*count = i;
- char** result = new char*[i];
+ char** result;
+ result = reinterpret_cast<char**>(Dart_ScopeAllocate(i * sizeof(*result)));
for (intptr_t current = 0; current < i; current++) {
result[current] = environ[current];
}
@@ -100,30 +103,23 @@
}
-void Platform::FreeEnvironment(char** env, intptr_t count) {
- delete[] env;
-}
-
-
-char* Platform::ResolveExecutablePath() {
+const char* Platform::ResolveExecutablePath() {
// Get the required length of the buffer.
uint32_t path_size = 0;
- char* path = NULL;
- if (_NSGetExecutablePath(path, &path_size) == 0) {
+ if (_NSGetExecutablePath(NULL, &path_size) == 0) {
return NULL;
}
// Allocate buffer and get executable path.
- path = reinterpret_cast<char*>(malloc(path_size));
+ char* path = DartUtils::ScopedCString(path_size);
if (_NSGetExecutablePath(path, &path_size) != 0) {
- free(path);
return NULL;
}
// Return the canonical path as the returned path might contain symlinks.
- char* canon_path = File::GetCanonicalPath(path);
- free(path);
+ const char* canon_path = File::GetCanonicalPath(path);
return canon_path;
}
+
void Platform::Exit(int exit_code) {
exit(exit_code);
}
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index 9b29cb7..9bc01bc 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -47,7 +47,9 @@
#if defined(PLATFORM_DISABLE_SOCKET)
return false;
#else
- if (!Socket::Initialize()) return false;
+ if (!Socket::Initialize()) {
+ return false;
+ }
return gethostname(buffer, buffer_length) == 0;
#endif
}
@@ -55,7 +57,9 @@
char** Platform::Environment(intptr_t* count) {
wchar_t* strings = GetEnvironmentStringsW();
- if (strings == NULL) return NULL;
+ if (strings == NULL) {
+ return NULL;
+ }
wchar_t* tmp = strings;
intptr_t i = 0;
while (*tmp != '\0') {
@@ -63,15 +67,20 @@
// These are synthetic variables corresponding to dynamic environment
// variables like %=C:% and %=ExitCode%, and the Dart environment does
// not include these.
- if (*tmp != '=') i++;
+ if (*tmp != '=') {
+ i++;
+ }
tmp += (wcslen(tmp) + 1);
}
*count = i;
- char** result = new char*[i];
+ char** result;
+ result = reinterpret_cast<char**>(Dart_ScopeAllocate(i * sizeof(*result)));
tmp = strings;
for (intptr_t current = 0; current < i;) {
// Skip the strings that were not counted above.
- if (*tmp != '=') result[current++] = StringUtilsWin::WideToUtf8(tmp);
+ if (*tmp != '=') {
+ result[current++] = StringUtilsWin::WideToUtf8(tmp);
+ }
tmp += (wcslen(tmp) + 1);
}
FreeEnvironmentStringsW(strings);
@@ -79,36 +88,27 @@
}
-void Platform::FreeEnvironment(char** env, intptr_t count) {
- for (intptr_t i = 0; i < count; i++) {
- free(env[i]);
- }
- delete[] env;
-}
-
-
-char* Platform::ResolveExecutablePath() {
+const char* Platform::ResolveExecutablePath() {
// GetModuleFileNameW cannot directly provide information on the
// required buffer size, so start out with a buffer large enough to
// hold any Windows path.
const int kTmpBufferSize = 32768;
- wchar_t* tmp_buffer = reinterpret_cast<wchar_t*>(malloc(kTmpBufferSize));
+ wchar_t* tmp_buffer =
+ reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(kTmpBufferSize));
// Ensure no last error before calling GetModuleFileNameW.
SetLastError(ERROR_SUCCESS);
// Get the required length of the buffer.
int path_length = GetModuleFileNameW(NULL, tmp_buffer, kTmpBufferSize);
if (GetLastError() != ERROR_SUCCESS) {
- free(tmp_buffer);
return NULL;
}
char* path = StringUtilsWin::WideToUtf8(tmp_buffer);
- free(tmp_buffer);
// Return the canonical path as the returned path might contain symlinks.
- char* canon_path = File::GetCanonicalPath(path);
- free(path);
+ const char* canon_path = File::GetCanonicalPath(path);
return canon_path;
}
+
void Platform::Exit(int exit_code) {
// TODO(zra): Remove once VM shuts down cleanly.
::dart::private_flag_windows_run_tls_destructors = false;
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index b583049..4a87e29 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -47,11 +47,12 @@
return NULL;
}
*length = len;
- char** string_args = new char*[len];
+ char** string_args;
+ string_args = reinterpret_cast<char**>(
+ Dart_ScopeAllocate(len * sizeof(*string_args)));
for (int i = 0; i < len; i++) {
Dart_Handle arg = Dart_ListGetAt(strings, i);
if (Dart_IsError(arg)) {
- delete[] string_args;
Dart_PropagateError(arg);
}
if (!Dart_IsString(arg)) {
@@ -64,7 +65,6 @@
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
- delete[] string_args;
return NULL;
}
string_args[i] = const_cast<char *>(DartUtils::GetStringValue(arg));
@@ -115,7 +115,6 @@
if (Dart_IsString(working_directory_handle)) {
working_directory = DartUtils::GetStringValue(working_directory_handle);
} else if (!Dart_IsNull(working_directory_handle)) {
- delete[] string_args;
result = DartUtils::SetIntegerField(status_handle, "_errorCode", 0);
if (Dart_IsError(result)) {
Dart_PropagateError(result);
@@ -139,7 +138,6 @@
"Environment values must be builtin strings",
&environment_length);
if (string_environment == NULL) {
- delete[] string_args;
Dart_SetReturnValue(args, Dart_NewBoolean(false));
return;
}
@@ -151,7 +149,7 @@
Dart_Handle stderr_handle = Dart_GetNativeArgument(args, 8);
Dart_Handle exit_handle = Dart_GetNativeArgument(args, 9);
intptr_t pid = -1;
- char* os_error_message = NULL;
+ char* os_error_message = NULL; // Scope allocated by Process::Start.
int error_code = Process::Start(path,
string_args,
@@ -188,15 +186,9 @@
os_error_message != NULL ? os_error_message
: "Cannot get error message");
if (Dart_IsError(result)) {
- delete[] string_args;
- delete[] string_environment;
- free(os_error_message);
Dart_PropagateError(result);
}
}
- delete[] string_args;
- delete[] string_environment;
- free(os_error_message);
Dart_SetReturnValue(args, Dart_NewBoolean(error_code == 0));
}
@@ -221,9 +213,13 @@
exit_event,
&result)) {
Dart_Handle out = result.stdout_data();
- if (Dart_IsError(out)) Dart_PropagateError(out);
+ if (Dart_IsError(out)) {
+ Dart_PropagateError(out);
+ }
Dart_Handle err = result.stderr_data();
- if (Dart_IsError(err)) Dart_PropagateError(err);
+ if (Dart_IsError(err)) {
+ Dart_PropagateError(err);
+ }
Dart_Handle list = Dart_NewList(4);
Dart_ListSetAt(list, 0, Dart_NewInteger(pid));
Dart_ListSetAt(list, 1, Dart_NewInteger(result.exit_code()));
@@ -323,25 +319,24 @@
Dart_Handle bytes = Dart_GetNativeArgument(args, 0);
intptr_t bytes_length = 0;
Dart_Handle result = Dart_ListLength(bytes, &bytes_length);
- if (Dart_IsError(result)) Dart_PropagateError(result);
- uint8_t* buffer =
- reinterpret_cast<uint8_t*>(Dart_ScopeAllocate(bytes_length + 1));
+ if (Dart_IsError(result)) {
+ Dart_PropagateError(result);
+ }
+ uint8_t* buffer = Dart_ScopeAllocate(bytes_length + 1);
result = Dart_ListGetAsBytes(bytes, 0, buffer, bytes_length);
buffer[bytes_length] = '\0';
- if (Dart_IsError(result)) Dart_PropagateError(result);
+ if (Dart_IsError(result)) {
+ Dart_PropagateError(result);
+ }
intptr_t len;
- char* str =
- StringUtils::ConsoleStringToUtf8(
- reinterpret_cast<char*>(buffer),
- bytes_length,
- &len);
+ char* str = StringUtils::ConsoleStringToUtf8(
+ reinterpret_cast<char*>(buffer), bytes_length, &len);
if (str == NULL) {
Dart_ThrowException(
DartUtils::NewInternalError("SystemEncodingToString failed"));
}
result =
Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(str), len);
- free(str);
Dart_SetReturnValue(args, result);
}
@@ -368,7 +363,6 @@
memmove(buffer, system_string, system_len);
}
Dart_SetReturnValue(args, external_array);
- free(const_cast<char*>(system_string));
}
} // namespace bin
diff --git a/runtime/bin/process_android.cc b/runtime/bin/process_android.cc
index b9d245b..6f2394d 100644
--- a/runtime/bin/process_android.cc
+++ b/runtime/bin/process_android.cc
@@ -16,6 +16,7 @@
#include <sys/wait.h> // NOLINT
#include <unistd.h> // NOLINT
+#include "bin/dartutils.h"
#include "bin/fdutils.h"
#include "bin/lockers.h"
#include "bin/log.h"
@@ -635,7 +636,9 @@
int actual_errno = errno;
// If CleanupAndReturnError is called without an actual errno make
// sure to return an error anyway.
- if (actual_errno == 0) actual_errno = EPERM;
+ if (actual_errno == 0) {
+ actual_errno = EPERM;
+ }
SetChildOsErrorMessage();
CloseAllPipes();
return actual_errno;
@@ -644,9 +647,9 @@
void SetChildOsErrorMessage() {
const int kBufferSize = 1024;
- char error_message[kBufferSize];
+ char* error_message = DartUtils::ScopedCString(kBufferSize);
Utils::StrError(errno, error_message, kBufferSize);
- *os_error_message_ = strdup(error_message);
+ *os_error_message_ = error_message;
}
@@ -681,7 +684,7 @@
void ReadChildError() {
const int kMaxMessageSize = 256;
- char* message = static_cast<char*>(malloc(kMaxMessageSize));
+ char* message = DartUtils::ScopedCString(kMaxMessageSize);
if (message != NULL) {
FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize);
message[kMaxMessageSize - 1] = '\0';
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 30f188f..572ced7 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -16,6 +16,7 @@
#include <sys/wait.h> // NOLINT
#include <unistd.h> // NOLINT
+#include "bin/dartutils.h"
#include "bin/fdutils.h"
#include "bin/lockers.h"
#include "bin/log.h"
@@ -634,7 +635,9 @@
int actual_errno = errno;
// If CleanupAndReturnError is called without an actual errno make
// sure to return an error anyway.
- if (actual_errno == 0) actual_errno = EPERM;
+ if (actual_errno == 0) {
+ actual_errno = EPERM;
+ }
SetChildOsErrorMessage();
CloseAllPipes();
return actual_errno;
@@ -643,8 +646,9 @@
void SetChildOsErrorMessage() {
const int kBufferSize = 1024;
- char error_buf[kBufferSize];
- *os_error_message_ = strdup(Utils::StrError(errno, error_buf, kBufferSize));
+ char* error_message = DartUtils::ScopedCString(kBufferSize);
+ Utils::StrError(errno, error_message, kBufferSize);
+ *os_error_message_ = error_message;
}
@@ -679,7 +683,7 @@
void ReadChildError() {
const int kMaxMessageSize = 256;
- char* message = static_cast<char*>(malloc(kMaxMessageSize));
+ char* message = DartUtils::ScopedCString(kMaxMessageSize);
if (message != NULL) {
FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize);
message[kMaxMessageSize - 1] = '\0';
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index 1ce34f9..00869a1 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -19,6 +19,7 @@
#include <string.h> // NOLINT
#include <unistd.h> // NOLINT
+#include "bin/dartutils.h"
#include "bin/fdutils.h"
#include "bin/lockers.h"
#include "bin/log.h"
@@ -292,7 +293,9 @@
int Start() {
// Create pipes required.
int err = CreatePipes();
- if (err != 0) return err;
+ if (err != 0) {
+ return err;
+ }
// Fork to create the new process.
pid_t pid = TEMP_FAILURE_RETRY(fork());
@@ -312,7 +315,9 @@
// Register the child process if not detached.
if (mode_ == kNormal) {
err = RegisterProcess(pid);
- if (err != 0) return err;
+ if (err != 0) {
+ return err;
+ }
}
// Notify child process to start. This is done to delay the call to exec
@@ -651,7 +656,9 @@
int actual_errno = errno;
// If CleanupAndReturnError is called without an actual errno make
// sure to return an error anyway.
- if (actual_errno == 0) actual_errno = EPERM;
+ if (actual_errno == 0) {
+ actual_errno = EPERM;
+ }
SetChildOsErrorMessage();
CloseAllPipes();
return actual_errno;
@@ -660,9 +667,9 @@
void SetChildOsErrorMessage() {
const int kBufferSize = 1024;
- char error_message[kBufferSize];
+ char* error_message = DartUtils::ScopedCString(kBufferSize);
Utils::StrError(errno, error_message, kBufferSize);
- *os_error_message_ = strdup(error_message);
+ *os_error_message_ = error_message;
}
@@ -697,7 +704,7 @@
void ReadChildError() {
const int kMaxMessageSize = 256;
- char* message = static_cast<char*>(malloc(kMaxMessageSize));
+ char* message = DartUtils::ScopedCString(kMaxMessageSize);
if (message != NULL) {
FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize);
message[kMaxMessageSize - 1] = '\0';
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index ebf4ce3..1c0a03d 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -8,6 +8,7 @@
#include <process.h> // NOLINT
#include "bin/builtin.h"
+#include "bin/dartutils.h"
#include "bin/process.h"
#include "bin/eventhandler.h"
#include "bin/lockers.h"
@@ -434,7 +435,9 @@
// Transform input strings to system format.
const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path_);
- wchar_t** system_arguments = new wchar_t*[arguments_length];
+ wchar_t** system_arguments;
+ system_arguments = reinterpret_cast<wchar_t**>(
+ Dart_ScopeAllocate(arguments_length * sizeof(*system_arguments)));
for (int i = 0; i < arguments_length; i++) {
system_arguments[i] = StringUtilsWin::Utf8ToWide(arguments[i]);
}
@@ -464,14 +467,13 @@
remaining -= written;
ASSERT(remaining >= 0);
}
- free(const_cast<wchar_t*>(system_path));
- for (int i = 0; i < arguments_length; i++) free(system_arguments[i]);
- delete[] system_arguments;
// Create environment block if an environment is supplied.
environment_block_ = NULL;
if (environment != NULL) {
- wchar_t** system_environment = new wchar_t*[environment_length];
+ wchar_t** system_environment;
+ system_environment = reinterpret_cast<wchar_t**>(
+ Dart_ScopeAllocate(environment_length * sizeof(*system_environment)));
// Convert environment strings to system strings.
for (intptr_t i = 0; i < environment_length; i++) {
system_environment[i] = StringUtilsWin::Utf8ToWide(environment[i]);
@@ -498,10 +500,6 @@
// Block-terminating zero char.
environment_block_[block_index++] = '\0';
ASSERT(block_index == block_size);
- for (intptr_t i = 0; i < environment_length; i++) {
- free(system_environment[i]);
- }
- delete[] system_environment;
}
system_working_directory_ = NULL;
@@ -518,9 +516,6 @@
// Deallocate command-line and environment block strings.
delete[] command_line_;
delete[] environment_block_;
- if (system_working_directory_ != NULL) {
- free(const_cast<wchar_t*>(system_working_directory_));
- }
if (attribute_list_ != NULL) {
delete_proc_thread_attr_list(attribute_list_);
free(attribute_list_);
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index e7646da..559305c 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -189,7 +189,6 @@
~InterfaceSocketAddress() {
delete socket_address_;
- free(const_cast<char*>(interface_name_));
}
SocketAddress* socket_address() const { return socket_address_; }
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index 606a817..da234f0 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -5,6 +5,9 @@
#include "platform/globals.h"
#if defined(TARGET_OS_ANDROID)
+#include "bin/socket.h"
+#include "bin/socket_android.h"
+
#include <errno.h> // NOLINT
#include <stdio.h> // NOLINT
#include <stdlib.h> // NOLINT
@@ -15,11 +18,8 @@
#include "bin/fdutils.h"
#include "bin/file.h"
-#include "bin/socket.h"
-
#include "platform/signal_blocker.h"
-
namespace dart {
namespace bin {
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index 976bd0f..575da3b 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -5,6 +5,9 @@
#include "platform/globals.h"
#if defined(TARGET_OS_LINUX)
+#include "bin/socket.h"
+#include "bin/socket_linux.h"
+
#include <errno.h> // NOLINT
#include <stdio.h> // NOLINT
#include <stdlib.h> // NOLINT
@@ -17,11 +20,9 @@
#include "bin/fdutils.h"
#include "bin/file.h"
-#include "bin/socket.h"
#include "bin/thread.h"
#include "platform/signal_blocker.h"
-
namespace dart {
namespace bin {
@@ -355,8 +356,9 @@
int i = 0;
for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
+ char* ifa_name = DartUtils::ScopedCopyCString(ifa->ifa_name);
addresses->SetAt(i, new InterfaceSocketAddress(
- ifa->ifa_addr, strdup(ifa->ifa_name), if_nametoindex(ifa->ifa_name)));
+ ifa->ifa_addr, ifa_name, if_nametoindex(ifa->ifa_name)));
i++;
}
}
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 205793b..22613d5 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -5,6 +5,9 @@
#include "platform/globals.h"
#if defined(TARGET_OS_MACOS)
+#include "bin/socket.h"
+#include "bin/socket_macos.h"
+
#include <errno.h> // NOLINT
#include <stdio.h> // NOLINT
#include <stdlib.h> // NOLINT
@@ -17,11 +20,8 @@
#include "bin/fdutils.h"
#include "bin/file.h"
-#include "bin/socket.h"
-
#include "platform/signal_blocker.h"
-
namespace dart {
namespace bin {
@@ -359,8 +359,9 @@
int i = 0;
for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
+ char* ifa_name = DartUtils::ScopedCopyCString(ifa->ifa_name);
addresses->SetAt(i, new InterfaceSocketAddress(
- ifa->ifa_addr, strdup(ifa->ifa_name), if_nametoindex(ifa->ifa_name)));
+ ifa->ifa_addr, ifa_name, if_nametoindex(ifa->ifa_name)));
i++;
}
}
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 19625e7..30bdc44 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -5,17 +5,18 @@
#include "platform/globals.h"
#if defined(TARGET_OS_WINDOWS)
+#include "bin/socket.h"
+#include "bin/socket_win.h"
+
#include "bin/builtin.h"
#include "bin/eventhandler.h"
#include "bin/file.h"
#include "bin/lockers.h"
#include "bin/log.h"
-#include "bin/socket.h"
#include "bin/thread.h"
#include "bin/utils.h"
#include "bin/utils_win.h"
-
namespace dart {
namespace bin {
@@ -366,7 +367,6 @@
ASSERT(type == SocketAddress::TYPE_IPV6);
result = InetPton(AF_INET6, system_address, &addr->in6.sin6_addr);
}
- free(const_cast<wchar_t*>(system_address));
return result == 1;
}
diff --git a/runtime/bin/utils_win.cc b/runtime/bin/utils_win.cc
index 116ae56..227cc24 100644
--- a/runtime/bin/utils_win.cc
+++ b/runtime/bin/utils_win.cc
@@ -47,9 +47,9 @@
FormatMessageIntoBuffer(code_, message, kMaxMessageLength);
char* utf8 = StringUtilsWin::WideToUtf8(message);
SetMessage(utf8);
- free(utf8);
}
+
void OSError::SetCodeAndMessage(SubSystem sub_system, int code) {
set_sub_system(sub_system);
set_code(code);
@@ -59,20 +59,22 @@
FormatMessageIntoBuffer(code_, message, kMaxMessageLength);
char* utf8 = StringUtilsWin::WideToUtf8(message);
SetMessage(utf8);
- free(utf8);
}
+
char* StringUtils::ConsoleStringToUtf8(char* str,
intptr_t len,
intptr_t* result_len) {
int wide_len = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
- wchar_t* wide = new wchar_t[wide_len];
+ wchar_t* wide;
+ wide =
+ reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(wide_len * sizeof(*wide)));
MultiByteToWideChar(CP_ACP, 0, str, len, wide, wide_len);
char* utf8 = StringUtilsWin::WideToUtf8(wide, wide_len, result_len);
- delete[] wide;
return utf8;
}
+
char* StringUtils::Utf8ToConsoleString(char* utf8,
intptr_t len,
intptr_t* result_len) {
@@ -80,19 +82,20 @@
wchar_t* wide = StringUtilsWin::Utf8ToWide(utf8, len, &wide_len);
int system_len = WideCharToMultiByte(
CP_ACP, 0, wide, wide_len, NULL, 0, NULL, NULL);
- char* ansi = reinterpret_cast<char*>(malloc(system_len));
+ char* ansi;
+ ansi =
+ reinterpret_cast<char*>(Dart_ScopeAllocate(system_len * sizeof(*ansi)));
if (ansi == NULL) {
- free(wide);
return NULL;
}
WideCharToMultiByte(CP_ACP, 0, wide, wide_len, ansi, system_len, NULL, NULL);
- free(wide);
if (result_len != NULL) {
*result_len = system_len;
}
return ansi;
}
+
char* StringUtilsWin::WideToUtf8(wchar_t* wide,
intptr_t len,
intptr_t* result_len) {
@@ -100,7 +103,8 @@
// NUL byte in the length.
int utf8_len = WideCharToMultiByte(
CP_UTF8, 0, wide, len, NULL, 0, NULL, NULL);
- char* utf8 = reinterpret_cast<char*>(malloc(utf8_len));
+ char* utf8;
+ utf8 = reinterpret_cast<char*>(Dart_ScopeAllocate(utf8_len * sizeof(*utf8)));
WideCharToMultiByte(CP_UTF8, 0, wide, len, utf8, utf8_len, NULL, NULL);
if (result_len != NULL) {
*result_len = utf8_len;
@@ -115,8 +119,9 @@
// If len is -1 then MultiByteToWideChar will include the terminating
// NUL byte in the length.
int wide_len = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0);
- wchar_t* wide =
- reinterpret_cast<wchar_t*>(malloc((wide_len) * sizeof(wchar_t)));
+ wchar_t* wide;
+ wide =
+ reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(wide_len * sizeof(*wide)));
MultiByteToWideChar(CP_UTF8, 0, utf8, len, wide, wide_len);
if (result_len != NULL) {
*result_len = wide_len;
@@ -124,6 +129,7 @@
return wide;
}
+
const char* StringUtils::Utf8ToConsoleString(
const char* utf8, intptr_t len, intptr_t* result_len) {
return const_cast<const char*>(
@@ -131,6 +137,7 @@
const_cast<char*>(utf8), len, result_len));
}
+
const char* StringUtils::ConsoleStringToUtf8(
const char* str, intptr_t len, intptr_t* result_len) {
return const_cast<const char*>(
@@ -138,23 +145,28 @@
const_cast<char*>(str), len, result_len));
}
+
const char* StringUtilsWin::WideToUtf8(
const wchar_t* wide, intptr_t len, intptr_t* result_len) {
return const_cast<const char*>(
StringUtilsWin::WideToUtf8(const_cast<wchar_t*>(wide), len, result_len));
}
+
const wchar_t* StringUtilsWin::Utf8ToWide(
const char* utf8, intptr_t len, intptr_t* result_len) {
return const_cast<const wchar_t*>(
StringUtilsWin::Utf8ToWide(const_cast<char*>(utf8), len, result_len));
}
+
bool ShellUtils::GetUtf8Argv(int argc, char** argv) {
wchar_t* command_line = GetCommandLineW();
int unicode_argc;
wchar_t** unicode_argv = CommandLineToArgvW(command_line, &unicode_argc);
- if (unicode_argv == NULL) return false;
+ if (unicode_argv == NULL) {
+ return false;
+ }
// The argc passed to main should have the same argc as we get here.
ASSERT(argc == unicode_argc);
if (argc < unicode_argc) {
@@ -162,12 +174,17 @@
}
for (int i = 0; i < unicode_argc; i++) {
wchar_t* arg = unicode_argv[i];
- argv[i] = StringUtilsWin::WideToUtf8(arg);
+ int arg_len =
+ WideCharToMultiByte(CP_UTF8, 0, arg, -1, NULL, 0, NULL, NULL);
+ char* utf8_arg = reinterpret_cast<char*>(malloc(arg_len));
+ WideCharToMultiByte(CP_UTF8, 0, arg, -1, utf8_arg, arg_len, NULL, NULL);
+ argv[i] = utf8_arg;
}
LocalFree(unicode_argv);
return true;
}
+
static int64_t GetCurrentTimeMicros() {
static const int64_t kTimeEpoc = 116444736000000000LL;
static const int64_t kTimeScaler = 10; // 100 ns to us.
@@ -187,6 +204,7 @@
return (time.t_ - kTimeEpoc) / kTimeScaler;
}
+
static int64_t qpc_ticks_per_second = 0;
void TimerUtils::InitOnce() {
@@ -198,10 +216,12 @@
}
}
+
int64_t TimerUtils::GetCurrentMonotonicMillis() {
return GetCurrentMonotonicMicros() / 1000;
}
+
int64_t TimerUtils::GetCurrentMonotonicMicros() {
if (qpc_ticks_per_second == 0) {
// QueryPerformanceCounter not supported, fallback.
@@ -219,6 +239,7 @@
return result;
}
+
void TimerUtils::Sleep(int64_t millis) {
::Sleep(millis);
}
diff --git a/runtime/bin/utils_win.h b/runtime/bin/utils_win.h
index 92de84e..b8f9fbc 100644
--- a/runtime/bin/utils_win.h
+++ b/runtime/bin/utils_win.h
@@ -12,6 +12,11 @@
void FormatMessageIntoBuffer(DWORD code, wchar_t* buffer, int buffer_length);
+// These string utility functions return strings that have been allocated with
+// Dart_ScopeAllocate(). They should be used only when we are inside an API
+// scope. If a string returned by one of these functions must persist beyond
+// the scope, then copy the results into a suitable buffer that you have
+// allocated.
class StringUtilsWin {
public:
static char* WideToUtf8(wchar_t* wide,
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index 13be4f9..8b9b013 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -1078,4 +1078,50 @@
DART_EXPORT Dart_Handle Dart_TimelineAsyncEnd(const char* label,
int64_t async_id);
+
+/**
+ * Called by the VM to let the embedder know when to start recording into their
+ * own timeline implementation. Can be called from any thread.
+ */
+typedef void (*Dart_EmbedderTimelineStartRecording)();
+
+/**
+ * Called by the VM to let the embedder know when to stop recording into their
+ * own timeline implementation. Can be called from any thread.
+ */
+typedef void (*Dart_EmbedderTimelineStopRecording)();
+
+/**
+ * Called by the VM to request data from the embedder's private timeline
+ * implementation. Can be called from any thread and must complete
+ * synchronously.
+ *
+ * \param stream_consumer The embedder must only call the stream_consumer with
+ * the Dart_StreamConsumer_kData state. See Dart_StreamConsumer above.
+ * \param user_data
+ *
+ * \return Returns true on success.
+ *
+ */
+typedef bool (*Dart_EmbedderTimelineGetTimeline)(
+ Dart_StreamConsumer stream_consumer,
+ void* user_data);
+
+
+/**
+ * Sets the embedder timeline callbacks. These callbacks are used by the VM
+ * to notify the embedder of timeline recording state changes and to request
+ * data from the embedder.
+ *
+ * \param start_recording See Dart_EmbedderTimelineStartRecording.
+ * \param stop_recording See Dart_EmbedderTimelineStopRecording.
+ * \param get_timeline See Dart_EmbedderTimelineGetTimeline.
+ *
+ * NOTE: To avoid races, this should be called before Dart_Initialize.
+ */
+DART_EXPORT void Dart_SetEmbedderTimelineCallbacks(
+ Dart_EmbedderTimelineStartRecording start_recording,
+ Dart_EmbedderTimelineStopRecording stop_recording,
+ Dart_EmbedderTimelineGetTimeline get_timeline);
+
#endif // INCLUDE_DART_TOOLS_API_H_
diff --git a/runtime/lib/errors.cc b/runtime/lib/errors.cc
index 785950b..0387f80 100644
--- a/runtime/lib/errors.cc
+++ b/runtime/lib/errors.cc
@@ -53,7 +53,7 @@
// Allocate and throw a new TypeError or CastError.
// Arg0: index of the token of the failed type check.
// Arg1: src value.
-// Arg2: dst type name.
+// Arg2: dst type.
// Arg3: dst name.
// Arg4: type error message.
// Return value: none, throws an exception.
@@ -64,14 +64,13 @@
TokenPosition(Smi::CheckedHandle(arguments->NativeArgAt(0)).Value());
const Instance& src_value =
Instance::CheckedHandle(arguments->NativeArgAt(1));
- const String& dst_type_name =
- String::CheckedHandle(arguments->NativeArgAt(2));
+ const AbstractType& dst_type =
+ AbstractType::CheckedHandle(arguments->NativeArgAt(2));
const String& dst_name = String::CheckedHandle(arguments->NativeArgAt(3));
const String& error_msg = String::CheckedHandle(arguments->NativeArgAt(4));
- const String& src_type_name = String::Handle(
- AbstractType::Handle(src_value.GetType()).UserVisibleName());
- Exceptions::CreateAndThrowTypeError(location, src_type_name,
- dst_type_name, dst_name, error_msg);
+ const AbstractType& src_type = AbstractType::Handle(src_value.GetType());
+ Exceptions::CreateAndThrowTypeError(
+ location, src_type, dst_type, dst_name, error_msg);
UNREACHABLE();
return Object::null();
}
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 0165ed9..29c14f5 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -45,69 +45,44 @@
}
class _TypeError extends _AssertionError implements TypeError {
- _TypeError._create(String url, int line, int column,
- this._srcType, this._dstType, this._dstName,
- this._errorMsg)
+ _TypeError._create(String url, int line, int column, this._errorMsg)
: super._create("is assignable", url, line, column);
static _throwNew(int location,
Object src_value,
- String dst_type_name,
+ _Type dst_type,
String dst_name,
- String error_msg)
+ String bound_error_msg)
native "TypeError_throwNew";
static _throwNewIfNotLoaded(_LibraryPrefix prefix,
int location,
Object src_value,
- String dst_type_name,
+ _Type dst_type,
String dst_name,
- String error_msg) {
+ String bound_error_msg) {
if (!prefix.isLoaded()) {
- _throwNew(location, src_value, dst_type_name, dst_name, error_msg);
+ _throwNew(location, src_value, dst_type, dst_name, bound_error_msg);
}
}
+ String toString() => _errorMsg;
- String toString() {
- String str = (_errorMsg != null) ? _errorMsg : "";
- if ((_dstName != null) && (_dstName.length > 0)) {
- str = "${str}type '$_srcType' is not a subtype of "
- "type '$_dstType' of '$_dstName'.";
- } else {
- str = "${str}type error.";
- }
- return str;
- }
-
- final String _srcType;
- final String _dstType;
- final String _dstName;
final String _errorMsg;
}
class _CastError extends Error implements CastError {
- _CastError._create(this._url, this._line, this._column,
- this._srcType, this._dstType, this._dstName,
- this._errorMsg);
+ _CastError._create(this._url, this._line, this._column, this._errorMsg);
// A CastError is allocated by TypeError._throwNew() when dst_name equals
- // Exceptions::kCastErrorDstName.
+ // Symbols::InTypeCast().
- String toString() {
- String str = (_errorMsg != null) ? _errorMsg : "";
- str = "${str}type '$_srcType' is not a subtype of "
- "type '$_dstType' in type cast.";
- return str;
- }
+ String toString() => _errorMsg;
// Fields _url, _line, and _column are only used for debugging purposes.
final String _url;
final int _line;
final int _column;
- final String _srcType;
- final String _dstType;
- final String _dstName;
final String _errorMsg;
}
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 09e4808..b450038 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -138,10 +138,11 @@
const char* result_str = is_instance_of ? "true" : "false";
OS::Print("Native Object.instanceOf: result %s\n", result_str);
const AbstractType& instance_type =
- AbstractType::Handle(instance.GetType());
+ AbstractType::Handle(zone, instance.GetType());
OS::Print(" instance type: %s\n",
- String::Handle(instance_type.Name()).ToCString());
- OS::Print(" test type: %s\n", String::Handle(type.Name()).ToCString());
+ String::Handle(zone, instance_type.Name()).ToCString());
+ OS::Print(" test type: %s\n",
+ String::Handle(zone, type.Name()).ToCString());
if (!bound_error.IsNull()) {
OS::Print(" bound error: %s\n", bound_error.ToErrorCString());
}
@@ -155,7 +156,7 @@
String& bound_error_message = String::Handle(
zone, String::New(bound_error.ToErrorCString()));
Exceptions::CreateAndThrowTypeError(
- location, Symbols::Empty(), Symbols::Empty(),
+ location, AbstractType::Handle(zone), AbstractType::Handle(zone),
Symbols::Empty(), bound_error_message);
UNREACHABLE();
}
@@ -224,15 +225,16 @@
DEFINE_NATIVE_ENTRY(Object_as, 3) {
- const Instance& instance = Instance::CheckedHandle(arguments->NativeArgAt(0));
+ const Instance& instance =
+ Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
const TypeArguments& instantiator_type_arguments =
- TypeArguments::CheckedHandle(arguments->NativeArgAt(1));
- const AbstractType& type =
- AbstractType::CheckedHandle(arguments->NativeArgAt(2));
+ TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(1));
+ AbstractType& type =
+ AbstractType::CheckedHandle(zone, arguments->NativeArgAt(2));
ASSERT(type.IsFinalized());
ASSERT(!type.IsMalformed());
ASSERT(!type.IsMalbounded());
- Error& bound_error = Error::Handle();
+ Error& bound_error = Error::Handle(zone);
if (instance.IsNull()) {
return instance.raw();
}
@@ -243,10 +245,11 @@
const char* result_str = is_instance_of ? "true" : "false";
OS::Print("Object.as: result %s\n", result_str);
const AbstractType& instance_type =
- AbstractType::Handle(instance.GetType());
+ AbstractType::Handle(zone, instance.GetType());
OS::Print(" instance type: %s\n",
- String::Handle(instance_type.Name()).ToCString());
- OS::Print(" cast type: %s\n", String::Handle(type.Name()).ToCString());
+ String::Handle(zone, instance_type.Name()).ToCString());
+ OS::Print(" cast type: %s\n",
+ String::Handle(zone, type.Name()).ToCString());
if (!bound_error.IsNull()) {
OS::Print(" bound error: %s\n", bound_error.ToErrorCString());
}
@@ -257,33 +260,23 @@
ASSERT(caller_frame != NULL);
const TokenPosition location = caller_frame->GetTokenPos();
const AbstractType& instance_type =
- AbstractType::Handle(instance.GetType());
- const String& instance_type_name =
- String::Handle(instance_type.UserVisibleName());
- String& type_name = String::Handle();
+ AbstractType::Handle(zone, instance.GetType());
if (!type.IsInstantiated()) {
// Instantiate type before reporting the error.
- const AbstractType& instantiated_type = AbstractType::Handle(
- type.InstantiateFrom(instantiator_type_arguments, NULL,
- NULL, NULL, Heap::kNew));
- // Note that instantiated_type may be malformed.
- type_name = instantiated_type.UserVisibleName();
- } else {
- type_name = type.UserVisibleName();
+ type = type.InstantiateFrom(instantiator_type_arguments, NULL,
+ NULL, NULL, Heap::kNew);
+ // Note that the instantiated type may be malformed.
}
- String& bound_error_message = String::Handle();
if (bound_error.IsNull()) {
- const String& dst_name = String::ZoneHandle(
- Symbols::New(Exceptions::kCastErrorDstName));
-
Exceptions::CreateAndThrowTypeError(
- location, instance_type_name, type_name,
- dst_name, Object::null_string());
+ location, instance_type, type,
+ Symbols::InTypeCast(), Object::null_string());
} else {
ASSERT(isolate->type_checks());
- bound_error_message = String::New(bound_error.ToErrorCString());
+ const String& bound_error_message =
+ String::Handle(zone, String::New(bound_error.ToErrorCString()));
Exceptions::CreateAndThrowTypeError(
- location, instance_type_name, Symbols::Empty(),
+ location, instance_type, AbstractType::Handle(zone),
Symbols::Empty(), bound_error_message);
}
UNREACHABLE();
@@ -294,14 +287,14 @@
DEFINE_NATIVE_ENTRY(AbstractType_toString, 1) {
const AbstractType& type =
- AbstractType::CheckedHandle(arguments->NativeArgAt(0));
+ AbstractType::CheckedHandle(zone, arguments->NativeArgAt(0));
return type.UserVisibleName();
}
DEFINE_NATIVE_ENTRY(LibraryPrefix_invalidateDependentCode, 1) {
const LibraryPrefix& prefix =
- LibraryPrefix::CheckedHandle(arguments->NativeArgAt(0));
+ LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
prefix.InvalidateDependentCode();
return Bool::Get(true).raw();
}
@@ -309,7 +302,7 @@
DEFINE_NATIVE_ENTRY(LibraryPrefix_load, 1) {
const LibraryPrefix& prefix =
- LibraryPrefix::CheckedHandle(arguments->NativeArgAt(0));
+ LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
bool hasCompleted = prefix.LoadLibrary();
return Bool::Get(hasCompleted).raw();
}
@@ -317,19 +310,19 @@
DEFINE_NATIVE_ENTRY(LibraryPrefix_loadError, 1) {
const LibraryPrefix& prefix =
- LibraryPrefix::CheckedHandle(arguments->NativeArgAt(0));
+ LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
// Currently all errors are Dart instances, e.g. I/O errors
// created by deferred loading code. LanguageErrors from
// failed loading or finalization attempts are propagated and result
// in the isolate's death.
- const Instance& error = Instance::Handle(prefix.LoadError());
+ const Instance& error = Instance::Handle(zone, prefix.LoadError());
return error.raw();
}
DEFINE_NATIVE_ENTRY(LibraryPrefix_isLoaded, 1) {
const LibraryPrefix& prefix =
- LibraryPrefix::CheckedHandle(arguments->NativeArgAt(0));
+ LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
return Bool::Get(prefix.is_loaded()).raw();
}
diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc
index 28b8147..8d39988 100644
--- a/runtime/lib/typed_data.cc
+++ b/runtime/lib/typed_data.cc
@@ -163,9 +163,10 @@
// array based on available physical addressable memory on the system. The
// maximum possible length is a scaled value of kSmiMax which is set up based
// on whether the underlying architecture is 32-bit or 64-bit.
+// Argument 0 is type arguments and is ignored.
#define TYPED_DATA_NEW(name) \
-DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 1) { \
- GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); \
+DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 2) { \
+ GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1)); \
intptr_t cid = kTypedData##name##Cid; \
intptr_t len = length.Value(); \
intptr_t max = TypedData::MaxElements(cid); \
@@ -178,10 +179,11 @@
// array based on available physical addressable memory on the system. The
// maximum possible length is a scaled value of kSmiMax which is set up based
// on whether the underlying architecture is 32-bit or 64-bit.
+// Argument 0 is type arguments and is ignored.
#define EXT_TYPED_DATA_NEW(name) \
-DEFINE_NATIVE_ENTRY(ExternalTypedData_##name##_new, 1) { \
+DEFINE_NATIVE_ENTRY(ExternalTypedData_##name##_new, 2) { \
const int kAlignment = 16; \
- GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(0)); \
+ GET_NON_NULL_NATIVE_ARGUMENT(Smi, length, arguments->NativeArgAt(1)); \
intptr_t cid = kExternalTypedData##name##Cid; \
intptr_t len = length.Value(); \
intptr_t max = ExternalTypedData::MaxElements(cid); \
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index a56c39f..3abb630 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -927,10 +927,7 @@
class _Int8Array extends _TypedList with _IntListMixin implements Int8List {
// Factory constructors.
- factory _Int8Array(int length) {
- return _new(length);
- }
-
+ factory _Int8Array(int length) native "TypedData_Int8Array_new";
// Method(s) implementing List interface.
@@ -959,20 +956,15 @@
// Internal utility methods.
_Int8Array _createList(int length) {
- return _new(length);
+ return new _Int8Array(length);
}
-
- static _Int8Array _new(int length) native "TypedData_Int8Array_new";
}
class _Uint8Array extends _TypedList with _IntListMixin implements Uint8List {
// Factory constructors.
- factory _Uint8Array(int length) {
- return _new(length);
- }
-
+ factory _Uint8Array(int length) native "TypedData_Uint8Array_new";
// Methods implementing List interface.
int operator[](int index) {
@@ -999,19 +991,15 @@
// Internal utility methods.
_Uint8Array _createList(int length) {
- return _new(length);
+ return new _Uint8Array(length);
}
-
- static _Uint8Array _new(int length) native "TypedData_Uint8Array_new";
}
class _Uint8ClampedArray extends _TypedList with _IntListMixin implements Uint8ClampedList {
// Factory constructors.
- factory _Uint8ClampedArray(int length) {
- return _new(length);
- }
+ factory _Uint8ClampedArray(int length) native "TypedData_Uint8ClampedArray_new";
// Methods implementing List interface.
@@ -1039,21 +1027,15 @@
// Internal utility methods.
_Uint8ClampedArray _createList(int length) {
- return _new(length);
+ return new _Uint8ClampedArray(length);
}
-
- static _Uint8ClampedArray _new(int length)
- native "TypedData_Uint8ClampedArray_new";
}
class _Int16Array extends _TypedList with _IntListMixin implements Int16List {
// Factory constructors.
- factory _Int16Array(int length) {
- return _new(length);
- }
-
+ factory _Int16Array(int length) native "TypedData_Int16Array_new";
// Method(s) implementing List interface.
@@ -1092,7 +1074,7 @@
// Internal utility methods.
_Int16Array _createList(int length) {
- return _new(length);
+ return new _Int16Array(length);
}
int _getIndexedInt16(int index) {
@@ -1102,18 +1084,13 @@
void _setIndexedInt16(int index, int value) {
_setInt16(index * Int16List.BYTES_PER_ELEMENT, value);
}
-
- static _Int16Array _new(int length) native "TypedData_Int16Array_new";
}
class _Uint16Array extends _TypedList with _IntListMixin implements Uint16List {
// Factory constructors.
- factory _Uint16Array(int length) {
- return _new(length);
- }
-
+ factory _Uint16Array(int length) native "TypedData_Uint16Array_new";
// Method(s) implementing the List interface.
@@ -1152,7 +1129,7 @@
// Internal utility methods.
_Uint16Array _createList(int length) {
- return _new(length);
+ return new _Uint16Array(length);
}
int _getIndexedUint16(int index) {
@@ -1162,18 +1139,13 @@
void _setIndexedUint16(int index, int value) {
_setUint16(index * Uint16List.BYTES_PER_ELEMENT, value);
}
-
- static _Uint16Array _new(int length) native "TypedData_Uint16Array_new";
}
class _Int32Array extends _TypedList with _IntListMixin implements Int32List {
// Factory constructors.
- factory _Int32Array(int length) {
- return _new(length);
- }
-
+ factory _Int32Array(int length) native "TypedData_Int32Array_new";
// Method(s) implementing the List interface.
@@ -1202,7 +1174,7 @@
// Internal utility methods.
_Int32Array _createList(int length) {
- return _new(length);
+ return new _Int32Array(length);
}
int _getIndexedInt32(int index) {
@@ -1213,17 +1185,13 @@
_setInt32(index * Int32List.BYTES_PER_ELEMENT, value);
}
- static _Int32Array _new(int length) native "TypedData_Int32Array_new";
}
class _Uint32Array extends _TypedList with _IntListMixin implements Uint32List {
// Factory constructors.
- factory _Uint32Array(int length) {
- return _new(length);
- }
-
+ factory _Uint32Array(int length) native "TypedData_Uint32Array_new";
// Method(s) implementing the List interface.
@@ -1252,7 +1220,7 @@
// Internal utility methods.
_Uint32Array _createList(int length) {
- return _new(length);
+ return new _Uint32Array(length);
}
int _getIndexedUint32(int index) {
@@ -1262,18 +1230,13 @@
void _setIndexedUint32(int index, int value) {
_setUint32(index * Uint32List.BYTES_PER_ELEMENT, value);
}
-
- static _Uint32Array _new(int length) native "TypedData_Uint32Array_new";
}
class _Int64Array extends _TypedList with _IntListMixin implements Int64List {
// Factory constructors.
- factory _Int64Array(int length) {
- return _new(length);
- }
-
+ factory _Int64Array(int length) native "TypedData_Int64Array_new";
// Method(s) implementing the List interface.
@@ -1302,7 +1265,7 @@
// Internal utility methods.
_Int64Array _createList(int length) {
- return _new(length);
+ return new _Int64Array(length);
}
int _getIndexedInt64(int index) {
@@ -1312,18 +1275,13 @@
void _setIndexedInt64(int index, int value) {
_setInt64(index * Int64List.BYTES_PER_ELEMENT, value);
}
-
- static _Int64Array _new(int length) native "TypedData_Int64Array_new";
}
class _Uint64Array extends _TypedList with _IntListMixin implements Uint64List {
// Factory constructors.
- factory _Uint64Array(int length) {
- return _new(length);
- }
-
+ factory _Uint64Array(int length) native "TypedData_Uint64Array_new";
// Method(s) implementing the List interface.
@@ -1352,7 +1310,7 @@
// Internal utility methods.
_Uint64Array _createList(int length) {
- return _new(length);
+ return new _Uint64Array(length);
}
int _getIndexedUint64(int index) {
@@ -1362,18 +1320,13 @@
void _setIndexedUint64(int index, int value) {
_setUint64(index * Uint64List.BYTES_PER_ELEMENT, value);
}
-
- static _Uint64Array _new(int length) native "TypedData_Uint64Array_new";
}
class _Float32Array extends _TypedList with _DoubleListMixin implements Float32List {
// Factory constructors.
- factory _Float32Array(int length) {
- return _new(length);
- }
-
+ factory _Float32Array(int length) native "TypedData_Float32Array_new";
// Method(s) implementing the List interface.
@@ -1402,7 +1355,7 @@
// Internal utility methods.
_Float32Array _createList(int length) {
- return _new(length);
+ return new _Float32Array(length);
}
double _getIndexedFloat32(int index) {
@@ -1412,18 +1365,13 @@
void _setIndexedFloat32(int index, double value) {
_setFloat32(index * Float32List.BYTES_PER_ELEMENT, value);
}
-
- static _Float32Array _new(int length) native "TypedData_Float32Array_new";
}
class _Float64Array extends _TypedList with _DoubleListMixin implements Float64List {
// Factory constructors.
- factory _Float64Array(int length) {
- return _new(length);
- }
-
+ factory _Float64Array(int length) native "TypedData_Float64Array_new";
// Method(s) implementing the List interface.
@@ -1452,7 +1400,7 @@
// Internal utility methods.
_Float64Array _createList(int length) {
- return _new(length);
+ return new _Float64Array(length);
}
double _getIndexedFloat64(int index) {
@@ -1462,18 +1410,13 @@
void _setIndexedFloat64(int index, double value) {
_setFloat64(index * Float64List.BYTES_PER_ELEMENT, value);
}
-
- static _Float64Array _new(int length) native "TypedData_Float64Array_new";
}
class _Float32x4Array extends _TypedList with _Float32x4ListMixin implements Float32x4List {
// Factory constructors.
- factory _Float32x4Array(int length) {
- return _new(length);
- }
-
+ factory _Float32x4Array(int length) native "TypedData_Float32x4Array_new";
Float32x4 operator[](int index) {
if (index < 0 || index >= length) {
@@ -1500,7 +1443,7 @@
// Internal utility methods.
_Float32x4Array _createList(int length) {
- return _new(length);
+ return new _Float32x4Array(length);
}
Float32x4 _getIndexedFloat32x4(int index) {
@@ -1510,18 +1453,13 @@
void _setIndexedFloat32x4(int index, Float32x4 value) {
_setFloat32x4(index * Float32x4List.BYTES_PER_ELEMENT, value);
}
-
- static _Float32x4Array _new(int length) native "TypedData_Float32x4Array_new";
}
class _Int32x4Array extends _TypedList with _Int32x4ListMixin implements Int32x4List {
// Factory constructors.
- factory _Int32x4Array(int length) {
- return _new(length);
- }
-
+ factory _Int32x4Array(int length) native "TypedData_Int32x4Array_new";
Int32x4 operator[](int index) {
if (index < 0 || index >= length) {
@@ -1548,7 +1486,7 @@
// Internal utility methods.
_Int32x4Array _createList(int length) {
- return _new(length);
+ return new _Int32x4Array(length);
}
Int32x4 _getIndexedInt32x4(int index) {
@@ -1558,18 +1496,13 @@
void _setIndexedInt32x4(int index, Int32x4 value) {
_setInt32x4(index * Int32x4List.BYTES_PER_ELEMENT, value);
}
-
- static _Int32x4Array _new(int length) native "TypedData_Int32x4Array_new";
}
class _Float64x2Array extends _TypedList with _Float64x2ListMixin implements Float64x2List {
// Factory constructors.
- factory _Float64x2Array(int length) {
- return _new(length);
- }
-
+ factory _Float64x2Array(int length) native "TypedData_Float64x2Array_new";
Float64x2 operator[](int index) {
if (index < 0 || index >= length) {
@@ -1596,7 +1529,7 @@
// Internal utility methods.
_Float64x2Array _createList(int length) {
- return _new(length);
+ return new _Float64x2Array(length);
}
Float64x2 _getIndexedFloat64x2(int index) {
@@ -1606,18 +1539,13 @@
void _setIndexedFloat64x2(int index, Float64x2 value) {
_setFloat64x2(index * Float64x2List.BYTES_PER_ELEMENT, value);
}
-
- static _Float64x2Array _new(int length) native "TypedData_Float64x2Array_new";
}
class _ExternalInt8Array extends _TypedList with _IntListMixin implements Int8List {
// Factory constructors.
- factory _ExternalInt8Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalInt8Array(int length) native "ExternalTypedData_Int8Array_new";
// Method(s) implementing the List interface.
int operator[](int index) {
@@ -1647,19 +1575,13 @@
Int8List _createList(int length) {
return new Int8List(length);
}
-
- static _ExternalInt8Array _new(int length) native
- "ExternalTypedData_Int8Array_new";
}
class _ExternalUint8Array extends _TypedList with _IntListMixin implements Uint8List {
// Factory constructors.
- factory _ExternalUint8Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalUint8Array(int length) native "ExternalTypedData_Uint8Array_new";
// Method(s) implementing the List interface.
@@ -1690,18 +1612,13 @@
Uint8List _createList(int length) {
return new Uint8List(length);
}
-
- static _ExternalUint8Array _new(int length) native
- "ExternalTypedData_Uint8Array_new";
}
class _ExternalUint8ClampedArray extends _TypedList with _IntListMixin implements Uint8ClampedList {
// Factory constructors.
- factory _ExternalUint8ClampedArray(int length) {
- return _new(length);
- }
+ factory _ExternalUint8ClampedArray(int length) native "ExternalTypedData_Uint8ClampedArray_new";
// Method(s) implementing the List interface.
@@ -1732,19 +1649,13 @@
Uint8ClampedList _createList(int length) {
return new Uint8ClampedList(length);
}
-
- static _ExternalUint8ClampedArray _new(int length) native
- "ExternalTypedData_Uint8ClampedArray_new";
}
class _ExternalInt16Array extends _TypedList with _IntListMixin implements Int16List {
// Factory constructors.
- factory _ExternalInt16Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalInt16Array(int length) native "ExternalTypedData_Int16Array_new";
// Method(s) implementing the List interface.
@@ -1783,19 +1694,13 @@
void _setIndexedInt16(int index, int value) {
_setInt16(index * Int16List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalInt16Array _new(int length) native
- "ExternalTypedData_Int16Array_new";
}
class _ExternalUint16Array extends _TypedList with _IntListMixin implements Uint16List {
// Factory constructors.
- factory _ExternalUint16Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalUint16Array(int length) native "ExternalTypedData_Uint16Array_new";
// Method(s) implementing the List interface.
@@ -1834,19 +1739,13 @@
void _setIndexedUint16(int index, int value) {
_setUint16(index * Uint16List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalUint16Array _new(int length) native
- "ExternalTypedData_Uint16Array_new";
}
class _ExternalInt32Array extends _TypedList with _IntListMixin implements Int32List {
// Factory constructors.
- factory _ExternalInt32Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalInt32Array(int length) native "ExternalTypedData_Int32Array_new";
// Method(s) implementing the List interface.
@@ -1885,19 +1784,13 @@
void _setIndexedInt32(int index, int value) {
_setInt32(index * Int32List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalInt32Array _new(int length) native
- "ExternalTypedData_Int32Array_new";
}
class _ExternalUint32Array extends _TypedList with _IntListMixin implements Uint32List {
// Factory constructors.
- factory _ExternalUint32Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalUint32Array(int length) native "ExternalTypedData_Uint32Array_new";
// Method(s) implementing the List interface.
@@ -1936,19 +1829,13 @@
void _setIndexedUint32(int index, int value) {
_setUint32(index * Uint32List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalUint32Array _new(int length) native
- "ExternalTypedData_Uint32Array_new";
}
class _ExternalInt64Array extends _TypedList with _IntListMixin implements Int64List {
// Factory constructors.
- factory _ExternalInt64Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalInt64Array(int length) native "ExternalTypedData_Int64Array_new";
// Method(s) implementing the List interface.
@@ -1987,19 +1874,13 @@
void _setIndexedInt64(int index, int value) {
_setInt64(index * Int64List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalInt64Array _new(int length) native
- "ExternalTypedData_Int64Array_new";
}
class _ExternalUint64Array extends _TypedList with _IntListMixin implements Uint64List {
// Factory constructors.
- factory _ExternalUint64Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalUint64Array(int length) native "ExternalTypedData_Uint64Array_new";
// Method(s) implementing the List interface.
@@ -2038,19 +1919,13 @@
void _setIndexedUint64(int index, int value) {
_setUint64(index * Uint64List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalUint64Array _new(int length) native
- "ExternalTypedData_Uint64Array_new";
}
class _ExternalFloat32Array extends _TypedList with _DoubleListMixin implements Float32List {
// Factory constructors.
- factory _ExternalFloat32Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalFloat32Array(int length) native "ExternalTypedData_Float32Array_new";
// Method(s) implementing the List interface.
@@ -2089,19 +1964,13 @@
void _setIndexedFloat32(int index, double value) {
_setFloat32(index * Float32List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalFloat32Array _new(int length) native
- "ExternalTypedData_Float32Array_new";
}
class _ExternalFloat64Array extends _TypedList with _DoubleListMixin implements Float64List {
// Factory constructors.
- factory _ExternalFloat64Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalFloat64Array(int length) native "ExternalTypedData_Float64Array_new";
// Method(s) implementing the List interface.
@@ -2140,19 +2009,13 @@
void _setIndexedFloat64(int index, double value) {
_setFloat64(index * Float64List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalFloat64Array _new(int length) native
- "ExternalTypedData_Float64Array_new";
}
class _ExternalFloat32x4Array extends _TypedList with _Float32x4ListMixin implements Float32x4List {
// Factory constructors.
- factory _ExternalFloat32x4Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalFloat32x4Array(int length) native "ExternalTypedData_Float32x4Array_new";
// Method(s) implementing the List interface.
@@ -2191,19 +2054,13 @@
void _setIndexedFloat32x4(int index, Float32x4 value) {
_setFloat32x4(index * Float32x4List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalFloat32x4Array _new(int length) native
- "ExternalTypedData_Float32x4Array_new";
}
class _ExternalInt32x4Array extends _TypedList with _Int32x4ListMixin implements Int32x4List {
// Factory constructors.
- factory _ExternalInt32x4Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalInt32x4Array(int length) native "ExternalTypedData_Int32x4Array_new";
// Method(s) implementing the List interface.
@@ -2242,19 +2099,13 @@
void _setIndexedInt32x4(int index, Int32x4 value) {
_setInt32x4(index * Int32x4List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalInt32x4Array _new(int length) native
- "ExternalTypedData_Int32x4Array_new";
}
class _ExternalFloat64x2Array extends _TypedList with _Float64x2ListMixin implements Float64x2List {
// Factory constructors.
- factory _ExternalFloat64x2Array(int length) {
- return _new(length);
- }
-
+ factory _ExternalFloat64x2Array(int length) native "ExternalTypedData_Float64x2Array_new";
// Method(s) implementing the List interface.
@@ -2293,9 +2144,6 @@
void _setIndexedFloat64x2(int index, Float64x2 value) {
_setFloat64x2(index * Float64x2List.BYTES_PER_ELEMENT, value);
}
-
- static _ExternalFloat64x2Array _new(int length) native
- "ExternalTypedData_Float64x2Array_new";
}
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index aa3c0a8..6528c8d 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -361,6 +361,42 @@
}
}
+class ScriptLineProfile {
+ ScriptLineProfile(this.line, this.sampleCount);
+
+ static const kHotThreshold = 0.05; // 5%.
+ static const kMediumThreshold = 0.02; // 2%.
+
+ final int line;
+ final int sampleCount;
+
+ int selfTicks = 0;
+ int totalTicks = 0;
+
+ void process(int exclusive, int inclusive) {
+ selfTicks += exclusive;
+ totalTicks += inclusive;
+ }
+
+ String get formattedSelfTicks {
+ return Utils.formatPercent(selfTicks, sampleCount);
+ }
+
+ String get formattedTotalTicks {
+ return Utils.formatPercent(totalTicks, sampleCount);
+ }
+
+ double _percent() {
+ if (sampleCount == 0) {
+ return 0.0;
+ }
+ return totalTicks / sampleCount;
+ }
+
+ bool get isHot => _percent() > kHotThreshold;
+ bool get isMedium => _percent() > kMediumThreshold;
+}
+
/// Box with script source code in it.
@CustomTag('script-inset')
class ScriptInsetElement extends ObservatoryElement {
@@ -378,6 +414,7 @@
@published Element scroller;
RefreshButtonElement _refreshButton;
+ ToggleButtonElement _toggleProfileButton;
int _currentLine;
int _currentCol;
@@ -387,6 +424,7 @@
Map<int, List<ServiceMap>> _rangeMap = {};
Set _callSites = new Set<CallSite>();
Set _possibleBreakpointLines = new Set<int>();
+ Map<int, ScriptLineProfile> _profileMap = {};
var annotations = [];
var annotationsCursor;
@@ -396,6 +434,7 @@
StreamSubscription _scrollSubscription;
bool hasLoadedLibraryDeclarations = false;
+ bool _includeProfile = false;
String makeLineId(int line) {
return 'line-$line';
@@ -435,13 +474,17 @@
}
void _onScroll(event) {
- if (_refreshButton == null) {
- return;
+ if (_refreshButton != null) {
+ var newTop = _buttonTop(_refreshButton);
+ if (_refreshButton.style.top != newTop) {
+ _refreshButton.style.top = '${newTop}px';
+ }
}
- var currentTop = _refreshButton.style.top;
- var newTop = _refreshButtonTop();
- if (currentTop != newTop) {
- _refreshButton.style.top = '${newTop}px';
+ if (_toggleProfileButton != null) {
+ var newTop = _buttonTop(_toggleProfileButton);
+ if (_toggleProfileButton.style.top != newTop) {
+ _toggleProfileButton.style.top = '${newTop}px';
+ }
}
}
@@ -535,12 +578,18 @@
// Build _rangeMap and _callSites from a source report.
Future _refreshSourceReport() async {
+ var reports = [Isolate.kCallSitesReport,
+ Isolate.kPossibleBreakpointsReport];
+ if (_includeProfile) {
+ reports.add(Isolate.kProfileReport);
+ }
var sourceReport = await script.isolate.getSourceReport(
- [Isolate.kCallSitesReport, Isolate.kPossibleBreakpointsReport],
+ reports,
script, startPos, endPos);
_possibleBreakpointLines = getPossibleBreakpointLines(sourceReport, script);
_rangeMap.clear();
_callSites.clear();
+ _profileMap.clear();
for (var range in sourceReport['ranges']) {
int startLine = script.tokenToLine(range['startPos']);
int endLine = script.tokenToLine(range['endPos']);
@@ -552,6 +601,28 @@
rangeList.add(range);
}
}
+ if (_includeProfile && range['profile'] != null) {
+ List positions = range['profile']['positions'];
+ List exclusiveTicks = range['profile']['exclusiveTicks'];
+ List inclusiveTicks = range['profile']['inclusiveTicks'];
+ int sampleCount = range['profile']['metadata']['sampleCount'];
+ assert(positions.length == exclusiveTicks.length);
+ assert(positions.length == inclusiveTicks.length);
+ for (int i = 0; i < positions.length; i++) {
+ if (positions[i] is String) {
+ // String positions are classifying token positions.
+ // TODO(johnmccutchan): Add classifier data to UI.
+ continue;
+ }
+ int line = script.tokenToLine(positions[i]);
+ ScriptLineProfile lineProfile = _profileMap[line];
+ if (lineProfile == null) {
+ lineProfile = new ScriptLineProfile(line, sampleCount);
+ _profileMap[line] = lineProfile;
+ }
+ lineProfile.process(exclusiveTicks[i], inclusiveTicks[i]);
+ }
+ }
if (range['compiled']) {
var rangeCallSites = range['callSites'];
if (rangeCallSites != null) {
@@ -901,14 +972,14 @@
}
}
- int _refreshButtonTop() {
- if (_refreshButton == null) {
+ int _buttonTop(Element element) {
+ if (element == null) {
return 5;
}
const padding = 5;
const navbarHeight = NavBarElement.height;
var rect = getBoundingClientRect();
- var buttonHeight = _refreshButton.clientHeight;
+ var buttonHeight = element.clientHeight;
return min(max(0, navbarHeight - rect.top) + padding,
rect.height - (buttonHeight + padding));
}
@@ -917,9 +988,37 @@
var button = new Element.tag('refresh-button');
button.style.position = 'absolute';
button.style.display = 'inline-block';
- button.style.top = '${_refreshButtonTop()}px';
+ button.style.top = '${_buttonTop(null)}px';
button.style.right = '5px';
button.callback = _refresh;
+ button.title = 'Refresh coverage';
+ return button;
+ }
+
+ ToggleButtonElement _newToggleProfileButton() {
+ ToggleButtonElement button = new Element.tag('toggle-button');
+ button.style.position = 'absolute';
+ button.style.display = 'inline-block';
+ button.style.top = '${_buttonTop(null)}px';
+ button.style.right = '30px';
+ button.title = 'Toggle CPU profile information';
+ final String enabledColor = 'black';
+ final String disabledColor = 'rgba(0, 0, 0 ,.3)';
+ button.callback = (enabled) async {
+ _includeProfile = enabled;
+ if (button.children.length > 0) {
+ var content = button.children[0];
+ if (enabled) {
+ content.style.color = enabledColor;
+ } else {
+ content.style.color = disabledColor;
+ }
+ }
+ await update();
+ };
+ button.children.add(new Element.tag('icon-whatshot'));
+ button.children[0].style.color = disabledColor;
+ button.enabled = _includeProfile;
return button;
}
@@ -928,7 +1027,9 @@
table.classes.add("sourceTable");
_refreshButton = _newRefreshButton();
+ _toggleProfileButton = _newToggleProfileButton();
table.append(_refreshButton);
+ table.append(_toggleProfileButton);
if (_startLine == null || _endLine == null) {
return table;
@@ -996,10 +1097,60 @@
e.classes.add("sourceRow");
e.append(lineBreakpointElement(line));
e.append(lineNumberElement(line, lineNumPad));
+ if (_includeProfile) {
+ e.append(lineProfileElement(line, false));
+ e.append(lineProfileElement(line, true));
+ }
e.append(lineSourceElement(line));
return e;
}
+ Element lineProfileElement(ScriptLine line, bool self) {
+ var e = span('');
+ e.classes.add('noCopy');
+ if (self) {
+ e.title = 'Self %';
+ } else {
+ e.title = 'Total %';
+ }
+
+ if (line == null) {
+ e.classes.add('notSourceProfile');
+ e.text = nbsp;
+ return e;
+ }
+
+ var ranges = _rangeMap[line.line];
+ if ((ranges == null) || ranges.isEmpty) {
+ e.classes.add('notSourceProfile');
+ e.text = nbsp;
+ return e;
+ }
+
+ ScriptLineProfile lineProfile = _profileMap[line.line];
+ if (lineProfile == null) {
+ e.classes.add('noProfile');
+ e.text = nbsp;
+ return e;
+ }
+
+ if (self) {
+ e.text = lineProfile.formattedSelfTicks;
+ } else {
+ e.text = lineProfile.formattedTotalTicks;
+ }
+
+ if (lineProfile.isHot) {
+ e.classes.add('hotProfile');
+ } else if (lineProfile.isMedium) {
+ e.classes.add('mediumProfile');
+ } else {
+ e.classes.add('coldProfile');
+ }
+
+ return e;
+ }
+
Element lineBreakpointElement(ScriptLine line) {
var e = new DivElement();
if (line == null || !_possibleBreakpointLines.contains(line.line)) {
@@ -1191,6 +1342,22 @@
}
+@CustomTag('toggle-button')
+class ToggleButtonElement extends PolymerElement {
+ ToggleButtonElement.created() : super.created();
+
+ @published var callback = null;
+ @observable bool enabled = false;
+
+ Future buttonClick(var event, var b, var c) async {
+ enabled = !enabled;
+ if (callback != null) {
+ await callback(enabled);
+ }
+ }
+}
+
+
@CustomTag('source-inset')
class SourceInsetElement extends PolymerElement {
SourceInsetElement.created() : super.created();
diff --git a/runtime/observatory/lib/src/elements/script_inset.html b/runtime/observatory/lib/src/elements/script_inset.html
index 92d2940..dd21155 100644
--- a/runtime/observatory/lib/src/elements/script_inset.html
+++ b/runtime/observatory/lib/src/elements/script_inset.html
@@ -14,6 +14,19 @@
</template>
</polymer-element>
+<polymer-element name="icon-whatshot" noscript>
+ <template>
+ <style>
+ svg {
+ fill: currentColor
+ }
+ </style>
+ <svg width="24" height="24">
+ <path d="M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 4.04 0 2.65-2.15 4.8-4.8 4.8z"></path>
+ </svg>
+ </template>
+</polymer-element>
+
<polymer-element name="script-inset" extends="observatory-element">
<template>
<style>
@@ -116,6 +129,30 @@
color: white;
background-color: #e66;
}
+ .notSourceProfile, .noProfile, .coldProfile, .mediumProfile, .hotProfile {
+ display: table-cell;
+ vertical-align: top;
+ font: 400 14px consolas, courier, monospace;
+ width: 4em;
+ text-align: right;
+ cursor: pointer;
+ margin-left: 5px;
+ margin-right: 5px;
+ }
+ .notSourceProfile {
+ }
+ .noProfile {
+ background-color: #e0e0e0;
+ }
+ .coldProfile {
+ background-color: #aea;
+ }
+ .mediumProfile {
+ background-color: #fe9;
+ }
+ .hotProfile {
+ background-color: #faa;
+ }
</style>
</template>
</polymer-element>
@@ -148,6 +185,25 @@
</template>
</polymer-element>
+<polymer-element name="toggle-button">
+ <template>
+ <style>
+ </style>
+ <template if="{{ callback != null }}">
+ <template if="{{ enabled }}">
+ <a on-click="{{ buttonClick }}">
+ <content></content>
+ </a>
+ </template>
+ <template if="{{ !enabled }}">
+ <a on-click="{{ buttonClick }}">
+ <content></content>
+ </a>
+ </template>
+ </template>
+ </template>
+</polymer-element>
+
<polymer-element name="source-inset">
<template>
<template if="{{ location != null }}">
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 3345716..19a086c 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1171,6 +1171,7 @@
static const kCallSitesReport = '_CallSites';
static const kPossibleBreakpointsReport = 'PossibleBreakpoints';
+ static const kProfileReport = '_Profile';
Future<ServiceMap> getSourceReport(List<String> report_kinds,
[Script script,
diff --git a/runtime/platform/text_buffer.cc b/runtime/platform/text_buffer.cc
index b9c6ac7..1536dac 100644
--- a/runtime/platform/text_buffer.cc
+++ b/runtime/platform/text_buffer.cc
@@ -48,6 +48,14 @@
}
+void TextBuffer::AddRaw(const uint8_t* buffer,
+ intptr_t buffer_length) {
+ EnsureCapacity(buffer_length);
+ memmove(&buf_[msg_len_], buffer, buffer_length);
+ msg_len_ += buffer_length;
+ buf_[msg_len_] = '\0';
+}
+
intptr_t TextBuffer::Printf(const char* format, ...) {
va_list args;
va_start(args, format);
diff --git a/runtime/platform/text_buffer.h b/runtime/platform/text_buffer.h
index f8f0c2f..1908ecb 100644
--- a/runtime/platform/text_buffer.h
+++ b/runtime/platform/text_buffer.h
@@ -23,6 +23,8 @@
void EscapeAndAddCodeUnit(uint32_t cu);
void AddString(const char* s);
void AddEscapedString(const char* s);
+ void AddRaw(const uint8_t* buffer,
+ intptr_t buffer_length);
void Clear();
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index a0c7a40..c8a025f 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -52,7 +52,7 @@
dart/inline_stack_frame_test: RuntimeError, Pass # Issue 7953
[ $compiler == dart2js && $cps_ir && $checked ]
-dart/inline_stack_frame_test: Crash # Unable to compile ArgumentError.message
+dart/*: Skip # checked mode + cpsir not supported yet. Issue 25761
[ $compiler == dart2js || $compiler == dart2analyzer ]
# Data uri's not supported by dart2js or the analyzer.
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index 49f9f18..102cf96 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -2386,14 +2386,12 @@
return;
}
}
- const String& dst_name = String::ZoneHandle(Z,
- Symbols::New(Exceptions::kCastErrorDstName));
AssertAssignableInstr* assert_as =
new(Z) AssertAssignableInstr(call->token_pos(),
new(Z) Value(left),
new(Z) Value(type_args),
type,
- dst_name,
+ Symbols::InTypeCast(),
call->deopt_id());
ReplaceCall(call, assert_as);
}
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 4043fc1..6f8cf47 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -2754,6 +2754,13 @@
}
+void Assembler::BranchLinkToRuntime() {
+ ldr(IP, Address(THR, Thread::call_to_runtime_entry_point_offset()));
+ ldr(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
+ blx(IP);
+}
+
+
void Assembler::BranchLinkWithEquivalence(const StubEntry& stub_entry,
const Object& equivalence) {
const Code& target = Code::Handle(stub_entry.code());
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index b3014fb..a85dd43 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -675,6 +675,7 @@
void BranchLink(const StubEntry& stub_entry,
Patchability patchable = kNotPatchable);
void BranchLink(const Code& code, Patchability patchable);
+ void BranchLinkToRuntime();
// Branch and link to an entry address. Call sequence can be patched.
void BranchLinkPatchable(const StubEntry& stub_entry);
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index 70b2f2c..a481b7b 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -612,6 +612,13 @@
}
+void Assembler::BranchLinkToRuntime() {
+ ldr(LR, Address(THR, Thread::call_to_runtime_entry_point_offset()));
+ ldr(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
+ blr(LR);
+}
+
+
void Assembler::BranchLinkWithEquivalence(const StubEntry& stub_entry,
const Object& equivalence) {
const Code& target = Code::Handle(stub_entry.code());
diff --git a/runtime/vm/assembler_arm64.h b/runtime/vm/assembler_arm64.h
index 1475625..ee8eb70 100644
--- a/runtime/vm/assembler_arm64.h
+++ b/runtime/vm/assembler_arm64.h
@@ -1228,6 +1228,7 @@
Patchability patchable = kNotPatchable);
void BranchLinkPatchable(const StubEntry& stub_entry);
+ void BranchLinkToRuntime();
// Emit a call that shares its object pool entries with other calls
// that have the same equivalence marker.
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index 2759cd2..b9e80d0 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -2645,6 +2645,12 @@
}
+void Assembler::CallToRuntime() {
+ movl(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
+ call(Address(THR, Thread::call_to_runtime_entry_point_offset()));
+}
+
+
void Assembler::Jmp(const StubEntry& stub_entry) {
const ExternalLabel label(stub_entry.EntryPoint());
jmp(&label);
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index 075ac70..536a06e 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -738,6 +738,7 @@
void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count);
void Call(const StubEntry& stub_entry);
+ void CallToRuntime();
void Jmp(const StubEntry& stub_entry);
void J(Condition condition, const StubEntry& stub_entry);
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index f5cbd1a..98aebcb 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -533,6 +533,13 @@
}
+void Assembler::BranchLinkToRuntime() {
+ lw(T9, Address(THR, Thread::call_to_runtime_entry_point_offset()));
+ lw(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
+ jalr(T9);
+}
+
+
void Assembler::BranchLinkWithEquivalence(const StubEntry& stub_entry,
const Object& equivalence) {
const Code& target = Code::Handle(stub_entry.code());
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 0ca7945..4e4f7f3 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -929,6 +929,7 @@
Patchability patchable = kNotPatchable);
void BranchLinkPatchable(const StubEntry& stub_entry);
+ void BranchLinkToRuntime();
// Emit a call that shares its object pool entries with other calls
// that have the same equivalence marker.
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index e80efe6..1418548 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -117,6 +117,13 @@
}
+void Assembler::CallToRuntime() {
+ movq(TMP, Address(THR, Thread::call_to_runtime_entry_point_offset()));
+ movq(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
+ call(TMP);
+}
+
+
void Assembler::pushq(Register reg) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitRegisterREX(reg, REX_NONE);
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 95c474b..4f6eac3 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -773,6 +773,7 @@
void J(Condition condition, const StubEntry& stub_entry, Register pp);
void CallPatchable(const StubEntry& stub_entry);
void Call(const StubEntry& stub_entry);
+ void CallToRuntime();
// Emit a call that shares its object pool entries with other calls
// that have the same equivalence marker.
void CallWithEquivalence(const StubEntry& stub_entry,
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 8cb5d77..07da822 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -355,9 +355,12 @@
// Eagerly compile the _Closure class as it is the class of all closure
// instances. This allows us to just finalize function types
// without going through the hoops of trying to compile their scope class.
- const Class& cls =
+ Class& cls =
Class::Handle(zone, isolate->object_store()->closure_class());
Compiler::CompileClass(cls);
+ // Eagerly compile Bool class, bool constants are used from within compiler.
+ cls = isolate->object_store()->bool_class();
+ Compiler::CompileClass(cls);
}
// Restore the library tag handler for the isolate.
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 02b1e3c..03f2869 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -164,34 +164,34 @@
V(Timeline_reportCompleteEvent, 5) \
V(Timeline_reportInstantEvent, 4) \
V(Timeline_reportTaskEvent, 6) \
- V(TypedData_Int8Array_new, 1) \
- V(TypedData_Uint8Array_new, 1) \
- V(TypedData_Uint8ClampedArray_new, 1) \
- V(TypedData_Int16Array_new, 1) \
- V(TypedData_Uint16Array_new, 1) \
- V(TypedData_Int32Array_new, 1) \
- V(TypedData_Uint32Array_new, 1) \
- V(TypedData_Int64Array_new, 1) \
- V(TypedData_Uint64Array_new, 1) \
- V(TypedData_Float32Array_new, 1) \
- V(TypedData_Float64Array_new, 1) \
- V(TypedData_Float32x4Array_new, 1) \
- V(TypedData_Int32x4Array_new, 1) \
- V(TypedData_Float64x2Array_new, 1) \
- V(ExternalTypedData_Int8Array_new, 1) \
- V(ExternalTypedData_Uint8Array_new, 1) \
- V(ExternalTypedData_Uint8ClampedArray_new, 1) \
- V(ExternalTypedData_Int16Array_new, 1) \
- V(ExternalTypedData_Uint16Array_new, 1) \
- V(ExternalTypedData_Int32Array_new, 1) \
- V(ExternalTypedData_Uint32Array_new, 1) \
- V(ExternalTypedData_Int64Array_new, 1) \
- V(ExternalTypedData_Uint64Array_new, 1) \
- V(ExternalTypedData_Float32Array_new, 1) \
- V(ExternalTypedData_Float64Array_new, 1) \
- V(ExternalTypedData_Float32x4Array_new, 1) \
- V(ExternalTypedData_Int32x4Array_new, 1) \
- V(ExternalTypedData_Float64x2Array_new, 1) \
+ V(TypedData_Int8Array_new, 2) \
+ V(TypedData_Uint8Array_new, 2) \
+ V(TypedData_Uint8ClampedArray_new, 2) \
+ V(TypedData_Int16Array_new, 2) \
+ V(TypedData_Uint16Array_new, 2) \
+ V(TypedData_Int32Array_new, 2) \
+ V(TypedData_Uint32Array_new, 2) \
+ V(TypedData_Int64Array_new, 2) \
+ V(TypedData_Uint64Array_new, 2) \
+ V(TypedData_Float32Array_new, 2) \
+ V(TypedData_Float64Array_new, 2) \
+ V(TypedData_Float32x4Array_new, 2) \
+ V(TypedData_Int32x4Array_new, 2) \
+ V(TypedData_Float64x2Array_new, 2) \
+ V(ExternalTypedData_Int8Array_new, 2) \
+ V(ExternalTypedData_Uint8Array_new, 2) \
+ V(ExternalTypedData_Uint8ClampedArray_new, 2) \
+ V(ExternalTypedData_Int16Array_new, 2) \
+ V(ExternalTypedData_Uint16Array_new, 2) \
+ V(ExternalTypedData_Int32Array_new, 2) \
+ V(ExternalTypedData_Uint32Array_new, 2) \
+ V(ExternalTypedData_Int64Array_new, 2) \
+ V(ExternalTypedData_Uint64Array_new, 2) \
+ V(ExternalTypedData_Float32Array_new, 2) \
+ V(ExternalTypedData_Float64Array_new, 2) \
+ V(ExternalTypedData_Float32x4Array_new, 2) \
+ V(ExternalTypedData_Int32x4Array_new, 2) \
+ V(ExternalTypedData_Float64x2Array_new, 2) \
V(TypedData_length, 1) \
V(TypedData_setRange, 7) \
V(TypedData_GetInt8, 2) \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index d1e9f5b..81860b2 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1065,7 +1065,7 @@
if (FLAG_trace_type_finalization) {
THR_Print("Marking type '%s' as malbounded: %s\n",
String::Handle(Z, type.Name()).ToCString(),
- bound_error.ToCString());
+ bound_error.ToErrorCString());
}
}
}
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 652cdc2..85212a7 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -32,10 +32,6 @@
DEFINE_FLAG(int, regexp_optimization_counter_threshold, 1000,
"RegExp's usage-counter value before it is optimized, -1 means never");
DEFINE_FLAG(charp, optimization_filter, NULL, "Optimize only named function");
-// TODO(srdjan): Remove this flag once background compilation of regular
-// expressions is possible.
-DEFINE_FLAG(bool, regexp_opt_in_background, false,
- "Optimize reg-exp functions in background");
DEFINE_FLAG(int, reoptimization_counter_threshold, 4000,
"Counter threshold before a function gets reoptimized.");
DEFINE_FLAG(bool, stop_on_excessive_deoptimization, false,
@@ -190,21 +186,21 @@
// Arg1: instantiator type arguments.
// Return value: instantiated type.
DEFINE_RUNTIME_ENTRY(InstantiateType, 2) {
- AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(0));
+ AbstractType& type = AbstractType::CheckedHandle(zone, arguments.ArgAt(0));
const TypeArguments& instantiator =
- TypeArguments::CheckedHandle(arguments.ArgAt(1));
+ TypeArguments::CheckedHandle(zone, arguments.ArgAt(1));
ASSERT(!type.IsNull() && !type.IsInstantiated());
ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
- Error& bound_error = Error::Handle();
+ Error& bound_error = Error::Handle(zone);
type =
type.InstantiateFrom(instantiator, &bound_error, NULL, NULL, Heap::kOld);
if (!bound_error.IsNull()) {
// Throw a dynamic type error.
const TokenPosition location = GetCallerLocation();
String& bound_error_message = String::Handle(
- String::New(bound_error.ToErrorCString()));
+ zone, String::New(bound_error.ToErrorCString()));
Exceptions::CreateAndThrowTypeError(
- location, Symbols::Empty(), Symbols::Empty(),
+ location, AbstractType::Handle(zone), AbstractType::Handle(zone),
Symbols::Empty(), bound_error_message);
UNREACHABLE();
}
@@ -224,16 +220,16 @@
// Return value: instantiated type arguments.
DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) {
TypeArguments& type_arguments =
- TypeArguments::CheckedHandle(arguments.ArgAt(0));
+ TypeArguments::CheckedHandle(zone, arguments.ArgAt(0));
const TypeArguments& instantiator =
- TypeArguments::CheckedHandle(arguments.ArgAt(1));
+ TypeArguments::CheckedHandle(zone, arguments.ArgAt(1));
ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated());
ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
// Code inlined in the caller should have optimized the case where the
// instantiator can be reused as type argument vector.
ASSERT(instantiator.IsNull() || !type_arguments.IsUninstantiatedIdentity());
if (isolate->type_checks()) {
- Error& bound_error = Error::Handle();
+ Error& bound_error = Error::Handle(zone);
type_arguments =
type_arguments.InstantiateAndCanonicalizeFrom(instantiator,
&bound_error);
@@ -241,9 +237,9 @@
// Throw a dynamic type error.
const TokenPosition location = GetCallerLocation();
String& bound_error_message = String::Handle(
- String::New(bound_error.ToErrorCString()));
+ zone, String::New(bound_error.ToErrorCString()));
Exceptions::CreateAndThrowTypeError(
- location, Symbols::Empty(), Symbols::Empty(),
+ location, AbstractType::Handle(zone), AbstractType::Handle(zone),
Symbols::Empty(), bound_error_message);
UNREACHABLE();
}
@@ -260,7 +256,7 @@
// Arg0: number of variables.
// Return value: newly allocated context.
DEFINE_RUNTIME_ENTRY(AllocateContext, 1) {
- const Smi& num_variables = Smi::CheckedHandle(arguments.ArgAt(0));
+ const Smi& num_variables = Smi::CheckedHandle(zone, arguments.ArgAt(0));
arguments.SetReturn(Context::Handle(Context::New(num_variables.Value())));
}
@@ -270,8 +266,9 @@
// Arg0: the context to be cloned.
// Return value: newly allocated context.
DEFINE_RUNTIME_ENTRY(CloneContext, 1) {
- const Context& ctx = Context::CheckedHandle(arguments.ArgAt(0));
- Context& cloned_ctx = Context::Handle(Context::New(ctx.num_variables()));
+ const Context& ctx = Context::CheckedHandle(zone, arguments.ArgAt(0));
+ Context& cloned_ctx =
+ Context::Handle(zone, Context::New(ctx.num_variables()));
cloned_ctx.set_parent(Context::Handle(ctx.parent()));
Object& inst = Object::Handle(zone);
for (int i = 0; i < ctx.num_variables(); i++) {
@@ -449,17 +446,18 @@
// Arg3: SubtypeTestCache.
// Return value: true or false, or may throw a type error in checked mode.
DEFINE_RUNTIME_ENTRY(Instanceof, 4) {
- const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0));
- const AbstractType& type = AbstractType::CheckedHandle(arguments.ArgAt(1));
+ const Instance& instance = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+ const AbstractType& type =
+ AbstractType::CheckedHandle(zone, arguments.ArgAt(1));
const TypeArguments& instantiator_type_arguments =
- TypeArguments::CheckedHandle(arguments.ArgAt(2));
+ TypeArguments::CheckedHandle(zone, arguments.ArgAt(2));
const SubtypeTestCache& cache =
- SubtypeTestCache::CheckedHandle(arguments.ArgAt(3));
+ SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(3));
ASSERT(type.IsFinalized());
ASSERT(!type.IsDynamicType()); // No need to check assignment.
ASSERT(!type.IsMalformed()); // Already checked in code generator.
ASSERT(!type.IsMalbounded()); // Already checked in code generator.
- Error& bound_error = Error::Handle();
+ Error& bound_error = Error::Handle(zone);
const Bool& result =
Bool::Get(instance.IsInstanceOf(type,
instantiator_type_arguments,
@@ -472,9 +470,9 @@
// Throw a dynamic type error only if the instanceof test fails.
const TokenPosition location = GetCallerLocation();
String& bound_error_message = String::Handle(
- String::New(bound_error.ToErrorCString()));
+ zone, String::New(bound_error.ToErrorCString()));
Exceptions::CreateAndThrowTypeError(
- location, Symbols::Empty(), Symbols::Empty(),
+ location, AbstractType::Handle(zone), AbstractType::Handle(zone),
Symbols::Empty(), bound_error_message);
UNREACHABLE();
}
@@ -493,19 +491,21 @@
// Arg4: SubtypeTestCache.
// Return value: instance if a subtype, otherwise throw a TypeError.
DEFINE_RUNTIME_ENTRY(TypeCheck, 5) {
- const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0));
- AbstractType& dst_type = AbstractType::CheckedHandle(arguments.ArgAt(1));
+ const Instance& src_instance =
+ Instance::CheckedHandle(zone, arguments.ArgAt(0));
+ AbstractType& dst_type =
+ AbstractType::CheckedHandle(zone, arguments.ArgAt(1));
const TypeArguments& instantiator_type_arguments =
- TypeArguments::CheckedHandle(arguments.ArgAt(2));
- const String& dst_name = String::CheckedHandle(arguments.ArgAt(3));
+ TypeArguments::CheckedHandle(zone, arguments.ArgAt(2));
+ const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(3));
const SubtypeTestCache& cache =
- SubtypeTestCache::CheckedHandle(arguments.ArgAt(4));
+ SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(4));
ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
ASSERT(!dst_type.IsMalformed()); // Already checked in code generator.
ASSERT(!dst_type.IsMalbounded()); // Already checked in code generator.
ASSERT(!src_instance.IsNull()); // Already checked in inlined code.
- Error& bound_error = Error::Handle();
+ Error& bound_error = Error::Handle(zone);
const bool is_instance_of = src_instance.IsInstanceOf(
dst_type, instantiator_type_arguments, &bound_error);
@@ -517,25 +517,20 @@
if (!is_instance_of) {
// Throw a dynamic type error.
const TokenPosition location = GetCallerLocation();
- const AbstractType& src_type = AbstractType::Handle(src_instance.GetType());
- String& src_type_name = String::Handle(src_type.UserVisibleName());
+ const AbstractType& src_type =
+ AbstractType::Handle(zone, src_instance.GetType());
if (!dst_type.IsInstantiated()) {
// Instantiate dst_type before reporting the error.
dst_type = dst_type.InstantiateFrom(instantiator_type_arguments, NULL,
NULL, NULL, Heap::kNew);
// Note that instantiated dst_type may be malbounded.
}
- String& dst_type_name = String::Handle(dst_type.UserVisibleName());
- String& bound_error_message = String::Handle();
+ String& bound_error_message = String::Handle(zone);
if (!bound_error.IsNull()) {
ASSERT(isolate->type_checks());
bound_error_message = String::New(bound_error.ToErrorCString());
}
- if (src_type_name.Equals(dst_type_name)) {
- src_type_name = src_type.UserVisibleNameWithURI();
- dst_type_name = dst_type.UserVisibleNameWithURI();
- }
- Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name,
+ Exceptions::CreateAndThrowTypeError(location, src_type, dst_type,
dst_name, bound_error_message);
UNREACHABLE();
}
@@ -552,17 +547,18 @@
// Return value: none, throws TypeError or AssertionError.
DEFINE_RUNTIME_ENTRY(NonBoolTypeError, 1) {
const TokenPosition location = GetCallerLocation();
- const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0));
+ const Instance& src_instance =
+ Instance::CheckedHandle(zone, arguments.ArgAt(0));
if (src_instance.IsNull()) {
- const Array& args = Array::Handle(Array::New(4));
- args.SetAt(0, String::Handle(
+ const Array& args = Array::Handle(zone, Array::New(4));
+ args.SetAt(0, String::Handle(zone,
String::New("Failed assertion: boolean expression must not be null")));
// No source code for this assertion, set url to null.
- args.SetAt(1, String::Handle(String::null()));
- args.SetAt(2, Smi::Handle(Smi::New(0)));
- args.SetAt(3, Smi::Handle(Smi::New(0)));
+ args.SetAt(1, String::Handle(zone, String::null()));
+ args.SetAt(2, Smi::Handle(zone, Smi::New(0)));
+ args.SetAt(3, Smi::Handle(zone, Smi::New(0)));
Exceptions::ThrowByType(Exceptions::kAssertion, args);
UNREACHABLE();
@@ -570,12 +566,10 @@
ASSERT(!src_instance.IsBool());
const Type& bool_interface = Type::Handle(Type::BoolType());
- const AbstractType& src_type = AbstractType::Handle(src_instance.GetType());
- const String& src_type_name = String::Handle(src_type.UserVisibleName());
- const String& bool_type_name =
- String::Handle(bool_interface.UserVisibleName());
- const String& no_bound_error = String::Handle();
- Exceptions::CreateAndThrowTypeError(location, src_type_name, bool_type_name,
+ const AbstractType& src_type =
+ AbstractType::Handle(zone, src_instance.GetType());
+ const String& no_bound_error = String::Handle(zone);
+ Exceptions::CreateAndThrowTypeError(location, src_type, bool_interface,
Symbols::BooleanExpression(),
no_bound_error);
UNREACHABLE();
@@ -589,26 +583,14 @@
// Return value: none, throws an exception.
DEFINE_RUNTIME_ENTRY(BadTypeError, 3) {
const TokenPosition location = GetCallerLocation();
- const Instance& src_value = Instance::CheckedHandle(arguments.ArgAt(0));
- const String& dst_name = String::CheckedHandle(arguments.ArgAt(1));
+ const Instance& src_value = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+ const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(1));
const AbstractType& dst_type =
- AbstractType::CheckedHandle(arguments.ArgAt(2));
- const AbstractType& src_type = AbstractType::Handle(src_value.GetType());
- const String& src_type_name = String::Handle(src_type.UserVisibleName());
-
- String& dst_type_name = String::Handle();
- LanguageError& error = LanguageError::Handle(dst_type.error());
- ASSERT(!error.IsNull());
- if (error.kind() == Report::kMalformedType) {
- dst_type_name = Symbols::Malformed().raw();
- } else {
- ASSERT(error.kind() == Report::kMalboundedType);
- dst_type_name = Symbols::Malbounded().raw();
- }
- const String& error_message = String::ZoneHandle(
- Symbols::New(error.ToErrorCString()));
+ AbstractType::CheckedHandle(zone, arguments.ArgAt(2));
+ const AbstractType& src_type =
+ AbstractType::Handle(zone, src_value.GetType());
Exceptions::CreateAndThrowTypeError(
- location, src_type_name, dst_type_name, dst_name, error_message);
+ location, src_type, dst_type, dst_name, String::Handle(zone));
UNREACHABLE();
}
@@ -635,19 +617,19 @@
DartFrameIterator iterator;
StackFrame* caller_frame = iterator.NextFrame();
ASSERT(caller_frame != NULL);
- const Code& caller_code = Code::Handle(caller_frame->LookupDartCode());
+ const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
ASSERT(!caller_code.IsNull());
ASSERT(caller_code.is_optimized());
const Function& target_function = Function::Handle(
- caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc()));
+ zone, caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc()));
if (!target_function.HasCode()) {
const Error& error =
- Error::Handle(Compiler::CompileFunction(thread, target_function));
+ Error::Handle(zone, Compiler::CompileFunction(thread, target_function));
if (!error.IsNull()) {
Exceptions::PropagateError(error);
}
}
- const Code& target_code = Code::Handle(target_function.CurrentCode());
+ const Code& target_code = Code::Handle(zone, target_function.CurrentCode());
// Before patching verify that we are not repeatedly patching to the same
// target.
ASSERT(target_code.raw() !=
@@ -688,8 +670,9 @@
StackFrame* caller_frame = iterator.NextFrame();
ASSERT(caller_frame != NULL);
const Code& orig_stub = Code::Handle(
- isolate->debugger()->GetPatchedStubAddress(caller_frame->pc()));
- const Error& error = Error::Handle(isolate->debugger()->SignalBpReached());
+ zone, isolate->debugger()->GetPatchedStubAddress(caller_frame->pc()));
+ const Error& error =
+ Error::Handle(zone, isolate->debugger()->SignalBpReached());
if (!error.IsNull()) {
Exceptions::PropagateError(error);
UNREACHABLE();
@@ -704,7 +687,7 @@
return;
}
const Error& error =
- Error::Handle(isolate->debugger()->DebuggerStepCallback());
+ Error::Handle(zone, isolate->debugger()->DebuggerStepCallback());
if (!error.IsNull()) {
Exceptions::PropagateError(error);
UNREACHABLE();
@@ -1465,8 +1448,7 @@
}
}
// TODO(srdjan): Fix background compilation of regular expressions.
- if (FLAG_background_compilation &&
- (!function.IsIrregexpFunction() || FLAG_regexp_opt_in_background)) {
+ if (FLAG_background_compilation) {
if (FLAG_enable_inlining_annotations) {
FATAL("Cannot enable inlining annotations and background compilation");
}
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 6365b3c..dd5f71c 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1157,6 +1157,11 @@
const bool success = helper.Compile(pipeline);
if (!success) {
if (optimized) {
+ if (Compiler::IsBackgroundCompilation()) {
+ // Try again later, background compilation may abort because of
+ // state change during compilation.
+ return Error::null();
+ }
// Optimizer bailed out. Disable optimizations and never try again.
if (trace_compiler) {
THR_Print("--> disabling optimizations for '%s'\n",
@@ -1294,11 +1299,8 @@
// Optimization must happen in non-mutator/Dart thread if background
// compilation is on. OSR compilation still occurs in the main thread.
- // TODO(Srdjan): Remove assert allowance for regular expression functions
- // once they can be compiled in background.
ASSERT((osr_id != kNoOSRDeoptId) || !FLAG_background_compilation ||
- !thread->IsMutatorThread() ||
- function.IsIrregexpFunction());
+ !thread->IsMutatorThread());
CompilationPipeline* pipeline =
CompilationPipeline::New(thread->zone(), function);
return CompileFunctionHelper(pipeline,
@@ -1504,7 +1506,7 @@
void Compiler::AbortBackgroundCompilation(intptr_t deopt_id) {
if (FLAG_trace_compiler) {
- THR_Print("ABORT background compilation.");
+ THR_Print("ABORT background compilation\n");
}
ASSERT(Compiler::IsBackgroundCompilation());
Thread::Current()->long_jump_base()->Jump(
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 3b94487..12a7fdb 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1605,10 +1605,13 @@
DART_EXPORT Dart_Handle Dart_RunLoop() {
- Thread* T = Thread::Current();
- Isolate* I = T->isolate();
- CHECK_API_SCOPE(T);
- CHECK_CALLBACK_STATE(T);
+ Isolate* I;
+ {
+ Thread* T = Thread::Current();
+ I = T->isolate();
+ CHECK_API_SCOPE(T);
+ CHECK_CALLBACK_STATE(T);
+ }
API_TIMELINE_BEGIN_END;
// The message handler run loop does not expect to have a current isolate
// so we exit the isolate here and enter it again after the runloop is done.
@@ -1627,13 +1630,14 @@
}
}
::Dart_EnterIsolate(Api::CastIsolate(I));
- if (T->sticky_error() != Object::null()) {
- Dart_Handle error = Api::NewHandle(T, T->sticky_error());
- T->clear_sticky_error();
+ if (I->sticky_error() != Object::null()) {
+ Dart_Handle error =
+ Api::NewHandle(Thread::Current(), I->sticky_error());
+ I->clear_sticky_error();
return error;
}
if (FLAG_print_class_table) {
- HANDLESCOPE(T);
+ HANDLESCOPE(Thread::Current());
I->class_table()->Print();
}
return Api::Success();
@@ -5903,23 +5907,19 @@
ASSERT(output[output_length - 1] == ']');
// Replace the ']' with the null character.
output[output_length - 1] = '\0';
+ char* start = &output[1];
// We are skipping the '['.
output_length -= 1;
- // Start the stream.
- StartStreamToConsumer(consumer, user_data, "timeline");
-
DataStreamToConsumer(consumer,
user_data,
- &output[1],
+ start,
output_length,
"timeline");
// We stole the JSONStream's output buffer, free it.
free(output);
- // Finish the stream.
- FinishStreamToConsumer(consumer, user_data, "timeline");
return true;
}
@@ -5945,7 +5945,23 @@
JSONStream js;
IsolateTimelineEventFilter filter(isolate->main_port());
timeline_recorder->PrintTraceEvent(&js, &filter);
- return StreamTraceEvents(consumer, user_data, &js);
+ StartStreamToConsumer(consumer, user_data, "timeline");
+ bool success = StreamTraceEvents(consumer, user_data, &js);
+ FinishStreamToConsumer(consumer, user_data, "timeline");
+ return success;
+}
+
+
+DART_EXPORT void Dart_SetEmbedderTimelineCallbacks(
+ Dart_EmbedderTimelineStartRecording start_recording,
+ Dart_EmbedderTimelineStopRecording stop_recording,
+ Dart_EmbedderTimelineGetTimeline get_timeline) {
+ if (!FLAG_support_timeline) {
+ return;
+ }
+ Timeline::set_start_recording_cb(start_recording);
+ Timeline::set_stop_recording_cb(stop_recording);
+ Timeline::set_get_timeline_cb(get_timeline);
}
@@ -5967,10 +5983,16 @@
return false;
}
Timeline::ReclaimCachedBlocksFromThreads();
+ bool success = false;
JSONStream js;
TimelineEventFilter filter;
timeline_recorder->PrintTraceEvent(&js, &filter);
- return StreamTraceEvents(consumer, user_data, &js);
+ StartStreamToConsumer(consumer, user_data, "timeline");
+ if (StreamTraceEvents(consumer, user_data, &js)) {
+ success = true;
+ }
+ FinishStreamToConsumer(consumer, user_data, "timeline");
+ return success;
}
@@ -6095,7 +6117,6 @@
return Api::Success();
}
-
// The precompiler is included in dart_bootstrap and dart_noopt, and
// excluded from dart and dart_precompiled_runtime.
#if !defined(DART_PRECOMPILER)
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 91043ed..4be3fa9 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -9289,6 +9289,7 @@
return;
}
ASSERT(state == Dart_StreamConsumer_kData);
+
// Grow buffer.
data->buffer = reinterpret_cast<uint8_t*>(
realloc(data->buffer, data->buffer_length + buffer_length));
@@ -9772,6 +9773,67 @@
EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer);
}
+static bool start_called = false;
+static bool stop_called = false;
+
+static void StartRecording() {
+ start_called = true;
+}
+
+static void StopRecording() {
+ stop_called = true;
+}
+
+
+TEST_CASE(Timeline_Dart_EmbedderTimelineStartStopRecording) {
+ Dart_SetEmbedderTimelineCallbacks(StartRecording, StopRecording, NULL);
+
+ EXPECT(!start_called);
+ EXPECT(!stop_called);
+ Timeline::SetStreamEmbedderEnabled(true);
+ EXPECT(start_called);
+ EXPECT(!stop_called);
+
+ start_called = false;
+ stop_called = false;
+ EXPECT(!start_called);
+ EXPECT(!stop_called);
+ Timeline::SetStreamEmbedderEnabled(false);
+ EXPECT(!start_called);
+ EXPECT(stop_called);
+}
+
+static bool GetTimeline(Dart_StreamConsumer stream_consumer,
+ void* user_data) {
+ ASSERT(stream_consumer != NULL);
+ ASSERT(user_data != NULL);
+
+ const char* test_string = "HELLO FROM EMBEDDER";
+ stream_consumer(Dart_StreamConsumer_kData,
+ "embedder.timeline",
+ reinterpret_cast<const uint8_t*>(test_string),
+ strlen(test_string),
+ user_data);
+ return true;
+}
+
+TEST_CASE(Timeline_Dart_EmbedderTimelineGetTimeline) {
+ Dart_SetEmbedderTimelineCallbacks(NULL, NULL, GetTimeline);
+
+ Dart_GlobalTimelineSetRecordedStreams(DART_TIMELINE_STREAM_EMBEDDER);
+ Dart_TimelineDuration("testDurationEvent", 0, 1);
+
+ AppendData data;
+ bool success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
+ EXPECT(success);
+
+ EXPECT_SUBSTRING("}},HELLO FROM EMBEDDER",
+ data.buffer);
+
+ // Free buffer allocated by AppendStreamConsumer
+ free(data.buffer);
+}
+
#endif // !PRODUCT
} // namespace dart
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 84ca377..e55edd0 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -10,6 +10,7 @@
#include "vm/dart_entry.h"
#include "vm/debugger.h"
#include "vm/flags.h"
+#include "vm/log.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/stack_frame.h"
@@ -23,9 +24,6 @@
"Prints a stack trace everytime a throw occurs.");
-const char* Exceptions::kCastErrorDstName = "type cast";
-
-
class StacktraceBuilder : public ValueObject {
public:
StacktraceBuilder() { }
@@ -371,8 +369,8 @@
ASSERT(handler_pc != 0);
if (FLAG_print_stacktrace_at_throw) {
- OS::Print("Exception '%s' thrown:\n", exception.ToCString());
- OS::Print("%s\n", stacktrace.ToCString());
+ THR_Print("Exception '%s' thrown:\n", exception.ToCString());
+ THR_Print("%s\n", stacktrace.ToCString());
}
if (handler_exists) {
// Found a dart handler for the exception, jump to it.
@@ -434,18 +432,20 @@
// Allocate, initialize, and throw a TypeError or CastError.
// If error_msg is not null, throw a TypeError, even for a type cast.
void Exceptions::CreateAndThrowTypeError(TokenPosition location,
- const String& src_type_name,
- const String& dst_type_name,
+ const AbstractType& src_type,
+ const AbstractType& dst_type,
const String& dst_name,
- const String& error_msg) {
- const Array& args = Array::Handle(Array::New(7));
+ const String& bound_error_msg) {
+ ASSERT(!dst_name.IsNull()); // Pass Symbols::Empty() instead.
+ Zone* zone = Thread::Current()->zone();
+ const Array& args = Array::Handle(zone, Array::New(4));
ExceptionType exception_type =
- (error_msg.IsNull() && dst_name.Equals(kCastErrorDstName)) ?
- kCast : kType;
+ (bound_error_msg.IsNull() &&
+ (dst_name.raw() == Symbols::InTypeCast().raw())) ? kCast : kType;
DartFrameIterator iterator;
- const Script& script = Script::Handle(GetCallerScript(&iterator));
+ const Script& script = Script::Handle(zone, GetCallerScript(&iterator));
intptr_t line;
intptr_t column = -1;
if (script.HasSource()) {
@@ -454,32 +454,64 @@
script.GetTokenLocation(location, &line, NULL);
}
// Initialize '_url', '_line', and '_column' arguments.
- args.SetAt(0, String::Handle(script.url()));
- args.SetAt(1, Smi::Handle(Smi::New(line)));
- args.SetAt(2, Smi::Handle(Smi::New(column)));
+ args.SetAt(0, String::Handle(zone, script.url()));
+ args.SetAt(1, Smi::Handle(zone, Smi::New(line)));
+ args.SetAt(2, Smi::Handle(zone, Smi::New(column)));
- // Initialize '_srcType', '_dstType', '_dstName', and '_errorMsg'.
- args.SetAt(3, src_type_name);
- args.SetAt(4, dst_type_name);
- args.SetAt(5, dst_name);
- args.SetAt(6, error_msg);
+ // Construct '_errorMsg'.
+ GrowableHandlePtrArray<const String> pieces(zone, 20);
+
+ // Print bound error first, if any.
+ if (!bound_error_msg.IsNull() && (bound_error_msg.Length() > 0)) {
+ pieces.Add(bound_error_msg);
+ pieces.Add(Symbols::NewLine());
+ }
+
+ // If dst_type is malformed or malbounded, only print the embedded error.
+ if (!dst_type.IsNull()) {
+ const LanguageError& error = LanguageError::Handle(zone, dst_type.error());
+ if (!error.IsNull()) {
+ // Print the embedded error only.
+ pieces.Add(String::Handle(zone, Symbols::New(error.ToErrorCString())));
+ pieces.Add(Symbols::NewLine());
+ } else {
+ // Describe the type error.
+ if (!src_type.IsNull()) {
+ pieces.Add(Symbols::TypeQuote());
+ pieces.Add(String::Handle(zone, src_type.UserVisibleName()));
+ pieces.Add(Symbols::QuoteIsNotASubtypeOf());
+ }
+ pieces.Add(Symbols::TypeQuote());
+ pieces.Add(String::Handle(zone, dst_type.UserVisibleName()));
+ pieces.Add(Symbols::SingleQuote());
+ if (exception_type == kCast) {
+ pieces.Add(dst_name);
+ } else if (dst_name.Length() > 0) {
+ pieces.Add(Symbols::SpaceOfSpace());
+ pieces.Add(Symbols::SingleQuote());
+ pieces.Add(dst_name);
+ pieces.Add(Symbols::SingleQuote());
+ }
+ // Print URIs of src and dst types.
+ pieces.Add(Symbols::SpaceWhereNewLine());
+ if (!src_type.IsNull()) {
+ pieces.Add(String::Handle(zone, src_type.EnumerateURIs()));
+ }
+ if (!dst_type.IsDynamicType() && !dst_type.IsVoidType()) {
+ pieces.Add(String::Handle(zone, dst_type.EnumerateURIs()));
+ }
+ }
+ }
+ const String& error_msg =
+ String::Handle(zone, Symbols::FromConcatAll(pieces));
+ args.SetAt(3, error_msg);
// Type errors in the core library may be difficult to diagnose.
// Print type error information before throwing the error when debugging.
if (FLAG_print_stacktrace_at_throw) {
- if (!error_msg.IsNull()) {
- OS::Print("%s\n", error_msg.ToCString());
- }
- OS::Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ",
- String::Handle(script.url()).ToCString(), line, column);
- if (!dst_name.IsNull() && (dst_name.Length() > 0)) {
- OS::Print("type '%s' is not a subtype of type '%s' of '%s'.\n",
- src_type_name.ToCString(),
- dst_type_name.ToCString(),
- dst_name.ToCString());
- } else {
- OS::Print("type error.\n");
- }
+ THR_Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ",
+ String::Handle(zone, script.url()).ToCString(), line, column);
+ THR_Print("%s\n", error_msg.ToCString());
}
// Throw TypeError or CastError instance.
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 86e3261..e0a64c8 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -11,28 +11,21 @@
namespace dart {
// Forward declarations.
+class AbstractType;
class Array;
-class Class;
class DartFrameIterator;
class Error;
class Instance;
class Integer;
-class Object;
class RawInstance;
class RawObject;
class RawScript;
class RawStacktrace;
-class RawString;
-class Script;
-class StackFrame;
-class Stacktrace;
class String;
class Thread;
class Exceptions : AllStatic {
public:
- static const char* kCastErrorDstName;
-
static void Throw(Thread* thread, const Instance& exception);
static void ReThrow(Thread* thread,
const Instance& exception,
@@ -44,10 +37,10 @@
static RawScript* GetCallerScript(DartFrameIterator* iterator);
static RawInstance* NewInstance(const char* class_name);
static void CreateAndThrowTypeError(TokenPosition location,
- const String& src_type_name,
- const String& dst_type_name,
+ const AbstractType& src_type,
+ const AbstractType& dst_type,
const String& dst_name,
- const String& error_msg);
+ const String& bound_error_msg);
enum ExceptionType {
kNone,
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 4bf3ec9..c411bbd 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1684,12 +1684,10 @@
ValueGraphVisitor for_value(owner());
node->left()->Visit(&for_value);
Append(for_value);
- const String& dst_name = String::ZoneHandle(
- Z, Symbols::New(Exceptions::kCastErrorDstName));
if (CanSkipTypeCheck(node->token_pos(),
for_value.value(),
type,
- dst_name)) {
+ Symbols::InTypeCast())) {
ReturnValue(for_value.value());
return;
}
@@ -2675,30 +2673,37 @@
static intptr_t GetResultCidOfNativeFactory(const Function& function) {
- const Class& function_class = Class::Handle(function.Owner());
- if (function_class.library() == Library::TypedDataLibrary()) {
- const String& function_name = String::Handle(function.name());
- if (!String::EqualsIgnoringPrivateKey(function_name, Symbols::_New())) {
- return kDynamicCid;
- }
- switch (function_class.id()) {
- case kTypedDataInt8ArrayCid:
- case kTypedDataUint8ArrayCid:
- case kTypedDataUint8ClampedArrayCid:
- case kTypedDataInt16ArrayCid:
- case kTypedDataUint16ArrayCid:
- case kTypedDataInt32ArrayCid:
- case kTypedDataUint32ArrayCid:
- case kTypedDataInt64ArrayCid:
- case kTypedDataUint64ArrayCid:
- case kTypedDataFloat32ArrayCid:
- case kTypedDataFloat64ArrayCid:
- case kTypedDataFloat32x4ArrayCid:
- case kTypedDataInt32x4ArrayCid:
- return function_class.id();
- default:
- return kDynamicCid; // Unknown.
- }
+ switch (function.recognized_kind()) {
+ case MethodRecognizer::kTypedData_Int8Array_factory:
+ return kTypedDataInt8ArrayCid;
+ case MethodRecognizer::kTypedData_Uint8Array_factory:
+ return kTypedDataUint8ArrayCid;
+ case MethodRecognizer::kTypedData_Uint8ClampedArray_factory:
+ return kTypedDataUint8ClampedArrayCid;
+ case MethodRecognizer::kTypedData_Int16Array_factory:
+ return kTypedDataInt16ArrayCid;
+ case MethodRecognizer::kTypedData_Uint16Array_factory:
+ return kTypedDataUint16ArrayCid;
+ case MethodRecognizer::kTypedData_Int32Array_factory:
+ return kTypedDataInt32ArrayCid;
+ case MethodRecognizer::kTypedData_Uint32Array_factory:
+ return kTypedDataUint32ArrayCid;
+ case MethodRecognizer::kTypedData_Int64Array_factory:
+ return kTypedDataInt64ArrayCid;
+ case MethodRecognizer::kTypedData_Uint64Array_factory:
+ return kTypedDataUint64ArrayCid;
+ case MethodRecognizer::kTypedData_Float32Array_factory:
+ return kTypedDataFloat32ArrayCid;
+ case MethodRecognizer::kTypedData_Float64Array_factory:
+ return kTypedDataFloat64ArrayCid;
+ case MethodRecognizer::kTypedData_Float32x4Array_factory:
+ return kTypedDataFloat32x4ArrayCid;
+ case MethodRecognizer::kTypedData_Int32x4Array_factory:
+ return kTypedDataInt32x4ArrayCid;
+ case MethodRecognizer::kTypedData_Float64x2Array_factory:
+ return kTypedDataFloat64x2ArrayCid;
+ default:
+ break;
}
return kDynamicCid;
}
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index c15d63c..437c684 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -915,22 +915,30 @@
ASSERT(error.IsLanguageError());
if (LanguageError::Cast(error).kind() == Report::kBailout) {
- thread()->set_deopt_id(prev_deopt_id);
- TRACE_INLINING(THR_Print(" Bailout: %s\n",
- error.ToErrorCString()));
- PRINT_INLINING_TREE("Bailout",
- &call_data->caller, &function, call);
- return false;
+ if (error.raw() == Object::background_compilation_error().raw()) {
+ // Fall through to exit the compilation, and retry it later.
+ } else {
+ thread()->set_deopt_id(prev_deopt_id);
+ TRACE_INLINING(THR_Print(" Bailout: %s\n",
+ error.ToErrorCString()));
+ PRINT_INLINING_TREE("Bailout",
+ &call_data->caller, &function, call);
+ return false;
+ }
} else {
// Fall through to exit long jump scope.
+ ASSERT(FLAG_precompiled_mode);
}
}
}
- // Propagate a compile-time error. Only in precompilation do we attempt to
+ // Propagate a compile-time error. In precompilation we attempt to
// inline functions that have never been compiled before; when JITing we
// should only see compile-time errors in unoptimized compilation.
- ASSERT(FLAG_precompiled_mode);
+ // In background compilation we may abort compilation as the state
+ // changes while compiling. Propagate that 'error' and retry compilation
+ // later.
+ ASSERT(FLAG_precompiled_mode || Compiler::IsBackgroundCompilation());
Thread::Current()->long_jump_base()->Jump(1, error);
UNREACHABLE();
return false;
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index c5b593e..b34af54 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -446,6 +446,19 @@
}
+#if defined(DEBUG)
+void Heap::WaitForSweeperTasks() {
+ Thread* thread = Thread::Current();
+ {
+ MonitorLocker ml(old_space_.tasks_lock());
+ while (old_space_.tasks() > 0) {
+ ml.WaitWithSafepointCheck(thread);
+ }
+ }
+}
+#endif
+
+
bool Heap::ShouldPretenure(intptr_t class_id) const {
if (class_id == kOneByteStringCid) {
return pretenure_policy_ > 0;
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 97e04a1..6fd1934 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -124,6 +124,10 @@
return old_space_.NeedsGarbageCollection();
}
+#if defined(DEBUG)
+ void WaitForSweeperTasks();
+#endif
+
// Enables growth control on the page space heaps. This should be
// called before any user code is executed.
void InitGrowthControl();
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index e4fcd9d..bd83626 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -6561,8 +6561,11 @@
// Load code object from frame.
__ movl(target_reg, Address(EBP, kPcMarkerSlotFromFp * kWordSize));
- // Load instructions entry point.
- __ movl(target_reg, FieldAddress(target_reg, Code::entry_point_offset()));
+ // Load instructions object (active_instructions and Code::entry_point() may
+ // not point to this instruction object any more; see Code::DisableDartCode).
+ __ movl(target_reg,
+ FieldAddress(target_reg, Code::saved_instructions_offset()));
+ __ addl(target_reg, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
// Add the offset.
Register offset_reg = locs()->in(0).reg();
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 0487fea..979ca87 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -245,12 +245,6 @@
#define TYPED_DATA_ALLOCATOR(clazz) \
-void Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) { \
- intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
- intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid); \
- int shift = GetScaleFactor(size); \
- TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, shift); \
-} \
void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) { \
intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid); \
diff --git a/runtime/vm/intrinsifier_arm64.cc b/runtime/vm/intrinsifier_arm64.cc
index f12ea8d..fa7c20d0 100644
--- a/runtime/vm/intrinsifier_arm64.cc
+++ b/runtime/vm/intrinsifier_arm64.cc
@@ -238,12 +238,6 @@
#define TYPED_DATA_ALLOCATOR(clazz) \
-void Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) { \
- intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
- intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid); \
- int shift = GetScaleFactor(size); \
- TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, shift); \
-} \
void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) { \
intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid); \
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 29870b2..ab3fcb3 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -294,12 +294,6 @@
#define TYPED_DATA_ALLOCATOR(clazz) \
-void Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) { \
- intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
- intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid); \
- ScaleFactor scale = GetScaleFactor(size); \
- TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale); \
-} \
void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) { \
intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid); \
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index ddd9c52..3625b13 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -238,12 +238,6 @@
#define TYPED_DATA_ALLOCATOR(clazz) \
-void Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) { \
- intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
- intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid); \
- int shift = GetScaleFactor(size); \
- TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, shift); \
-} \
void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) { \
intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid); \
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index e98777f..b3f0a73 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -238,12 +238,6 @@
#define TYPED_DATA_ALLOCATOR(clazz) \
-void Intrinsifier::TypedData_##clazz##_new(Assembler* assembler) { \
- intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
- intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid); \
- ScaleFactor scale = GetScaleFactor(size); \
- TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale); \
-} \
void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler) { \
intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid); \
intptr_t max_len = TypedData::MaxElements(kTypedData##clazz##Cid); \
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 4b11247..0c6a662 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -813,6 +813,7 @@
object_id_ring_(NULL),
tag_table_(GrowableObjectArray::null()),
deoptimized_code_array_(GrowableObjectArray::null()),
+ sticky_error_(Error::null()),
background_compiler_(NULL),
pending_service_extension_calls_(GrowableObjectArray::null()),
registered_service_extension_handlers_(GrowableObjectArray::null()),
@@ -1864,6 +1865,9 @@
visitor->VisitPointer(
reinterpret_cast<RawObject**>(&deoptimized_code_array_));
+ visitor->VisitPointer(
+ reinterpret_cast<RawObject**>(&sticky_error_));
+
// Visit the pending service extension calls.
visitor->VisitPointer(
reinterpret_cast<RawObject**>(&pending_service_extension_calls_));
@@ -2081,6 +2085,11 @@
}
+void Isolate::clear_sticky_error() {
+ sticky_error_ = Error::null();
+}
+
+
void Isolate::set_pending_service_extension_calls(
const GrowableObjectArray& value) {
pending_service_extension_calls_ = value.raw();
@@ -2592,6 +2601,13 @@
// so we create a MonitorLocker object which does not do any
// no_safepoint_scope_depth increments/decrements.
MonitorLocker ml(threads_lock(), false);
+ if (is_mutator) {
+ if (thread->sticky_error() != Error::null()) {
+ ASSERT(sticky_error_ == Error::null());
+ sticky_error_ = thread->sticky_error();
+ thread->clear_sticky_error();
+ }
+ }
if (!bypass_safepoint) {
// Ensure that the thread reports itself as being at a safepoint.
thread->EnterSafepoint();
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index e40b3900..c6a5bd9 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -581,6 +581,9 @@
void set_deoptimized_code_array(const GrowableObjectArray& value);
void TrackDeoptimizedCode(const Code& code);
+ RawError* sticky_error() const { return sticky_error_; }
+ void clear_sticky_error();
+
bool compilation_allowed() const { return compilation_allowed_; }
void set_compilation_allowed(bool allowed) {
compilation_allowed_ = allowed;
@@ -808,6 +811,8 @@
RawGrowableObjectArray* deoptimized_code_array_;
+ RawError* sticky_error_;
+
// Background compilation.
BackgroundCompiler* background_compiler_;
diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc
index f5f2211..c02fa8c 100644
--- a/runtime/vm/jit_optimizer.cc
+++ b/runtime/vm/jit_optimizer.cc
@@ -2690,14 +2690,12 @@
return;
}
}
- const String& dst_name = String::ZoneHandle(Z,
- Symbols::New(Exceptions::kCastErrorDstName));
AssertAssignableInstr* assert_as =
new(Z) AssertAssignableInstr(call->token_pos(),
new(Z) Value(left),
new(Z) Value(type_args),
type,
- dst_name,
+ Symbols::InTypeCast(),
call->deopt_id());
ReplaceCall(call, assert_as);
}
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index a68d87d..a721c7e 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -20,6 +20,23 @@
#ifndef PRODUCT
+void AppendJSONStreamConsumer(Dart_StreamConsumer_State state,
+ const char* stream_name,
+ const uint8_t* buffer,
+ intptr_t buffer_length,
+ void* user_data) {
+ if ((state == Dart_StreamConsumer_kStart) ||
+ (state == Dart_StreamConsumer_kFinish)) {
+ // Ignore.
+ return;
+ }
+ ASSERT(state == Dart_StreamConsumer_kData);
+ JSONStream* js = reinterpret_cast<JSONStream*>(user_data);
+ ASSERT(js != NULL);
+ js->AppendSerializedObject(buffer, buffer_length);
+}
+
+
DECLARE_FLAG(bool, trace_service);
JSONStream::JSONStream(intptr_t buf_size)
@@ -263,6 +280,11 @@
}
+void JSONStream::AppendSerializedObject(const uint8_t* buffer,
+ intptr_t buffer_length) {
+ buffer_.AddRaw(buffer, buffer_length);
+}
+
void JSONStream::AppendSerializedObject(const char* property_name,
const char* serialized_object) {
PrintCommaIfNeeded();
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index 6c4f23e..5b020b0 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -55,6 +55,12 @@
kIsolateMustBeRunnable = 105,
};
+// Expected that user_data is a JSONStream*.
+void AppendJSONStreamConsumer(Dart_StreamConsumer_State state,
+ const char* stream_name,
+ const uint8_t* buffer,
+ intptr_t buffer_length,
+ void* user_data);
class JSONStream : ValueObject {
public:
@@ -129,6 +135,12 @@
// Append |serialized_object| to the stream.
void AppendSerializedObject(const char* serialized_object);
+ void PrintCommaIfNeeded();
+
+ // Append |buffer| to the stream.
+ void AppendSerializedObject(const uint8_t* buffer,
+ intptr_t buffer_length);
+
// Append |serialized_object| to the stream with |property_name|.
void AppendSerializedObject(const char* property_name,
const char* serialized_object);
@@ -196,7 +208,6 @@
const TimelineEventBlock* timeline_event_block);
void PrintPropertyVM(const char* name, bool ref = true);
void PrintPropertyName(const char* name);
- void PrintCommaIfNeeded();
bool NeedComma();
bool AddDartString(const String& s, intptr_t offset, intptr_t count);
diff --git a/runtime/vm/json_test.cc b/runtime/vm/json_test.cc
index 7c5b49f..e8c4f5d 100644
--- a/runtime/vm/json_test.cc
+++ b/runtime/vm/json_test.cc
@@ -315,6 +315,33 @@
EXPECT(!js.ParamIs("dog", "banana"));
}
+
+TEST_CASE(JSON_JSONStream_AppendJSONStreamConsumer) {
+ JSONStream js;
+
+ {
+ JSONObject obj(&js);
+ {
+ JSONArray arr(&obj, "test");
+ const char* test_data = "{a, b, c},";
+ AppendJSONStreamConsumer(Dart_StreamConsumer_kData, "",
+ reinterpret_cast<const uint8_t*>(&test_data[0]),
+ strlen(test_data),
+ &js);
+ AppendJSONStreamConsumer(Dart_StreamConsumer_kData, "",
+ reinterpret_cast<const uint8_t*>(&test_data[0]),
+ strlen(test_data),
+ &js);
+ AppendJSONStreamConsumer(Dart_StreamConsumer_kData, "",
+ reinterpret_cast<const uint8_t*>(&test_data[0]),
+ strlen(test_data) - 1,
+ &js);
+ }
+ }
+
+ EXPECT_STREQ("{\"test\":[{a, b, c},{a, b, c},{a, b, c}]}", js.ToCString());
+}
+
#endif // !PRODUCT
} // namespace dart
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h
index 87a524e..1292b84 100644
--- a/runtime/vm/method_recognizer.h
+++ b/runtime/vm/method_recognizer.h
@@ -245,34 +245,20 @@
#define TYPED_DATA_LIB_INTRINSIC_LIST(V) \
- V(_Int8Array, _new, TypedData_Int8Array_new, 1025382728) \
- V(_Uint8Array, _new, TypedData_Uint8Array_new, 1772090315) \
- V(_Uint8ClampedArray, _new, TypedData_Uint8ClampedArray_new, 1817995920) \
- V(_Int16Array, _new, TypedData_Int16Array_new, 857482727) \
- V(_Uint16Array, _new, TypedData_Uint16Array_new, 224498043) \
- V(_Int32Array, _new, TypedData_Int32Array_new, 662785062) \
- V(_Uint32Array, _new, TypedData_Uint32Array_new, 457777042) \
- V(_Int64Array, _new, TypedData_Int64Array_new, 11424776) \
- V(_Uint64Array, _new, TypedData_Uint64Array_new, 580841705) \
- V(_Float32Array, _new, TypedData_Float32Array_new, 141243383) \
- V(_Float64Array, _new, TypedData_Float64Array_new, 2054234881) \
- V(_Float32x4Array, _new, TypedData_Float32x4Array_new, 1277009760) \
- V(_Int32x4Array, _new, TypedData_Int32x4Array_new, 366994774) \
- V(_Float64x2Array, _new, TypedData_Float64x2Array_new, 134695262) \
- V(_Int8Array, ., TypedData_Int8Array_factory, 484088513) \
- V(_Uint8Array, ., TypedData_Uint8Array_factory, 1830561671) \
- V(_Uint8ClampedArray, ., TypedData_Uint8ClampedArray_factory, 980532456) \
- V(_Int16Array, ., TypedData_Int16Array_factory, 2095566414) \
- V(_Uint16Array, ., TypedData_Uint16Array_factory, 248627537) \
- V(_Int32Array, ., TypedData_Int32Array_factory, 836050202) \
- V(_Uint32Array, ., TypedData_Uint32Array_factory, 102123815) \
- V(_Int64Array, ., TypedData_Int64Array_factory, 1820730838) \
- V(_Uint64Array, ., TypedData_Uint64Array_factory, 1668399825) \
- V(_Float32Array, ., TypedData_Float32Array_factory, 307228626) \
- V(_Float64Array, ., TypedData_Float64Array_factory, 1700923139) \
- V(_Float32x4Array, ., TypedData_Float32x4Array_factory, 1083909924) \
- V(_Int32x4Array, ., TypedData_Int32x4Array_factory, 803703492) \
- V(_Float64x2Array, ., TypedData_Float64x2Array_factory, 944719167) \
+ V(_Int8Array, ., TypedData_Int8Array_factory, 1058992179) \
+ V(_Uint8Array, ., TypedData_Uint8Array_factory, 1807546986) \
+ V(_Uint8ClampedArray, ., TypedData_Uint8ClampedArray_factory, 548459853) \
+ V(_Int16Array, ., TypedData_Int16Array_factory, 1796211480) \
+ V(_Uint16Array, ., TypedData_Uint16Array_factory, 1960868166) \
+ V(_Int32Array, ., TypedData_Int32Array_factory, 372258367) \
+ V(_Uint32Array, ., TypedData_Uint32Array_factory, 1446612721) \
+ V(_Int64Array, ., TypedData_Int64Array_factory, 964028713) \
+ V(_Uint64Array, ., TypedData_Uint64Array_factory, 721823156) \
+ V(_Float32Array, ., TypedData_Float32Array_factory, 392399264) \
+ V(_Float64Array, ., TypedData_Float64Array_factory, 42503976) \
+ V(_Float32x4Array, ., TypedData_Float32x4Array_factory, 1960198693) \
+ V(_Int32x4Array, ., TypedData_Int32x4Array_factory, 1433742555) \
+ V(_Float64x2Array, ., TypedData_Float64x2Array_factory, 165463437) \
#define GRAPH_TYPED_DATA_INTRINSICS_LIST(V) \
V(_Uint8Array, [], Uint8ArrayGetIndexed, 513704632) \
@@ -518,18 +504,18 @@
V(_ListFactory, kArrayCid, 184405219) \
V(_GrowableListWithData, kGrowableObjectArrayCid, 131424500) \
V(_GrowableListFactory, kGrowableObjectArrayCid, 664918385) \
- V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 484088513) \
- V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1830561671) \
- V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 980532456) \
- V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 2095566414) \
- V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 248627537) \
- V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 836050202) \
- V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 102123815) \
- V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 1820730838) \
- V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 1668399825) \
- V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 1700923139) \
- V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 307228626) \
- V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 1083909924) \
+ V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 1058992179) \
+ V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1807546986) \
+ V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 548459853) \
+ V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 1796211480) \
+ V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 1960868166) \
+ V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 372258367) \
+ V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 1446612721) \
+ V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 964028713) \
+ V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 721823156) \
+ V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 42503976) \
+ V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 392399264) \
+ V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 1960198693) \
// Class that recognizes factories and returns corresponding result cid.
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index faeb61f..7b84774 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -6154,11 +6154,15 @@
Report::kError,
Heap::kNew,
"signature type '%s' of function '%s' is not a subtype of signature "
- "type '%s' of function '%s'",
+ "type '%s' of function '%s' where\n%s%s",
String::Handle(UserVisibleSignature()).ToCString(),
String::Handle(UserVisibleName()).ToCString(),
String::Handle(other.UserVisibleSignature()).ToCString(),
- String::Handle(other.UserVisibleName()).ToCString());
+ String::Handle(other.UserVisibleName()).ToCString(),
+ String::Handle(FunctionType::Handle(
+ SignatureType()).EnumerateURIs()).ToCString(),
+ String::Handle(FunctionType::Handle(
+ other.SignatureType()).EnumerateURIs()).ToCString());
return false;
}
// We should also check that if the other function explicitly specifies a
@@ -7966,7 +7970,7 @@
}
}
if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) {
- literals.Add(Symbols::DoubleQuotes());
+ literals.Add(Symbols::DoubleQuote());
}
if (escape_characters) {
literal = String::EscapeSpecialCharacters(literal);
@@ -7975,7 +7979,7 @@
literals.Add(literal);
}
if ((next != Token::kINTERPOL_VAR) && (next != Token::kINTERPOL_START)) {
- literals.Add(Symbols::DoubleQuotes());
+ literals.Add(Symbols::DoubleQuote());
}
} else if (curr == Token::kINTERPOL_VAR) {
literals.Add(Symbols::Dollar());
@@ -15328,8 +15332,10 @@
Zone* zone = Thread::Current()->zone();
GrowableHandlePtrArray<const String> pieces(zone, 3);
pieces.Add(String::Handle(zone, BuildName(kUserVisibleName)));
- pieces.Add(Symbols::SpaceWhereNewLine());
- pieces.Add(String::Handle(zone, EnumerateURIs()));
+ if (!IsDynamicType() && !IsVoidType()) {
+ pieces.Add(Symbols::SpaceWhereNewLine());
+ pieces.Add(String::Handle(zone, EnumerateURIs()));
+ }
return Symbols::FromConcatAll(pieces);
}
@@ -15445,6 +15451,7 @@
if (other.IsObjectType() || other.IsDynamicType()) {
return true;
}
+ Zone* zone = Thread::Current()->zone();
if (IsBoundedType() || other.IsBoundedType()) {
if (Equals(other)) {
return true;
@@ -15454,9 +15461,30 @@
AbstractType::Handle(BoundedType::Cast(*this).bound()).Equals(other)) {
return true;
}
- return false; // TODO(regis): We should return "maybe after instantiation".
+ // Bound checking at run time occurs when allocating an instance of a
+ // generic bounded type using a valid instantiator. The instantiator is
+ // the type of an instance successfully allocated, i.e. not containing
+ // unchecked bounds anymore.
+ // Therefore, when performing a type test at compile time (what is happening
+ // here), it is safe to ignore the bounds, since they will not exist at run
+ // time anymore.
+ if (IsBoundedType()) {
+ const AbstractType& bounded_type =
+ AbstractType::Handle(zone, BoundedType::Cast(*this).type());
+ return bounded_type.TypeTest(test_kind,
+ other,
+ bound_error,
+ bound_trail,
+ space);
+ }
+ const AbstractType& other_bounded_type =
+ AbstractType::Handle(zone, BoundedType::Cast(other).type());
+ return TypeTest(test_kind,
+ other_bounded_type,
+ bound_error,
+ bound_trail,
+ space);
}
- Zone* zone = Thread::Current()->zone();
// Type parameters cannot be handled by Class::TypeTest().
// When comparing two uninstantiated function types, one returning type
// parameter K, the other returning type parameter V, we cannot assume that K
@@ -16050,7 +16078,7 @@
RawString* Type::EnumerateURIs() const {
- if (IsDynamicType()) {
+ if (IsDynamicType() || IsVoidType()) {
return Symbols::Empty().raw();
}
Zone* zone = Thread::Current()->zone();
@@ -16540,9 +16568,7 @@
}
// Handle result type last, since it appears last in the user visible name.
type = sig_fun.result_type();
- if (!type.IsDynamicType() && !type.IsVoidType()) {
- pieces.Add(String::Handle(zone, type.EnumerateURIs()));
- }
+ pieces.Add(String::Handle(zone, type.EnumerateURIs()));
return Symbols::FromConcatAll(pieces);
}
@@ -16751,7 +16777,20 @@
RawString* TypeRef::EnumerateURIs() const {
- return Symbols::Empty().raw(); // Break cycle.
+ const AbstractType& ref_type = AbstractType::Handle(type());
+ ASSERT(!ref_type.IsDynamicType() && !ref_type.IsVoidType());
+ Zone* zone = Thread::Current()->zone();
+ GrowableHandlePtrArray<const String> pieces(zone, 6);
+ const Class& cls = Class::Handle(zone, ref_type.type_class());
+ pieces.Add(Symbols::TwoSpaces());
+ pieces.Add(String::Handle(zone, cls.UserVisibleName()));
+ // Break cycle by not printing type arguments, but '<optimized out>' instead.
+ pieces.Add(Symbols::OptimizedOut());
+ pieces.Add(Symbols::SpaceIsFromSpace());
+ const Library& library = Library::Handle(zone, cls.library());
+ pieces.Add(String::Handle(zone, library.url()));
+ pieces.Add(Symbols::NewLine());
+ return Symbols::FromConcatAll(pieces);
}
@@ -16920,12 +16959,14 @@
Report::kMalboundedType,
Heap::kNew,
"type parameter '%s' of class '%s' must extend bound '%s', "
- "but type argument '%s' is not a subtype of '%s'\n",
+ "but type argument '%s' is not a subtype of '%s' where\n%s%s",
type_param_name.ToCString(),
class_name.ToCString(),
declared_bound_name.ToCString(),
bounded_type_name.ToCString(),
- upper_bound_name.ToCString());
+ upper_bound_name.ToCString(),
+ String::Handle(bounded_type.EnumerateURIs()).ToCString(),
+ String::Handle(upper_bound.EnumerateURIs()).ToCString());
}
}
return false;
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 9cb7dd4..9c4d714 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -10278,15 +10278,12 @@
type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos.value()))));
// Src value argument.
arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance()));
- // Dst type name argument.
- arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Malformed()));
+ // Dst type argument.
+ arguments->Add(new(Z) LiteralNode(type_pos, type));
// Dst name argument.
arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Empty()));
- // Malformed type error or malbounded type error.
- const Error& error = Error::Handle(Z, type.error());
- ASSERT(!error.IsNull());
- arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z,
- Symbols::New(error.ToErrorCString()))));
+ // Bound error msg argument.
+ arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance()));
return MakeStaticCall(Symbols::TypeError(), method_name, arguments);
}
@@ -13288,7 +13285,7 @@
(la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH);
LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z);
- AbstractType& type = AbstractType::Handle(Z,
+ AbstractType& type = AbstractType::ZoneHandle(Z,
ParseType(ClassFinalizer::kCanonicalizeWellFormed,
allow_deferred_type,
consume_unresolved_prefix,
@@ -13297,7 +13294,7 @@
if (FLAG_load_deferred_eagerly &&
!prefix.IsNull() && prefix.is_deferred_load() && !prefix.is_loaded()) {
// Add runtime check.
- Type& malformed_type = Type::Handle(Z);
+ Type& malformed_type = Type::ZoneHandle(Z);
malformed_type = ClassFinalizer::NewFinalizedMalformedType(
Error::Handle(Z), // No previous error.
script_,
@@ -13417,7 +13414,7 @@
NULL); // No existing function.
} else if (constructor.IsRedirectingFactory()) {
ClassFinalizer::ResolveRedirectingFactory(type_class, constructor);
- Type& redirect_type = Type::Handle(Z, constructor.RedirectionType());
+ Type& redirect_type = Type::ZoneHandle(Z, constructor.RedirectionType());
if (!redirect_type.IsMalformedOrMalbounded() &&
!redirect_type.IsInstantiated()) {
// The type arguments of the redirection type are instantiated from the
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index b8bfc18..1d111dd 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -203,6 +203,12 @@
TraceTypesFromRetainedClasses();
DropTypes();
DropTypeArguments();
+
+ // Clear these before dropping classes as they may hold onto otherwise
+ // dead instances of classes we will remove.
+ I->object_store()->set_compile_time_constants(Array::null_array());
+ I->object_store()->set_unique_dynamic_targets(Array::null_array());
+
DropClasses();
DropLibraries();
@@ -216,9 +222,6 @@
DedupInstructions();
}
- I->object_store()->set_compile_time_constants(Array::null_array());
- I->object_store()->set_unique_dynamic_targets(Array::null_array());
-
zone_ = NULL;
}
@@ -1473,6 +1476,7 @@
constants = Array::MakeArray(retained_constants);
cls.set_constants(constants);
} else {
+ constants = Object::empty_array().raw();
cls.set_constants(Object::empty_array());
}
@@ -1492,14 +1496,17 @@
void Precompiler::DropClasses() {
Library& lib = Library::Handle(Z);
Class& cls = Class::Handle(Z);
- Array& members = Array::Handle(Z);
+ Array& constants = Array::Handle(Z);
String& name = String::Handle(Z);
#if defined(DEBUG)
- {
- // Force GC for allocation stats.
- I->heap()->CollectAllGarbage();
- }
+ // We are about to remove classes from the class table. For this to be safe,
+ // there must be no instances of these classes on the heap, not even
+ // corpses because the class table entry may be used to find the size of
+ // corpses. Request a full GC and wait for the sweeper tasks to finish before
+ // we continue.
+ I->heap()->CollectAllGarbage();
+ I->heap()->WaitForSweeperTasks();
#endif
ClassTable* class_table = I->class_table();
@@ -1518,22 +1525,16 @@
// removed.
continue;
}
- if (cls.is_enum_class()) {
- // Enum classes have live instances, so we cannot unregister
- // them.
- continue;
- }
- members = cls.constants();
- if (members.Length() > 0) {
- // --compile_all?
- continue;
- }
bool retain = classes_to_retain_.Lookup(&cls) != NULL;
if (retain) {
continue;
}
+ ASSERT(!cls.is_allocated());
+ constants = cls.constants();
+ ASSERT(constants.Length() == 0);
+
#if defined(DEBUG)
intptr_t instances =
class_table->StatsWithUpdatedSize(cid)->post_gc.new_count +
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 8eaf6c1..35fd771 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -157,18 +157,38 @@
void ProfileFunction::TickSourcePosition(TokenPosition token_position,
bool exclusive) {
- for (intptr_t i = 0; i < source_position_ticks_.length(); i++) {
+ intptr_t i = 0;
+ for (; i < source_position_ticks_.length(); i++) {
ProfileFunctionSourcePosition& position = source_position_ticks_[i];
- if (position.token_pos() == token_position) {
+ if (position.token_pos().value() == token_position.value()) {
+ if (FLAG_trace_profiler) {
+ OS::Print("Ticking source position %s %s\n",
+ exclusive ? "exclusive" : "inclusive",
+ token_position.ToCString());
+ }
// Found existing position, tick it.
position.Tick(exclusive);
return;
}
+ if (position.token_pos().value() > token_position.value()) {
+ break;
+ }
}
- // Add new one.
+
+ // Add new one, sorted by token position value.
ProfileFunctionSourcePosition pfsp(token_position);
+ if (FLAG_trace_profiler) {
+ OS::Print("Ticking source position %s %s\n",
+ exclusive ? "exclusive" : "inclusive",
+ token_position.ToCString());
+ }
pfsp.Tick(exclusive);
- source_position_ticks_.Add(pfsp);
+
+ if (i < source_position_ticks_.length()) {
+ source_position_ticks_.InsertAt(i, pfsp);
+ } else {
+ source_position_ticks_.Add(pfsp);
+ }
}
@@ -1427,6 +1447,28 @@
}
}
+ intptr_t OffsetForPC(uword pc,
+ const Code& code,
+ ProcessedSample* sample,
+ intptr_t frame_index) {
+ intptr_t offset = pc - code.EntryPoint();
+ if (frame_index != 0) {
+ // The PC of frames below the top frame is a call's return address,
+ // which can belong to a different inlining interval than the call.
+ offset--;
+ } else if (sample->IsAllocationSample()) {
+ // Allocation samples skip the top frame, so the top frame's pc is
+ // also a call's return address.
+ offset--;
+ } else if (!sample->first_frame_executing()) {
+ // If the first frame wasn't executing code (i.e. we started to collect
+ // the stack trace at an exit frame), the top frame's pc is also a
+ // call's return address.
+ offset--;
+ }
+ return offset;
+ }
+
ProfileFunctionTrieNode* ProcessFrame(
ProfileFunctionTrieNode* current,
intptr_t sample_index,
@@ -1444,21 +1486,7 @@
GrowableArray<TokenPosition> inlined_token_positions;
TokenPosition token_position = TokenPosition::kNoSource;
if (!code.IsNull()) {
- intptr_t offset = pc - code.EntryPoint();
- if (frame_index != 0) {
- // The PC of frames below the top frame is a call's return address,
- // which can belong to a different inlining interval than the call.
- offset--;
- } else if (sample->IsAllocationSample()) {
- // Allocation samples skip the top frame, so the top frame's pc is
- // also a call's return address.
- offset--;
- } else if (!sample->first_frame_executing()) {
- // If the first frame wasn't executing code (i.e. we started to collect
- // the stack trace at an exit frame), the top frame's pc is also a
- // call's return address.
- offset--;
- }
+ const intptr_t offset = OffsetForPC(pc, code, sample, frame_index);
code.GetInlinedFunctionsAt(offset,
&inlined_functions,
&inlined_token_positions);
@@ -1587,13 +1615,15 @@
ProfileFunction* function,
TokenPosition token_position,
intptr_t code_index) {
- if (FLAG_trace_profiler) {
- THR_Print("S[%" Pd "]F[%" Pd "] %s %s\n",
- sample_index,
- frame_index,
- function->Name(), token_position.ToCString());
- }
if (tick_functions_) {
+ if (FLAG_trace_profiler) {
+ THR_Print("S[%" Pd "]F[%" Pd "] %s %s 0x%" Px "\n",
+ sample_index,
+ frame_index,
+ function->Name(),
+ token_position.ToCString(),
+ sample->At(frame_index));
+ }
function->Tick(IsExecutingFrame(sample, frame_index),
sample_index,
token_position);
@@ -2108,6 +2138,10 @@
}
+intptr_t Profile::NumFunctions() const {
+ return functions_->length();
+}
+
ProfileFunction* Profile::GetFunction(intptr_t index) {
ASSERT(functions_ != NULL);
return functions_->At(index);
@@ -2224,6 +2258,15 @@
}
+ProfileFunction* Profile::FindFunction(const Function& function) {
+ const intptr_t index = functions_->LookupIndex(function);
+ if (index < 0) {
+ return NULL;
+ }
+ return functions_->At(index);
+}
+
+
void Profile::PrintProfileJSON(JSONStream* stream) {
ScopeTimer sw("Profile::PrintProfileJSON", FLAG_trace_profiler);
JSONObject obj(stream);
diff --git a/runtime/vm/profiler_service.h b/runtime/vm/profiler_service.h
index 218bcb9..4bd64da 100644
--- a/runtime/vm/profiler_service.h
+++ b/runtime/vm/profiler_service.h
@@ -105,6 +105,14 @@
void TickSourcePosition(TokenPosition token_position, bool exclusive);
+ intptr_t NumSourcePositions() const {
+ return source_position_ticks_.length();
+ }
+
+ const ProfileFunctionSourcePosition& GetSourcePosition(intptr_t i) const {
+ return source_position_ticks_.At(i);
+ }
+
private:
const Kind kind_;
const char* name_;
@@ -347,6 +355,8 @@
}
intptr_t sample_count() const { return sample_count_; }
+ intptr_t NumFunctions() const;
+
ProfileFunction* GetFunction(intptr_t index);
ProfileCode* GetCode(intptr_t index);
ProfileTrieNode* GetTrieRoot(TrieKind trie_kind);
@@ -354,6 +364,8 @@
void PrintProfileJSON(JSONStream* stream);
void PrintTimelineJSON(JSONStream* stream);
+ ProfileFunction* FindFunction(const Function& function);
+
private:
void PrintHeaderJSON(JSONObject* obj);
void PrintTimelineFrameJSON(JSONObject* frames,
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index f0354fe..6f4e0ad 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -9,6 +9,7 @@
#include "vm/globals.h"
#include "vm/profiler.h"
#include "vm/profiler_service.h"
+#include "vm/source_report.h"
#include "vm/unit_test.h"
namespace dart {
@@ -989,8 +990,6 @@
walker.Reset(Profile::kExclusiveCode);
EXPECT(walker.Down());
- EXPECT_STREQ("_Float32Array._new", walker.CurrentName());
- EXPECT(walker.Down());
EXPECT_STREQ("_Float32Array._Float32Array", walker.CurrentName());
EXPECT(walker.Down());
EXPECT_STREQ("Float32List.Float32List", walker.CurrentName());
@@ -2301,6 +2300,204 @@
}
}
+
+static void InsertFakeSample(SampleBuffer* sample_buffer,
+ uword* pc_offsets) {
+ ASSERT(sample_buffer != NULL);
+ Isolate* isolate = Isolate::Current();
+ Sample* sample = sample_buffer->ReserveSample();
+ ASSERT(sample != NULL);
+ sample->Init(isolate,
+ OS::GetCurrentMonotonicMicros(),
+ OSThread::Current()->trace_id());
+
+ intptr_t i = 0;
+ while (pc_offsets[i] != 0) {
+ // When we collect a real stack trace, all PCs collected aside from the
+ // executing one (i == 0) are actually return addresses. Return addresses
+ // are one byte beyond the call instruction that is executing. The profiler
+ // accounts for this and subtracts one from these addresses when querying
+ // inline and token position ranges. To be consistent with real stack
+ // traces, we add one byte to all PCs except the executing one.
+ // See OffsetForPC in profiler_service.cc for more context.
+ const intptr_t return_address_offset = i > 0 ? 1 : 0;
+ sample->SetAt(i, pc_offsets[i] + return_address_offset);
+ i++;
+ }
+ sample->SetAt(i, NULL);
+}
+
+
+static uword FindPCForTokenPosition(const Code& code,
+ const CodeSourceMap& code_source_map,
+ TokenPosition tp) {
+ CodeSourceMap::Iterator it(code_source_map);
+
+ while (it.MoveNext()) {
+ if (it.TokenPos() == tp) {
+ return it.PcOffset() + code.EntryPoint();
+ }
+ }
+
+ return 0;
+}
+
+
+TEST_CASE(Profiler_GetSourceReport) {
+ const char* kScript =
+ "doWork(i) => i * i;\n"
+ "main() {\n"
+ " var sum = 0;\n"
+ " for (var i = 0; i < 100; i++) {\n"
+ " sum += doWork(i);\n"
+ " }\n"
+ " return sum;\n"
+ "}\n";
+
+ // Token position of * in `i * i`.
+ const TokenPosition squarePosition = TokenPosition(6);
+
+ // Token position of the call to `doWork`.
+ const TokenPosition callPosition = TokenPosition(39);
+
+ DisableNativeProfileScope dnps;
+ // Disable profiling for this thread.
+ DisableThreadInterruptsScope dtis(Thread::Current());
+
+ SampleBuffer* sample_buffer = Profiler::sample_buffer();
+ EXPECT(sample_buffer != NULL);
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ EXPECT_VALID(lib);
+ Library& root_library = Library::Handle();
+ root_library ^= Api::UnwrapHandle(lib);
+
+ // Invoke main so that it gets compiled.
+ Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+ EXPECT_VALID(result);
+
+ {
+ // Clear the profile for this isolate.
+ ClearProfileVisitor cpv(Isolate::Current());
+ sample_buffer->VisitSamples(&cpv);
+ }
+
+ // Query the code object for main and determine the PC at some token
+ // positions.
+ const Function& main = Function::Handle(GetFunction(root_library, "main"));
+ EXPECT(!main.IsNull());
+
+ const Function& do_work =
+ Function::Handle(GetFunction(root_library, "doWork"));
+ EXPECT(!do_work.IsNull());
+
+ const Script& script = Script::Handle(main.script());
+ EXPECT(!script.IsNull());
+
+ const Code& main_code = Code::Handle(main.CurrentCode());
+ EXPECT(!main_code.IsNull());
+
+ const Code& do_work_code = Code::Handle(do_work.CurrentCode());
+ EXPECT(!do_work_code.IsNull());
+
+ const CodeSourceMap& main_code_source_map =
+ CodeSourceMap::Handle(main_code.code_source_map());
+ EXPECT(!main_code_source_map.IsNull());
+
+ const CodeSourceMap& do_work_code_source_map =
+ CodeSourceMap::Handle(do_work_code.code_source_map());
+ EXPECT(!do_work_code_source_map.IsNull());
+
+ // Dump code source map.
+ CodeSourceMap::Dump(do_work_code_source_map, do_work_code, main);
+ CodeSourceMap::Dump(main_code_source_map, main_code, main);
+
+ // Look up some source token position's pc.
+ uword squarePositionPc =
+ FindPCForTokenPosition(do_work_code,
+ do_work_code_source_map,
+ squarePosition);
+ EXPECT(squarePositionPc != 0);
+
+ uword callPositionPc =
+ FindPCForTokenPosition(main_code, main_code_source_map, callPosition);
+ EXPECT(callPositionPc != 0);
+
+ // Look up some classifying token position's pc.
+ uword controlFlowPc =
+ FindPCForTokenPosition(do_work_code,
+ do_work_code_source_map,
+ TokenPosition::kControlFlow);
+ EXPECT(controlFlowPc != 0);
+
+ uword tempMovePc =
+ FindPCForTokenPosition(main_code,
+ main_code_source_map,
+ TokenPosition::kTempMove);
+ EXPECT(tempMovePc != 0);
+
+ // Insert fake samples.
+
+ // Sample 1:
+ // squarePositionPc exclusive.
+ // callPositionPc inclusive.
+ uword sample1[] = {
+ squarePositionPc, // doWork.
+ callPositionPc, // main.
+ 0
+ };
+
+ // Sample 2:
+ // squarePositionPc exclusive.
+ uword sample2[] = {
+ squarePositionPc, // doWork.
+ 0,
+ };
+
+ // Sample 3:
+ // controlFlowPc exclusive.
+ // callPositionPc inclusive.
+ uword sample3[] = {
+ controlFlowPc, // doWork.
+ callPositionPc, // main.
+ 0
+ };
+
+ // Sample 4:
+ // tempMovePc exclusive.
+ uword sample4[] = {
+ tempMovePc, // main.
+ 0
+ };
+
+ InsertFakeSample(sample_buffer, &sample1[0]);
+ InsertFakeSample(sample_buffer, &sample2[0]);
+ InsertFakeSample(sample_buffer, &sample3[0]);
+ InsertFakeSample(sample_buffer, &sample4[0]);
+
+ // Generate source report for main.
+ SourceReport sourceReport(SourceReport::kProfile);
+ JSONStream js;
+ sourceReport.PrintJSON(&js,
+ script,
+ do_work.token_pos(),
+ main.end_token_pos());
+
+ // Verify positions in do_work.
+ EXPECT_SUBSTRING("\"positions\":[\"ControlFlow\",6]", js.ToCString());
+ // Verify exclusive ticks in do_work.
+ EXPECT_SUBSTRING("\"exclusiveTicks\":[1,2]", js.ToCString());
+ // Verify inclusive ticks in do_work.
+ EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString());
+
+ // Verify positions in main.
+ EXPECT_SUBSTRING("\"positions\":[\"TempMove\",39]", js.ToCString());
+ // Verify exclusive ticks in main.
+ EXPECT_SUBSTRING("\"exclusiveTicks\":[1,0]", js.ToCString());
+ // Verify inclusive ticks in main.
+ EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString());
+}
+
#endif // !PRODUCT
} // namespace dart
diff --git a/runtime/vm/runtime_entry_arm.cc b/runtime/vm/runtime_entry_arm.cc
index 35e15ea..a0bb2e9 100644
--- a/runtime/vm/runtime_entry_arm.cc
+++ b/runtime/vm/runtime_entry_arm.cc
@@ -53,7 +53,7 @@
// informative error message.
__ LoadFromOffset(kWord, R9, THR, Thread::OffsetFromThread(this));
__ LoadImmediate(R4, argument_count);
- __ BranchLink(*StubCode::CallToRuntime_entry(), kNotPatchable);
+ __ BranchLinkToRuntime();
}
}
diff --git a/runtime/vm/runtime_entry_arm64.cc b/runtime/vm/runtime_entry_arm64.cc
index 5b1605a..f9cd8c2 100644
--- a/runtime/vm/runtime_entry_arm64.cc
+++ b/runtime/vm/runtime_entry_arm64.cc
@@ -65,7 +65,7 @@
// informative error message.
__ ldr(R5, Address(THR, Thread::OffsetFromThread(this)));
__ LoadImmediate(R4, argument_count);
- __ BranchLink(*StubCode::CallToRuntime_entry());
+ __ BranchLinkToRuntime();
}
}
diff --git a/runtime/vm/runtime_entry_ia32.cc b/runtime/vm/runtime_entry_ia32.cc
index f16db03..fdb2464 100644
--- a/runtime/vm/runtime_entry_ia32.cc
+++ b/runtime/vm/runtime_entry_ia32.cc
@@ -38,7 +38,7 @@
// informative error message.
__ movl(ECX, Immediate(GetEntryPoint()));
__ movl(EDX, Immediate(argument_count));
- __ Call(*StubCode::CallToRuntime_entry());
+ __ CallToRuntime();
}
}
diff --git a/runtime/vm/runtime_entry_mips.cc b/runtime/vm/runtime_entry_mips.cc
index 31970fe..b310556 100644
--- a/runtime/vm/runtime_entry_mips.cc
+++ b/runtime/vm/runtime_entry_mips.cc
@@ -54,7 +54,7 @@
// informative error message.
__ lw(S5, Address(THR, Thread::OffsetFromThread(this)));
__ LoadImmediate(S4, argument_count);
- __ BranchLink(*StubCode::CallToRuntime_entry(), kNotPatchable);
+ __ BranchLinkToRuntime();
}
}
diff --git a/runtime/vm/runtime_entry_x64.cc b/runtime/vm/runtime_entry_x64.cc
index c3afdd8..84026ec 100644
--- a/runtime/vm/runtime_entry_x64.cc
+++ b/runtime/vm/runtime_entry_x64.cc
@@ -36,7 +36,7 @@
// informative error message.
__ movq(RBX, Address(THR, Thread::OffsetFromThread(this)));
__ movq(R10, Immediate(argument_count));
- __ Call(*StubCode::CallToRuntime_entry());
+ __ CallToRuntime();
}
}
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index aca3a5b..fb7a5db 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2400,15 +2400,11 @@
}
-static const char* kCallSitesStr = "_CallSites";
-static const char* kCoverageStr = "Coverage";
-static const char* kPossibleBreakpointsStr = "PossibleBreakpoints";
-
-
static const char* const report_enum_names[] = {
- kCallSitesStr,
- kCoverageStr,
- kPossibleBreakpointsStr,
+ SourceReport::kCallSitesStr,
+ SourceReport::kCoverageStr,
+ SourceReport::kPossibleBreakpointsStr,
+ SourceReport::kProfileStr,
NULL,
};
@@ -2436,12 +2432,14 @@
const char** reports = reports_parameter->Parse(thread->zone(), reports_str);
intptr_t report_set = 0;
while (*reports != NULL) {
- if (strcmp(*reports, kCallSitesStr) == 0) {
+ if (strcmp(*reports, SourceReport::kCallSitesStr) == 0) {
report_set |= SourceReport::kCallSites;
- } else if (strcmp(*reports, kCoverageStr) == 0) {
+ } else if (strcmp(*reports, SourceReport::kCoverageStr) == 0) {
report_set |= SourceReport::kCoverage;
- } else if (strcmp(*reports, kPossibleBreakpointsStr) == 0) {
+ } else if (strcmp(*reports, SourceReport::kPossibleBreakpointsStr) == 0) {
report_set |= SourceReport::kPossibleBreakpoints;
+ } else if (strcmp(*reports, SourceReport::kProfileStr) == 0) {
+ report_set |= SourceReport::kProfile;
}
reports++;
}
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index bbd35ab..494ac53 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -5,11 +5,19 @@
#include "vm/source_report.h"
#include "vm/compiler.h"
+#include "vm/isolate.h"
#include "vm/object.h"
#include "vm/object_store.h"
+#include "vm/profiler.h"
+#include "vm/profiler_service.h"
namespace dart {
+const char* SourceReport::kCallSitesStr = "_CallSites";
+const char* SourceReport::kCoverageStr = "Coverage";
+const char* SourceReport::kPossibleBreakpointsStr = "PossibleBreakpoints";
+const char* SourceReport::kProfileStr = "_Profile";
+
SourceReport::SourceReport(intptr_t report_set, CompileMode compile_mode)
: report_set_(report_set),
compile_mode_(compile_mode),
@@ -17,6 +25,7 @@
script_(NULL),
start_pos_(TokenPosition::kNoSource),
end_pos_(TokenPosition::kNoSource),
+ profile_(Isolate::Current()),
next_script_index_(0) {
}
@@ -32,6 +41,11 @@
script_table_entries_.Clear();
script_table_.Clear();
next_script_index_ = 0;
+ if (IsReportRequested(kProfile)) {
+ // Build the profile.
+ SampleFilter samplesForIsolate(thread_->isolate(), -1, -1);
+ profile_.Build(thread, &samplesForIsolate, Profile::kNoTags);
+ }
}
@@ -250,6 +264,58 @@
}
+void SourceReport::PrintProfileData(JSONObject* jsobj,
+ ProfileFunction* profile_function) {
+ ASSERT(profile_function != NULL);
+ ASSERT(profile_function->NumSourcePositions() > 0);
+
+ {
+ JSONObject profile(jsobj, "profile");
+
+ {
+ JSONObject profileData(&profile, "metadata");
+ profileData.AddProperty("sampleCount", profile_.sample_count());
+ }
+
+ // Positions.
+ {
+ JSONArray positions(&profile, "positions");
+ for (intptr_t i = 0; i < profile_function->NumSourcePositions(); i++) {
+ const ProfileFunctionSourcePosition& position =
+ profile_function->GetSourcePosition(i);
+ if (position.token_pos().IsSourcePosition() &&
+ !position.token_pos().IsNoSource()) {
+ // Add as an integer.
+ positions.AddValue(position.token_pos().Pos());
+ } else {
+ // Add as a string.
+ positions.AddValue(position.token_pos().ToCString());
+ }
+ }
+ }
+
+ // Exclusive ticks.
+ {
+ JSONArray exclusiveTicks(&profile, "exclusiveTicks");
+ for (intptr_t i = 0; i < profile_function->NumSourcePositions(); i++) {
+ const ProfileFunctionSourcePosition& position =
+ profile_function->GetSourcePosition(i);
+ exclusiveTicks.AddValue(position.exclusive_ticks());
+ }
+ }
+ // Inclusive ticks.
+ {
+ JSONArray inclusiveTicks(&profile, "inclusiveTicks");
+ for (intptr_t i = 0; i < profile_function->NumSourcePositions(); i++) {
+ const ProfileFunctionSourcePosition& position =
+ profile_function->GetSourcePosition(i);
+ inclusiveTicks.AddValue(position.inclusive_ticks());
+ }
+ }
+ }
+}
+
+
void SourceReport::PrintScriptTable(JSONArray* scripts) {
for (int i = 0; i < script_table_entries_.length(); i++) {
const Script* script = script_table_entries_[i].script;
@@ -311,6 +377,13 @@
if (IsReportRequested(kPossibleBreakpoints)) {
PrintPossibleBreakpointsData(&range, func, code);
}
+ if (IsReportRequested(kProfile)) {
+ ProfileFunction* profile_function = profile_.FindFunction(func);
+ if ((profile_function != NULL) &&
+ (profile_function->NumSourcePositions() > 0)) {
+ PrintProfileData(&range, profile_function);
+ }
+ }
}
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index 77bf6c2..cd2ad3a 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -9,6 +9,7 @@
#include "vm/flags.h"
#include "vm/hash_map.h"
#include "vm/object.h"
+#include "vm/profiler_service.h"
#include "vm/token_position.h"
namespace dart {
@@ -22,8 +23,14 @@
kCallSites = 0x1,
kCoverage = 0x2,
kPossibleBreakpoints = 0x4,
+ kProfile = 0x8,
};
+ static const char* kCallSitesStr;
+ static const char* kCoverageStr;
+ static const char* kPossibleBreakpointsStr;
+ static const char* kProfileStr;
+
enum CompileMode {
kNoCompile,
kForceCompile
@@ -48,6 +55,7 @@
Thread* thread() const { return thread_; }
Zone* zone() const { return thread_->zone(); }
+ Isolate* isolate() const { return thread_->isolate(); }
bool IsReportRequested(ReportKind report_kind);
bool ShouldSkipFunction(const Function& func);
@@ -60,6 +68,7 @@
const Function& func, const Code& code);
void PrintPossibleBreakpointsData(JSONObject* jsobj,
const Function& func, const Code& code);
+ void PrintProfileData(JSONObject* jsobj, ProfileFunction* profile_function);
void PrintScriptTable(JSONArray* jsarr);
void VisitFunction(JSONArray* jsarr, const Function& func);
@@ -104,6 +113,7 @@
const Script* script_;
TokenPosition start_pos_;
TokenPosition end_pos_;
+ Profile profile_;
GrowableArray<ScriptTableEntry> script_table_entries_;
DirectChainedHashMap<ScriptTableTrait> script_table_;
intptr_t next_script_index_;
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 9390ee1..5b31bef75 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -309,8 +309,6 @@
V(NullThrownError, "NullThrownError") \
V(IsolateSpawnException, "IsolateSpawnException") \
V(BooleanExpression, "boolean expression") \
- V(Malformed, "malformed") \
- V(Malbounded, "malbounded") \
V(MegamorphicMiss, "megamorphic_miss") \
V(CommaSpace, ", ") \
V(ColonSpace, ": ") \
@@ -318,6 +316,9 @@
V(SpaceExtendsSpace, " extends ") \
V(SpaceWhereNewLine, " where\n") \
V(SpaceIsFromSpace, " is from ") \
+ V(InTypeCast, " in type cast") \
+ V(TypeQuote, "type '") \
+ V(QuoteIsNotASubtypeOf, "' is not a subtype of ") \
V(SpaceOfSpace, " of ") \
V(SwitchExpr, ":switch_expr") \
V(TwoNewlines, "\n\n") \
@@ -333,7 +334,6 @@
V(ClosurizePrefix, "get:#") \
V(SetterPrefix, "set:") \
V(InitPrefix, "init:") \
- V(_New, "_new") \
V(Index, "index") \
V(DartScheme, "dart:") \
V(DartSchemePrivate, "dart:_") \
@@ -499,9 +499,12 @@
static const String& NewLine() {
return *(symbol_handles_[kNullCharId + '\n']);
}
- static const String& DoubleQuotes() {
+ static const String& DoubleQuote() {
return *(symbol_handles_[kNullCharId + '"']);
}
+ static const String& SingleQuote() {
+ return *(symbol_handles_[kNullCharId + '\'']);
+ }
static const String& LowercaseR() {
return *(symbol_handles_[kNullCharId + 'r']);
}
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 2d8531c..3bf5aab 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -82,10 +82,14 @@
StubCode::FixAllocationStubTarget_entry()->code(), NULL) \
V(RawCode*, invoke_dart_code_stub_, \
StubCode::InvokeDartCode_entry()->code(), NULL) \
+ V(RawCode*, call_to_runtime_stub_, \
+ StubCode::CallToRuntime_entry()->code(), NULL) \
#define CACHED_ADDRESSES_LIST(V) \
V(uword, update_store_buffer_entry_point_, \
StubCode::UpdateStoreBuffer_entry()->EntryPoint(), 0) \
+ V(uword, call_to_runtime_entry_point_, \
+ StubCode::CallToRuntime_entry()->EntryPoint(), 0) \
V(uword, native_call_wrapper_entry_point_, \
NativeEntry::NativeCallWrapperEntry(), 0) \
V(RawString**, predefined_symbols_address_, \
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 2fa59ef..cd0b0fd 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -155,6 +155,22 @@
}
+void Timeline::StreamStateChange(const char* stream_name,
+ bool prev,
+ bool curr) {
+ if (prev == curr) {
+ return;
+ }
+ if (strcmp(stream_name, "Embedder") == 0) {
+ if (curr && (Timeline::get_start_recording_cb() != NULL)) {
+ Timeline::get_start_recording_cb()();
+ } else if (!curr && (Timeline::get_stop_recording_cb() != NULL)) {
+ Timeline::get_stop_recording_cb()();
+ }
+ }
+}
+
+
void Timeline::Shutdown() {
ASSERT(recorder_ != NULL);
if (FLAG_timeline_dir != NULL) {
@@ -273,6 +289,9 @@
TimelineStream Timeline::vm_stream_;
TimelineStream Timeline::vm_api_stream_;
MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL;
+Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL;
+Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL;
+Dart_EmbedderTimelineGetTimeline Timeline::get_timeline_cb_ = NULL;
#define ISOLATE_TIMELINE_STREAM_DEFINE_FLAG(name, enabled_by_default) \
bool Timeline::stream_##name##_enabled_ = enabled_by_default;
@@ -1008,6 +1027,14 @@
}
+void TimelineEventRecorder::PrintEmbedderJSONEvents(JSONStream* events) {
+ if (Timeline::get_get_timeline_cb() != NULL) {
+ events->PrintCommaIfNeeded();
+ Timeline::get_get_timeline_cb()(AppendJSONStreamConsumer, events);
+ }
+}
+
+
void TimelineEventRecorder::WriteTo(const char* directory) {
if (!FLAG_support_service) {
return;
@@ -1147,6 +1174,7 @@
JSONArray events(&topLevel, "traceEvents");
PrintJSONMeta(&events);
PrintJSONEvents(&events, filter);
+ PrintEmbedderJSONEvents(js);
}
}
@@ -1158,6 +1186,7 @@
}
JSONArray events(js);
PrintJSONEvents(&events, filter);
+ PrintEmbedderJSONEvents(js);
}
@@ -1280,6 +1309,7 @@
JSONArray events(&topLevel, "traceEvents");
PrintJSONMeta(&events);
PrintJSONEvents(&events, filter);
+ PrintEmbedderJSONEvents(js);
}
}
@@ -1292,6 +1322,7 @@
}
JSONArray events(js);
PrintJSONEvents(&events, filter);
+ PrintEmbedderJSONEvents(js);
}
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 002f8c9..9887aff 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -5,6 +5,8 @@
#ifndef VM_TIMELINE_H_
#define VM_TIMELINE_H_
+#include "include/dart_tools_api.h"
+
#include "vm/allocation.h"
#include "vm/bitfield.h"
#include "vm/os.h"
@@ -65,17 +67,49 @@
return &stream_##name##_enabled_; \
} \
static void SetStream##name##Enabled(bool enabled) { \
+ StreamStateChange(#name, stream_##name##_enabled_, enabled); \
stream_##name##_enabled_ = enabled; \
}
ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_FLAGS)
#undef ISOLATE_TIMELINE_STREAM_FLAGS
static void SetVMStreamEnabled(bool enabled);
+ static void set_start_recording_cb(
+ Dart_EmbedderTimelineStartRecording start_recording_cb) {
+ start_recording_cb_ = start_recording_cb;
+ }
+
+ static Dart_EmbedderTimelineStartRecording get_start_recording_cb() {
+ return start_recording_cb_;
+ }
+
+ static void set_stop_recording_cb(
+ Dart_EmbedderTimelineStopRecording stop_recording_cb) {
+ stop_recording_cb_ = stop_recording_cb;
+ }
+
+ static Dart_EmbedderTimelineStopRecording get_stop_recording_cb() {
+ return stop_recording_cb_;
+ }
+
+ static void set_get_timeline_cb(
+ Dart_EmbedderTimelineGetTimeline get_timeline_cb) {
+ get_timeline_cb_ = get_timeline_cb;
+ }
+
+ static Dart_EmbedderTimelineGetTimeline get_get_timeline_cb() {
+ return get_timeline_cb_;
+ }
+
private:
+ static void StreamStateChange(const char* stream_name, bool prev, bool curr);
static TimelineEventRecorder* recorder_;
static TimelineStream vm_stream_;
static TimelineStream vm_api_stream_;
static MallocGrowableArray<char*>* enabled_streams_;
+ static Dart_EmbedderTimelineStartRecording start_recording_cb_;
+ static Dart_EmbedderTimelineStopRecording stop_recording_cb_;
+ static Dart_EmbedderTimelineGetTimeline get_timeline_cb_;
#define ISOLATE_TIMELINE_STREAM_DECLARE_FLAG(name, not_used) \
static bool stream_##name##_enabled_;
@@ -644,6 +678,7 @@
void PrintJSONMeta(JSONArray* array) const;
TimelineEvent* ThreadBlockStartEvent();
void ThreadBlockCompleteEvent(TimelineEvent* event);
+ void PrintEmbedderJSONEvents(JSONStream* events);
Mutex lock_;
uintptr_t async_id_;
diff --git a/sdk/lib/core/num.dart b/sdk/lib/core/num.dart
index 8009536..38587b1 100644
--- a/sdk/lib/core/num.dart
+++ b/sdk/lib/core/num.dart
@@ -374,8 +374,8 @@
* 1234567.toStringAsPrecision(9); // 1234567.00
* 12345678901234567890.toStringAsPrecision(20); // 12345678901234567168
* 12345678901234567890.toStringAsPrecision(14); // 1.2345678901235e+19
- * 0.00000012345.toPrecision(15); // 1.23450000000000e-7
- * 0.0000012345.toPrecision(15); // 0.00000123450000000000
+ * 0.00000012345.toStringAsPrecision(15); // 1.23450000000000e-7
+ * 0.0000012345.toStringAsPrecision(15); // 0.00000123450000000000
*/
String toStringAsPrecision(int precision);
diff --git a/sdk/lib/internal/iterable.dart b/sdk/lib/internal/iterable.dart
index 9a5f29f..f3e3166 100644
--- a/sdk/lib/internal/iterable.dart
+++ b/sdk/lib/internal/iterable.dart
@@ -749,12 +749,6 @@
E get current => null;
}
-/** An [Iterator] that can move in both directions. */
-abstract class BidirectionalIterator<T> implements Iterator<T> {
- bool movePrevious();
-}
-
-
/**
* Creates errors throw by [Iterable] when the element count is wrong.
*/
diff --git a/sdk/lib/io/data_transformer.dart b/sdk/lib/io/data_transformer.dart
index 144234d..d3648e7 100644
--- a/sdk/lib/io/data_transformer.dart
+++ b/sdk/lib/io/data_transformer.dart
@@ -518,7 +518,6 @@
_closed = true;
throw e;
}
- if (!_closed) _filter.end();
_closed = true;
_sink.close();
}
@@ -545,13 +544,6 @@
*/
List<int> processed({bool flush: true, bool end: false});
- /**
- * Mark the filter as closed. Always call this method for any filter created
- * to avoid leaking resources. [end] can be called at any time, but any
- * successive calls to [process] or [processed] will fail.
- */
- void end();
-
external static _Filter _newZLibDeflateFilter(bool gzip, int level,
int windowBits, int memLevel,
int strategy,
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index 2aa894c..6acd661 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -581,7 +581,6 @@
if ((serverSide && clientNoContextTakeover) ||
(!serverSide && serverNoContextTakeover)) {
- decoder.end();
decoder = null;
}
@@ -614,7 +613,6 @@
if ((!serverSide && clientNoContextTakeover) ||
(serverSide && serverNoContextTakeover)) {
- encoder.end();
encoder = null;
}
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index d2b1f39..070baf7 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -1171,7 +1171,7 @@
operator []=(int index, value) => blink_jsObject[index] = value;
int get length => blink_jsObject.length;
- int set length(int newLength) => blink_jsObject.length = newLength;
+ set length(int newLength) => blink_jsObject.length = newLength;
}
@Deprecated("Internal Use Only")
diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
index 7af7f45..6592ea8 100644
--- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -210,7 +210,7 @@
// http://www.w3.org/TR/webdatabase/#sqlresultsetrowlist
@Experimental() // deprecated
@Native("SQLResultSetRowList")
-class SqlResultSetRowList extends Interceptor with ListMixin<Map>, ImmutableListMixin<Map> implements JavaScriptIndexingBehavior, List<Map> {
+class SqlResultSetRowList extends Interceptor with ListMixin<Map>, ImmutableListMixin<Map> implements List<Map> {
// To suppress missing implicit constructor warnings.
factory SqlResultSetRowList._() { throw new UnsupportedError("Not supported"); }
@@ -222,7 +222,7 @@
if (JS("bool", "# >>> 0 !== # || # >= #", index,
index, index, length))
throw new RangeError.index(index, this);
- return JS("Map", "#[#]", this, index);
+ return this.item(index);
}
void operator[]=(int index, Map value) {
throw new UnsupportedError("Cannot assign element of immutable List.");
@@ -264,8 +264,13 @@
@DomName('SQLResultSetRowList.item')
@DocsEditable()
- @Creates('=Object')
- Object item(int index) native;
+ Map item(int index) {
+ return convertNativeToDart_Dictionary(_item_1(index));
+ }
+ @JSName('item')
+ @DomName('SQLResultSetRowList.item')
+ @DocsEditable()
+ _item_1(index) native;
}
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
diff --git a/tests/benchmark_smoke/benchmark_smoke.status b/tests/benchmark_smoke/benchmark_smoke.status
index 188684a..7aa0af0 100644
--- a/tests/benchmark_smoke/benchmark_smoke.status
+++ b/tests/benchmark_smoke/benchmark_smoke.status
@@ -9,5 +9,4 @@
*: Fail, Pass # TODO(ahe): Triage these tests.
[ $compiler == dart2js && $cps_ir && $checked ]
-benchmark_smoke: Crash # `assert` not implemented
-
+*: Skip # Issue 25761
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 71496c5..021b554 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -9638,8 +9638,6 @@
[ $compiler == dart2js && $cps_ir ]
Language/Types/Interface_Types/subtype_t09: Crash # Pending static: JSArray
LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
-LibTest/core/Invocation/isGetter_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Invocation/isSetter_A01_t02: RuntimeError # Please triage this failure.
LibTest/core/Invocation/memberName_A01_t01: RuntimeError # Expect.equals(expected: <Symbol("bar=")>, actual: <Symbol("bar")>) fails.
[ $compiler == dart2js && $cps_ir && $host_checked ]
diff --git a/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart b/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
index e4b9326..e774726 100644
--- a/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
+++ b/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
@@ -105,7 +105,7 @@
bool isHelper(Element element) {
Uri uri = element.library.canonicalUri;
- return uri.path.endsWith('src/helpers/helpers.dart');
+ return '$uri'.startsWith('package:compiler/src/helpers/');
}
void checkAccess(Node node, MemberElement element) {
@@ -233,4 +233,4 @@
_) {
checkAccess(node, constant.target);
}
-}
\ No newline at end of file
+}
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 9f20998..3581b17 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -57,7 +57,7 @@
void expectHasNoBody(compiler, ElementX element) {
var node = element.parseNode(compiler.parsing);
Expect.isNotNull(node, "Element isn't parseable, when a body was expected");
- Expect.isFalse(node.hasBody());
+ Expect.isFalse(node.hasBody);
}
Element ensure(compiler,
diff --git a/tests/compiler/dart2js/sourcemaps/source_mapping_invokes_test.dart b/tests/compiler/dart2js/sourcemaps/source_mapping_invokes_test.dart
index ce4d362..6ca3c0f 100644
--- a/tests/compiler/dart2js/sourcemaps/source_mapping_invokes_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/source_mapping_invokes_test.dart
@@ -3,17 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'source_mapping_tester.dart';
-import 'sourcemap_helper.dart';
-import 'package:compiler/src/io/position_information.dart';
void main() {
- test(['invokes'], whiteListFunction: (String config, String file) {
- if (config == 'cps') {
- return (CodePoint codePoint) {
- // Temporarily allow missing code points on expression statements.
- return codePoint.kind == StepKind.EXPRESSION_STATEMENT;
- };
- }
- return emptyWhiteList;
- });
+ test(['invokes']);
}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/sourcemaps/source_mapping_operators_test.dart b/tests/compiler/dart2js/sourcemaps/source_mapping_operators_test.dart
index 3aaacce..34a826c 100644
--- a/tests/compiler/dart2js/sourcemaps/source_mapping_operators_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/source_mapping_operators_test.dart
@@ -4,7 +4,6 @@
import 'source_mapping_tester.dart';
import 'sourcemap_helper.dart';
-import 'package:compiler/src/io/position_information.dart';
void main() {
test(['operators'], whiteListFunction: (String config, String file) {
@@ -13,20 +12,6 @@
return codePoint.jsCode.contains(r'.$gt()'); // # Issue 25304
}
- if (config == 'cps') {
- return (CodePoint codePoint) {
- // Temporarily allow missing code points on expression statements.
- if (codePoint.kind == StepKind.EXPRESSION_STATEMENT ||
- codePoint.kind == StepKind.IF_CONDITION) {
- return true;
- }
- if (codePoint.jsCode.contains(r'H.iae(')) {
- // Allow missing code points for bailout calls.
- return true;
- }
- return allowGtOptimization(codePoint);
- };
- }
return allowGtOptimization;
});
}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/value_range2_test.dart b/tests/compiler/dart2js/value_range2_test.dart
index 803ab05..d14311b 100644
--- a/tests/compiler/dart2js/value_range2_test.dart
+++ b/tests/compiler/dart2js/value_range2_test.dart
@@ -3,7 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import "package:expect/expect.dart";
-import "package:compiler/src/ssa/ssa.dart";
+import "package:compiler/src/ssa/nodes.dart";
+import "package:compiler/src/ssa/value_range_analyzer.dart";
import "package:compiler/src/js_backend/constant_system_javascript.dart";
ValueRangeInfo info = new ValueRangeInfo(const JavaScriptConstantSystem());
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index e08d601..28abf25 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -24,7 +24,6 @@
foreign_test: RuntimeError # Expect.equals(expected: <1234567891011>, actual: <1234567891011>) fails.
native_exception_test: RuntimeError # Issue 24421
optimization_hints_test: RuntimeError # Please triage this failure.
-subclassing_constructor_2_test: RuntimeError # Please triage this failure.
[ $compiler == dart2js && $cps_ir && $checked ]
*: Skip # `assert` not implemented, 75% of the tests fail.
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 083fa8f..021d7ba 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -181,6 +181,9 @@
regexp/pcre_test: Crash # Stack Overflow in LoopHierarchy.
core_runtime_types_test: Pass, RuntimeError # Issue 25795.
+[ $compiler == dart2js && $cps_ir && $checked ]
+*: Skip # Issue 25761
+
[ $compiler == dart2js && $cps_ir && $host_checked ]
regexp/pcre_test: Crash # Stack Overflow
collection_removes_test: Crash # Issue 25911
diff --git a/tests/html/canvasrenderingcontext2d_test.dart b/tests/html/canvasrenderingcontext2d_test.dart
index ffd8b8d..6d87a64 100644
--- a/tests/html/canvasrenderingcontext2d_test.dart
+++ b/tests/html/canvasrenderingcontext2d_test.dart
@@ -688,7 +688,9 @@
expectPixelFilled(x + 10, y);
// The box does not draw after `width` pixels.
- expectPixelFilled(x + width - 1, y);
+ // Check -2 rather than -1 because this seems
+ // to run into a rounding error on Mac bots.
+ expectPixelFilled(x + width - 2, y);
expectPixelUnfilled(x + width + 1, y);
});
@@ -709,7 +711,9 @@
expectPixelFilled(x + 10, y);
// The box does not draw after `width` pixels.
- expectPixelFilled(x + width - 1, y);
+ // Check -2 rather than -1 because this seems
+ // to run into a rounding error on Mac bots.
+ expectPixelFilled(x + width - 2, y);
expectPixelUnfilled(x + width + 1, y);
});
diff --git a/tests/html/html.status b/tests/html/html.status
index 3398318..5b30a0a 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -32,9 +32,6 @@
wrapping_collections_test: SkipByDesign # Testing an issue that is only relevant to Dartium
js_typed_interop_default_arg_test/default_value: MissingCompileTimeError # Issue #25759
-[ $compiler == dart2js && ($runtime == chrome || $runtime == drt || $runtime == dartium || $runtime == safari) ]
-websql_test/functional: RuntimeError, Slow # Issue 25927
-
[ $compiler == dart2js && $checked ]
js_function_getter_trust_types_test: Skip # --trust-type-annotations incompatible with --checked
@@ -423,17 +420,6 @@
js_typed_interop_default_arg_test/default_value: MissingCompileTimeError # Issue #25759
[ $compiler == dart2js && $cps_ir && $browser ]
-# Custom element support:
-custom/constructor_calls_created_synchronously_test: RuntimeError # Need custom element support #25484
-custom/element_upgrade_test: RuntimeError # Need custom element support #25484
-custom/mirrors_test: RuntimeError # Need custom element support #25484
-custom_elements_23127_test/baseline: RuntimeError # Need custom element support #25484
-custom_elements_23127_test/c2: RuntimeError # Need custom element support #25484
-custom_elements_23127_test/c1t: RuntimeError # Need custom element support #25484
-custom_elements_23127_test/c2t: RuntimeError # Need custom element support #25484
-custom_elements_test/innerHtml: RuntimeError # Need custom element support #25484
-custom_elements_test/register: RuntimeError # Need custom element support #25484
-
js_typed_interop_side_cast_exp_test: RuntimeError # Corner case in package:js that we might want to remove (See comment in #24978).
js_typed_interop_test/static_method_tearoff_1: RuntimeError # Tree-shaking a used tear-off (#24978, #25720).
js_typed_interop_default_arg_test/explicit_argument: RuntimeError # Tree-shaking a used tear-off (#24978, #25720).
diff --git a/tests/language/generic_functions_test.dart b/tests/language/generic_functions_test.dart
new file mode 100644
index 0000000..54ab173
--- /dev/null
+++ b/tests/language/generic_functions_test.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart test verifying that the parser can handle type parameterization of
+// function declarations and function invocations. Variant of code from
+// DEP #22, adjusted to use generic top level functions.
+
+class BinaryTreeNode<K extends Comparable<K>, V> {
+ final K _key;
+ final V _value;
+ final BinaryTreeNode<K, V> _left;
+ final BinaryTreeNode<K, V> _right;
+
+ BinaryTreeNode(this._key, this._value,
+ {BinaryTreeNode<K, V> left: null, BinaryTreeNode<K, V> right: null}) :
+ _left = left, _right = right;
+
+ BinaryTreeNode<K, V> insert(K key, V value) {
+ int c = key.compareTo(_key);
+ if (c == 0) return this;
+ var _insert = (BinaryTreeNode<K, V> t, K key, V value) =>
+ insertOpt<K, V>(t, key, value);
+ BinaryTreeNode<K, V> left = _left;
+ BinaryTreeNode<K, V> right = _right;
+ if (c < 0) {
+ left = _insert(_left, key, value);
+ } else {
+ right = _insert(_right, key, value);
+ }
+ return new BinaryTreeNode<K, V>(_key, _value, left: left, right: right);
+ }
+
+ BinaryTreeNode<K, U> map<U>(U f(V x)){
+ var _map = (BinaryTreeNode<K, V> t, U f(V x)) => mapOpt<K, V, U>(t, f);
+ return new BinaryTreeNode<K, U>(
+ _key,
+ f(_value),
+ left: _map(_left, f),
+ right: _map(_right, f));
+ }
+
+ S foldPre<S>(S init, S f(V t, S s)) {
+ var _fold = (BinaryTreeNode<K, V> t, S s, S f(V t, S s)) =>
+ foldPreOpt<K, V, S>(t, s, f);
+ S s = init;
+ s = f(_value, s);
+ s = _fold(_left, s, f);
+ s = _fold(_right, s, f);
+ return s;
+ }
+}
+
+// Use fresh type variables.
+BinaryTreeNode<K2, V2> insertOpt<K2 extends Comparable<K2>, V2>(
+ BinaryTreeNode<K2, V2> t, K2 key, V2 value) {
+ return (t == null) ? new BinaryTreeNode(key, value) : t.insert(key, value);
+}
+
+// Reuse type variables [K], [V] to test shadowing.
+BinaryTreeNode<K, U> mapOpt<K extends Comparable<K>, V, U>(
+ BinaryTreeNode<K, V> t, U f(V x)) {
+ return (t == null) ? null : t.map<U>(f);
+}
+
+// Use fresh [K2], shadowing [V].
+S foldPreOpt<K2 extends Comparable<K2>, V, S>(
+ BinaryTreeNode<K2, V> t, S init, S f(V t, S s)) {
+ return (t == null) ? init : t.foldPre<S>(init, f);
+}
+
+class BinaryTree<K extends Comparable<K>, V> {
+ final BinaryTreeNode<K, V> _root;
+
+ BinaryTree._internal(this._root);
+ BinaryTree.empty() : this._internal(null);
+
+ BinaryTree<K, V> insert(K key, V value) {
+ BinaryTreeNode<K, V> root = insertOpt<K, V>(_root, key, value);
+ return new BinaryTree<K, V>._internal(root);
+ }
+
+ BinaryTree<K, U> map<U>(U f(V x)) {
+ BinaryTreeNode<K, U> root = mapOpt<K, V, U>(_root, f);
+ return new BinaryTree<K, U>._internal(root);
+ }
+
+ S foldPre<S>(S init, S f(V t, S s)) {
+ return foldPreOpt<K, V, S>(_root, init, f);
+ }
+}
+
+main() {
+ BinaryTree<num, String> sT = new BinaryTree<num, String>.empty();
+
+ sT = sT.insert(0, "");
+ sT = sT.insert(1, " ");
+ sT = sT.insert(2, " ");
+ sT = sT.insert(3, " ");
+
+ BinaryTree<num, num> iT = sT.map<num>((String s) => s.length);
+
+ Expect.equals(iT.foldPre<num>(0, (int i, num s) => i + s), 6);
+}
diff --git a/tests/language/generic_functions_test.options b/tests/language/generic_functions_test.options
new file mode 100644
index 0000000..86e2aac
--- /dev/null
+++ b/tests/language/generic_functions_test.options
@@ -0,0 +1,3 @@
+analyzer:
+ language:
+ enableGenericMethods: true
diff --git a/tests/language/generic_methods_test.dart b/tests/language/generic_methods_test.dart
new file mode 100644
index 0000000..3fd6d24
--- /dev/null
+++ b/tests/language/generic_methods_test.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Dart test verifying that the parser can handle type parameterization of
+// method declarations and method invocations. Slightly adjusted version of
+// code from DEP #22.
+
+class BinaryTreeNode<K extends Comparable<K>, V> {
+ final K _key;
+ final V _value;
+ final BinaryTreeNode<K, V> _left;
+ final BinaryTreeNode<K, V> _right;
+
+ BinaryTreeNode(this._key, this._value,
+ {BinaryTreeNode<K, V> left: null, BinaryTreeNode<K, V> right: null}) :
+ _left = left, _right = right;
+
+ // Use fresh type variables.
+ static BinaryTreeNode<K2, V2> insertOpt<K2 extends Comparable<K2>, V2>(
+ BinaryTreeNode<K2, V2> t, K2 key, V2 value) {
+ return (t == null) ? new BinaryTreeNode(key, value) : t.insert(key, value);
+ }
+
+ BinaryTreeNode<K, V> insert(K key, V value) {
+ int c = key.compareTo(_key);
+ if (c == 0) return this;
+ var _insert = (BinaryTreeNode<K, V> node, K key, V value) =>
+ insertOpt<K, V>(node, key, value);
+ BinaryTreeNode<K, V> left = _left;
+ BinaryTreeNode<K, V> right = _right;
+ if (c < 0) {
+ left = _insert(_left, key, value);
+ } else {
+ right = _insert(_right, key, value);
+ }
+ return new BinaryTreeNode<K, V>(_key, _value, left: left, right: right);
+ }
+
+ // Reuse type variables [K], [V] to test shadowing.
+ static BinaryTreeNode<K, U> mapOpt<K extends Comparable<K>, V, U>
+ (BinaryTreeNode<K, V> t, U f(V x)) {
+ return (t == null) ? null : t.map<U>(f);
+ }
+
+ BinaryTreeNode<K, U> map<U>(U f(V x)){
+ var _map = (BinaryTreeNode<K, V> t, U f(V x)) => mapOpt<K, V, U>(t, f);
+ return new BinaryTreeNode<K, U>(
+ _key,
+ f(_value),
+ left: _map(_left, f),
+ right: _map(_right, f));
+ }
+
+ // Use fresh [K2], shadowing [V].
+ static S foldPreOpt<K2 extends Comparable<K2>, V, S>(
+ BinaryTreeNode<K2, V> t, S init, S f(V t, S s)) {
+ return (t == null) ? init : t.foldPre<S>(init, f);
+ }
+
+ S foldPre<S>(S init, S f(V t, S s)) {
+ var _fold = (BinaryTreeNode<K, V> t, S s, S f(V t, S s)) =>
+ foldPreOpt<K, V, S>(t, s, f);
+ S s = init;
+ s = f(_value, s);
+ s = _fold(_left, s, f);
+ s = _fold(_right, s, f);
+ return s;
+ }
+}
+
+class BinaryTree<K extends Comparable<K>, V> {
+ final BinaryTreeNode<K, V> _root;
+
+ BinaryTree._internal(this._root);
+ BinaryTree.empty() : this._internal(null);
+
+ BinaryTree<K, V> insert(K key, V value) {
+ BinaryTreeNode<K, V> root =
+ BinaryTreeNode.insertOpt<K, V>(_root, key, value);
+ return new BinaryTree<K, V>._internal(root);
+ }
+
+ BinaryTree<K, U> map<U>(U f(V x)) {
+ BinaryTreeNode<K, U> root = BinaryTreeNode.mapOpt<K, V, U>(_root, f);
+ return new BinaryTree<K, U>._internal(root);
+ }
+
+ S foldPre<S>(S init, S f(V t, S s)) {
+ return BinaryTreeNode.foldPreOpt<K, V, S>(_root, init, f);
+ }
+}
+
+main() {
+ BinaryTree<num, String> sT = new BinaryTree<num, String>.empty();
+
+ sT = sT.insert(0, "");
+ sT = sT.insert(1, " ");
+ sT = sT.insert(2, " ");
+ sT = sT.insert(3, " ");
+
+ BinaryTree<num, num> iT = sT.map<num>((String s) => s.length);
+
+ Expect.equals(iT.foldPre<num>(0, (int i, num s) => i + s), 6);
+}
diff --git a/tests/language/generic_methods_test.options b/tests/language/generic_methods_test.options
new file mode 100644
index 0000000..86e2aac
--- /dev/null
+++ b/tests/language/generic_methods_test.options
@@ -0,0 +1,3 @@
+analyzer:
+ language:
+ enableGenericMethods: true
diff --git a/tests/language/generic_sends_test.dart b/tests/language/generic_sends_test.dart
new file mode 100644
index 0000000..2e98215d
--- /dev/null
+++ b/tests/language/generic_sends_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+// Dart test verifying that the parser can handle certain cases where
+// grammar ambiguity is resolved in favor of generic sends, not
+// relational expressions.
+
+f(arg1, [arg2]) => null;
+g<X, Y>(arg) => null;
+
+main() {
+ // Generic invocations.
+ f(g<int, String>(3));
+ f(g<int, List<String>>(3));
+ f(g<int, String>(3), 4);
+ f(g<int, List<String>>(3), 4);
+
+ // Relational expressions.
+ int a = 0, b = 1, c = 2, d = 3;
+ f(a < b, c > 3);
+ f(a < b, c >> 3);
+ f(a < b, c < d >> 3);
+}
diff --git a/tests/language/generic_sends_test.options b/tests/language/generic_sends_test.options
new file mode 100644
index 0000000..86e2aac
--- /dev/null
+++ b/tests/language/generic_sends_test.options
@@ -0,0 +1,3 @@
+analyzer:
+ language:
+ enableGenericMethods: true
diff --git a/tests/language/language.status b/tests/language/language.status
index 673b6b1..ff38b09 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -45,6 +45,11 @@
async_star_cancel_while_paused_test: RuntimeError
async_star_await_pauses_test: Skip # Times out. Issue 23996
+# Experimental feature: Syntactic support for generic methods.
+generic_methods_test: CompiletimeError # Issue 25869
+generic_functions_test: CompiletimeError # Issue 25869
+generic_sends_test: CompiletimeError # Issue 25869
+
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
class_keyword_test/02: MissingCompileTimeError # Issue 13627
@@ -84,6 +89,10 @@
main_test/42: Fail # Issue 20028
mirror_in_static_init_test: Fail # Issue 22071
vm/debug_break_enabled_vm_test/*: Skip # Issue 14651.
+# Experimental feature: Syntactic support for generic methods.
+generic_methods_test: RuntimeError # Issue 25869
+generic_functions_test: RuntimeError # Issue 25869
+generic_sends_test: RuntimeError # Issue 25869
[ $compiler == none && $runtime == dartium && $system == linux && $arch != x64 ]
issue_22780_test/01 : Pass, Timeout # Issue 24473
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index d3dfe4e..71180bb 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -520,3 +520,8 @@
for_in3_test: StaticWarning, OK # Test should have warning by design.
for_in_side_effects_test: StaticWarning, OK # Test uses custom class that does not implement Iterable in for-in.
+
+# Experimental feature: Syntactic support for generic methods.
+generic_functions_test: CompileTimeError # Issue 25868
+generic_methods_test: CompileTimeError # Issue 25868
+generic_sends_test: CompileTimeError # Issue 25868
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 1d68288..b151186 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -36,6 +36,11 @@
accessor_conflict_import_prefixed_test: RuntimeError # Issue 25626
accessor_conflict_import_test: RuntimeError # Issue 25626
+# Experimental feature: Syntactic support for generic methods.
+generic_functions_test: CompileTimeError # Issue 25835
+generic_methods_test: CompileTimeError # Issue 25835
+generic_sends_test: CompileTimeError # Issue 25835
+
[ $compiler == dart2js && $runtime == jsshell ]
await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
async_star_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
diff --git a/tests/language/regress_25935_test.dart b/tests/language/regress_25935_test.dart
new file mode 100644
index 0000000..1e653ad
--- /dev/null
+++ b/tests/language/regress_25935_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ AddIssueSourceMember2 m = new AddIssueSourceMember2();
+}
+
+abstract class RepoListEditorState2<M extends RepoListMember2<M>,
+ S extends RepoListEditorState2<M, S>>
+ extends AbstractListEditorState2<M, S> {}
+
+abstract class AbstractListEditorState2<
+ M extends AbstractListMember2<Object, M>,
+ S extends AbstractListEditorState2<M, S>> extends ComponentState2<S> {}
+
+class AddIssueSourceMember2 extends RepoListMember2<AddIssueSourceMember2> {}
+
+class RepoListMember2<M extends RepoListMember2<M>>
+ extends AbstractListMember2<Object, M> {}
+
+abstract class AbstractListMember2<E, M extends AbstractListMember2<E, M>>
+ extends ComponentState2<M> {}
+
+abstract class ComponentState2<S extends ComponentState2<S>> {}
+
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 87b74f2..6319860 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -336,6 +336,9 @@
async/stream_iterator_test: Crash # (Stream createCancel... cannot handle sync*/async* functions
mirrors/parameter_annotation_mirror_test: Pass, Fail # Issue 25501. Depends on inlining.
+[ $compiler == dart2js && $cps_ir && $checked ]
+*: Skip # Issue 25761
+
[ $compiler == dart2js && $host_checked ]
mirrors/circular_factory_redirection_test/02: Crash # Assertion failure: Constant constructor already computed for generative_constructor(A#circular2). Issue 25911
mirrors/metadata_allowed_values_test/28: Crash # Issue 25911
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 7efc16b..fecad33 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -13,7 +13,7 @@
package/scenarios/empty_packages_file/empty_packages_file_option_test: Fail, OK # CompileTimeErrors intentionally
package/scenarios/invalid/invalid_package_name_test: RuntimeError, CompileTimeError # Errors intentionally
package/scenarios/invalid/same_package_twice_test.dart: RuntimeError, CompileTimeError # Errors intentionally
-full_coverage_test: Pass, Slow
+full_coverage_test: Pass, Slow, Timeout
issue14236_test: Pass # Do not remove this line. It serves as a marker for Issue 14516 comment #4.
@@ -65,6 +65,7 @@
issue14236_test: Skip # Issue 14236 Script snapshots do not work in the browser.
oom_error_stacktrace_test: Skip
out_of_memory_test: Skip
+map_insert_remove_oom_test: Skip # Issue 24571
verbose_gc_to_bmu_test: Skip
precompilation_test: Skip # Standalone only test.
precompilation_dart2js_test: Skip # Standalone only test.
@@ -156,9 +157,6 @@
[ $compiler == none && $runtime == dartium && $unchecked ]
assert_test: Fail # Issue 14651.
-[ $compiler == none && $runtime == drt ]
-map_insert_remove_oom_test: RuntimeError # Issue 24571
-
[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
io/directory_invalid_arguments_test: StaticWarning
io/process_invalid_arguments_test: StaticWarning
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 7037f46..bec008c 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -21,12 +21,6 @@
[ $noopt || $compiler == precompiler || $mode == product ]
source_mirrors_test: SkipByDesign # Imports dart:mirrors
-[ $compiler == dart2analyzer ]
-dart2js_test: StaticWarning # https://github.com/dart-lang/sdk/issues/25943
-recursive_import_test: StaticWarning # https://github.com/dart-lang/sdk/issues/25943
-dummy_compiler_test: StaticWarning # https://github.com/dart-lang/sdk/issues/25943
-source_mirrors_test: StaticWarning # https://github.com/dart-lang/sdk/issues/25943
-
[ $compiler == dart2js && $cps_ir && $host_checked ]
dummy_compiler_test: Crash # Issue 24485
recursive_import_test: Crash # Issue 24485
diff --git a/tools/VERSION b/tools/VERSION
index 597af30..4c33897 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 1
MINOR 16
PATCH 0
-PRERELEASE 0
+PRERELEASE 1
PRERELEASE_PATCH 0
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 0105c11..0af7797 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -8,7 +8,7 @@
# Now we need to override some settings and add some new ones.
vars.update({
- "dartium_chromium_commit": "8df9de5a8f073d9c0feadf8d652408807e4a254e",
+ "dartium_chromium_commit": "18e2b11bf18e8db4dd3e0f77991a1dc6b87ce07b",
"dartium_webkit_commit": "28b9a6c03797eaecf6c92677cba747eb9df0787c",
"chromium_base_revision": "338390",
diff --git a/tools/deps/dartium.deps/DEPS.chromium b/tools/deps/dartium.deps/DEPS.chromium
index 4abb484..d15aff5 100644
--- a/tools/deps/dartium.deps/DEPS.chromium
+++ b/tools/deps/dartium.deps/DEPS.chromium
@@ -1,490 +1,694 @@
-# This file is used to manage the dependencies of the Chromium src repo. It is
-# used by gclient to determine what version of each dependency to check out, and
-# where.
-#
-# For more information, please refer to the official documentation:
-# https://sites.google.com/a/chromium.org/dev/developers/how-tos/get-the-code
-#
-# When adding a new dependency, please update the top-level .gitignore file
-# to list the dependency's destination directory.
-#
-# -----------------------------------------------------------------------------
-# Rolling deps
-# -----------------------------------------------------------------------------
-# All repositories in this file are git-based, using Chromium git mirrors where
-# necessary (e.g., a git mirror is used when the source project is SVN-based).
-# To update the revision that Chromium pulls for a given dependency:
-#
-# # Create and switch to a new branch
-# git new-branch depsroll
-# # Run roll-dep (provided by depot_tools) giving the dep's path and the
-# # desired SVN revision number (e.g., third_party/foo/bar and a revision such
-# # number from Subversion)
-# roll-dep third_party/foo/bar REVISION_NUMBER
-# # You should now have a modified DEPS file; commit and upload as normal
-# git commit -a
-# git cl upload
-
-
vars = {
- # Use this googlecode_url variable only if there is an internal mirror for it.
- # If you do not know, use the full path while defining your new deps entry.
- 'googlecode_url': 'http://%s.googlecode.com/svn',
'webkit_revision': 'abaaf1d0b6b6483140b5dca34e80fc259833ddf7', # from svn revision 198714
- 'chromium_git': 'https://chromium.googlesource.com',
- 'libvpx_revision': '96484d320036bbc1e30f1dea232799a3e0517b1d',
- 'sfntly_revision': '1bdaae8fc788a5ac8936d68bf24f37d977a13dac',
- 'skia_revision': 'ea561bf055bb803f4c10ca323ea60a9d94da7956',
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling V8
- # and whatever else without interference from each other.
- 'v8_revision': '7f211533faba9dd85708b1394186c7fe99b88392',
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling swarming_client
- # and whatever else without interference from each other.
- 'swarming_revision': 'b39a448d8522392389b28f6997126a6ab04bfe87',
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling ANGLE
- # and whatever else without interference from each other.
- 'angle_revision': '44897140a2ae07dc5ba88190100179baa6fe7914',
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling build tools
- # and whatever else without interference from each other.
- 'buildtools_revision': 'ecc8e253abac3b6186a97573871a084f4c0ca3ae',
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling PDFium
- # and whatever else without interference from each other.
- 'pdfium_revision': 'cc2323f0d0d626edac4a426097eb38b53ba54848',
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling openmax_dl
- # and whatever else without interference from each other.
- 'openmax_dl_revision': '22bb1085a6a0f6f3589a8c3d60ed0a9b82248275',
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling BoringSSL
- # and whatever else without interference from each other.
- 'boringssl_revision': 'de24aadc5bc01130b6a9d25582203bb5308fabe1',
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling nss
- # and whatever else without interference from each other.
- 'nss_revision': 'aab0d08a298b29407397fbb1c4219f99e99431ed', # from svn revision 295435
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling google-toolbox-for-mac
- # and whatever else without interference from each other.
- 'google_toolbox_for_mac_revision': 'ce47a231ea0b238fbe95538e86cc61d74c234be6', # from svn revision 705
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling lighttpd
- # and whatever else without interference from each other.
- 'lighttpd_revision': '9dfa55d15937a688a92cbf2b7a8621b0927d06eb',
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling lss
- # and whatever else without interference from each other.
- 'lss_revision': '6f97298fe3794e92c8c896a6bc06e0b36e4c3de3',
- # Three lines of non-changing comments so that
- # the commit queue can handle CLs rolling NaCl
- # and whatever else without interference from each other.
- 'nacl_revision': 'b3d4cc125348924f727d3b87cee3674a839b54a0',
+ 'angle_revision':
+ '44897140a2ae07dc5ba88190100179baa6fe7914',
+ 'boringssl_revision':
+ 'de24aadc5bc01130b6a9d25582203bb5308fabe1',
+ 'buildspec_platforms':
+ 'ios,',
+ 'buildtools_revision':
+ 'ecc8e253abac3b6186a97573871a084f4c0ca3ae',
+ 'chromium_git':
+ 'https://chromium.googlesource.com',
+ 'google_toolbox_for_mac_revision':
+ 'ce47a231ea0b238fbe95538e86cc61d74c234be6',
+ 'googlecode_url':
+ 'http://%s.googlecode.com/svn',
+ 'libvpx_revision':
+ '96484d320036bbc1e30f1dea232799a3e0517b1d',
+ 'lighttpd_revision':
+ '9dfa55d15937a688a92cbf2b7a8621b0927d06eb',
+ 'lss_revision':
+ '6f97298fe3794e92c8c896a6bc06e0b36e4c3de3',
+ 'nacl_revision':
+ 'b3d4cc125348924f727d3b87cee3674a839b54a0',
+ 'nss_revision':
+ 'aab0d08a298b29407397fbb1c4219f99e99431ed',
+ 'openmax_dl_revision':
+ '22bb1085a6a0f6f3589a8c3d60ed0a9b82248275',
+ 'pdfium_revision':
+ 'cc2323f0d0d626edac4a426097eb38b53ba54848',
+ 'sfntly_revision':
+ '1bdaae8fc788a5ac8936d68bf24f37d977a13dac',
+ 'skia_revision':
+ 'ea561bf055bb803f4c10ca323ea60a9d94da7956',
+ 'swarming_revision':
+ 'b39a448d8522392389b28f6997126a6ab04bfe87',
+ 'v8_revision':
+ '7f211533faba9dd85708b1394186c7fe99b88392'
}
-
-# Only these hosts are allowed for dependencies in this DEPS file.
-# If you need to add a new host, contact chrome infrastracture team.
allowed_hosts = [
- 'chromium.googlesource.com',
- 'boringssl.googlesource.com',
- 'pdfium.googlesource.com',
'android.googlesource.com',
+ 'boringssl.googlesource.com',
+ 'chromium.googlesource.com',
+ 'pdfium.googlesource.com'
]
-
deps = {
'src/breakpad/src':
- Var('chromium_git') + '/external/google-breakpad/src.git' + '@' + '242fb9a38db6ba534b1f7daa341dd4d79171658b', # from svn revision 1471
-
+ (Var("chromium_git")) + '/external/google-breakpad/src.git@242fb9a38db6ba534b1f7daa341dd4d79171658b',
'src/buildtools':
- Var('chromium_git') + '/chromium/buildtools.git' + '@' + Var('buildtools_revision'),
-
- 'src/sdch/open-vcdiff':
- Var('chromium_git') + '/external/open-vcdiff.git' + '@' + '438f2a5be6d809bc21611a94cd37bfc8c28ceb33', # from svn revision 41
-
- 'src/testing/gtest':
- Var('chromium_git') + '/external/googletest.git' + '@' + '23574bf2333f834ff665f894c97bef8a5b33a0a9', # from svn revision 711
-
- 'src/testing/gmock':
- Var('chromium_git') + '/external/googlemock.git' + '@' + '29763965ab52f24565299976b936d1265cb6a271', # from svn revision 501
-
- 'src/third_party/angle':
- Var('chromium_git') + '/angle/angle.git' + '@' + Var('angle_revision'),
-
- 'src/third_party/colorama/src':
- Var('chromium_git') + '/external/colorama.git' + '@' + '799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',
-
- 'src/third_party/crashpad/crashpad':
- Var('chromium_git') + '/crashpad/crashpad.git' + '@' + '797adb320680a4a8ad39428075cca287e04b111f',
-
- 'src/third_party/trace-viewer':
- Var('chromium_git') + '/external/trace-viewer.git' + '@' + '4f30209abd53c699c937519f39ce41888f93507b',
-
- 'src/third_party/WebKit':
- Var('chromium_git') + '/chromium/blink.git' + '@' + Var('webkit_revision'),
-
- 'src/third_party/icu':
- Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'c81a1a3989c3b66fa323e9a6ee7418d7c08297af',
-
- 'src/third_party/libexif/sources':
- Var('chromium_git') + '/chromium/deps/libexif/sources.git' + '@' + 'ed98343daabd7b4497f97fda972e132e6877c48a',
-
- 'src/third_party/hunspell_dictionaries':
- Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + 'c106afdcec5d3de2622e19f1b3294c47bbd8bd72',
-
- 'src/third_party/safe_browsing/testing':
- Var('chromium_git') + '/external/google-safe-browsing/testing.git' + '@' + '9d7e8064f3ca2e45891470c9b5b1dce54af6a9d6',
-
- 'src/third_party/leveldatabase/src':
- Var('chromium_git') + '/external/leveldb.git' + '@' + '40c17c0b84ac0b791fb434096fd5c05f3819ad55',
-
- 'src/third_party/snappy/src':
- Var('chromium_git') + '/external/snappy.git' + '@' + '762bb32f0c9d2f31ba4958c7c0933d22e80c20bf',
-
- 'src/tools/grit':
- Var('chromium_git') + '/external/grit-i18n.git' + '@' + '1dac9ae64b0224beb1547810933a6f9998d0d55e', # from svn revision 191
-
- 'src/tools/gyp':
- Var('chromium_git') + '/external/gyp.git' + '@' + '5122240c5e5c4d8da12c543d82b03d6089eb77c5',
-
- 'src/tools/swarming_client':
- Var('chromium_git') + '/external/swarming.client.git' + '@' + Var('swarming_revision'),
-
- 'src/v8':
- Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'),
-
- 'src/native_client':
- Var('chromium_git') + '/native_client/src/native_client.git' + '@' + Var('nacl_revision'),
-
- 'src/third_party/sfntly/cpp/src':
- Var('chromium_git') + '/external/sfntly/cpp/src.git' + '@' + Var('sfntly_revision'),
-
- 'src/third_party/skia':
- Var('chromium_git') + '/skia.git' + '@' + Var('skia_revision'),
-
- 'src/tools/page_cycler/acid3':
- Var('chromium_git') + '/chromium/deps/acid3.git' + '@' + '6be0a66a1ebd7ebc5abc1b2f405a945f6d871521',
-
+ (Var("chromium_git")) + '/chromium/buildtools.git@ecc8e253abac3b6186a97573871a084f4c0ca3ae',
'src/chrome/test/data/perf/canvas_bench':
- Var('chromium_git') + '/chromium/canvas_bench.git' + '@' + 'a7b40ea5ae0239517d78845a5fc9b12976bfc732',
-
+ (Var("chromium_git")) + '/chromium/canvas_bench.git@a7b40ea5ae0239517d78845a5fc9b12976bfc732',
'src/chrome/test/data/perf/frame_rate/content':
- Var('chromium_git') + '/chromium/frame_rate/content.git' + '@' + 'c10272c88463efeef6bb19c9ec07c42bc8fe22b9',
-
- 'src/third_party/bidichecker':
- Var('chromium_git') + '/external/bidichecker/lib.git' + '@' + '97f2aa645b74c28c57eca56992235c79850fa9e0',
-
- 'src/third_party/webgl/src':
- Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '8986f8bfa84547b1a30a9256ebdd665024d68d71',
-
- 'src/third_party/webdriver/pylib':
- Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd',
-
- 'src/third_party/libvpx':
- Var('chromium_git') + '/chromium/deps/libvpx.git' + '@' + Var('libvpx_revision'),
-
- 'src/third_party/ffmpeg':
- Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'f76066ad9f4aea07a53890b54d24cc22830b9efd',
-
- 'src/third_party/libjingle/source/talk':
- Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + 'f7c923ddc729dc7f002b0e194ab72b661f932c00', # commit position 9564
-
- 'src/third_party/usrsctp/usrsctplib':
- Var('chromium_git') + '/external/usrsctplib.git' + '@' + '36444a999739e9e408f8f587cb4c3ffeef2e50ac', # from svn revision 9215
-
- 'src/third_party/libsrtp':
- Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + '9c53f858cddd4d890e405e91ff3af0b48dfd90e6', # from svn revision 295151
-
- 'src/third_party/yasm/source/patched-yasm':
- Var('chromium_git') + '/chromium/deps/yasm/patched-yasm.git' + '@' + '4671120cd8558ce62ee8672ebf3eb6f5216f909b',
-
- 'src/third_party/libjpeg_turbo':
- Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + 'f4631b6ee8b1dbb05e51ae335a7886f9ac598ab6',
-
- 'src/third_party/flac':
- Var('chromium_git') + '/chromium/deps/flac.git' + '@' + 'c291ce676d2c855f7b2739f00f5c7f7e813813dc',
-
- 'src/third_party/pyftpdlib/src':
- Var('chromium_git') + '/external/pyftpdlib.git' + '@' + '2be6d65e31c7ee6320d059f581f05ae8d89d7e45',
-
- 'src/third_party/scons-2.0.1':
- Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
-
- 'src/third_party/webrtc':
- Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '847b12a225694e10425c8a9b31e0eec028baf841', # commit position 9565
-
- 'src/third_party/openmax_dl':
- Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
-
- 'src/third_party/jsoncpp/source':
- Var('chromium_git') + '/external/github.com/open-source-parsers/jsoncpp.git' + '@' + 'f572e8e42e22cfcf5ab0aea26574f408943edfa4', # from svn 248
-
- 'src/third_party/libyuv':
- Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '0e83b64e8879e9469919dc96b5d970c7c5bd05af', # from version 1444
-
- 'src/third_party/smhasher/src':
- Var('chromium_git') + '/external/smhasher.git' + '@' + 'e87738e57558e0ec472b2fc3a643b838e5b6e88f',
-
- 'src/third_party/libaddressinput/src':
- Var('chromium_git') + '/external/libaddressinput.git' + '@' + '5eeeb797e79fa01503fcdcbebdc50036fac023ef',
-
- # These are all at libphonenumber r728.
- 'src/third_party/libphonenumber/src/phonenumbers':
- Var('chromium_git') + '/external/libphonenumber/cpp/src/phonenumbers.git' + '@' + '0d6e3e50e17c94262ad1ca3b7d52b11223084bca',
- 'src/third_party/libphonenumber/src/test':
- Var('chromium_git') + '/external/libphonenumber/cpp/test.git' + '@' + 'f351a7e007f9c9995494499120bbc361ca808a16',
- 'src/third_party/libphonenumber/src/resources':
- Var('chromium_git') + '/external/libphonenumber/resources.git' + '@' + 'b6dfdc7952571ff7ee72643cd88c988cbe966396',
-
- 'src/tools/deps2git':
- Var('chromium_git') + '/chromium/tools/deps2git.git' + '@' + 'f04828eb0b5acd3e7ad983c024870f17f17b06d9',
-
- 'src/third_party/webpagereplay':
- Var('chromium_git') + '/external/github.com/chromium/web-page-replay.git' + '@' + '5da5975950daa7b30a6938da73fd0b3200901b0c',
-
- 'src/third_party/pywebsocket/src':
- Var('chromium_git') + '/external/pywebsocket/src.git' + '@' + 'cb349e87ddb30ff8d1fa1a89be39cec901f4a29c',
-
- 'src/third_party/opus/src':
- Var('chromium_git') + '/chromium/deps/opus.git' + '@' + 'cae696156f1e60006e39821e79a1811ae1933c69',
-
+ (Var("chromium_git")) + '/chromium/frame_rate/content.git@c10272c88463efeef6bb19c9ec07c42bc8fe22b9',
'src/media/cdm/ppapi/api':
- Var('chromium_git') + '/chromium/cdm.git' + '@' + '7377023e384f296cbb27644eb2c485275f1f92e8', # from svn revision 294518
-
- 'src/third_party/mesa/src':
- Var('chromium_git') + '/chromium/deps/mesa.git' + '@' + '071d25db04c23821a12a8b260ab9d96a097402f0',
-
- 'src/third_party/cld_2/src':
- Var('chromium_git') + '/external/cld2.git' + '@' + '14d9ef8d4766326f8aa7de54402d1b9c782d4481', # from svn revision 193
-
- 'src/third_party/pdfium':
- 'https://pdfium.googlesource.com/pdfium.git' + '@' + Var('pdfium_revision'),
-
+ (Var("chromium_git")) + '/chromium/cdm.git@7377023e384f296cbb27644eb2c485275f1f92e8',
+ 'src/native_client':
+ (Var("chromium_git")) + '/native_client/src/native_client.git@b3d4cc125348924f727d3b87cee3674a839b54a0',
+ 'src/sdch/open-vcdiff':
+ (Var("chromium_git")) + '/external/open-vcdiff.git@438f2a5be6d809bc21611a94cd37bfc8c28ceb33',
+ 'src/testing/gmock':
+ (Var("chromium_git")) + '/external/googlemock.git@29763965ab52f24565299976b936d1265cb6a271',
+ 'src/testing/gtest':
+ (Var("chromium_git")) + '/external/googletest.git@23574bf2333f834ff665f894c97bef8a5b33a0a9',
+ 'src/third_party/angle':
+ (Var("chromium_git")) + '/angle/angle.git@6f0fd8c5457f9dcffc9fa9fab3852417311be0a9',
+ 'src/third_party/bidichecker':
+ (Var("chromium_git")) + '/external/bidichecker/lib.git@97f2aa645b74c28c57eca56992235c79850fa9e0',
'src/third_party/boringssl/src':
- 'https://boringssl.googlesource.com/boringssl.git' + '@' + Var('boringssl_revision'),
-
- 'src/third_party/py_trace_event/src':
- Var('chromium_git') + '/external/py_trace_event.git' + '@' + 'dd463ea9e2c430de2b9e53dea57a77b4c3ac9b30',
-
+ 'https://boringssl.googlesource.com/boringssl.git@de24aadc5bc01130b6a9d25582203bb5308fabe1',
+ 'src/third_party/cld_2/src':
+ (Var("chromium_git")) + '/external/cld2.git@14d9ef8d4766326f8aa7de54402d1b9c782d4481',
+ 'src/third_party/colorama/src':
+ (Var("chromium_git")) + '/external/colorama.git@799604a1041e9b3bc5d2789ecbd7e8db2e18e6b8',
+ 'src/third_party/crashpad/crashpad':
+ (Var("chromium_git")) + '/crashpad/crashpad.git@797adb320680a4a8ad39428075cca287e04b111f',
'src/third_party/dom_distiller_js/dist':
- Var('chromium_git') + '/external/github.com/chromium/dom-distiller-dist.git' + '@' + '81e5b59da2a7a0a518b90b5ded58670322c98128',
+ (Var("chromium_git")) + '/external/github.com/chromium/dom-distiller-dist.git@81e5b59da2a7a0a518b90b5ded58670322c98128',
+ 'src/third_party/ffmpeg':
+ (Var("chromium_git")) + '/chromium/third_party/ffmpeg.git@833732528c1873f37b490b289eeaded2ae86349c',
+ 'src/third_party/flac':
+ (Var("chromium_git")) + '/chromium/deps/flac.git@c291ce676d2c855f7b2739f00f5c7f7e813813dc',
+ 'src/third_party/hunspell_dictionaries':
+ (Var("chromium_git")) + '/chromium/deps/hunspell_dictionaries.git@c106afdcec5d3de2622e19f1b3294c47bbd8bd72',
+ 'src/third_party/icu':
+ (Var("chromium_git")) + '/chromium/deps/icu.git@257f502ab8b2a6371efcd6d4606202e7f5be17d8',
+ 'src/third_party/jsoncpp/source':
+ (Var("chromium_git")) + '/external/github.com/open-source-parsers/jsoncpp.git@f572e8e42e22cfcf5ab0aea26574f408943edfa4',
+ 'src/third_party/leveldatabase/src':
+ (Var("chromium_git")) + '/external/leveldb.git@40c17c0b84ac0b791fb434096fd5c05f3819ad55',
+ 'src/third_party/libaddressinput/src':
+ (Var("chromium_git")) + '/external/libaddressinput.git@5eeeb797e79fa01503fcdcbebdc50036fac023ef',
+ 'src/third_party/libexif/sources':
+ (Var("chromium_git")) + '/chromium/deps/libexif/sources.git@ed98343daabd7b4497f97fda972e132e6877c48a',
+# TODO(terry): Commented out 45 roll and reverted to use old SHA1 for this from roll 39
+# 'src/third_party/libjingle/source/talk':
+# (Var("chromium_git")) + '/external/webrtc/trunk/talk.git@e0fa7aec7298a0c82081b14e17191f80f9f0e044',
+ 'src/third_party/libjingle/source/talk':
+ (Var('chromium_git')) + '/external/webrtc/trunk/talk.git' + '@' + 'f7c923ddc729dc7f002b0e194ab72b661f932c00', # commit position 9564
+ 'src/third_party/libjpeg_turbo':
+ (Var("chromium_git")) + '/chromium/deps/libjpeg_turbo.git@f4631b6ee8b1dbb05e51ae335a7886f9ac598ab6',
+ 'src/third_party/libphonenumber/src/phonenumbers':
+ (Var("chromium_git")) + '/external/libphonenumber/cpp/src/phonenumbers.git@0d6e3e50e17c94262ad1ca3b7d52b11223084bca',
+ 'src/third_party/libphonenumber/src/resources':
+ (Var("chromium_git")) + '/external/libphonenumber/resources.git@b6dfdc7952571ff7ee72643cd88c988cbe966396',
+ 'src/third_party/libphonenumber/src/test':
+ (Var("chromium_git")) + '/external/libphonenumber/cpp/test.git@f351a7e007f9c9995494499120bbc361ca808a16',
+ 'src/third_party/libsrtp':
+ (Var("chromium_git")) + '/chromium/deps/libsrtp.git@9c53f858cddd4d890e405e91ff3af0b48dfd90e6',
+ 'src/third_party/libvpx':
+ (Var("chromium_git")) + '/chromium/deps/libvpx.git@96484d320036bbc1e30f1dea232799a3e0517b1d',
+ 'src/third_party/libyuv':
+ (Var("chromium_git")) + '/libyuv/libyuv.git@0e83b64e8879e9469919dc96b5d970c7c5bd05af',
+ 'src/third_party/mesa/src':
+ (Var("chromium_git")) + '/chromium/deps/mesa.git@071d25db04c23821a12a8b260ab9d96a097402f0',
+ 'src/third_party/openmax_dl':
+ (Var("chromium_git")) + '/external/webrtc/deps/third_party/openmax.git@22bb1085a6a0f6f3589a8c3d60ed0a9b82248275',
+ 'src/third_party/opus/src':
+ (Var("chromium_git")) + '/chromium/deps/opus.git@cae696156f1e60006e39821e79a1811ae1933c69',
+ 'src/third_party/pdfium':
+ 'https://pdfium.googlesource.com/pdfium.git@860a3eb0f3c18853f95df5a70dc50a95a29aafb1',
+ 'src/third_party/py_trace_event/src':
+ (Var("chromium_git")) + '/external/py_trace_event.git@dd463ea9e2c430de2b9e53dea57a77b4c3ac9b30',
+ 'src/third_party/pyftpdlib/src':
+ (Var("chromium_git")) + '/external/pyftpdlib.git@2be6d65e31c7ee6320d059f581f05ae8d89d7e45',
+ 'src/third_party/pywebsocket/src':
+ (Var("chromium_git")) + '/external/pywebsocket/src.git@cb349e87ddb30ff8d1fa1a89be39cec901f4a29c',
+ 'src/third_party/safe_browsing/testing':
+ (Var("chromium_git")) + '/external/google-safe-browsing/testing.git@9d7e8064f3ca2e45891470c9b5b1dce54af6a9d6',
+ 'src/third_party/scons-2.0.1':
+ (Var("chromium_git")) + '/native_client/src/third_party/scons-2.0.1.git@1c1550e17fc26355d08627fbdec13d8291227067',
+ 'src/third_party/sfntly/cpp/src':
+ (Var("chromium_git")) + '/external/sfntly/cpp/src.git@1bdaae8fc788a5ac8936d68bf24f37d977a13dac',
+ 'src/third_party/skia':
+ (Var("chromium_git")) + '/skia.git@56032c4f7bab7b0dd31b4d1eb139561d73fcd12d',
+ 'src/third_party/smhasher/src':
+ (Var("chromium_git")) + '/external/smhasher.git@e87738e57558e0ec472b2fc3a643b838e5b6e88f',
+ 'src/third_party/snappy/src':
+ (Var("chromium_git")) + '/external/snappy.git@762bb32f0c9d2f31ba4958c7c0933d22e80c20bf',
+ 'src/third_party/trace-viewer':
+ (Var("chromium_git")) + '/external/trace-viewer.git@4f30209abd53c699c937519f39ce41888f93507b',
+ 'src/third_party/usrsctp/usrsctplib':
+ (Var("chromium_git")) + '/external/usrsctplib.git@36444a999739e9e408f8f587cb4c3ffeef2e50ac',
+ 'src/third_party/webdriver/pylib':
+ (Var("chromium_git")) + '/external/selenium/py.git@5fd78261a75fe08d27ca4835fb6c5ce4b42275bd',
+ 'src/third_party/webgl/src':
+ (Var("chromium_git")) + '/external/khronosgroup/webgl.git@8986f8bfa84547b1a30a9256ebdd665024d68d71',
+ 'src/third_party/webpagereplay':
+ (Var("chromium_git")) + '/external/github.com/chromium/web-page-replay.git@5da5975950daa7b30a6938da73fd0b3200901b0c',
+# TODO(terry): Commented out 45 roll and reverted to use old SHA1 for this from roll 39
+# 'src/third_party/webrtc':
+# (Var("chromium_git")) + '/external/webrtc/trunk/webrtc.git@7c166694b3c8f614eeb47148f4ab68545c78786e',
+ 'src/third_party/webrtc':
+ (Var('chromium_git')) + '/external/webrtc/trunk/webrtc.git' + '@' + '847b12a225694e10425c8a9b31e0eec028baf841', # commit position 9565
+ 'src/third_party/yasm/source/patched-yasm':
+ (Var("chromium_git")) + '/chromium/deps/yasm/patched-yasm.git@4671120cd8558ce62ee8672ebf3eb6f5216f909b',
+ 'src/tools/deps2git':
+ (Var("chromium_git")) + '/chromium/tools/deps2git.git@f04828eb0b5acd3e7ad983c024870f17f17b06d9',
+ 'src/tools/grit':
+ (Var("chromium_git")) + '/external/grit-i18n.git@1dac9ae64b0224beb1547810933a6f9998d0d55e',
+ 'src/tools/gyp':
+ (Var("chromium_git")) + '/external/gyp.git@5122240c5e5c4d8da12c543d82b03d6089eb77c5',
+ 'src/tools/page_cycler/acid3':
+ (Var("chromium_git")) + '/chromium/deps/acid3.git@6be0a66a1ebd7ebc5abc1b2f405a945f6d871521',
+ 'src/tools/swarming_client':
+ (Var("chromium_git")) + '/external/swarming.client.git@b39a448d8522392389b28f6997126a6ab04bfe87',
+ 'src/v8':
+ (Var("chromium_git")) + '/v8/v8.git@96dddb455daff3d8626bc4e5d7b2898fbab55991'
}
-
-
deps_os = {
- 'win': {
- 'src/chrome/tools/test/reference_build/chrome_win':
- Var('chromium_git') + '/chromium/reference_builds/chrome_win.git' + '@' + 'f8a3a845dfc845df6b14280f04f86a61959357ef',
-
- 'src/third_party/cygwin':
- Var('chromium_git') + '/chromium/deps/cygwin.git' + '@' + 'c89e446b273697fadf3a10ff1007a97c0b7de6df',
-
- 'src/third_party/psyco_win32':
- Var('chromium_git') + '/chromium/deps/psyco_win32.git' + '@' + 'f5af9f6910ee5a8075bbaeed0591469f1661d868',
-
- 'src/third_party/bison':
- Var('chromium_git') + '/chromium/deps/bison.git' + '@' + '083c9a45e4affdd5464ee2b224c2df649c6e26c3',
-
- 'src/third_party/gperf':
- Var('chromium_git') + '/chromium/deps/gperf.git' + '@' + 'd892d79f64f9449770443fb06da49b5a1e5d33c1',
-
- 'src/third_party/perl':
- Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
-
- 'src/third_party/lighttpd':
- Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'),
-
- # Parses Windows PE/COFF executable format.
- 'src/third_party/pefile':
- Var('chromium_git') + '/external/pefile.git' + '@' + '72c6ae42396cb913bcab63c15585dc3b5c3f92f1',
-
- # NSS, for SSLClientSocketNSS.
- 'src/third_party/nss':
- Var('chromium_git') + '/chromium/deps/nss.git' + '@' + Var('nss_revision'),
-
- # GNU binutils assembler for x86-32.
- 'src/third_party/gnu_binutils':
- Var('chromium_git') + '/native_client/deps/third_party/gnu_binutils.git' + '@' + 'f4003433b61b25666565690caf3d7a7a1a4ec436',
- # GNU binutils assembler for x86-64.
- 'src/third_party/mingw-w64/mingw/bin':
- Var('chromium_git') + '/native_client/deps/third_party/mingw-w64/mingw/bin.git' + '@' + '3cc8b140b883a9fe4986d12cfd46c16a093d3527',
-
- # Dependencies used by libjpeg-turbo
- 'src/third_party/yasm/binaries':
- Var('chromium_git') + '/chromium/deps/yasm/binaries.git' + '@' + '52f9b3f4b0aa06da24ef8b123058bb61ee468881',
-
- # Binaries for nacl sdk.
- 'src/third_party/nacl_sdk_binaries':
- Var('chromium_git') + '/chromium/deps/nacl_sdk_binaries.git' + '@' + '759dfca03bdc774da7ecbf974f6e2b84f43699a5',
-
- # ANGLE uses dEQP for GPU testing
- 'src/third_party/deqp/src':
- 'https://android.googlesource.com/platform/external/deqp@194294e69d44eac48bc1fb063bd607189650aa5e',
- },
- 'ios': {
- 'src/ios/third_party/gcdwebserver/src':
- Var('chromium_git') + '/external/github.com/swisspol/GCDWebServer.git' + '@' + '3d5fd0b8281a7224c057deb2d17709b5bea64836',
-
- 'src/third_party/google_toolbox_for_mac/src':
- Var('chromium_git') + '/external/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'),
-
- 'src/third_party/nss':
- Var('chromium_git') + '/chromium/deps/nss.git' + '@' + Var('nss_revision'),
-
- # class-dump utility to generate header files for undocumented SDKs
- 'src/third_party/class-dump/src':
- Var('chromium_git') + '/external/github.com/nygard/class-dump.git' + '@' + '93e7c6a5419380d89656dcc511dc60d475199b67',
-
- # Code that's not needed due to not building everything
- 'src/chrome/test/data/perf/canvas_bench': None,
- 'src/chrome/test/data/perf/frame_rate/content': None,
- 'src/native_client': None,
- 'src/third_party/ffmpeg': None,
- 'src/third_party/hunspell_dictionaries': None,
- 'src/third_party/webgl': None,
- },
- 'mac': {
- 'src/chrome/tools/test/reference_build/chrome_mac':
- Var('chromium_git') + '/chromium/reference_builds/chrome_mac.git' + '@' + '8dc181329e7c5255f83b4b85dc2f71498a237955',
-
- 'src/third_party/google_toolbox_for_mac/src':
- Var('chromium_git') + '/external/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'),
-
-
- 'src/third_party/pdfsqueeze':
- Var('chromium_git') + '/external/pdfsqueeze.git' + '@' + '5936b871e6a087b7e50d4cbcb122378d8a07499f',
-
- 'src/third_party/lighttpd':
- Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'),
-
- # NSS, for SSLClientSocketNSS.
- 'src/third_party/nss':
- Var('chromium_git') + '/chromium/deps/nss.git' + '@' + Var('nss_revision'),
-
- 'src/chrome/installer/mac/third_party/xz/xz':
- Var('chromium_git') + '/chromium/deps/xz.git' + '@' + 'eecaf55632ca72e90eb2641376bce7cdbc7284f7',
- },
- 'unix': {
- # Linux, really.
- 'src/chrome/tools/test/reference_build/chrome_linux':
- Var('chromium_git') + '/chromium/reference_builds/chrome_linux64.git' + '@' + '033d053a528e820e1de3e2db766678d862a86b36',
-
- 'src/third_party/xdg-utils':
- Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
-
- 'src/third_party/lss':
- Var('chromium_git') + '/external/linux-syscall-support/lss.git' + '@' + Var('lss_revision'),
-
- # For Linux and Chromium OS.
- 'src/third_party/cros_system_api':
- Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '513f58ccbcecfd4a3d21545f67136090838eaf52',
-
- # Note that this is different from Android's freetype repo.
- 'src/third_party/freetype2/src':
- Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + '1dd5f5f4a909866f15c92a45c9702bce290a0151',
-
- # Build tools for Chrome OS.
- 'src/third_party/chromite':
- Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'e19f83ba227bf1ec0077f5d3a816a415f1dd88d0',
-
- # Dependency of chromite.git.
- 'src/third_party/pyelftools':
- Var('chromium_git') + '/chromiumos/third_party/pyelftools.git' + '@' + 'bdc1d380acd88d4bfaf47265008091483b0d614e',
-
- 'src/third_party/liblouis/src':
- Var('chromium_git') + '/external/liblouis-github.git' + '@' + '5f9c03f2a3478561deb6ae4798175094be8a26c2',
-
- # Used for embedded builds. CrOS & Linux use the system version.
- 'src/third_party/fontconfig/src':
- Var('chromium_git') + '/external/fontconfig.git' + '@' + 'f16c3118e25546c1b749f9823c51827a60aeb5c1',
-
- 'src/third_party/stp/src':
- Var('chromium_git') + '/external/github.com/stp/stp.git' + '@' + 'fc94a599207752ab4d64048204f0c88494811b62',
- },
'android': {
'src/third_party/android_protobuf/src':
- Var('chromium_git') + '/external/android_protobuf.git' + '@' + '999188d0dc72e97f7fe08bb756958a2cf090f4e7',
-
+ (Var("chromium_git")) + '/external/android_protobuf.git@999188d0dc72e97f7fe08bb756958a2cf090f4e7',
'src/third_party/android_tools':
- Var('chromium_git') + '/android_tools.git' + '@' + '21f4bcbd6cd927e4b4227cfde7d5f13486be1236',
-
+ (Var("chromium_git")) + '/android_tools.git@4238a28593b7e6178c95431f91ca8c24e45fa7eb',
'src/third_party/apache-mime4j':
- Var('chromium_git') + '/chromium/deps/apache-mime4j.git' + '@' + '28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a',
-
+ (Var("chromium_git")) + '/chromium/deps/apache-mime4j.git@28cb1108bff4b6cf0a2e86ff58b3d025934ebe3a',
'src/third_party/appurify-python/src':
- Var('chromium_git') + '/external/github.com/appurify/appurify-python.git' + '@' + 'ee7abd5c5ae3106f72b2a0b9d2cb55094688e867',
-
+ (Var("chromium_git")) + '/external/github.com/appurify/appurify-python.git@ee7abd5c5ae3106f72b2a0b9d2cb55094688e867',
'src/third_party/cardboard-java/src':
- Var('chromium_git') + '/external/github.com/googlesamples/cardboard-java.git' + '@' + '08ad25a04f2801bd822c3f2cd28301b68d74aef6',
-
- 'src/third_party/errorprone/lib':
- Var('chromium_git') + '/chromium/third_party/errorprone.git' + '@' + '6c66e56c0f9d750aef83190466df834f9d6af8ab',
-
- 'src/third_party/findbugs':
- Var('chromium_git') + '/chromium/deps/findbugs.git' + '@' + '7f69fa78a6db6dc31866d09572a0e356e921bf12',
-
- 'src/third_party/freetype-android/src':
- Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + 'e186230678ee8e4ea4ac4797ece8125761e3225a',
-
- 'src/third_party/elfutils/src':
- Var('chromium_git') + '/external/elfutils.git' + '@' + '249673729a7e5dbd5de4f3760bdcaa3d23d154d7',
-
- 'src/third_party/httpcomponents-client':
- Var('chromium_git') + '/chromium/deps/httpcomponents-client.git' + '@' + '285c4dafc5de0e853fa845dce5773e223219601c',
-
- 'src/third_party/httpcomponents-core':
- Var('chromium_git') + '/chromium/deps/httpcomponents-core.git' + '@' + '9f7180a96f8fa5cab23f793c14b413356d419e62',
-
- 'src/third_party/jarjar':
- Var('chromium_git') + '/chromium/deps/jarjar.git' + '@' + '2e1ead4c68c450e0b77fe49e3f9137842b8b6920',
-
- 'src/third_party/jsr-305/src':
- Var('chromium_git') + '/external/jsr-305.git' + '@' + '642c508235471f7220af6d5df2d3210e3bfc0919',
-
- 'src/third_party/junit/src':
- Var('chromium_git') + '/external/junit.git' + '@' + '45a44647e7306262162e1346b750c3209019f2e1',
-
- 'src/third_party/mockito/src':
- Var('chromium_git') + '/external/mockito/mockito.git' + '@' + 'ed99a52e94a84bd7c467f2443b475a22fcc6ba8e',
-
- 'src/third_party/robolectric/lib':
- Var('chromium_git') + '/chromium/third_party/robolectric.git' + '@' + '6b63c99a8b6967acdb42cbed0adb067c80efc810',
-
- 'src/third_party/ub-uiautomator/lib':
- Var('chromium_git') + '/chromium/third_party/ub-uiautomator.git' + '@' + 'e6f02481bada8bdbdfdd7987dd6e648c44a3adcb',
-
- 'src/third_party/lss':
- Var('chromium_git') + '/external/linux-syscall-support/lss.git' + '@' + Var('lss_revision'),
-
- 'src/third_party/requests/src':
- Var('chromium_git') + '/external/github.com/kennethreitz/requests.git' + '@' + 'f172b30356d821d180fa4ecfa3e71c7274a32de4',
-
+ (Var("chromium_git")) + '/external/github.com/googlesamples/cardboard-java.git@08ad25a04f2801bd822c3f2cd28301b68d74aef6',
'src/third_party/custom_tabs_client/src':
- Var('chromium_git') + '/external/github.com/GoogleChrome/custom-tabs-client.git' + '@' + 'ef3ea193af9f4e45dd5094e8b6a952fb213bf11e',
+ (Var("chromium_git")) + '/external/github.com/GoogleChrome/custom-tabs-client.git@a562624975518bd6c6c5976eb883fcc5f69d16b6',
+ 'src/third_party/elfutils/src':
+ (Var("chromium_git")) + '/external/elfutils.git@249673729a7e5dbd5de4f3760bdcaa3d23d154d7',
+ 'src/third_party/errorprone/lib':
+ (Var("chromium_git")) + '/chromium/third_party/errorprone.git@6c66e56c0f9d750aef83190466df834f9d6af8ab',
+ 'src/third_party/findbugs':
+ (Var("chromium_git")) + '/chromium/deps/findbugs.git@7f69fa78a6db6dc31866d09572a0e356e921bf12',
+ 'src/third_party/freetype-android/src':
+ (Var("chromium_git")) + '/chromium/src/third_party/freetype2.git@e186230678ee8e4ea4ac4797ece8125761e3225a',
+ 'src/third_party/httpcomponents-client':
+ (Var("chromium_git")) + '/chromium/deps/httpcomponents-client.git@285c4dafc5de0e853fa845dce5773e223219601c',
+ 'src/third_party/httpcomponents-core':
+ (Var("chromium_git")) + '/chromium/deps/httpcomponents-core.git@9f7180a96f8fa5cab23f793c14b413356d419e62',
+ 'src/third_party/jarjar':
+ (Var("chromium_git")) + '/chromium/deps/jarjar.git@2e1ead4c68c450e0b77fe49e3f9137842b8b6920',
+ 'src/third_party/jsr-305/src':
+ (Var("chromium_git")) + '/external/jsr-305.git@642c508235471f7220af6d5df2d3210e3bfc0919',
+ 'src/third_party/junit/src':
+ (Var("chromium_git")) + '/external/junit.git@45a44647e7306262162e1346b750c3209019f2e1',
+ 'src/third_party/lss':
+ (Var("chromium_git")) + '/external/linux-syscall-support/lss.git@6f97298fe3794e92c8c896a6bc06e0b36e4c3de3',
+ 'src/third_party/mockito/src':
+ (Var("chromium_git")) + '/external/mockito/mockito.git@ed99a52e94a84bd7c467f2443b475a22fcc6ba8e',
+ 'src/third_party/requests/src':
+ (Var("chromium_git")) + '/external/github.com/kennethreitz/requests.git@f172b30356d821d180fa4ecfa3e71c7274a32de4',
+ 'src/third_party/robolectric/lib':
+ (Var("chromium_git")) + '/chromium/third_party/robolectric.git@6b63c99a8b6967acdb42cbed0adb067c80efc810',
+ 'src/third_party/ub-uiautomator/lib':
+ (Var("chromium_git")) + '/chromium/third_party/ub-uiautomator.git@e6f02481bada8bdbdfdd7987dd6e648c44a3adcb'
},
+ 'ios': {
+ 'src/chrome/test/data/perf/canvas_bench': None,
+ 'src/chrome/test/data/perf/frame_rate/content': None,
+ 'src/ios/third_party/gcdwebserver/src':
+ (Var("chromium_git")) + '/external/github.com/swisspol/GCDWebServer.git@3d5fd0b8281a7224c057deb2d17709b5bea64836',
+ 'src/native_client': None,
+ 'src/third_party/class-dump/src':
+ (Var("chromium_git")) + '/external/github.com/nygard/class-dump.git@978d177ca6f0d2e5e34acf3e8dadc63e3140ebbc',
+ 'src/third_party/ffmpeg': None,
+ 'src/third_party/google_toolbox_for_mac/src':
+ (Var("chromium_git")) + '/external/google-toolbox-for-mac.git@ce47a231ea0b238fbe95538e86cc61d74c234be6',
+ 'src/third_party/hunspell_dictionaries': None,
+ 'src/third_party/nss':
+ (Var("chromium_git")) + '/chromium/deps/nss.git@aab0d08a298b29407397fbb1c4219f99e99431ed',
+ 'src/third_party/webgl': None
+ },
+ 'mac': {
+ 'src/chrome/installer/mac/third_party/xz/xz':
+ (Var("chromium_git")) + '/chromium/deps/xz.git@eecaf55632ca72e90eb2641376bce7cdbc7284f7',
+ 'src/chrome/tools/test/reference_build/chrome_mac':
+ (Var("chromium_git")) + '/chromium/reference_builds/chrome_mac.git@8dc181329e7c5255f83b4b85dc2f71498a237955',
+ 'src/third_party/google_toolbox_for_mac/src':
+ (Var("chromium_git")) + '/external/google-toolbox-for-mac.git@ce47a231ea0b238fbe95538e86cc61d74c234be6',
+ 'src/third_party/lighttpd':
+ (Var("chromium_git")) + '/chromium/deps/lighttpd.git@9dfa55d15937a688a92cbf2b7a8621b0927d06eb',
+ 'src/third_party/nss':
+ (Var("chromium_git")) + '/chromium/deps/nss.git@aab0d08a298b29407397fbb1c4219f99e99431ed',
+ 'src/third_party/pdfsqueeze':
+ (Var("chromium_git")) + '/external/pdfsqueeze.git@5936b871e6a087b7e50d4cbcb122378d8a07499f'
+ },
+ 'unix': {
+ 'src/chrome/tools/test/reference_build/chrome_linux':
+ (Var("chromium_git")) + '/chromium/reference_builds/chrome_linux64.git@033d053a528e820e1de3e2db766678d862a86b36',
+ 'src/third_party/chromite':
+ (Var("chromium_git")) + '/chromiumos/chromite.git@e19f83ba227bf1ec0077f5d3a816a415f1dd88d0',
+ 'src/third_party/cros_system_api':
+ (Var("chromium_git")) + '/chromiumos/platform/system_api.git@513f58ccbcecfd4a3d21545f67136090838eaf52',
+ 'src/third_party/fontconfig/src':
+ (Var("chromium_git")) + '/external/fontconfig.git@f16c3118e25546c1b749f9823c51827a60aeb5c1',
+ 'src/third_party/freetype2/src':
+ (Var("chromium_git")) + '/chromium/src/third_party/freetype2.git@1dd5f5f4a909866f15c92a45c9702bce290a0151',
+ 'src/third_party/liblouis/src':
+ (Var("chromium_git")) + '/external/liblouis-github.git@5f9c03f2a3478561deb6ae4798175094be8a26c2',
+ 'src/third_party/lss':
+ (Var("chromium_git")) + '/external/linux-syscall-support/lss.git@6f97298fe3794e92c8c896a6bc06e0b36e4c3de3',
+ 'src/third_party/pyelftools':
+ (Var("chromium_git")) + '/chromiumos/third_party/pyelftools.git@bdc1d380acd88d4bfaf47265008091483b0d614e',
+ 'src/third_party/stp/src':
+ (Var("chromium_git")) + '/external/github.com/stp/stp.git@fc94a599207752ab4d64048204f0c88494811b62',
+ 'src/third_party/xdg-utils':
+ (Var("chromium_git")) + '/chromium/deps/xdg-utils.git@d80274d5869b17b8c9067a1022e4416ee7ed5e0d'
+ },
+ 'win': {
+ 'src/chrome/tools/test/reference_build/chrome_win':
+ (Var("chromium_git")) + '/chromium/reference_builds/chrome_win.git@f8a3a845dfc845df6b14280f04f86a61959357ef',
+ 'src/third_party/bison':
+ (Var("chromium_git")) + '/chromium/deps/bison.git@083c9a45e4affdd5464ee2b224c2df649c6e26c3',
+ 'src/third_party/cygwin':
+ (Var("chromium_git")) + '/chromium/deps/cygwin.git@c89e446b273697fadf3a10ff1007a97c0b7de6df',
+ 'src/third_party/deqp/src':
+ 'https://android.googlesource.com/platform/external/deqp@194294e69d44eac48bc1fb063bd607189650aa5e',
+ 'src/third_party/gnu_binutils':
+ (Var("chromium_git")) + '/native_client/deps/third_party/gnu_binutils.git@f4003433b61b25666565690caf3d7a7a1a4ec436',
+ 'src/third_party/gperf':
+ (Var("chromium_git")) + '/chromium/deps/gperf.git@d892d79f64f9449770443fb06da49b5a1e5d33c1',
+ 'src/third_party/lighttpd':
+ (Var("chromium_git")) + '/chromium/deps/lighttpd.git@9dfa55d15937a688a92cbf2b7a8621b0927d06eb',
+ 'src/third_party/mingw-w64/mingw/bin':
+ (Var("chromium_git")) + '/native_client/deps/third_party/mingw-w64/mingw/bin.git@3cc8b140b883a9fe4986d12cfd46c16a093d3527',
+ 'src/third_party/nacl_sdk_binaries':
+ (Var("chromium_git")) + '/chromium/deps/nacl_sdk_binaries.git@759dfca03bdc774da7ecbf974f6e2b84f43699a5',
+ 'src/third_party/nss':
+ (Var("chromium_git")) + '/chromium/deps/nss.git@aab0d08a298b29407397fbb1c4219f99e99431ed',
+ 'src/third_party/pefile':
+ (Var("chromium_git")) + '/external/pefile.git@72c6ae42396cb913bcab63c15585dc3b5c3f92f1',
+ 'src/third_party/perl':
+ (Var("chromium_git")) + '/chromium/deps/perl.git@ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
+ 'src/third_party/psyco_win32':
+ (Var("chromium_git")) + '/chromium/deps/psyco_win32.git@f5af9f6910ee5a8075bbaeed0591469f1661d868',
+ 'src/third_party/yasm/binaries':
+ (Var("chromium_git")) + '/chromium/deps/yasm/binaries.git@52f9b3f4b0aa06da24ef8b123058bb61ee468881'
+ }
}
-
-
+hooks = [
+ {
+ 'action': [
+ 'python',
+ 'src/build/landmines.py'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'landmines'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/build/download_nacl_toolchains.py',
+ '--mode',
+ 'nacl_core_sdk',
+ 'sync',
+ '--extract'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'nacltools'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/build/download_sdk_extras.py'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'sdkextras'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/build/linux/sysroot_scripts/install-sysroot.py',
+ '--running-as-hook'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'sysroot'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/build/vs_toolchain.py',
+ 'update'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'win_toolchain'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/third_party/binutils/download.py'
+ ],
+ 'pattern':
+ 'src/third_party/binutils',
+ 'name':
+ 'binutils'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/tools/clang/scripts/update.py',
+ '--if-needed'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'clang'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/build/util/lastchange.py',
+ '-o',
+ 'src/build/util/LASTCHANGE'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'lastchange'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/build/util/lastchange.py',
+ '--git-hash-only',
+ '-s',
+ 'src/third_party/WebKit',
+ '-o',
+ 'src/build/util/LASTCHANGE.blink'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'lastchange'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=win32',
+ '--no_auth',
+ '--bucket',
+ 'chromium-gn',
+ '-s',
+ 'src/buildtools/win/gn.exe.sha1'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'gn_win'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=darwin',
+ '--no_auth',
+ '--bucket',
+ 'chromium-gn',
+ '-s',
+ 'src/buildtools/mac/gn.sha1'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'gn_mac'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=linux*',
+ '--no_auth',
+ '--bucket',
+ 'chromium-gn',
+ '-s',
+ 'src/buildtools/linux64/gn.sha1'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'gn_linux64'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=win32',
+ '--no_auth',
+ '--bucket',
+ 'chromium-clang-format',
+ '-s',
+ 'src/buildtools/win/clang-format.exe.sha1'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'clang_format_win'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=darwin',
+ '--no_auth',
+ '--bucket',
+ 'chromium-clang-format',
+ '-s',
+ 'src/buildtools/mac/clang-format.sha1'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'clang_format_mac'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=linux*',
+ '--no_auth',
+ '--bucket',
+ 'chromium-clang-format',
+ '-s',
+ 'src/buildtools/linux64/clang-format.sha1'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'clang_format_linux'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=win32',
+ '--no_auth',
+ '--bucket',
+ 'chromium-luci',
+ '-d',
+ 'src/tools/luci-go/win64'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'luci-go_win'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=darwin',
+ '--no_auth',
+ '--bucket',
+ 'chromium-luci',
+ '-d',
+ 'src/tools/luci-go/mac64'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'luci-go_mac'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=linux*',
+ '--no_auth',
+ '--bucket',
+ 'chromium-luci',
+ '-d',
+ 'src/tools/luci-go/linux64'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'luci-go_linux'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=linux*',
+ '--no_auth',
+ '--bucket',
+ 'chromium-eu-strip',
+ '-s',
+ 'src/build/linux/bin/eu-strip.sha1'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'eu-strip'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=win32',
+ '--no_auth',
+ '--bucket',
+ 'chromium-drmemory',
+ '-s',
+ 'src/third_party/drmemory/drmemory-windows-sfx.exe.sha1'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'drmemory'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/build/get_syzygy_binaries.py',
+ '--output-dir=src/third_party/syzygy/binaries',
+ '--revision=e50a9822fc8aeb5e7902da5e2940ea135d732e57',
+ '--overwrite'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'syzygy-binaries'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/build/get_syzygy_binaries.py',
+ '--output-dir=src/third_party/kasko',
+ '--revision=283aeaceeb22e2ba40a1753e3cb32454b59cc017',
+ '--resource=kasko.zip',
+ '--resource=kasko_symbols.zip',
+ '--overwrite'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'kasko'
+ },
+ {
+ 'action': [
+ 'download_from_google_storage',
+ '--no_resume',
+ '--platform=win32',
+ '--directory',
+ '--recursive',
+ '--no_auth',
+ '--num_threads=16',
+ '--bucket',
+ 'chromium-apache-win32',
+ 'src/third_party/apache-win32'
+ ],
+ 'pattern':
+ '\\.sha1',
+ 'name':
+ 'apache_win32'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/third_party/mojo/src/mojo/public/tools/download_shell_binary.py',
+ '--tools-directory=../../../../../../tools'
+ ],
+ 'pattern':
+ '',
+ 'name':
+ 'download_mojo_shell'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/third_party/instrumented_libraries/scripts/download_binaries.py'
+ ],
+ 'pattern':
+ '\\.sha1',
+ 'name':
+ 'instrumented_libraries'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/tools/remove_stale_pyc_files.py',
+ 'src/android_webview/tools',
+ 'src/gpu/gles2_conform_support',
+ 'src/ppapi',
+ 'src/printing',
+ 'src/third_party/closure_compiler/build',
+ 'src/tools'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'remove_stale_pyc_files'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/build/gyp_chromium'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'gyp'
+ },
+ {
+ 'action': [
+ 'python',
+ 'src/tools/check_git_config.py',
+ '--running-as-hook'
+ ],
+ 'pattern':
+ '.',
+ 'name':
+ 'check_git_config'
+ }
+]
include_rules = [
- # Everybody can use some things.
- # NOTE: THIS HAS TO STAY IN SYNC WITH third_party/DEPS which disallows these.
'+base',
'+build',
'+ipc',
-
- # Everybody can use headers generated by tools/generate_library_loader.
'+library_loaders',
-
'+testing',
'+third_party/icu/source/common/unicode',
'+third_party/icu/source/i18n/unicode',
- '+url',
+ '+url'
]
-
-
-# checkdeps.py shouldn't check include paths for files in these dirs:
skip_child_includes = [
'breakpad',
'native_client_sdk',
@@ -493,306 +697,5 @@
'skia',
'testing',
'v8',
- 'win8',
-]
-
-
-hooks = [
- {
- # This clobbers when necessary (based on get_landmines.py). It must be the
- # first hook so that other things that get/generate into the output
- # directory will not subsequently be clobbered.
- 'name': 'landmines',
- 'pattern': '.',
- 'action': [
- 'python',
- 'src/build/landmines.py',
- ],
- },
- {
- # This downloads binaries for Native Client's newlib toolchain.
- # Done in lieu of building the toolchain from scratch as it can take
- # anywhere from 30 minutes to 4 hours depending on platform to build.
- 'name': 'nacltools',
- 'pattern': '.',
- 'action': [
- 'python',
- 'src/build/download_nacl_toolchains.py',
- '--mode', 'nacl_core_sdk',
- 'sync', '--extract',
- ],
- },
- {
- # This downloads SDK extras and puts them in the
- # third_party/android_tools/sdk/extras directory on the bots. Developers
- # need to manually install these packages and accept the ToS.
- 'name': 'sdkextras',
- 'pattern': '.',
- # When adding a new sdk extras package to download, add the package
- # directory and zip file to .gitignore in third_party/android_tools.
- 'action': ['python', 'src/build/download_sdk_extras.py'],
- },
- {
- # Downloads the current stable linux sysroot to build/linux/ if needed.
- # This sysroot updates at about the same rate that the chrome build deps
- # change. This script is a no-op except for linux users who are doing
- # official chrome builds or cross compiling.
- 'name': 'sysroot',
- 'pattern': '.',
- 'action': ['python', 'src/build/linux/sysroot_scripts/install-sysroot.py',
- '--running-as-hook'],
- },
- {
- # Update the Windows toolchain if necessary.
- 'name': 'win_toolchain',
- 'pattern': '.',
- 'action': ['python', 'src/build/vs_toolchain.py', 'update'],
- },
- # Pull binutils for linux, enabled debug fission for faster linking /
- # debugging when used with clang on Ubuntu Precise.
- # https://code.google.com/p/chromium/issues/detail?id=352046
- {
- 'name': 'binutils',
- 'pattern': 'src/third_party/binutils',
- 'action': [
- 'python',
- 'src/third_party/binutils/download.py',
- ],
- },
- {
- # Pull clang if needed or requested via GYP_DEFINES.
- # Note: On Win, this should run after win_toolchain, as it may use it.
- 'name': 'clang',
- 'pattern': '.',
- 'action': ['python', 'src/tools/clang/scripts/update.py', '--if-needed'],
- },
- {
- # Update LASTCHANGE.
- 'name': 'lastchange',
- 'pattern': '.',
- 'action': ['python', 'src/build/util/lastchange.py',
- '-o', 'src/build/util/LASTCHANGE'],
- },
- {
- # Update LASTCHANGE.blink.
- 'name': 'lastchange',
- 'pattern': '.',
- 'action': ['python', 'src/build/util/lastchange.py',
- '-s', 'src/third_party/WebKit',
- '-o', 'src/build/util/LASTCHANGE.blink'],
- },
- # Pull GN binaries. This needs to be before running GYP below.
- {
- 'name': 'gn_win',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=win32',
- '--no_auth',
- '--bucket', 'chromium-gn',
- '-s', 'src/buildtools/win/gn.exe.sha1',
- ],
- },
- {
- 'name': 'gn_mac',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=darwin',
- '--no_auth',
- '--bucket', 'chromium-gn',
- '-s', 'src/buildtools/mac/gn.sha1',
- ],
- },
- {
- 'name': 'gn_linux64',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=linux*',
- '--no_auth',
- '--bucket', 'chromium-gn',
- '-s', 'src/buildtools/linux64/gn.sha1',
- ],
- },
- # Pull clang-format binaries using checked-in hashes.
- {
- 'name': 'clang_format_win',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=win32',
- '--no_auth',
- '--bucket', 'chromium-clang-format',
- '-s', 'src/buildtools/win/clang-format.exe.sha1',
- ],
- },
- {
- 'name': 'clang_format_mac',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=darwin',
- '--no_auth',
- '--bucket', 'chromium-clang-format',
- '-s', 'src/buildtools/mac/clang-format.sha1',
- ],
- },
- {
- 'name': 'clang_format_linux',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=linux*',
- '--no_auth',
- '--bucket', 'chromium-clang-format',
- '-s', 'src/buildtools/linux64/clang-format.sha1',
- ],
- },
- # Pull luci-go binaries (isolate, swarming) using checked-in hashes.
- {
- 'name': 'luci-go_win',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=win32',
- '--no_auth',
- '--bucket', 'chromium-luci',
- '-d', 'src/tools/luci-go/win64',
- ],
- },
- {
- 'name': 'luci-go_mac',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=darwin',
- '--no_auth',
- '--bucket', 'chromium-luci',
- '-d', 'src/tools/luci-go/mac64',
- ],
- },
- {
- 'name': 'luci-go_linux',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=linux*',
- '--no_auth',
- '--bucket', 'chromium-luci',
- '-d', 'src/tools/luci-go/linux64',
- ],
- },
- # Pull eu-strip binaries using checked-in hashes.
- {
- 'name': 'eu-strip',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=linux*',
- '--no_auth',
- '--bucket', 'chromium-eu-strip',
- '-s', 'src/build/linux/bin/eu-strip.sha1',
- ],
- },
- {
- 'name': 'drmemory',
- 'pattern': '.',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=win32',
- '--no_auth',
- '--bucket', 'chromium-drmemory',
- '-s', 'src/third_party/drmemory/drmemory-windows-sfx.exe.sha1',
- ],
- },
- # Pull the Syzygy binaries, used for optimization and instrumentation.
- {
- 'name': 'syzygy-binaries',
- 'pattern': '.',
- 'action': ['python',
- 'src/build/get_syzygy_binaries.py',
- '--output-dir=src/third_party/syzygy/binaries',
- '--revision=e50a9822fc8aeb5e7902da5e2940ea135d732e57',
- '--overwrite',
- ],
- },
- {
- 'name': 'kasko',
- 'pattern': '.',
- 'action': ['python',
- 'src/build/get_syzygy_binaries.py',
- '--output-dir=src/third_party/kasko',
- '--revision=283aeaceeb22e2ba40a1753e3cb32454b59cc017',
- '--resource=kasko.zip',
- '--resource=kasko_symbols.zip',
- '--overwrite',
- ],
- },
- {
- 'name': 'apache_win32',
- 'pattern': '\\.sha1',
- 'action': [ 'download_from_google_storage',
- '--no_resume',
- '--platform=win32',
- '--directory',
- '--recursive',
- '--no_auth',
- '--num_threads=16',
- '--bucket', 'chromium-apache-win32',
- 'src/third_party/apache-win32',
- ],
- },
- # Pull the mojo_shell binary, used for mojo development
- {
- 'name': 'download_mojo_shell',
- 'pattern': '',
- 'action': [ 'python',
- 'src/third_party/mojo/src/mojo/public/tools/download_shell_binary.py',
- '--tools-directory=../../../../../../tools',
- ],
- },
- {
- # Pull sanitizer-instrumented third-party libraries if requested via
- # GYP_DEFINES.
- 'name': 'instrumented_libraries',
- 'pattern': '\\.sha1',
- 'action': ['python', 'src/third_party/instrumented_libraries/scripts/download_binaries.py'],
- },
- {
- # Ensure that while generating dependencies lists in .gyp files we don't
- # accidentally reference any .pyc files whose corresponding .py files have
- # already been deleted.
- # We should actually try to avoid generating .pyc files, crbug.com/500078.
- 'name': 'remove_stale_pyc_files',
- 'pattern': '.',
- 'action': [
- 'python',
- 'src/tools/remove_stale_pyc_files.py',
- 'src/android_webview/tools',
- 'src/gpu/gles2_conform_support',
- 'src/ppapi',
- 'src/printing',
- 'src/third_party/closure_compiler/build',
- 'src/tools',
- ],
- },
- {
- # A change to a .gyp, .gypi, or to GYP itself should run the generator.
- 'name': 'gyp',
- 'pattern': '.',
- 'action': ['python', 'src/build/gyp_chromium'],
- },
- {
- # Verify committers' ~/.netc, gclient and git are properly configured for
- # write access to the git repo. To be removed sometime after Chrome to git
- # migration completes (let's say Sep 1 2014).
- 'name': 'check_git_config',
- 'pattern': '.',
- 'action': [
- 'python',
- 'src/tools/check_git_config.py',
- '--running-as-hook',
- ],
- },
-]
+ 'win8'
+]
\ No newline at end of file
diff --git a/tools/dom/dom.json b/tools/dom/dom.json
index f22b2a4..a7863c4 100644
--- a/tools/dom/dom.json
+++ b/tools/dom/dom.json
@@ -15095,6 +15095,12 @@
},
"encoding": {
"support_level": "untriaged"
+ },
+ "fatal": {
+ "support_level": "untriaged"
+ },
+ "ignoreBOM": {
+ "support_level": "untriaged"
}
},
"support_level": "untriaged"
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index fefbd2d..9beaef9 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -329,8 +329,6 @@
"@Returns('NodeList|HtmlCollection')",
],
- 'SQLResultSetRowList.item': ["@Creates('=Object')"],
-
# Touch targets are Elements in a Document, or the Document.
'Touch.target': [
"@Creates('Element|Document')",
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index a5488b2..7e6fe8b 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -721,6 +721,9 @@
'any set IDBObjectStore.put': _serialize_SSV,
'any set IDBCursor.update': _serialize_SSV,
+ 'any get SQLResultSetRowList.item' :
+ Conversion('convertNativeToDart_Dictionary', 'dynamic', 'Map'),
+
# postMessage
'SerializedScriptValue set': _serialize_SSV,
'any set CompositorWorkerGlobalScope.postMessage': _serialize_SSV,
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index b31b23d..672d97e 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -828,7 +828,8 @@
ext_attrs = self._interface.ext_attrs
has_indexed_getter = 'CustomIndexedGetter' in ext_attrs
for operation in self._interface.operations:
- if operation.id == 'item' and 'getter' in operation.specials:
+ if operation.id == 'item' and 'getter' in operation.specials \
+ and not self._OperationRequiresConversions(operation):
has_indexed_getter = True
break
return has_indexed_getter
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index a4abf47..2151a6d 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -793,11 +793,14 @@
}
int get timeout {
+ return configuration['timeout'] * SLOW_TIMEOUT_MULTIPLIER;
+/*
if (expectedOutcomes.contains(Expectation.SLOW)) {
return configuration['timeout'] * SLOW_TIMEOUT_MULTIPLIER;
} else {
return configuration['timeout'];
}
+*/
}
String get configurationString {
diff --git a/utils/dartanalyzer/dartanalyzer.gyp b/utils/dartanalyzer/dartanalyzer.gyp
index 1fa08ee..f23d464 100644
--- a/utils/dartanalyzer/dartanalyzer.gyp
+++ b/utils/dartanalyzer/dartanalyzer.gyp
@@ -32,7 +32,7 @@
],
},
{
- 'action_name': 'generate_summaries',
+ 'action_name': 'generate_summary_bundle',
'inputs': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
'<(SHARED_INTERMEDIATE_DIR)/packages.stamp',
@@ -40,14 +40,48 @@
'<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../pkg/analyzer"])',
],
'outputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/sdk_summary_bundle.bin',
+ ],
+ 'action': [
+ '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--package-root=<(PRODUCT_DIR)/packages/',
+ '../../pkg/analyzer/tool/summary/build_sdk_summaries.dart',
+ 'single-output',
+ '<(SHARED_INTERMEDIATE_DIR)/sdk_summary_bundle.bin',
+ ],
+ },
+ {
+ 'action_name': 'extract_spec_summary',
+ 'inputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/sdk_summary_bundle.bin',
+ ],
+ 'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/spec.sum',
+ ],
+ 'action': [
+ '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--package-root=<(PRODUCT_DIR)/packages/',
+ '../../pkg/analyzer/tool/summary/build_sdk_summaries.dart',
+ 'extract-spec-sum',
+ '<(SHARED_INTERMEDIATE_DIR)/sdk_summary_bundle.bin',
+ '<(SHARED_INTERMEDIATE_DIR)/spec.sum',
+ ],
+ },
+ {
+ 'action_name': 'extract_strong_summary',
+ 'inputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/sdk_summary_bundle.bin',
+ ],
+ 'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/strong.sum',
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
'--package-root=<(PRODUCT_DIR)/packages/',
'../../pkg/analyzer/tool/summary/build_sdk_summaries.dart',
- '<(SHARED_INTERMEDIATE_DIR)',
+ 'extract-strong-sum',
+ '<(SHARED_INTERMEDIATE_DIR)/sdk_summary_bundle.bin',
+ '<(SHARED_INTERMEDIATE_DIR)/strong.sum',
],
},
],