Version 1.17.0-dev.2.0
Merge f7a3e215a50e232fe60b57a6cdea51cc82636b8b into dev
diff --git a/DEPS b/DEPS
index c4bf8bb..a040da2 100644
--- a/DEPS
+++ b/DEPS
@@ -49,7 +49,7 @@
"dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
"dart_style_tag": "@0.2.4",
"dartdoc_tag" : "@v0.9.0",
- "dev_compiler_rev": "@0ed6aeca35fa0e618ad0f7f19f3eba64afdd80c4",
+ "dev_compiler_rev": "@ec95b3c45819f4d0de847588fdaa752a8e4651fb",
"fixnum_tag": "@0.10.4",
"func_rev": "@8d4aea75c21be2179cb00dc2b94a71414653094e",
"glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol.dart b/pkg/analysis_server/lib/plugin/protocol/protocol.dart
index 032e4f9..92ef921 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol.dart
@@ -160,7 +160,7 @@
*/
Request(this.id, this.method,
[Map<String, Object> params, this.clientRequestTime])
- : _params = params != null ? params : new HashMap<String, Object>();
+ : _params = params ?? new HashMap<String, Object>();
/**
* Return a request parsed from the given json, or `null` if the [data] is
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 5a06a6e..a00ab31 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -330,7 +330,7 @@
sdkManager = new DartSdkManager(defaultSdkCreator);
if (useSingleContextManager) {
contextManager = new SingleContextManager(resourceProvider, sdkManager,
- () => packageResolverProvider(null), analyzedFilesGlobs);
+ packageResolverProvider, analyzedFilesGlobs, defaultContextOptions);
} else {
contextManager = new ContextManagerImpl(
resourceProvider,
@@ -1420,7 +1420,7 @@
}
// if library has not been resolved yet, the unit will be resolved later
Source librarySource = librarySources[0];
- if (context.getResult(librarySource, LIBRARY_ELEMENT5) == null) {
+ if (context.getResult(librarySource, LIBRARY_ELEMENT6) == null) {
return null;
}
// if library has been already resolved, resolve unit
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index 33b5941..d4e10b4 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -127,5 +127,5 @@
return null;
}
- static _safeToString(obj) => obj != null ? obj.toString() : null;
+ static _safeToString(obj) => obj?.toString();
}
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 8603884..a89ff02 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -41,8 +41,7 @@
VariableDeclarationList fields = fieldDeclaration.fields;
if (fields != null) {
TypeName fieldType = fields.type;
- String fieldTypeName =
- fieldType != null ? fieldType.toSource() : '';
+ String fieldTypeName = _safeToSource(fieldType);
for (VariableDeclaration field in fields.variables) {
classContents.add(_newVariableOutline(fieldTypeName,
ElementKind.FIELD, field, fieldDeclaration.isStatic));
@@ -69,7 +68,7 @@
VariableDeclarationList fields = fieldDeclaration.variables;
if (fields != null) {
TypeName fieldType = fields.type;
- String fieldTypeName = fieldType != null ? fieldType.toSource() : '';
+ String fieldTypeName = _safeToSource(fieldType);
for (VariableDeclaration field in fields.variables) {
unitContents.add(_newVariableOutline(
fieldTypeName, ElementKind.TOP_LEVEL_VARIABLE, field, false));
@@ -207,7 +206,7 @@
}
_SourceRegion sourceRegion = _getSourceRegion(constructor);
FormalParameterList parameters = constructor.parameters;
- String parametersStr = parameters != null ? parameters.toSource() : '';
+ String parametersStr = _safeToSource(parameters);
Element element = new Element(
ElementKind.CONSTRUCTOR,
name,
@@ -266,8 +265,8 @@
kind = ElementKind.FUNCTION;
}
_SourceRegion sourceRegion = _getSourceRegion(function);
- String parametersStr = parameters != null ? parameters.toSource() : '';
- String returnTypeStr = returnType != null ? returnType.toSource() : '';
+ String parametersStr = _safeToSource(parameters);
+ String returnTypeStr = _safeToSource(returnType);
Element element = new Element(
kind,
name,
@@ -291,8 +290,8 @@
String name = nameNode.name;
_SourceRegion sourceRegion = _getSourceRegion(node);
FormalParameterList parameters = node.parameters;
- String parametersStr = parameters != null ? parameters.toSource() : '';
- String returnTypeStr = returnType != null ? returnType.toSource() : '';
+ String parametersStr = _safeToSource(parameters);
+ String returnTypeStr = _safeToSource(returnType);
Element element = new Element(
ElementKind.FUNCTION_TYPE_ALIAS,
name,
@@ -320,8 +319,8 @@
kind = ElementKind.METHOD;
}
_SourceRegion sourceRegion = _getSourceRegion(method);
- String parametersStr = parameters != null ? parameters.toSource() : null;
- String returnTypeStr = returnType != null ? returnType.toSource() : '';
+ String parametersStr = parameters?.toSource();
+ String returnTypeStr = _safeToSource(returnType);
Element element = new Element(
kind,
name,
@@ -383,6 +382,9 @@
engine.Element element = declaration.element;
return element != null && element.isDeprecated;
}
+
+ static String _safeToSource(AstNode node) =>
+ node == null ? '' : node.toSource();
}
/**
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index a87fdc5..181eeac 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -16,6 +16,7 @@
import 'package:analyzer/plugin/options.dart';
import 'package:analyzer/plugin/resolver_provider.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/config.dart';
import 'package:analyzer/source/embedder.dart';
import 'package:analyzer/source/package_map_provider.dart';
import 'package:analyzer/source/package_map_resolver.dart';
@@ -597,7 +598,7 @@
}
} else {
// Check for embedded options.
- YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
+ Map embeddedOptions = _getEmbeddedOptions(info.context);
if (embeddedOptions != null) {
options = _toStringMap(new Merger().merge(embeddedOptions, options));
}
@@ -1072,6 +1073,27 @@
folderMap[folder] = info.context;
info.context.name = folder.path;
+ // Look for pubspec-specified analysis configuration.
+ File pubspec;
+ if (packagespecFile?.exists == true) {
+ if (packagespecFile.shortName == PUBSPEC_NAME) {
+ pubspec = packagespecFile;
+ }
+ }
+ if (pubspec == null) {
+ Resource child = folder.getChild(PUBSPEC_NAME);
+ if (child.exists && child is File) {
+ pubspec = child;
+ }
+ }
+ if (pubspec != null) {
+ File pubSource = resourceProvider.getFile(pubspec.path);
+ setConfiguration(
+ info.context,
+ new AnalysisConfiguration.fromPubspec(
+ pubSource, resourceProvider, disposition.packages));
+ }
+
processOptionsForContext(info, optionMap);
return info;
@@ -1235,18 +1257,36 @@
return packageSpec;
}
- /// Get analysis options associated with an `_embedder.yaml`. If there is
- /// more than one `_embedder.yaml` associated with the given context, `null`
- /// is returned.
- YamlMap _getEmbeddedOptions(AnalysisContext context) {
+ /// Get analysis options inherited from an `_embedder.yaml` (deprecated)
+ /// and/or a package specified configuration. If more than one
+ /// `_embedder.yaml` is associated with the given context, the embedder is
+ /// skipped.
+ ///
+ /// Returns null if there are no embedded/configured options.
+ Map _getEmbeddedOptions(AnalysisContext context) {
+ Map embeddedOptions;
+
if (context is InternalAnalysisContext) {
EmbedderYamlLocator locator = context.embedderYamlLocator;
Iterable<YamlMap> maps = locator.embedderYamls.values;
if (maps.length == 1) {
- return maps.first;
+ embeddedOptions = maps.first;
+ }
+
+ AnalysisConfiguration configuration = getConfiguration(context);
+ if (configuration != null) {
+ Map configMap = configuration.options;
+ if (configMap != null) {
+ if (embeddedOptions != null) {
+ embeddedOptions = new Merger().merge(embeddedOptions, configMap);
+ } else {
+ embeddedOptions = configMap;
+ }
+ }
}
}
- return null;
+
+ return embeddedOptions;
}
/**
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index 6f71721..76b27ae 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -89,8 +89,7 @@
return;
}
// Dart
- CompilationUnit dartUnit =
- resolvedDartUnit != null ? resolvedDartUnit : parsedDartUnit;
+ CompilationUnit dartUnit = resolvedDartUnit ?? parsedDartUnit;
if (resolvedDartUnit != null) {
if (server.hasAnalysisSubscription(
protocol.AnalysisService.HIGHLIGHTS, file)) {
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index a5af1b22..6ccf8ae 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -334,7 +334,7 @@
* Set the [plugins] that are defined outside the analysis_server package.
*/
void set userDefinedPlugins(List<Plugin> plugins) {
- _userDefinedPlugins = plugins == null ? <Plugin>[] : plugins;
+ _userDefinedPlugins = plugins ?? <Plugin>[];
}
/**
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
index 0272fb8..7c64604 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
@@ -42,7 +42,7 @@
void complete([String tag = null]) {
_stopwatch.stop();
- _logDuration(tag != null ? tag : 'total time', _stopwatch.elapsed);
+ _logDuration(tag ?? 'total time', _stopwatch.elapsed);
}
void logElapseTime(String tag) {
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 8f27b86..b448251 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
@@ -55,7 +55,7 @@
if (libElem is LibraryElement) {
var unit = request.context.getResult(
new LibrarySpecificUnit(libElem.source, request.source),
- RESOLVED_UNIT4);
+ RESOLVED_UNIT5);
if (unit is CompilationUnit) {
return new CompletionTarget.forOffset(unit, request.offset);
}
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 7be86e4..e582d37 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
@@ -311,7 +311,7 @@
CompilationUnit unit = await _computeAsync(
this,
new LibrarySpecificUnit(libElem.source, unresolvedUnit.source),
- RESOLVED_UNIT4,
+ RESOLVED_UNIT5,
performance,
'resolve library unit');
checkAborted();
@@ -388,7 +388,7 @@
unit = await _computeAsync(
request,
new LibrarySpecificUnit(libSource, source),
- resultDescriptor ?? RESOLVED_UNIT4,
+ resultDescriptor ?? RESOLVED_UNIT5,
performance,
'resolve declarations');
}
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 750e623..d9778a5 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
@@ -387,44 +387,6 @@
}
}
- void _addLocalSuggestion_includeTypeNameSuggestions(
- SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind,
- {bool isAbstract: false,
- bool isDeprecated: false,
- ClassDeclaration classDecl,
- FormalParameterList param,
- int relevance: DART_RELEVANCE_DEFAULT}) {
- relevance = optype.typeNameSuggestionsFilter(
- _staticTypeOfIdentifier(id), relevance);
- if (relevance != null) {
- _addLocalSuggestion(id, typeName, elemKind,
- isAbstract: isAbstract,
- isDeprecated: isDeprecated,
- classDecl: classDecl,
- param: param,
- relevance: relevance);
- }
- }
-
- void _addLocalSuggestion_includeReturnValueSuggestions(
- SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind,
- {bool isAbstract: false,
- bool isDeprecated: false,
- ClassDeclaration classDecl,
- FormalParameterList param,
- int relevance: DART_RELEVANCE_DEFAULT}) {
- relevance = optype.returnValueSuggestionsFilter(
- _staticTypeOfIdentifier(id), relevance);
- if (relevance != null) {
- _addLocalSuggestion(id, typeName, elemKind,
- isAbstract: isAbstract,
- isDeprecated: isDeprecated,
- classDecl: classDecl,
- param: param,
- relevance: relevance);
- }
- }
-
void _addLocalSuggestion(
SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind,
{bool isAbstract: false,
@@ -447,7 +409,7 @@
suggestion.element = _createLocalElement(request.source, elemKind, id,
isAbstract: isAbstract,
isDeprecated: isDeprecated,
- parameters: param != null ? param.toSource() : null,
+ parameters: param?.toSource(),
returnType: typeName);
if ((elemKind == protocol.ElementKind.METHOD ||
elemKind == protocol.ElementKind.FUNCTION) &&
@@ -457,6 +419,44 @@
}
}
+ void _addLocalSuggestion_includeReturnValueSuggestions(
+ SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind,
+ {bool isAbstract: false,
+ bool isDeprecated: false,
+ ClassDeclaration classDecl,
+ FormalParameterList param,
+ int relevance: DART_RELEVANCE_DEFAULT}) {
+ relevance = optype.returnValueSuggestionsFilter(
+ _staticTypeOfIdentifier(id), relevance);
+ if (relevance != null) {
+ _addLocalSuggestion(id, typeName, elemKind,
+ isAbstract: isAbstract,
+ isDeprecated: isDeprecated,
+ classDecl: classDecl,
+ param: param,
+ relevance: relevance);
+ }
+ }
+
+ void _addLocalSuggestion_includeTypeNameSuggestions(
+ SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind,
+ {bool isAbstract: false,
+ bool isDeprecated: false,
+ ClassDeclaration classDecl,
+ FormalParameterList param,
+ int relevance: DART_RELEVANCE_DEFAULT}) {
+ relevance = optype.typeNameSuggestionsFilter(
+ _staticTypeOfIdentifier(id), relevance);
+ if (relevance != null) {
+ _addLocalSuggestion(id, typeName, elemKind,
+ isAbstract: isAbstract,
+ isDeprecated: isDeprecated,
+ classDecl: classDecl,
+ param: param,
+ relevance: relevance);
+ }
+ }
+
void _addParameterInfo(
CompletionSuggestion suggestion, FormalParameterList parameters) {
var paramList = parameters.parameters;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
index 71ac473..2c4d913 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
@@ -80,6 +80,7 @@
}
List<String> variableNameSuggestions = getCamelWordCombinations(strName);
+ variableNameSuggestions.remove(strName);
List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
for (String varName in variableNameSuggestions) {
CompletionSuggestion suggestion = _createNameSuggestion(varName);
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 b1dd15b..f855a29 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -1044,8 +1044,7 @@
} else {
ClassDeclaration enclosingClass =
node.getAncestor((node) => node is ClassDeclaration);
- targetElement =
- enclosingClass != null ? enclosingClass.element : null;
+ targetElement = enclosingClass?.element;
argument = nameNode;
}
}
@@ -2145,10 +2144,7 @@
if (n is MethodInvocation &&
n.offset == errorOffset &&
n.length == errorLength) {
- Expression target = n.target;
- while (target is ParenthesizedExpression) {
- target = (target as ParenthesizedExpression).expression;
- }
+ Expression target = n.target.unParenthesized;
// replace "/" with "~/"
BinaryExpression binary = target as BinaryExpression;
_addReplaceEdit(rf.rangeToken(binary.operator), '~/');
@@ -2595,7 +2591,7 @@
// return myFunction();
if (parent is ReturnStatement) {
ExecutableElement executable = getEnclosingExecutableElement(expression);
- return executable != null ? executable.returnType : null;
+ return executable?.returnType;
}
// int v = myFunction();
if (parent is VariableDeclaration) {
@@ -2653,7 +2649,7 @@
// foo( myFunction() );
if (parent is ArgumentList) {
ParameterElement parameter = expression.bestParameterElement;
- return parameter != null ? parameter.type : null;
+ return parameter?.type;
}
// bool
{
diff --git a/pkg/analysis_server/lib/src/services/correction/namespace.dart b/pkg/analysis_server/lib/src/services/correction/namespace.dart
index b0058aa..0aa0b8d 100644
--- a/pkg/analysis_server/lib/src/services/correction/namespace.dart
+++ b/pkg/analysis_server/lib/src/services/correction/namespace.dart
@@ -46,7 +46,7 @@
return importDirective.element;
}
ImportElementInfo info = internal_getImportElementInfo(prefixNode);
- return info != null ? info.element : null;
+ return info?.element;
}
/**
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 4592367..7cf8aa5 100644
--- a/pkg/analysis_server/lib/src/services/correction/sort_members.dart
+++ b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
@@ -197,11 +197,16 @@
directive.documentationComment.offset,
directive.documentationComment.end);
}
+ String annotationText;
+ if (directive.metadata.beginToken != null) {
+ annotationText = code.substring(directive.metadata.beginToken.offset,
+ directive.metadata.endToken.end);
+ }
int offset = directive.firstTokenAfterCommentAndMetadata.offset;
int length = directive.end - offset;
String text = code.substring(offset, offset + length);
- directives.add(new _DirectiveInfo(
- directive, kind, uriContent, documentationText, text));
+ directives.add(new _DirectiveInfo(directive, kind, uriContent,
+ documentationText, annotationText, text));
}
}
// nothing to do
@@ -245,6 +250,10 @@
sb.write(endOfLine);
}
}
+ if (directive.annotationText != null) {
+ sb.write(directive.annotationText);
+ sb.write(endOfLine);
+ }
sb.write(directive.text);
sb.write(endOfLine);
}
@@ -369,10 +378,11 @@
final _DirectivePriority priority;
final String uri;
final String documentationText;
+ final String annotationText;
final String text;
_DirectiveInfo(this.directive, this.priority, this.uri,
- this.documentationText, this.text);
+ this.documentationText, this.annotationText, this.text);
@override
int compareTo(_DirectiveInfo other) {
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index ca38579..551964a 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -1284,18 +1284,15 @@
*/
_InvertedCondition _invertCondition0(Expression expression) {
if (expression is BooleanLiteral) {
- BooleanLiteral literal = expression;
- if (literal.value) {
+ if (expression.value) {
return _InvertedCondition._simple("false");
} else {
return _InvertedCondition._simple("true");
}
- }
- if (expression is BinaryExpression) {
- BinaryExpression binary = expression;
- TokenType operator = binary.operator.type;
- Expression le = binary.leftOperand;
- Expression re = binary.rightOperand;
+ } else if (expression is BinaryExpression) {
+ TokenType operator = expression.operator.type;
+ Expression le = expression.leftOperand;
+ Expression re = expression.rightOperand;
_InvertedCondition ls = _invertCondition0(le);
_InvertedCondition rs = _invertCondition0(re);
if (operator == TokenType.LT) {
@@ -1324,37 +1321,22 @@
return _InvertedCondition._binary(
TokenType.AMPERSAND_AMPERSAND.precedence, ls, " && ", rs);
}
- }
- if (expression is IsExpression) {
- IsExpression isExpression = expression;
- String expressionSource = getNodeText(isExpression.expression);
- String typeSource = getNodeText(isExpression.type);
- if (isExpression.notOperator == null) {
+ } else if (expression is IsExpression) {
+ String expressionSource = getNodeText(expression.expression);
+ String typeSource = getNodeText(expression.type);
+ if (expression.notOperator == null) {
return _InvertedCondition._simple("$expressionSource is! $typeSource");
} else {
return _InvertedCondition._simple("$expressionSource is $typeSource");
}
- }
- if (expression is PrefixExpression) {
- PrefixExpression prefixExpression = expression;
- TokenType operator = prefixExpression.operator.type;
+ } else if (expression is PrefixExpression) {
+ TokenType operator = expression.operator.type;
if (operator == TokenType.BANG) {
- Expression operand = prefixExpression.operand;
- while (operand is ParenthesizedExpression) {
- ParenthesizedExpression pe = operand as ParenthesizedExpression;
- operand = pe.expression;
- }
+ Expression operand = expression.operand.unParenthesized;
return _InvertedCondition._simple(getNodeText(operand));
}
- }
- if (expression is ParenthesizedExpression) {
- ParenthesizedExpression pe = expression;
- Expression innerExpression = pe.expression;
- while (innerExpression is ParenthesizedExpression) {
- innerExpression =
- (innerExpression as ParenthesizedExpression).expression;
- }
- return _invertCondition0(innerExpression);
+ } else if (expression is ParenthesizedExpression) {
+ return _invertCondition0(expression.unParenthesized);
}
DartType type = expression.bestType;
if (type.displayName == "bool") {
diff --git a/pkg/analysis_server/lib/src/single_context_manager.dart b/pkg/analysis_server/lib/src/single_context_manager.dart
index bdc3a67..0a8c9f1 100644
--- a/pkg/analysis_server/lib/src/single_context_manager.dart
+++ b/pkg/analysis_server/lib/src/single_context_manager.dart
@@ -10,6 +10,7 @@
import 'package:analysis_server/src/context_manager.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/plugin/resolver_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -18,12 +19,6 @@
import 'package:watcher/watcher.dart';
/**
- * A function that will return a [UriResolver] that can be used to resolve
- * `package:` URIs in [SingleContextManager].
- */
-typedef UriResolver PackageResolverProvider();
-
-/**
* Implementation of [ContextManager] that supports only one [AnalysisContext].
* So, sources from all analysis roots are added to this single context. All
* features that could otherwise cause creating additional contexts, such as
@@ -51,7 +46,7 @@
* A function that will return a [UriResolver] that can be used to resolve
* `package:` URIs.
*/
- final PackageResolverProvider packageResolverProvider;
+ final ResolverProvider packageResolverProvider;
/**
* A list of the globs used to determine which files should be analyzed.
@@ -59,6 +54,11 @@
final List<Glob> analyzedFilesGlobs;
/**
+ * The default options used to create new analysis contexts.
+ */
+ final AnalysisOptionsImpl defaultContextOptions;
+
+ /**
* The list of included paths (folders and files) most recently passed to
* [setRoots].
*/
@@ -103,8 +103,12 @@
/**
* The [packageResolverProvider] must not be `null`.
*/
- SingleContextManager(this.resourceProvider, this.sdkManager,
- this.packageResolverProvider, this.analyzedFilesGlobs) {
+ SingleContextManager(
+ this.resourceProvider,
+ this.sdkManager,
+ this.packageResolverProvider,
+ this.analyzedFilesGlobs,
+ this.defaultContextOptions) {
pathContext = resourceProvider.pathContext;
}
@@ -196,8 +200,8 @@
}
// Create or update the analysis context.
if (context == null) {
- UriResolver packageResolver = packageResolverProvider();
- context = callbacks.addContext(contextFolder, new AnalysisOptionsImpl(),
+ UriResolver packageResolver = packageResolverProvider(contextFolder);
+ context = callbacks.addContext(contextFolder, defaultContextOptions,
new CustomPackageResolverDisposition(packageResolver));
ChangeSet changeSet =
_buildChangeSet(added: _includedFiles(includedPaths, excludedPaths));
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index a2cc48f..5b3f6de 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -461,6 +461,10 @@
if (unit != null) {
return unit;
}
+ unit = entry.getValue(RESOLVED_UNIT13);
+ if (unit != null) {
+ return unit;
+ }
return entry.getValue(RESOLVED_UNIT);
}
@@ -492,6 +496,7 @@
results.add(LIBRARY_ELEMENT3);
results.add(LIBRARY_ELEMENT4);
results.add(LIBRARY_ELEMENT5);
+ results.add(LIBRARY_ELEMENT6);
results.add(LIBRARY_ELEMENT);
results.add(LIBRARY_ERRORS_READY);
results.add(PARSE_ERRORS);
@@ -518,6 +523,7 @@
results.add(INFERABLE_STATIC_VARIABLES_IN_UNIT);
results.add(LIBRARY_UNIT_ERRORS);
results.add(RESOLVE_TYPE_NAMES_ERRORS);
+ results.add(RESOLVE_TYPE_BOUNDS_ERRORS);
results.add(RESOLVE_UNIT_ERRORS);
results.add(RESOLVED_UNIT1);
results.add(RESOLVED_UNIT2);
@@ -531,6 +537,7 @@
results.add(RESOLVED_UNIT10);
results.add(RESOLVED_UNIT11);
results.add(RESOLVED_UNIT12);
+ results.add(RESOLVED_UNIT13);
results.add(RESOLVED_UNIT);
results.add(STRONG_MODE_ERRORS);
results.add(USED_IMPORTED_ELEMENTS);
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index d20e599..9f00603 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -78,6 +78,11 @@
String projPath = '/my/proj';
+ AnalysisError missing_required_param = new AnalysisError(
+ new TestSource(), 0, 1, HintCode.MISSING_REQUIRED_PARAM, [
+ ['x']
+ ]);
+
AnalysisError missing_return =
new AnalysisError(new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
['x']
@@ -284,6 +289,98 @@
// No error means success.
}
+ test_configed_options() async {
+ // Create files.
+ String libPath = newFolder([projPath, LIB_NAME]);
+ newFile([projPath, 'test', 'test.dart']);
+ newFile(
+ [projPath, 'pubspec.yaml'],
+ r'''
+dependencies:
+ test_pack: any
+analyzer:
+ configuration: test_pack/config
+''');
+
+ // Setup .packages file
+ newFile(
+ [projPath, '.packages'],
+ r'''
+test_pack:lib/''');
+
+ // Setup config.yaml.
+ newFile(
+ [libPath, 'config', 'config.yaml'],
+ r'''
+analyzer:
+ strong-mode: true
+ language:
+ enableSuperMixins: true
+ errors:
+ missing_return: false
+linter:
+ rules:
+ - avoid_as
+''');
+
+ // Setup .analysis_options
+ newFile(
+ [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+ r'''
+analyzer:
+ exclude:
+ - 'test/**'
+ language:
+ enableGenericMethods: true
+ enableAsync: false
+ errors:
+ unused_local_variable: false
+linter:
+ rules:
+ - camel_case_types
+''');
+
+ // Setup context.
+ manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+ await pumpEventQueue();
+
+ // Confirm that one context was created.
+ var contexts =
+ manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
+ expect(contexts, isNotNull);
+ expect(contexts, hasLength(1));
+
+ var context = contexts.first;
+
+ // Verify options.
+ // * from `config.yaml`:
+ expect(context.analysisOptions.strongMode, isTrue);
+ expect(context.analysisOptions.enableSuperMixins, isTrue);
+ expect(context.analysisOptions.enableAsync, isFalse);
+ // * from `.analysis_options`:
+ expect(context.analysisOptions.enableGenericMethods, isTrue);
+
+ // * verify tests are excluded
+ expect(callbacks.currentContextFilePaths[projPath].keys,
+ unorderedEquals(['/my/proj/.analysis_options']));
+
+ // Verify filter setup.
+ expect(errorProcessors, hasLength(2));
+
+ // * (config.)
+ expect(getProcessor(missing_return).severity, isNull);
+
+ // * (options.)
+ expect(getProcessor(unused_local_variable).severity, isNull);
+
+ // Verify lints.
+ var lintNames = lints.map((lint) => lint.name);
+ expect(
+ lintNames,
+ unorderedEquals(
+ ['avoid_as' /* config */, 'camel_case_types' /* options */]));
+ }
+
void test_contextsInAnalysisRoot_nestedContext() {
String subProjPath = posix.join(projPath, 'subproj');
Folder subProjFolder = resourceProvider.newFolder(subProjPath);
@@ -362,6 +459,130 @@
expect(contexts.first.sourceFactory.forUri('dart:typed_data'), isNotNull);
}
+ test_embedder_and_configed_options() async {
+ // Create files.
+ String libPath = newFolder([projPath, LIB_NAME]);
+ String sdkExtPath = newFolder([projPath, 'sdk_ext']);
+ newFile([projPath, 'test', 'test.dart']);
+ newFile([sdkExtPath, 'entry.dart']);
+
+ // Setup pubspec with configuration.
+ newFile(
+ [projPath, 'pubspec.yaml'],
+ r'''
+dependencies:
+ test_pack: any
+analyzer:
+ configuration: test_pack/config
+''');
+
+ // Setup _embedder.yaml.
+ newFile(
+ [libPath, '_embedder.yaml'],
+ r'''
+embedded_libs:
+ "dart:foobar": "../sdk_ext/entry.dart"
+analyzer:
+ strong-mode: true
+ language:
+ enableSuperMixins: true
+ errors:
+ missing_return: false
+linter:
+ rules:
+ - avoid_as
+''');
+
+ // Setup .packages file
+ newFile(
+ [projPath, '.packages'],
+ r'''
+test_pack:lib/''');
+
+ // Setup .analysis_options
+ newFile(
+ [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+ r'''
+analyzer:
+ exclude:
+ - 'test/**'
+ language:
+ enableGenericMethods: true
+ enableAsync: false
+ errors:
+ unused_local_variable: false
+linter:
+ rules:
+ - camel_case_types
+''');
+
+ // Setup config.yaml.
+ newFile(
+ [libPath, 'config', 'config.yaml'],
+ r'''
+analyzer:
+ errors:
+ missing_required_param: error
+linter:
+ rules:
+ - always_specify_types
+''');
+
+ // Setup context.
+ manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+ await pumpEventQueue();
+
+ // Confirm that one context was created.
+ var contexts =
+ manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
+ expect(contexts, isNotNull);
+ expect(contexts, hasLength(1));
+ var context = contexts[0];
+
+ // Verify options.
+ // * from `_embedder.yaml`:
+ expect(context.analysisOptions.strongMode, isTrue);
+ expect(context.analysisOptions.enableSuperMixins, isTrue);
+ expect(context.analysisOptions.enableAsync, isFalse);
+ // * from `.analysis_options`:
+ expect(context.analysisOptions.enableGenericMethods, isTrue);
+
+ // * verify tests are excluded
+ expect(
+ callbacks.currentContextFilePaths[projPath].keys,
+ unorderedEquals(
+ ['/my/proj/sdk_ext/entry.dart', '/my/proj/.analysis_options']));
+
+ // Verify filter setup.
+ expect(errorProcessors, hasLength(3));
+
+ // * (embedder.)
+ expect(getProcessor(missing_return).severity, isNull);
+
+ // * (config.)
+ expect(getProcessor(missing_required_param).severity, ErrorSeverity.ERROR);
+
+ // * (options.)
+ expect(getProcessor(unused_local_variable).severity, isNull);
+
+ // Verify lints.
+ var lintNames = lints.map((lint) => lint.name);
+
+ expect(
+ lintNames,
+ unorderedEquals([
+ 'avoid_as' /* embedder */,
+ 'always_specify_types' /* config*/,
+ 'camel_case_types' /* options */
+ ]));
+
+ // Sanity check embedder libs.
+ var source = context.sourceFactory.forUri('dart:foobar');
+ expect(source, isNotNull);
+ expect(source.fullName,
+ '/my/proj/sdk_ext/entry.dart'.replaceAll('/', JavaFile.separator));
+ }
+
test_embedder_options() async {
// Create files.
String libPath = newFolder([projPath, LIB_NAME]);
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index a955360..ee801df7 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -144,6 +144,40 @@
''');
}
+ test_OK_directives_withAnnotation() async {
+ addTestFile('''
+library lib;
+
+export 'dart:bbb';
+@MyAnnotation(1)
+@MyAnnotation(2)
+import 'dart:bbb';
+@MyAnnotation(3)
+export 'dart:aaa';
+import 'dart:aaa';
+
+class MyAnnotation {
+ const MyAnnotation(_);
+}
+''');
+ return _assertSorted(r'''
+library lib;
+
+import 'dart:aaa';
+@MyAnnotation(1)
+@MyAnnotation(2)
+import 'dart:bbb';
+
+@MyAnnotation(3)
+export 'dart:aaa';
+export 'dart:bbb';
+
+class MyAnnotation {
+ const MyAnnotation(_);
+}
+''');
+ }
+
test_OK_unitMembers_class() async {
addTestFile('''
class C {}
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 dc011c1..08c83de 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
@@ -143,10 +143,10 @@
if (elemOffset != null) {
expect(cs.element.location.offset, elemOffset);
}
- if(paramName != null) {
+ if (paramName != null) {
expect(cs.parameterName, paramName);
}
- if(paramType != null) {
+ if (paramType != null) {
expect(cs.parameterType, paramType);
}
return cs;
@@ -262,8 +262,6 @@
expect(cs.returnType, returnType);
} else if (isNullExpectedReturnTypeConsideredDynamic) {
expect(cs.returnType, 'dynamic');
- } else {
- expect(cs.returnType, isNull);
}
protocol.Element element = cs.element;
expect(element, isNotNull);
@@ -278,8 +276,6 @@
expect(element.returnType, returnType);
} else if (isNullExpectedReturnTypeConsideredDynamic) {
expect(element.returnType, 'dynamic');
- } else {
- expect(element.returnType, isNull);
}
assertHasParameterInfo(cs);
return cs;
@@ -369,8 +365,7 @@
return cs;
}
- CompletionSuggestion assertSuggestName(
- String name,
+ CompletionSuggestion assertSuggestName(String name,
{int relevance: DART_RELEVANCE_DEFAULT,
String importUri,
CompletionSuggestionKind kind: CompletionSuggestionKind.IDENTIFIER,
@@ -419,8 +414,6 @@
expect(cs.returnType, returnType);
} else if (isNullExpectedReturnTypeConsideredDynamic) {
expect(cs.returnType, 'dynamic');
- } else {
- expect(cs.returnType, isNull);
}
protocol.Element element = cs.element;
expect(element, isNotNull);
@@ -431,8 +424,6 @@
expect(element.returnType, returnType);
} else if (isNullExpectedReturnTypeConsideredDynamic) {
expect(element.returnType, 'dynamic');
- } else {
- expect(element.returnType, isNull);
}
assertHasNoParameterInfo(cs);
return cs;
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 6b63ce0..51125e7 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
@@ -2729,7 +2729,7 @@
// in which case suggestions will have null (unresolved) returnType
assertSuggestTopLevelVar('T1', null);
assertSuggestFunction('F1', null);
- assertSuggestFunctionTypeAlias('D1', 'null');
+ assertSuggestFunctionTypeAlias('D1', 'dynamic');
assertSuggestClass('C1');
assertNotSuggested('T2');
assertNotSuggested('F2');
diff --git a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
index 72a4cab..6896850 100644
--- a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
@@ -24,24 +24,24 @@
return new VariableNameContributor();
}
- test_ExpressionStatement_short() async {
+ test_ExpressionStatement_dont_suggest_type() async {
addTestSource('''
- f() { A ^ }
+ f() { a ^ }
''');
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestName('a');
+ assertNotSuggested('a');
}
- test_ExpressionStatement_short_semicolon() async {
+ test_ExpressionStatement_dont_suggest_type_semicolon() async {
addTestSource('''
- f() { A ^; }
+ f() { a ^; }
''');
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestName('a');
+ assertNotSuggested('a');
}
test_ExpressionStatement_long() async {
@@ -100,9 +100,9 @@
assertSuggestName('name');
}
- test_ExpressionStatement_top_level_short() async {
+ test_ExpressionStatement_short() async {
addTestSource('''
- A ^
+ f() { A ^ }
''');
await computeSuggestions();
expect(replacementOffset, completionOffset);
@@ -110,9 +110,9 @@
assertSuggestName('a');
}
- test_ExpressionStatement_top_level_short_semicolon() async {
+ test_ExpressionStatement_short_semicolon() async {
addTestSource('''
- A ^;
+ f() { A ^; }
''');
await computeSuggestions();
expect(replacementOffset, completionOffset);
@@ -120,7 +120,27 @@
assertSuggestName('a');
}
- test_ExpressionStatement_top_level_long() async {
+ test_TopLevelVariableDeclaration_dont_suggest_type() async {
+ addTestSource('''
+ a ^
+ ''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ }
+
+ test_TopLevelVariableDeclaration_dont_suggest_type_semicolon() async {
+ addTestSource('''
+ a ^;
+ ''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertNotSuggested('a');
+ }
+
+ test_TopLevelVariableDeclaration_long() async {
addTestSource('''
AbstractCrazyNonsenseClassName ^
''');
@@ -134,7 +154,7 @@
assertSuggestName('name');
}
- test_ExpressionStatement_top_level_long_semicolon() async {
+ test_TopLevelVariableDeclaration_long_semicolon() async {
addTestSource('''
AbstractCrazyNonsenseClassName ^;
''');
@@ -148,7 +168,35 @@
assertSuggestName('name');
}
- test_ExpressionStatement_top_level_prefixed() async {
+ test_TopLevelVariableDeclaration_partial() async {
+ addTestSource('''
+ AbstractCrazyNonsenseClassName abs^
+ ''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 3);
+ expect(replacementLength, 3);
+ assertSuggestName('abstractCrazyNonsenseClassName');
+ assertSuggestName('crazyNonsenseClassName');
+ assertSuggestName('nonsenseClassName');
+ assertSuggestName('className');
+ assertSuggestName('name');
+ }
+
+ test_TopLevelVariableDeclaration_partial_semicolon() async {
+ addTestSource('''
+ AbstractCrazyNonsenseClassName abs^
+ ''');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset - 3);
+ expect(replacementLength, 3);
+ assertSuggestName('abstractCrazyNonsenseClassName');
+ assertSuggestName('crazyNonsenseClassName');
+ assertSuggestName('nonsenseClassName');
+ assertSuggestName('className');
+ assertSuggestName('name');
+ }
+
+ test_TopLevelVariableDeclaration_prefixed() async {
addTestSource('''
prefix.AbstractCrazyNonsenseClassName ^
''');
@@ -162,7 +210,7 @@
assertSuggestName('name');
}
- test_ExpressionStatement_top_level_prefixed_semicolon() async {
+ test_TopLevelVariableDeclaration_prefixed_semicolon() async {
addTestSource('''
prefix.AbstractCrazyNonsenseClassName ^;
''');
@@ -176,24 +224,23 @@
assertSuggestName('name');
}
- test_VariableDeclaration_short() async {
+ test_TopLevelVariableDeclaration_short() async {
addTestSource('''
- AAA a^
+ A ^
''');
await computeSuggestions();
- expect(replacementOffset, completionOffset-1);
- expect(replacementLength, 1);
- assertSuggestName('aaa');
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestName('a');
}
- test_VariableDeclaration_short_semicolon() async {
+ test_TopLevelVariableDeclaration_short_semicolon() async {
addTestSource('''
- AAA a^;
+ A ^;
''');
await computeSuggestions();
- expect(replacementOffset, completionOffset-1);
- expect(replacementLength, 1);
- assertSuggestName('aaa');
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestName('a');
}
-
}
diff --git a/pkg/analysis_server/test/single_context_manager_test.dart b/pkg/analysis_server/test/single_context_manager_test.dart
index f436006..25ab3bd 100644
--- a/pkg/analysis_server/test/single_context_manager_test.dart
+++ b/pkg/analysis_server/test/single_context_manager_test.dart
@@ -69,7 +69,7 @@
return new MockSdk();
});
manager = new SingleContextManager(resourceProvider, sdkManager,
- () => packageResolver, analysisFilesGlobs);
+ (_) => packageResolver, analysisFilesGlobs, new AnalysisOptionsImpl());
callbacks = new TestContextManagerCallbacks(resourceProvider);
manager.callbacks = callbacks;
}
diff --git a/pkg/analyzer/doc/tasks.html b/pkg/analyzer/doc/tasks.html
index 5e242a5..4fdabc9 100644
--- a/pkg/analyzer/doc/tasks.html
+++ b/pkg/analyzer/doc/tasks.html
@@ -52,23 +52,24 @@
CREATED_RESOLVED_UNIT [shape=box]
CREATED_RESOLVED_UNIT1 [shape=box]
CREATED_RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
- CREATED_RESOLVED_UNIT10 -> InferStaticVariableTypeTask
- CREATED_RESOLVED_UNIT10 -> PartiallyResolveUnitReferencesTask
- CREATED_RESOLVED_UNIT10 -> ResolveInstanceFieldsInUnitTask
- CREATED_RESOLVED_UNIT10 -> ResolveUnitTask
CREATED_RESOLVED_UNIT10 [shape=box]
- CREATED_RESOLVED_UNIT11 -> ResolveConstantExpressionTask
+ CREATED_RESOLVED_UNIT11 -> InferInstanceMembersInUnitTask
+ CREATED_RESOLVED_UNIT11 -> InferStaticVariableTypeTask
+ CREATED_RESOLVED_UNIT11 -> PartiallyResolveUnitReferencesTask
+ CREATED_RESOLVED_UNIT11 -> ResolveInstanceFieldsInUnitTask
+ CREATED_RESOLVED_UNIT11 -> ResolveUnitTask
CREATED_RESOLVED_UNIT11 [shape=box]
+ CREATED_RESOLVED_UNIT12 -> ResolveConstantExpressionTask
CREATED_RESOLVED_UNIT12 [shape=box]
+ CREATED_RESOLVED_UNIT13 [shape=box]
CREATED_RESOLVED_UNIT2 [shape=box]
CREATED_RESOLVED_UNIT3 [shape=box]
CREATED_RESOLVED_UNIT4 [shape=box]
CREATED_RESOLVED_UNIT5 [shape=box]
CREATED_RESOLVED_UNIT6 [shape=box]
CREATED_RESOLVED_UNIT7 [shape=box]
- CREATED_RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
CREATED_RESOLVED_UNIT8 [shape=box]
- CREATED_RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
+ CREATED_RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
CREATED_RESOLVED_UNIT9 [shape=box]
ComputeConstantDependenciesTask -> CONSTANT_DEPENDENCIES
ComputeConstantValueTask -> CONSTANT_VALUE
@@ -88,11 +89,12 @@
EXPORTED_LIBRARIES -> ReadyLibraryElement2Task
EXPORTED_LIBRARIES -> ReadyLibraryElement5Task
EXPORTED_LIBRARIES -> ReadyLibraryElement6Task
+ EXPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
EXPORTED_LIBRARIES [shape=box]
EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
EXPORT_SOURCE_CLOSURE [shape=box]
- EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT12
- EvaluateUnitConstantsTask -> RESOLVED_UNIT12
+ EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT13
+ EvaluateUnitConstantsTask -> RESOLVED_UNIT13
GatherUsedImportedElementsTask -> USED_IMPORTED_ELEMENTS
GatherUsedLocalElementsTask -> USED_LOCAL_ELEMENTS
GenerateHintsTask -> HINTS
@@ -103,7 +105,8 @@
IMPORTED_LIBRARIES -> ReadyLibraryElement2Task
IMPORTED_LIBRARIES -> ReadyLibraryElement5Task
IMPORTED_LIBRARIES -> ReadyLibraryElement6Task
- IMPORTED_LIBRARIES -> ResolveUnitTypeNamesTask
+ IMPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
+ IMPORTED_LIBRARIES -> ResolveTopLevelUnitTypeBoundsTask
IMPORTED_LIBRARIES [shape=box]
INCLUDED_PARTS -> BuildLibraryElementTask
INCLUDED_PARTS [shape=box]
@@ -115,11 +118,11 @@
INFERRED_STATIC_VARIABLE -> InferStaticVariableTypesInUnitTask
INFERRED_STATIC_VARIABLE [shape=box]
IS_LAUNCHABLE [shape=box]
- InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT10
- InferInstanceMembersInUnitTask -> RESOLVED_UNIT10
+ InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT11
+ InferInstanceMembersInUnitTask -> RESOLVED_UNIT11
InferStaticVariableTypeTask -> INFERRED_STATIC_VARIABLE
- InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
- InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT8
+ InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT9
+ InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT9
LIBRARY_CYCLE [shape=box]
LIBRARY_CYCLE_DEPENDENCIES -> InferInstanceMembersInUnitTask
LIBRARY_CYCLE_DEPENDENCIES -> InferStaticVariableTypeTask
@@ -144,29 +147,34 @@
LIBRARY_ELEMENT3 -> BuildExportNamespaceTask
LIBRARY_ELEMENT3 -> BuildTypeProviderTask
LIBRARY_ELEMENT3 [shape=box]
- LIBRARY_ELEMENT4 -> ResolveLibraryTypeNamesTask
- LIBRARY_ELEMENT4 -> ResolveUnitTypeNamesTask
+ LIBRARY_ELEMENT4 -> ResolveTopLevelLibraryTypeBoundsTask
+ LIBRARY_ELEMENT4 -> ResolveTopLevelUnitTypeBoundsTask
LIBRARY_ELEMENT4 [shape=box]
- LIBRARY_ELEMENT5 -> PartiallyResolveUnitReferencesTask
- LIBRARY_ELEMENT5 -> PropagateVariableTypesInLibraryTask
- LIBRARY_ELEMENT5 -> ReadyLibraryElement5Task
- LIBRARY_ELEMENT5 -> ResolveInstanceFieldsInUnitTask
+ LIBRARY_ELEMENT5 -> ResolveLibraryTypeNamesTask
+ LIBRARY_ELEMENT5 -> ResolveTopLevelLibraryTypeBoundsTask
+ LIBRARY_ELEMENT5 -> ResolveUnitTypeNamesTask
LIBRARY_ELEMENT5 [shape=box]
- LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryClosureTask
- LIBRARY_ELEMENT6 -> ReadyLibraryElement6Task
+ LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
+ LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryTask
+ LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
+ LIBRARY_ELEMENT6 -> ResolveInstanceFieldsInUnitTask
LIBRARY_ELEMENT6 [shape=box]
- LIBRARY_ELEMENT7 -> ResolveLibraryReferencesTask
- LIBRARY_ELEMENT7 -> ResolveUnitTask
+ LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
+ LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
LIBRARY_ELEMENT7 [shape=box]
- LIBRARY_ELEMENT8 -> EvaluateUnitConstantsTask
- LIBRARY_ELEMENT8 -> ResolveLibraryTask
+ LIBRARY_ELEMENT8 -> ResolveLibraryReferencesTask
+ LIBRARY_ELEMENT8 -> ResolveUnitTask
LIBRARY_ELEMENT8 [shape=box]
+ LIBRARY_ELEMENT9 -> EvaluateUnitConstantsTask
+ LIBRARY_ELEMENT9 -> ResolveLibraryTask
+ LIBRARY_ELEMENT9 [shape=box]
LIBRARY_ERRORS_READY [shape=box]
LIBRARY_SPECIFIC_UNITS -> GenerateHintsTask
LIBRARY_SPECIFIC_UNITS -> PropagateVariableTypesInLibraryTask
LIBRARY_SPECIFIC_UNITS -> ReadyResolvedUnitTask
LIBRARY_SPECIFIC_UNITS -> ResolveLibraryReferencesTask
LIBRARY_SPECIFIC_UNITS -> ResolveLibraryTypeNamesTask
+ LIBRARY_SPECIFIC_UNITS -> ResolveTopLevelLibraryTypeBoundsTask
LIBRARY_SPECIFIC_UNITS [shape=box]
LIBRARY_UNIT_ERRORS -> dartErrorsForUnit
LIBRARY_UNIT_ERRORS [shape=box]
@@ -204,24 +212,24 @@
ParseDartTask -> REFERENCED_SOURCES
ParseDartTask -> SOURCE_KIND
ParseDartTask -> UNITS
- PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT6
+ PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT7
PartiallyResolveUnitReferencesTask -> INFERABLE_STATIC_VARIABLES_IN_UNIT
PartiallyResolveUnitReferencesTask -> PROPAGABLE_VARIABLES_IN_UNIT
- PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT6
+ PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT7
PropagateVariableTypeTask -> PROPAGATED_VARIABLE
- PropagateVariableTypesInLibraryClosureTask -> LIBRARY_ELEMENT7
- PropagateVariableTypesInLibraryTask -> LIBRARY_ELEMENT6
- PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT7
- PropagateVariableTypesInUnitTask -> RESOLVED_UNIT7
+ PropagateVariableTypesInLibraryClosureTask -> LIBRARY_ELEMENT8
+ PropagateVariableTypesInLibraryTask -> LIBRARY_ELEMENT7
+ PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
+ PropagateVariableTypesInUnitTask -> RESOLVED_UNIT8
READY_LIBRARY_ELEMENT2 -> ComputeLibraryCycleTask
READY_LIBRARY_ELEMENT2 -> ReadyLibraryElement2Task
READY_LIBRARY_ELEMENT2 [shape=box]
- READY_LIBRARY_ELEMENT5 -> PartiallyResolveUnitReferencesTask
- READY_LIBRARY_ELEMENT5 -> ReadyLibraryElement5Task
- READY_LIBRARY_ELEMENT5 [shape=box]
- READY_LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryClosureTask
- READY_LIBRARY_ELEMENT6 -> ReadyLibraryElement6Task
+ READY_LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
+ READY_LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
READY_LIBRARY_ELEMENT6 [shape=box]
+ READY_LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
+ READY_LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
+ READY_LIBRARY_ELEMENT7 [shape=box]
READY_RESOLVED_UNIT -> ResolveLibraryTask
READY_RESOLVED_UNIT -> VerifyUnitTask
READY_RESOLVED_UNIT [shape=box]
@@ -238,63 +246,72 @@
RESOLVED_UNIT1 -> BuildLibraryElementTask
RESOLVED_UNIT1 -> ResolveDirectiveElementsTask
RESOLVED_UNIT1 [shape=box]
- RESOLVED_UNIT10 -> ResolveUnitTask
+ RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
RESOLVED_UNIT10 [shape=box]
- RESOLVED_UNIT11 -> EvaluateUnitConstantsTask
- RESOLVED_UNIT11 -> GatherUsedImportedElementsTask
- RESOLVED_UNIT11 -> GatherUsedLocalElementsTask
- RESOLVED_UNIT11 -> ResolveLibraryReferencesTask
+ RESOLVED_UNIT11 -> ResolveUnitTask
RESOLVED_UNIT11 [shape=box]
- RESOLVED_UNIT12 -> StrongModeVerifyUnitTask
+ RESOLVED_UNIT12 -> EvaluateUnitConstantsTask
+ RESOLVED_UNIT12 -> GatherUsedImportedElementsTask
+ RESOLVED_UNIT12 -> GatherUsedLocalElementsTask
+ RESOLVED_UNIT12 -> ResolveLibraryReferencesTask
RESOLVED_UNIT12 [shape=box]
+ RESOLVED_UNIT13 -> StrongModeVerifyUnitTask
+ RESOLVED_UNIT13 [shape=box]
RESOLVED_UNIT2 -> BuildEnumMemberElementsTask
RESOLVED_UNIT2 [shape=box]
- RESOLVED_UNIT3 -> ResolveUnitTypeNamesTask
+ RESOLVED_UNIT3 -> ResolveTopLevelUnitTypeBoundsTask
RESOLVED_UNIT3 [shape=box]
- RESOLVED_UNIT4 -> ResolveLibraryTypeNamesTask
- RESOLVED_UNIT4 -> ResolveVariableReferencesTask
+ RESOLVED_UNIT4 -> ResolveTopLevelLibraryTypeBoundsTask
+ RESOLVED_UNIT4 -> ResolveUnitTypeNamesTask
RESOLVED_UNIT4 [shape=box]
- RESOLVED_UNIT5 -> PartiallyResolveUnitReferencesTask
+ RESOLVED_UNIT5 -> ResolveLibraryTypeNamesTask
+ RESOLVED_UNIT5 -> ResolveVariableReferencesTask
RESOLVED_UNIT5 [shape=box]
- RESOLVED_UNIT6 -> ComputeInferableStaticVariableDependenciesTask
- RESOLVED_UNIT6 -> ComputePropagableVariableDependenciesTask
- RESOLVED_UNIT6 -> PropagateVariableTypeTask
- RESOLVED_UNIT6 -> PropagateVariableTypesInUnitTask
+ RESOLVED_UNIT6 -> PartiallyResolveUnitReferencesTask
RESOLVED_UNIT6 [shape=box]
- RESOLVED_UNIT7 -> InferStaticVariableTypeTask
- RESOLVED_UNIT7 -> InferStaticVariableTypesInUnitTask
- RESOLVED_UNIT7 -> PropagateVariableTypesInLibraryTask
+ RESOLVED_UNIT7 -> ComputeInferableStaticVariableDependenciesTask
+ RESOLVED_UNIT7 -> ComputePropagableVariableDependenciesTask
+ RESOLVED_UNIT7 -> PropagateVariableTypeTask
+ RESOLVED_UNIT7 -> PropagateVariableTypesInUnitTask
RESOLVED_UNIT7 [shape=box]
- RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
+ RESOLVED_UNIT8 -> InferStaticVariableTypeTask
+ RESOLVED_UNIT8 -> InferStaticVariableTypesInUnitTask
+ RESOLVED_UNIT8 -> PropagateVariableTypesInLibraryTask
RESOLVED_UNIT8 [shape=box]
- RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
+ RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
RESOLVED_UNIT9 [shape=box]
+ RESOLVE_TYPE_BOUNDS_ERRORS -> LibraryUnitErrorsTask
+ RESOLVE_TYPE_BOUNDS_ERRORS [shape=box]
RESOLVE_TYPE_NAMES_ERRORS -> LibraryUnitErrorsTask
RESOLVE_TYPE_NAMES_ERRORS [shape=box]
RESOLVE_UNIT_ERRORS -> LibraryUnitErrorsTask
RESOLVE_UNIT_ERRORS [shape=box]
ReadyLibraryElement2Task -> READY_LIBRARY_ELEMENT2
- ReadyLibraryElement5Task -> READY_LIBRARY_ELEMENT5
- ReadyLibraryElement6Task -> READY_LIBRARY_ELEMENT6
+ ReadyLibraryElement5Task -> READY_LIBRARY_ELEMENT6
+ ReadyLibraryElement6Task -> READY_LIBRARY_ELEMENT7
ReadyResolvedUnitTask -> READY_RESOLVED_UNIT
ResolveConstantExpressionTask -> CONSTANT_EXPRESSION_RESOLVED
ResolveDirectiveElementsTask -> CREATED_RESOLVED_UNIT2
ResolveDirectiveElementsTask -> RESOLVED_UNIT2
- ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT9
- ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT9
- ResolveLibraryReferencesTask -> LIBRARY_ELEMENT8
+ ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT10
+ ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT10
+ ResolveLibraryReferencesTask -> LIBRARY_ELEMENT9
ResolveLibraryReferencesTask -> REFERENCED_NAMES
ResolveLibraryTask -> LIBRARY_ELEMENT
- ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT5
+ ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT6
+ ResolveTopLevelLibraryTypeBoundsTask -> LIBRARY_ELEMENT5
+ ResolveTopLevelUnitTypeBoundsTask -> CREATED_RESOLVED_UNIT4
+ ResolveTopLevelUnitTypeBoundsTask -> RESOLVED_UNIT4
+ ResolveTopLevelUnitTypeBoundsTask -> RESOLVE_TYPE_BOUNDS_ERRORS
ResolveUnitTask -> CONSTANT_EXPRESSIONS_DEPENDENCIES
- ResolveUnitTask -> CREATED_RESOLVED_UNIT11
- ResolveUnitTask -> RESOLVED_UNIT11
+ ResolveUnitTask -> CREATED_RESOLVED_UNIT12
+ ResolveUnitTask -> RESOLVED_UNIT12
ResolveUnitTask -> RESOLVE_UNIT_ERRORS
- ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT4
- ResolveUnitTypeNamesTask -> RESOLVED_UNIT4
+ ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT5
+ ResolveUnitTypeNamesTask -> RESOLVED_UNIT5
ResolveUnitTypeNamesTask -> RESOLVE_TYPE_NAMES_ERRORS
- ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT5
- ResolveVariableReferencesTask -> RESOLVED_UNIT5
+ ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT6
+ ResolveVariableReferencesTask -> RESOLVED_UNIT6
ResolveVariableReferencesTask -> VARIABLE_REFERENCE_ERRORS
SCAN_ERRORS -> dartErrorsForSource
SCAN_ERRORS [shape=box]
@@ -320,6 +337,7 @@
TYPE_PROVIDER -> PropagateVariableTypeTask
TYPE_PROVIDER -> ResolveInstanceFieldsInUnitTask
TYPE_PROVIDER -> ResolveLibraryTypeNamesTask
+ TYPE_PROVIDER -> ResolveTopLevelUnitTypeBoundsTask
TYPE_PROVIDER -> ResolveUnitTask
TYPE_PROVIDER -> ResolveUnitTypeNamesTask
TYPE_PROVIDER -> ResolveVariableReferencesTask
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 9e5bca2..89be5a5 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -125,12 +125,9 @@
* named constructor. The [arguments] can be `null` if the annotation is not
* referencing a constructor.
*/
- factory Annotation(
- Token atSign,
- Identifier name,
- Token period,
- SimpleIdentifier constructorName,
- ArgumentList arguments) = AnnotationImpl;
+ factory Annotation(Token atSign, Identifier name, Token period,
+ SimpleIdentifier constructorName, ArgumentList arguments) =>
+ new AnnotationImpl(atSign, name, period, constructorName, arguments);
/**
* Return the arguments to the constructor being invoked, or `null` if this
@@ -288,8 +285,9 @@
/**
* Initialize a newly created as expression.
*/
- factory AsExpression(Expression expression, Token asOperator, TypeName type) =
- AsExpressionImpl;
+ factory AsExpression(
+ Expression expression, Token asOperator, TypeName type) =>
+ new AsExpressionImpl(expression, asOperator, type);
/**
* Return the 'as' operator.
@@ -337,13 +335,15 @@
* be `null` if there is no message.
*/
factory AssertStatement(
- Token assertKeyword,
- Token leftParenthesis,
- Expression condition,
- Token comma,
- Expression message,
- Token rightParenthesis,
- Token semicolon) = AssertStatementImpl;
+ Token assertKeyword,
+ Token leftParenthesis,
+ Expression condition,
+ Token comma,
+ Expression message,
+ Token rightParenthesis,
+ Token semicolon) =>
+ new AssertStatementImpl(assertKeyword, leftParenthesis, condition, comma,
+ message, rightParenthesis, semicolon);
/**
* Return the token representing the 'assert' keyword.
@@ -433,8 +433,8 @@
* Initialize a newly created assignment expression.
*/
factory AssignmentExpression(
- Expression leftHandSide, Token operator, Expression rightHandSide) =
- AssignmentExpressionImpl;
+ Expression leftHandSide, Token operator, Expression rightHandSide) =>
+ new AssignmentExpressionImpl(leftHandSide, operator, rightHandSide);
/**
* Return the best element available for this operator. If resolution was able
@@ -862,8 +862,8 @@
/**
* Initialize a newly created await expression.
*/
- factory AwaitExpression(Token awaitKeyword, Expression expression) =
- AwaitExpressionImpl;
+ factory AwaitExpression(Token awaitKeyword, Expression expression) =>
+ new AwaitExpressionImpl(awaitKeyword, expression);
/**
* Return the 'await' keyword.
@@ -899,8 +899,8 @@
* Initialize a newly created binary expression.
*/
factory BinaryExpression(
- Expression leftOperand, Token operator, Expression rightOperand) =
- BinaryExpressionImpl;
+ Expression leftOperand, Token operator, Expression rightOperand) =>
+ new BinaryExpressionImpl(leftOperand, operator, rightOperand);
/**
* Return the best element available for this operator. If resolution was able
@@ -985,8 +985,8 @@
* Initialize a newly created block of code.
*/
factory Block(
- Token leftBracket, List<Statement> statements, Token rightBracket) =
- BlockImpl;
+ Token leftBracket, List<Statement> statements, Token rightBracket) =>
+ new BlockImpl(leftBracket, statements, rightBracket);
/**
* Return the left curly bracket.
@@ -1029,8 +1029,8 @@
* for the block. The [star] can be `null` if there is no star following the
* keyword (and must be `null` if there is no keyword).
*/
- factory BlockFunctionBody(Token keyword, Token star, Block block) =
- BlockFunctionBodyImpl;
+ factory BlockFunctionBody(Token keyword, Token star, Block block) =>
+ new BlockFunctionBodyImpl(keyword, star, block);
/**
* Return the block representing the body of the function.
@@ -1097,8 +1097,8 @@
* there is no label associated with the statement.
*/
factory BreakStatement(
- Token breakKeyword, SimpleIdentifier label, Token semicolon) =
- BreakStatementImpl;
+ Token breakKeyword, SimpleIdentifier label, Token semicolon) =>
+ new BreakStatementImpl(breakKeyword, label, semicolon);
/**
* Return the token representing the 'break' keyword.
@@ -1173,8 +1173,8 @@
* [cascadeSections] must contain at least one element.
*/
factory CascadeExpression(
- Expression target, List<Expression> cascadeSections) =
- CascadeExpressionImpl;
+ Expression target, List<Expression> cascadeSections) =>
+ new CascadeExpressionImpl(target, cascadeSections);
/**
* Return the cascade sections sharing the common target.
@@ -1212,15 +1212,25 @@
* parameter is not defined.
*/
factory CatchClause(
- Token onKeyword,
- TypeName exceptionType,
- Token catchKeyword,
- Token leftParenthesis,
- SimpleIdentifier exceptionParameter,
- Token comma,
- SimpleIdentifier stackTraceParameter,
- Token rightParenthesis,
- Block body) = CatchClauseImpl;
+ Token onKeyword,
+ TypeName exceptionType,
+ Token catchKeyword,
+ Token leftParenthesis,
+ SimpleIdentifier exceptionParameter,
+ Token comma,
+ SimpleIdentifier stackTraceParameter,
+ Token rightParenthesis,
+ Block body) =>
+ new CatchClauseImpl(
+ onKeyword,
+ exceptionType,
+ catchKeyword,
+ leftParenthesis,
+ exceptionParameter,
+ comma,
+ stackTraceParameter,
+ rightParenthesis,
+ body);
/**
* Return the body of the catch block.
@@ -1346,18 +1356,31 @@
* not have any members.
*/
factory ClassDeclaration(
- Comment comment,
- List<Annotation> metadata,
- Token abstractKeyword,
- Token classKeyword,
- SimpleIdentifier name,
- TypeParameterList typeParameters,
- ExtendsClause extendsClause,
- WithClause withClause,
- ImplementsClause implementsClause,
- Token leftBracket,
- List<ClassMember> members,
- Token rightBracket) = ClassDeclarationImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token abstractKeyword,
+ Token classKeyword,
+ SimpleIdentifier name,
+ TypeParameterList typeParameters,
+ ExtendsClause extendsClause,
+ WithClause withClause,
+ ImplementsClause implementsClause,
+ Token leftBracket,
+ List<ClassMember> members,
+ Token rightBracket) =>
+ new ClassDeclarationImpl(
+ comment,
+ metadata,
+ abstractKeyword,
+ classKeyword,
+ name,
+ typeParameters,
+ extendsClause,
+ withClause,
+ implementsClause,
+ leftBracket,
+ members,
+ rightBracket);
/**
* Return the 'abstract' keyword, or `null` if the keyword was absent.
@@ -1515,17 +1538,29 @@
* if the class does not implement any interfaces.
*/
factory ClassTypeAlias(
- Comment comment,
- List<Annotation> metadata,
- Token keyword,
- SimpleIdentifier name,
- TypeParameterList typeParameters,
- Token equals,
- Token abstractKeyword,
- TypeName superclass,
- WithClause withClause,
- ImplementsClause implementsClause,
- Token semicolon) = ClassTypeAliasImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token keyword,
+ SimpleIdentifier name,
+ TypeParameterList typeParameters,
+ Token equals,
+ Token abstractKeyword,
+ TypeName superclass,
+ WithClause withClause,
+ ImplementsClause implementsClause,
+ Token semicolon) =>
+ new ClassTypeAliasImpl(
+ comment,
+ metadata,
+ keyword,
+ name,
+ typeParameters,
+ equals,
+ abstractKeyword,
+ superclass,
+ withClause,
+ implementsClause,
+ semicolon);
/**
* Return the token for the 'abstract' keyword, or `null` if this is not
@@ -1716,8 +1751,8 @@
* Initialize a newly created reference to a Dart element. The [newKeyword]
* can be `null` if the reference is not to a constructor.
*/
- factory CommentReference(Token newKeyword, Identifier identifier) =
- CommentReferenceImpl;
+ factory CommentReference(Token newKeyword, Identifier identifier) =>
+ new CommentReferenceImpl(newKeyword, identifier);
/**
* Return the identifier being referenced.
@@ -1775,11 +1810,13 @@
* be `null` if there are no declarations in the compilation unit.
*/
factory CompilationUnit(
- Token beginToken,
- ScriptTag scriptTag,
- List<Directive> directives,
- List<CompilationUnitMember> declarations,
- Token endToken) = CompilationUnitImpl;
+ Token beginToken,
+ ScriptTag scriptTag,
+ List<Directive> directives,
+ List<CompilationUnitMember> declarations,
+ Token endToken) =>
+ new CompilationUnitImpl(
+ beginToken, scriptTag, directives, declarations, endToken);
/**
* Set the first token included in this node's source range to the given
@@ -1872,12 +1909,10 @@
/**
* Initialize a newly created conditional expression.
*/
- factory ConditionalExpression(
- Expression condition,
- Token question,
- Expression thenExpression,
- Token colon,
- Expression elseExpression) = ConditionalExpressionImpl;
+ factory ConditionalExpression(Expression condition, Token question,
+ Expression thenExpression, Token colon, Expression elseExpression) =>
+ new ConditionalExpressionImpl(
+ condition, question, thenExpression, colon, elseExpression);
/**
* Return the token used to separate the then expression from the else
@@ -1958,13 +1993,15 @@
* Initialize a newly created configuration.
*/
factory Configuration(
- Token ifKeyword,
- Token leftParenthesis,
- DottedName name,
- Token equalToken,
- StringLiteral value,
- Token rightParenthesis,
- StringLiteral libraryUri) = ConfigurationImpl;
+ Token ifKeyword,
+ Token leftParenthesis,
+ DottedName name,
+ Token equalToken,
+ StringLiteral value,
+ Token rightParenthesis,
+ StringLiteral libraryUri) =>
+ new ConfigurationImpl(ifKeyword, leftParenthesis, name, equalToken, value,
+ rightParenthesis, libraryUri);
/**
* Return the token for the equal operator, or `null` if the condition does
@@ -2084,19 +2121,33 @@
* the constructor does not have a body.
*/
factory ConstructorDeclaration(
- Comment comment,
- List<Annotation> metadata,
- Token externalKeyword,
- Token constKeyword,
- Token factoryKeyword,
- Identifier returnType,
- Token period,
- SimpleIdentifier name,
- FormalParameterList parameters,
- Token separator,
- List<ConstructorInitializer> initializers,
- ConstructorName redirectedConstructor,
- FunctionBody body) = ConstructorDeclarationImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token externalKeyword,
+ Token constKeyword,
+ Token factoryKeyword,
+ Identifier returnType,
+ Token period,
+ SimpleIdentifier name,
+ FormalParameterList parameters,
+ Token separator,
+ List<ConstructorInitializer> initializers,
+ ConstructorName redirectedConstructor,
+ FunctionBody body) =>
+ new ConstructorDeclarationImpl(
+ comment,
+ metadata,
+ externalKeyword,
+ constKeyword,
+ factoryKeyword,
+ returnType,
+ period,
+ name,
+ parameters,
+ separator,
+ initializers,
+ redirectedConstructor,
+ body);
/**
* Return the body of the constructor, or `null` if the constructor does not
@@ -2240,12 +2291,10 @@
* the given name to the value of the given expression. The [thisKeyword] and
* [period] can be `null` if the 'this' keyword was not specified.
*/
- factory ConstructorFieldInitializer(
- Token thisKeyword,
- Token period,
- SimpleIdentifier fieldName,
- Token equals,
- Expression expression) = ConstructorFieldInitializerImpl;
+ factory ConstructorFieldInitializer(Token thisKeyword, Token period,
+ SimpleIdentifier fieldName, Token equals, Expression expression) =>
+ new ConstructorFieldInitializerImpl(
+ thisKeyword, period, fieldName, equals, expression);
/**
* Return the token for the equal sign between the field name and the
@@ -2329,8 +2378,8 @@
* Initialize a newly created constructor name. The [period] and [name] can be
* `null` if the constructor being named is the unnamed constructor.
*/
- factory ConstructorName(TypeName type, Token period, SimpleIdentifier name) =
- ConstructorNameImpl;
+ factory ConstructorName(TypeName type, Token period, SimpleIdentifier name) =>
+ new ConstructorNameImpl(type, period, name);
/**
* Return the name of the constructor, or `null` if the specified constructor
@@ -2393,8 +2442,8 @@
* there is no label associated with the statement.
*/
factory ContinueStatement(
- Token continueKeyword, SimpleIdentifier label, Token semicolon) =
- ContinueStatementImpl;
+ Token continueKeyword, SimpleIdentifier label, Token semicolon) =>
+ new ContinueStatementImpl(continueKeyword, label, semicolon);
/**
* Return the token representing the 'continue' keyword.
@@ -2474,12 +2523,9 @@
* corresponding attribute. The [keyword] can be `null` if a type name is
* given. The [type] must be `null` if the keyword is 'var'.
*/
- factory DeclaredIdentifier(
- Comment comment,
- List<Annotation> metadata,
- Token keyword,
- TypeName type,
- SimpleIdentifier identifier) = DeclaredIdentifierImpl;
+ factory DeclaredIdentifier(Comment comment, List<Annotation> metadata,
+ Token keyword, TypeName type, SimpleIdentifier identifier) =>
+ new DeclaredIdentifierImpl(comment, metadata, keyword, type, identifier);
@override
LocalVariableElement get element;
@@ -2548,11 +2594,9 @@
* Initialize a newly created default formal parameter. The [separator] and
* [defaultValue] can be `null` if there is no default value.
*/
- factory DefaultFormalParameter(
- NormalFormalParameter parameter,
- ParameterKind kind,
- Token separator,
- Expression defaultValue) = DefaultFormalParameterImpl;
+ factory DefaultFormalParameter(NormalFormalParameter parameter,
+ ParameterKind kind, Token separator, Expression defaultValue) =>
+ new DefaultFormalParameterImpl(parameter, kind, separator, defaultValue);
/**
* Return the expression computing the default value for the parameter, or
@@ -2639,13 +2683,15 @@
* Initialize a newly created do loop.
*/
factory DoStatement(
- Token doKeyword,
- Statement body,
- Token whileKeyword,
- Token leftParenthesis,
- Expression condition,
- Token rightParenthesis,
- Token semicolon) = DoStatementImpl;
+ Token doKeyword,
+ Statement body,
+ Token whileKeyword,
+ Token leftParenthesis,
+ Expression condition,
+ Token rightParenthesis,
+ Token semicolon) =>
+ new DoStatementImpl(doKeyword, body, whileKeyword, leftParenthesis,
+ condition, rightParenthesis, semicolon);
/**
* Return the body of the loop.
@@ -2844,8 +2890,8 @@
* but we allow it for consistency.)
*/
factory EnumConstantDeclaration(
- Comment comment, List<Annotation> metadata, SimpleIdentifier name) =
- EnumConstantDeclarationImpl;
+ Comment comment, List<Annotation> metadata, SimpleIdentifier name) =>
+ new EnumConstantDeclarationImpl(comment, metadata, name);
/**
* Return the name of the constant.
@@ -2874,13 +2920,15 @@
* value.
*/
factory EnumDeclaration(
- Comment comment,
- List<Annotation> metadata,
- Token enumKeyword,
- SimpleIdentifier name,
- Token leftBracket,
- List<EnumConstantDeclaration> constants,
- Token rightBracket) = EnumDeclarationImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token enumKeyword,
+ SimpleIdentifier name,
+ Token leftBracket,
+ List<EnumConstantDeclaration> constants,
+ Token rightBracket) =>
+ new EnumDeclarationImpl(comment, metadata, enumKeyword, name, leftBracket,
+ constants, rightBracket);
/**
* Return the enumeration constants being declared.
@@ -2937,13 +2985,15 @@
* are no combinators.
*/
factory ExportDirective(
- Comment comment,
- List<Annotation> metadata,
- Token keyword,
- StringLiteral libraryUri,
- List<Configuration> configurations,
- List<Combinator> combinators,
- Token semicolon) = ExportDirectiveImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token keyword,
+ StringLiteral libraryUri,
+ List<Configuration> configurations,
+ List<Combinator> combinators,
+ Token semicolon) =>
+ new ExportDirectiveImpl(comment, metadata, keyword, libraryUri,
+ configurations, combinators, semicolon);
}
/**
@@ -3038,6 +3088,13 @@
* Set the static type of this expression to the given [type].
*/
void set staticType(DartType type);
+
+ /**
+ * If this expression is a parenthesized expression, return the result of
+ * unwrapping the expression inside the parentheses. Otherwise, return this
+ * expression.
+ */
+ Expression get unParenthesized;
}
/**
@@ -3055,7 +3112,9 @@
* async function body.
*/
factory ExpressionFunctionBody(Token keyword, Token functionDefinition,
- Expression expression, Token semicolon) = ExpressionFunctionBodyImpl;
+ Expression expression, Token semicolon) =>
+ new ExpressionFunctionBodyImpl(
+ keyword, functionDefinition, expression, semicolon);
/**
* Return the expression representing the body of the function.
@@ -3108,8 +3167,8 @@
/**
* Initialize a newly created expression statement.
*/
- factory ExpressionStatement(Expression expression, Token semicolon) =
- ExpressionStatementImpl;
+ factory ExpressionStatement(Expression expression, Token semicolon) =>
+ new ExpressionStatementImpl(expression, semicolon);
/**
* Return the expression that comprises the statement.
@@ -3145,8 +3204,8 @@
/**
* Initialize a newly created extends clause.
*/
- factory ExtendsClause(Token extendsKeyword, TypeName superclass) =
- ExtendsClauseImpl;
+ factory ExtendsClause(Token extendsKeyword, TypeName superclass) =>
+ new ExtendsClauseImpl(extendsKeyword, superclass);
/**
* Return the token representing the 'extends' keyword.
@@ -3185,11 +3244,13 @@
* not a static field.
*/
factory FieldDeclaration(
- Comment comment,
- List<Annotation> metadata,
- Token staticKeyword,
- VariableDeclarationList fieldList,
- Token semicolon) = FieldDeclarationImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token staticKeyword,
+ VariableDeclarationList fieldList,
+ Token semicolon) =>
+ new FieldDeclarationImpl(
+ comment, metadata, staticKeyword, fieldList, semicolon);
/**
* Return the fields being declared.
@@ -3248,15 +3309,17 @@
* parameter.
*/
factory FieldFormalParameter(
- Comment comment,
- List<Annotation> metadata,
- Token keyword,
- TypeName type,
- Token thisKeyword,
- Token period,
- SimpleIdentifier identifier,
- TypeParameterList typeParameters,
- FormalParameterList parameters) = FieldFormalParameterImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token keyword,
+ TypeName type,
+ Token thisKeyword,
+ Token period,
+ SimpleIdentifier identifier,
+ TypeParameterList typeParameters,
+ FormalParameterList parameters) =>
+ new FieldFormalParameterImpl(comment, metadata, keyword, type,
+ thisKeyword, period, identifier, typeParameters, parameters);
/**
* Return the token representing either the 'final', 'const' or 'var' keyword,
@@ -3344,14 +3407,23 @@
* `null` if this is not an asynchronous for loop.
*/
factory ForEachStatement.withDeclaration(
- Token awaitKeyword,
- Token forKeyword,
- Token leftParenthesis,
- DeclaredIdentifier loopVariable,
- Token inKeyword,
- Expression iterator,
- Token rightParenthesis,
- Statement body) = ForEachStatementImpl.withDeclaration;
+ Token awaitKeyword,
+ Token forKeyword,
+ Token leftParenthesis,
+ DeclaredIdentifier loopVariable,
+ Token inKeyword,
+ Expression iterator,
+ Token rightParenthesis,
+ Statement body) =>
+ new ForEachStatementImpl.withDeclaration(
+ awaitKeyword,
+ forKeyword,
+ leftParenthesis,
+ loopVariable,
+ inKeyword,
+ iterator,
+ rightParenthesis,
+ body);
/**
* Initialize a newly created for-each statement whose loop control variable
@@ -3359,14 +3431,23 @@
* is not an asynchronous for loop.
*/
factory ForEachStatement.withReference(
- Token awaitKeyword,
- Token forKeyword,
- Token leftParenthesis,
- SimpleIdentifier identifier,
- Token inKeyword,
- Expression iterator,
- Token rightParenthesis,
- Statement body) = ForEachStatementImpl.withReference;
+ Token awaitKeyword,
+ Token forKeyword,
+ Token leftParenthesis,
+ SimpleIdentifier identifier,
+ Token inKeyword,
+ Expression iterator,
+ Token rightParenthesis,
+ Statement body) =>
+ new ForEachStatementImpl.withReference(
+ awaitKeyword,
+ forKeyword,
+ leftParenthesis,
+ identifier,
+ inKeyword,
+ iterator,
+ rightParenthesis,
+ body);
/**
* Return the token representing the 'await' keyword, or `null` if there is no
@@ -3630,16 +3711,27 @@
* attribute.
*/
factory ForStatement(
- Token forKeyword,
- Token leftParenthesis,
- VariableDeclarationList variableList,
- Expression initialization,
- Token leftSeparator,
- Expression condition,
- Token rightSeparator,
- List<Expression> updaters,
- Token rightParenthesis,
- Statement body) = ForStatementImpl;
+ Token forKeyword,
+ Token leftParenthesis,
+ VariableDeclarationList variableList,
+ Expression initialization,
+ Token leftSeparator,
+ Expression condition,
+ Token rightSeparator,
+ List<Expression> updaters,
+ Token rightParenthesis,
+ Statement body) =>
+ new ForStatementImpl(
+ forKeyword,
+ leftParenthesis,
+ variableList,
+ initialization,
+ leftSeparator,
+ condition,
+ rightSeparator,
+ updaters,
+ rightParenthesis,
+ body);
/**
* Return the body of the loop.
@@ -3830,13 +3922,15 @@
* function is neither a getter or a setter.
*/
factory FunctionDeclaration(
- Comment comment,
- List<Annotation> metadata,
- Token externalKeyword,
- TypeName returnType,
- Token propertyKeyword,
- SimpleIdentifier name,
- FunctionExpression functionExpression) = FunctionDeclarationImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token externalKeyword,
+ TypeName returnType,
+ Token propertyKeyword,
+ SimpleIdentifier name,
+ FunctionExpression functionExpression) =>
+ new FunctionDeclarationImpl(comment, metadata, externalKeyword,
+ returnType, propertyKeyword, name, functionExpression);
@override
ExecutableElement get element;
@@ -3933,10 +4027,9 @@
/**
* Initialize a newly created function declaration.
*/
- factory FunctionExpression(
- TypeParameterList typeParameters,
- FormalParameterList parameters,
- FunctionBody body) = FunctionExpressionImpl;
+ factory FunctionExpression(TypeParameterList typeParameters,
+ FormalParameterList parameters, FunctionBody body) =>
+ new FunctionExpressionImpl(typeParameters, parameters, body);
/**
* Return the body of the function, or `null` if this is an external function.
@@ -3998,10 +4091,10 @@
/**
* Initialize a newly created function expression invocation.
*/
- factory FunctionExpressionInvocation(
- Expression function,
- TypeArgumentList typeArguments,
- ArgumentList argumentList) = FunctionExpressionInvocationImpl;
+ factory FunctionExpressionInvocation(Expression function,
+ TypeArgumentList typeArguments, ArgumentList argumentList) =>
+ new FunctionExpressionInvocationImpl(
+ function, typeArguments, argumentList);
/**
* Set the list of arguments to the method to the given [argumentList].
@@ -4120,14 +4213,16 @@
* type parameters.
*/
factory FunctionTypeAlias(
- Comment comment,
- List<Annotation> metadata,
- Token keyword,
- TypeName returnType,
- SimpleIdentifier name,
- TypeParameterList typeParameters,
- FormalParameterList parameters,
- Token semicolon) = FunctionTypeAliasImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token keyword,
+ TypeName returnType,
+ SimpleIdentifier name,
+ TypeParameterList typeParameters,
+ FormalParameterList parameters,
+ Token semicolon) =>
+ new FunctionTypeAliasImpl(comment, metadata, keyword, returnType, name,
+ typeParameters, parameters, semicolon);
/**
* Return the parameters associated with the function type.
@@ -4181,12 +4276,14 @@
* was specified.
*/
factory FunctionTypedFormalParameter(
- Comment comment,
- List<Annotation> metadata,
- TypeName returnType,
- SimpleIdentifier identifier,
- TypeParameterList typeParameters,
- FormalParameterList parameters) = FunctionTypedFormalParameterImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ TypeName returnType,
+ SimpleIdentifier identifier,
+ TypeParameterList typeParameters,
+ FormalParameterList parameters) =>
+ new FunctionTypedFormalParameterImpl(comment, metadata, returnType,
+ identifier, typeParameters, parameters);
/**
* Return the parameters of the function-typed parameter.
@@ -4308,13 +4405,15 @@
* [elseStatement] can be `null` if there is no else clause.
*/
factory IfStatement(
- Token ifKeyword,
- Token leftParenthesis,
- Expression condition,
- Token rightParenthesis,
- Statement thenStatement,
- Token elseKeyword,
- Statement elseStatement) = IfStatementImpl;
+ Token ifKeyword,
+ Token leftParenthesis,
+ Expression condition,
+ Token rightParenthesis,
+ Statement thenStatement,
+ Token elseKeyword,
+ Statement elseStatement) =>
+ new IfStatementImpl(ifKeyword, leftParenthesis, condition,
+ rightParenthesis, thenStatement, elseKeyword, elseStatement);
/**
* Return the condition used to determine which of the statements is executed
@@ -4460,8 +4559,8 @@
//
SimpleIdentifier prefix1 = import1.prefix;
SimpleIdentifier prefix2 = import2.prefix;
- String prefixStr1 = prefix1 != null ? prefix1.name : null;
- String prefixStr2 = prefix2 != null ? prefix2.name : null;
+ String prefixStr1 = prefix1?.name;
+ String prefixStr2 = prefix2?.name;
if (prefixStr1 != null || prefixStr2 != null) {
if (prefixStr1 == null) {
return -1;
@@ -4537,16 +4636,27 @@
* are no combinators.
*/
factory ImportDirective(
- Comment comment,
- List<Annotation> metadata,
- Token keyword,
- StringLiteral libraryUri,
- List<Configuration> configurations,
- Token deferredKeyword,
- Token asKeyword,
- SimpleIdentifier prefix,
- List<Combinator> combinators,
- Token semicolon) = ImportDirectiveImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token keyword,
+ StringLiteral libraryUri,
+ List<Configuration> configurations,
+ Token deferredKeyword,
+ Token asKeyword,
+ SimpleIdentifier prefix,
+ List<Combinator> combinators,
+ Token semicolon) =>
+ new ImportDirectiveImpl(
+ comment,
+ metadata,
+ keyword,
+ libraryUri,
+ configurations,
+ deferredKeyword,
+ asKeyword,
+ prefix,
+ combinators,
+ semicolon);
/**
* Return the token representing the 'as' keyword, or `null` if the imported
@@ -4595,13 +4705,17 @@
* Initialize a newly created index expression.
*/
factory IndexExpression.forCascade(Token period, Token leftBracket,
- Expression index, Token rightBracket) = IndexExpressionImpl.forCascade;
+ Expression index, Token rightBracket) =>
+ new IndexExpressionImpl.forCascade(
+ period, leftBracket, index, rightBracket);
/**
* Initialize a newly created index expression.
*/
factory IndexExpression.forTarget(Expression target, Token leftBracket,
- Expression index, Token rightBracket) = IndexExpressionImpl.forTarget;
+ Expression index, Token rightBracket) =>
+ new IndexExpressionImpl.forTarget(
+ target, leftBracket, index, rightBracket);
/**
* Return the auxiliary elements associated with this identifier, or `null` if
@@ -4758,10 +4872,10 @@
/**
* Initialize a newly created instance creation expression.
*/
- factory InstanceCreationExpression(
- Token keyword,
- ConstructorName constructorName,
- ArgumentList argumentList) = InstanceCreationExpressionImpl;
+ factory InstanceCreationExpression(Token keyword,
+ ConstructorName constructorName, ArgumentList argumentList) =>
+ new InstanceCreationExpressionImpl(
+ keyword, constructorName, argumentList);
/**
* Return the list of arguments to the constructor.
@@ -4883,8 +4997,8 @@
* Initialize a newly created interpolation expression.
*/
factory InterpolationExpression(
- Token leftBracket, Expression expression, Token rightBracket) =
- InterpolationExpressionImpl;
+ Token leftBracket, Expression expression, Token rightBracket) =>
+ new InterpolationExpressionImpl(leftBracket, expression, rightBracket);
/**
* Return the expression to be evaluated for the value to be converted into a
@@ -5052,7 +5166,8 @@
* if the sense of the test is not negated.
*/
factory IsExpression(Expression expression, Token isOperator,
- Token notOperator, TypeName type) = IsExpressionImpl;
+ Token notOperator, TypeName type) =>
+ new IsExpressionImpl(expression, isOperator, notOperator, type);
/**
* Return the expression used to compute the value whose type is being tested.
@@ -5108,7 +5223,8 @@
/**
* Initialize a newly created label.
*/
- factory Label(SimpleIdentifier label, Token colon) = LabelImpl;
+ factory Label(SimpleIdentifier label, Token colon) =>
+ new LabelImpl(label, colon);
/**
* Return the colon that separates the label from the statement.
@@ -5144,8 +5260,8 @@
/**
* Initialize a newly created labeled statement.
*/
- factory LabeledStatement(List<Label> labels, Statement statement) =
- LabeledStatementImpl;
+ factory LabeledStatement(List<Label> labels, Statement statement) =>
+ new LabeledStatementImpl(labels, statement);
/**
* Return the labels being associated with the statement.
@@ -5178,12 +5294,10 @@
* [comment] and [metadata] can be `null` if the directive does not have the
* corresponding attribute.
*/
- factory LibraryDirective(
- Comment comment,
- List<Annotation> metadata,
- Token libraryKeyword,
- LibraryIdentifier name,
- Token semicolon) = LibraryDirectiveImpl;
+ factory LibraryDirective(Comment comment, List<Annotation> metadata,
+ Token libraryKeyword, LibraryIdentifier name, Token semicolon) =>
+ new LibraryDirectiveImpl(
+ comment, metadata, libraryKeyword, name, semicolon);
/**
* Return the token representing the 'library' keyword.
@@ -5361,8 +5475,8 @@
/**
* Initialize a newly created map literal entry.
*/
- factory MapLiteralEntry(Expression key, Token separator, Expression value) =
- MapLiteralEntryImpl;
+ factory MapLiteralEntry(Expression key, Token separator, Expression value) =>
+ new MapLiteralEntryImpl(key, separator, value);
/**
* Return the expression computing the key with which the value will be
@@ -5428,17 +5542,29 @@
* this method declares a getter.
*/
factory MethodDeclaration(
- Comment comment,
- List<Annotation> metadata,
- Token externalKeyword,
- Token modifierKeyword,
- TypeName returnType,
- Token propertyKeyword,
- Token operatorKeyword,
- SimpleIdentifier name,
- TypeParameterList typeParameters,
- FormalParameterList parameters,
- FunctionBody body) = MethodDeclarationImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token externalKeyword,
+ Token modifierKeyword,
+ TypeName returnType,
+ Token propertyKeyword,
+ Token operatorKeyword,
+ SimpleIdentifier name,
+ TypeParameterList typeParameters,
+ FormalParameterList parameters,
+ FunctionBody body) =>
+ new MethodDeclarationImpl(
+ comment,
+ metadata,
+ externalKeyword,
+ modifierKeyword,
+ returnType,
+ propertyKeyword,
+ operatorKeyword,
+ name,
+ typeParameters,
+ parameters,
+ body);
/**
* Return the body of the method.
@@ -5586,11 +5712,13 @@
* can be `null` if there is no target.
*/
factory MethodInvocation(
- Expression target,
- Token operator,
- SimpleIdentifier methodName,
- TypeArgumentList typeArguments,
- ArgumentList argumentList) = MethodInvocationImpl;
+ Expression target,
+ Token operator,
+ SimpleIdentifier methodName,
+ TypeArgumentList typeArguments,
+ ArgumentList argumentList) =>
+ new MethodInvocationImpl(
+ target, operator, methodName, typeArguments, argumentList);
/**
* Set the list of arguments to the method to the given [argumentList].
@@ -5727,8 +5855,8 @@
/**
* Initialize a newly created named expression..
*/
- factory NamedExpression(Label name, Expression expression) =
- NamedExpressionImpl;
+ factory NamedExpression(Label name, Expression expression) =>
+ new NamedExpressionImpl(name, expression);
/**
* Return the element representing the parameter being named by this
@@ -5809,8 +5937,8 @@
/**
* Initialize a newly created native clause.
*/
- factory NativeClause(Token nativeKeyword, StringLiteral name) =
- NativeClauseImpl;
+ factory NativeClause(Token nativeKeyword, StringLiteral name) =>
+ new NativeClauseImpl(nativeKeyword, name);
/**
* Return the name of the native object that implements the class.
@@ -5849,8 +5977,8 @@
* a string literal, and a semicolon.
*/
factory NativeFunctionBody(
- Token nativeKeyword, StringLiteral stringLiteral, Token semicolon) =
- NativeFunctionBodyImpl;
+ Token nativeKeyword, StringLiteral stringLiteral, Token semicolon) =>
+ new NativeFunctionBodyImpl(nativeKeyword, stringLiteral, semicolon);
/**
* Return the token representing 'native' that marks the start of the function
@@ -6024,7 +6152,9 @@
* Initialize a newly created parenthesized expression.
*/
factory ParenthesizedExpression(Token leftParenthesis, Expression expression,
- Token rightParenthesis) = ParenthesizedExpressionImpl;
+ Token rightParenthesis) =>
+ new ParenthesizedExpressionImpl(
+ leftParenthesis, expression, rightParenthesis);
/**
* Return the expression within the parentheses.
@@ -6114,12 +6244,14 @@
* corresponding attribute.
*/
factory PartOfDirective(
- Comment comment,
- List<Annotation> metadata,
- Token partKeyword,
- Token ofKeyword,
- LibraryIdentifier libraryName,
- Token semicolon) = PartOfDirectiveImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ Token partKeyword,
+ Token ofKeyword,
+ LibraryIdentifier libraryName,
+ Token semicolon) =>
+ new PartOfDirectiveImpl(
+ comment, metadata, partKeyword, ofKeyword, libraryName, semicolon);
/**
* Return the name of the library that the containing compilation unit is part
@@ -6176,8 +6308,8 @@
/**
* Initialize a newly created postfix expression.
*/
- factory PostfixExpression(Expression operand, Token operator) =
- PostfixExpressionImpl;
+ factory PostfixExpression(Expression operand, Token operator) =>
+ new PostfixExpressionImpl(operand, operator);
/**
* Return the best element available for this operator. If resolution was able
@@ -6251,8 +6383,8 @@
* Initialize a newly created prefixed identifier.
*/
factory PrefixedIdentifier(
- SimpleIdentifier prefix, Token period, SimpleIdentifier identifier) =
- PrefixedIdentifierImpl;
+ SimpleIdentifier prefix, Token period, SimpleIdentifier identifier) =>
+ new PrefixedIdentifierImpl(prefix, period, identifier);
/**
* Return the identifier being prefixed.
@@ -6309,8 +6441,8 @@
/**
* Initialize a newly created prefix expression.
*/
- factory PrefixExpression(Token operator, Expression operand) =
- PrefixExpressionImpl;
+ factory PrefixExpression(Token operator, Expression operand) =>
+ new PrefixExpressionImpl(operator, operand);
/**
* Return the best element available for this operator. If resolution was able
@@ -6387,8 +6519,8 @@
* Initialize a newly created property access expression.
*/
factory PropertyAccess(
- Expression target, Token operator, SimpleIdentifier propertyName) =
- PropertyAccessImpl;
+ Expression target, Token operator, SimpleIdentifier propertyName) =>
+ new PropertyAccessImpl(target, operator, propertyName);
/**
* Return `true` if this expression is cascaded. If it is, then the target of
@@ -6456,11 +6588,10 @@
* with the given name with the given arguments. The [constructorName] can be
* `null` if the constructor being invoked is the unnamed constructor.
*/
- factory RedirectingConstructorInvocation(
- Token thisKeyword,
- Token period,
- SimpleIdentifier constructorName,
- ArgumentList argumentList) = RedirectingConstructorInvocationImpl;
+ factory RedirectingConstructorInvocation(Token thisKeyword, Token period,
+ SimpleIdentifier constructorName, ArgumentList argumentList) =>
+ new RedirectingConstructorInvocationImpl(
+ thisKeyword, period, constructorName, argumentList);
/**
* Return the list of arguments to the constructor.
@@ -6559,8 +6690,8 @@
* if no explicit value was provided.
*/
factory ReturnStatement(
- Token returnKeyword, Expression expression, Token semicolon) =
- ReturnStatementImpl;
+ Token returnKeyword, Expression expression, Token semicolon) =>
+ new ReturnStatementImpl(returnKeyword, expression, semicolon);
/**
* Return the expression computing the value to be returned, or `null` if no
@@ -6657,12 +6788,10 @@
* corresponding attribute. The [keyword] can be `null` if a type was
* specified. The [type] must be `null` if the keyword is 'var'.
*/
- factory SimpleFormalParameter(
- Comment comment,
- List<Annotation> metadata,
- Token keyword,
- TypeName type,
- SimpleIdentifier identifier) = SimpleFormalParameterImpl;
+ factory SimpleFormalParameter(Comment comment, List<Annotation> metadata,
+ Token keyword, TypeName type, SimpleIdentifier identifier) =>
+ new SimpleFormalParameterImpl(
+ comment, metadata, keyword, type, identifier);
/**
* Return the token representing either the 'final', 'const' or 'var' keyword,
@@ -6958,11 +7087,10 @@
* [constructorName] can be `null` if the constructor being invoked is the
* unnamed constructor.
*/
- factory SuperConstructorInvocation(
- Token superKeyword,
- Token period,
- SimpleIdentifier constructorName,
- ArgumentList argumentList) = SuperConstructorInvocationImpl;
+ factory SuperConstructorInvocation(Token superKeyword, Token period,
+ SimpleIdentifier constructorName, ArgumentList argumentList) =>
+ new SuperConstructorInvocationImpl(
+ superKeyword, period, constructorName, argumentList);
/**
* Return the list of arguments to the constructor.
@@ -7061,7 +7189,8 @@
* if there are no labels.
*/
factory SwitchCase(List<Label> labels, Token keyword, Expression expression,
- Token colon, List<Statement> statements) = SwitchCaseImpl;
+ Token colon, List<Statement> statements) =>
+ new SwitchCaseImpl(labels, keyword, expression, colon, statements);
/**
* Return the expression controlling whether the statements will be executed.
@@ -7151,13 +7280,15 @@
* `null` if there are no switch members.
*/
factory SwitchStatement(
- Token switchKeyword,
- Token leftParenthesis,
- Expression expression,
- Token rightParenthesis,
- Token leftBracket,
- List<SwitchMember> members,
- Token rightBracket) = SwitchStatementImpl;
+ Token switchKeyword,
+ Token leftParenthesis,
+ Expression expression,
+ Token rightParenthesis,
+ Token leftBracket,
+ List<SwitchMember> members,
+ Token rightBracket) =>
+ new SwitchStatementImpl(switchKeyword, leftParenthesis, expression,
+ rightParenthesis, leftBracket, members, rightBracket);
/**
* Return the expression used to determine which of the switch members will be
@@ -7295,8 +7426,8 @@
/**
* Initialize a newly created throw expression.
*/
- factory ThrowExpression(Token throwKeyword, Expression expression) =
- ThrowExpressionImpl;
+ factory ThrowExpression(Token throwKeyword, Expression expression) =>
+ new ThrowExpressionImpl(throwKeyword, expression);
/**
* Return the expression computing the exception to be thrown.
@@ -7336,10 +7467,12 @@
* the corresponding attribute.
*/
factory TopLevelVariableDeclaration(
- Comment comment,
- List<Annotation> metadata,
- VariableDeclarationList variableList,
- Token semicolon) = TopLevelVariableDeclarationImpl;
+ Comment comment,
+ List<Annotation> metadata,
+ VariableDeclarationList variableList,
+ Token semicolon) =>
+ new TopLevelVariableDeclarationImpl(
+ comment, metadata, variableList, semicolon);
/**
* Return the semicolon terminating the declaration.
@@ -7381,11 +7514,13 @@
* [finallyBlock] can be `null` if there is no finally clause.
*/
factory TryStatement(
- Token tryKeyword,
- Block body,
- List<CatchClause> catchClauses,
- Token finallyKeyword,
- Block finallyBlock) = TryStatementImpl;
+ Token tryKeyword,
+ Block body,
+ List<CatchClause> catchClauses,
+ Token finallyKeyword,
+ Block finallyBlock) =>
+ new TryStatementImpl(
+ tryKeyword, body, catchClauses, finallyKeyword, finallyBlock);
/**
* Return the body of the statement.
@@ -7558,8 +7693,8 @@
* Initialize a newly created type name. The [typeArguments] can be `null` if
* there are no type arguments.
*/
- factory TypeName(Identifier name, TypeArgumentList typeArguments) =
- TypeNameImpl;
+ factory TypeName(Identifier name, TypeArgumentList typeArguments) =>
+ new TypeNameImpl(name, typeArguments);
/**
* Return `true` if this type is a deferred type.
@@ -7618,12 +7753,9 @@
* corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
* the parameter does not have an upper bound.
*/
- factory TypeParameter(
- Comment comment,
- List<Annotation> metadata,
- SimpleIdentifier name,
- Token extendsKeyword,
- TypeName bound) = TypeParameterImpl;
+ factory TypeParameter(Comment comment, List<Annotation> metadata,
+ SimpleIdentifier name, Token extendsKeyword, TypeName bound) =>
+ new TypeParameterImpl(comment, metadata, name, extendsKeyword, bound);
/**
* Return the name of the upper bound for legal arguments, or `null` if there
@@ -7784,8 +7916,8 @@
* [initializer] can be `null` if there is no initializer.
*/
factory VariableDeclaration(
- SimpleIdentifier name, Token equals, Expression initializer) =
- VariableDeclarationImpl;
+ SimpleIdentifier name, Token equals, Expression initializer) =>
+ new VariableDeclarationImpl(name, equals, initializer);
@override
VariableElement get element;
@@ -7858,12 +7990,10 @@
* the corresponding attribute. The [keyword] can be `null` if a type was
* specified. The [type] must be `null` if the keyword is 'var'.
*/
- factory VariableDeclarationList(
- Comment comment,
- List<Annotation> metadata,
- Token keyword,
- TypeName type,
- List<VariableDeclaration> variables) = VariableDeclarationListImpl;
+ factory VariableDeclarationList(Comment comment, List<Annotation> metadata,
+ Token keyword, TypeName type, List<VariableDeclaration> variables) =>
+ new VariableDeclarationListImpl(
+ comment, metadata, keyword, type, variables);
/**
* Return `true` if the variables in this list were declared with the 'const'
@@ -7922,8 +8052,8 @@
* Initialize a newly created variable declaration statement.
*/
factory VariableDeclarationStatement(
- VariableDeclarationList variableList, Token semicolon) =
- VariableDeclarationStatementImpl;
+ VariableDeclarationList variableList, Token semicolon) =>
+ new VariableDeclarationStatementImpl(variableList, semicolon);
/**
* Return the semicolon terminating the statement.
@@ -7958,12 +8088,10 @@
/**
* Initialize a newly created while statement.
*/
- factory WhileStatement(
- Token whileKeyword,
- Token leftParenthesis,
- Expression condition,
- Token rightParenthesis,
- Statement body) = WhileStatementImpl;
+ factory WhileStatement(Token whileKeyword, Token leftParenthesis,
+ Expression condition, Token rightParenthesis, Statement body) =>
+ new WhileStatementImpl(
+ whileKeyword, leftParenthesis, condition, rightParenthesis, body);
/**
* Return the body of the loop.
@@ -8063,7 +8191,8 @@
* star was provided.
*/
factory YieldStatement(Token yieldKeyword, Token star, Expression expression,
- Token semicolon) = YieldStatementImpl;
+ Token semicolon) =>
+ new YieldStatementImpl(yieldKeyword, star, expression, semicolon);
/**
* Return the expression whose value will be yielded.
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index ba2bf4b..b841a36 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -218,7 +218,7 @@
Resource resource =
_provider.getResource(_provider.pathContext.fromUri(uri));
if (resource is File) {
- return resource.createSource(actualUri != null ? actualUri : uri);
+ return resource.createSource(actualUri ?? uri);
}
return null;
}
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 5035b93..3ec640e 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -188,7 +188,7 @@
_MemoryFile file = new _MemoryFile(this, path);
_pathToResource[path] = file;
_pathToContent[path] = content;
- _pathToTimestamp[path] = stamp != null ? stamp : nextStamp++;
+ _pathToTimestamp[path] = stamp ?? nextStamp++;
_notifyWatchers(path, ChangeType.MODIFY);
return file;
}
diff --git a/pkg/analyzer/lib/plugin/resolver_provider.dart b/pkg/analyzer/lib/plugin/resolver_provider.dart
index ed0e366..33bb366 100644
--- a/pkg/analyzer/lib/plugin/resolver_provider.dart
+++ b/pkg/analyzer/lib/plugin/resolver_provider.dart
@@ -11,8 +11,5 @@
* A function that will return a [UriResolver] that can be used to resolve a
* specific kind of URI within the analysis context rooted at the given
* [folder].
- *
- * The given [folder] may be `null` if analysis is performed in an environment
- * where URI resolution is always the same in any folder.
*/
typedef UriResolver ResolverProvider(Folder folder);
diff --git a/pkg/analyzer/lib/source/analysis_options_provider.dart b/pkg/analyzer/lib/source/analysis_options_provider.dart
index 600dffc..3b6e330 100644
--- a/pkg/analyzer/lib/source/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/source/analysis_options_provider.dart
@@ -73,7 +73,7 @@
throw new OptionsFormatException(
'Bad options file format (expected String scope key, '
'got ${k.runtimeType})',
- k != null ? k.span : doc.span);
+ (k ?? doc).span);
}
if (v != null && v is! YamlNode) {
throw new OptionsFormatException(
diff --git a/pkg/analyzer/lib/source/config.dart b/pkg/analyzer/lib/source/config.dart
new file mode 100644
index 0000000..376c189
--- /dev/null
+++ b/pkg/analyzer/lib/source/config.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:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/task/model.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:package_config/packages.dart';
+import 'package:yaml/src/yaml_node.dart';
+import 'package:yaml/yaml.dart';
+
+/// The descriptor used to associate analysis configuration with analysis
+/// contexts in configuration data.
+final ResultDescriptor<AnalysisConfiguration> ANALYSIS_CONFIGURATION =
+ new ResultDescriptorImpl('analysis.config', null);
+
+/// Return configuration associated with this [context], or `null` if there is
+/// none.
+AnalysisConfiguration getConfiguration(AnalysisContext context) =>
+ context.getConfigurationData(ANALYSIS_CONFIGURATION)
+ as AnalysisConfiguration;
+
+/// Associate this [config] with the given [context].
+void setConfiguration(AnalysisContext context, AnalysisConfiguration config) {
+ context.setConfigurationData(ANALYSIS_CONFIGURATION, config);
+}
+
+/// Analysis configuration.
+abstract class AnalysisConfiguration {
+ final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
+ final Packages packages;
+ final ResourceProvider resourceProvider;
+ AnalysisConfiguration(this.resourceProvider, this.packages);
+
+ factory AnalysisConfiguration.fromPubspec(
+ File pubspec, ResourceProvider resourceProvider, Packages packages) =>
+ new PubspecConfiguration(pubspec, resourceProvider, packages);
+
+ /// Get a map of options defined by this configuration (or `null` if none
+ /// are specified).
+ Map get options;
+}
+
+/// Describes an analysis configuration.
+class AnalysisConfigurationDescriptor {
+ /// The name of the package hosting the configuration.
+ String package;
+ /// The name of the configuration "pragma".
+ String pragma;
+
+ AnalysisConfigurationDescriptor.fromAnalyzerOptions(Map analyzerOptions) {
+ Object config = analyzerOptions['configuration'];
+ if (config is String) {
+ List<String> items = config.split('/');
+ if (items.length == 2) {
+ package = items[0].trim();
+ pragma = items[1].trim();
+ }
+ }
+ }
+
+ /// Return true if this descriptor is valid.
+ bool get isValid => package != null && pragma != null;
+}
+
+/// Pubspec-specified analysis configuration.
+class PubspecConfiguration extends AnalysisConfiguration {
+ final File pubspec;
+ PubspecConfiguration(
+ this.pubspec, ResourceProvider resourceProvider, Packages packages)
+ : super(resourceProvider, packages);
+
+ @override
+ Map get options {
+ //Safest not to cache (requested infrequently).
+ if (pubspec.exists) {
+ try {
+ String contents = pubspec.readAsStringSync();
+ YamlNode map = loadYamlNode(contents);
+ if (map is YamlMap) {
+ YamlNode config = map['analyzer'];
+ if (config is YamlMap) {
+ AnalysisConfigurationDescriptor descriptor =
+ new AnalysisConfigurationDescriptor.fromAnalyzerOptions(config);
+
+ if (descriptor.isValid) {
+ //Create a path, given descriptor and packagemap
+ Uri uri = packages.asMap()[descriptor.package];
+ Uri pragma = new Uri.file('config/${descriptor.pragma}.yaml',
+ windows: false);
+ Uri optionsUri = uri.resolveUri(pragma);
+ File file = resourceProvider.getFile(optionsUri.toFilePath());
+ if (file.exists) {
+ return optionsProvider.getOptionsFromFile(file);
+ }
+ }
+ }
+ }
+ } catch (_) {
+ // Skip exceptional configurations.
+ }
+ }
+ return null;
+ }
+}
diff --git a/pkg/analyzer/lib/source/path_filter.dart b/pkg/analyzer/lib/source/path_filter.dart
index 816bc55..c207014 100644
--- a/pkg/analyzer/lib/source/path_filter.dart
+++ b/pkg/analyzer/lib/source/path_filter.dart
@@ -22,7 +22,7 @@
/// Construct a new path filter rooted at [root] with [ignorePatterns].
/// If [pathContext] is not specified, then the system path context is used.
PathFilter(this.root, List<String> ignorePatterns, [path.Context pathContext])
- : this.pathContext = pathContext != null ? pathContext : path.context {
+ : this.pathContext = pathContext ?? path.context {
setIgnorePatterns(ignorePatterns);
}
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 7e6e0a0..c5641a9 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -514,7 +514,7 @@
ResultData data = getResultData(descriptor);
_setDependedOnResults(data, thisResult, dependedOn);
data.state = CacheState.VALID;
- data.value = value == null ? descriptor.defaultValue : value;
+ data.value = value ?? descriptor.defaultValue;
}
/**
@@ -922,7 +922,7 @@
*/
List<Source> getSourcesWithFullName(String path) {
List<Source> sources = pathToSource[path];
- return sources != null ? sources : Source.EMPTY_LIST;
+ return sources ?? Source.EMPTY_LIST;
}
/**
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 7815864..7540c0f 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -843,10 +843,8 @@
}
@override
- InternalAnalysisContext getContextFor(Source source) {
- InternalAnalysisContext context = _cache.getContextFor(source);
- return context == null ? this : context;
- }
+ InternalAnalysisContext getContextFor(Source source) =>
+ _cache.getContextFor(source) ?? this;
@override
Element getElement(ElementLocation location) {
@@ -1205,10 +1203,12 @@
setValue(LIBRARY_ELEMENT6, library);
setValue(LIBRARY_ELEMENT7, library);
setValue(LIBRARY_ELEMENT8, library);
+ setValue(LIBRARY_ELEMENT9, library);
setValue(LINE_INFO, new LineInfo(<int>[0]));
setValue(PARSE_ERRORS, AnalysisError.NO_ERRORS);
entry.setState(PARSED_UNIT, CacheState.FLUSHED);
entry.setState(RESOLVE_TYPE_NAMES_ERRORS, CacheState.FLUSHED);
+ entry.setState(RESOLVE_TYPE_BOUNDS_ERRORS, CacheState.FLUSHED);
setValue(SCAN_ERRORS, AnalysisError.NO_ERRORS);
setValue(SOURCE_KIND, SourceKind.LIBRARY);
entry.setState(TOKEN_STREAM, CacheState.FLUSHED);
@@ -1235,6 +1235,7 @@
entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
+ entry.setState(RESOLVED_UNIT13, CacheState.FLUSHED);
// USED_IMPORTED_ELEMENTS
// USED_LOCAL_ELEMENTS
setValue(STRONG_MODE_ERRORS, AnalysisError.NO_ERRORS);
@@ -1314,6 +1315,7 @@
entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
+ entry.setState(RESOLVED_UNIT13, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
}
@@ -1549,12 +1551,12 @@
new LibrarySpecificUnit(librarySource, unitSource);
for (ResultDescriptor result in [
RESOLVED_UNIT,
+ RESOLVED_UNIT13,
RESOLVED_UNIT12,
RESOLVED_UNIT11,
RESOLVED_UNIT10,
RESOLVED_UNIT9,
- RESOLVED_UNIT8,
- RESOLVED_UNIT7
+ RESOLVED_UNIT8
]) {
CompilationUnit unit = getResult(target, result);
if (unit != null) {
@@ -1790,6 +1792,7 @@
entry.explicitlyAdded = true;
entry.modificationTime = getModificationStamp(source);
entry.setState(CONTENT, CacheState.INVALID);
+ entry.setState(MODIFICATION_TIME, CacheState.INVALID);
}
}
diff --git a/pkg/analyzer/lib/src/context/source.dart b/pkg/analyzer/lib/src/context/source.dart
index 3a22291..32792df 100644
--- a/pkg/analyzer/lib/src/context/source.dart
+++ b/pkg/analyzer/lib/src/context/source.dart
@@ -53,9 +53,8 @@
*/
SourceFactoryImpl(this.resolvers,
[this._packages, ResourceProvider resourceProvider])
- : _resourceProvider = resourceProvider != null
- ? resourceProvider
- : PhysicalResourceProvider.INSTANCE;
+ : _resourceProvider =
+ resourceProvider ?? PhysicalResourceProvider.INSTANCE;
/**
* Return the [DartSdk] associated with this [SourceFactory], or `null` if
@@ -105,7 +104,7 @@
// Default to the PackageMapUriResolver.
PackageMapUriResolver resolver = resolvers
.firstWhere((r) => r is PackageMapUriResolver, orElse: () => null);
- return resolver != null ? resolver.packageMap : null;
+ return resolver?.packageMap;
}
/**
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 2825ef5..ad6c9c8 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -43,7 +43,7 @@
* valid, the list of [strings] must contain at least two elements.
*/
AdjacentStringsImpl(List<StringLiteral> strings) {
- _strings = new NodeList<StringLiteral>(this, strings);
+ _strings = new NodeListImpl<StringLiteral>(this, strings);
}
@override
@@ -96,9 +96,9 @@
* and [metadata] can be `null` if the node does not have the corresponding
* attribute.
*/
- AnnotatedNodeImpl(Comment comment, List<Annotation> metadata) {
+ AnnotatedNodeImpl(CommentImpl comment, List<Annotation> metadata) {
_comment = _becomeParentOf(comment);
- _metadata = new NodeList<Annotation>(this, metadata);
+ _metadata = new NodeListImpl<Annotation>(this, metadata);
}
@override
@@ -124,7 +124,7 @@
@override
void set documentationComment(Comment comment) {
- _comment = _becomeParentOf(comment);
+ _comment = _becomeParentOf(comment as AstNodeImpl);
}
@override
@@ -238,8 +238,8 @@
* named constructor. The [arguments] can be `null` if the annotation is not
* referencing a constructor.
*/
- AnnotationImpl(this.atSign, Identifier name, this.period,
- SimpleIdentifier constructorName, ArgumentList arguments) {
+ AnnotationImpl(this.atSign, IdentifierImpl name, this.period,
+ SimpleIdentifierImpl constructorName, ArgumentListImpl arguments) {
_name = _becomeParentOf(name);
_constructorName = _becomeParentOf(constructorName);
_arguments = _becomeParentOf(arguments);
@@ -250,7 +250,7 @@
@override
void set arguments(ArgumentList arguments) {
- _arguments = _becomeParentOf(arguments);
+ _arguments = _becomeParentOf(arguments as AstNodeImpl);
}
@override
@@ -269,7 +269,7 @@
@override
void set constructorName(SimpleIdentifier name) {
- _constructorName = _becomeParentOf(name);
+ _constructorName = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -302,7 +302,7 @@
@override
void set name(Identifier name) {
- _name = _becomeParentOf(name);
+ _name = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -372,7 +372,7 @@
*/
ArgumentListImpl(
this.leftParenthesis, List<Expression> arguments, this.rightParenthesis) {
- _arguments = new NodeList<Expression>(this, arguments);
+ _arguments = new NodeListImpl<Expression>(this, arguments);
}
@override
@@ -499,7 +499,8 @@
/**
* Initialize a newly created as expression.
*/
- AsExpressionImpl(Expression expression, this.asOperator, TypeName type) {
+ AsExpressionImpl(
+ ExpressionImpl expression, this.asOperator, TypeNameImpl type) {
_expression = _becomeParentOf(expression);
_type = _becomeParentOf(type);
}
@@ -519,7 +520,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -530,7 +531,7 @@
@override
void set type(TypeName name) {
- _type = _becomeParentOf(name);
+ _type = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -598,9 +599,9 @@
AssertStatementImpl(
this.assertKeyword,
this.leftParenthesis,
- Expression condition,
+ ExpressionImpl condition,
this.comma,
- Expression message,
+ ExpressionImpl message,
this.rightParenthesis,
this.semicolon) {
_condition = _becomeParentOf(condition);
@@ -625,7 +626,7 @@
@override
void set condition(Expression condition) {
- _condition = _becomeParentOf(condition);
+ _condition = _becomeParentOf(condition as AstNodeImpl);
}
@override
@@ -636,7 +637,7 @@
@override
void set message(Expression expression) {
- _message = _becomeParentOf(expression);
+ _message = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -695,8 +696,8 @@
/**
* Initialize a newly created assignment expression.
*/
- AssignmentExpressionImpl(
- Expression leftHandSide, this.operator, Expression rightHandSide) {
+ AssignmentExpressionImpl(ExpressionImpl leftHandSide, this.operator,
+ ExpressionImpl rightHandSide) {
if (leftHandSide == null || rightHandSide == null) {
String message;
if (leftHandSide == null) {
@@ -741,7 +742,7 @@
@override
void set leftHandSide(Expression expression) {
- _leftHandSide = _becomeParentOf(expression);
+ _leftHandSide = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -752,7 +753,7 @@
@override
void set rightHandSide(Expression expression) {
- _rightHandSide = _becomeParentOf(expression);
+ _rightHandSide = _becomeParentOf(expression as AstNodeImpl);
}
/**
@@ -937,9 +938,9 @@
/**
* Make this node the parent of the given [child] node. Return the child node.
*/
- AstNode _becomeParentOf(AstNode child) {
+ AstNode _becomeParentOf(AstNodeImpl child) {
if (child != null) {
- (child as AstNodeImpl)._parent = this;
+ child._parent = this;
}
return child;
}
@@ -966,7 +967,7 @@
/**
* Initialize a newly created await expression.
*/
- AwaitExpressionImpl(this.awaitKeyword, Expression expression) {
+ AwaitExpressionImpl(this.awaitKeyword, ExpressionImpl expression) {
_expression = _becomeParentOf(expression);
}
@@ -990,7 +991,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -1050,7 +1051,7 @@
* Initialize a newly created binary expression.
*/
BinaryExpressionImpl(
- Expression leftOperand, this.operator, Expression rightOperand) {
+ ExpressionImpl leftOperand, this.operator, ExpressionImpl rightOperand) {
_leftOperand = _becomeParentOf(leftOperand);
_rightOperand = _becomeParentOf(rightOperand);
}
@@ -1079,7 +1080,7 @@
@override
void set leftOperand(Expression expression) {
- _leftOperand = _becomeParentOf(expression);
+ _leftOperand = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -1090,7 +1091,7 @@
@override
void set rightOperand(Expression expression) {
- _rightOperand = _becomeParentOf(expression);
+ _rightOperand = _becomeParentOf(expression as AstNodeImpl);
}
/**
@@ -1171,7 +1172,7 @@
* for the block. The [star] can be `null` if there is no star following the
* keyword (and must be `null` if there is no keyword).
*/
- BlockFunctionBodyImpl(this.keyword, this.star, Block block) {
+ BlockFunctionBodyImpl(this.keyword, this.star, BlockImpl block) {
_block = _becomeParentOf(block);
}
@@ -1188,7 +1189,7 @@
@override
void set block(Block block) {
- _block = _becomeParentOf(block);
+ _block = _becomeParentOf(block as AstNodeImpl);
}
@override
@@ -1245,7 +1246,7 @@
* Initialize a newly created block of code.
*/
BlockImpl(this.leftBracket, List<Statement> statements, this.rightBracket) {
- _statements = new NodeList<Statement>(this, statements);
+ _statements = new NodeListImpl<Statement>(this, statements);
}
@override
@@ -1360,7 +1361,7 @@
* there is no label associated with the statement.
*/
BreakStatementImpl(
- this.breakKeyword, SimpleIdentifier label, this.semicolon) {
+ this.breakKeyword, SimpleIdentifierImpl label, this.semicolon) {
_label = _becomeParentOf(label);
}
@@ -1379,7 +1380,7 @@
@override
void set label(SimpleIdentifier identifier) {
- _label = _becomeParentOf(identifier);
+ _label = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -1424,9 +1425,10 @@
* Initialize a newly created cascade expression. The list of
* [cascadeSections] must contain at least one element.
*/
- CascadeExpressionImpl(Expression target, List<Expression> cascadeSections) {
+ CascadeExpressionImpl(
+ ExpressionImpl target, List<Expression> cascadeSections) {
_target = _becomeParentOf(target);
- _cascadeSections = new NodeList<Expression>(this, cascadeSections);
+ _cascadeSections = new NodeListImpl<Expression>(this, cascadeSections);
}
@override
@@ -1451,7 +1453,7 @@
@override
void set target(Expression target) {
- _target = _becomeParentOf(target);
+ _target = _becomeParentOf(target as AstNodeImpl);
}
@override
@@ -1540,14 +1542,14 @@
*/
CatchClauseImpl(
this.onKeyword,
- TypeName exceptionType,
+ TypeNameImpl exceptionType,
this.catchKeyword,
this.leftParenthesis,
- SimpleIdentifier exceptionParameter,
+ SimpleIdentifierImpl exceptionParameter,
this.comma,
- SimpleIdentifier stackTraceParameter,
+ SimpleIdentifierImpl stackTraceParameter,
this.rightParenthesis,
- Block body) {
+ BlockImpl body) {
_exceptionType = _becomeParentOf(exceptionType);
_exceptionParameter = _becomeParentOf(exceptionParameter);
_stackTraceParameter = _becomeParentOf(stackTraceParameter);
@@ -1567,7 +1569,7 @@
@override
void set body(Block block) {
- _body = _becomeParentOf(block);
+ _body = _becomeParentOf(block as AstNodeImpl);
}
@override
@@ -1590,7 +1592,7 @@
@override
void set exceptionParameter(SimpleIdentifier parameter) {
- _exceptionParameter = _becomeParentOf(parameter);
+ _exceptionParameter = _becomeParentOf(parameter as AstNodeImpl);
}
@override
@@ -1598,7 +1600,7 @@
@override
void set exceptionType(TypeName exceptionType) {
- _exceptionType = _becomeParentOf(exceptionType);
+ _exceptionType = _becomeParentOf(exceptionType as AstNodeImpl);
}
@override
@@ -1606,7 +1608,7 @@
@override
void set stackTraceParameter(SimpleIdentifier parameter) {
- _stackTraceParameter = _becomeParentOf(parameter);
+ _stackTraceParameter = _becomeParentOf(parameter as AstNodeImpl);
}
@override
@@ -1739,11 +1741,11 @@
List<Annotation> metadata,
this.abstractKeyword,
this.classKeyword,
- SimpleIdentifier name,
- TypeParameterList typeParameters,
- ExtendsClause extendsClause,
- WithClause withClause,
- ImplementsClause implementsClause,
+ SimpleIdentifierImpl name,
+ TypeParameterListImpl typeParameters,
+ ExtendsClauseImpl extendsClause,
+ WithClauseImpl withClause,
+ ImplementsClauseImpl implementsClause,
this.leftBracket,
List<ClassMember> members,
this.rightBracket)
@@ -1752,7 +1754,7 @@
_extendsClause = _becomeParentOf(extendsClause);
_withClause = _becomeParentOf(withClause);
_implementsClause = _becomeParentOf(implementsClause);
- _members = new NodeList<ClassMember>(this, members);
+ _members = new NodeListImpl<ClassMember>(this, members);
}
@override
@@ -1770,8 +1772,7 @@
..add(rightBracket);
@override
- ClassElement get element =>
- _name != null ? (_name.staticElement as ClassElement) : null;
+ ClassElement get element => _name?.staticElement as ClassElement;
@override
Token get endToken => rightBracket;
@@ -1781,7 +1782,7 @@
@override
void set extendsClause(ExtendsClause extendsClause) {
- _extendsClause = _becomeParentOf(extendsClause);
+ _extendsClause = _becomeParentOf(extendsClause as AstNodeImpl);
}
@override
@@ -1797,7 +1798,7 @@
@override
void set implementsClause(ImplementsClause implementsClause) {
- _implementsClause = _becomeParentOf(implementsClause);
+ _implementsClause = _becomeParentOf(implementsClause as AstNodeImpl);
}
@override
@@ -1811,7 +1812,7 @@
@override
void set nativeClause(NativeClause nativeClause) {
- _nativeClause = _becomeParentOf(nativeClause);
+ _nativeClause = _becomeParentOf(nativeClause as AstNodeImpl);
}
@override
@@ -1819,7 +1820,7 @@
@override
void set typeParameters(TypeParameterList typeParameters) {
- _typeParameters = _becomeParentOf(typeParameters);
+ _typeParameters = _becomeParentOf(typeParameters as AstNodeImpl);
}
@override
@@ -1827,7 +1828,7 @@
@override
void set withClause(WithClause withClause) {
- _withClause = _becomeParentOf(withClause);
+ _withClause = _becomeParentOf(withClause as AstNodeImpl);
}
@override
@@ -1963,16 +1964,16 @@
* if the class does not implement any interfaces.
*/
ClassTypeAliasImpl(
- Comment comment,
+ CommentImpl comment,
List<Annotation> metadata,
Token keyword,
- SimpleIdentifier name,
- TypeParameterList typeParameters,
+ SimpleIdentifierImpl name,
+ TypeParameterListImpl typeParameters,
this.equals,
this.abstractKeyword,
- TypeName superclass,
- WithClause withClause,
- ImplementsClause implementsClause,
+ TypeNameImpl superclass,
+ WithClauseImpl withClause,
+ ImplementsClauseImpl implementsClause,
Token semicolon)
: super(comment, metadata, keyword, name, semicolon) {
_typeParameters = _becomeParentOf(typeParameters);
@@ -1994,8 +1995,7 @@
..add(semicolon);
@override
- ClassElement get element =>
- _name != null ? (_name.staticElement as ClassElement) : null;
+ ClassElement get element => _name?.staticElement as ClassElement;
@override
Token get firstTokenAfterCommentAndMetadata {
@@ -2010,7 +2010,7 @@
@override
void set implementsClause(ImplementsClause implementsClause) {
- _implementsClause = _becomeParentOf(implementsClause);
+ _implementsClause = _becomeParentOf(implementsClause as AstNodeImpl);
}
@override
@@ -2021,7 +2021,7 @@
@override
void set superclass(TypeName superclass) {
- _superclass = _becomeParentOf(superclass);
+ _superclass = _becomeParentOf(superclass as AstNodeImpl);
}
@override
@@ -2029,7 +2029,7 @@
@override
void set typeParameters(TypeParameterList typeParameters) {
- _typeParameters = _becomeParentOf(typeParameters);
+ _typeParameters = _becomeParentOf(typeParameters as AstNodeImpl);
}
@override
@@ -2037,7 +2037,7 @@
@override
void set withClause(WithClause withClause) {
- _withClause = _becomeParentOf(withClause);
+ _withClause = _becomeParentOf(withClause as AstNodeImpl);
}
@override
@@ -2123,7 +2123,7 @@
* references.
*/
CommentImpl(this.tokens, this._type, List<CommentReference> references) {
- _references = new NodeList<CommentReference>(this, references);
+ _references = new NodeListImpl<CommentReference>(this, references);
}
@override
@@ -2207,7 +2207,7 @@
* Initialize a newly created reference to a Dart element. The [newKeyword]
* can be `null` if the reference is not to a constructor.
*/
- CommentReferenceImpl(this.newKeyword, Identifier identifier) {
+ CommentReferenceImpl(this.newKeyword, IdentifierImpl identifier) {
_identifier = _becomeParentOf(identifier);
}
@@ -2226,7 +2226,7 @@
@override
void set identifier(Identifier identifier) {
- _identifier = _becomeParentOf(identifier);
+ _identifier = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -2348,13 +2348,13 @@
*/
CompilationUnitImpl(
this.beginToken,
- ScriptTag scriptTag,
+ ScriptTagImpl scriptTag,
List<Directive> directives,
List<CompilationUnitMember> declarations,
this.endToken) {
_scriptTag = _becomeParentOf(scriptTag);
- _directives = new NodeList<Directive>(this, directives);
- _declarations = new NodeList<CompilationUnitMember>(this, declarations);
+ _directives = new NodeListImpl<Directive>(this, directives);
+ _declarations = new NodeListImpl<CompilationUnitMember>(this, declarations);
}
@override
@@ -2391,7 +2391,7 @@
@override
void set scriptTag(ScriptTag scriptTag) {
- _scriptTag = _becomeParentOf(scriptTag);
+ _scriptTag = _becomeParentOf(scriptTag as AstNodeImpl);
}
@override
@@ -2494,8 +2494,12 @@
/**
* Initialize a newly created conditional expression.
*/
- ConditionalExpressionImpl(Expression condition, this.question,
- Expression thenExpression, this.colon, Expression elseExpression) {
+ ConditionalExpressionImpl(
+ ExpressionImpl condition,
+ this.question,
+ ExpressionImpl thenExpression,
+ this.colon,
+ ExpressionImpl elseExpression) {
_condition = _becomeParentOf(condition);
_thenExpression = _becomeParentOf(thenExpression);
_elseExpression = _becomeParentOf(elseExpression);
@@ -2517,7 +2521,7 @@
@override
void set condition(Expression expression) {
- _condition = _becomeParentOf(expression);
+ _condition = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -2525,7 +2529,7 @@
@override
void set elseExpression(Expression expression) {
- _elseExpression = _becomeParentOf(expression);
+ _elseExpression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -2539,7 +2543,7 @@
@override
void set thenExpression(Expression expression) {
- _thenExpression = _becomeParentOf(expression);
+ _thenExpression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -2582,11 +2586,11 @@
ConfigurationImpl(
this.ifKeyword,
this.leftParenthesis,
- DottedName name,
+ DottedNameImpl name,
this.equalToken,
- StringLiteral value,
+ StringLiteralImpl value,
this.rightParenthesis,
- StringLiteral libraryUri) {
+ StringLiteralImpl libraryUri) {
_name = _becomeParentOf(name);
_value = _becomeParentOf(value);
_libraryUri = _becomeParentOf(libraryUri);
@@ -2613,7 +2617,7 @@
@override
void set libraryUri(StringLiteral libraryUri) {
- _libraryUri = _becomeParentOf(libraryUri);
+ _libraryUri = _becomeParentOf(libraryUri as AstNodeImpl);
}
@override
@@ -2621,7 +2625,7 @@
@override
void set name(DottedName name) {
- _name = _becomeParentOf(name);
+ _name = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -2629,7 +2633,7 @@
@override
void set value(StringLiteral value) {
- _value = _becomeParentOf(value);
+ _value = _becomeParentOf(value as AstNodeImpl);
}
@override
@@ -2761,24 +2765,25 @@
* the constructor does not have a body.
*/
ConstructorDeclarationImpl(
- Comment comment,
+ CommentImpl comment,
List<Annotation> metadata,
this.externalKeyword,
this.constKeyword,
this.factoryKeyword,
- Identifier returnType,
+ IdentifierImpl returnType,
this.period,
- SimpleIdentifier name,
- FormalParameterList parameters,
+ SimpleIdentifierImpl name,
+ FormalParameterListImpl parameters,
this.separator,
List<ConstructorInitializer> initializers,
- ConstructorName redirectedConstructor,
- FunctionBody body)
+ ConstructorNameImpl redirectedConstructor,
+ FunctionBodyImpl body)
: super(comment, metadata) {
_returnType = _becomeParentOf(returnType);
_name = _becomeParentOf(name);
_parameters = _becomeParentOf(parameters);
- _initializers = new NodeList<ConstructorInitializer>(this, initializers);
+ _initializers =
+ new NodeListImpl<ConstructorInitializer>(this, initializers);
_redirectedConstructor = _becomeParentOf(redirectedConstructor);
_body = _becomeParentOf(body);
}
@@ -2788,7 +2793,7 @@
@override
void set body(FunctionBody functionBody) {
- _body = _becomeParentOf(functionBody);
+ _body = _becomeParentOf(functionBody as AstNodeImpl);
}
@override
@@ -2833,7 +2838,7 @@
@override
void set name(SimpleIdentifier identifier) {
- _name = _becomeParentOf(identifier);
+ _name = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -2841,7 +2846,7 @@
@override
void set parameters(FormalParameterList parameters) {
- _parameters = _becomeParentOf(parameters);
+ _parameters = _becomeParentOf(parameters as AstNodeImpl);
}
@override
@@ -2849,7 +2854,8 @@
@override
void set redirectedConstructor(ConstructorName redirectedConstructor) {
- _redirectedConstructor = _becomeParentOf(redirectedConstructor);
+ _redirectedConstructor =
+ _becomeParentOf(redirectedConstructor as AstNodeImpl);
}
@override
@@ -2857,7 +2863,7 @@
@override
void set returnType(Identifier typeName) {
- _returnType = _becomeParentOf(typeName);
+ _returnType = _becomeParentOf(typeName as AstNodeImpl);
}
@override
@@ -2919,7 +2925,7 @@
* [period] can be `null` if the 'this' keyword was not specified.
*/
ConstructorFieldInitializerImpl(this.thisKeyword, this.period,
- SimpleIdentifier fieldName, this.equals, Expression expression) {
+ SimpleIdentifierImpl fieldName, this.equals, ExpressionImpl expression) {
_fieldName = _becomeParentOf(fieldName);
_expression = _becomeParentOf(expression);
}
@@ -2948,7 +2954,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -2956,7 +2962,7 @@
@override
void set fieldName(SimpleIdentifier identifier) {
- _fieldName = _becomeParentOf(identifier);
+ _fieldName = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -3018,7 +3024,8 @@
* Initialize a newly created constructor name. The [period] and [name] can be
* `null` if the constructor being named is the unnamed constructor.
*/
- ConstructorNameImpl(TypeName type, this.period, SimpleIdentifier name) {
+ ConstructorNameImpl(
+ TypeNameImpl type, this.period, SimpleIdentifierImpl name) {
_type = _becomeParentOf(type);
_name = _becomeParentOf(name);
}
@@ -3043,7 +3050,7 @@
@override
void set name(SimpleIdentifier name) {
- _name = _becomeParentOf(name);
+ _name = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -3051,7 +3058,7 @@
@override
void set type(TypeName type) {
- _type = _becomeParentOf(type);
+ _type = _becomeParentOf(type as AstNodeImpl);
}
@override
@@ -3104,7 +3111,7 @@
* there is no label associated with the statement.
*/
ContinueStatementImpl(
- this.continueKeyword, SimpleIdentifier label, this.semicolon) {
+ this.continueKeyword, SimpleIdentifierImpl label, this.semicolon) {
_label = _becomeParentOf(label);
}
@@ -3123,7 +3130,7 @@
@override
void set label(SimpleIdentifier identifier) {
- _label = _becomeParentOf(identifier);
+ _label = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -3183,8 +3190,8 @@
* corresponding attribute. The [keyword] can be `null` if a type name is
* given. The [type] must be `null` if the keyword is 'var'.
*/
- DeclaredIdentifierImpl(Comment comment, List<Annotation> metadata,
- this.keyword, TypeName type, SimpleIdentifier identifier)
+ DeclaredIdentifierImpl(CommentImpl comment, List<Annotation> metadata,
+ this.keyword, TypeNameImpl type, SimpleIdentifierImpl identifier)
: super(comment, metadata) {
_type = _becomeParentOf(type);
_identifier = _becomeParentOf(identifier);
@@ -3220,7 +3227,7 @@
@override
void set identifier(SimpleIdentifier identifier) {
- _identifier = _becomeParentOf(identifier);
+ _identifier = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -3234,7 +3241,7 @@
@override
void set type(TypeName typeName) {
- _type = _becomeParentOf(typeName);
+ _type = _becomeParentOf(typeName as AstNodeImpl);
}
@override
@@ -3308,8 +3315,8 @@
* Initialize a newly created default formal parameter. The [separator] and
* [defaultValue] can be `null` if there is no default value.
*/
- DefaultFormalParameterImpl(NormalFormalParameter parameter, this.kind,
- this.separator, Expression defaultValue) {
+ DefaultFormalParameterImpl(NormalFormalParameterImpl parameter, this.kind,
+ this.separator, ExpressionImpl defaultValue) {
_parameter = _becomeParentOf(parameter);
_defaultValue = _becomeParentOf(defaultValue);
}
@@ -3326,7 +3333,7 @@
@override
void set defaultValue(Expression expression) {
- _defaultValue = _becomeParentOf(expression);
+ _defaultValue = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -3354,7 +3361,7 @@
@override
void set parameter(NormalFormalParameter formalParameter) {
- _parameter = _becomeParentOf(formalParameter);
+ _parameter = _becomeParentOf(formalParameter as AstNodeImpl);
}
@override
@@ -3455,10 +3462,10 @@
*/
DoStatementImpl(
this.doKeyword,
- Statement body,
+ StatementImpl body,
this.whileKeyword,
this.leftParenthesis,
- Expression condition,
+ ExpressionImpl condition,
this.rightParenthesis,
this.semicolon) {
_body = _becomeParentOf(body);
@@ -3473,7 +3480,7 @@
@override
void set body(Statement statement) {
- _body = _becomeParentOf(statement);
+ _body = _becomeParentOf(statement as AstNodeImpl);
}
@override
@@ -3491,7 +3498,7 @@
@override
void set condition(Expression expression) {
- _condition = _becomeParentOf(expression);
+ _condition = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -3524,7 +3531,7 @@
* Initialize a newly created dotted name.
*/
DottedNameImpl(List<SimpleIdentifier> components) {
- _components = new NodeList<SimpleIdentifier>(this, components);
+ _components = new NodeListImpl<SimpleIdentifier>(this, components);
}
@override
@@ -3690,7 +3697,7 @@
* but we allow it for consistency.)
*/
EnumConstantDeclarationImpl(
- Comment comment, List<Annotation> metadata, SimpleIdentifier name)
+ CommentImpl comment, List<Annotation> metadata, SimpleIdentifierImpl name)
: super(comment, metadata) {
_name = _becomeParentOf(name);
}
@@ -3699,8 +3706,7 @@
Iterable get childEntities => super._childEntities..add(_name);
@override
- FieldElement get element =>
- _name == null ? null : (_name.staticElement as FieldElement);
+ FieldElement get element => _name?.staticElement as FieldElement;
@override
Token get endToken => _name.endToken;
@@ -3713,7 +3719,7 @@
@override
void set name(SimpleIdentifier name) {
- _name = _becomeParentOf(name);
+ _name = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -3773,7 +3779,7 @@
List<EnumConstantDeclaration> constants,
this.rightBracket)
: super(comment, metadata, name) {
- _constants = new NodeList<EnumConstantDeclaration>(this, constants);
+ _constants = new NodeListImpl<EnumConstantDeclaration>(this, constants);
}
@override
@@ -3789,8 +3795,7 @@
NodeList<EnumConstantDeclaration> get constants => _constants;
@override
- ClassElement get element =>
- _name != null ? (_name.staticElement as ClassElement) : null;
+ ClassElement get element => _name?.staticElement as ClassElement;
@override
Token get endToken => rightBracket;
@@ -3913,7 +3918,7 @@
* async function body.
*/
ExpressionFunctionBodyImpl(this.keyword, this.functionDefinition,
- Expression expression, this.semicolon) {
+ ExpressionImpl expression, this.semicolon) {
_expression = _becomeParentOf(expression);
}
@@ -3945,7 +3950,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -4063,6 +4068,9 @@
}
return null;
}
+
+ @override
+ Expression get unParenthesized => this;
}
/**
@@ -4088,7 +4096,7 @@
/**
* Initialize a newly created expression statement.
*/
- ExpressionStatementImpl(Expression expression, this.semicolon) {
+ ExpressionStatementImpl(ExpressionImpl expression, this.semicolon) {
_expression = _becomeParentOf(expression);
}
@@ -4112,7 +4120,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -4149,7 +4157,7 @@
/**
* Initialize a newly created extends clause.
*/
- ExtendsClauseImpl(this.extendsKeyword, TypeName superclass) {
+ ExtendsClauseImpl(this.extendsKeyword, TypeNameImpl superclass) {
_superclass = _becomeParentOf(superclass);
}
@@ -4168,7 +4176,7 @@
@override
void set superclass(TypeName name) {
- _superclass = _becomeParentOf(name);
+ _superclass = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -4212,8 +4220,8 @@
* corresponding attribute. The [staticKeyword] can be `null` if the field is
* not a static field.
*/
- FieldDeclarationImpl(Comment comment, List<Annotation> metadata,
- this.staticKeyword, VariableDeclarationList fieldList, this.semicolon)
+ FieldDeclarationImpl(CommentImpl comment, List<Annotation> metadata,
+ this.staticKeyword, VariableDeclarationListImpl fieldList, this.semicolon)
: super(comment, metadata) {
_fieldList = _becomeParentOf(fieldList);
}
@@ -4233,7 +4241,7 @@
@override
void set fields(VariableDeclarationList fields) {
- _fieldList = _becomeParentOf(fields);
+ _fieldList = _becomeParentOf(fields as AstNodeImpl);
}
@override
@@ -4314,15 +4322,15 @@
* parameter.
*/
FieldFormalParameterImpl(
- Comment comment,
+ CommentImpl comment,
List<Annotation> metadata,
this.keyword,
- TypeName type,
+ TypeNameImpl type,
this.thisKeyword,
this.period,
- SimpleIdentifier identifier,
- TypeParameterList typeParameters,
- FormalParameterList parameters)
+ SimpleIdentifierImpl identifier,
+ TypeParameterListImpl typeParameters,
+ FormalParameterListImpl parameters)
: super(comment, metadata, identifier) {
_type = _becomeParentOf(type);
_typeParameters = _becomeParentOf(typeParameters);
@@ -4367,7 +4375,7 @@
@override
void set parameters(FormalParameterList parameters) {
- _parameters = _becomeParentOf(parameters);
+ _parameters = _becomeParentOf(parameters as AstNodeImpl);
}
@override
@@ -4375,7 +4383,7 @@
@override
void set type(TypeName typeName) {
- _type = _becomeParentOf(typeName);
+ _type = _becomeParentOf(typeName as AstNodeImpl);
}
@override
@@ -4383,7 +4391,7 @@
@override
void set typeParameters(TypeParameterList typeParameters) {
- _typeParameters = _becomeParentOf(typeParameters);
+ _typeParameters = _becomeParentOf(typeParameters as AstNodeImpl);
}
@override
@@ -4469,11 +4477,11 @@
this.awaitKeyword,
this.forKeyword,
this.leftParenthesis,
- DeclaredIdentifier loopVariable,
+ DeclaredIdentifierImpl loopVariable,
this.inKeyword,
- Expression iterator,
+ ExpressionImpl iterator,
this.rightParenthesis,
- Statement body) {
+ StatementImpl body) {
_loopVariable = _becomeParentOf(loopVariable);
_iterable = _becomeParentOf(iterator);
_body = _becomeParentOf(body);
@@ -4488,11 +4496,11 @@
this.awaitKeyword,
this.forKeyword,
this.leftParenthesis,
- SimpleIdentifier identifier,
+ SimpleIdentifierImpl identifier,
this.inKeyword,
- Expression iterator,
+ ExpressionImpl iterator,
this.rightParenthesis,
- Statement body) {
+ StatementImpl body) {
_identifier = _becomeParentOf(identifier);
_iterable = _becomeParentOf(iterator);
_body = _becomeParentOf(body);
@@ -4506,7 +4514,7 @@
@override
void set body(Statement statement) {
- _body = _becomeParentOf(statement);
+ _body = _becomeParentOf(statement as AstNodeImpl);
}
@override
@@ -4529,7 +4537,7 @@
@override
void set identifier(SimpleIdentifier identifier) {
- _identifier = _becomeParentOf(identifier);
+ _identifier = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -4537,7 +4545,7 @@
@override
void set iterable(Expression expression) {
- _iterable = _becomeParentOf(expression);
+ _iterable = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -4545,7 +4553,7 @@
@override
void set loopVariable(DeclaredIdentifier variable) {
- _loopVariable = _becomeParentOf(variable);
+ _loopVariable = _becomeParentOf(variable as AstNodeImpl);
}
@override
@@ -4652,7 +4660,7 @@
this.leftDelimiter,
this.rightDelimiter,
this.rightParenthesis) {
- _parameters = new NodeList<FormalParameter>(this, parameters);
+ _parameters = new NodeListImpl<FormalParameter>(this, parameters);
}
@override
@@ -4782,18 +4790,18 @@
ForStatementImpl(
this.forKeyword,
this.leftParenthesis,
- VariableDeclarationList variableList,
- Expression initialization,
+ VariableDeclarationListImpl variableList,
+ ExpressionImpl initialization,
this.leftSeparator,
- Expression condition,
+ ExpressionImpl condition,
this.rightSeparator,
List<Expression> updaters,
this.rightParenthesis,
- Statement body) {
+ StatementImpl body) {
_variableList = _becomeParentOf(variableList);
_initialization = _becomeParentOf(initialization);
_condition = _becomeParentOf(condition);
- _updaters = new NodeList<Expression>(this, updaters);
+ _updaters = new NodeListImpl<Expression>(this, updaters);
_body = _becomeParentOf(body);
}
@@ -4805,7 +4813,7 @@
@override
void set body(Statement statement) {
- _body = _becomeParentOf(statement);
+ _body = _becomeParentOf(statement as AstNodeImpl);
}
@override
@@ -4826,7 +4834,7 @@
@override
void set condition(Expression expression) {
- _condition = _becomeParentOf(expression);
+ _condition = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -4837,7 +4845,7 @@
@override
void set initialization(Expression initialization) {
- _initialization = _becomeParentOf(initialization);
+ _initialization = _becomeParentOf(initialization as AstNodeImpl);
}
@override
@@ -4848,7 +4856,7 @@
@override
void set variables(VariableDeclarationList variableList) {
- _variableList = _becomeParentOf(variableList);
+ _variableList = _becomeParentOf(variableList as AstNodeImpl);
}
@override
@@ -4975,13 +4983,13 @@
* function is neither a getter or a setter.
*/
FunctionDeclarationImpl(
- Comment comment,
+ CommentImpl comment,
List<Annotation> metadata,
this.externalKeyword,
- TypeName returnType,
+ TypeNameImpl returnType,
this.propertyKeyword,
- SimpleIdentifier name,
- FunctionExpression functionExpression)
+ SimpleIdentifierImpl name,
+ FunctionExpressionImpl functionExpression)
: super(comment, metadata, name) {
_returnType = _becomeParentOf(returnType);
_functionExpression = _becomeParentOf(functionExpression);
@@ -4996,8 +5004,7 @@
..add(_functionExpression);
@override
- ExecutableElement get element =>
- _name != null ? (_name.staticElement as ExecutableElement) : null;
+ ExecutableElement get element => _name?.staticElement as ExecutableElement;
@override
Token get endToken => _functionExpression.endToken;
@@ -5021,7 +5028,7 @@
@override
void set functionExpression(FunctionExpression functionExpression) {
- _functionExpression = _becomeParentOf(functionExpression);
+ _functionExpression = _becomeParentOf(functionExpression as AstNodeImpl);
}
@override
@@ -5035,7 +5042,7 @@
@override
void set returnType(TypeName returnType) {
- _returnType = _becomeParentOf(returnType);
+ _returnType = _becomeParentOf(returnType as AstNodeImpl);
}
@override
@@ -5065,7 +5072,7 @@
* Initialize a newly created function declaration statement.
*/
FunctionDeclarationStatementImpl(FunctionDeclaration functionDeclaration) {
- _functionDeclaration = _becomeParentOf(functionDeclaration);
+ _functionDeclaration = _becomeParentOf(functionDeclaration as AstNodeImpl);
}
@override
@@ -5082,7 +5089,7 @@
@override
void set functionDeclaration(FunctionDeclaration functionDeclaration) {
- _functionDeclaration = _becomeParentOf(functionDeclaration);
+ _functionDeclaration = _becomeParentOf(functionDeclaration as AstNodeImpl);
}
@override
@@ -5129,8 +5136,8 @@
/**
* Initialize a newly created function declaration.
*/
- FunctionExpressionImpl(TypeParameterList typeParameters,
- FormalParameterList parameters, FunctionBody body) {
+ FunctionExpressionImpl(TypeParameterListImpl typeParameters,
+ FormalParameterListImpl parameters, FunctionBodyImpl body) {
_typeParameters = _becomeParentOf(typeParameters);
_parameters = _becomeParentOf(parameters);
_body = _becomeParentOf(body);
@@ -5155,7 +5162,7 @@
@override
void set body(FunctionBody functionBody) {
- _body = _becomeParentOf(functionBody);
+ _body = _becomeParentOf(functionBody as AstNodeImpl);
}
@override
@@ -5179,7 +5186,7 @@
@override
void set parameters(FormalParameterList parameters) {
- _parameters = _becomeParentOf(parameters);
+ _parameters = _becomeParentOf(parameters as AstNodeImpl);
}
@override
@@ -5190,7 +5197,7 @@
@override
void set typeParameters(TypeParameterList typeParameters) {
- _typeParameters = _becomeParentOf(typeParameters);
+ _typeParameters = _becomeParentOf(typeParameters as AstNodeImpl);
}
@override
@@ -5240,8 +5247,8 @@
/**
* Initialize a newly created function expression invocation.
*/
- FunctionExpressionInvocationImpl(Expression function,
- TypeArgumentList typeArguments, ArgumentList argumentList)
+ FunctionExpressionInvocationImpl(ExpressionImpl function,
+ TypeArgumentListImpl typeArguments, ArgumentListImpl argumentList)
: super(typeArguments, argumentList) {
_function = _becomeParentOf(function);
}
@@ -5270,7 +5277,7 @@
@override
void set function(Expression expression) {
- _function = _becomeParentOf(expression);
+ _function = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -5323,13 +5330,13 @@
* type parameters.
*/
FunctionTypeAliasImpl(
- Comment comment,
+ CommentImpl comment,
List<Annotation> metadata,
Token keyword,
- TypeName returnType,
- SimpleIdentifier name,
- TypeParameterList typeParameters,
- FormalParameterList parameters,
+ TypeNameImpl returnType,
+ SimpleIdentifierImpl name,
+ TypeParameterListImpl typeParameters,
+ FormalParameterListImpl parameters,
Token semicolon)
: super(comment, metadata, keyword, name, semicolon) {
_returnType = _becomeParentOf(returnType);
@@ -5348,14 +5355,14 @@
@override
FunctionTypeAliasElement get element =>
- _name != null ? (_name.staticElement as FunctionTypeAliasElement) : null;
+ _name?.staticElement as FunctionTypeAliasElement;
@override
FormalParameterList get parameters => _parameters;
@override
void set parameters(FormalParameterList parameters) {
- _parameters = _becomeParentOf(parameters);
+ _parameters = _becomeParentOf(parameters as AstNodeImpl);
}
@override
@@ -5363,7 +5370,7 @@
@override
void set returnType(TypeName typeName) {
- _returnType = _becomeParentOf(typeName);
+ _returnType = _becomeParentOf(typeName as AstNodeImpl);
}
@override
@@ -5371,7 +5378,7 @@
@override
void set typeParameters(TypeParameterList typeParameters) {
- _typeParameters = _becomeParentOf(typeParameters);
+ _typeParameters = _becomeParentOf(typeParameters as AstNodeImpl);
}
@override
@@ -5420,12 +5427,12 @@
* was specified.
*/
FunctionTypedFormalParameterImpl(
- Comment comment,
+ CommentImpl comment,
List<Annotation> metadata,
- TypeName returnType,
- SimpleIdentifier identifier,
- TypeParameterList typeParameters,
- FormalParameterList parameters)
+ TypeNameImpl returnType,
+ SimpleIdentifierImpl identifier,
+ TypeParameterListImpl typeParameters,
+ FormalParameterListImpl parameters)
: super(comment, metadata, identifier) {
_returnType = _becomeParentOf(returnType);
_typeParameters = _becomeParentOf(typeParameters);
@@ -5458,7 +5465,7 @@
@override
void set parameters(FormalParameterList parameters) {
- _parameters = _becomeParentOf(parameters);
+ _parameters = _becomeParentOf(parameters as AstNodeImpl);
}
@override
@@ -5466,7 +5473,7 @@
@override
void set returnType(TypeName type) {
- _returnType = _becomeParentOf(type);
+ _returnType = _becomeParentOf(type as AstNodeImpl);
}
@override
@@ -5474,7 +5481,7 @@
@override
void set typeParameters(TypeParameterList typeParameters) {
- _typeParameters = _becomeParentOf(typeParameters);
+ _typeParameters = _becomeParentOf(typeParameters as AstNodeImpl);
}
@override
@@ -5509,7 +5516,7 @@
*/
HideCombinatorImpl(Token keyword, List<SimpleIdentifier> hiddenNames)
: super(keyword) {
- _hiddenNames = new NodeList<SimpleIdentifier>(this, hiddenNames);
+ _hiddenNames = new NodeListImpl<SimpleIdentifier>(this, hiddenNames);
}
@override
@@ -5609,11 +5616,11 @@
IfStatementImpl(
this.ifKeyword,
this.leftParenthesis,
- Expression condition,
+ ExpressionImpl condition,
this.rightParenthesis,
- Statement thenStatement,
+ StatementImpl thenStatement,
this.elseKeyword,
- Statement elseStatement) {
+ StatementImpl elseStatement) {
_condition = _becomeParentOf(condition);
_thenStatement = _becomeParentOf(thenStatement);
_elseStatement = _becomeParentOf(elseStatement);
@@ -5637,7 +5644,7 @@
@override
void set condition(Expression expression) {
- _condition = _becomeParentOf(expression);
+ _condition = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -5645,7 +5652,7 @@
@override
void set elseStatement(Statement statement) {
- _elseStatement = _becomeParentOf(statement);
+ _elseStatement = _becomeParentOf(statement as AstNodeImpl);
}
@override
@@ -5661,7 +5668,7 @@
@override
void set thenStatement(Statement statement) {
- _thenStatement = _becomeParentOf(statement);
+ _thenStatement = _becomeParentOf(statement as AstNodeImpl);
}
@override
@@ -5698,7 +5705,7 @@
* Initialize a newly created implements clause.
*/
ImplementsClauseImpl(this.implementsKeyword, List<TypeName> interfaces) {
- _interfaces = new NodeList<TypeName>(this, interfaces);
+ _interfaces = new NodeListImpl<TypeName>(this, interfaces);
}
@override
@@ -5763,14 +5770,14 @@
* are no combinators.
*/
ImportDirectiveImpl(
- Comment comment,
+ CommentImpl comment,
List<Annotation> metadata,
Token keyword,
- StringLiteral libraryUri,
+ StringLiteralImpl libraryUri,
List<Configuration> configurations,
this.deferredKeyword,
this.asKeyword,
- SimpleIdentifier prefix,
+ SimpleIdentifierImpl prefix,
List<Combinator> combinators,
Token semicolon)
: super(comment, metadata, keyword, libraryUri, configurations,
@@ -5795,7 +5802,7 @@
@override
void set prefix(SimpleIdentifier identifier) {
- _prefix = _becomeParentOf(identifier);
+ _prefix = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -5885,15 +5892,15 @@
* Initialize a newly created index expression.
*/
IndexExpressionImpl.forCascade(
- this.period, this.leftBracket, Expression index, this.rightBracket) {
+ this.period, this.leftBracket, ExpressionImpl index, this.rightBracket) {
_index = _becomeParentOf(index);
}
/**
* Initialize a newly created index expression.
*/
- IndexExpressionImpl.forTarget(Expression target, this.leftBracket,
- Expression index, this.rightBracket) {
+ IndexExpressionImpl.forTarget(ExpressionImpl target, this.leftBracket,
+ ExpressionImpl index, this.rightBracket) {
_target = _becomeParentOf(target);
_index = _becomeParentOf(index);
}
@@ -5931,7 +5938,7 @@
@override
void set index(Expression expression) {
- _index = _becomeParentOf(expression);
+ _index = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -5963,7 +5970,7 @@
@override
void set target(Expression expression) {
- _target = _becomeParentOf(expression);
+ _target = _becomeParentOf(expression as AstNodeImpl);
}
/**
@@ -6075,8 +6082,8 @@
/**
* Initialize a newly created instance creation expression.
*/
- InstanceCreationExpressionImpl(this.keyword, ConstructorName constructorName,
- ArgumentList argumentList) {
+ InstanceCreationExpressionImpl(this.keyword,
+ ConstructorNameImpl constructorName, ArgumentListImpl argumentList) {
_constructorName = _becomeParentOf(constructorName);
_argumentList = _becomeParentOf(argumentList);
}
@@ -6086,7 +6093,7 @@
@override
void set argumentList(ArgumentList argumentList) {
- _argumentList = _becomeParentOf(argumentList);
+ _argumentList = _becomeParentOf(argumentList as AstNodeImpl);
}
@override
@@ -6103,7 +6110,7 @@
@override
void set constructorName(ConstructorName name) {
- _constructorName = _becomeParentOf(name);
+ _constructorName = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -6220,7 +6227,7 @@
* Initialize a newly created interpolation expression.
*/
InterpolationExpressionImpl(
- this.leftBracket, Expression expression, this.rightBracket) {
+ this.leftBracket, ExpressionImpl expression, this.rightBracket) {
_expression = _becomeParentOf(expression);
}
@@ -6246,7 +6253,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -6342,7 +6349,7 @@
* Initialize a newly created invocation.
*/
InvocationExpressionImpl(
- TypeArgumentList typeArguments, ArgumentList argumentList) {
+ TypeArgumentListImpl typeArguments, ArgumentListImpl argumentList) {
_typeArguments = _becomeParentOf(typeArguments);
_argumentList = _becomeParentOf(argumentList);
}
@@ -6351,14 +6358,14 @@
ArgumentList get argumentList => _argumentList;
void set argumentList(ArgumentList argumentList) {
- _argumentList = _becomeParentOf(argumentList);
+ _argumentList = _becomeParentOf(argumentList as AstNodeImpl);
}
@override
TypeArgumentList get typeArguments => _typeArguments;
void set typeArguments(TypeArgumentList typeArguments) {
- _typeArguments = _becomeParentOf(typeArguments);
+ _typeArguments = _becomeParentOf(typeArguments as AstNodeImpl);
}
}
@@ -6395,8 +6402,8 @@
* Initialize a newly created is expression. The [notOperator] can be `null`
* if the sense of the test is not negated.
*/
- IsExpressionImpl(
- Expression expression, this.isOperator, this.notOperator, TypeName type) {
+ IsExpressionImpl(ExpressionImpl expression, this.isOperator, this.notOperator,
+ TypeNameImpl type) {
_expression = _becomeParentOf(expression);
_type = _becomeParentOf(type);
}
@@ -6419,7 +6426,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -6430,7 +6437,7 @@
@override
void set type(TypeName name) {
- _type = _becomeParentOf(name);
+ _type = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -6464,8 +6471,8 @@
/**
* Initialize a newly created labeled statement.
*/
- LabeledStatementImpl(List<Label> labels, Statement statement) {
- _labels = new NodeList<Label>(this, labels);
+ LabeledStatementImpl(List<Label> labels, StatementImpl statement) {
+ _labels = new NodeListImpl<Label>(this, labels);
_statement = _becomeParentOf(statement);
}
@@ -6493,7 +6500,7 @@
@override
void set statement(Statement statement) {
- _statement = _becomeParentOf(statement);
+ _statement = _becomeParentOf(statement as AstNodeImpl);
}
@override
@@ -6531,7 +6538,7 @@
/**
* Initialize a newly created label.
*/
- LabelImpl(SimpleIdentifier label, this.colon) {
+ LabelImpl(SimpleIdentifierImpl label, this.colon) {
_label = _becomeParentOf(label);
}
@@ -6549,7 +6556,7 @@
@override
void set label(SimpleIdentifier label) {
- _label = _becomeParentOf(label);
+ _label = _becomeParentOf(label as AstNodeImpl);
}
@override
@@ -6591,8 +6598,8 @@
* [comment] and [metadata] can be `null` if the directive does not have the
* corresponding attribute.
*/
- LibraryDirectiveImpl(Comment comment, List<Annotation> metadata,
- this.libraryKeyword, LibraryIdentifier name, this.semicolon)
+ LibraryDirectiveImpl(CommentImpl comment, List<Annotation> metadata,
+ this.libraryKeyword, LibraryIdentifierImpl name, this.semicolon)
: super(comment, metadata) {
_name = _becomeParentOf(name);
}
@@ -6615,7 +6622,7 @@
@override
void set name(LibraryIdentifier name) {
- _name = _becomeParentOf(name);
+ _name = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -6646,7 +6653,7 @@
* Initialize a newly created prefixed identifier.
*/
LibraryIdentifierImpl(List<SimpleIdentifier> components) {
- _components = new NodeList<SimpleIdentifier>(this, components);
+ _components = new NodeListImpl<SimpleIdentifier>(this, components);
}
@override
@@ -6732,7 +6739,7 @@
ListLiteralImpl(Token constKeyword, TypeArgumentList typeArguments,
this.leftBracket, List<Expression> elements, this.rightBracket)
: super(constKeyword, typeArguments) {
- _elements = new NodeList<Expression>(this, elements);
+ _elements = new NodeListImpl<Expression>(this, elements);
}
@override
@@ -6834,7 +6841,8 @@
/**
* Initialize a newly created map literal entry.
*/
- MapLiteralEntryImpl(Expression key, this.separator, Expression value) {
+ MapLiteralEntryImpl(
+ ExpressionImpl key, this.separator, ExpressionImpl value) {
_key = _becomeParentOf(key);
_value = _becomeParentOf(value);
}
@@ -6854,7 +6862,7 @@
@override
void set key(Expression string) {
- _key = _becomeParentOf(string);
+ _key = _becomeParentOf(string as AstNodeImpl);
}
@override
@@ -6862,7 +6870,7 @@
@override
void set value(Expression expression) {
- _value = _becomeParentOf(expression);
+ _value = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -6909,7 +6917,7 @@
MapLiteralImpl(Token constKeyword, TypeArgumentList typeArguments,
this.leftBracket, List<MapLiteralEntry> entries, this.rightBracket)
: super(constKeyword, typeArguments) {
- _entries = new NodeList<MapLiteralEntry>(this, entries);
+ _entries = new NodeListImpl<MapLiteralEntry>(this, entries);
}
@override
@@ -7031,17 +7039,17 @@
* this method declares a getter.
*/
MethodDeclarationImpl(
- Comment comment,
+ CommentImpl comment,
List<Annotation> metadata,
this.externalKeyword,
this.modifierKeyword,
- TypeName returnType,
+ TypeNameImpl returnType,
this.propertyKeyword,
this.operatorKeyword,
- SimpleIdentifier name,
- TypeParameterList typeParameters,
- FormalParameterList parameters,
- FunctionBody body)
+ SimpleIdentifierImpl name,
+ TypeParameterListImpl typeParameters,
+ FormalParameterListImpl parameters,
+ FunctionBodyImpl body)
: super(comment, metadata) {
_returnType = _becomeParentOf(returnType);
_name = _becomeParentOf(name);
@@ -7055,7 +7063,7 @@
@override
void set body(FunctionBody functionBody) {
- _body = _becomeParentOf(functionBody);
+ _body = _becomeParentOf(functionBody as AstNodeImpl);
}
@override
@@ -7077,8 +7085,7 @@
* getter or a setter.
*/
@override
- ExecutableElement get element =>
- _name != null ? (_name.staticElement as ExecutableElement) : null;
+ ExecutableElement get element => _name?.staticElement as ExecutableElement;
@override
Token get endToken => _body.endToken;
@@ -7123,7 +7130,7 @@
@override
void set name(SimpleIdentifier identifier) {
- _name = _becomeParentOf(identifier);
+ _name = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -7131,7 +7138,7 @@
@override
void set parameters(FormalParameterList parameters) {
- _parameters = _becomeParentOf(parameters);
+ _parameters = _becomeParentOf(parameters as AstNodeImpl);
}
@override
@@ -7139,7 +7146,7 @@
@override
void set returnType(TypeName typeName) {
- _returnType = _becomeParentOf(typeName);
+ _returnType = _becomeParentOf(typeName as AstNodeImpl);
}
@override
@@ -7147,7 +7154,7 @@
@override
void set typeParameters(TypeParameterList typeParameters) {
- _typeParameters = _becomeParentOf(typeParameters);
+ _typeParameters = _becomeParentOf(typeParameters as AstNodeImpl);
}
@override
@@ -7201,11 +7208,11 @@
* can be `null` if there is no target.
*/
MethodInvocationImpl(
- Expression target,
+ ExpressionImpl target,
this.operator,
- SimpleIdentifier methodName,
- TypeArgumentList typeArguments,
- ArgumentList argumentList)
+ SimpleIdentifierImpl methodName,
+ TypeArgumentListImpl typeArguments,
+ ArgumentListImpl argumentList)
: super(typeArguments, argumentList) {
_target = _becomeParentOf(target);
_methodName = _becomeParentOf(methodName);
@@ -7243,7 +7250,7 @@
@override
void set methodName(SimpleIdentifier identifier) {
- _methodName = _becomeParentOf(identifier);
+ _methodName = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -7269,7 +7276,7 @@
@override
void set target(Expression expression) {
- _target = _becomeParentOf(expression);
+ _target = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -7301,7 +7308,7 @@
* does not have the corresponding attribute.
*/
NamedCompilationUnitMemberImpl(
- Comment comment, List<Annotation> metadata, SimpleIdentifier name)
+ CommentImpl comment, List<Annotation> metadata, SimpleIdentifierImpl name)
: super(comment, metadata) {
_name = _becomeParentOf(name);
}
@@ -7311,7 +7318,7 @@
@override
void set name(SimpleIdentifier identifier) {
- _name = _becomeParentOf(identifier);
+ _name = _becomeParentOf(identifier as AstNodeImpl);
}
}
@@ -7336,7 +7343,7 @@
/**
* Initialize a newly created named expression..
*/
- NamedExpressionImpl(Label name, Expression expression) {
+ NamedExpressionImpl(LabelImpl name, ExpressionImpl expression) {
_name = _becomeParentOf(name);
_expression = _becomeParentOf(expression);
}
@@ -7365,7 +7372,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -7373,7 +7380,7 @@
@override
void set name(Label identifier) {
- _name = _becomeParentOf(identifier);
+ _name = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -7437,8 +7444,8 @@
List<Combinator> combinators,
this.semicolon)
: super(comment, metadata, libraryUri) {
- _configurations = new NodeList<Configuration>(this, configurations);
- _combinators = new NodeList<Combinator>(this, combinators);
+ _configurations = new NodeListImpl<Configuration>(this, configurations);
+ _combinators = new NodeListImpl<Combinator>(this, combinators);
}
@override
@@ -7478,7 +7485,7 @@
/**
* Initialize a newly created native clause.
*/
- NativeClauseImpl(this.nativeKeyword, StringLiteral name) {
+ NativeClauseImpl(this.nativeKeyword, StringLiteralImpl name) {
_name = _becomeParentOf(name);
}
@@ -7497,7 +7504,7 @@
@override
void set name(StringLiteral name) {
- _name = _becomeParentOf(name);
+ _name = _becomeParentOf(name as AstNodeImpl);
}
@override
@@ -7542,7 +7549,7 @@
* a string literal, and a semicolon.
*/
NativeFunctionBodyImpl(
- this.nativeKeyword, StringLiteral stringLiteral, this.semicolon) {
+ this.nativeKeyword, StringLiteralImpl stringLiteral, this.semicolon) {
_stringLiteral = _becomeParentOf(stringLiteral);
}
@@ -7563,7 +7570,7 @@
@override
void set stringLiteral(StringLiteral stringLiteral) {
- _stringLiteral = _becomeParentOf(stringLiteral);
+ _stringLiteral = _becomeParentOf(stringLiteral as AstNodeImpl);
}
@override
@@ -7645,7 +7652,7 @@
if (index < 0 || index >= _elements.length) {
throw new RangeError("Index: $index, Size: ${_elements.length}");
}
- _owner._becomeParentOf(node);
+ _owner._becomeParentOf(node as AstNodeImpl);
_elements[index] = node;
}
@@ -7667,7 +7674,7 @@
if (nodes != null && !nodes.isEmpty) {
_elements.addAll(nodes);
for (E node in nodes) {
- _owner._becomeParentOf(node);
+ _owner._becomeParentOf(node as AstNodeImpl);
}
return true;
}
@@ -7685,7 +7692,7 @@
if (index < 0 || index > length) {
throw new RangeError("Index: $index, Size: ${_elements.length}");
}
- _owner._becomeParentOf(node);
+ _owner._becomeParentOf(node as AstNodeImpl);
if (length == 0) {
_elements.add(node);
} else {
@@ -7735,10 +7742,10 @@
* [comment] and [metadata] can be `null` if the parameter does not have the
* corresponding attribute.
*/
- NormalFormalParameterImpl(
- Comment comment, List<Annotation> metadata, SimpleIdentifier identifier) {
+ NormalFormalParameterImpl(CommentImpl comment, List<Annotation> metadata,
+ SimpleIdentifierImpl identifier) {
_comment = _becomeParentOf(comment);
- _metadata = new NodeList<Annotation>(this, metadata);
+ _metadata = new NodeListImpl<Annotation>(this, metadata);
_identifier = _becomeParentOf(identifier);
}
@@ -7747,7 +7754,7 @@
@override
void set documentationComment(Comment comment) {
- _comment = _becomeParentOf(comment);
+ _comment = _becomeParentOf(comment as AstNodeImpl);
}
@override
@@ -7755,7 +7762,7 @@
@override
void set identifier(SimpleIdentifier identifier) {
- _identifier = _becomeParentOf(identifier);
+ _identifier = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -7887,7 +7894,7 @@
* Initialize a newly created parenthesized expression.
*/
ParenthesizedExpressionImpl(
- this.leftParenthesis, Expression expression, this.rightParenthesis) {
+ this.leftParenthesis, ExpressionImpl expression, this.rightParenthesis) {
_expression = _becomeParentOf(expression);
}
@@ -7908,13 +7915,24 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
int get precedence => 15;
@override
+ Expression get unParenthesized {
+ // This is somewhat inefficient, but it avoids a stack overflow in the
+ // degenerate case.
+ Expression expression = _expression;
+ while (expression is ParenthesizedExpressionImpl) {
+ expression = (expression as ParenthesizedExpressionImpl)._expression;
+ }
+ return expression;
+ }
+
+ @override
dynamic/*=E*/ accept/*<E>*/(AstVisitor/*<E>*/ visitor) =>
visitor.visitParenthesizedExpression(this);
@@ -8009,11 +8027,11 @@
* corresponding attribute.
*/
PartOfDirectiveImpl(
- Comment comment,
+ CommentImpl comment,
List<Annotation> metadata,
this.partKeyword,
this.ofKeyword,
- LibraryIdentifier libraryName,
+ LibraryIdentifierImpl libraryName,
this.semicolon)
: super(comment, metadata) {
_libraryName = _becomeParentOf(libraryName);
@@ -8040,7 +8058,7 @@
@override
void set libraryName(LibraryIdentifier libraryName) {
- _libraryName = _becomeParentOf(libraryName);
+ _libraryName = _becomeParentOf(libraryName as AstNodeImpl);
}
@override
@@ -8093,7 +8111,7 @@
/**
* Initialize a newly created postfix expression.
*/
- PostfixExpressionImpl(Expression operand, this.operator) {
+ PostfixExpressionImpl(ExpressionImpl operand, this.operator) {
_operand = _becomeParentOf(operand);
}
@@ -8121,7 +8139,7 @@
@override
void set operand(Expression expression) {
- _operand = _becomeParentOf(expression);
+ _operand = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -8198,8 +8216,8 @@
/**
* Initialize a newly created prefixed identifier.
*/
- PrefixedIdentifierImpl(
- SimpleIdentifier prefix, this.period, SimpleIdentifier identifier) {
+ PrefixedIdentifierImpl(SimpleIdentifierImpl prefix, this.period,
+ SimpleIdentifierImpl identifier) {
_prefix = _becomeParentOf(prefix);
_identifier = _becomeParentOf(identifier);
}
@@ -8234,7 +8252,7 @@
@override
void set identifier(SimpleIdentifier identifier) {
- _identifier = _becomeParentOf(identifier);
+ _identifier = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -8262,7 +8280,7 @@
@override
void set prefix(SimpleIdentifier identifier) {
- _prefix = _becomeParentOf(identifier);
+ _prefix = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -8326,7 +8344,7 @@
/**
* Initialize a newly created prefix expression.
*/
- PrefixExpressionImpl(this.operator, Expression operand) {
+ PrefixExpressionImpl(this.operator, ExpressionImpl operand) {
_operand = _becomeParentOf(operand);
}
@@ -8354,7 +8372,7 @@
@override
void set operand(Expression expression) {
- _operand = _becomeParentOf(expression);
+ _operand = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -8434,7 +8452,7 @@
* Initialize a newly created property access expression.
*/
PropertyAccessImpl(
- Expression target, this.operator, SimpleIdentifier propertyName) {
+ ExpressionImpl target, this.operator, SimpleIdentifierImpl propertyName) {
_target = _becomeParentOf(target);
_propertyName = _becomeParentOf(propertyName);
}
@@ -8469,7 +8487,7 @@
@override
void set propertyName(SimpleIdentifier identifier) {
- _propertyName = _becomeParentOf(identifier);
+ _propertyName = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -8492,7 +8510,7 @@
@override
void set target(Expression expression) {
- _target = _becomeParentOf(expression);
+ _target = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -8550,7 +8568,7 @@
* `null` if the constructor being invoked is the unnamed constructor.
*/
RedirectingConstructorInvocationImpl(this.thisKeyword, this.period,
- SimpleIdentifier constructorName, ArgumentList argumentList) {
+ SimpleIdentifierImpl constructorName, ArgumentListImpl argumentList) {
_constructorName = _becomeParentOf(constructorName);
_argumentList = _becomeParentOf(argumentList);
}
@@ -8560,7 +8578,7 @@
@override
void set argumentList(ArgumentList argumentList) {
- _argumentList = _becomeParentOf(argumentList);
+ _argumentList = _becomeParentOf(argumentList as AstNodeImpl);
}
@override
@@ -8578,7 +8596,7 @@
@override
void set constructorName(SimpleIdentifier identifier) {
- _constructorName = _becomeParentOf(identifier);
+ _constructorName = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -8663,7 +8681,7 @@
* if no explicit value was provided.
*/
ReturnStatementImpl(
- this.returnKeyword, Expression expression, this.semicolon) {
+ this.returnKeyword, ExpressionImpl expression, this.semicolon) {
_expression = _becomeParentOf(expression);
}
@@ -8682,7 +8700,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -8748,7 +8766,7 @@
*/
ShowCombinatorImpl(Token keyword, List<SimpleIdentifier> shownNames)
: super(keyword) {
- _shownNames = new NodeList<SimpleIdentifier>(this, shownNames);
+ _shownNames = new NodeListImpl<SimpleIdentifier>(this, shownNames);
}
@override
@@ -8799,8 +8817,8 @@
* corresponding attribute. The [keyword] can be `null` if a type was
* specified. The [type] must be `null` if the keyword is 'var'.
*/
- SimpleFormalParameterImpl(Comment comment, List<Annotation> metadata,
- this.keyword, TypeName type, SimpleIdentifier identifier)
+ SimpleFormalParameterImpl(CommentImpl comment, List<Annotation> metadata,
+ this.keyword, TypeNameImpl type, SimpleIdentifierImpl identifier)
: super(comment, metadata, identifier) {
_type = _becomeParentOf(type);
}
@@ -8836,7 +8854,7 @@
@override
void set type(TypeName typeName) {
- _type = _becomeParentOf(typeName);
+ _type = _becomeParentOf(typeName as AstNodeImpl);
}
@override
@@ -9184,7 +9202,7 @@
* Initialize a newly created string interpolation expression.
*/
StringInterpolationImpl(List<InterpolationElement> elements) {
- _elements = new NodeList<InterpolationElement>(this, elements);
+ _elements = new NodeListImpl<InterpolationElement>(this, elements);
}
@override
@@ -9411,7 +9429,7 @@
* unnamed constructor.
*/
SuperConstructorInvocationImpl(this.superKeyword, this.period,
- SimpleIdentifier constructorName, ArgumentList argumentList) {
+ SimpleIdentifierImpl constructorName, ArgumentListImpl argumentList) {
_constructorName = _becomeParentOf(constructorName);
_argumentList = _becomeParentOf(argumentList);
}
@@ -9421,7 +9439,7 @@
@override
void set argumentList(ArgumentList argumentList) {
- _argumentList = _becomeParentOf(argumentList);
+ _argumentList = _becomeParentOf(argumentList as AstNodeImpl);
}
@override
@@ -9439,7 +9457,7 @@
@override
void set constructorName(SimpleIdentifier identifier) {
- _constructorName = _becomeParentOf(identifier);
+ _constructorName = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -9511,7 +9529,7 @@
* Initialize a newly created switch case. The list of [labels] can be `null`
* if there are no labels.
*/
- SwitchCaseImpl(List<Label> labels, Token keyword, Expression expression,
+ SwitchCaseImpl(List<Label> labels, Token keyword, ExpressionImpl expression,
Token colon, List<Statement> statements)
: super(labels, keyword, colon, statements) {
_expression = _becomeParentOf(expression);
@@ -9530,7 +9548,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -9612,8 +9630,8 @@
*/
SwitchMemberImpl(List<Label> labels, this.keyword, this.colon,
List<Statement> statements) {
- _labels = new NodeList<Label>(this, labels);
- _statements = new NodeList<Statement>(this, statements);
+ _labels = new NodeListImpl<Label>(this, labels);
+ _statements = new NodeListImpl<Statement>(this, statements);
}
@override
@@ -9689,13 +9707,13 @@
SwitchStatementImpl(
this.switchKeyword,
this.leftParenthesis,
- Expression expression,
+ ExpressionImpl expression,
this.rightParenthesis,
this.leftBracket,
List<SwitchMember> members,
this.rightBracket) {
_expression = _becomeParentOf(expression);
- _members = new NodeList<SwitchMember>(this, members);
+ _members = new NodeListImpl<SwitchMember>(this, members);
}
@override
@@ -9719,7 +9737,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -9839,7 +9857,7 @@
/**
* Initialize a newly created throw expression.
*/
- ThrowExpressionImpl(this.throwKeyword, Expression expression) {
+ ThrowExpressionImpl(this.throwKeyword, ExpressionImpl expression) {
_expression = _becomeParentOf(expression);
}
@@ -9863,7 +9881,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -9903,8 +9921,11 @@
* of the [comment] and [metadata] can be `null` if the variable does not have
* the corresponding attribute.
*/
- TopLevelVariableDeclarationImpl(Comment comment, List<Annotation> metadata,
- VariableDeclarationList variableList, this.semicolon)
+ TopLevelVariableDeclarationImpl(
+ CommentImpl comment,
+ List<Annotation> metadata,
+ VariableDeclarationListImpl variableList,
+ this.semicolon)
: super(comment, metadata) {
_variableList = _becomeParentOf(variableList);
}
@@ -9927,7 +9948,7 @@
@override
void set variables(VariableDeclarationList variables) {
- _variableList = _becomeParentOf(variables);
+ _variableList = _becomeParentOf(variables as AstNodeImpl);
}
@override
@@ -9983,10 +10004,14 @@
* `null` if there are no catch clauses. The [finallyKeyword] and
* [finallyBlock] can be `null` if there is no finally clause.
*/
- TryStatementImpl(this.tryKeyword, Block body, List<CatchClause> catchClauses,
- this.finallyKeyword, Block finallyBlock) {
+ TryStatementImpl(
+ this.tryKeyword,
+ BlockImpl body,
+ List<CatchClause> catchClauses,
+ this.finallyKeyword,
+ BlockImpl finallyBlock) {
_body = _becomeParentOf(body);
- _catchClauses = new NodeList<CatchClause>(this, catchClauses);
+ _catchClauses = new NodeListImpl<CatchClause>(this, catchClauses);
_finallyBlock = _becomeParentOf(finallyBlock);
}
@@ -9998,7 +10023,7 @@
@override
void set body(Block block) {
- _body = _becomeParentOf(block);
+ _body = _becomeParentOf(block as AstNodeImpl);
}
@override
@@ -10029,7 +10054,7 @@
@override
void set finallyBlock(Block block) {
- _finallyBlock = _becomeParentOf(block);
+ _finallyBlock = _becomeParentOf(block as AstNodeImpl);
}
@override
@@ -10109,7 +10134,7 @@
*/
TypeArgumentListImpl(
this.leftBracket, List<TypeName> arguments, this.rightBracket) {
- _arguments = new NodeList<TypeName>(this, arguments);
+ _arguments = new NodeListImpl<TypeName>(this, arguments);
}
@override
@@ -10163,7 +10188,7 @@
* if the literal is not a constant. The [typeArguments] can be `null` if no
* type arguments were declared.
*/
- TypedLiteralImpl(this.constKeyword, TypeArgumentList typeArguments) {
+ TypedLiteralImpl(this.constKeyword, TypeArgumentListImpl typeArguments) {
_typeArguments = _becomeParentOf(typeArguments);
}
@@ -10172,7 +10197,7 @@
@override
void set typeArguments(TypeArgumentList typeArguments) {
- _typeArguments = _becomeParentOf(typeArguments);
+ _typeArguments = _becomeParentOf(typeArguments as AstNodeImpl);
}
ChildEntities get _childEntities =>
@@ -10211,7 +10236,7 @@
* Initialize a newly created type name. The [typeArguments] can be `null` if
* there are no type arguments.
*/
- TypeNameImpl(Identifier name, TypeArgumentList typeArguments) {
+ TypeNameImpl(IdentifierImpl name, TypeArgumentListImpl typeArguments) {
_name = _becomeParentOf(name);
_typeArguments = _becomeParentOf(typeArguments);
}
@@ -10248,7 +10273,7 @@
@override
void set name(Identifier identifier) {
- _name = _becomeParentOf(identifier);
+ _name = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -10256,7 +10281,7 @@
@override
void set typeArguments(TypeArgumentList typeArguments) {
- _typeArguments = _becomeParentOf(typeArguments);
+ _typeArguments = _becomeParentOf(typeArguments as AstNodeImpl);
}
@override
@@ -10300,8 +10325,8 @@
* corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
* the parameter does not have an upper bound.
*/
- TypeParameterImpl(Comment comment, List<Annotation> metadata,
- SimpleIdentifier name, this.extendsKeyword, TypeName bound)
+ TypeParameterImpl(CommentImpl comment, List<Annotation> metadata,
+ SimpleIdentifierImpl name, this.extendsKeyword, TypeNameImpl bound)
: super(comment, metadata) {
_name = _becomeParentOf(name);
_bound = _becomeParentOf(bound);
@@ -10312,7 +10337,7 @@
@override
void set bound(TypeName typeName) {
- _bound = _becomeParentOf(typeName);
+ _bound = _becomeParentOf(typeName as AstNodeImpl);
}
@override
@@ -10321,7 +10346,7 @@
@override
TypeParameterElement get element =>
- _name != null ? (_name.staticElement as TypeParameterElement) : null;
+ _name?.staticElement as TypeParameterElement;
@override
Token get endToken {
@@ -10339,7 +10364,7 @@
@override
void set name(SimpleIdentifier identifier) {
- _name = _becomeParentOf(identifier);
+ _name = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -10381,7 +10406,7 @@
*/
TypeParameterListImpl(
this.leftBracket, List<TypeParameter> typeParameters, this.rightBracket) {
- _typeParameters = new NodeList<TypeParameter>(this, typeParameters);
+ _typeParameters = new NodeListImpl<TypeParameter>(this, typeParameters);
}
@override
@@ -10446,7 +10471,7 @@
* corresponding attribute.
*/
UriBasedDirectiveImpl(
- Comment comment, List<Annotation> metadata, StringLiteral uri)
+ CommentImpl comment, List<Annotation> metadata, StringLiteralImpl uri)
: super(comment, metadata) {
_uri = _becomeParentOf(uri);
}
@@ -10456,7 +10481,7 @@
@override
void set uri(StringLiteral uri) {
- _uri = _becomeParentOf(uri);
+ _uri = _becomeParentOf(uri as AstNodeImpl);
}
@override
@@ -10550,7 +10575,7 @@
* [initializer] can be `null` if there is no initializer.
*/
VariableDeclarationImpl(
- SimpleIdentifier name, this.equals, Expression initializer)
+ SimpleIdentifierImpl name, this.equals, ExpressionImpl initializer)
: super(null, null) {
_name = _becomeParentOf(name);
_initializer = _becomeParentOf(initializer);
@@ -10578,8 +10603,7 @@
}
@override
- VariableElement get element =>
- _name != null ? (_name.staticElement as VariableElement) : null;
+ VariableElement get element => _name?.staticElement as VariableElement;
@override
Token get endToken {
@@ -10597,7 +10621,7 @@
@override
void set initializer(Expression expression) {
- _initializer = _becomeParentOf(expression);
+ _initializer = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -10617,7 +10641,7 @@
@override
void set name(SimpleIdentifier identifier) {
- _name = _becomeParentOf(identifier);
+ _name = _becomeParentOf(identifier as AstNodeImpl);
}
@override
@@ -10668,11 +10692,11 @@
* the corresponding attribute. The [keyword] can be `null` if a type was
* specified. The [type] must be `null` if the keyword is 'var'.
*/
- VariableDeclarationListImpl(Comment comment, List<Annotation> metadata,
- this.keyword, TypeName type, List<VariableDeclaration> variables)
+ VariableDeclarationListImpl(CommentImpl comment, List<Annotation> metadata,
+ this.keyword, TypeNameImpl type, List<VariableDeclaration> variables)
: super(comment, metadata) {
_type = _becomeParentOf(type);
- _variables = new NodeList<VariableDeclaration>(this, variables);
+ _variables = new NodeListImpl<VariableDeclaration>(this, variables);
}
@override
@@ -10706,7 +10730,7 @@
@override
void set type(TypeName typeName) {
- _type = _becomeParentOf(typeName);
+ _type = _becomeParentOf(typeName as AstNodeImpl);
}
@override
@@ -10747,7 +10771,7 @@
* Initialize a newly created variable declaration statement.
*/
VariableDeclarationStatementImpl(
- VariableDeclarationList variableList, this.semicolon) {
+ VariableDeclarationListImpl variableList, this.semicolon) {
_variableList = _becomeParentOf(variableList);
}
@@ -10766,7 +10790,7 @@
@override
void set variables(VariableDeclarationList variables) {
- _variableList = _becomeParentOf(variables);
+ _variableList = _becomeParentOf(variables as AstNodeImpl);
}
@override
@@ -10815,7 +10839,7 @@
* Initialize a newly created while statement.
*/
WhileStatementImpl(this.whileKeyword, this.leftParenthesis,
- Expression condition, this.rightParenthesis, Statement body) {
+ ExpressionImpl condition, this.rightParenthesis, StatementImpl body) {
_condition = _becomeParentOf(condition);
_body = _becomeParentOf(body);
}
@@ -10828,7 +10852,7 @@
@override
void set body(Statement statement) {
- _body = _becomeParentOf(statement);
+ _body = _becomeParentOf(statement as AstNodeImpl);
}
@override
@@ -10844,7 +10868,7 @@
@override
void set condition(Expression expression) {
- _condition = _becomeParentOf(expression);
+ _condition = _becomeParentOf(expression as AstNodeImpl);
}
@override
@@ -10882,7 +10906,7 @@
* Initialize a newly created with clause.
*/
WithClauseImpl(this.withKeyword, List<TypeName> mixinTypes) {
- _mixinTypes = new NodeList<TypeName>(this, mixinTypes);
+ _mixinTypes = new NodeListImpl<TypeName>(this, mixinTypes);
}
@override
@@ -10942,7 +10966,7 @@
* star was provided.
*/
YieldStatementImpl(
- this.yieldKeyword, this.star, Expression expression, this.semicolon) {
+ this.yieldKeyword, this.star, ExpressionImpl expression, this.semicolon) {
_expression = _becomeParentOf(expression);
}
@@ -10974,7 +10998,7 @@
@override
void set expression(Expression expression) {
- _expression = _becomeParentOf(expression);
+ _expression = _becomeParentOf(expression as AstNodeImpl);
}
@override
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index a87c085..cde4825 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -3679,7 +3679,7 @@
*/
NodeLocator(int startOffset, [int endOffset])
: this._startOffset = startOffset,
- this._endOffset = endOffset == null ? startOffset : endOffset;
+ this._endOffset = endOffset ?? startOffset;
/**
* Return the node that was found that corresponds to the given source range
@@ -3783,7 +3783,7 @@
*/
NodeLocator2(int startOffset, [int endOffset])
: this._startOffset = startOffset,
- this._endOffset = endOffset == null ? startOffset : endOffset;
+ this._endOffset = endOffset ?? startOffset;
/**
* Search within the given AST [node] and return the node that was found,
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 7f0a7b8..5c5a74d 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -85,10 +85,9 @@
*/
ConstantEvaluationEngine(this.typeProvider, this._declaredVariables,
{ConstantEvaluationValidator validator, TypeSystem typeSystem})
- : validator = validator != null
- ? validator
- : new ConstantEvaluationValidator_ForProduction(),
- typeSystem = typeSystem != null ? typeSystem : new TypeSystemImpl();
+ : validator =
+ validator ?? new ConstantEvaluationValidator_ForProduction(),
+ typeSystem = typeSystem ?? new TypeSystemImpl();
/**
* Check that the arguments to a call to fromEnvironment() are correct. The
@@ -1476,7 +1475,7 @@
*/
void _error(AstNode node, ErrorCode code) {
_errorReporter.reportErrorForNode(
- code == null ? CompileTimeErrorCode.INVALID_CONSTANT : code, node);
+ code ?? CompileTimeErrorCode.INVALID_CONSTANT, node);
}
/**
@@ -1929,8 +1928,7 @@
* compile time constant if the errors would have been reported by other parts
* of the analysis engine.
*/
- List<AnalysisError> get errors =>
- _errors == null ? AnalysisError.NO_ERRORS : _errors;
+ List<AnalysisError> get errors => _errors ?? AnalysisError.NO_ERRORS;
/**
* Return `true` if the expression is a compile-time constant expression that
@@ -1973,7 +1971,7 @@
final DartObjectImpl value;
EvaluationResultImpl(this.value, [List<AnalysisError> errors]) {
- this._errors = errors == null ? <AnalysisError>[] : errors;
+ this._errors = errors ?? <AnalysisError>[];
}
List<AnalysisError> get errors => _errors;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 567c6fe..2175e9e 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -166,11 +166,8 @@
List<ConstructorElement> get constructors {
if (!isMixinApplication) {
assert(_constructors != null);
- return _constructors == null
- ? ConstructorElement.EMPTY_LIST
- : _constructors;
+ return _constructors ?? ConstructorElement.EMPTY_LIST;
}
-
return _computeMixinAppConstructors();
}
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 14e459e..7d08ca8 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1564,8 +1564,7 @@
}
HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
InterfaceType supertype = superclass;
- ClassElement supertypeElement =
- supertype == null ? null : supertype.element;
+ ClassElement supertypeElement = supertype?.element;
while (supertype != null && !visitedClasses.contains(supertypeElement)) {
visitedClasses.add(supertypeElement);
PropertyAccessorElement element = supertype.getGetter(getterName);
@@ -1579,7 +1578,7 @@
}
}
supertype = supertype.superclass;
- supertypeElement = supertype == null ? null : supertype.element;
+ supertypeElement = supertype?.element;
}
return null;
}
@@ -1669,8 +1668,7 @@
}
HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
InterfaceType supertype = superclass;
- ClassElement supertypeElement =
- supertype == null ? null : supertype.element;
+ ClassElement supertypeElement = supertype?.element;
while (supertype != null && !visitedClasses.contains(supertypeElement)) {
visitedClasses.add(supertypeElement);
MethodElement element = supertype.getMethod(methodName);
@@ -1684,7 +1682,7 @@
}
}
supertype = supertype.superclass;
- supertypeElement = supertype == null ? null : supertype.element;
+ supertypeElement = supertype?.element;
}
return null;
}
@@ -1710,8 +1708,7 @@
}
HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
InterfaceType supertype = superclass;
- ClassElement supertypeElement =
- supertype == null ? null : supertype.element;
+ ClassElement supertypeElement = supertype?.element;
while (supertype != null && !visitedClasses.contains(supertypeElement)) {
visitedClasses.add(supertypeElement);
PropertyAccessorElement element = supertype.getSetter(setterName);
@@ -1725,7 +1722,7 @@
}
}
supertype = supertype.superclass;
- supertypeElement = supertype == null ? null : supertype.element;
+ supertypeElement = supertype?.element;
}
return null;
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
index 76cedf7..3f449de 100644
--- a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
@@ -461,8 +461,7 @@
List<Map<String, ExecutableElement>> _gatherInterfaceLookupMaps(
ClassElement classElt, HashSet<ClassElement> visitedInterfaces) {
InterfaceType supertype = classElt.supertype;
- ClassElement superclassElement =
- supertype != null ? supertype.element : null;
+ ClassElement superclassElement = supertype?.element;
List<InterfaceType> mixins = classElt.mixins;
List<InterfaceType> interfaces = classElt.interfaces;
// Recursively collect the list of mappings from all of the interface types
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index f646167..0b17d71 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -324,11 +324,8 @@
LabelScope lookup(String targetLabel) {
if (_label == targetLabel) {
return this;
- } else if (_outerScope != null) {
- return _outerScope.lookup(targetLabel);
- } else {
- return null;
}
+ return _outerScope?.lookup(targetLabel);
}
}
diff --git a/pkg/analyzer/lib/src/dart/scanner/reader.dart b/pkg/analyzer/lib/src/dart/scanner/reader.dart
index 1f5d87d..81f506e 100644
--- a/pkg/analyzer/lib/src/dart/scanner/reader.dart
+++ b/pkg/analyzer/lib/src/dart/scanner/reader.dart
@@ -109,12 +109,12 @@
/**
* The number of characters in the string.
*/
- int _stringLength = 0;
+ int _stringLength;
/**
- * The index, relative to the string, of the last character that was read.
+ * The index, relative to the string, of the next character to be read.
*/
- int _charOffset = 0;
+ int _charOffset;
/**
* Initialize a newly created reader to read the characters in the given
@@ -122,35 +122,35 @@
*/
CharSequenceReader(this._sequence) {
this._stringLength = _sequence.length;
- this._charOffset = -1;
+ this._charOffset = 0;
}
@override
- int get offset => _charOffset;
+ int get offset => _charOffset - 1;
@override
void set offset(int offset) {
- _charOffset = offset;
+ _charOffset = offset + 1;
}
@override
int advance() {
- if (_charOffset + 1 >= _stringLength) {
+ if (_charOffset >= _stringLength) {
return -1;
}
- return _sequence.codeUnitAt(++_charOffset);
+ return _sequence.codeUnitAt(_charOffset++);
}
@override
String getString(int start, int endDelta) =>
- _sequence.substring(start, _charOffset + 1 + endDelta).toString();
+ _sequence.substring(start, _charOffset + endDelta);
@override
int peek() {
- if (_charOffset + 1 >= _stringLength) {
+ if (_charOffset >= _stringLength) {
return -1;
}
- return _sequence.codeUnitAt(_charOffset + 1);
+ return _sequence.codeUnitAt(_charOffset);
}
}
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index b3a9e78..0bd0f84 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -120,7 +120,7 @@
* types.
*/
ConstantEvaluator(this._source, this._typeProvider, {TypeSystem typeSystem})
- : _typeSystem = typeSystem != null ? typeSystem : new TypeSystemImpl();
+ : _typeSystem = typeSystem ?? new TypeSystemImpl();
EvaluationResult evaluate(Expression expression) {
RecordingErrorListener errorListener = new RecordingErrorListener();
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 833e55e..c7b502f 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -613,7 +613,7 @@
} else if (methodName.name == FunctionElement.LOAD_LIBRARY_NAME &&
_isDeferredPrefix(target)) {
if (node.operator.type == TokenType.QUESTION_PERIOD) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
target,
[(target as SimpleIdentifier).name]);
@@ -749,7 +749,8 @@
identical(errorCode,
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT) ||
identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
- _resolver.reportErrorForNode(errorCode, methodName, [methodName.name]);
+ _resolver.errorReporter
+ .reportErrorForNode(errorCode, methodName, [methodName.name]);
} else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
String targetTypeName;
if (target == null) {
@@ -798,7 +799,7 @@
}
}
}
- targetTypeName = targetType == null ? null : targetType.displayName;
+ targetTypeName = targetType?.displayName;
ErrorCode proxyErrorCode = (generatedWithTypePropagation
? HintCode.UNDEFINED_METHOD
: StaticTypeWarningCode.UNDEFINED_METHOD);
@@ -817,8 +818,10 @@
}
DartType targetType = getSuperType(_getStaticType(target));
String targetTypeName = targetType?.name;
- _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
- methodName, [methodName.name, targetTypeName]);
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
+ methodName,
+ [methodName.name, targetTypeName]);
}
return null;
}
@@ -892,17 +895,21 @@
}
if (element == null) {
if (identifier.inSetterContext()) {
- _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_SETTER,
- identifier, [identifier.name, prefixElement.name]);
+ _resolver.errorReporter.reportErrorForNode(
+ StaticWarningCode.UNDEFINED_SETTER,
+ identifier,
+ [identifier.name, prefixElement.name]);
return null;
}
AstNode parent = node.parent;
if (parent is Annotation) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_ANNOTATION, parent);
} else {
- _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_GETTER,
- identifier, [identifier.name, prefixElement.name]);
+ _resolver.errorReporter.reportErrorForNode(
+ StaticWarningCode.UNDEFINED_GETTER,
+ identifier,
+ [identifier.name, prefixElement.name]);
}
return null;
}
@@ -1077,25 +1084,25 @@
ClassElement enclosingClass = _resolver.enclosingClass;
if (_isFactoryConstructorReturnType(node) &&
!identical(element, enclosingClass)) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node);
} else if (_isConstructorReturnType(node) &&
!identical(element, enclosingClass)) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node);
element = null;
} else if (element == null ||
(element is PrefixElement && !_isValidAsPrefix(node))) {
// TODO(brianwilkerson) Recover from this error.
if (_isConstructorReturnType(node)) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node);
} else {
if (parent is Annotation) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_ANNOTATION, parent);
} else if (element != null) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
node,
[element.name]);
@@ -1137,19 +1144,19 @@
return null;
}
SimpleIdentifier name = node.constructorName;
- String superName = name != null ? name.name : null;
+ String superName = name?.name;
ConstructorElement element =
superType.lookUpConstructor(superName, _definingLibrary);
if (element == null ||
(!enclosingClass.doesMixinLackConstructors &&
!enclosingClass.isSuperConstructorAccessible(element))) {
if (name != null) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER,
node,
[superType.displayName, name]);
} else {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
node,
[superType.displayName]);
@@ -1157,7 +1164,7 @@
return null;
} else {
if (element.isFactory) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]);
}
}
@@ -1177,7 +1184,7 @@
@override
Object visitSuperExpression(SuperExpression node) {
if (!_isSuperInValidContext(node)) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node);
}
return super.visitSuperExpression(node);
@@ -1526,7 +1533,7 @@
NodeList<TypeName> arguments = typeArguments?.arguments;
if (arguments != null && arguments.length != parameters.length) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
node,
[invokeType, parameters.length, arguments?.length ?? 0]);
@@ -1635,7 +1642,7 @@
if (labelScope == null) {
// There are no labels in scope, so by definition the label is
// undefined.
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
return null;
}
@@ -1643,7 +1650,7 @@
if (definingScope == null) {
// No definition of the given label name could be found in any
// enclosing scope.
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
return null;
}
@@ -1652,8 +1659,10 @@
ExecutableElement labelContainer = definingScope.element
.getAncestor((element) => element is ExecutableElement);
if (!identical(labelContainer, _resolver.enclosingFunction)) {
- _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE,
- labelNode, [labelNode.name]);
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE,
+ labelNode,
+ [labelNode.name]);
}
return definingScope.node;
}
@@ -1815,7 +1824,7 @@
void _recordUndefinedNode(Element declaringElement, ErrorCode errorCode,
AstNode node, List<Object> arguments) {
if (_doesntHaveProxy(declaringElement)) {
- _resolver.reportErrorForNode(errorCode, node, arguments);
+ _resolver.errorReporter.reportErrorForNode(errorCode, node, arguments);
}
}
@@ -1830,7 +1839,8 @@
void _recordUndefinedOffset(Element declaringElement, ErrorCode errorCode,
int offset, int length, List<Object> arguments) {
if (_doesntHaveProxy(declaringElement)) {
- _resolver.reportErrorForOffset(errorCode, offset, length, arguments);
+ _resolver.errorReporter
+ .reportErrorForOffset(errorCode, offset, length, arguments);
}
}
@@ -1845,7 +1855,7 @@
void _recordUndefinedToken(Element declaringElement, ErrorCode errorCode,
Token token, List<Object> arguments) {
if (_doesntHaveProxy(declaringElement)) {
- _resolver.reportErrorForToken(errorCode, token, arguments);
+ _resolver.errorReporter.reportErrorForToken(errorCode, token, arguments);
}
}
@@ -1951,7 +1961,7 @@
}
// we need constructor
if (constructor == null) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
return;
}
@@ -1965,19 +1975,19 @@
Annotation annotation, PropertyAccessorElement accessorElement) {
// accessor should be synthetic
if (!accessorElement.isSynthetic) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
return;
}
// variable should be constant
VariableElement variableElement = accessorElement.variable;
if (!variableElement.isConst) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
}
// no arguments
if (annotation.arguments != null) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS,
annotation.name,
[annotation.name]);
@@ -2017,7 +2027,7 @@
List<ParameterElement> _resolveArgumentsToParameters(bool reportAsError,
ArgumentList argumentList, List<ParameterElement> parameters) {
return ResolverVisitor.resolveArgumentsToParameters(
- argumentList, parameters, _resolver.reportErrorForNode,
+ argumentList, parameters, _resolver.errorReporter.reportErrorForNode,
reportAsError: reportAsError);
}
@@ -2183,7 +2193,7 @@
Element targetElement = target.staticElement;
if (targetElement is PrefixElement) {
if (isConditional) {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
target,
[target.name]);
@@ -2288,9 +2298,8 @@
shouldReportMissingMember_static ? staticType : propagatedType;
Element staticOrPropagatedEnclosingElt = staticOrPropagatedType.element;
bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt);
- DartType displayType = staticOrPropagatedType != null
- ? staticOrPropagatedType
- : propagatedType != null ? propagatedType : staticType;
+ DartType displayType =
+ staticOrPropagatedType ?? propagatedType ?? staticType;
// Special getter cases.
if (propertyName.inGetterContext()) {
if (!isStaticProperty &&
@@ -2306,7 +2315,7 @@
return;
} else if (staticOrPropagatedEnclosingElt.isEnum &&
propertyName.name == "_name") {
- _resolver.reportErrorForNode(
+ _resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
propertyName,
[propertyName.name]);
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 96333ad..8db8ee0 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -816,7 +816,7 @@
* analysis engine to the given [logger].
*/
void set logger(Logger logger) {
- this._logger = logger == null ? Logger.NULL : logger;
+ this._logger = logger ?? Logger.NULL;
}
/**
@@ -1200,14 +1200,6 @@
bool enableAsync = true;
/**
- * A flag indicating whether interface libraries are to be supported (DEP 40).
- */
- bool get enableConditionalDirectives => true;
-
- @deprecated
- void set enableConditionalDirectives(_) {}
-
- /**
* A flag indicating whether generic methods are to be supported (DEP 22).
*/
bool enableGenericMethods = false;
@@ -1349,6 +1341,14 @@
_analyzeFunctionBodiesPredicate = value;
}
+ /**
+ * A flag indicating whether interface libraries are to be supported (DEP 40).
+ */
+ bool get enableConditionalDirectives => true;
+
+ @deprecated
+ void set enableConditionalDirectives(_) {}
+
@override
int encodeCrossContextOptions() =>
(enableAssertMessage ? ENABLE_ASSERT_FLAG : 0) |
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 96cdd80..5d0cee2 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -3147,7 +3147,7 @@
* Setting the source to `null` will cause the default source to be used.
*/
void set source(Source source) {
- this._source = source == null ? _defaultSource : source;
+ this._source = source ?? _defaultSource;
}
/**
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index c99057a..6d2f8b9 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -648,8 +648,7 @@
try {
_inAsync = node.isAsynchronous;
_inGenerator = node.isGenerator;
- FunctionType functionType =
- _enclosingFunction == null ? null : _enclosingFunction.type;
+ FunctionType functionType = _enclosingFunction?.type;
DartType expectedReturnType = functionType == null
? DynamicTypeImpl.instance
: functionType.returnType;
@@ -770,6 +769,8 @@
_errorReporter.reportErrorForNode(
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
functionExpression);
+ } else if (expressionType is FunctionType) {
+ _checkTypeArguments(expressionType.element, node.typeArguments);
}
return super.visitFunctionExpressionInvocation(node);
}
@@ -943,6 +944,8 @@
}
_checkForMissingRequiredParam(
node.staticInvokeType, node.argumentList, methodName);
+ _checkTypeArguments(
+ node.methodName.staticElement, node.typeArguments, target?.staticType);
return super.visitMethodInvocation(node);
}
@@ -1404,7 +1407,7 @@
// an error message once it's ready to "return false".
if (!overridingFT.typeFormals.isEmpty) {
if (overriddenFT.typeFormals.isEmpty) {
- overriddenFT = _typeSystem.instantiateToBounds(overriddenFT);
+ overridingFT = _typeSystem.instantiateToBounds(overridingFT);
} else {
List<TypeParameterElement> params1 = overridingFT.typeFormals;
List<TypeParameterElement> params2 = overriddenFT.typeFormals;
@@ -1792,8 +1795,7 @@
return;
}
FormalParameterList formalParameterList = method.parameters;
- NodeList<FormalParameter> parameterList =
- formalParameterList != null ? formalParameterList.parameters : null;
+ NodeList<FormalParameter> parameterList = formalParameterList?.parameters;
List<AstNode> parameters =
parameterList != null ? new List.from(parameterList) : null;
_checkForAllInvalidOverrideErrorCodesForExecutable(executableElement,
@@ -1916,8 +1918,7 @@
* [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE].
*/
void _checkForAllReturnStatementErrorCodes(ReturnStatement statement) {
- FunctionType functionType =
- _enclosingFunction == null ? null : _enclosingFunction.type;
+ FunctionType functionType = _enclosingFunction?.type;
DartType expectedReturnType = functionType == null
? DynamicTypeImpl.instance
: functionType.returnType;
@@ -2034,8 +2035,7 @@
return;
}
ParameterElement staticParameterElement = argument.staticParameterElement;
- DartType staticParameterType =
- staticParameterElement == null ? null : staticParameterElement.type;
+ DartType staticParameterType = staticParameterElement?.type;
_checkForArgumentTypeNotAssignableWithExpectedTypes(argument,
staticParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
}
@@ -3440,39 +3440,60 @@
}
if (_enclosingFunction.isAsynchronous) {
if (_enclosingFunction.isGenerator) {
- if (_options.strongMode) {
- if (_enclosingFunction.returnType.element !=
- _typeProvider.streamType.element) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE,
- returnType);
- }
- } else if (!_typeSystem.isAssignableTo(
- _enclosingFunction.returnType, _typeProvider.streamDynamicType)) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE,
- returnType);
- }
+ _checkForIllegalReturnTypeCode(
+ returnType,
+ _typeProvider.streamDynamicType,
+ StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE);
} else {
- if (_options.strongMode) {
- if (_enclosingFunction.returnType.element !=
- _typeProvider.futureType.element) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, returnType);
- }
- } else if (!_typeSystem.isAssignableTo(
- _enclosingFunction.returnType, _typeProvider.futureDynamicType)) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, returnType);
- }
+ _checkForIllegalReturnTypeCode(
+ returnType,
+ _typeProvider.futureDynamicType,
+ StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE);
}
} else if (_enclosingFunction.isGenerator) {
- if (!_typeSystem.isAssignableTo(
- _enclosingFunction.returnType, _typeProvider.iterableDynamicType)) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE,
- returnType);
+ _checkForIllegalReturnTypeCode(
+ returnType,
+ _typeProvider.iterableDynamicType,
+ StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE);
+ }
+ }
+
+ /**
+ * If the current function is async, async*, or sync*, verify that its
+ * declared return type is assignable to Future, Stream, or Iterable,
+ * respectively. This is called by [_checkForIllegalReturnType] to check if
+ * the declared [returnTypeName] is assignable to the required [expectedType]
+ * and if not report [errorCode].
+ */
+ void _checkForIllegalReturnTypeCode(TypeName returnTypeName,
+ DartType expectedType, StaticTypeWarningCode errorCode) {
+ DartType returnType = _enclosingFunction.returnType;
+ if (_options.strongMode) {
+ //
+ // When checking an async/sync*/async* method, we know the exact type
+ // that will be returned (e.g. Future, Iterable, or Stream).
+ //
+ // For example an `async` function body will return a `Future<T>` for
+ // some `T` (possibly `dynamic`).
+ //
+ // We allow the declared return type to be a supertype of that
+ // (e.g. `dynamic`, `Object`), or Future<S> for some S.
+ // (We assume the T <: S relation is checked elsewhere.)
+ //
+ // We do not allow user-defined subtypes of Future, because an `async`
+ // method will never return those.
+ //
+ // To check for this, we ensure that `Future<bottom> <: returnType`.
+ //
+ // Similar logic applies for sync* and async*.
+ //
+ InterfaceType genericType = (expectedType.element as ClassElement).type;
+ DartType lowerBound = genericType.instantiate([BottomTypeImpl.instance]);
+ if (!_typeSystem.isSubtypeOf(lowerBound, returnType)) {
+ _errorReporter.reportErrorForNode(errorCode, returnTypeName);
}
+ } else if (!_typeSystem.isAssignableTo(returnType, expectedType)) {
+ _errorReporter.reportErrorForNode(errorCode, returnTypeName);
}
}
@@ -3678,9 +3699,7 @@
}
// The type of the loop variable.
- SimpleIdentifier variable = node.identifier != null
- ? node.identifier
- : node.loopVariable.identifier;
+ SimpleIdentifier variable = node.identifier ?? node.loopVariable.identifier;
DartType variableType = getStaticType(variable);
DartType loopType = node.awaitKeyword != null
@@ -3767,8 +3786,7 @@
!executableElement.isOperator) {
HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
InterfaceType superclassType = _enclosingClass.supertype;
- ClassElement superclassElement =
- superclassType == null ? null : superclassType.element;
+ ClassElement superclassElement = superclassType?.element;
bool executableElementPrivate =
Identifier.isPrivateName(executableElementName);
while (superclassElement != null &&
@@ -3820,8 +3838,7 @@
}
}
superclassType = superclassElement.supertype;
- superclassElement =
- superclassType == null ? null : superclassType.element;
+ superclassElement = superclassType?.element;
}
}
return false;
@@ -3839,8 +3856,7 @@
return;
}
ParameterElement staticParameterElement = argument.staticParameterElement;
- DartType staticParameterType =
- staticParameterElement == null ? null : staticParameterElement.type;
+ DartType staticParameterType = staticParameterElement?.type;
_checkForArgumentTypeNotAssignable(argument, staticParameterType, _intType,
StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
}
@@ -4571,6 +4587,10 @@
FunctionType requiredMemberFT = _inheritanceManager
.substituteTypeArgumentsInMemberFromInheritance(
requiredMemberType, memberName, enclosingType);
+ foundConcreteFT =
+ _typeSystem.typeToConcreteType(_typeProvider, foundConcreteFT);
+ requiredMemberFT =
+ _typeSystem.typeToConcreteType(_typeProvider, requiredMemberFT);
if (_typeSystem.isSubtypeOf(foundConcreteFT, requiredMemberFT)) {
continue;
}
@@ -5217,13 +5237,14 @@
int loopThroughIndex =
math.min(typeNameArgList.length, boundingElts.length);
+ bool shouldSubstitute = typeArguments.length != 0 &&
+ typeArguments.length == typeParameters.length;
for (int i = 0; i < loopThroughIndex; i++) {
TypeName argTypeName = typeNameArgList[i];
DartType argType = argTypeName.type;
DartType boundType = boundingElts[i].bound;
if (argType != null && boundType != null) {
- if (typeArguments.length != 0 &&
- typeArguments.length == typeParameters.length) {
+ if (shouldSubstitute) {
boundType = boundType.substitute2(typeArguments, typeParameters);
}
if (!_typeSystem.isSubtypeOf(argType, boundType)) {
@@ -5646,6 +5667,82 @@
}
}
+ /**
+ * Verify that the given [typeArguments] are all within their bounds, as
+ * defined by the given [element].
+ *
+ * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
+ */
+ void _checkTypeArguments(Element element, TypeArgumentList typeArguments,
+ [DartType targetType]) {
+ if (element == null || typeArguments == null) {
+ return;
+ }
+ void reportError(
+ TypeName argument, DartType argumentType, DartType parameterType) {
+ _errorReporter.reportTypeErrorForNode(
+ StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+ argument,
+ [argumentType, parameterType]);
+ }
+ if (element is FunctionTypedElement) {
+ _checkTypeArgumentsAgainstBounds(
+ element.typeParameters, typeArguments, targetType, reportError);
+ } else if (element is ClassElement) {
+ _checkTypeArgumentsAgainstBounds(
+ element.typeParameters, typeArguments, targetType, reportError);
+ } else if (element is ParameterElement || element is LocalVariableElement) {
+ // TODO(brianwilkerson) Implement this case
+ } else {
+ print('Unhandled element type: ${element.runtimeType}');
+ }
+ }
+
+ void _checkTypeArgumentsAgainstBounds(
+ List<TypeParameterElement> typeParameters,
+ TypeArgumentList typeArgumentList,
+ DartType targetType,
+ void reportError(
+ TypeName argument, DartType argumentType, DartType parameterType)) {
+ NodeList<TypeName> typeArguments = typeArgumentList.arguments;
+ int argumentsLength = typeArguments.length;
+ int maxIndex = math.min(typeParameters.length, argumentsLength);
+
+ bool shouldSubstitute =
+ argumentsLength != 0 && argumentsLength == typeParameters.length;
+ List<DartType> argumentTypes = shouldSubstitute
+ ? typeArguments.map((TypeName typeName) => typeName.type).toList()
+ : null;
+ List<DartType> parameterTypes = shouldSubstitute
+ ? typeParameters
+ .map((TypeParameterElement element) => element.type)
+ .toList()
+ : null;
+ List<DartType> targetTypeParameterTypes = null;
+ for (int i = 0; i < maxIndex; i++) {
+ TypeName argTypeName = typeArguments[i];
+ DartType argType = argTypeName.type;
+ DartType boundType = typeParameters[i].bound;
+ if (argType != null && boundType != null) {
+ if (targetType is ParameterizedType) {
+ if (targetTypeParameterTypes == null) {
+ targetTypeParameterTypes = targetType.typeParameters
+ .map((TypeParameterElement element) => element.type)
+ .toList();
+ }
+ boundType = boundType.substitute2(
+ targetType.typeArguments, targetTypeParameterTypes);
+ }
+ if (shouldSubstitute) {
+ boundType = boundType.substitute2(argumentTypes, parameterTypes);
+ }
+ if (!_typeSystem.isSubtypeOf(argType, boundType)) {
+ reportError(argTypeName, argType, boundType);
+ }
+ }
+ }
+ }
+
DartType _computeReturnTypeForMethod(Expression returnExpression) {
// This method should never be called for generators, since generators are
// never allowed to contain return statements with expressions.
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 2b98d4a..04f9153 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -935,6 +935,8 @@
isByTask(ResolveLibraryReferencesTask.DESCRIPTOR) ||
isByTask(ResolveLibraryTask.DESCRIPTOR) ||
isByTask(ResolveLibraryTypeNamesTask.DESCRIPTOR) ||
+ isByTask(ResolveTopLevelLibraryTypeBoundsTask.DESCRIPTOR) ||
+ isByTask(ResolveTopLevelUnitTypeBoundsTask.DESCRIPTOR) ||
isByTask(ResolveUnitTask.DESCRIPTOR) ||
isByTask(ResolveUnitTypeNamesTask.DESCRIPTOR) ||
isByTask(ResolveVariableReferencesTask.DESCRIPTOR) ||
@@ -1254,6 +1256,7 @@
_shiftErrors_NEW(LINTS);
_shiftErrors_NEW(LIBRARY_UNIT_ERRORS);
_shiftErrors_NEW(RESOLVE_TYPE_NAMES_ERRORS);
+ _shiftErrors_NEW(RESOLVE_TYPE_BOUNDS_ERRORS);
_shiftErrors_NEW(RESOLVE_UNIT_ERRORS);
_shiftErrors_NEW(STRONG_MODE_ERRORS);
_shiftErrors_NEW(VARIABLE_REFERENCE_ERRORS);
@@ -1302,6 +1305,7 @@
void _updateEntry() {
_updateErrors_NEW(RESOLVE_TYPE_NAMES_ERRORS, []);
+ _updateErrors_NEW(RESOLVE_TYPE_BOUNDS_ERRORS, []);
_updateErrors_NEW(RESOLVE_UNIT_ERRORS, _resolveErrors);
_updateErrors_NEW(VARIABLE_REFERENCE_ERRORS, []);
_updateErrors_NEW(VERIFY_ERRORS, _verifyErrors);
@@ -1722,7 +1726,7 @@
} else if (token is TokenWithComment) {
token.precedingComments = comment;
} else {
- Type parentType = token != null ? token.runtimeType : null;
+ Type parentType = token?.runtimeType;
throw new AnalysisException('Uknown parent token type: $parentType');
}
}
diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
index d28dd98..752475d 100644
--- a/pkg/analyzer/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -37,7 +37,7 @@
int index = int.parse(indexStr);
Object arg = arguments[index];
assert(arg != null);
- return arg != null ? arg.toString() : null;
+ return arg?.toString();
});
}
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 98a26e9..f63edfa 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2120,7 +2120,7 @@
final AnalysisErrorListener _errorListener;
/**
- * An [errorListener] lock, if more than `0`, then errors are not reported.
+ * An [_errorListener] lock, if more than `0`, then errors are not reported.
*/
int _errorListenerLock = 0;
@@ -8199,12 +8199,8 @@
_advance();
variables.add(_parseVariableDeclaration());
}
- return new VariableDeclarationList(
- commentAndMetadata != null ? commentAndMetadata.comment : null,
- commentAndMetadata != null ? commentAndMetadata.metadata : null,
- keyword,
- type,
- variables);
+ return new VariableDeclarationList(commentAndMetadata?.comment,
+ commentAndMetadata?.metadata, keyword, type, variables);
}
/**
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 3b06ea0..7f00554 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -77,17 +77,29 @@
TypeSystem _typeSystem;
/**
+ * The current library
+ */
+ LibraryElement _currentLibrary;
+
+ /**
* Create a new instance of the [BestPracticesVerifier].
*
* @param errorReporter the error reporter
*/
- BestPracticesVerifier(this._errorReporter, TypeProvider typeProvider,
+ BestPracticesVerifier(
+ this._errorReporter, TypeProvider typeProvider, this._currentLibrary,
{TypeSystem typeSystem})
: _futureNullType = typeProvider.futureNullType,
- _typeSystem = (typeSystem != null) ? typeSystem : new TypeSystemImpl();
+ _typeSystem = typeSystem ?? new TypeSystemImpl();
@override
Object visitArgumentList(ArgumentList node) {
+ for (Expression argument in node.arguments) {
+ ParameterElement parameter = argument.bestParameterElement;
+ if (parameter?.parameterKind == ParameterKind.POSITIONAL) {
+ _checkForDeprecatedMemberUse(parameter, argument);
+ }
+ }
_checkForArgumentTypesNotAssignableInList(node);
return super.visitArgumentList(node);
}
@@ -149,6 +161,20 @@
}
@override
+ Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ if (node.element.isFactory) {
+ if (node.body is BlockFunctionBody) {
+ // Check the block for a return statement, if not, create the hint.
+ if (!ExitDetector.exits(node.body)) {
+ _errorReporter.reportErrorForNode(
+ HintCode.MISSING_RETURN, node, [node.returnType.name]);
+ }
+ }
+ }
+ return super.visitConstructorDeclaration(node);
+ }
+
+ @override
Object visitDoStatement(DoStatement node) {
_checkForPossibleNullCondition(node.condition);
return super.visitDoStatement(node);
@@ -191,10 +217,8 @@
Object visitImportDirective(ImportDirective node) {
_checkForDeprecatedMemberUse(node.uriElement, node);
ImportElement importElement = node.element;
- if (importElement != null) {
- if (importElement.isDeferred) {
- _checkForLoadLibraryFunction(node, importElement);
- }
+ if (importElement != null && importElement.isDeferred) {
+ _checkForLoadLibraryFunction(node, importElement);
}
return super.visitImportDirective(node);
}
@@ -239,6 +263,12 @@
Object visitMethodInvocation(MethodInvocation node) {
_checkForCanBeNullAfterNullAware(node.realTarget, node.operator);
_checkForInvalidProtectedMethodCalls(node);
+ DartType staticInvokeType = node.staticInvokeType;
+ if (staticInvokeType is InterfaceType) {
+ MethodElement methodElement = staticInvokeType.lookUpMethod(
+ FunctionElement.CALL_METHOD_NAME, _currentLibrary);
+ _checkForDeprecatedMemberUse(methodElement, node);
+ }
return super.visitMethodInvocation(node);
}
@@ -326,8 +356,7 @@
return true;
}
Element rhsElement = rhsType.element;
- LibraryElement libraryElement =
- rhsElement != null ? rhsElement.library : null;
+ LibraryElement libraryElement = rhsElement?.library;
if (libraryElement != null && libraryElement.isDartCore) {
// if x is Object or null is Null
if (rhsType.isObject ||
@@ -395,11 +424,8 @@
// Hint case: test propagated type information
//
// Compute the best types to use.
- DartType expectedBestType = expectedPropagatedType != null
- ? expectedPropagatedType
- : expectedStaticType;
- DartType actualBestType =
- actualPropagatedType != null ? actualPropagatedType : actualStaticType;
+ DartType expectedBestType = expectedPropagatedType ?? expectedStaticType;
+ DartType actualBestType = actualPropagatedType ?? actualStaticType;
if (actualBestType != null && expectedBestType != null) {
if (!_typeSystem.isAssignableTo(actualBestType, expectedBestType)) {
_errorReporter.reportTypeErrorForNode(
@@ -424,13 +450,10 @@
return false;
}
ParameterElement staticParameterElement = argument.staticParameterElement;
- DartType staticParameterType =
- staticParameterElement == null ? null : staticParameterElement.type;
+ DartType staticParameterType = staticParameterElement?.type;
ParameterElement propagatedParameterElement =
argument.propagatedParameterElement;
- DartType propagatedParameterType = propagatedParameterElement == null
- ? null
- : propagatedParameterElement.type;
+ DartType propagatedParameterType = propagatedParameterElement?.type;
return _checkForArgumentTypeNotAssignableWithExpectedTypes(
argument,
staticParameterType,
@@ -491,9 +514,7 @@
if (operator?.type == TokenType.QUESTION_PERIOD) {
return;
}
- while (target is ParenthesizedExpression) {
- target = (target as ParenthesizedExpression).expression;
- }
+ target = target?.unParenthesized;
if (target is MethodInvocation) {
if (target.operator?.type == TokenType.QUESTION_PERIOD) {
_errorReporter.reportErrorForNode(
@@ -540,6 +561,11 @@
if (!element.displayName.isEmpty) {
displayName = "$displayName.${element.displayName}";
}
+ } else if (displayName == FunctionElement.CALL_METHOD_NAME &&
+ node is MethodInvocation &&
+ node.staticInvokeType is InterfaceType) {
+ displayName =
+ "${node.staticInvokeType.displayName}.${element.displayName}";
}
_errorReporter.reportErrorForNode(
HintCode.DEPRECATED_MEMBER_USE, node, [displayName]);
@@ -787,9 +813,7 @@
* Produce a hint if the given [condition] could have a value of `null`.
*/
void _checkForPossibleNullCondition(Expression condition) {
- while (condition is ParenthesizedExpression) {
- condition = (condition as ParenthesizedExpression).expression;
- }
+ condition = condition?.unParenthesized;
if (condition is BinaryExpression) {
_checkForPossibleNullConditionInBinaryExpression(condition);
} else if (condition is PrefixExpression) {
@@ -805,10 +829,8 @@
*/
void _checkForPossibleNullConditionInBinaryExpression(
BinaryExpression condition) {
- Token operator = condition.operator;
- if (operator != null &&
- (operator.type == TokenType.AMPERSAND_AMPERSAND ||
- operator.type == TokenType.BAR_BAR)) {
+ TokenType type = condition.operator?.type;
+ if (type == TokenType.AMPERSAND_AMPERSAND || type == TokenType.BAR_BAR) {
_checkForPossibleNullCondition(condition.leftOperand);
_checkForPossibleNullCondition(condition.rightOperand);
}
@@ -830,14 +852,12 @@
*/
void _checkForPossibleNullConditionInSimpleExpression(Expression condition) {
if (condition is MethodInvocation) {
- Token operator = condition.operator;
- if (operator != null && operator.type == TokenType.QUESTION_PERIOD) {
+ if (condition.operator?.type == TokenType.QUESTION_PERIOD) {
_errorReporter.reportErrorForNode(
HintCode.NULL_AWARE_IN_CONDITION, condition);
}
} else if (condition is PropertyAccess) {
- Token operator = condition.operator;
- if (operator != null && operator.type == TokenType.QUESTION_PERIOD) {
+ if (condition.operator?.type == TokenType.QUESTION_PERIOD) {
_errorReporter.reportErrorForNode(
HintCode.NULL_AWARE_IN_CONDITION, condition);
}
@@ -1717,8 +1737,8 @@
bool _checkForIsDoubleHints(IsExpression node) {
TypeName typeName = node.type;
DartType type = typeName.type;
- if (type != null && type.element != null) {
- Element element = type.element;
+ Element element = type?.element;
+ if (element != null) {
String typeNameStr = element.name;
LibraryElement libraryElement = element.library;
// if (typeNameStr.equals(INT_TYPE_NAME) && libraryElement != null
@@ -1766,8 +1786,7 @@
* @param errorReporter the error reporter
*/
DeadCodeVerifier(this._errorReporter, {TypeSystem typeSystem})
- : this._typeSystem =
- (typeSystem != null) ? typeSystem : new TypeSystemImpl();
+ : this._typeSystem = typeSystem ?? new TypeSystemImpl();
@override
Object visitBinaryExpression(BinaryExpression node) {
@@ -1779,14 +1798,15 @@
if (!_isDebugConstant(lhsCondition)) {
EvaluationResultImpl lhsResult = _getConstantBooleanValue(lhsCondition);
if (lhsResult != null) {
- if (lhsResult.value.toBoolValue() == true && isBarBar) {
+ bool value = lhsResult.value.toBoolValue();
+ if (value == true && isBarBar) {
// report error on else block: true || !e!
_errorReporter.reportErrorForNode(
HintCode.DEAD_CODE, node.rightOperand);
// only visit the LHS:
lhsCondition?.accept(this);
return null;
- } else if (lhsResult.value.toBoolValue() == false && isAmpAmp) {
+ } else if (value == false && isAmpAmp) {
// report error on if block: false && !e!
_errorReporter.reportErrorForNode(
HintCode.DEAD_CODE, node.rightOperand);
@@ -1941,9 +1961,8 @@
if (catchClause.onKeyword != null) {
// on-catch clause found, verify that the exception type is not a
// subtype of a previous on-catch exception type
- TypeName typeName = catchClause.exceptionType;
- if (typeName != null && typeName.type != null) {
- DartType currentType = typeName.type;
+ DartType currentType = catchClause.exceptionType?.type;
+ if (currentType != null) {
if (currentType.isObject) {
// Found catch clause clause that has Object as an exception type,
// this is equivalent to having a catch clause that doesn't have an
@@ -3758,7 +3777,7 @@
}
// All of the members exit, determine whether there are possible cases
// that are not caught by the members.
- DartType type = node.expression == null ? null : node.expression.bestType;
+ DartType type = node.expression?.bestType;
if (type is InterfaceType) {
ClassElement element = type.element;
if (element != null && element.isEnum) {
@@ -4222,7 +4241,8 @@
unit.accept(new Dart2JSVerifier(errorReporter));
}
// Dart best practices
- unit.accept(new BestPracticesVerifier(errorReporter, _context.typeProvider,
+ unit.accept(new BestPracticesVerifier(
+ errorReporter, _context.typeProvider, _library,
typeSystem: _context.typeSystem));
unit.accept(new OverrideVerifier(errorReporter, _manager));
// Find to-do comments
@@ -4486,7 +4506,7 @@
String name = element.displayName;
for (ImportDirective importDirective in importsLibrary) {
Namespace namespace = _computeNamespace(importDirective);
- if (namespace != null && namespace.get(name) != null) {
+ if (namespace?.get(name) != null) {
_unusedImports.remove(importDirective);
_removeFromUnusedShownNamesMap(element, importDirective);
}
@@ -5598,16 +5618,12 @@
}
/**
- * Return the static element associated with the given expression whose type can be promoted, or
- * `null` if there is no element whose type can be promoted.
- *
- * @param expression the expression with which the element is associated
- * @return the element associated with the given expression
+ * Return the static element associated with the given expression whose type
+ * can be promoted, or `null` if there is no element whose type can be
+ * promoted.
*/
VariableElement getPromotionStaticElement(Expression expression) {
- while (expression is ParenthesizedExpression) {
- expression = (expression as ParenthesizedExpression).expression;
- }
+ expression = expression?.unParenthesized;
if (expression is SimpleIdentifier) {
Element element = expression.staticElement;
if (element is VariableElement) {
@@ -5764,7 +5780,7 @@
void prepareToResolveMembersInClass(ClassDeclaration node) {
_enclosingClassDeclaration = node;
enclosingClass = node.element;
- typeAnalyzer.thisType = enclosingClass == null ? null : enclosingClass.type;
+ typeAnalyzer.thisType = enclosingClass?.type;
}
/**
@@ -6017,9 +6033,7 @@
//
// Resolve the metadata in the library scope.
//
- if (node.metadata != null) {
- node.metadata.accept(this);
- }
+ node.metadata?.accept(this);
_enclosingClassDeclaration = node;
//
// Continue the class resolution.
@@ -6027,13 +6041,12 @@
ClassElement outerType = enclosingClass;
try {
enclosingClass = node.element;
- typeAnalyzer.thisType =
- enclosingClass == null ? null : enclosingClass.type;
+ typeAnalyzer.thisType = enclosingClass?.type;
super.visitClassDeclaration(node);
node.accept(elementResolver);
node.accept(typeAnalyzer);
} finally {
- typeAnalyzer.thisType = outerType == null ? null : outerType.type;
+ typeAnalyzer.thisType = outerType?.type;
enclosingClass = outerType;
_enclosingClassDeclaration = null;
}
@@ -6048,15 +6061,13 @@
//
// Resolve the metadata in the library scope.
//
- if (node.metadata != null) {
- node.metadata.accept(this);
- }
+ node.metadata?.accept(this);
_enclosingClassDeclaration = node;
//
// Continue the class resolution.
//
enclosingClass = node.element;
- typeAnalyzer.thisType = enclosingClass == null ? null : enclosingClass.type;
+ typeAnalyzer.thisType = enclosingClass?.type;
node.accept(elementResolver);
node.accept(typeAnalyzer);
}
@@ -6274,13 +6285,12 @@
ClassElement outerType = enclosingClass;
try {
enclosingClass = node.element;
- typeAnalyzer.thisType =
- enclosingClass == null ? null : enclosingClass.type;
+ typeAnalyzer.thisType = enclosingClass?.type;
super.visitEnumDeclaration(node);
node.accept(elementResolver);
node.accept(typeAnalyzer);
} finally {
- typeAnalyzer.thisType = outerType == null ? null : outerType.type;
+ typeAnalyzer.thisType = outerType?.type;
enclosingClass = outerType;
_enclosingClassDeclaration = null;
}
@@ -7093,8 +7103,7 @@
FunctionType expectedClosureType = mayByFunctionType as FunctionType;
// If the expectedClosureType is not more specific than the static type,
// return.
- DartType staticClosureType =
- closure.element != null ? closure.element.type : null;
+ DartType staticClosureType = closure.element?.type;
if (staticClosureType != null &&
!expectedClosureType.isMoreSpecificThan(staticClosureType)) {
return;
@@ -7145,9 +7154,7 @@
// would eventually turn this into a method on Expression that returns a
// termination indication (normal, abrupt with no exception, abrupt with an
// exception).
- while (expression is ParenthesizedExpression) {
- expression = (expression as ParenthesizedExpression).expression;
- }
+ expression = expression?.unParenthesized;
return expression is ThrowExpression || expression is RethrowExpression;
}
@@ -7464,6 +7471,10 @@
* The abstract class `ScopedVisitor` maintains name and label scopes as an AST structure is
* being visited.
*/
+/**
+ * The abstract class `ScopedVisitor` maintains name and label scopes as an AST structure is
+ * being visited.
+ */
abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
/**
* The element for the library containing the compilation unit being visited.
@@ -7476,9 +7487,15 @@
final Source source;
/**
- * The error listener that will be informed of any errors that are found during resolution.
+ * The object used to access the types from the core library.
*/
- final AnalysisErrorListener errorListener;
+ final TypeProvider typeProvider;
+
+ /**
+ * The error reporter that will be informed of any errors that are found
+ * during resolution.
+ */
+ final ErrorReporter errorReporter;
/**
* The scope used to resolve identifiers.
@@ -7486,11 +7503,6 @@
Scope nameScope;
/**
- * The object used to access the types from the core library.
- */
- final TypeProvider typeProvider;
-
- /**
* The scope used to resolve unlabeled `break` and `continue` statements.
*/
ImplicitLabelScope _implicitLabelScope = ImplicitLabelScope.ROOT;
@@ -7522,9 +7534,11 @@
* first be visited. If `null` or unspecified, a new [LibraryScope] will be
* created based on [definingLibrary] and [typeProvider].
*/
- ScopedVisitor(
- this.definingLibrary, this.source, this.typeProvider, this.errorListener,
- {Scope nameScope}) {
+ ScopedVisitor(this.definingLibrary, Source source, this.typeProvider,
+ AnalysisErrorListener errorListener,
+ {Scope nameScope})
+ : source = source,
+ errorReporter = new ErrorReporter(errorListener, source) {
if (nameScope == null) {
this.nameScope = new LibraryScope(definingLibrary, errorListener);
} else {
@@ -7559,46 +7573,6 @@
return nameScope;
}
- /**
- * Report an error with the given error code and arguments.
- *
- * @param errorCode the error code of the error to be reported
- * @param node the node specifying the location of the error
- * @param arguments the arguments to the error, used to compose the error message
- */
- void reportErrorForNode(ErrorCode errorCode, AstNode node,
- [List<Object> arguments]) {
- errorListener.onError(new AnalysisError(
- source, node.offset, node.length, errorCode, arguments));
- }
-
- /**
- * Report an error with the given error code and arguments.
- *
- * @param errorCode the error code of the error to be reported
- * @param offset the offset of the location of the error
- * @param length the length of the location of the error
- * @param arguments the arguments to the error, used to compose the error message
- */
- void reportErrorForOffset(ErrorCode errorCode, int offset, int length,
- [List<Object> arguments]) {
- errorListener.onError(
- new AnalysisError(source, offset, length, errorCode, arguments));
- }
-
- /**
- * Report an error with the given error code and arguments.
- *
- * @param errorCode the error code of the error to be reported
- * @param token the token specifying the location of the error
- * @param arguments the arguments to the error, used to compose the error message
- */
- void reportErrorForToken(ErrorCode errorCode, Token token,
- [List<Object> arguments]) {
- errorListener.onError(new AnalysisError(
- source, token.offset, token.length, errorCode, arguments));
- }
-
@override
Object visitBlock(Block node) {
Scope outerScope = nameScope;
@@ -8372,6 +8346,498 @@
}
/**
+ * Helper for resolving [TypeName]s.
+ *
+ * The client must set [nameScope] before calling [resolveTypeName].
+ */
+class TypeNameResolver {
+ final TypeSystem typeSystem;
+ final DartType dynamicType;
+ final DartType undefinedType;
+ final LibraryElement definingLibrary;
+ final Source source;
+ final AnalysisErrorListener errorListener;
+
+ Scope nameScope;
+
+ TypeNameResolver(this.typeSystem, TypeProvider typeProvider,
+ this.definingLibrary, this.source, this.errorListener)
+ : dynamicType = typeProvider.dynamicType,
+ undefinedType = typeProvider.undefinedType;
+
+ /**
+ * Report an error with the given error code and arguments.
+ *
+ * @param errorCode the error code of the error to be reported
+ * @param node the node specifying the location of the error
+ * @param arguments the arguments to the error, used to compose the error message
+ */
+ void reportErrorForNode(ErrorCode errorCode, AstNode node,
+ [List<Object> arguments]) {
+ errorListener.onError(new AnalysisError(
+ source, node.offset, node.length, errorCode, arguments));
+ }
+
+ /**
+ * Resolve the given [TypeName] - set its element and static type. Only the
+ * given [node] is resolved, all its children must be already resolved.
+ *
+ * The client must set [nameScope] before calling [resolveTypeName].
+ */
+ void resolveTypeName(TypeName node) {
+ Identifier typeName = node.name;
+ _setElement(typeName, null); // Clear old Elements from previous run.
+ TypeArgumentList argumentList = node.typeArguments;
+ Element element = nameScope.lookup(typeName, definingLibrary);
+ if (element == null) {
+ //
+ // Check to see whether the type name is either 'dynamic' or 'void',
+ // neither of which are in the name scope and hence will not be found by
+ // normal means.
+ //
+ if (typeName.name == dynamicType.name) {
+ _setElement(typeName, dynamicType.element);
+// if (argumentList != null) {
+// // TODO(brianwilkerson) Report this error
+// reporter.reportError(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, node, dynamicType.getName(), 0, argumentList.getArguments().size());
+// }
+ typeName.staticType = dynamicType;
+ node.type = dynamicType;
+ return;
+ }
+ VoidTypeImpl voidType = VoidTypeImpl.instance;
+ if (typeName.name == voidType.name) {
+ // There is no element for 'void'.
+// if (argumentList != null) {
+// // TODO(brianwilkerson) Report this error
+// reporter.reportError(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, node, voidType.getName(), 0, argumentList.getArguments().size());
+// }
+ typeName.staticType = voidType;
+ node.type = voidType;
+ return;
+ }
+ //
+ // If not, the look to see whether we might have created the wrong AST
+ // structure for a constructor name. If so, fix the AST structure and then
+ // proceed.
+ //
+ AstNode parent = node.parent;
+ if (typeName is PrefixedIdentifier &&
+ parent is ConstructorName &&
+ argumentList == null) {
+ ConstructorName name = parent;
+ if (name.name == null) {
+ PrefixedIdentifier prefixedIdentifier =
+ typeName as PrefixedIdentifier;
+ SimpleIdentifier prefix = prefixedIdentifier.prefix;
+ element = nameScope.lookup(prefix, definingLibrary);
+ if (element is PrefixElement) {
+ AstNode grandParent = parent.parent;
+ if (grandParent is InstanceCreationExpression &&
+ grandParent.isConst) {
+ // If, if this is a const expression, then generate a
+ // CompileTimeErrorCode.CONST_WITH_NON_TYPE error.
+ reportErrorForNode(
+ CompileTimeErrorCode.CONST_WITH_NON_TYPE,
+ prefixedIdentifier.identifier,
+ [prefixedIdentifier.identifier.name]);
+ } else {
+ // Else, if this expression is a new expression, report a
+ // NEW_WITH_NON_TYPE warning.
+ reportErrorForNode(
+ StaticWarningCode.NEW_WITH_NON_TYPE,
+ prefixedIdentifier.identifier,
+ [prefixedIdentifier.identifier.name]);
+ }
+ _setElement(prefix, element);
+ return;
+ } else if (element != null) {
+ //
+ // Rewrite the constructor name. The parser, when it sees a
+ // constructor named "a.b", cannot tell whether "a" is a prefix and
+ // "b" is a class name, or whether "a" is a class name and "b" is a
+ // constructor name. It arbitrarily chooses the former, but in this
+ // case was wrong.
+ //
+ name.name = prefixedIdentifier.identifier;
+ name.period = prefixedIdentifier.period;
+ node.name = prefix;
+ typeName = prefix;
+ }
+ }
+ }
+ }
+ // check element
+ bool elementValid = element is! MultiplyDefinedElement;
+ if (elementValid &&
+ element is! ClassElement &&
+ _isTypeNameInInstanceCreationExpression(node)) {
+ SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName);
+ InstanceCreationExpression creation =
+ node.parent.parent as InstanceCreationExpression;
+ if (creation.isConst) {
+ if (element == null) {
+ reportErrorForNode(
+ CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typeName]);
+ } else {
+ reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE,
+ typeNameSimple, [typeName]);
+ }
+ elementValid = false;
+ } else {
+ if (element != null) {
+ reportErrorForNode(
+ StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typeName]);
+ elementValid = false;
+ }
+ }
+ }
+ if (elementValid && element == null) {
+ // We couldn't resolve the type name.
+ // TODO(jwren) Consider moving the check for
+ // CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE from the
+ // ErrorVerifier, so that we don't have two errors on a built in
+ // identifier being used as a class name.
+ // See CompileTimeErrorCodeTest.test_builtInIdentifierAsType().
+ SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName);
+ RedirectingConstructorKind redirectingConstructorKind;
+ if (_isBuiltInIdentifier(node) && _isTypeAnnotation(node)) {
+ reportErrorForNode(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE,
+ typeName, [typeName.name]);
+ } else if (typeNameSimple.name == "boolean") {
+ reportErrorForNode(
+ StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, []);
+ } else if (_isTypeNameInCatchClause(node)) {
+ reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName,
+ [typeName.name]);
+ } else if (_isTypeNameInAsExpression(node)) {
+ reportErrorForNode(
+ StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
+ } else if (_isTypeNameInIsExpression(node)) {
+ reportErrorForNode(StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME,
+ typeName, [typeName.name]);
+ } else if ((redirectingConstructorKind =
+ _getRedirectingConstructorKind(node)) !=
+ null) {
+ ErrorCode errorCode =
+ (redirectingConstructorKind == RedirectingConstructorKind.CONST
+ ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
+ : StaticWarningCode.REDIRECT_TO_NON_CLASS);
+ reportErrorForNode(errorCode, typeName, [typeName.name]);
+ } else if (_isTypeNameInTypeArgumentList(node)) {
+ reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
+ typeName, [typeName.name]);
+ } else {
+ reportErrorForNode(
+ StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]);
+ }
+ elementValid = false;
+ }
+ if (!elementValid) {
+ if (element is MultiplyDefinedElement) {
+ _setElement(typeName, element);
+ }
+ typeName.staticType = undefinedType;
+ node.type = undefinedType;
+ return;
+ }
+ DartType type = null;
+ if (element is ClassElement) {
+ _setElement(typeName, element);
+ type = element.type;
+ } else if (element is FunctionTypeAliasElement) {
+ _setElement(typeName, element);
+ type = element.type;
+ } else if (element is TypeParameterElement) {
+ _setElement(typeName, element);
+ type = element.type;
+// if (argumentList != null) {
+// // Type parameters cannot have type arguments.
+// // TODO(brianwilkerson) Report this error.
+// // resolver.reportError(ResolverErrorCode.?, keyType);
+// }
+ } else if (element is MultiplyDefinedElement) {
+ List<Element> elements = element.conflictingElements;
+ type = _getTypeWhenMultiplyDefined(elements);
+ if (type != null) {
+ node.type = type;
+ }
+ } else {
+ // The name does not represent a type.
+ RedirectingConstructorKind redirectingConstructorKind;
+ if (_isTypeNameInCatchClause(node)) {
+ reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName,
+ [typeName.name]);
+ } else if (_isTypeNameInAsExpression(node)) {
+ reportErrorForNode(
+ StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
+ } else if (_isTypeNameInIsExpression(node)) {
+ reportErrorForNode(StaticWarningCode.TYPE_TEST_WITH_NON_TYPE, typeName,
+ [typeName.name]);
+ } else if ((redirectingConstructorKind =
+ _getRedirectingConstructorKind(node)) !=
+ null) {
+ ErrorCode errorCode =
+ (redirectingConstructorKind == RedirectingConstructorKind.CONST
+ ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
+ : StaticWarningCode.REDIRECT_TO_NON_CLASS);
+ reportErrorForNode(errorCode, typeName, [typeName.name]);
+ } else if (_isTypeNameInTypeArgumentList(node)) {
+ reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
+ typeName, [typeName.name]);
+ } else {
+ AstNode parent = typeName.parent;
+ while (parent is TypeName) {
+ parent = parent.parent;
+ }
+ if (parent is ExtendsClause ||
+ parent is ImplementsClause ||
+ parent is WithClause ||
+ parent is ClassTypeAlias) {
+ // Ignored. The error will be reported elsewhere.
+ } else {
+ reportErrorForNode(
+ StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]);
+ }
+ }
+ typeName.staticType = dynamicType;
+ node.type = dynamicType;
+ return;
+ }
+ if (argumentList != null) {
+ NodeList<TypeName> arguments = argumentList.arguments;
+ int argumentCount = arguments.length;
+ List<DartType> parameters = typeSystem.typeFormalsAsTypes(type);
+ int parameterCount = parameters.length;
+ List<DartType> typeArguments = new List<DartType>(parameterCount);
+ if (argumentCount == parameterCount) {
+ for (int i = 0; i < parameterCount; i++) {
+ TypeName argumentTypeName = arguments[i];
+ DartType argumentType = _getType(argumentTypeName);
+ if (argumentType == null) {
+ argumentType = dynamicType;
+ }
+ typeArguments[i] = argumentType;
+ }
+ } else {
+ reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node,
+ [typeName.name, parameterCount, argumentCount]);
+ for (int i = 0; i < parameterCount; i++) {
+ typeArguments[i] = dynamicType;
+ }
+ }
+ type = typeSystem.instantiateType(type, typeArguments);
+ } else {
+ type = typeSystem.instantiateToBounds(type);
+ }
+ typeName.staticType = type;
+ node.type = type;
+ }
+
+ /**
+ * The number of type arguments in the given type name does not match the number of parameters in
+ * the corresponding class element. Return the error code that should be used to report this
+ * error.
+ *
+ * @param node the type name with the wrong number of type arguments
+ * @return the error code that should be used to report that the wrong number of type arguments
+ * were provided
+ */
+ ErrorCode _getInvalidTypeParametersErrorCode(TypeName node) {
+ AstNode parent = node.parent;
+ if (parent is ConstructorName) {
+ parent = parent.parent;
+ if (parent is InstanceCreationExpression) {
+ if (parent.isConst) {
+ return CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS;
+ } else {
+ return StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS;
+ }
+ }
+ }
+ return StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS;
+ }
+
+ /**
+ * Checks if the given type name is the target in a redirected constructor.
+ *
+ * @param typeName the type name to analyze
+ * @return some [RedirectingConstructorKind] if the given type name is used as the type in a
+ * redirected constructor, or `null` otherwise
+ */
+ RedirectingConstructorKind _getRedirectingConstructorKind(TypeName typeName) {
+ AstNode parent = typeName.parent;
+ if (parent is ConstructorName) {
+ AstNode grandParent = parent.parent;
+ if (grandParent is ConstructorDeclaration) {
+ if (identical(grandParent.redirectedConstructor, parent)) {
+ if (grandParent.constKeyword != null) {
+ return RedirectingConstructorKind.CONST;
+ }
+ return RedirectingConstructorKind.NORMAL;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return the type represented by the given type name.
+ *
+ * @param typeName the type name representing the type to be returned
+ * @return the type represented by the type name
+ */
+ DartType _getType(TypeName typeName) {
+ DartType type = typeName.type;
+ if (type == null) {
+ return undefinedType;
+ }
+ return type;
+ }
+
+ /**
+ * Returns the simple identifier of the given (may be qualified) type name.
+ *
+ * @param typeName the (may be qualified) qualified type name
+ * @return the simple identifier of the given (may be qualified) type name.
+ */
+ SimpleIdentifier _getTypeSimpleIdentifier(Identifier typeName) {
+ if (typeName is SimpleIdentifier) {
+ return typeName;
+ } else {
+ return (typeName as PrefixedIdentifier).identifier;
+ }
+ }
+
+ /**
+ * Given the multiple elements to which a single name could potentially be resolved, return the
+ * single interface type that should be used, or `null` if there is no clear choice.
+ *
+ * @param elements the elements to which a single name could potentially be resolved
+ * @return the single interface type that should be used for the type name
+ */
+ InterfaceType _getTypeWhenMultiplyDefined(List<Element> elements) {
+ InterfaceType type = null;
+ for (Element element in elements) {
+ if (element is ClassElement) {
+ if (type != null) {
+ return null;
+ }
+ type = element.type;
+ }
+ }
+ return type;
+ }
+
+ /**
+ * Checks if the given type name is used as the type in an as expression.
+ *
+ * @param typeName the type name to analyzer
+ * @return `true` if the given type name is used as the type in an as expression
+ */
+ bool _isTypeNameInAsExpression(TypeName typeName) {
+ AstNode parent = typeName.parent;
+ if (parent is AsExpression) {
+ return identical(parent.type, typeName);
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the given type name is used as the exception type in a catch clause.
+ *
+ * @param typeName the type name to analyzer
+ * @return `true` if the given type name is used as the exception type in a catch clause
+ */
+ bool _isTypeNameInCatchClause(TypeName typeName) {
+ AstNode parent = typeName.parent;
+ if (parent is CatchClause) {
+ return identical(parent.exceptionType, typeName);
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the given type name is used as the type in an instance creation expression.
+ *
+ * @param typeName the type name to analyzer
+ * @return `true` if the given type name is used as the type in an instance creation
+ * expression
+ */
+ bool _isTypeNameInInstanceCreationExpression(TypeName typeName) {
+ AstNode parent = typeName.parent;
+ if (parent is ConstructorName &&
+ parent.parent is InstanceCreationExpression) {
+ return parent != null && identical(parent.type, typeName);
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the given type name is used as the type in an is expression.
+ *
+ * @param typeName the type name to analyzer
+ * @return `true` if the given type name is used as the type in an is expression
+ */
+ bool _isTypeNameInIsExpression(TypeName typeName) {
+ AstNode parent = typeName.parent;
+ if (parent is IsExpression) {
+ return identical(parent.type, typeName);
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the given type name used in a type argument list.
+ *
+ * @param typeName the type name to analyzer
+ * @return `true` if the given type name is in a type argument list
+ */
+ bool _isTypeNameInTypeArgumentList(TypeName typeName) =>
+ typeName.parent is TypeArgumentList;
+
+ /**
+ * Records the new Element for a TypeName's Identifier.
+ *
+ * A null may be passed in to indicate that the element can't be resolved.
+ * (During a re-run of a task, it's important to clear any previous value
+ * of the element.)
+ */
+ void _setElement(Identifier typeName, Element element) {
+ if (typeName is SimpleIdentifier) {
+ typeName.staticElement = element;
+ } else if (typeName is PrefixedIdentifier) {
+ typeName.identifier.staticElement = element;
+ SimpleIdentifier prefix = typeName.prefix;
+ prefix.staticElement = nameScope.lookup(prefix, definingLibrary);
+ }
+ }
+
+ /**
+ * @return `true` if the name of the given [TypeName] is an built-in identifier.
+ */
+ static bool _isBuiltInIdentifier(TypeName node) {
+ Token token = node.name.beginToken;
+ return token.type == TokenType.KEYWORD;
+ }
+
+ /**
+ * @return `true` if given [TypeName] is used as a type annotation.
+ */
+ static bool _isTypeAnnotation(TypeName node) {
+ AstNode parent = node.parent;
+ if (parent is VariableDeclarationList) {
+ return identical(parent.type, node);
+ } else if (parent is FieldFormalParameter) {
+ return identical(parent.type, node);
+ } else if (parent is SimpleFormalParameter) {
+ return identical(parent.type, node);
+ }
+ return false;
+ }
+}
+
+/**
* Instances of the class `TypeOverrideManager` manage the ability to override the type of an
* element within a given context.
*/
@@ -8449,7 +8915,7 @@
*/
DartType getBestType(VariableElement element) {
DartType bestType = getType(element);
- return bestType == null ? element.type : bestType;
+ return bestType ?? element.type;
}
/**
@@ -8577,12 +9043,7 @@
if (_overridenTypes.containsKey(nonAccessor)) {
return type;
}
- if (type != null) {
- return type;
- } else if (_outerScope != null) {
- return _outerScope.getType(nonAccessor);
- }
- return null;
+ return type ?? _outerScope?.getType(element);
}
/**
@@ -8604,6 +9065,70 @@
}
/**
+ * This class resolves bounds of type parameters of classes, class and function
+ * type aliases.
+ */
+class TypeParameterBoundsResolver {
+ final TypeProvider typeProvider;
+ final LibraryElement library;
+ final Source source;
+ final AnalysisErrorListener errorListener;
+
+ Scope libraryScope = null;
+ TypeNameResolver typeNameResolver = null;
+
+ TypeParameterBoundsResolver(
+ this.typeProvider, this.library, this.source, this.errorListener);
+
+ /**
+ * Resolve bounds of type parameters of classes, class and function type
+ * aliases.
+ */
+ void resolveTypeBounds(CompilationUnit unit) {
+ for (CompilationUnitMember unitMember in unit.declarations) {
+ if (unitMember is ClassDeclaration) {
+ _resolveTypeParameters(unitMember.typeParameters,
+ () => new TypeParameterScope(libraryScope, unitMember.element));
+ } else if (unitMember is ClassTypeAlias) {
+ _resolveTypeParameters(unitMember.typeParameters,
+ () => new TypeParameterScope(libraryScope, unitMember.element));
+ } else if (unitMember is FunctionTypeAlias) {
+ _resolveTypeParameters(unitMember.typeParameters,
+ () => new FunctionTypeScope(libraryScope, unitMember.element));
+ }
+ }
+ }
+
+ void _resolveTypeName(TypeName typeName) {
+ typeName.typeArguments?.arguments?.forEach(_resolveTypeName);
+ typeNameResolver.resolveTypeName(typeName);
+ // TODO(scheglov) report error when don't apply type bounds for type bounds
+ }
+
+ void _resolveTypeParameters(
+ TypeParameterList typeParameters, Scope createTypeParametersScope()) {
+ if (typeParameters != null) {
+ Scope typeParametersScope = null;
+ for (TypeParameter typeParameter in typeParameters.typeParameters) {
+ TypeName bound = typeParameter.bound;
+ if (bound != null) {
+ libraryScope ??= new LibraryScope(library, errorListener);
+ typeParametersScope ??= createTypeParametersScope();
+ typeNameResolver ??= new TypeNameResolver(new TypeSystemImpl(),
+ typeProvider, library, source, errorListener);
+ typeNameResolver.nameScope = typeParametersScope;
+ _resolveTypeName(bound);
+ Element typeParameterElement = typeParameter.name.staticElement;
+ if (typeParameterElement is TypeParameterElementImpl) {
+ typeParameterElement.bound = bound.type;
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
* Instances of the class `TypePromotionManager` manage the ability to promote types of local
* variables and formal parameters from their declared types based on control flow.
*/
@@ -8636,31 +9161,16 @@
}
/**
- * Returns static type of the given variable - declared or promoted.
- *
- * @return the static type of the given variable - declared or promoted
+ * Return the static type of the given [variable] - declared or promoted.
*/
- DartType getStaticType(VariableElement variable) {
- DartType staticType = getType(variable);
- if (staticType == null) {
- staticType = variable.type;
- }
- return staticType;
- }
+ DartType getStaticType(VariableElement variable) =>
+ getType(variable) ?? variable.type;
/**
- * Return the promoted type of the given element, or `null` if the type of the element has
- * not been promoted.
- *
- * @param element the element whose type might have been promoted
- * @return the promoted type of the given element
+ * Return the promoted type of the given [element], or `null` if the type of
+ * the element has not been promoted.
*/
- DartType getType(Element element) {
- if (currentScope == null) {
- return null;
- }
- return currentScope.getType(element);
- }
+ DartType getType(Element element) => currentScope?.getType(element);
/**
* Set the promoted type of the given element to the given type.
@@ -9195,6 +9705,11 @@
TypeSystem _typeSystem;
/**
+ * The helper to resolve [TypeName]s.
+ */
+ TypeNameResolver _typeNameResolver;
+
+ /**
* Initialize a newly created visitor to resolve the nodes in an AST node.
*
* [definingLibrary] is the element for the library containing the node being
@@ -9218,6 +9733,8 @@
_undefinedType = typeProvider.undefinedType;
_strongMode = definingLibrary.context.analysisOptions.strongMode;
_typeSystem = TypeSystem.create(definingLibrary.context);
+ _typeNameResolver = new TypeNameResolver(
+ _typeSystem, typeProvider, definingLibrary, source, errorListener);
}
@override
@@ -9262,7 +9779,7 @@
if (exceptionTypeName == null) {
exceptionType = typeProvider.dynamicType;
} else {
- exceptionType = _getType(exceptionTypeName);
+ exceptionType = _typeNameResolver._getType(exceptionTypeName);
}
_recordType(exception, exceptionType);
Element element = exception.staticElement;
@@ -9402,7 +9919,7 @@
if (typeName == null) {
declaredType = _dynamicType;
} else {
- declaredType = _getType(typeName);
+ declaredType = _typeNameResolver._getType(typeName);
}
LocalVariableElementImpl element = node.element as LocalVariableElementImpl;
element.type = declaredType;
@@ -9429,7 +9946,7 @@
}
}
} else {
- type = _getType(typeName);
+ type = _typeNameResolver._getType(typeName);
}
element.type = type;
} else {
@@ -9531,7 +10048,7 @@
if (typeName == null) {
declaredType = _dynamicType;
} else {
- declaredType = _getType(typeName);
+ declaredType = _typeNameResolver._getType(typeName);
}
Element element = node.identifier.staticElement;
if (element is ParameterElementImpl) {
@@ -9551,265 +10068,28 @@
@override
Object visitTypeName(TypeName node) {
super.visitTypeName(node);
- Identifier typeName = node.name;
- _setElement(typeName, null); // Clear old Elements from previous run.
- TypeArgumentList argumentList = node.typeArguments;
- Element element = nameScope.lookup(typeName, definingLibrary);
- if (element == null) {
- //
- // Check to see whether the type name is either 'dynamic' or 'void',
- // neither of which are in the name scope and hence will not be found by
- // normal means.
- //
- if (typeName.name == _dynamicType.name) {
- _setElement(typeName, _dynamicType.element);
- if (argumentList != null) {
- // TODO(brianwilkerson) Report this error
-// reporter.reportError(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, node, dynamicType.getName(), 0, argumentList.getArguments().size());
- }
- typeName.staticType = _dynamicType;
- node.type = _dynamicType;
- return null;
- }
- VoidTypeImpl voidType = VoidTypeImpl.instance;
- if (typeName.name == voidType.name) {
- // There is no element for 'void'.
- if (argumentList != null) {
- // TODO(brianwilkerson) Report this error
-// reporter.reportError(StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, node, voidType.getName(), 0, argumentList.getArguments().size());
- }
- typeName.staticType = voidType;
- node.type = voidType;
- return null;
- }
- //
- // If not, the look to see whether we might have created the wrong AST
- // structure for a constructor name. If so, fix the AST structure and then
- // proceed.
- //
- AstNode parent = node.parent;
- if (typeName is PrefixedIdentifier &&
- parent is ConstructorName &&
- argumentList == null) {
- ConstructorName name = parent;
- if (name.name == null) {
- PrefixedIdentifier prefixedIdentifier =
- typeName as PrefixedIdentifier;
- SimpleIdentifier prefix = prefixedIdentifier.prefix;
- element = nameScope.lookup(prefix, definingLibrary);
- if (element is PrefixElement) {
- AstNode grandParent = parent.parent;
- if (grandParent is InstanceCreationExpression &&
- grandParent.isConst) {
- // If, if this is a const expression, then generate a
- // CompileTimeErrorCode.CONST_WITH_NON_TYPE error.
- reportErrorForNode(
- CompileTimeErrorCode.CONST_WITH_NON_TYPE,
- prefixedIdentifier.identifier,
- [prefixedIdentifier.identifier.name]);
- } else {
- // Else, if this expression is a new expression, report a
- // NEW_WITH_NON_TYPE warning.
- reportErrorForNode(
- StaticWarningCode.NEW_WITH_NON_TYPE,
- prefixedIdentifier.identifier,
- [prefixedIdentifier.identifier.name]);
- }
- _setElement(prefix, element);
- return null;
- } else if (element != null) {
- //
- // Rewrite the constructor name. The parser, when it sees a
- // constructor named "a.b", cannot tell whether "a" is a prefix and
- // "b" is a class name, or whether "a" is a class name and "b" is a
- // constructor name. It arbitrarily chooses the former, but in this
- // case was wrong.
- //
- name.name = prefixedIdentifier.identifier;
- name.period = prefixedIdentifier.period;
- node.name = prefix;
- typeName = prefix;
- }
- }
- }
- }
- // check element
- bool elementValid = element is! MultiplyDefinedElement;
- if (elementValid &&
- element is! ClassElement &&
- _isTypeNameInInstanceCreationExpression(node)) {
- SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName);
- InstanceCreationExpression creation =
- node.parent.parent as InstanceCreationExpression;
- if (creation.isConst) {
- if (element == null) {
- reportErrorForNode(
- CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typeName]);
- } else {
- reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE,
- typeNameSimple, [typeName]);
- }
- elementValid = false;
- } else {
- if (element != null) {
- reportErrorForNode(
- StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [typeName]);
- elementValid = false;
- }
- }
- }
- if (elementValid && element == null) {
- // We couldn't resolve the type name.
- // TODO(jwren) Consider moving the check for
- // CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE from the
- // ErrorVerifier, so that we don't have two errors on a built in
- // identifier being used as a class name.
- // See CompileTimeErrorCodeTest.test_builtInIdentifierAsType().
- SimpleIdentifier typeNameSimple = _getTypeSimpleIdentifier(typeName);
- RedirectingConstructorKind redirectingConstructorKind;
- if (_isBuiltInIdentifier(node) && _isTypeAnnotation(node)) {
- reportErrorForNode(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE,
- typeName, [typeName.name]);
- } else if (typeNameSimple.name == "boolean") {
- reportErrorForNode(
- StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, []);
- } else if (_isTypeNameInCatchClause(node)) {
- reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName,
- [typeName.name]);
- } else if (_isTypeNameInAsExpression(node)) {
- reportErrorForNode(
- StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
- } else if (_isTypeNameInIsExpression(node)) {
- reportErrorForNode(StaticWarningCode.TYPE_TEST_WITH_UNDEFINED_NAME,
- typeName, [typeName.name]);
- } else if ((redirectingConstructorKind =
- _getRedirectingConstructorKind(node)) !=
- null) {
- ErrorCode errorCode =
- (redirectingConstructorKind == RedirectingConstructorKind.CONST
- ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
- : StaticWarningCode.REDIRECT_TO_NON_CLASS);
- reportErrorForNode(errorCode, typeName, [typeName.name]);
- } else if (_isTypeNameInTypeArgumentList(node)) {
- reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
- typeName, [typeName.name]);
- } else {
- reportErrorForNode(
- StaticWarningCode.UNDEFINED_CLASS, typeName, [typeName.name]);
- }
- elementValid = false;
- }
- if (!elementValid) {
- if (element is MultiplyDefinedElement) {
- _setElement(typeName, element);
- }
- typeName.staticType = _undefinedType;
- node.type = _undefinedType;
- return null;
- }
- DartType type = null;
- if (element is ClassElement) {
- _setElement(typeName, element);
- type = element.type;
- } else if (element is FunctionTypeAliasElement) {
- _setElement(typeName, element);
- type = element.type;
- } else if (element is TypeParameterElement) {
- _setElement(typeName, element);
- type = element.type;
- if (argumentList != null) {
- // Type parameters cannot have type arguments.
- // TODO(brianwilkerson) Report this error.
- // resolver.reportError(ResolverErrorCode.?, keyType);
- }
- } else if (element is MultiplyDefinedElement) {
- List<Element> elements = element.conflictingElements;
- type = _getTypeWhenMultiplyDefined(elements);
- if (type != null) {
- node.type = type;
- }
- } else {
- // The name does not represent a type.
- RedirectingConstructorKind redirectingConstructorKind;
- if (_isTypeNameInCatchClause(node)) {
- reportErrorForNode(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, typeName,
- [typeName.name]);
- } else if (_isTypeNameInAsExpression(node)) {
- reportErrorForNode(
- StaticWarningCode.CAST_TO_NON_TYPE, typeName, [typeName.name]);
- } else if (_isTypeNameInIsExpression(node)) {
- reportErrorForNode(StaticWarningCode.TYPE_TEST_WITH_NON_TYPE, typeName,
- [typeName.name]);
- } else if ((redirectingConstructorKind =
- _getRedirectingConstructorKind(node)) !=
- null) {
- ErrorCode errorCode =
- (redirectingConstructorKind == RedirectingConstructorKind.CONST
- ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
- : StaticWarningCode.REDIRECT_TO_NON_CLASS);
- reportErrorForNode(errorCode, typeName, [typeName.name]);
- } else if (_isTypeNameInTypeArgumentList(node)) {
- reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
- typeName, [typeName.name]);
- } else {
- AstNode parent = typeName.parent;
- while (parent is TypeName) {
- parent = parent.parent;
- }
- if (parent is ExtendsClause ||
- parent is ImplementsClause ||
- parent is WithClause ||
- parent is ClassTypeAlias) {
- // Ignored. The error will be reported elsewhere.
- } else {
- reportErrorForNode(
- StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]);
- }
- }
- typeName.staticType = _dynamicType;
- node.type = _dynamicType;
- return null;
- }
- if (argumentList != null) {
- NodeList<TypeName> arguments = argumentList.arguments;
- int argumentCount = arguments.length;
- List<DartType> parameters = _typeSystem.typeFormalsAsTypes(type);
- int parameterCount = parameters.length;
- List<DartType> typeArguments = new List<DartType>(parameterCount);
- if (argumentCount == parameterCount) {
- for (int i = 0; i < parameterCount; i++) {
- TypeName argumentTypeName = arguments[i];
- DartType argumentType = _getType(argumentTypeName);
- if (argumentType == null) {
- argumentType = _dynamicType;
- }
- typeArguments[i] = argumentType;
- }
- } else {
- reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node,
- [typeName.name, parameterCount, argumentCount]);
- for (int i = 0; i < parameterCount; i++) {
- typeArguments[i] = _dynamicType;
- }
- }
- type = _typeSystem.instantiateType(type, typeArguments);
- } else {
- type = _typeSystem.instantiateToBounds(type);
- }
- typeName.staticType = type;
- node.type = type;
+ _typeNameResolver.nameScope = this.nameScope;
+ _typeNameResolver.resolveTypeName(node);
return null;
}
@override
Object visitTypeParameter(TypeParameter node) {
super.visitTypeParameter(node);
- TypeName bound = node.bound;
- if (bound != null) {
- TypeParameterElementImpl typeParameter =
- node.name.staticElement as TypeParameterElementImpl;
- if (typeParameter != null) {
- typeParameter.bound = bound.type;
+ AstNode parent2 = node.parent?.parent;
+ if (parent2 is ClassDeclaration ||
+ parent2 is ClassTypeAlias ||
+ parent2 is FunctionTypeAlias) {
+ // Bounds of parameters of classes and function type aliases are
+ // already resolved.
+ } else {
+ TypeName bound = node.bound;
+ if (bound != null) {
+ TypeParameterElementImpl typeParameter =
+ node.name.staticElement as TypeParameterElementImpl;
+ if (typeParameter != null) {
+ typeParameter.bound = bound.type;
+ }
}
}
return null;
@@ -9823,7 +10103,7 @@
if (typeName == null) {
declaredType = _dynamicType;
} else {
- declaredType = _getType(typeName);
+ declaredType = _typeNameResolver._getType(typeName);
}
Element element = node.name.staticElement;
if (element is VariableElement) {
@@ -9910,101 +10190,6 @@
}
/**
- * The number of type arguments in the given type name does not match the number of parameters in
- * the corresponding class element. Return the error code that should be used to report this
- * error.
- *
- * @param node the type name with the wrong number of type arguments
- * @return the error code that should be used to report that the wrong number of type arguments
- * were provided
- */
- ErrorCode _getInvalidTypeParametersErrorCode(TypeName node) {
- AstNode parent = node.parent;
- if (parent is ConstructorName) {
- parent = parent.parent;
- if (parent is InstanceCreationExpression) {
- if (parent.isConst) {
- return CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS;
- } else {
- return StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS;
- }
- }
- }
- return StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS;
- }
-
- /**
- * Checks if the given type name is the target in a redirected constructor.
- *
- * @param typeName the type name to analyze
- * @return some [RedirectingConstructorKind] if the given type name is used as the type in a
- * redirected constructor, or `null` otherwise
- */
- RedirectingConstructorKind _getRedirectingConstructorKind(TypeName typeName) {
- AstNode parent = typeName.parent;
- if (parent is ConstructorName) {
- AstNode grandParent = parent.parent;
- if (grandParent is ConstructorDeclaration) {
- if (identical(grandParent.redirectedConstructor, parent)) {
- if (grandParent.constKeyword != null) {
- return RedirectingConstructorKind.CONST;
- }
- return RedirectingConstructorKind.NORMAL;
- }
- }
- }
- return null;
- }
-
- /**
- * Return the type represented by the given type name.
- *
- * @param typeName the type name representing the type to be returned
- * @return the type represented by the type name
- */
- DartType _getType(TypeName typeName) {
- DartType type = typeName.type;
- if (type == null) {
- return _undefinedType;
- }
- return type;
- }
-
- /**
- * Returns the simple identifier of the given (may be qualified) type name.
- *
- * @param typeName the (may be qualified) qualified type name
- * @return the simple identifier of the given (may be qualified) type name.
- */
- SimpleIdentifier _getTypeSimpleIdentifier(Identifier typeName) {
- if (typeName is SimpleIdentifier) {
- return typeName;
- } else {
- return (typeName as PrefixedIdentifier).identifier;
- }
- }
-
- /**
- * Given the multiple elements to which a single name could potentially be resolved, return the
- * single interface type that should be used, or `null` if there is no clear choice.
- *
- * @param elements the elements to which a single name could potentially be resolved
- * @return the single interface type that should be used for the type name
- */
- InterfaceType _getTypeWhenMultiplyDefined(List<Element> elements) {
- InterfaceType type = null;
- for (Element element in elements) {
- if (element is ClassElement) {
- if (type != null) {
- return null;
- }
- type = element.type;
- }
- }
- return type;
- }
-
- /**
* In strong mode we infer "void" as the setter return type (as void is the
* only legal return type for a setter). This allows us to give better
* errors later if an invalid type is returned.
@@ -10019,73 +10204,6 @@
}
/**
- * Checks if the given type name is used as the type in an as expression.
- *
- * @param typeName the type name to analyzer
- * @return `true` if the given type name is used as the type in an as expression
- */
- bool _isTypeNameInAsExpression(TypeName typeName) {
- AstNode parent = typeName.parent;
- if (parent is AsExpression) {
- return identical(parent.type, typeName);
- }
- return false;
- }
-
- /**
- * Checks if the given type name is used as the exception type in a catch clause.
- *
- * @param typeName the type name to analyzer
- * @return `true` if the given type name is used as the exception type in a catch clause
- */
- bool _isTypeNameInCatchClause(TypeName typeName) {
- AstNode parent = typeName.parent;
- if (parent is CatchClause) {
- return identical(parent.exceptionType, typeName);
- }
- return false;
- }
-
- /**
- * Checks if the given type name is used as the type in an instance creation expression.
- *
- * @param typeName the type name to analyzer
- * @return `true` if the given type name is used as the type in an instance creation
- * expression
- */
- bool _isTypeNameInInstanceCreationExpression(TypeName typeName) {
- AstNode parent = typeName.parent;
- if (parent is ConstructorName &&
- parent.parent is InstanceCreationExpression) {
- return parent != null && identical(parent.type, typeName);
- }
- return false;
- }
-
- /**
- * Checks if the given type name is used as the type in an is expression.
- *
- * @param typeName the type name to analyzer
- * @return `true` if the given type name is used as the type in an is expression
- */
- bool _isTypeNameInIsExpression(TypeName typeName) {
- AstNode parent = typeName.parent;
- if (parent is IsExpression) {
- return identical(parent.type, typeName);
- }
- return false;
- }
-
- /**
- * Checks if the given type name used in a type argument list.
- *
- * @param typeName the type name to analyzer
- * @return `true` if the given type name is in a type argument list
- */
- bool _isTypeNameInTypeArgumentList(TypeName typeName) =>
- typeName.parent is TypeArgumentList;
-
- /**
* Record that the static type of the given node is the given type.
*
* @param expression the node whose type is to be recorded
@@ -10148,7 +10266,7 @@
Element element2 = identifier2.staticElement;
if (element != null && element == element2) {
detectedRepeatOnIndex[j] = true;
- reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.IMPLEMENTS_REPEATED, typeName2, [name2]);
}
}
@@ -10173,7 +10291,7 @@
if (type is InterfaceType) {
ClassElement element = type.element;
if (element != null && element.isEnum) {
- reportErrorForNode(enumTypeError, typeName);
+ errorReporter.reportErrorForNode(enumTypeError, typeName);
return null;
}
return type;
@@ -10182,9 +10300,9 @@
// to be a DynamicTypeImpl
Identifier name = typeName.name;
if (name.name == Keyword.DYNAMIC.syntax) {
- reportErrorForNode(dynamicTypeError, name, [name.name]);
+ errorReporter.reportErrorForNode(dynamicTypeError, name, [name.name]);
} else {
- reportErrorForNode(nonTypeError, name, [name.name]);
+ errorReporter.reportErrorForNode(nonTypeError, name, [name.name]);
}
return null;
}
@@ -10216,23 +10334,6 @@
}
/**
- * Records the new Element for a TypeName's Identifier.
- *
- * A null may be passed in to indicate that the element can't be resolved.
- * (During a re-run of a task, it's important to clear any previous value
- * of the element.)
- */
- void _setElement(Identifier typeName, Element element) {
- if (typeName is SimpleIdentifier) {
- typeName.staticElement = element;
- } else if (typeName is PrefixedIdentifier) {
- typeName.identifier.staticElement = element;
- SimpleIdentifier prefix = typeName.prefix;
- prefix.staticElement = nameScope.lookup(prefix, definingLibrary);
- }
- }
-
- /**
* Given a parameter element, create a function type based on the given return type and parameter
* list and associate the created type with the element.
*
@@ -10252,29 +10353,6 @@
element.type = new FunctionTypeImpl(functionElement);
functionElement.type = element.type;
}
-
- /**
- * @return `true` if the name of the given [TypeName] is an built-in identifier.
- */
- static bool _isBuiltInIdentifier(TypeName node) {
- Token token = node.name.beginToken;
- return token.type == TokenType.KEYWORD;
- }
-
- /**
- * @return `true` if given [TypeName] is used as a type annotation.
- */
- static bool _isTypeAnnotation(TypeName node) {
- AstNode parent = node.parent;
- if (parent is VariableDeclarationList) {
- return identical(parent.type, node);
- } else if (parent is FieldFormalParameter) {
- return identical(parent.type, node);
- } else if (parent is SimpleFormalParameter) {
- return identical(parent.type, node);
- }
- return false;
- }
}
/**
@@ -10714,7 +10792,7 @@
this.parameterElements,
DeclaredVariables declaredVariables,
{TypeSystem typeSystem})
- : _typeSystem = (typeSystem != null) ? typeSystem : new TypeSystemImpl(),
+ : _typeSystem = typeSystem ?? new TypeSystemImpl(),
super(
new ConstantEvaluationEngine(typeProvider, declaredVariables,
typeSystem: typeSystem),
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 65e8f95..3032565 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -14,7 +14,8 @@
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
-import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
+import 'package:analyzer/src/generated/source_io.dart'
+ show FileBasedSource, FileUriResolver, PackageUriResolver;
import 'package:analyzer/task/model.dart';
import 'package:package_config/packages.dart';
import 'package:path/path.dart' as pathos;
@@ -111,7 +112,7 @@
if (!fileUri.isAbsolute) return null;
JavaFile javaFile = new JavaFile.fromUri(fileUri);
- return new FileBasedSource(javaFile, actualUri != null ? actualUri : uri);
+ return new FileBasedSource(javaFile, actualUri ?? uri);
}
}
@@ -895,6 +896,20 @@
}
return null;
}
+
+ /**
+ * Return the URI kind corresponding to the given scheme string.
+ */
+ static UriKind fromScheme(String scheme) {
+ if (scheme == PackageUriResolver.PACKAGE_SCHEME) {
+ return UriKind.PACKAGE_URI;
+ } else if (scheme == DartUriResolver.DART_SCHEME) {
+ return UriKind.DART_URI;
+ } else if (scheme == FileUriResolver.FILE_SCHEME) {
+ return UriKind.FILE_URI;
+ }
+ return UriKind.FILE_URI;
+ }
}
/**
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 5c9c740..5b25c2c 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -98,7 +98,14 @@
@override
Source resolveAbsolute(Uri uri, [Uri actualUri]) {
- return new FileBasedSource(uriToFileMap[uri], actualUri ?? uri);
+ JavaFile file = uriToFileMap[uri];
+ actualUri ??= uri;
+ if (file == null) {
+ return new NonExistingSource(
+ uri.toString(), actualUri, UriKind.fromScheme(actualUri.scheme));
+ } else {
+ return new FileBasedSource(file, actualUri);
+ }
}
@override
@@ -169,11 +176,10 @@
* derived, otherwise a `file:` URI will be created based on the [file].
*/
FileBasedSource(JavaFile file, [Uri uri])
- : this.uri = (uri == null ? file.toURI() : uri),
+ : this.uri = uri ?? file.toURI(),
this.file = file,
id = _idTable.putIfAbsent(
- '${uri == null ? file.toURI() : uri}@${file.getPath()}',
- () => _idTable.length);
+ '${uri ?? file.toURI()}@${file.getPath()}', () => _idTable.length);
@override
TimestampedData<String> get contents {
@@ -229,14 +235,7 @@
@override
UriKind get uriKind {
String scheme = uri.scheme;
- if (scheme == PackageUriResolver.PACKAGE_SCHEME) {
- return UriKind.PACKAGE_URI;
- } else if (scheme == DartUriResolver.DART_SCHEME) {
- return UriKind.DART_URI;
- } else if (scheme == FileUriResolver.FILE_SCHEME) {
- return UriKind.FILE_URI;
- }
- return UriKind.FILE_URI;
+ return UriKind.fromScheme(scheme);
}
@override
@@ -269,8 +268,7 @@
if (!isFileUri(uri)) {
return null;
}
- return new FileBasedSource(
- new JavaFile.fromUri(uri), actualUri != null ? actualUri : uri);
+ return new FileBasedSource(new JavaFile.fromUri(uri), actualUri ?? uri);
}
@override
@@ -456,7 +454,7 @@
}
return new FileBasedSource(
getCanonicalFile(_packagesDirectories[0], pkgName, relPath),
- actualUri != null ? actualUri : uri);
+ actualUri ?? uri);
}
@override
@@ -545,7 +543,7 @@
for (JavaFile dir in _relativeDirectories) {
JavaFile file = new JavaFile.relative(dir, filePath);
if (file.exists()) {
- return new FileBasedSource(file, actualUri != null ? actualUri : uri);
+ return new FileBasedSource(file, actualUri ?? uri);
}
}
}
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index 145c4aa..69b74c6 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -229,6 +229,8 @@
registerExtension(taskId, ResolveLibraryReferencesTask.DESCRIPTOR);
registerExtension(taskId, ResolveLibraryTask.DESCRIPTOR);
registerExtension(taskId, ResolveLibraryTypeNamesTask.DESCRIPTOR);
+ registerExtension(taskId, ResolveTopLevelLibraryTypeBoundsTask.DESCRIPTOR);
+ registerExtension(taskId, ResolveTopLevelUnitTypeBoundsTask.DESCRIPTOR);
registerExtension(taskId, ResolveUnitTask.DESCRIPTOR);
registerExtension(taskId, ResolveUnitTypeNamesTask.DESCRIPTOR);
registerExtension(taskId, ResolveVariableReferencesTask.DESCRIPTOR);
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index edaf034..b47ef55 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -4208,9 +4208,11 @@
UnlinkedDocumentationCommentBuilder _documentationComment;
int _inferredReturnTypeSlot;
bool _isAbstract;
+ bool _isAsynchronous;
bool _isConst;
bool _isExternal;
bool _isFactory;
+ bool _isGenerator;
bool _isRedirectedConstructor;
bool _isStatic;
idl.UnlinkedExecutableKind _kind;
@@ -4320,6 +4322,17 @@
}
@override
+ bool get isAsynchronous => _isAsynchronous ??= false;
+
+ /**
+ * Indicates whether the executable has body marked as being asynchronous.
+ */
+ void set isAsynchronous(bool _value) {
+ assert(!_finished);
+ _isAsynchronous = _value;
+ }
+
+ @override
bool get isConst => _isConst ??= false;
/**
@@ -4353,6 +4366,17 @@
}
@override
+ bool get isGenerator => _isGenerator ??= false;
+
+ /**
+ * Indicates whether the executable has body marked as being a generator.
+ */
+ void set isGenerator(bool _value) {
+ assert(!_finished);
+ _isGenerator = _value;
+ }
+
+ @override
bool get isRedirectedConstructor => _isRedirectedConstructor ??= false;
/**
@@ -4566,7 +4590,7 @@
_visibleOffset = _value;
}
- UnlinkedExecutableBuilder({List<UnlinkedConstBuilder> annotations, CodeRangeBuilder codeRange, List<UnlinkedConstructorInitializerBuilder> constantInitializers, int constCycleSlot, UnlinkedDocumentationCommentBuilder documentationComment, int inferredReturnTypeSlot, bool isAbstract, bool isConst, bool isExternal, bool isFactory, bool isRedirectedConstructor, bool isStatic, idl.UnlinkedExecutableKind kind, List<UnlinkedExecutableBuilder> localFunctions, List<UnlinkedLabelBuilder> localLabels, List<UnlinkedVariableBuilder> localVariables, String name, int nameEnd, int nameOffset, List<UnlinkedParamBuilder> parameters, int periodOffset, EntityRefBuilder redirectedConstructor, String redirectedConstructorName, EntityRefBuilder returnType, List<UnlinkedTypeParamBuilder> typeParameters, int visibleLength, int visibleOffset})
+ UnlinkedExecutableBuilder({List<UnlinkedConstBuilder> annotations, CodeRangeBuilder codeRange, List<UnlinkedConstructorInitializerBuilder> constantInitializers, int constCycleSlot, UnlinkedDocumentationCommentBuilder documentationComment, int inferredReturnTypeSlot, bool isAbstract, bool isAsynchronous, bool isConst, bool isExternal, bool isFactory, bool isGenerator, bool isRedirectedConstructor, bool isStatic, idl.UnlinkedExecutableKind kind, List<UnlinkedExecutableBuilder> localFunctions, List<UnlinkedLabelBuilder> localLabels, List<UnlinkedVariableBuilder> localVariables, String name, int nameEnd, int nameOffset, List<UnlinkedParamBuilder> parameters, int periodOffset, EntityRefBuilder redirectedConstructor, String redirectedConstructorName, EntityRefBuilder returnType, List<UnlinkedTypeParamBuilder> typeParameters, int visibleLength, int visibleOffset})
: _annotations = annotations,
_codeRange = codeRange,
_constantInitializers = constantInitializers,
@@ -4574,9 +4598,11 @@
_documentationComment = documentationComment,
_inferredReturnTypeSlot = inferredReturnTypeSlot,
_isAbstract = isAbstract,
+ _isAsynchronous = isAsynchronous,
_isConst = isConst,
_isExternal = isExternal,
_isFactory = isFactory,
+ _isGenerator = isGenerator,
_isRedirectedConstructor = isRedirectedConstructor,
_isStatic = isStatic,
_kind = kind,
@@ -4603,7 +4629,9 @@
_codeRange = null;
_constantInitializers?.forEach((b) => b.flushInformative());
_documentationComment = null;
- _localFunctions = null;
+ _isAsynchronous = null;
+ _isGenerator = null;
+ _localFunctions?.forEach((b) => b.flushInformative());
_localLabels = null;
_localVariables = null;
_nameEnd = null;
@@ -4692,6 +4720,9 @@
if (_isAbstract == true) {
fbBuilder.addBool(10, true);
}
+ if (_isAsynchronous == true) {
+ fbBuilder.addBool(27, true);
+ }
if (_isConst == true) {
fbBuilder.addBool(12, true);
}
@@ -4701,6 +4732,9 @@
if (_isFactory == true) {
fbBuilder.addBool(8, true);
}
+ if (_isGenerator == true) {
+ fbBuilder.addBool(28, true);
+ }
if (_isRedirectedConstructor == true) {
fbBuilder.addBool(13, true);
}
@@ -4775,9 +4809,11 @@
idl.UnlinkedDocumentationComment _documentationComment;
int _inferredReturnTypeSlot;
bool _isAbstract;
+ bool _isAsynchronous;
bool _isConst;
bool _isExternal;
bool _isFactory;
+ bool _isGenerator;
bool _isRedirectedConstructor;
bool _isStatic;
idl.UnlinkedExecutableKind _kind;
@@ -4839,6 +4875,12 @@
}
@override
+ bool get isAsynchronous {
+ _isAsynchronous ??= const fb.BoolReader().vTableGet(_bp, 27, false);
+ return _isAsynchronous;
+ }
+
+ @override
bool get isConst {
_isConst ??= const fb.BoolReader().vTableGet(_bp, 12, false);
return _isConst;
@@ -4857,6 +4899,12 @@
}
@override
+ bool get isGenerator {
+ _isGenerator ??= const fb.BoolReader().vTableGet(_bp, 28, false);
+ return _isGenerator;
+ }
+
+ @override
bool get isRedirectedConstructor {
_isRedirectedConstructor ??= const fb.BoolReader().vTableGet(_bp, 13, false);
return _isRedirectedConstructor;
@@ -4970,9 +5018,11 @@
if (documentationComment != null) _result["documentationComment"] = documentationComment.toJson();
if (inferredReturnTypeSlot != 0) _result["inferredReturnTypeSlot"] = inferredReturnTypeSlot;
if (isAbstract != false) _result["isAbstract"] = isAbstract;
+ if (isAsynchronous != false) _result["isAsynchronous"] = isAsynchronous;
if (isConst != false) _result["isConst"] = isConst;
if (isExternal != false) _result["isExternal"] = isExternal;
if (isFactory != false) _result["isFactory"] = isFactory;
+ if (isGenerator != false) _result["isGenerator"] = isGenerator;
if (isRedirectedConstructor != false) _result["isRedirectedConstructor"] = isRedirectedConstructor;
if (isStatic != false) _result["isStatic"] = isStatic;
if (kind != idl.UnlinkedExecutableKind.functionOrMethod) _result["kind"] = kind.toString().split('.')[1];
@@ -5002,9 +5052,11 @@
"documentationComment": documentationComment,
"inferredReturnTypeSlot": inferredReturnTypeSlot,
"isAbstract": isAbstract,
+ "isAsynchronous": isAsynchronous,
"isConst": isConst,
"isExternal": isExternal,
"isFactory": isFactory,
+ "isGenerator": isGenerator,
"isRedirectedConstructor": isRedirectedConstructor,
"isStatic": isStatic,
"kind": kind,
@@ -8114,7 +8166,7 @@
_codeRange = null;
_constExpr?.flushInformative();
_documentationComment = null;
- _initializer = null;
+ _initializer?.flushInformative();
_nameOffset = null;
_type?.flushInformative();
}
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 97528d7..44d5544 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1624,6 +1624,11 @@
isAbstract:bool (id: 10);
/**
+ * Indicates whether the executable has body marked as being asynchronous.
+ */
+ isAsynchronous:bool (id: 27);
+
+ /**
* Indicates whether the executable is declared using the `const` keyword.
*/
isConst:bool (id: 12);
@@ -1639,6 +1644,11 @@
isFactory:bool (id: 8);
/**
+ * Indicates whether the executable has body marked as being a generator.
+ */
+ isGenerator:bool (id: 28);
+
+ /**
* Indicates whether the executable is a redirected constructor.
*/
isRedirectedConstructor:bool (id: 13);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index d83c9ef..7992ccc 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -1670,6 +1670,13 @@
bool get isAbstract;
/**
+ * Indicates whether the executable has body marked as being asynchronous.
+ */
+ @informative
+ @Id(27)
+ bool get isAsynchronous;
+
+ /**
* Indicates whether the executable is declared using the `const` keyword.
*/
@Id(12)
@@ -1688,6 +1695,13 @@
bool get isFactory;
/**
+ * Indicates whether the executable has body marked as being a generator.
+ */
+ @informative
+ @Id(28)
+ bool get isGenerator;
+
+ /**
* Indicates whether the executable is a redirected constructor.
*/
@Id(13)
@@ -1713,7 +1727,6 @@
/**
* The list of local functions.
*/
- @informative
@Id(18)
List<UnlinkedExecutable> get localFunctions;
@@ -2624,7 +2637,6 @@
* The synthetic initializer function of the variable. Absent if the variable
* does not have an initializer.
*/
- @informative
@Id(13)
UnlinkedExecutable get initializer;
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 0aff6d2..e68b5df 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -271,6 +271,9 @@
hasBeenInferred = !enclosingElement.isInBuildUnit;
@override
+ List<PropertyAccessorElementForLink> get accessors;
+
+ @override
ConstructorElementForLink get asConstructor => unnamedConstructor;
@override
@@ -323,6 +326,12 @@
_containedNames[field.name] = field;
}
}
+ for (PropertyAccessorElementForLink accessor in accessors) {
+ if (accessor.isStatic && !accessor.isSynthetic) {
+ // TODO(paulberry): add synthetic elements too?
+ _containedNames[accessor.name] = accessor;
+ }
+ }
// TODO(paulberry): add methods.
}
return _containedNames.putIfAbsent(
@@ -1290,6 +1299,7 @@
for (UnlinkedConstOperation operation in unlinkedConst.operations) {
switch (operation) {
case UnlinkedConstOperation.pushReference:
+ case UnlinkedConstOperation.invokeMethodRef:
EntityRef ref = unlinkedConst.references[refPtr++];
ConstVariableNode variable =
compilationUnit._resolveRef(ref.reference).asConstVariable;
@@ -2782,6 +2792,9 @@
@override
bool get isDartAsync => _absoluteUri == 'dart:async';
+ @override
+ bool get isDartCore => _absoluteUri == 'dart:core';
+
/**
* If this library is part of the build unit being linked, return the library
* cycle it is part of. Otherwise return `null`.
@@ -3457,7 +3470,7 @@
* linking.
*/
abstract class PropertyAccessorElementForLink
- implements PropertyAccessorElementImpl {
+ implements PropertyAccessorElementImpl, ReferenceableElementForLink {
void link(CompilationUnitElementInBuildUnit compilationUnit);
}
@@ -3478,6 +3491,18 @@
unlinkedExecutable);
@override
+ ConstructorElementForLink get asConstructor => null;
+
+ @override
+ ConstVariableNode get asConstVariable => null;
+
+ @override
+ DartType get asStaticType => returnType;
+
+ @override
+ TypeInferenceNode get asTypeInferenceNode => null;
+
+ @override
PropertyAccessorElementForLink_Executable get correspondingGetter =>
variable.getter;
@@ -3494,6 +3519,15 @@
UnlinkedExecutableKind.getter ? ElementKind.GETTER : ElementKind.SETTER;
@override
+ DartType buildType(DartType getTypeArgument(int i),
+ List<int> implicitFunctionTypeIndices) =>
+ DynamicTypeImpl.instance;
+
+ @override
+ ReferenceableElementForLink getContainedName(String name) =>
+ UndefinedElementForLink.instance;
+
+ @override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@override
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index bde6e40..e765fae 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -63,6 +63,7 @@
result == LIBRARY_ELEMENT6 ||
result == LIBRARY_ELEMENT7 ||
result == LIBRARY_ELEMENT8 ||
+ result == LIBRARY_ELEMENT9 ||
result == LIBRARY_ELEMENT ||
false) {
LibraryElement libraryElement =
@@ -70,8 +71,8 @@
entry.setValue(result, libraryElement, TargetedResult.EMPTY_LIST);
return true;
} else if (result == READY_LIBRARY_ELEMENT2 ||
- result == READY_LIBRARY_ELEMENT5 ||
- result == READY_LIBRARY_ELEMENT6) {
+ result == READY_LIBRARY_ELEMENT6 ||
+ result == READY_LIBRARY_ELEMENT7) {
entry.setValue(result, true, TargetedResult.EMPTY_LIST);
return true;
} else if (result == SOURCE_KIND) {
diff --git a/pkg/analyzer/lib/src/summary/prelink.dart b/pkg/analyzer/lib/src/summary/prelink.dart
index e98b64b..ec947f0 100644
--- a/pkg/analyzer/lib/src/summary/prelink.dart
+++ b/pkg/analyzer/lib/src/summary/prelink.dart
@@ -274,6 +274,9 @@
UnlinkedExecutableKind.functionOrMethod &&
executable.isStatic) {
kind = ReferenceKind.method;
+ } else if (executable.kind == UnlinkedExecutableKind.getter &&
+ executable.isStatic) {
+ kind = ReferenceKind.propertyAccessor;
}
if (kind != null && executable.name.isNotEmpty) {
namespace[executable.name] = new _Meaning(
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
index 5cb6e8e5..684113e 100644
--- a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
+++ b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
@@ -83,14 +83,15 @@
}
if (member is MethodDeclaration &&
member.isStatic &&
- !member.isGetter &&
!member.isSetter &&
!member.isOperator) {
String name = member.name.name;
if (isPublic(name)) {
cls.members.add(new UnlinkedPublicNameBuilder(
name: name,
- kind: ReferenceKind.method,
+ kind: member.isGetter
+ ? ReferenceKind.propertyAccessor
+ : ReferenceKind.method,
numTypeParameters:
member.typeParameters?.typeParameters?.length ?? 0));
}
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 23fecd5..749812e 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -286,9 +286,6 @@
Expression get expr => stack.single;
Expression build() {
- if (!uc.isValidConst) {
- return AstFactory.identifier3(r'$$invalidConstExpr$$');
- }
for (UnlinkedConstOperation operation in uc.operations) {
switch (operation) {
case UnlinkedConstOperation.pushNull:
@@ -564,12 +561,12 @@
void _pushExtractProperty() {
Expression target = _pop();
String name = uc.strings[stringPtr++];
- // TODO(scheglov) Only String.length property access is supported.
- assert(name == 'length');
- _push(AstFactory.propertyAccess(
- target,
- AstFactory.identifier3('length')
- ..staticElement = _getStringLengthElement()));
+ SimpleIdentifier propertyNode = AstFactory.identifier3(name);
+ // Only String.length property access can be potentially resolved.
+ if (name == 'length') {
+ propertyNode.staticElement = _getStringLengthElement();
+ }
+ _push(AstFactory.propertyAccess(target, propertyNode));
}
void _pushInstanceCreation() {
@@ -1928,7 +1925,9 @@
}
executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
executableElement, null, getCurrentTypeArguments(skipLevels: 1), false);
+ executableElement.asynchronous = serializedExecutable.isAsynchronous;
executableElement.external = serializedExecutable.isExternal;
+ executableElement.generator = serializedExecutable.isGenerator;
buildDocumentation(
executableElement, serializedExecutable.documentationComment);
buildAnnotations(executableElement, serializedExecutable.annotations);
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 3c4ddb7..35c6d01 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -7,6 +7,7 @@
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/type.dart' show DartType;
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
@@ -49,20 +50,20 @@
Identifier name = annotation.name;
EntityRefBuilder constructor;
if (name is PrefixedIdentifier && annotation.constructorName == null) {
- constructor = serializeConstructorName(
- new TypeName(name.prefix, null), name.identifier);
+ constructor =
+ serializeConstructorRef(null, name.prefix, null, name.identifier);
} else {
- constructor = serializeConstructorName(
- new TypeName(annotation.name, null), annotation.constructorName);
+ constructor = serializeConstructorRef(
+ null, annotation.name, null, annotation.constructorName);
}
serializeInstanceCreation(constructor, annotation.arguments);
}
}
@override
- EntityRefBuilder serializeConstructorName(
- TypeName type, SimpleIdentifier name) {
- EntityRefBuilder typeBuilder = serializeType(type);
+ EntityRefBuilder serializeConstructorRef(DartType type, Identifier typeName,
+ TypeArgumentList typeArguments, SimpleIdentifier name) {
+ EntityRefBuilder typeBuilder = serializeType(type, typeName, typeArguments);
if (name == null) {
return typeBuilder;
} else {
@@ -117,8 +118,9 @@
}
@override
- EntityRefBuilder serializeType(TypeName node) {
- return visitor.serializeTypeName(node);
+ EntityRefBuilder serializeType(
+ DartType type, Identifier name, TypeArgumentList arguments) {
+ return visitor.serializeType(name, arguments);
}
}
@@ -575,6 +577,8 @@
}
b.isExternal = isExternal;
b.isAbstract = !isExternal && body is EmptyFunctionBody;
+ b.isAsynchronous = body.isAsynchronous;
+ b.isGenerator = body.isGenerator;
b.name = nameString;
b.nameOffset = nameOffset;
b.typeParameters =
@@ -750,12 +754,12 @@
* a [EntityRef]. Note that this method does the right thing if the
* name doesn't refer to an entity other than a type (e.g. a class member).
*/
- EntityRefBuilder serializeTypeName(TypeName node) {
- if (node == null) {
+ EntityRefBuilder serializeType(
+ Identifier identifier, TypeArgumentList typeArguments) {
+ if (identifier == null) {
return null;
} else {
EntityRefBuilder b = new EntityRefBuilder();
- Identifier identifier = node.name;
if (identifier is SimpleIdentifier) {
String name = identifier.name;
int indexOffset = 0;
@@ -788,9 +792,9 @@
throw new StateError(
'Unexpected identifier type: ${identifier.runtimeType}');
}
- if (node.typeArguments != null) {
+ if (typeArguments != null) {
// Trailing type arguments of type 'dynamic' should be omitted.
- NodeList<TypeName> args = node.typeArguments.arguments;
+ NodeList<TypeName> args = typeArguments.arguments;
int numArgsToSerialize = args.length;
while (
numArgsToSerialize > 0 && isDynamic(args[numArgsToSerialize - 1])) {
@@ -809,6 +813,16 @@
}
/**
+ * Serialize a type name (which might be defined in a nested scope, at top
+ * level within this library, or at top level within an imported library) to
+ * a [EntityRef]. Note that this method does the right thing if the
+ * name doesn't refer to an entity other than a type (e.g. a class member).
+ */
+ EntityRefBuilder serializeTypeName(TypeName node) {
+ return serializeType(node?.name, node?.typeArguments);
+ }
+
+ /**
* Serialize the given [typeParameters] into a list of [UnlinkedTypeParam]s,
* and also store them in [typeParameterScope].
*/
@@ -950,9 +964,10 @@
b.isFactory = true;
if (node.redirectedConstructor != null) {
b.isRedirectedConstructor = true;
+ TypeName typeName = node.redirectedConstructor.type;
b.redirectedConstructor = new _ConstExprSerializer(this, null)
- .serializeConstructorName(node.redirectedConstructor.type,
- node.redirectedConstructor.name);
+ .serializeConstructorRef(null, typeName.name,
+ typeName.typeArguments, node.redirectedConstructor.name);
}
} else {
for (ConstructorInitializer initializer in node.initializers) {
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 6362f01..17a0b51 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/type.dart' show DartType;
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
@@ -103,10 +104,12 @@
/**
* Return [EntityRefBuilder] that corresponds to the constructor having name
- * [name] in the class identified by [type].
+ * [name] in the class identified by [typeName]. It is expected that [type]
+ * corresponds to the given [typeName] and [typeArguments]. The parameter
+ * [type] might be `null` if the type is not resolved.
*/
- EntityRefBuilder serializeConstructorName(
- TypeName type, SimpleIdentifier name);
+ EntityRefBuilder serializeConstructorRef(DartType type, Identifier typeName,
+ TypeArgumentList typeArguments, SimpleIdentifier name);
/**
* Return [EntityRefBuilder] that corresponds to the given [identifier].
@@ -127,9 +130,20 @@
}
/**
+ * Return [EntityRefBuilder] that corresponds to the [type] with the given
+ * [name] and [arguments]. It is expected that [type] corresponds to the
+ * given [name] and [arguments]. The parameter [type] might be `null` if the
+ * type is not resolved.
+ */
+ EntityRefBuilder serializeType(
+ DartType type, Identifier name, TypeArgumentList arguments);
+
+ /**
* Return [EntityRefBuilder] that corresponds to the given [type].
*/
- EntityRefBuilder serializeType(TypeName type);
+ EntityRefBuilder serializeTypeName(TypeName type) {
+ return serializeType(type?.type, type?.name, type?.typeArguments);
+ }
/**
* Return the [UnlinkedConstBuilder] that corresponds to the state of this
@@ -226,9 +240,10 @@
if (!expr.isConst) {
isValidConst = false;
}
+ TypeName typeName = expr.constructorName.type;
serializeInstanceCreation(
- serializeConstructorName(
- expr.constructorName.type, expr.constructorName.name),
+ serializeConstructorRef(typeName.type, typeName.name,
+ typeName.typeArguments, expr.constructorName.name),
expr.argumentList);
} else if (expr is ListLiteral) {
_serializeListLiteral(expr);
@@ -271,12 +286,12 @@
} else if (expr is AsExpression) {
isValidConst = false;
_serialize(expr.expression);
- references.add(serializeType(expr.type));
+ references.add(serializeTypeName(expr.type));
operations.add(UnlinkedConstOperation.typeCast);
} else if (expr is IsExpression) {
isValidConst = false;
_serialize(expr.expression);
- references.add(serializeType(expr.type));
+ references.add(serializeTypeName(expr.type));
operations.add(UnlinkedConstOperation.typeCheck);
} else if (expr is ThrowExpression) {
isValidConst = false;
@@ -408,7 +423,7 @@
ints.add(elements.length);
if (expr.typeArguments != null &&
expr.typeArguments.arguments.length == 1) {
- references.add(serializeType(expr.typeArguments.arguments[0]));
+ references.add(serializeTypeName(expr.typeArguments.arguments[0]));
operations.add(UnlinkedConstOperation.makeTypedList);
} else {
operations.add(UnlinkedConstOperation.makeUntypedList);
@@ -423,8 +438,8 @@
ints.add(expr.entries.length);
if (expr.typeArguments != null &&
expr.typeArguments.arguments.length == 2) {
- references.add(serializeType(expr.typeArguments.arguments[0]));
- references.add(serializeType(expr.typeArguments.arguments[1]));
+ references.add(serializeTypeName(expr.typeArguments.arguments[0]));
+ references.add(serializeTypeName(expr.typeArguments.arguments[1]));
operations.add(UnlinkedConstOperation.makeTypedMap);
} else {
operations.add(UnlinkedConstOperation.makeUntypedMap);
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 353de09..b8828ec 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -609,6 +609,7 @@
List<UnlinkedPublicNameBuilder> bs = <UnlinkedPublicNameBuilder>[];
for (FieldElement field in cls.fields) {
if (field.isStatic && field.isConst && field.isPublic) {
+ // TODO(paulberry): include non-consts
// TODO(paulberry): should numTypeParameters include class params?
bs.add(new UnlinkedPublicNameBuilder(
name: field.name,
@@ -625,6 +626,17 @@
numTypeParameters: method.typeParameters.length));
}
}
+ for (PropertyAccessorElement accessor in cls.accessors) {
+ if (accessor.isStatic &&
+ accessor.isGetter &&
+ accessor.isPublic &&
+ !accessor.isSynthetic) {
+ // TODO(paulberry): combine with field code above.
+ // TODO(paulberry): should numTypeParameters include class params?
+ bs.add(new UnlinkedPublicNameBuilder(
+ name: accessor.name, kind: ReferenceKind.propertyAccessor));
+ }
+ }
for (ConstructorElement constructor in cls.constructors) {
if (constructor.isPublic && constructor.name.isNotEmpty) {
// TODO(paulberry): should numTypeParameters include class params?
@@ -794,6 +806,8 @@
b.kind = UnlinkedExecutableKind.functionOrMethod;
}
b.isAbstract = executableElement.isAbstract;
+ b.isAsynchronous = executableElement.isAsynchronous;
+ b.isGenerator = executableElement.isGenerator;
b.isStatic = executableElement.isStatic &&
executableElement.enclosingElement is ClassElement;
b.isExternal = executableElement.isExternal;
@@ -1331,21 +1345,19 @@
EntityRefBuilder constructor;
if (nameElement is ConstructorElement && name is PrefixedIdentifier) {
assert(annotation.constructorName == null);
- constructor = serializeConstructorName(
- new TypeName(name.prefix, null)..type = nameElement.returnType,
- name.identifier);
+ constructor = serializeConstructorRef(
+ nameElement.returnType, name.prefix, null, name.identifier);
} else if (nameElement is TypeDefiningElement) {
- constructor = serializeConstructorName(
- new TypeName(annotation.name, null)..type = nameElement.type,
- annotation.constructorName);
+ constructor = serializeConstructorRef(nameElement.type, annotation.name,
+ null, annotation.constructorName);
} else if (nameElement == null) {
// Unresolved annotation.
if (name is PrefixedIdentifier && annotation.constructorName == null) {
- constructor = serializeConstructorName(
- new TypeName(name.prefix, null), name.identifier);
+ constructor =
+ serializeConstructorRef(null, name.prefix, null, name.identifier);
} else {
- constructor = serializeConstructorName(
- new TypeName(annotation.name, null), annotation.constructorName);
+ constructor = serializeConstructorRef(
+ null, annotation.name, null, annotation.constructorName);
}
} else {
throw new StateError('Unexpected annotation nameElement type:'
@@ -1356,9 +1368,9 @@
}
@override
- EntityRefBuilder serializeConstructorName(
- TypeName type, SimpleIdentifier name) {
- EntityRefBuilder typeRef = serializeType(type);
+ EntityRefBuilder serializeConstructorRef(DartType type, Identifier typeName,
+ TypeArgumentList typeArguments, SimpleIdentifier name) {
+ EntityRefBuilder typeRef = serializeType(type, typeName, typeArguments);
if (name == null) {
return typeRef;
} else {
@@ -1433,15 +1445,15 @@
}
@override
- EntityRefBuilder serializeType(TypeName typeName) {
- if (typeName != null) {
- DartType type = typeName.type;
+ EntityRefBuilder serializeType(
+ DartType type, Identifier name, TypeArgumentList arguments) {
+ if (name != null) {
if (type == null || type.isUndefined) {
- return serializeIdentifier(typeName.name);
+ return serializeIdentifier(name);
}
}
- DartType type = typeName != null ? typeName.type : DynamicTypeImpl.instance;
- return serializer.serializeTypeRef(type, context);
+ DartType typeOrDynamic = type ?? DynamicTypeImpl.instance;
+ return serializer.serializeTypeRef(typeOrDynamic, context);
}
/**
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index f38ede3..77303c3 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -65,6 +65,7 @@
result == LIBRARY_ELEMENT6 ||
result == LIBRARY_ELEMENT7 ||
result == LIBRARY_ELEMENT8 ||
+ result == LIBRARY_ELEMENT9 ||
result == LIBRARY_ELEMENT) {
// TODO(scheglov) try to find a way to avoid listing every result
// e.g. "result.whenComplete == LIBRARY_ELEMENT"
@@ -73,8 +74,8 @@
entry.setValue(result, libraryElement, TargetedResult.EMPTY_LIST);
return true;
} else if (result == READY_LIBRARY_ELEMENT2 ||
- result == READY_LIBRARY_ELEMENT5 ||
- result == READY_LIBRARY_ELEMENT6) {
+ result == READY_LIBRARY_ELEMENT6 ||
+ result == READY_LIBRARY_ELEMENT7) {
entry.setValue(result, true, TargetedResult.EMPTY_LIST);
return true;
} else if (result == SOURCE_KIND) {
@@ -102,7 +103,8 @@
result == CREATED_RESOLVED_UNIT7 ||
result == CREATED_RESOLVED_UNIT8 ||
result == CREATED_RESOLVED_UNIT9 ||
- result == CREATED_RESOLVED_UNIT10) {
+ result == CREATED_RESOLVED_UNIT10 ||
+ result == CREATED_RESOLVED_UNIT11) {
entry.setValue(result, true, TargetedResult.EMPTY_LIST);
return true;
}
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 283bca3..ca0f09d 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -233,6 +233,15 @@
new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT12', false);
/**
+ * The flag specifying that [RESOLVED_UNIT13] has been been computed for this
+ * compilation unit (without requiring that the AST for it still be in cache).
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<bool> CREATED_RESOLVED_UNIT13 =
+ new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT13', false);
+
+/**
* The flag specifying that [RESOLVED_UNIT2] has been been computed for this
* compilation unit (without requiring that the AST for it still be in cache).
*
@@ -449,7 +458,7 @@
/**
* The partial [LibraryElement] associated with a library.
*
- * [LIBRARY_ELEMENT4] plus resolved types for every element.
+ * [LIBRARY_ELEMENT5] plus resolved types type parameter bounds.
*
* The result is only available for [Source]s representing a library.
*/
@@ -460,7 +469,7 @@
/**
* The partial [LibraryElement] associated with a library.
*
- * [LIBRARY_ELEMENT5] plus propagated types for propagable variables.
+ * [LIBRARY_ELEMENT5] plus resolved types for every element.
*
* The result is only available for [Source]s representing a library.
*/
@@ -471,7 +480,7 @@
/**
* The partial [LibraryElement] associated with a library.
*
- * [LIBRARY_ELEMENT6] for the library and its import/export closure.
+ * [LIBRARY_ELEMENT6] plus propagated types for propagable variables.
*
* The result is only available for [Source]s representing a library.
*/
@@ -482,7 +491,7 @@
/**
* The partial [LibraryElement] associated with a library.
*
- * The same as a [LIBRARY_ELEMENT7].
+ * [LIBRARY_ELEMENT7] for the library and its import/export closure.
*
* The result is only available for [Source]s representing a library.
*/
@@ -491,6 +500,17 @@
cachingPolicy: ELEMENT_CACHING_POLICY);
/**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * The same as a [LIBRARY_ELEMENT8].
+ *
+ * The result is only available for [Source]s representing a library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT9 =
+ new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT9', null,
+ cachingPolicy: ELEMENT_CACHING_POLICY);
+
+/**
* The flag specifying whether all analysis errors are computed in a specific
* library.
*
@@ -582,15 +602,6 @@
new ResultDescriptor<bool>('READY_LIBRARY_ELEMENT2', false);
/**
- * The flag specifying that [LIBRARY_ELEMENT5] is ready for a library and its
- * import/export closure.
- *
- * The result is only available for [Source]s representing a library.
- */
-final ResultDescriptor<bool> READY_LIBRARY_ELEMENT5 =
- new ResultDescriptor<bool>('READY_LIBRARY_ELEMENT5', false);
-
-/**
* The flag specifying that [LIBRARY_ELEMENT6] is ready for a library and its
* import/export closure.
*
@@ -600,6 +611,15 @@
new ResultDescriptor<bool>('READY_LIBRARY_ELEMENT6', false);
/**
+ * The flag specifying that [LIBRARY_ELEMENT7] is ready for a library and its
+ * import/export closure.
+ *
+ * The result is only available for [Source]s representing a library.
+ */
+final ResultDescriptor<bool> READY_LIBRARY_ELEMENT7 =
+ new ResultDescriptor<bool>('READY_LIBRARY_ELEMENT7', false);
+
+/**
* The flag specifying that [RESOLVED_UNIT] is ready for all of the units of a
* library.
*
@@ -628,6 +648,18 @@
new ListResultDescriptor<Source>('REFERENCED_SOURCES', Source.EMPTY_LIST);
/**
+ * The errors produced while resolving bounds of type parameters of classes,
+ * class and function aliases.
+ *
+ * The list will be empty if there were no errors, but will not be `null`.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ListResultDescriptor<AnalysisError> RESOLVE_TYPE_BOUNDS_ERRORS =
+ new ListResultDescriptor<AnalysisError>(
+ 'RESOLVE_TYPE_BOUNDS_ERRORS', AnalysisError.NO_ERRORS);
+
+/**
* The errors produced while resolving type names.
*
* The list will be empty if there were no errors, but will not be `null`.
@@ -663,9 +695,11 @@
cachingPolicy: AST_CACHING_POLICY);
/**
- * The resolved [CompilationUnit] associated with a compilation unit in which
- * the types of class members have been inferred in addition to everything that
- * is true of a [RESOLVED_UNIT9].
+ * The partially resolved [CompilationUnit] associated with a compilation unit.
+ *
+ * In addition to what is true of a [RESOLVED_UNIT9], tasks that use this value
+ * as an input can assume that the initializers of instance variables have been
+ * re-resolved.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -674,8 +708,9 @@
cachingPolicy: AST_CACHING_POLICY);
/**
- * The resolved [CompilationUnit] associated with a compilation unit, with
- * constants not yet resolved.
+ * The resolved [CompilationUnit] associated with a compilation unit in which
+ * the types of class members have been inferred in addition to everything that
+ * is true of a [RESOLVED_UNIT10].
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -685,7 +720,7 @@
/**
* The resolved [CompilationUnit] associated with a compilation unit, with
- * constants resolved.
+ * constants not yet resolved.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -694,6 +729,16 @@
cachingPolicy: AST_CACHING_POLICY);
/**
+ * The resolved [CompilationUnit] associated with a compilation unit, with
+ * constants resolved.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT13 =
+ new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT13', null,
+ cachingPolicy: AST_CACHING_POLICY);
+
+/**
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT1], tasks that use this value
@@ -722,9 +767,8 @@
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT3], tasks that use this value
- * as an input can assume that the types associated with declarations have been
- * resolved. This includes the types of superclasses, mixins, interfaces,
- * fields, return types, parameters, and local variables.
+ * as an input can assume that the types associated with type bounds have been
+ * resolved.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -736,8 +780,9 @@
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT4], tasks that use this value
- * as an input can assume that references to local variables and formal
- * parameters have been resolved.
+ * as an input can assume that the types associated with declarations have been
+ * resolved. This includes the types of superclasses, mixins, interfaces,
+ * fields, return types, parameters, and local variables.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -749,9 +794,8 @@
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT5], tasks that use this value
- * as an input can assume that elements and types associated with expressions
- * outside of method bodies (essentially initializers) have been initially
- * resolved.
+ * as an input can assume that references to local variables and formal
+ * parameters have been resolved.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -763,8 +807,9 @@
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT6], tasks that use this value
- * as an input can assume that the types of final variables have been
- * propagated.
+ * as an input can assume that elements and types associated with expressions
+ * outside of method bodies (essentially initializers) have been initially
+ * resolved.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -776,7 +821,8 @@
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT7], tasks that use this value
- * as an input can assume that the types of static variables have been inferred.
+ * as an input can assume that the types of final variables have been
+ * propagated.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -788,8 +834,7 @@
* The partially resolved [CompilationUnit] associated with a compilation unit.
*
* In addition to what is true of a [RESOLVED_UNIT8], tasks that use this value
- * as an input can assume that the initializers of instance variables have been
- * re-resolved.
+ * as an input can assume that the types of static variables have been inferred.
*
* The result is only available for [LibrarySpecificUnit]s.
*/
@@ -1921,7 +1966,7 @@
class ComputeInferableStaticVariableDependenciesTask
extends InferStaticVariableTask {
/**
- * The name of the [RESOLVED_UNIT6] input.
+ * The name of the [RESOLVED_UNIT7] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -1975,7 +2020,7 @@
CompilationUnitElementImpl unit = target
.getAncestor((Element element) => element is CompilationUnitElement);
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT6
+ UNIT_INPUT: RESOLVED_UNIT7
.of(new LibrarySpecificUnit(unit.librarySource, unit.source))
};
}
@@ -2105,7 +2150,7 @@
class ComputePropagableVariableDependenciesTask
extends InferStaticVariableTask {
/**
- * The name of the [RESOLVED_UNIT6] input.
+ * The name of the [RESOLVED_UNIT7] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2160,7 +2205,7 @@
CompilationUnitElementImpl unit = target
.getAncestor((Element element) => element is CompilationUnitElement);
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT6
+ UNIT_INPUT: RESOLVED_UNIT7
.of(new LibrarySpecificUnit(unit.librarySource, unit.source))
};
}
@@ -2526,11 +2571,11 @@
}
/**
- * A task that builds [RESOLVED_UNIT12] for a unit.
+ * A task that builds [RESOLVED_UNIT13] for a unit.
*/
class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT11] input.
+ * The name of the [RESOLVED_UNIT12] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2546,7 +2591,7 @@
'EvaluateUnitConstantsTask',
createTask,
buildInputs,
- <ResultDescriptor>[CREATED_RESOLVED_UNIT12, RESOLVED_UNIT12]);
+ <ResultDescriptor>[CREATED_RESOLVED_UNIT13, RESOLVED_UNIT13]);
EvaluateUnitConstantsTask(AnalysisContext context, LibrarySpecificUnit target)
: super(context, target);
@@ -2559,8 +2604,8 @@
// No actual work needs to be performed; the task manager will ensure that
// all constants are evaluated before this method is called.
CompilationUnit unit = getRequiredInput(UNIT_INPUT);
- outputs[RESOLVED_UNIT12] = unit;
- outputs[CREATED_RESOLVED_UNIT12] = true;
+ outputs[RESOLVED_UNIT13] = unit;
+ outputs[CREATED_RESOLVED_UNIT13] = true;
}
/**
@@ -2571,8 +2616,8 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- 'libraryElement': LIBRARY_ELEMENT8.of(unit.library),
- UNIT_INPUT: RESOLVED_UNIT11.of(unit),
+ 'libraryElement': LIBRARY_ELEMENT9.of(unit.library),
+ UNIT_INPUT: RESOLVED_UNIT12.of(unit),
CONSTANT_VALUES:
COMPILATION_UNIT_CONSTANTS.of(unit).toListOf(CONSTANT_VALUE),
'constantExpressionsDependencies':
@@ -2595,7 +2640,7 @@
*/
class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT11] input.
+ * The name of the [RESOLVED_UNIT12] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2639,7 +2684,7 @@
*/
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
- return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT11.of(unit)};
+ return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT12.of(unit)};
}
/**
@@ -2657,7 +2702,7 @@
*/
class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT11] input.
+ * The name of the [RESOLVED_UNIT12] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2701,7 +2746,7 @@
*/
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
- return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT11.of(unit)};
+ return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT12.of(unit)};
}
/**
@@ -2719,7 +2764,7 @@
*/
class GenerateHintsTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT11] input.
+ * The name of the [RESOLVED_UNIT12] input.
*/
static const String RESOLVED_UNIT_INPUT = 'RESOLVED_UNIT';
@@ -2805,7 +2850,8 @@
new InheritanceManager(libraryElement);
TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
- unit.accept(new BestPracticesVerifier(errorReporter, typeProvider,
+ unit.accept(new BestPracticesVerifier(
+ errorReporter, typeProvider, libraryElement,
typeSystem: typeSystem));
unit.accept(new OverrideVerifier(errorReporter, inheritanceManager));
// Find to-do comments.
@@ -2939,7 +2985,7 @@
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the input whose value is the [RESOLVED_UNIT8] for the
+ * The name of the input whose value is the [RESOLVED_UNIT9] for the
* compilation unit.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -2951,7 +2997,7 @@
'InferInstanceMembersInUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[CREATED_RESOLVED_UNIT10, RESOLVED_UNIT10]);
+ <ResultDescriptor>[CREATED_RESOLVED_UNIT11, RESOLVED_UNIT11]);
/**
* Initialize a newly created task to build a library element for the given
@@ -2983,8 +3029,8 @@
//
// Record outputs.
//
- outputs[RESOLVED_UNIT10] = unit;
- outputs[CREATED_RESOLVED_UNIT10] = true;
+ outputs[RESOLVED_UNIT11] = unit;
+ outputs[CREATED_RESOLVED_UNIT11] = true;
}
/**
@@ -2995,7 +3041,7 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT9.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT10.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
// In strong mode, add additional dependencies to enforce inference
// ordering.
@@ -3003,14 +3049,14 @@
// Require that field re-resolution be complete for all units in the
// current library cycle.
'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT9.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source))),
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source)))
@@ -3081,7 +3127,7 @@
*/
class InferStaticVariableTypesInUnitTask extends SourceBasedAnalysisTask {
/**
- * The name of the input whose value is the [RESOLVED_UNIT7] for the
+ * The name of the input whose value is the [RESOLVED_UNIT8] for the
* compilation unit.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3099,7 +3145,7 @@
'InferStaticVariableTypesInUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[CREATED_RESOLVED_UNIT8, RESOLVED_UNIT8]);
+ <ResultDescriptor>[CREATED_RESOLVED_UNIT9, RESOLVED_UNIT9]);
/**
* Initialize a newly created task to build a library element for the given
@@ -3123,8 +3169,8 @@
// because the work has implicitly been done by virtue of the task model
// preparing all of the inputs.
//
- outputs[RESOLVED_UNIT8] = unit;
- outputs[CREATED_RESOLVED_UNIT8] = true;
+ outputs[RESOLVED_UNIT9] = unit;
+ outputs[CREATED_RESOLVED_UNIT9] = true;
}
/**
@@ -3138,7 +3184,7 @@
INFERRED_VARIABLES_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT
.of(unit)
.toListOf(INFERRED_STATIC_VARIABLE),
- UNIT_INPUT: RESOLVED_UNIT7.of(unit)
+ UNIT_INPUT: RESOLVED_UNIT8.of(unit)
};
}
@@ -3169,7 +3215,7 @@
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the [RESOLVED_UNIT7] input.
+ * The name of the [RESOLVED_UNIT8] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3260,14 +3306,14 @@
.of(variable)
.toListOf(INFERRED_STATIC_VARIABLE),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
- UNIT_INPUT: RESOLVED_UNIT7.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT8.of(unit),
// In strong mode, add additional dependencies to enforce inference
// ordering.
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source)))
@@ -3369,6 +3415,12 @@
'RESOLVE_TYPE_NAMES_ERRORS';
/**
+ * The name of the [RESOLVE_TYPE_BOUNDS_ERRORS] input.
+ */
+ static const String RESOLVE_TYPE_NAMES_ERRORS2_INPUT =
+ 'RESOLVE_TYPE_NAMES_ERRORS2';
+
+ /**
* The name of the [RESOLVE_UNIT_ERRORS] input.
*/
static const String RESOLVE_UNIT_ERRORS_INPUT = 'RESOLVE_UNIT_ERRORS';
@@ -3410,6 +3462,7 @@
errorLists.add(getRequiredInput(HINTS_INPUT));
errorLists.add(getRequiredInput(LINTS_INPUT));
errorLists.add(getRequiredInput(RESOLVE_TYPE_NAMES_ERRORS_INPUT));
+ errorLists.add(getRequiredInput(RESOLVE_TYPE_NAMES_ERRORS2_INPUT));
errorLists.add(getRequiredInput(RESOLVE_UNIT_ERRORS_INPUT));
errorLists.add(getRequiredInput(STRONG_MODE_ERRORS_INPUT));
errorLists.add(getRequiredInput(VARIABLE_REFERENCE_ERRORS_INPUT));
@@ -3431,6 +3484,7 @@
HINTS_INPUT: HINTS.of(unit),
LINTS_INPUT: LINTS.of(unit),
RESOLVE_TYPE_NAMES_ERRORS_INPUT: RESOLVE_TYPE_NAMES_ERRORS.of(unit),
+ RESOLVE_TYPE_NAMES_ERRORS2_INPUT: RESOLVE_TYPE_BOUNDS_ERRORS.of(unit),
RESOLVE_UNIT_ERRORS_INPUT: RESOLVE_UNIT_ERRORS.of(unit),
STRONG_MODE_ERRORS_INPUT: STRONG_MODE_ERRORS.of(unit),
VARIABLE_REFERENCE_ERRORS_INPUT: VARIABLE_REFERENCE_ERRORS.of(unit),
@@ -3673,16 +3727,16 @@
}
/**
- * A task that builds [RESOLVED_UNIT6] for a unit.
+ * A task that builds [RESOLVED_UNIT7] for a unit.
*/
class PartiallyResolveUnitReferencesTask extends SourceBasedAnalysisTask {
/**
- * The name of the [LIBRARY_ELEMENT5] input.
+ * The name of the [LIBRARY_ELEMENT6] input.
*/
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
/**
- * The name of the [RESOLVED_UNIT5] input.
+ * The name of the [RESOLVED_UNIT6] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3700,8 +3754,8 @@
buildInputs, <ResultDescriptor>[
INFERABLE_STATIC_VARIABLES_IN_UNIT,
PROPAGABLE_VARIABLES_IN_UNIT,
- CREATED_RESOLVED_UNIT6,
- RESOLVED_UNIT6
+ CREATED_RESOLVED_UNIT7,
+ RESOLVED_UNIT7
]);
PartiallyResolveUnitReferencesTask(
@@ -3735,8 +3789,8 @@
outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = VariableElement.EMPTY_LIST;
}
outputs[PROPAGABLE_VARIABLES_IN_UNIT] = visitor.propagableVariables;
- outputs[RESOLVED_UNIT6] = unit;
- outputs[CREATED_RESOLVED_UNIT6] = true;
+ outputs[RESOLVED_UNIT7] = unit;
+ outputs[CREATED_RESOLVED_UNIT7] = true;
}
/**
@@ -3747,9 +3801,9 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- 'fullyBuiltLibraryElements': READY_LIBRARY_ELEMENT5.of(unit.library),
- LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library),
- UNIT_INPUT: RESOLVED_UNIT5.of(unit),
+ 'fullyBuiltLibraryElements': READY_LIBRARY_ELEMENT6.of(unit.library),
+ LIBRARY_INPUT: LIBRARY_ELEMENT6.of(unit.library),
+ UNIT_INPUT: RESOLVED_UNIT6.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
// In strong mode, add additional dependencies to enforce inference
// ordering.
@@ -3757,7 +3811,7 @@
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source)))
@@ -3781,7 +3835,7 @@
class PropagateVariableTypesInLibraryClosureTask
extends SourceBasedAnalysisTask {
/**
- * The name of the [LIBRARY_ELEMENT6] input.
+ * The name of the [LIBRARY_ELEMENT7] input.
*/
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
@@ -3792,7 +3846,7 @@
'PropagateVariableTypesInLibraryClosureTask',
createTask,
buildInputs,
- <ResultDescriptor>[LIBRARY_ELEMENT7]);
+ <ResultDescriptor>[LIBRARY_ELEMENT8]);
PropagateVariableTypesInLibraryClosureTask(
InternalAnalysisContext context, AnalysisTarget target)
@@ -3804,6 +3858,61 @@
@override
void internalPerform() {
LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+ outputs[LIBRARY_ELEMENT8] = library;
+ }
+
+ /**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the
+ * given [target].
+ */
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+ Source source = target;
+ return <String, TaskInput>{
+ 'readyForClosure': READY_LIBRARY_ELEMENT7.of(source),
+ LIBRARY_INPUT: LIBRARY_ELEMENT7.of(source),
+ };
+ }
+
+ /**
+ * Create a [PropagateVariableTypesInLibraryClosureTask] based on the given
+ * [target] in the given [context].
+ */
+ static PropagateVariableTypesInLibraryClosureTask createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new PropagateVariableTypesInLibraryClosureTask(context, target);
+ }
+}
+
+/**
+ * An artificial task that does nothing except to force propagated types for
+ * all propagable variables in the defining and part units of a library.
+ */
+class PropagateVariableTypesInLibraryTask extends SourceBasedAnalysisTask {
+ /**
+ * The name of the [LIBRARY_ELEMENT6] input.
+ */
+ static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+ /**
+ * The task descriptor describing this kind of task.
+ */
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'PropagateVariableTypesInLibraryTask',
+ createTask,
+ buildInputs,
+ <ResultDescriptor>[LIBRARY_ELEMENT7]);
+
+ PropagateVariableTypesInLibraryTask(
+ InternalAnalysisContext context, AnalysisTarget target)
+ : super(context, target);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ void internalPerform() {
+ LibraryElement library = getRequiredInput(LIBRARY_INPUT);
outputs[LIBRARY_ELEMENT7] = library;
}
@@ -3815,64 +3924,9 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
Source source = target;
return <String, TaskInput>{
- 'readyForClosure': READY_LIBRARY_ELEMENT6.of(source),
- LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source),
- };
- }
-
- /**
- * Create a [PropagateVariableTypesInLibraryClosureTask] based on the given
- * [target] in the given [context].
- */
- static PropagateVariableTypesInLibraryClosureTask createTask(
- AnalysisContext context, AnalysisTarget target) {
- return new PropagateVariableTypesInLibraryClosureTask(context, target);
- }
-}
-
-/**
- * An artificial task that does nothing except to force propagated types for
- * all propagable variables in the defining and part units of a library.
- */
-class PropagateVariableTypesInLibraryTask extends SourceBasedAnalysisTask {
- /**
- * The name of the [LIBRARY_ELEMENT5] input.
- */
- static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
-
- /**
- * The task descriptor describing this kind of task.
- */
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
- 'PropagateVariableTypesInLibraryTask',
- createTask,
- buildInputs,
- <ResultDescriptor>[LIBRARY_ELEMENT6]);
-
- PropagateVariableTypesInLibraryTask(
- InternalAnalysisContext context, AnalysisTarget target)
- : super(context, target);
-
- @override
- TaskDescriptor get descriptor => DESCRIPTOR;
-
- @override
- void internalPerform() {
- LibraryElement library = getRequiredInput(LIBRARY_INPUT);
- outputs[LIBRARY_ELEMENT6] = library;
- }
-
- /**
- * Return a map from the names of the inputs of this kind of task to the task
- * input descriptors describing those inputs for a task with the
- * given [target].
- */
- static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
- Source source = target;
- return <String, TaskInput>{
'propagatedVariableTypesInUnits':
- LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT7),
- LIBRARY_INPUT: LIBRARY_ELEMENT5.of(source),
+ LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT8),
+ LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source),
};
}
@@ -3892,7 +3946,7 @@
*/
class PropagateVariableTypesInUnitTask extends SourceBasedAnalysisTask {
/**
- * The name of the input whose value is the [RESOLVED_UNIT6] for the
+ * The name of the input whose value is the [RESOLVED_UNIT7] for the
* compilation unit.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3904,7 +3958,7 @@
'PropagateVariableTypesInUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[CREATED_RESOLVED_UNIT7, RESOLVED_UNIT7]);
+ <ResultDescriptor>[CREATED_RESOLVED_UNIT8, RESOLVED_UNIT8]);
PropagateVariableTypesInUnitTask(
InternalAnalysisContext context, LibrarySpecificUnit unit)
@@ -3924,8 +3978,8 @@
// because the work has implicitly been done by virtue of the task model
// preparing all of the inputs.
//
- outputs[RESOLVED_UNIT7] = unit;
- outputs[CREATED_RESOLVED_UNIT7] = true;
+ outputs[RESOLVED_UNIT8] = unit;
+ outputs[CREATED_RESOLVED_UNIT8] = true;
}
/**
@@ -3938,7 +3992,7 @@
return <String, TaskInput>{
'variables':
PROPAGABLE_VARIABLES_IN_UNIT.of(unit).toListOf(PROPAGATED_VARIABLE),
- UNIT_INPUT: RESOLVED_UNIT6.of(unit)
+ UNIT_INPUT: RESOLVED_UNIT7.of(unit)
};
}
@@ -3963,7 +4017,7 @@
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the [RESOLVED_UNIT6] input.
+ * The name of the [RESOLVED_UNIT7] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -4049,7 +4103,7 @@
.of(variable)
.toListOf(PROPAGATED_VARIABLE),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
- UNIT_INPUT: RESOLVED_UNIT6.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT7.of(unit),
};
}
@@ -4107,7 +4161,7 @@
}
/**
- * A task that ensures that [LIBRARY_ELEMENT5] is ready for the target library
+ * A task that ensures that [LIBRARY_ELEMENT6] is ready for the target library
* source and its import/export closure.
*/
class ReadyLibraryElement5Task extends SourceBasedAnalysisTask {
@@ -4115,52 +4169,9 @@
'ReadyLibraryElement5Task',
createTask,
buildInputs,
- <ResultDescriptor>[READY_LIBRARY_ELEMENT5]);
-
- ReadyLibraryElement5Task(
- InternalAnalysisContext context, AnalysisTarget target)
- : super(context, target);
-
- @override
- TaskDescriptor get descriptor => DESCRIPTOR;
-
- @override
- bool get handlesDependencyCycles => true;
-
- @override
- void internalPerform() {
- outputs[READY_LIBRARY_ELEMENT5] = true;
- }
-
- static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
- Source source = target;
- return <String, TaskInput>{
- 'thisLibraryElementReady': LIBRARY_ELEMENT5.of(source),
- 'directlyImportedLibrariesReady':
- IMPORTED_LIBRARIES.of(source).toListOf(READY_LIBRARY_ELEMENT5),
- 'directlyExportedLibrariesReady':
- EXPORTED_LIBRARIES.of(source).toListOf(READY_LIBRARY_ELEMENT5),
- };
- }
-
- static ReadyLibraryElement5Task createTask(
- AnalysisContext context, AnalysisTarget target) {
- return new ReadyLibraryElement5Task(context, target);
- }
-}
-
-/**
- * A task that ensures that [LIBRARY_ELEMENT6] is ready for the target library
- * source and its import/export closure.
- */
-class ReadyLibraryElement6Task extends SourceBasedAnalysisTask {
- static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
- 'ReadyLibraryElement6Task',
- createTask,
- buildInputs,
<ResultDescriptor>[READY_LIBRARY_ELEMENT6]);
- ReadyLibraryElement6Task(
+ ReadyLibraryElement5Task(
InternalAnalysisContext context, AnalysisTarget target)
: super(context, target);
@@ -4186,6 +4197,49 @@
};
}
+ static ReadyLibraryElement5Task createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new ReadyLibraryElement5Task(context, target);
+ }
+}
+
+/**
+ * A task that ensures that [LIBRARY_ELEMENT7] is ready for the target library
+ * source and its import/export closure.
+ */
+class ReadyLibraryElement6Task extends SourceBasedAnalysisTask {
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'ReadyLibraryElement6Task',
+ createTask,
+ buildInputs,
+ <ResultDescriptor>[READY_LIBRARY_ELEMENT7]);
+
+ ReadyLibraryElement6Task(
+ InternalAnalysisContext context, AnalysisTarget target)
+ : super(context, target);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ bool get handlesDependencyCycles => true;
+
+ @override
+ void internalPerform() {
+ outputs[READY_LIBRARY_ELEMENT7] = true;
+ }
+
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+ Source source = target;
+ return <String, TaskInput>{
+ 'thisLibraryElementReady': LIBRARY_ELEMENT7.of(source),
+ 'directlyImportedLibrariesReady':
+ IMPORTED_LIBRARIES.of(source).toListOf(READY_LIBRARY_ELEMENT7),
+ 'directlyExportedLibrariesReady':
+ EXPORTED_LIBRARIES.of(source).toListOf(READY_LIBRARY_ELEMENT7),
+ };
+ }
+
static ReadyLibraryElement6Task createTask(
AnalysisContext context, AnalysisTarget target) {
return new ReadyLibraryElement6Task(context, target);
@@ -4373,7 +4427,7 @@
'Cannot build inputs for a ${target.runtimeType}');
}
return <String, TaskInput>{
- 'createdResolvedUnit': CREATED_RESOLVED_UNIT11
+ 'createdResolvedUnit': CREATED_RESOLVED_UNIT12
.of(new LibrarySpecificUnit(librarySource, target.source))
};
}
@@ -4468,7 +4522,7 @@
*/
class ResolveInstanceFieldsInUnitTask extends SourceBasedAnalysisTask {
/**
- * The name of the [LIBRARY_ELEMENT5] input.
+ * The name of the [LIBRARY_ELEMENT6] input.
*/
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
@@ -4478,7 +4532,7 @@
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the input whose value is the [RESOLVED_UNIT8] for the
+ * The name of the input whose value is the [RESOLVED_UNIT9] for the
* compilation unit.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -4490,7 +4544,7 @@
'ResolveInstanceFieldsInUnitTask',
createTask,
buildInputs,
- <ResultDescriptor>[CREATED_RESOLVED_UNIT9, RESOLVED_UNIT9]);
+ <ResultDescriptor>[CREATED_RESOLVED_UNIT10, RESOLVED_UNIT10]);
/**
* Initialize a newly created task to build a library element for the given
@@ -4527,8 +4581,8 @@
//
// Record outputs.
//
- outputs[RESOLVED_UNIT9] = unit;
- outputs[CREATED_RESOLVED_UNIT9] = true;
+ outputs[RESOLVED_UNIT10] = unit;
+ outputs[CREATED_RESOLVED_UNIT10] = true;
}
/**
@@ -4539,8 +4593,8 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT8.of(unit),
- LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library),
+ UNIT_INPUT: RESOLVED_UNIT9.of(unit),
+ LIBRARY_INPUT: LIBRARY_ELEMENT6.of(unit.library),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
// In strong mode, add additional dependencies to enforce inference
// ordering.
@@ -4548,14 +4602,14 @@
// Require that static variable inference be complete for all units in
// the current library cycle.
'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT8.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT9.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source))),
// Require that full inference be complete for all dependencies of the
// current library cycle.
'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source)))
@@ -4573,17 +4627,17 @@
}
/**
- * A task that finishes resolution by requesting [RESOLVED_UNIT11] for every
- * unit in the libraries closure and produces [LIBRARY_ELEMENT8].
+ * A task that finishes resolution by requesting [RESOLVED_UNIT12] for every
+ * unit in the libraries closure and produces [LIBRARY_ELEMENT9].
*/
class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask {
/**
- * The name of the [LIBRARY_ELEMENT7] input.
+ * The name of the [LIBRARY_ELEMENT8] input.
*/
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
/**
- * The name of the list of [RESOLVED_UNIT11] input.
+ * The name of the list of [RESOLVED_UNIT12] input.
*/
static const String UNITS_INPUT = 'UNITS_INPUT';
@@ -4594,7 +4648,7 @@
'ResolveLibraryReferencesTask',
createTask,
buildInputs,
- <ResultDescriptor>[LIBRARY_ELEMENT8, REFERENCED_NAMES]);
+ <ResultDescriptor>[LIBRARY_ELEMENT9, REFERENCED_NAMES]);
ResolveLibraryReferencesTask(
InternalAnalysisContext context, AnalysisTarget target)
@@ -4618,7 +4672,7 @@
//
// Record outputs.
//
- outputs[LIBRARY_ELEMENT8] = library;
+ outputs[LIBRARY_ELEMENT9] = library;
outputs[REFERENCED_NAMES] = referencedNames;
}
@@ -4630,8 +4684,8 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
Source source = target;
return <String, TaskInput>{
- LIBRARY_INPUT: LIBRARY_ELEMENT7.of(source),
- UNITS_INPUT: LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT11),
+ LIBRARY_INPUT: LIBRARY_ELEMENT8.of(source),
+ UNITS_INPUT: LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT12),
};
}
@@ -4646,17 +4700,17 @@
}
/**
- * A task that finishes resolution by requesting [RESOLVED_UNIT12] for every
+ * A task that finishes resolution by requesting [RESOLVED_UNIT13] for every
* unit in the libraries closure and produces [LIBRARY_ELEMENT].
*/
class ResolveLibraryTask extends SourceBasedAnalysisTask {
/**
- * The name of the [LIBRARY_ELEMENT8] input.
+ * The name of the [LIBRARY_ELEMENT9] input.
*/
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
/**
- * The name of the list of [RESOLVED_UNIT12] input.
+ * The name of the list of [RESOLVED_UNIT13] input.
*/
static const String UNITS_INPUT = 'UNITS_INPUT';
@@ -4695,7 +4749,7 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
Source source = target;
return <String, TaskInput>{
- LIBRARY_INPUT: LIBRARY_ELEMENT8.of(source),
+ LIBRARY_INPUT: LIBRARY_ELEMENT9.of(source),
'thisLibraryClosureIsReady': READY_RESOLVED_UNIT.of(source),
};
}
@@ -4716,7 +4770,7 @@
*/
class ResolveLibraryTypeNamesTask extends SourceBasedAnalysisTask {
/**
- * The name of the [LIBRARY_ELEMENT4] input.
+ * The name of the [LIBRARY_ELEMENT5] input.
*/
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
@@ -4732,7 +4786,7 @@
'ResolveLibraryTypeNamesTask',
createTask,
buildInputs,
- <ResultDescriptor>[LIBRARY_ELEMENT5]);
+ <ResultDescriptor>[LIBRARY_ELEMENT6]);
ResolveLibraryTypeNamesTask(
InternalAnalysisContext context, AnalysisTarget target)
@@ -4755,7 +4809,7 @@
//
// Record outputs.
//
- outputs[LIBRARY_ELEMENT5] = library;
+ outputs[LIBRARY_ELEMENT6] = library;
}
/**
@@ -4767,8 +4821,8 @@
Source source = target;
return <String, TaskInput>{
'resolvedUnit':
- LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT4),
- LIBRARY_INPUT: LIBRARY_ELEMENT4.of(source),
+ LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT5),
+ LIBRARY_INPUT: LIBRARY_ELEMENT5.of(source),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
};
}
@@ -4784,12 +4838,167 @@
}
/**
+ * An artificial task that does nothing except to force type parameter bounds
+ * type names resolution for the defining and part units of a library.
+ */
+class ResolveTopLevelLibraryTypeBoundsTask extends SourceBasedAnalysisTask {
+ /**
+ * The name of the [LIBRARY_ELEMENT4] input.
+ */
+ static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+ /**
+ * The task descriptor describing this kind of task.
+ */
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'ResolveTopLevelLibraryTypeBoundsTask',
+ createTask,
+ buildInputs,
+ <ResultDescriptor>[LIBRARY_ELEMENT5]);
+
+ ResolveTopLevelLibraryTypeBoundsTask(
+ InternalAnalysisContext context, AnalysisTarget target)
+ : super(context, target);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ bool get handlesDependencyCycles => true;
+
+ @override
+ void internalPerform() {
+ LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+ outputs[LIBRARY_ELEMENT5] = library;
+ }
+
+ /**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the
+ * given [target].
+ */
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+ Source source = target;
+ return <String, TaskInput>{
+ LIBRARY_INPUT: LIBRARY_ELEMENT4.of(source),
+ 'thisLibraryUnitsReady':
+ LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT4),
+ 'directlyImportedLibrariesReady':
+ IMPORTED_LIBRARIES.of(source).toListOf(LIBRARY_ELEMENT5),
+ 'directlyExportedLibrariesReady':
+ EXPORTED_LIBRARIES.of(source).toListOf(LIBRARY_ELEMENT5),
+ };
+ }
+
+ /**
+ * Create a [ResolveTopLevelLibraryTypeBoundsTask] based on the given [target]
+ * in the given [context].
+ */
+ static ResolveTopLevelLibraryTypeBoundsTask createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new ResolveTopLevelLibraryTypeBoundsTask(context, target);
+ }
+}
+
+/**
+ * A task that builds [RESOLVED_UNIT4] for a unit.
+ */
+class ResolveTopLevelUnitTypeBoundsTask extends SourceBasedAnalysisTask {
+ /**
+ * The name of the input whose value is the defining [LIBRARY_ELEMENT4].
+ */
+ static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+ /**
+ * The name of the [RESOLVED_UNIT3] input.
+ */
+ static const String UNIT_INPUT = 'UNIT_INPUT';
+
+ /**
+ * The name of the [TYPE_PROVIDER] input.
+ */
+ static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
+
+ /**
+ * The task descriptor describing this kind of task.
+ */
+ static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+ 'ResolveTopLevelUnitTypeBoundsTask',
+ createTask,
+ buildInputs, <ResultDescriptor>[
+ RESOLVE_TYPE_BOUNDS_ERRORS,
+ CREATED_RESOLVED_UNIT4,
+ RESOLVED_UNIT4
+ ]);
+
+ ResolveTopLevelUnitTypeBoundsTask(
+ InternalAnalysisContext context, AnalysisTarget target)
+ : super(context, target);
+
+ @override
+ TaskDescriptor get descriptor => DESCRIPTOR;
+
+ @override
+ void internalPerform() {
+ //
+ // Prepare inputs.
+ //
+ LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+ CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+ CompilationUnitElement unitElement = unit.element;
+ TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
+ //
+ // Resolve TypeName nodes.
+ //
+ RecordingErrorListener errorListener = new RecordingErrorListener();
+ new TypeParameterBoundsResolver(
+ typeProvider, library, unitElement.source, errorListener)
+ .resolveTypeBounds(unit);
+ //
+ // Record outputs.
+ //
+ outputs[RESOLVE_TYPE_BOUNDS_ERRORS] =
+ getTargetSourceErrors(errorListener, target);
+ outputs[RESOLVED_UNIT4] = unit;
+ outputs[CREATED_RESOLVED_UNIT4] = true;
+ }
+
+ /**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the
+ * given [target].
+ */
+ static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+ // TODO(brianwilkerson) This task updates the element model to have type
+ // information and updates the class hierarchy. It should produce a new
+ // version of the element model in order to record those changes.
+ LibrarySpecificUnit unit = target;
+ return <String, TaskInput>{
+ 'importsExportNamespace':
+ IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4),
+ LIBRARY_INPUT: LIBRARY_ELEMENT4.of(unit.library),
+ UNIT_INPUT: RESOLVED_UNIT3.of(unit),
+ TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
+ };
+ }
+
+ /**
+ * Create a [ResolveTopLevelUnitTypeBoundsTask] based on the given [target] in
+ * the given [context].
+ */
+ static ResolveTopLevelUnitTypeBoundsTask createTask(
+ AnalysisContext context, AnalysisTarget target) {
+ return new ResolveTopLevelUnitTypeBoundsTask(context, target);
+ }
+}
+
+/**
* A task that resolves the bodies of top-level functions, constructors, and
* methods within a single compilation unit.
*/
class ResolveUnitTask extends SourceBasedAnalysisTask {
/**
- * The name of the input whose value is the defining [LIBRARY_ELEMENT7].
+ * The name of the input whose value is the defining [LIBRARY_ELEMENT8].
*/
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
@@ -4799,7 +5008,7 @@
static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
/**
- * The name of the [RESOLVED_UNIT10] input.
+ * The name of the [RESOLVED_UNIT11] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -4807,8 +5016,8 @@
'ResolveUnitTask', createTask, buildInputs, <ResultDescriptor>[
CONSTANT_EXPRESSIONS_DEPENDENCIES,
RESOLVE_UNIT_ERRORS,
- CREATED_RESOLVED_UNIT11,
- RESOLVED_UNIT11
+ CREATED_RESOLVED_UNIT12,
+ RESOLVED_UNIT12
]);
ResolveUnitTask(
@@ -4854,8 +5063,8 @@
//
outputs[CONSTANT_EXPRESSIONS_DEPENDENCIES] = constExprDependencies;
outputs[RESOLVE_UNIT_ERRORS] = getTargetSourceErrors(errorListener, target);
- outputs[RESOLVED_UNIT11] = unit;
- outputs[CREATED_RESOLVED_UNIT11] = true;
+ outputs[RESOLVED_UNIT12] = unit;
+ outputs[CREATED_RESOLVED_UNIT12] = true;
}
/**
@@ -4866,16 +5075,16 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- LIBRARY_INPUT: LIBRARY_ELEMENT7.of(unit.library),
+ LIBRARY_INPUT: LIBRARY_ELEMENT8.of(unit.library),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
- UNIT_INPUT: RESOLVED_UNIT10.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT11.of(unit),
// In strong mode, add additional dependencies to enforce inference
// ordering.
// Require that inference be complete for all units in the
// current library cycle.
'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit).toList(
- (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+ (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
new LibrarySpecificUnit(
(unit as CompilationUnitElementImpl).librarySource,
unit.source)))
@@ -4893,16 +5102,16 @@
}
/**
- * A task that builds [RESOLVED_UNIT4] for a unit.
+ * A task that builds [RESOLVED_UNIT5] for a unit.
*/
class ResolveUnitTypeNamesTask extends SourceBasedAnalysisTask {
/**
- * The name of the input whose value is the defining [LIBRARY_ELEMENT4].
+ * The name of the input whose value is the defining [LIBRARY_ELEMENT5].
*/
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
/**
- * The name of the [RESOLVED_UNIT3] input.
+ * The name of the [RESOLVED_UNIT4] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -4917,8 +5126,8 @@
static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
'ResolveUnitTypeNamesTask', createTask, buildInputs, <ResultDescriptor>[
RESOLVE_TYPE_NAMES_ERRORS,
- CREATED_RESOLVED_UNIT4,
- RESOLVED_UNIT4
+ CREATED_RESOLVED_UNIT5,
+ RESOLVED_UNIT5
]);
ResolveUnitTypeNamesTask(
@@ -4949,8 +5158,8 @@
//
outputs[RESOLVE_TYPE_NAMES_ERRORS] =
getTargetSourceErrors(errorListener, target);
- outputs[RESOLVED_UNIT4] = unit;
- outputs[CREATED_RESOLVED_UNIT4] = true;
+ outputs[RESOLVED_UNIT5] = unit;
+ outputs[CREATED_RESOLVED_UNIT5] = true;
}
/**
@@ -4964,10 +5173,8 @@
// version of the element model in order to record those changes.
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- 'importsExportNamespace':
- IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4),
- LIBRARY_INPUT: LIBRARY_ELEMENT4.of(unit.library),
- UNIT_INPUT: RESOLVED_UNIT3.of(unit),
+ LIBRARY_INPUT: LIBRARY_ELEMENT5.of(unit.library),
+ UNIT_INPUT: RESOLVED_UNIT4.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
};
}
@@ -4983,7 +5190,7 @@
}
/**
- * A task that builds [RESOLVED_UNIT5] for a unit.
+ * A task that builds [RESOLVED_UNIT6] for a unit.
*/
class ResolveVariableReferencesTask extends SourceBasedAnalysisTask {
/**
@@ -4992,7 +5199,7 @@
static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
/**
- * The name of the [RESOLVED_UNIT4] input.
+ * The name of the [RESOLVED_UNIT5] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -5008,8 +5215,8 @@
'ResolveVariableReferencesTask',
createTask,
buildInputs, <ResultDescriptor>[
- CREATED_RESOLVED_UNIT5,
- RESOLVED_UNIT5,
+ CREATED_RESOLVED_UNIT6,
+ RESOLVED_UNIT6,
VARIABLE_REFERENCE_ERRORS
]);
@@ -5041,8 +5248,8 @@
//
// Record outputs.
//
- outputs[RESOLVED_UNIT5] = unit;
- outputs[CREATED_RESOLVED_UNIT5] = true;
+ outputs[RESOLVED_UNIT6] = unit;
+ outputs[CREATED_RESOLVED_UNIT6] = true;
outputs[VARIABLE_REFERENCE_ERRORS] =
getTargetSourceErrors(errorListener, target);
}
@@ -5056,7 +5263,7 @@
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
LIBRARY_INPUT: LIBRARY_ELEMENT1.of(unit.library),
- UNIT_INPUT: RESOLVED_UNIT4.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT5.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
};
}
@@ -5221,7 +5428,7 @@
*/
class StrongModeVerifyUnitTask extends SourceBasedAnalysisTask {
/**
- * The name of the [RESOLVED_UNIT12] input.
+ * The name of the [RESOLVED_UNIT13] input.
*/
static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -5277,7 +5484,7 @@
static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
LibrarySpecificUnit unit = target;
return <String, TaskInput>{
- UNIT_INPUT: RESOLVED_UNIT12.of(unit),
+ UNIT_INPUT: RESOLVED_UNIT13.of(unit),
TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
};
}
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 0eb6613..8c8176a 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -41,6 +41,7 @@
LINTS,
LIBRARY_UNIT_ERRORS,
RESOLVE_TYPE_NAMES_ERRORS,
+ RESOLVE_TYPE_BOUNDS_ERRORS,
RESOLVE_UNIT_ERRORS,
STRONG_MODE_ERRORS,
VARIABLE_REFERENCE_ERRORS,
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 08d414b..3e6f6f5 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -104,13 +104,14 @@
final bool _hints;
bool _failure = false;
- CodeChecker(this.typeProvider, StrongTypeSystemImpl rules,
+ CodeChecker(TypeProvider typeProvider, StrongTypeSystemImpl rules,
AnalysisErrorListener reporter,
{bool hints: false})
- : rules = rules,
+ : typeProvider = typeProvider,
+ rules = rules,
reporter = reporter,
_hints = hints,
- _overrideChecker = new _OverrideChecker(rules, reporter);
+ _overrideChecker = new _OverrideChecker(typeProvider, rules, reporter);
bool get failure => _failure || _overrideChecker._failure;
@@ -324,9 +325,7 @@
@override
void visitForEachStatement(ForEachStatement node) {
- var loopVariable = node.identifier != null
- ? node.identifier
- : node.loopVariable?.identifier;
+ var loopVariable = node.identifier ?? node.loopVariable?.identifier;
// Safely handle malformed statements.
if (loopVariable != null) {
@@ -956,9 +955,10 @@
class _OverrideChecker {
bool _failure = false;
final StrongTypeSystemImpl rules;
+ final TypeProvider _typeProvider;
final AnalysisErrorListener _reporter;
- _OverrideChecker(this.rules, this._reporter);
+ _OverrideChecker(this._typeProvider, this.rules, this._reporter);
void check(ClassDeclaration node) {
if (node.element.type.isObject) return;
@@ -1132,8 +1132,7 @@
// Check overrides from its mixins
for (int i = 0; i < type.mixins.length; i++) {
- var loc =
- errorLocation != null ? errorLocation : node.withClause.mixinTypes[i];
+ var loc = errorLocation ?? node.withClause.mixinTypes[i];
for (var interfaceType in interfaces) {
// We copy [seen] so we can report separately if more than one mixin or
// the base class have an invalid override.
@@ -1145,8 +1144,10 @@
// Check overrides from its superclasses
if (includeParents) {
var parent = type.superclass;
- if (parent.isObject) return;
- var loc = errorLocation != null ? errorLocation : node.extendsClause;
+ if (parent.isObject) {
+ return;
+ }
+ var loc = errorLocation ?? node.extendsClause;
// No need to copy [seen] here because we made copies above when reporting
// errors on mixins.
_checkInterfacesOverrides(parent, interfaces, seen,
@@ -1225,7 +1226,20 @@
errorLocation, element, type, subType, baseType));
}
}
- if (!rules.isSubtypeOf(subType, baseType)) {
+ FunctionType concreteSubType = subType;
+ FunctionType concreteBaseType = baseType;
+ if (element is MethodElement) {
+ if (concreteSubType.typeFormals.isNotEmpty) {
+ if (concreteBaseType.typeFormals.isEmpty) {
+ concreteSubType = rules.instantiateToBounds(concreteSubType);
+ }
+ }
+ concreteSubType =
+ rules.typeToConcreteType(_typeProvider, concreteSubType);
+ concreteBaseType =
+ rules.typeToConcreteType(_typeProvider, concreteBaseType);
+ }
+ if (!rules.isSubtypeOf(concreteSubType, concreteBaseType)) {
// See whether non-subtype cases fit one of our common patterns:
//
// Common pattern 1: Inferable return type (on getters and methods)
diff --git a/pkg/analyzer/lib/src/task/strong/info.dart b/pkg/analyzer/lib/src/task/strong/info.dart
index 41703e1..39885cd 100644
--- a/pkg/analyzer/lib/src/task/strong/info.dart
+++ b/pkg/analyzer/lib/src/task/strong/info.dart
@@ -212,10 +212,7 @@
toErrorCode() => new HintCode(name, message);
/// Whether this [node] is the target of a dynamic operation.
- static bool get(AstNode node) {
- var value = node.getProperty(_propertyName);
- return value != null ? value : false;
- }
+ static bool get(AstNode node) => node.getProperty(_propertyName) ?? false;
/// Sets whether this node is the target of a dynamic operation.
static bool set(AstNode node, bool value) {
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 6c8b8cc..126b5a6 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.27.3
+version: 0.27.4-alpha.1
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
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 34dd9b9..5bd95e5 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -2209,7 +2209,7 @@
Source source = addSource(r'''
class A {
int x;
- factory A(this.x) {}
+ factory A(this.x) => null;
}''');
computeLibrarySourceErrors(source);
assertErrors(
@@ -3201,7 +3201,7 @@
Source source = addSource(r'''
int B;
class A {
- factory B() {}
+ factory B() => null;
}''');
computeLibrarySourceErrors(source);
assertErrors(
@@ -3212,7 +3212,7 @@
void test_invalidFactoryNameNotAClass_notEnclosingClassName() {
Source source = addSource(r'''
class A {
- factory B() {}
+ factory B() => null;
}''');
computeLibrarySourceErrors(source);
assertErrors(
@@ -4736,7 +4736,7 @@
void test_nonGenerativeConstructor_explicit() {
Source source = addSource(r'''
class A {
- factory A.named() {}
+ factory A.named() => null;
}
class B extends A {
B() : super.named();
@@ -4749,7 +4749,7 @@
void test_nonGenerativeConstructor_implicit() {
Source source = addSource(r'''
class A {
- factory A() {}
+ factory A() => null;
}
class B extends A {
B();
@@ -4762,7 +4762,7 @@
void test_nonGenerativeConstructor_implicit2() {
Source source = addSource(r'''
class A {
- factory A() {}
+ factory A() => null;
}
class B extends A {
}''');
@@ -5760,6 +5760,7 @@
class B extends A {
factory B() {
super.m();
+ return null;
}
}''');
computeLibrarySourceErrors(source);
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 79cb436..7a05a39 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -658,6 +658,28 @@
verify([source]);
}
+ void test_deprecatedAnnotationUse_positional() {
+ Source source = addSource(r'''
+class A {
+ m([@deprecated int x]) {}
+ n() {m(1);}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
+ void test_deprecatedAnnotationUse_named() {
+ Source source = addSource(r'''
+class A {
+ m({@deprecated int x}) {}
+ n() {m(x: 1);}
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
void test_deprecatedAnnotationUse_export() {
Source source = addSource("export 'deprecated_library.dart';");
addNamedSource(
@@ -813,6 +835,21 @@
verify([source]);
}
+ void test_deprecatedAnnotationUse_call() {
+ Source source = addSource(r'''
+class A {
+ @deprecated
+ call() {}
+ m() {
+ A a = new A();
+ a();
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEPRECATED_MEMBER_USE]);
+ verify([source]);
+ }
+
void test_divisionOptimization_double() {
Source source = addSource(r'''
f(double x, double y) {
@@ -1323,6 +1360,17 @@
verify([source]);
}
+ void test_missingReturn_factory() {
+ Source source = addSource(r'''
+class A {
+ factory A() {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MISSING_RETURN]);
+ verify([source]);
+ }
+
void test_missingReturn_method() {
Source source = addSource(r'''
class A {
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 80c41e1..518f8c8a 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -4892,6 +4892,7 @@
_assertCacheSourceResult(LIBRARY_ELEMENT6);
_assertCacheSourceResult(LIBRARY_ELEMENT7);
_assertCacheSourceResult(LIBRARY_ELEMENT8);
+ _assertCacheSourceResult(LIBRARY_ELEMENT9);
if (expectCachePostConstantsValid) {
_assertCacheSourceResult(LIBRARY_ELEMENT);
}
@@ -4906,8 +4907,9 @@
_assertCacheUnitResult(RESOLVED_UNIT9);
_assertCacheUnitResult(RESOLVED_UNIT10);
_assertCacheUnitResult(RESOLVED_UNIT11);
+ _assertCacheUnitResult(RESOLVED_UNIT12);
if (expectCachePostConstantsValid) {
- _assertCacheUnitResult(RESOLVED_UNIT12);
+ _assertCacheUnitResult(RESOLVED_UNIT13);
_assertCacheUnitResult(RESOLVED_UNIT);
}
}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 28f721e..e458070 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -2827,7 +2827,7 @@
void test_invalidFactoryNameNotAClass() {
Source source = addSource(r'''
class A {
- factory A() {}
+ factory A() => null;
}''');
computeLibrarySourceErrors(source);
assertNoErrors(source);
@@ -3491,7 +3491,7 @@
void test_mixinDeclaresConstructor_factory() {
Source source = addSource(r'''
class A {
- factory A() {}
+ factory A() => null;
}
class B extends Object with A {}''');
computeLibrarySourceErrors(source);
@@ -4275,7 +4275,7 @@
Source source = addSource(r'''
class A {
A.named() {}
- factory A() {}
+ factory A() => null;
}
class B extends A {
B() : super.named();
@@ -4693,7 +4693,7 @@
factory B() = C;
}
class C implements B {
- factory C() {}
+ factory C() => null;
}''');
computeLibrarySourceErrors(source);
assertNoErrors(source);
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 4568fe9..9b3f082 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1288,6 +1288,64 @@
[StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
}
+ void test_typeArgumentNotMatchingBounds_methodInvocation_localFunction() {
+ resetWithOptions(new AnalysisOptionsImpl()..strongMode = true);
+ assertErrorsInCode(
+ r'''
+class Point<T extends num> {
+ Point(T x, T y);
+}
+
+main() {
+ Point/*<T>*/ f/*<T extends num>*/(num/*=T*/ x, num/*=T*/ y) {
+ return new Point/*<T>*/(x, y);
+ }
+ print(f/*<String>*/('hello', 'world'));
+}
+''',
+ [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ }
+
+ void test_typeArgumentNotMatchingBounds_methodInvocation_method() {
+ resetWithOptions(new AnalysisOptionsImpl()..strongMode = true);
+ assertErrorsInCode(
+ r'''
+class Point<T extends num> {
+ Point(T x, T y);
+}
+
+class PointFactory {
+ Point/*<T>*/ point/*<T extends num>*/(num/*=T*/ x, num/*=T*/ y) {
+ return new Point/*<T>*/(x, y);
+ }
+}
+
+f(PointFactory factory) {
+ print(factory.point/*<String>*/('hello', 'world'));
+}
+''',
+ [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ }
+
+ void test_typeArgumentNotMatchingBounds_methodInvocation_topLevelFunction() {
+ resetWithOptions(new AnalysisOptionsImpl()..strongMode = true);
+ assertErrorsInCode(
+ r'''
+class Point<T extends num> {
+ Point(T x, T y);
+}
+
+Point/*<T>*/ f/*<T extends num>*/(num/*=T*/ x, num/*=T*/ y) {
+ return new Point/*<T>*/(x, y);
+}
+
+main() {
+ print(f/*<String>*/('hello', 'world'));
+}
+''',
+ [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+ }
+
void test_typeArgumentNotMatchingBounds_methodReturnType() {
assertErrorsInCode(
r'''
@@ -2361,4 +2419,51 @@
}
verify([source]);
}
+
+ void test_legalAsyncGeneratorReturnType_function_supertypeOfStream() {
+ assertErrorsInCode(
+ '''
+import 'dart:async';
+f() async* { yield 42; }
+dynamic f2() async* { yield 42; }
+Object f3() async* { yield 42; }
+Stream f4() async* { yield 42; }
+Stream<dynamic> f5() async* { yield 42; }
+Stream<Object> f6() async* { yield 42; }
+Stream<num> f7() async* { yield 42; }
+Stream<int> f8() async* { yield 42; }
+''',
+ []);
+ }
+
+ void test_legalAsyncReturnType_function_supertypeOfFuture() {
+ assertErrorsInCode(
+ '''
+import 'dart:async';
+f() async { return 42; }
+dynamic f2() async { return 42; }
+Object f3() async { return 42; }
+Future f4() async { return 42; }
+Future<dynamic> f5() async { return 42; }
+Future<Object> f6() async { return 42; }
+Future<num> f7() async { return 42; }
+Future<int> f8() async { return 42; }
+''',
+ []);
+ }
+
+ void test_legalSyncGeneratorReturnType_function_supertypeOfIterable() {
+ assertErrorsInCode(
+ '''
+f() sync* { yield 42; }
+dynamic f2() sync* { yield 42; }
+Object f3() sync* { yield 42; }
+Iterable f4() sync* { yield 42; }
+Iterable<dynamic> f5() sync* { yield 42; }
+Iterable<Object> f6() sync* { yield 42; }
+Iterable<num> f7() sync* { yield 42; }
+Iterable<int> f8() sync* { yield 42; }
+''',
+ []);
+ }
}
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index 1445233..f8fc40d 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -19,6 +19,21 @@
@reflectiveTest
class StaticWarningCodeTest extends ResolverTestCase {
+ void fail_argumentTypeNotAssignable_tearOff_required() {
+ Source source = addSource(r'''
+class C {
+ Object/*=T*/ f/*<T>*/(Object/*=T*/ x) => x;
+}
+g(C c) {
+ var h = c.f/*<int>*/;
+ print(h('s'));
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ verify([source]);
+ }
+
void fail_undefinedGetter() {
Source source = addSource(r'''
''');
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 7bc5ed1..e169167 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -1958,10 +1958,10 @@
resolveTestUnit(code);
expectIdentifierType('ai', "A<dynamic>");
expectIdentifierType('bi', "B<num>");
- expectIdentifierType('ci', "C<int, B<int>, B<num>>");
+ expectIdentifierType('ci', "C<int, B<int>, B<dynamic>>");
expectIdentifierType('aa', "A<dynamic>");
expectIdentifierType('bb', "B<num>");
- expectIdentifierType('cc', "C<int, B<int>, B<num>>");
+ expectIdentifierType('cc', "C<int, B<int>, B<dynamic>>");
}
void test_setterWithDynamicTypeIsError() {
diff --git a/pkg/analyzer/test/reflective_tests.dart b/pkg/analyzer/test/reflective_tests.dart
index 310e7d0..4788776 100644
--- a/pkg/analyzer/test/reflective_tests.dart
+++ b/pkg/analyzer/test/reflective_tests.dart
@@ -12,6 +12,13 @@
/**
* A marker annotation used to annotate overridden test methods (so we cannot
+ * rename them to `fail_`) which are expected to fail at `assert` in the
+ * checked mode.
+ */
+const _AssertFailingTest assertFailingTest = const _AssertFailingTest();
+
+/**
+ * A marker annotation used to annotate overridden test methods (so we cannot
* rename them to `fail_`) which are expected to fail.
*/
const _FailingTest failingTest = const _FailingTest();
@@ -23,6 +30,18 @@
const ReflectiveTest reflectiveTest = const ReflectiveTest();
/**
+ * Is `true` the application is running in the checked mode.
+ */
+final bool _isCheckedMode = () {
+ try {
+ assert(false);
+ return false;
+ } catch (_) {
+ return true;
+ }
+}();
+
+/**
* Runs test methods existing in the given [type].
*
* Methods with names starting with `test` are run using [test] function.
@@ -58,7 +77,8 @@
// test_
if (memberName.startsWith('test_')) {
test(memberName, () {
- if (_hasFailingTestAnnotation(memberMirror)) {
+ if (_hasFailingTestAnnotation(memberMirror) ||
+ _isCheckedMode && _hasAssertFailingTestAnnotation(memberMirror)) {
return _runFailingTest(classMirror, symbol);
} else {
return _runTest(classMirror, symbol);
@@ -88,10 +108,15 @@
});
}
-bool _hasFailingTestAnnotation(MethodMirror method) {
- return method.metadata.any((InstanceMirror annotation) =>
- annotation.type.reflectedType == _FailingTest);
-}
+bool _hasAnnotationInstance(DeclarationMirror declaration, instance) =>
+ declaration.metadata.any((InstanceMirror annotation) =>
+ identical(annotation.reflectee, instance));
+
+bool _hasAssertFailingTestAnnotation(MethodMirror method) =>
+ _hasAnnotationInstance(method, assertFailingTest);
+
+bool _hasFailingTestAnnotation(MethodMirror method) =>
+ _hasAnnotationInstance(method, failingTest);
Future _invokeSymbolIfExists(InstanceMirror instanceMirror, Symbol symbol) {
var invocationResult = null;
@@ -139,6 +164,15 @@
/**
* A marker annotation used to annotate overridden test methods (so we cannot
+ * rename them to `fail_`) which are expected to fail at `assert` in the
+ * checked mode.
+ */
+class _AssertFailingTest {
+ const _AssertFailingTest();
+}
+
+/**
+ * A marker annotation used to annotate overridden test methods (so we cannot
* rename them to `fail_`) which are expected to fail.
*/
class _FailingTest {
diff --git a/pkg/analyzer/test/source/config_test.dart b/pkg/analyzer/test/source/config_test.dart
new file mode 100644
index 0000000..ccbc056
--- /dev/null
+++ b/pkg/analyzer/test/source/config_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.
+
+import 'package:analyzer/source/config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:yaml/yaml.dart';
+
+main() {
+ group('Analysis Config', () {
+ test('parseConfigSource', () {
+ String source = r'''
+analyzer:
+ configuration: google/strict
+''';
+ YamlMap options = loadYamlNode(source);
+ AnalysisConfigurationDescriptor descriptor =
+ new AnalysisConfigurationDescriptor.fromAnalyzerOptions(
+ options['analyzer']);
+ expect(descriptor.package, 'google');
+ expect(descriptor.pragma, 'strict');
+ });
+ });
+}
diff --git a/pkg/analyzer/test/source/test_all.dart b/pkg/analyzer/test/source/test_all.dart
index 725d23e..bca740b 100644
--- a/pkg/analyzer/test/source/test_all.dart
+++ b/pkg/analyzer/test/source/test_all.dart
@@ -8,6 +8,7 @@
import '../utils.dart';
import 'analysis_options_provider_test.dart' as analysis_options_provider_test;
+import 'config_test.dart' as config_test;
import 'embedder_test.dart' as embedder_test;
import 'error_processor_test.dart' as error_processor_test;
import 'package_map_provider_test.dart' as package_map_provider_test;
@@ -20,6 +21,7 @@
initializeTestEnvironment();
group('source', () {
analysis_options_provider_test.main();
+ config_test.main();
embedder_test.main();
error_processor_test.main();
package_map_provider_test.main();
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index e19a173..ea41470 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -2131,6 +2131,7 @@
entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
+ entry.setState(RESOLVED_UNIT13, CacheState.FLUSHED);
entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
context.resolveCompilationUnit2(source, source);
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index ebee2d6..4b5ee12 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -2083,6 +2083,132 @@
expect(f.type.toString(), '() \u2192 C<...>');
}
+ void test_typeParameters_genericLocalFunction_genericMethod_genericClass() {
+ //
+ // class C<S> {
+ // Object m<T>() {
+ // U f<U>() => null;
+ // }
+ // }
+ //
+ ClassElementImpl classElement =
+ ElementFactory.classElement('C', null, ['S']);
+ MethodElementImpl method = new MethodElementImpl('m', 0);
+ method.enclosingElement = classElement;
+ method.returnType = ElementFactory.objectType;
+ method.typeParameters = ElementFactory.typeParameters(['T']);
+ method.type = new FunctionTypeImpl(method);
+ FunctionElementImpl function = ElementFactory.functionElement('f');
+ function.enclosingElement = method;
+ function.typeParameters = ElementFactory.typeParameters(['U']);
+ function.returnType = function.typeParameters[0].type;
+ function.type = new FunctionTypeImpl(function);
+
+ List<TypeParameterElement> inheritedParameters = <TypeParameterElement>[];
+ inheritedParameters.addAll(method.typeParameters);
+ inheritedParameters.addAll(classElement.typeParameters);
+ expect(function.type.typeArguments,
+ unorderedEquals(_toTypes(inheritedParameters)));
+ expect(function.type.typeFormals, unorderedEquals(function.typeParameters));
+ expect(function.type.typeParameters, unorderedEquals(inheritedParameters));
+ }
+
+ void test_typeParameters_genericMethod_genericClass() {
+ //
+ // class C<S> {
+ // Object m<T>() => null;
+ // }
+ //
+ ClassElementImpl classElement =
+ ElementFactory.classElement('C', null, ['S']);
+ MethodElementImpl method = new MethodElementImpl('m', 0);
+ method.enclosingElement = classElement;
+ method.returnType = ElementFactory.objectType;
+ method.typeParameters = ElementFactory.typeParameters(['T']);
+ method.type = new FunctionTypeImpl(method);
+
+ expect(method.type.typeArguments,
+ unorderedEquals(_toTypes(classElement.typeParameters)));
+ expect(method.type.typeFormals, unorderedEquals(method.typeParameters));
+ expect(method.type.typeParameters,
+ unorderedEquals(classElement.typeParameters));
+ }
+
+ void test_typeParameters_genericMethod_simpleClass() {
+ //
+ // class C<S> {
+ // Object m<T>() => null;
+ // }
+ //
+ ClassElementImpl classElement = ElementFactory.classElement2('C');
+ MethodElementImpl method = new MethodElementImpl('m', 0);
+ method.enclosingElement = classElement;
+ method.returnType = ElementFactory.objectType;
+ method.typeParameters = ElementFactory.typeParameters(['T']);
+ method.type = new FunctionTypeImpl(method);
+
+ expect(method.type.typeArguments,
+ unorderedEquals(_toTypes(classElement.typeParameters)));
+ expect(method.type.typeFormals, unorderedEquals(method.typeParameters));
+ expect(method.type.typeParameters,
+ unorderedEquals(classElement.typeParameters));
+ }
+
+ void test_typeParameters_genericTopLevelFunction() {
+ //
+ // Object f<T>() => null;
+ //
+ FunctionElementImpl function = ElementFactory.functionElement('f');
+ function.returnType = ElementFactory.objectType;
+ function.typeParameters = ElementFactory.typeParameters(['T']);
+ function.type = new FunctionTypeImpl(function);
+
+ expect(function.type.typeArguments, isEmpty);
+ expect(function.type.typeFormals, unorderedEquals(function.typeParameters));
+ expect(function.type.typeParameters, isEmpty);
+ }
+
+ void test_typeParameters_simpleMethod_genericClass() {
+ //
+ // class C<S> {
+ // Object m<T>() => null;
+ // }
+ //
+ ClassElementImpl classElement =
+ ElementFactory.classElement('C', null, ['S']);
+ MethodElementImpl method = new MethodElementImpl('m', 0);
+ method.enclosingElement = classElement;
+ method.typeParameters = ElementFactory.typeParameters(['T']);
+ method.returnType = ElementFactory.objectType;
+ method.type = new FunctionTypeImpl(method);
+
+ expect(method.type.typeArguments,
+ unorderedEquals(_toTypes(classElement.typeParameters)));
+ expect(method.type.typeFormals, unorderedEquals(method.typeParameters));
+ expect(method.type.typeParameters,
+ unorderedEquals(classElement.typeParameters));
+ }
+
+ void test_typeParameters_simpleMethod_simpleClass() {
+ //
+ // class C<S> {
+ // Object m<T>() => null;
+ // }
+ //
+ ClassElementImpl classElement = ElementFactory.classElement2('C');
+ MethodElementImpl method = new MethodElementImpl('m', 0);
+ method.enclosingElement = classElement;
+ method.typeParameters = ElementFactory.typeParameters(['T']);
+ method.returnType = ElementFactory.objectType;
+ method.type = new FunctionTypeImpl(method);
+
+ expect(method.type.typeArguments,
+ unorderedEquals(_toTypes(classElement.typeParameters)));
+ expect(method.type.typeFormals, unorderedEquals(method.typeParameters));
+ expect(method.type.typeParameters,
+ unorderedEquals(classElement.typeParameters));
+ }
+
void test_withTypeArguments() {
ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
MethodElementImpl methodElement =
@@ -2094,6 +2220,10 @@
expect(arguments, hasLength(1));
expect(arguments[0], expectedType);
}
+
+ Iterable<DartType> _toTypes(List<TypeParameterElement> typeParameters) {
+ return typeParameters.map((TypeParameterElement element) => element.type);
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index e5f0dfa..ef33f95 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -454,6 +454,20 @@
'int');
}
+ void test_leastUpperBound_functionAndClass() {
+ createLinker('''
+class C {}
+void f() {}
+var x = {
+ 'C': C,
+ 'f': f
+};
+''');
+ LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+ library.libraryCycleForLink.ensureLinked();
+ // No assertions--just make sure it doesn't crash.
+ }
+
void test_libraryCycle_ignoresDependenciesOutsideBuildUnit() {
createLinker('import "dart:async";');
LibraryCycleForLink libraryCycle = testLibrary.libraryCycleForLink;
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 9d7a10d..420b70f 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -44,6 +44,9 @@
}
@override
+ bool get mayCheckTypesOfLocals => false;
+
+ @override
bool get skipBrokenAstInference => true;
@override
@@ -79,26 +82,26 @@
@override
@failingTest
- void test_blockBodiedLambdas_async_allReturnsAreValues() {
- super.test_blockBodiedLambdas_async_allReturnsAreValues();
+ void test_blockBodiedLambdas_async_allReturnsAreFutures_topLevel() {
+ super.test_blockBodiedLambdas_async_allReturnsAreFutures_topLevel();
}
@override
@failingTest
- void test_blockBodiedLambdas_async_alReturnsAreFutures() {
- super.test_blockBodiedLambdas_async_alReturnsAreFutures();
+ void test_blockBodiedLambdas_async_allReturnsAreValues_topLevel() {
+ super.test_blockBodiedLambdas_async_allReturnsAreValues_topLevel();
}
@override
@failingTest
- void test_blockBodiedLambdas_async_mixOfValuesAndFutures() {
- super.test_blockBodiedLambdas_async_mixOfValuesAndFutures();
+ void test_blockBodiedLambdas_async_mixOfValuesAndFutures_topLevel() {
+ super.test_blockBodiedLambdas_async_mixOfValuesAndFutures_topLevel();
}
@override
@failingTest
- void test_blockBodiedLambdas_asyncStar() {
- super.test_blockBodiedLambdas_asyncStar();
+ void test_blockBodiedLambdas_asyncStar_topLevel() {
+ super.test_blockBodiedLambdas_asyncStar_topLevel();
}
@override
@@ -109,32 +112,26 @@
@override
@failingTest
- void test_blockBodiedLambdas_doesNotInferBottom_async() {
- super.test_blockBodiedLambdas_doesNotInferBottom_async();
+ void test_blockBodiedLambdas_doesNotInferBottom_async_topLevel() {
+ super.test_blockBodiedLambdas_doesNotInferBottom_async_topLevel();
}
@override
@failingTest
- void test_blockBodiedLambdas_doesNotInferBottom_asyncStar() {
- super.test_blockBodiedLambdas_doesNotInferBottom_asyncStar();
+ void test_blockBodiedLambdas_doesNotInferBottom_asyncStar_topLevel() {
+ super.test_blockBodiedLambdas_doesNotInferBottom_asyncStar_topLevel();
}
@override
@failingTest
- void test_blockBodiedLambdas_doesNotInferBottom_sync() {
- super.test_blockBodiedLambdas_doesNotInferBottom_sync();
+ void test_blockBodiedLambdas_doesNotInferBottom_sync_topLevel() {
+ super.test_blockBodiedLambdas_doesNotInferBottom_sync_topLevel();
}
@override
@failingTest
- void test_blockBodiedLambdas_doesNotInferBottom_syncStar() {
- super.test_blockBodiedLambdas_doesNotInferBottom_syncStar();
- }
-
- @override
- @failingTest
- void test_blockBodiedLambdas_downwardsIncompatibleWithUpwardsInference() {
- super.test_blockBodiedLambdas_downwardsIncompatibleWithUpwardsInference();
+ void test_blockBodiedLambdas_doesNotInferBottom_syncStar_topLevel() {
+ super.test_blockBodiedLambdas_doesNotInferBottom_syncStar_topLevel();
}
@override
@@ -145,44 +142,14 @@
@override
@failingTest
- void test_blockBodiedLambdas_nestedLambdas() {
- super.test_blockBodiedLambdas_nestedLambdas();
+ void test_blockBodiedLambdas_nestedLambdas_topLevel() {
+ super.test_blockBodiedLambdas_nestedLambdas_topLevel();
}
@override
@failingTest
- void test_blockBodiedLambdas_noReturn() {
- super.test_blockBodiedLambdas_noReturn();
- }
-
- @override
- @failingTest
- void test_blockBodiedLambdas_syncStar() {
- super.test_blockBodiedLambdas_syncStar();
- }
-
- @override
- @failingTest
- void test_canInferAlsoFromStaticAndInstanceFieldsFlagOn() {
- super.test_canInferAlsoFromStaticAndInstanceFieldsFlagOn();
- }
-
- @override
- @failingTest
- void test_downwardsInferenceAnnotations() {
- super.test_downwardsInferenceAnnotations();
- }
-
- @override
- @failingTest
- void test_downwardsInferenceAsyncAwait() {
- super.test_downwardsInferenceAsyncAwait();
- }
-
- @override
- @failingTest
- void test_downwardsInferenceForEach() {
- super.test_downwardsInferenceForEach();
+ void test_blockBodiedLambdas_syncStar_topLevel() {
+ super.test_blockBodiedLambdas_syncStar_topLevel();
}
@override
@@ -199,12 +166,6 @@
@override
@failingTest
- void test_downwardsInferenceYieldYieldStar() {
- super.test_downwardsInferenceYieldYieldStar();
- }
-
- @override
- @failingTest
void test_genericMethods_inferJSBuiltin() {
super.test_genericMethods_inferJSBuiltin();
}
@@ -562,6 +523,42 @@
super.test_inferenceInCyclesIsDeterministic();
}
+ @override
+ @failingTest
+ void test_instantiateToBounds_generic2_hasBound_definedAfter() {
+ super.test_instantiateToBounds_generic2_hasBound_definedAfter();
+ }
+
+ @override
+ @failingTest
+ void test_instantiateToBounds_generic2_hasBound_definedBefore() {
+ super.test_instantiateToBounds_generic2_hasBound_definedBefore();
+ }
+
+ @override
+ @failingTest
+ void test_instantiateToBounds_generic2_noBound() {
+ super.test_instantiateToBounds_generic2_noBound();
+ }
+
+ @override
+ @failingTest
+ void test_instantiateToBounds_generic_hasBound_definedAfter() {
+ super.test_instantiateToBounds_generic_hasBound_definedAfter();
+ }
+
+ @override
+ @failingTest
+ void test_instantiateToBounds_generic_hasBound_definedBefore() {
+ super.test_instantiateToBounds_generic_hasBound_definedBefore();
+ }
+
+ @override
+ @failingTest
+ void test_instantiateToBounds_notGeneric() {
+ super.test_instantiateToBounds_notGeneric();
+ }
+
void test_invokeMethod_notGeneric_genericClass() {
var unit = checkFile(r'''
class C<T> {
@@ -584,18 +581,6 @@
@override
@failingTest
- void test_listLiteralsShouldNotInferBottom() {
- super.test_listLiteralsShouldNotInferBottom();
- }
-
- @override
- @failingTest
- void test_mapLiteralsShouldNotInferBottom() {
- super.test_mapLiteralsShouldNotInferBottom();
- }
-
- @override
- @failingTest
void test_nullLiteralShouldNotInferAsBottom() {
super.test_nullLiteralShouldNotInferAsBottom();
}
@@ -636,42 +621,12 @@
@override
@failingTest
- void test_constructor_initializers_field_notConst() {
- super.test_constructor_initializers_field_notConst();
- }
-
- @override
- @failingTest
void test_inferred_function_type_in_generic_class_constructor() {
super.test_inferred_function_type_in_generic_class_constructor();
}
@override
@failingTest
- void test_metadata_constructor_call_named() {
- super.test_metadata_constructor_call_named();
- }
-
- @override
- @failingTest
- void test_metadata_constructor_call_named_prefixed() {
- super.test_metadata_constructor_call_named_prefixed();
- }
-
- @override
- @failingTest
- void test_metadata_constructor_call_unnamed() {
- super.test_metadata_constructor_call_unnamed();
- }
-
- @override
- @failingTest
- void test_metadata_constructor_call_with_args() {
- super.test_metadata_constructor_call_with_args();
- }
-
- @override
- @failingTest
void test_type_reference_to_import_part_in_subdir() {
super.test_type_reference_to_import_part_in_subdir();
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index b4e87cd..c3ae04d 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -42,7 +42,6 @@
*/
abstract class AbstractResynthesizeTest extends AbstractSingleUnitTest {
Set<Source> otherLibrarySources = new Set<Source>();
- bool constantInitializersAreInvalid = false;
bool get checkPropagatedTypes => true;
@@ -335,11 +334,7 @@
} else if (oItem is ConstructorFieldInitializer &&
rItem is ConstructorFieldInitializer) {
compareConstAsts(rItem.fieldName, oItem.fieldName, desc);
- if (constantInitializersAreInvalid) {
- _assertUnresolvedIdentifier(rItem.expression, desc);
- } else {
- compareConstAsts(rItem.expression, oItem.expression, desc);
- }
+ compareConstAsts(rItem.expression, oItem.expression, desc);
} else if (oItem is SuperConstructorInvocation &&
rItem is SuperConstructorInvocation) {
compareElements(rItem.staticElement, oItem.staticElement, desc);
@@ -411,9 +406,13 @@
compareConstAsts(r.identifier, o.identifier, desc);
} else if (o is PropertyAccess && r is PropertyAccess) {
compareConstAsts(r.target, o.target, desc);
- expect(r.propertyName.name, o.propertyName.name, reason: desc);
- compareElements(
- r.propertyName.staticElement, o.propertyName.staticElement, desc);
+ String oName = o.propertyName.name;
+ String rName = r.propertyName.name;
+ expect(rName, oName, reason: desc);
+ if (oName == 'length') {
+ compareElements(
+ r.propertyName.staticElement, o.propertyName.staticElement, desc);
+ }
} else if (o is PropertyAccess &&
o.target is PrefixedIdentifier &&
r is SimpleIdentifier) {
@@ -648,7 +647,7 @@
return;
}
expect(original, isNotNull);
- expect(resynthesized, isNotNull);
+ expect(resynthesized, isNotNull, reason: desc);
expect(rImpl.runtimeType, oImpl.runtimeType);
expect(resynthesized.kind, original.kind);
expect(resynthesized.location, original.location, reason: desc);
@@ -1079,12 +1078,8 @@
resynthesized.constantValue, original.constantValue, desc);
} else {
Expression initializer = resynthesizedActual.constantInitializer;
- if (constantInitializersAreInvalid) {
- _assertUnresolvedIdentifier(initializer, desc);
- } else {
- compareConstAsts(initializer, originalActual.constantInitializer,
- '$desc initializer');
- }
+ compareConstAsts(initializer, originalActual.constantInitializer,
+ '$desc initializer');
}
}
checkPossibleMember(resynthesized, original, desc);
@@ -1200,12 +1195,6 @@
super.setUp();
prepareAnalysisContext(createOptions());
}
-
- void _assertUnresolvedIdentifier(Expression initializer, String desc) {
- expect(initializer, new isInstanceOf<SimpleIdentifier>(), reason: desc);
- SimpleIdentifier identifier = initializer;
- expect(identifier.staticElement, isNull, reason: desc);
- }
}
@reflectiveTest
@@ -1668,7 +1657,6 @@
}
test_const_invalid_field_const() {
- constantInitializersAreInvalid = true;
checkLibrary(
r'''
class C {
@@ -1680,7 +1668,6 @@
}
test_const_invalid_field_final() {
- constantInitializersAreInvalid = true;
checkLibrary(
r'''
class C {
@@ -1692,7 +1679,6 @@
}
test_const_invalid_topLevel() {
- constantInitializersAreInvalid = true;
checkLibrary(
r'''
const v = 1 + foo();
@@ -2435,7 +2421,6 @@
}
test_constructor_initializers_field_notConst() {
- constantInitializersAreInvalid = true;
checkLibrary(
'''
class C {
@@ -2931,6 +2916,20 @@
checkLibrary('class C { var x = 0; }');
}
+ test_function_async() {
+ checkLibrary(r'''
+import 'dart:async';
+Future f() async {}
+''');
+ }
+
+ test_function_asyncStar() {
+ checkLibrary(r'''
+import 'dart:async';
+Stream f() async* {}
+''');
+ }
+
test_function_documented() {
checkLibrary('''
// Extra comment so doc comment offset != 0
@@ -3543,6 +3542,24 @@
checkLibrary('export "a.dart";');
}
+ test_member_function_async() {
+ checkLibrary(r'''
+import 'dart:async';
+class C {
+ Future f() async {}
+}
+''');
+ }
+
+ test_member_function_asyncStar() {
+ checkLibrary(r'''
+import 'dart:async';
+class C {
+ Stream f() async* {}
+}
+''');
+ }
+
test_metadata_classDeclaration() {
checkLibrary('const a = null; @a class C {}');
}
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index c50e33b..7e25284 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -2819,6 +2819,73 @@
]);
}
+ test_constExpr_pushReference_staticGetter() {
+ UnlinkedVariable variable = serializeVariableText('''
+class C {
+ static int get x => null;
+}
+const v = C.x;
+''');
+ _assertUnlinkedConst(variable.constExpr, operators: [
+ UnlinkedConstOperation.pushReference
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'x',
+ expectedKind: ReferenceKind.propertyAccessor,
+ prefixExpectations: [
+ new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+ ])
+ ]);
+ }
+
+ test_constExpr_pushReference_staticGetter_imported() {
+ addNamedSource(
+ '/a.dart',
+ '''
+class C {
+ static int get x => null;
+}
+''');
+ UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+const v = C.x;
+''');
+ _assertUnlinkedConst(variable.constExpr, operators: [
+ UnlinkedConstOperation.pushReference
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'x',
+ expectedKind: ReferenceKind.propertyAccessor,
+ prefixExpectations: [
+ new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
+ absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart')
+ ])
+ ]);
+ }
+
+ test_constExpr_pushReference_staticGetter_imported_withPrefix() {
+ addNamedSource(
+ '/a.dart',
+ '''
+class C {
+ static int get x => null;
+}
+''');
+ UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const v = p.C.x;
+''');
+ _assertUnlinkedConst(variable.constExpr, operators: [
+ UnlinkedConstOperation.pushReference
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'x',
+ expectedKind: ReferenceKind.propertyAccessor,
+ prefixExpectations: [
+ new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
+ absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
+ new _PrefixExpectation(ReferenceKind.prefix, 'p')
+ ])
+ ]);
+ }
+
test_constExpr_pushReference_staticMethod() {
UnlinkedVariable variable = serializeVariableText('''
class C {
@@ -2956,6 +3023,48 @@
]);
}
+ test_constExpr_pushReference_topLevelGetter() {
+ UnlinkedVariable variable = serializeVariableText('''
+int get x => null;
+const v = x;
+''');
+ _assertUnlinkedConst(variable.constExpr, operators: [
+ UnlinkedConstOperation.pushReference
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'x',
+ expectedKind: ReferenceKind.topLevelPropertyAccessor)
+ ]);
+ }
+
+ test_constExpr_pushReference_topLevelGetter_imported() {
+ addNamedSource('/a.dart', 'int get x => null;');
+ UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+const v = x;
+''');
+ _assertUnlinkedConst(variable.constExpr, operators: [
+ UnlinkedConstOperation.pushReference
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'x',
+ expectedKind: ReferenceKind.topLevelPropertyAccessor)
+ ]);
+ }
+
+ test_constExpr_pushReference_topLevelGetter_imported_withPrefix() {
+ addNamedSource('/a.dart', 'int get x => null;');
+ UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const v = p.x;
+''');
+ _assertUnlinkedConst(variable.constExpr, operators: [
+ UnlinkedConstOperation.pushReference
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'x',
+ expectedKind: ReferenceKind.topLevelPropertyAccessor,
+ expectedPrefix: 'p')
+ ]);
+ }
+
test_constExpr_pushReference_topLevelVariable() {
UnlinkedVariable variable = serializeVariableText('''
const int a = 1;
@@ -3142,7 +3251,9 @@
findExecutable('', executables: serializeClassText(text).executables);
expect(executable.kind, UnlinkedExecutableKind.constructor);
expect(executable.returnType, isNull);
+ expect(executable.isAsynchronous, isFalse);
expect(executable.isExternal, isFalse);
+ expect(executable.isGenerator, isFalse);
expect(executable.nameOffset, text.indexOf('C();'));
expect(executable.periodOffset, 0);
expect(executable.nameEnd, 0);
@@ -4738,7 +4849,9 @@
UnlinkedExecutable executable = serializeExecutableText(text);
expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
expect(executable.returnType, isNull);
+ expect(executable.isAsynchronous, isFalse);
expect(executable.isExternal, isFalse);
+ expect(executable.isGenerator, isFalse);
expect(executable.nameOffset, text.indexOf('f'));
expect(executable.visibleOffset, 0);
expect(executable.visibleLength, 0);
@@ -4749,6 +4862,24 @@
expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
}
+ test_executable_function_async() {
+ UnlinkedExecutable executable = serializeExecutableText(r'''
+import 'dart:async';
+Future f() async {}
+''');
+ expect(executable.isAsynchronous, isTrue);
+ expect(executable.isGenerator, isFalse);
+ }
+
+ test_executable_function_asyncStar() {
+ UnlinkedExecutable executable = serializeExecutableText(r'''
+import 'dart:async';
+Stream f() async* {}
+''');
+ expect(executable.isAsynchronous, isTrue);
+ expect(executable.isGenerator, isTrue);
+ }
+
test_executable_function_explicit_return() {
UnlinkedExecutable executable =
serializeExecutableText('dynamic f() => null;');
@@ -4770,7 +4901,9 @@
UnlinkedExecutable executable = serializeExecutableText(text);
expect(executable.kind, UnlinkedExecutableKind.getter);
expect(executable.returnType, isNotNull);
+ expect(executable.isAsynchronous, isFalse);
expect(executable.isExternal, isFalse);
+ expect(executable.isGenerator, isFalse);
expect(executable.nameOffset, text.indexOf('f'));
expect(findVariable('f'), isNull);
expect(findExecutable('f='), isNull);
@@ -5203,12 +5336,38 @@
executables: serializeClassText('class C { f() {} }').executables);
expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
expect(executable.returnType, isNull);
+ expect(executable.isAsynchronous, isFalse);
expect(executable.isExternal, isFalse);
+ expect(executable.isGenerator, isFalse);
expect(executable.visibleOffset, 0);
expect(executable.visibleLength, 0);
_assertCodeRange(executable.codeRange, 10, 6);
}
+ test_executable_member_function_async() {
+ UnlinkedExecutable executable =
+ findExecutable('f', executables: serializeClassText(r'''
+import 'dart:async';
+class C {
+ Future f() async {}
+}
+''').executables);
+ expect(executable.isAsynchronous, isTrue);
+ expect(executable.isGenerator, isFalse);
+ }
+
+ test_executable_member_function_asyncStar() {
+ UnlinkedExecutable executable =
+ findExecutable('f', executables: serializeClassText(r'''
+import 'dart:async';
+class C {
+ Stream f() async* {}
+}
+''').executables);
+ expect(executable.isAsynchronous, isTrue);
+ expect(executable.isGenerator, isTrue);
+ }
+
test_executable_member_function_explicit_return() {
UnlinkedExecutable executable = findExecutable('f',
executables:
@@ -5229,10 +5388,16 @@
findExecutable('f', executables: cls.executables, failIfAbsent: true);
expect(executable.kind, UnlinkedExecutableKind.getter);
expect(executable.returnType, isNotNull);
+ expect(executable.isAsynchronous, isFalse);
expect(executable.isExternal, isFalse);
+ expect(executable.isGenerator, isFalse);
+ expect(executable.isStatic, isFalse);
_assertCodeRange(executable.codeRange, 10, 15);
expect(findVariable('f', variables: cls.fields), isNull);
expect(findExecutable('f=', executables: cls.executables), isNull);
+ expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+ expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+ expect(unlinkedUnits[0].publicNamespace.names[0].members, isEmpty);
}
test_executable_member_getter_external() {
@@ -5242,13 +5407,34 @@
expect(executable.isExternal, isTrue);
}
+ test_executable_member_getter_static() {
+ UnlinkedClass cls =
+ serializeClassText('class C { static int get f => 1; }');
+ UnlinkedExecutable executable =
+ findExecutable('f', executables: cls.executables, failIfAbsent: true);
+ expect(executable.isStatic, isTrue);
+ expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+ expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+ expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1));
+ expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'f');
+ expect(unlinkedUnits[0].publicNamespace.names[0].members[0].kind,
+ ReferenceKind.propertyAccessor);
+ expect(
+ unlinkedUnits[0].publicNamespace.names[0].members[0].numTypeParameters,
+ 0);
+ expect(
+ unlinkedUnits[0].publicNamespace.names[0].members[0].members, isEmpty);
+ }
+
test_executable_member_setter() {
UnlinkedClass cls = serializeClassText('class C { void set f(value) {} }');
UnlinkedExecutable executable =
findExecutable('f=', executables: cls.executables, failIfAbsent: true);
expect(executable.kind, UnlinkedExecutableKind.setter);
expect(executable.returnType, isNotNull);
+ expect(executable.isAsynchronous, isFalse);
expect(executable.isExternal, isFalse);
+ expect(executable.isGenerator, isFalse);
_assertCodeRange(executable.codeRange, 10, 20);
expect(findVariable('f', variables: cls.fields), isNull);
expect(findExecutable('f', executables: cls.executables), isNull);
@@ -5302,8 +5488,10 @@
expect(executable.name, '+');
expect(executable.returnType, isNotNull);
expect(executable.isAbstract, false);
+ expect(executable.isAsynchronous, isFalse);
expect(executable.isConst, false);
expect(executable.isFactory, false);
+ expect(executable.isGenerator, isFalse);
expect(executable.isStatic, false);
expect(executable.parameters, hasLength(1));
checkTypeRef(executable.returnType, null, null, 'C');
@@ -5316,7 +5504,9 @@
serializeClassText('class C { C operator+(C c); }', allowErrors: true)
.executables[0];
expect(executable.isAbstract, true);
+ expect(executable.isAsynchronous, isFalse);
expect(executable.isExternal, false);
+ expect(executable.isGenerator, isFalse);
}
test_executable_operator_equal() {
@@ -5331,7 +5521,9 @@
serializeClassText('class C { external C operator+(C c); }')
.executables[0];
expect(executable.isAbstract, false);
+ expect(executable.isAsynchronous, isFalse);
expect(executable.isExternal, true);
+ expect(executable.isGenerator, isFalse);
}
test_executable_operator_greater_equal() {
@@ -5582,7 +5774,9 @@
serializeExecutableText(text, executableName: 'f=');
expect(executable.kind, UnlinkedExecutableKind.setter);
expect(executable.returnType, isNotNull);
+ expect(executable.isAsynchronous, isFalse);
expect(executable.isExternal, isFalse);
+ expect(executable.isGenerator, isFalse);
expect(executable.nameOffset, text.indexOf('f'));
expect(findVariable('f'), isNull);
expect(findExecutable('f'), isNull);
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 4c3007b..cddc662 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -70,6 +70,7 @@
runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
runReflectiveTests(ResolveLibraryTaskTest);
runReflectiveTests(ResolveLibraryTypeNamesTaskTest);
+ runReflectiveTests(ResolveTopLevelUnitTypeBoundsTaskTest);
runReflectiveTests(ResolveUnitTaskTest);
runReflectiveTests(ResolveUnitTypeNamesTaskTest);
runReflectiveTests(ResolveVariableReferencesTaskTest);
@@ -136,6 +137,8 @@
isInstanceOf isResolveLibraryTask = new isInstanceOf<ResolveLibraryTask>();
isInstanceOf isResolveLibraryTypeNamesTask =
new isInstanceOf<ResolveLibraryTypeNamesTask>();
+isInstanceOf isResolveTopLevelUnitTypeBoundsTask =
+ new isInstanceOf<ResolveTopLevelUnitTypeBoundsTask>();
isInstanceOf isResolveUnitTask = new isInstanceOf<ResolveUnitTask>();
isInstanceOf isResolveUnitTypeNamesTask =
new isInstanceOf<ResolveUnitTypeNamesTask>();
@@ -1499,9 +1502,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT6);
- expect(outputs[RESOLVED_UNIT6], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT6], isTrue);
+ computeResult(target, RESOLVED_UNIT7);
+ expect(outputs[RESOLVED_UNIT7], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT7], isTrue);
}
test_perform() {
@@ -1512,8 +1515,8 @@
const b = 0;
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(target, RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
TopLevelVariableElement elementA = unit.element.topLevelVariables[0];
TopLevelVariableElement elementB = unit.element.topLevelVariables[1];
@@ -2025,8 +2028,8 @@
}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(target, RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
FieldElement elementA = AstFinder.getFieldInClassElement(unit, 'A', 'a');
// compute
computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
@@ -2056,8 +2059,8 @@
var d4 = 4;
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(target, RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
TopLevelVariableElement elementA =
AstFinder.getTopLevelVariableElement(unit, 'a');
// compute
@@ -2087,8 +2090,8 @@
final d = 4;
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(target, RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
TopLevelVariableElement elementA =
AstFinder.getTopLevelVariableElement(unit, 'a');
// compute
@@ -2111,8 +2114,8 @@
const c = 2;
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(target, RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
TopLevelVariableElement elementA =
AstFinder.getTopLevelVariableElement(unit, 'a');
// compute
@@ -2219,9 +2222,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT12);
- expect(outputs[RESOLVED_UNIT12], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT12], isTrue);
+ computeResult(target, RESOLVED_UNIT13);
+ expect(outputs[RESOLVED_UNIT13], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT13], isTrue);
}
test_perform() {
@@ -2238,9 +2241,9 @@
const x = const C();
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT12,
+ computeResult(target, RESOLVED_UNIT13,
matcher: isEvaluateUnitConstantsTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT12];
+ CompilationUnit unit = outputs[RESOLVED_UNIT13];
CompilationUnitElement unitElement = unit.element;
expect(
(unitElement.types[0].constructors[0] as ConstructorElementImpl)
@@ -2747,9 +2750,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT10);
- expect(outputs[RESOLVED_UNIT10], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
+ computeResult(target, RESOLVED_UNIT11);
+ expect(outputs[RESOLVED_UNIT11], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
}
void test_perform() {
@@ -2769,9 +2772,9 @@
class Y {}
class Z {}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
matcher: isInferInstanceMembersInUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT10];
+ CompilationUnit unit = outputs[RESOLVED_UNIT11];
VariableDeclaration field = AstFinder.getFieldInClass(unit, 'B', 'f');
MethodDeclaration method = AstFinder.getMethodInClass(unit, 'B', 'm');
DartType typeX = AstFinder.getClass(unit, 'X').element.type;
@@ -2803,12 +2806,12 @@
}
''');
computeResult(
- new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT10,
+ new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11,
matcher: isInferInstanceMembersInUnitTask);
- CompilationUnit firstUnit = outputs[RESOLVED_UNIT10];
+ CompilationUnit firstUnit = outputs[RESOLVED_UNIT11];
computeResult(
- new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT10);
- CompilationUnit secondUnit = outputs[RESOLVED_UNIT10];
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
+ CompilationUnit secondUnit = outputs[RESOLVED_UNIT11];
VariableDeclaration variableA =
AstFinder.getTopLevelVariable(firstUnit, 'a');
@@ -2835,8 +2838,8 @@
String field = topLevel;
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
- CompilationUnit unit = outputs[RESOLVED_UNIT10];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+ CompilationUnit unit = outputs[RESOLVED_UNIT11];
VariableDeclaration topLevelDecl =
AstFinder.getTopLevelVariable(unit, 'topLevel');
VariableDeclaration fieldDecl =
@@ -2867,9 +2870,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT8);
- expect(outputs[RESOLVED_UNIT8], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
+ computeResult(target, RESOLVED_UNIT9);
+ expect(outputs[RESOLVED_UNIT9], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
}
void test_perform_const_field() {
@@ -2881,9 +2884,9 @@
static const X = "";
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
matcher: isInferStaticVariableTypesInUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT8];
+ CompilationUnit unit = outputs[RESOLVED_UNIT9];
VariableDeclaration declaration = AstFinder.getFieldInClass(unit, 'M', 'X');
InterfaceType stringType = context.typeProvider.stringType;
expect(declaration.element.type, stringType);
@@ -2896,9 +2899,9 @@
@(i $=
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT8);
- expect(outputs[RESOLVED_UNIT8], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
+ computeResult(target, RESOLVED_UNIT9);
+ expect(outputs[RESOLVED_UNIT9], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
}
void test_perform_nestedDeclarations() {
@@ -2912,7 +2915,7 @@
return xSquared;
};
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
matcher: isInferStaticVariableTypesInUnitTask);
}
@@ -2935,12 +2938,12 @@
class M {}
''');
computeResult(
- new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8,
+ new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9,
matcher: isInferStaticVariableTypesInUnitTask);
- CompilationUnit firstUnit = outputs[RESOLVED_UNIT8];
+ CompilationUnit firstUnit = outputs[RESOLVED_UNIT9];
computeResult(
- new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8);
- CompilationUnit secondUnit = outputs[RESOLVED_UNIT8];
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9);
+ CompilationUnit secondUnit = outputs[RESOLVED_UNIT9];
VariableDeclaration variableA =
AstFinder.getTopLevelVariable(firstUnit, 'a');
@@ -2969,9 +2972,9 @@
return 1 + X;
};
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
matcher: isInferStaticVariableTypesInUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT8];
+ CompilationUnit unit = outputs[RESOLVED_UNIT9];
TopLevelVariableDeclaration declaration = unit.declarations[1];
FunctionExpression function =
declaration.variables.variables[0].initializer;
@@ -2993,8 +2996,8 @@
var field = '';
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
VariableDeclaration declaration =
AstFinder.getFieldInClass(unit, 'C', 'field');
VariableElement variable = declaration.name.staticElement;
@@ -3009,8 +3012,8 @@
'''
var topLevel = '';
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
VariableDeclaration declaration =
AstFinder.getTopLevelVariable(unit, 'topLevel');
VariableElement variable = declaration.name.staticElement;
@@ -3029,8 +3032,8 @@
var field3 = topLevel3;
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
VariableDeclaration topLevelDecl =
AstFinder.getTopLevelVariable(unit, 'topLevel3');
VariableDeclaration fieldDecl =
@@ -3056,8 +3059,8 @@
var field = topLevel;
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
VariableElement topLevel =
AstFinder.getTopLevelVariable(unit, 'topLevel').name.staticElement;
VariableElement field =
@@ -3079,8 +3082,8 @@
var pi = piFirst ? 3.14 : tau / 2;
var tau = piFirst ? pi * 2 : 6.28;
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
VariableElement piFirst =
AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
VariableElement pi =
@@ -3102,8 +3105,8 @@
'''
var a = '' / null;
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
VariableElement a =
AstFinder.getTopLevelVariable(unit, 'a').name.staticElement;
@@ -3119,8 +3122,8 @@
'''
var a = null;
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
VariableElement a =
AstFinder.getTopLevelVariable(unit, 'a').name.staticElement;
@@ -3434,11 +3437,11 @@
new A<int>().m();
}
''');
- computeResult(new LibrarySpecificUnit(sourceC, sourceC), RESOLVED_UNIT6,
+ computeResult(new LibrarySpecificUnit(sourceC, sourceC), RESOLVED_UNIT7,
matcher: isPartiallyResolveUnitReferencesTask);
// validate
expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(0));
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
expect(unit, isNotNull);
FunctionDeclaration mainFunction = unit.declarations[0];
@@ -3466,9 +3469,9 @@
}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT6,
+ computeResult(target, RESOLVED_UNIT7,
matcher: isPartiallyResolveUnitReferencesTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
// INFERABLE_STATIC_VARIABLES_IN_UNIT
{
List<VariableElement> variables =
@@ -3509,9 +3512,9 @@
}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT6,
+ computeResult(target, RESOLVED_UNIT7,
matcher: isPartiallyResolveUnitReferencesTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
NodeList<CompilationUnitMember> declarations = unit.declarations;
void expectReference(BlockFunctionBody body, bool isResolved) {
@@ -3560,9 +3563,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT7);
- expect(outputs[RESOLVED_UNIT7], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT7], isTrue);
+ computeResult(target, RESOLVED_UNIT8);
+ expect(outputs[RESOLVED_UNIT8], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
}
void test_perform_cycle() {
@@ -3574,9 +3577,9 @@
final tau = piFirst ? pi * 2 : 6.28;
''');
// compute
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
matcher: isPropagateVariableTypesInUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT7];
+ CompilationUnit unit = outputs[RESOLVED_UNIT8];
// verify
TopLevelVariableElement piFirst =
AstFinder.getTopLevelVariableElement(unit, 'piFirst');
@@ -3599,9 +3602,9 @@
final c = '2';
''');
// compute
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
matcher: isPropagateVariableTypesInUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT7];
+ CompilationUnit unit = outputs[RESOLVED_UNIT8];
// verify
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -3624,8 +3627,8 @@
final pi = piFirst ? 3.14 : tau / 2;
final tau = piFirst ? pi * 2 : 6.28;
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
TopLevelVariableElement piFirst =
AstFinder.getTopLevelVariableElement(unit, 'piFirst');
TopLevelVariableElement pi =
@@ -3647,8 +3650,8 @@
'''
var a = null;
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
TopLevelVariableElement a = AstFinder.getTopLevelVariableElement(unit, 'a');
// compute
computeResult(a, PROPAGATED_VARIABLE, matcher: isPropagateVariableTypeTask);
@@ -3663,8 +3666,8 @@
final b = 1;
final c = '2';
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT6);
- CompilationUnit unit = outputs[RESOLVED_UNIT6];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
+ CompilationUnit unit = outputs[RESOLVED_UNIT7];
TopLevelVariableElement elementA =
AstFinder.getTopLevelVariableElement(unit, 'a');
TopLevelVariableElement elementB =
@@ -3749,9 +3752,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT9);
- expect(outputs[RESOLVED_UNIT9], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
+ computeResult(target, RESOLVED_UNIT10);
+ expect(outputs[RESOLVED_UNIT10], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
}
// Test inference of instance fields across units
@@ -3781,16 +3784,16 @@
DartType dynamicType = context.typeProvider.dynamicType;
computeResult(
- new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
- CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
+ new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT10];
// B.b2 shoud be resolved on the rhs, but not yet inferred.
assertVariableDeclarationTypes(
AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
computeResult(
- new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
- CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
// B.b2 should now be fully resolved and inferred.
assertVariableDeclarationTypes(
@@ -3801,7 +3804,7 @@
AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
computeResult(
- new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
+ new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);
// A.a2 should now be fully resolved and inferred.
assertVariableDeclarationTypes(
@@ -3838,15 +3841,15 @@
DartType dynamicType = context.typeProvider.dynamicType;
computeResult(
- new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
- CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
// A.a2 should now be resolved on the rhs, but not yet inferred.
assertVariableDeclarationTypes(
AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
computeResult(
- new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
+ new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);
// A.a2 should now be fully resolved and inferred (but not re-resolved).
assertVariableDeclarationTypes(
@@ -3884,8 +3887,8 @@
DartType dynamicType = context.typeProvider.dynamicType;
computeResult(
- new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
- CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
+ new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT10];
assertVariableDeclarationTypes(
AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
@@ -3893,8 +3896,8 @@
AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
computeResult(
- new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
- CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
assertVariableDeclarationTypes(
AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
@@ -3907,7 +3910,7 @@
AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
computeResult(
- new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
+ new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);
assertVariableDeclarationTypes(
AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
@@ -3946,8 +3949,8 @@
DartType dynamicType = context.typeProvider.dynamicType;
computeResult(
- new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
- CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
+ new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
+ CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
// A.a2 should now be resolved on the rhs, but not yet inferred.
assertVariableDeclarationTypes(
@@ -3958,7 +3961,7 @@
AstFinder.getFieldInClass(unit0, "B", "b2"), dynamicType, intType);
computeResult(
- new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
+ new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
// A.a2 should now be fully resolved and inferred (but not re-resolved).
assertVariableDeclarationTypes(
@@ -4013,10 +4016,10 @@
part of my_lib;
class C extends A {}
''');
- computeResult(sourceLib, LIBRARY_ELEMENT5,
+ computeResult(sourceLib, LIBRARY_ELEMENT6,
matcher: isResolveLibraryTypeNamesTask);
// validate
- LibraryElement library = outputs[LIBRARY_ELEMENT5];
+ LibraryElement library = outputs[LIBRARY_ELEMENT6];
{
ClassElement classB = library.getType('B');
expect(classB.supertype.displayName, 'A');
@@ -4044,10 +4047,10 @@
''');
// The reference A to B should be resolved, but there's no requirement that
// the full class hierarchy be resolved.
- computeResult(sourceA, LIBRARY_ELEMENT5,
+ computeResult(sourceA, LIBRARY_ELEMENT6,
matcher: isResolveLibraryTypeNamesTask);
// validate
- LibraryElement library = outputs[LIBRARY_ELEMENT5];
+ LibraryElement library = outputs[LIBRARY_ELEMENT6];
{
ClassElement clazz = library.getType('A');
expect(clazz.displayName, 'A');
@@ -4058,6 +4061,134 @@
}
@reflectiveTest
+class ResolveTopLevelUnitTypeBoundsTaskTest extends _AbstractDartTaskTest {
+ test_perform_boundIsGenericType() {
+ Source source = newSource(
+ '/test.dart',
+ '''
+class C<T extends Map<String, List<int>>> {}
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, RESOLVED_UNIT4,
+ matcher: isResolveTopLevelUnitTypeBoundsTask);
+ // validate
+ CompilationUnit unit = outputs[RESOLVED_UNIT4];
+ ClassDeclaration nodeC = unit.declarations[0];
+ _assertTypeParameterBound(nodeC.typeParameters.typeParameters[0],
+ 'Map<String, List<int>>', 'Map');
+ }
+
+ test_perform_errors() {
+ Source source = newSource(
+ '/test.dart',
+ '''
+class C<T extends NoSuchClass> {}
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, RESOLVE_TYPE_BOUNDS_ERRORS,
+ matcher: isResolveTopLevelUnitTypeBoundsTask);
+ // validate
+ _fillErrorListener(RESOLVE_TYPE_BOUNDS_ERRORS);
+ errorListener
+ .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
+ }
+
+ test_perform_ignoreBoundsOfBounds() {
+ Source source = newSource(
+ '/test.dart',
+ '''
+class A<T1 extends num> {}
+class B<T2 extends A> {}
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, RESOLVED_UNIT4,
+ matcher: isResolveTopLevelUnitTypeBoundsTask);
+ // validate
+ CompilationUnit unit = outputs[RESOLVED_UNIT4];
+ ClassDeclaration nodeB = unit.declarations[1];
+ _assertTypeParameterBound(
+ nodeB.typeParameters.typeParameters[0], 'A<dynamic>', 'A');
+ }
+
+ test_perform_outputs() {
+ Source source = newSource(
+ '/test.dart',
+ r'''
+class C<T extends int> {}
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, RESOLVED_UNIT4);
+ expect(outputs[RESOLVED_UNIT4], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT4], isTrue);
+ expect(outputs[RESOLVE_TYPE_BOUNDS_ERRORS], isNotNull);
+ }
+
+ test_perform_unitMember_ClassDeclaration() {
+ Source source = newSource(
+ '/test.dart',
+ '''
+class C<T extends int> extends Object {}
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, RESOLVED_UNIT4,
+ matcher: isResolveTopLevelUnitTypeBoundsTask);
+ // validate
+ CompilationUnit unit = outputs[RESOLVED_UNIT4];
+ ClassDeclaration nodeC = unit.declarations[0];
+ // 'extends Object' is not resolved
+ expect(nodeC.extendsClause.superclass.name.staticElement, isNull);
+ // but 'T extends int' is resolved
+ _assertTypeParameterBound(
+ nodeC.typeParameters.typeParameters[0], 'int', 'int');
+ }
+
+ test_perform_unitMember_ClassTypeAlias() {
+ Source source = newSource(
+ '/test.dart',
+ '''
+class C<T extends double> = Object;
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, RESOLVED_UNIT4,
+ matcher: isResolveTopLevelUnitTypeBoundsTask);
+ // validate
+ CompilationUnit unit = outputs[RESOLVED_UNIT4];
+ ClassTypeAlias nodeC = unit.declarations[0];
+ // '= Object' is not resolved
+ expect(nodeC.superclass.name.staticElement, isNull);
+ // but 'T extends int' is resolved
+ _assertTypeParameterBound(
+ nodeC.typeParameters.typeParameters[0], 'double', 'double');
+ }
+
+ test_perform_unitMember_FunctionTypeAlias() {
+ Source source = newSource(
+ '/test.dart',
+ '''
+typedef F<T extends String>();
+''');
+ LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
+ computeResult(target, RESOLVED_UNIT4,
+ matcher: isResolveTopLevelUnitTypeBoundsTask);
+ // validate
+ CompilationUnit unit = outputs[RESOLVED_UNIT4];
+ FunctionTypeAlias nodeF = unit.declarations[0];
+ // but 'T extends String' is resolved
+ _assertTypeParameterBound(
+ nodeF.typeParameters.typeParameters[0], 'String', 'String');
+ }
+
+ void _assertTypeParameterBound(TypeParameter typeParameter,
+ String expectedBoundTypeString, String expectedBoundElementName) {
+ TypeName boundNode = typeParameter.bound;
+ Identifier boundName = boundNode.name;
+ expect(boundNode.type.toString(), expectedBoundTypeString);
+ expect(boundName.staticType.toString(), expectedBoundTypeString);
+ expect(boundName.staticElement.displayName, expectedBoundElementName);
+ }
+}
+
+@reflectiveTest
class ResolveUnitTaskTest extends _AbstractDartTaskTest {
test_created_resolved_unit() {
Source source = newSource(
@@ -4067,9 +4198,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT11);
- expect(outputs[RESOLVED_UNIT11], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
+ computeResult(target, RESOLVED_UNIT12);
+ expect(outputs[RESOLVED_UNIT12], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT12], isTrue);
}
void test_perform() {
@@ -4086,9 +4217,9 @@
}
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12,
matcher: isResolveUnitTask);
- CompilationUnit unit = outputs[RESOLVED_UNIT11];
+ CompilationUnit unit = outputs[RESOLVED_UNIT12];
FunctionDeclaration f = unit.declarations[0];
_assertResolved(f.functionExpression.body);
@@ -4115,10 +4246,10 @@
a.v.isEven;
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12,
matcher: isResolveUnitTask);
expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
- CompilationUnit unit = outputs[RESOLVED_UNIT11];
+ CompilationUnit unit = outputs[RESOLVED_UNIT12];
FunctionDeclaration main = unit.declarations[0];
BlockFunctionBody body = main.functionExpression.body;
ExpressionStatement statement = body.block.statements.single;
@@ -4143,9 +4274,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT4);
- expect(outputs[RESOLVED_UNIT4], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT4], isTrue);
+ computeResult(target, RESOLVED_UNIT5);
+ expect(outputs[RESOLVED_UNIT5], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT5], isTrue);
}
test_perform() {
@@ -4157,9 +4288,9 @@
int f(String p) => p.length;
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT4, matcher: isResolveUnitTypeNamesTask);
+ computeResult(target, RESOLVED_UNIT5, matcher: isResolveUnitTypeNamesTask);
// validate
- CompilationUnit unit = outputs[RESOLVED_UNIT4];
+ CompilationUnit unit = outputs[RESOLVED_UNIT5];
{
ClassDeclaration nodeA = unit.declarations[0];
ClassDeclaration nodeB = unit.declarations[1];
@@ -4199,9 +4330,9 @@
typedef String G(int p);
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT4, matcher: isResolveUnitTypeNamesTask);
+ computeResult(target, RESOLVED_UNIT5, matcher: isResolveUnitTypeNamesTask);
// validate
- CompilationUnit unit = outputs[RESOLVED_UNIT4];
+ CompilationUnit unit = outputs[RESOLVED_UNIT5];
FunctionTypeAlias nodeF = unit.declarations[0];
FunctionTypeAlias nodeG = unit.declarations[1];
{
@@ -4255,9 +4386,9 @@
class A {}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT5);
- expect(outputs[RESOLVED_UNIT5], isNotNull);
- expect(outputs[CREATED_RESOLVED_UNIT5], isTrue);
+ computeResult(target, RESOLVED_UNIT6);
+ expect(outputs[RESOLVED_UNIT6], isNotNull);
+ expect(outputs[CREATED_RESOLVED_UNIT6], isTrue);
}
test_perform_buildClosureLibraryElements() {
@@ -4268,7 +4399,7 @@
}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT5,
+ computeResult(target, RESOLVED_UNIT6,
matcher: isResolveVariableReferencesTask);
}
@@ -4290,10 +4421,10 @@
}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT5,
+ computeResult(target, RESOLVED_UNIT6,
matcher: isResolveVariableReferencesTask);
// validate
- CompilationUnit unit = outputs[RESOLVED_UNIT5];
+ CompilationUnit unit = outputs[RESOLVED_UNIT6];
FunctionDeclaration mainDeclaration = unit.declarations[0];
FunctionBody body = mainDeclaration.functionExpression.body;
FunctionElement main = mainDeclaration.element;
@@ -4317,10 +4448,10 @@
}
''');
LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
- computeResult(target, RESOLVED_UNIT5,
+ computeResult(target, RESOLVED_UNIT6,
matcher: isResolveVariableReferencesTask);
// validate
- CompilationUnit unit = outputs[RESOLVED_UNIT5];
+ CompilationUnit unit = outputs[RESOLVED_UNIT6];
FunctionDeclaration mainDeclaration = unit.declarations[0];
FunctionBody body = mainDeclaration.functionExpression.body;
FunctionElement main = mainDeclaration.element;
@@ -4399,8 +4530,8 @@
var pi = piFirst ? 3.14 : tau / 2;
var tau = piFirst ? pi * 2 : 6.28;
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
- CompilationUnit unit = outputs[RESOLVED_UNIT11];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
+ CompilationUnit unit = outputs[RESOLVED_UNIT12];
VariableElement piFirst =
AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
VariableElement pi =
@@ -4442,11 +4573,11 @@
}
''');
computeResult(
- new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11);
- CompilationUnit unit1 = outputs[RESOLVED_UNIT11];
+ new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT12);
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT12];
computeResult(
- new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
- CompilationUnit unit2 = outputs[RESOLVED_UNIT11];
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT12);
+ CompilationUnit unit2 = outputs[RESOLVED_UNIT12];
InterfaceType intType = context.typeProvider.intType;
@@ -4493,7 +4624,7 @@
'''
});
List<dynamic> units =
- computeLibraryResults(sources, RESOLVED_UNIT11).toList();
+ computeLibraryResults(sources, RESOLVED_UNIT12).toList();
CompilationUnit unit0 = units[0];
CompilationUnit unit1 = units[1];
CompilationUnit unit2 = units[2];
@@ -4540,7 +4671,7 @@
'''
});
List<dynamic> units =
- computeLibraryResults(sources, RESOLVED_UNIT11).toList();
+ computeLibraryResults(sources, RESOLVED_UNIT12).toList();
CompilationUnit unit0 = units[0];
CompilationUnit unit2 = units[2];
@@ -4581,11 +4712,11 @@
}
''');
computeResult(
- new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11);
- CompilationUnit unit1 = outputs[RESOLVED_UNIT11];
+ new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT12);
+ CompilationUnit unit1 = outputs[RESOLVED_UNIT12];
computeResult(
- new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
- CompilationUnit unit2 = outputs[RESOLVED_UNIT11];
+ new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT12);
+ CompilationUnit unit2 = outputs[RESOLVED_UNIT12];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -4635,7 +4766,7 @@
'''
});
List<dynamic> units =
- computeLibraryResults(sources, RESOLVED_UNIT11).toList();
+ computeLibraryResults(sources, RESOLVED_UNIT12).toList();
CompilationUnit unit0 = units[0];
CompilationUnit unit1 = units[1];
CompilationUnit unit2 = units[2];
@@ -4671,8 +4802,8 @@
y = "hi";
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
- CompilationUnit unit = outputs[RESOLVED_UNIT11];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
+ CompilationUnit unit = outputs[RESOLVED_UNIT12];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -4710,8 +4841,8 @@
final z = 42; // should infer `int`
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
- CompilationUnit unit = outputs[RESOLVED_UNIT11];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
+ CompilationUnit unit = outputs[RESOLVED_UNIT12];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -4759,8 +4890,8 @@
int y = 0; // field def after use
final z = 42; // should infer `int`
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
- CompilationUnit unit = outputs[RESOLVED_UNIT11];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
+ CompilationUnit unit = outputs[RESOLVED_UNIT12];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -4812,8 +4943,8 @@
new A().y2 = /*severe:StaticTypeError*/"hi";
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
- CompilationUnit unit = outputs[RESOLVED_UNIT11];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
+ CompilationUnit unit = outputs[RESOLVED_UNIT12];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
@@ -4854,8 +4985,8 @@
x = "hi";
}
''');
- computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
- CompilationUnit unit = outputs[RESOLVED_UNIT11];
+ computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
+ CompilationUnit unit = outputs[RESOLVED_UNIT12];
InterfaceType intType = context.typeProvider.intType;
InterfaceType stringType = context.typeProvider.stringType;
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 9a7b128..28ab23a 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -229,10 +229,8 @@
test('dynamic invocation', () {
checkFile('''
- class A {
- dynamic call(dynamic x) => x;
- }
- class B extends A {
+ typedef dynamic A(dynamic x);
+ class B {
int call(int x) => x;
double col(double x) => x;
}
@@ -276,7 +274,6 @@
/*info:DYNAMIC_INVOKE*/g.foo(42.0);
/*info:DYNAMIC_INVOKE*/g./*info:UNDEFINED_GETTER*/x;
A f = new B();
- 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;
@@ -2002,6 +1999,99 @@
''');
});
+ test('method override, fuzzy arrows', () {
+ checkFile('''
+ abstract class A {
+ bool operator ==(Object object);
+ }
+
+ class B implements A {}
+
+
+ class F {
+ void f(x) {}
+ void g(int x) {}
+ }
+
+ class G extends F {
+ /*severe:INVALID_METHOD_OVERRIDE*/void f(int x) {}
+ void g(dynamic x) {}
+ }
+
+ class H implements F {
+ /*severe:INVALID_METHOD_OVERRIDE*/void f(int x) {}
+ void g(dynamic x) {}
+ }
+
+ ''');
+ });
+
+ test('getter override, fuzzy arrows', () {
+ checkFile('''
+ typedef void ToVoid<T>(T x);
+ class F {
+ ToVoid<dynamic> get f => null;
+ ToVoid<int> get g => null;
+ }
+
+ class G extends F {
+ ToVoid<int> get f => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
+ }
+
+ class H implements F {
+ ToVoid<int> get f => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
+ }
+ ''');
+ });
+
+ test('setter override, fuzzy arrows', () {
+ checkFile('''
+ typedef void ToVoid<T>(T x);
+ class F {
+ void set f(ToVoid<dynamic> x) {}
+ void set g(ToVoid<int> x) {}
+ void set h(dynamic x) {}
+ void set i(int x) {}
+ }
+
+ class G extends F {
+ /*severe:INVALID_METHOD_OVERRIDE*/void set f(ToVoid<int> x) {}
+ void set g(ToVoid<dynamic> x) {}
+ void set h(int x) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/void set i(dynamic x) {}
+ }
+
+ class H implements F {
+ /*severe:INVALID_METHOD_OVERRIDE*/void set f(ToVoid<int> x) {}
+ void set g(ToVoid<dynamic> x) {}
+ void set h(int x) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/void set i(dynamic x) {}
+ }
+ ''');
+ });
+
+ test('field override, fuzzy arrows', () {
+ checkFile('''
+ typedef void ToVoid<T>(T x);
+ class F {
+ final ToVoid<dynamic> f = null;
+ final ToVoid<int> g = null;
+ }
+
+ class G extends F {
+ /*severe:INVALID_FIELD_OVERRIDE*/final ToVoid<int> f = null;
+ /*severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/final ToVoid<dynamic> g = null;
+ }
+
+ class H implements F {
+ final ToVoid<int> f = null;
+ /*severe:INVALID_METHOD_OVERRIDE*/final ToVoid<dynamic> g = null;
+ }
+ ''');
+ });
+
test('generic class method override', () {
checkFile('''
class A {}
@@ -2631,7 +2721,7 @@
implements I1 {}
class T2 extends Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/m(a) {}
+ m(a) {}
}
class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T3
@@ -2639,7 +2729,7 @@
implements I1 {}
class T4 extends Object with Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/m(a) {}
+ m(a) {}
}
''');
});
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 84052c4..d1ebb09 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -20,6 +20,11 @@
abstract class InferredTypeMixin {
/**
+ * If `true` then types of local elements may be checked.
+ */
+ bool get mayCheckTypesOfLocals;
+
+ /**
* Add a new file with the given [name] and [content].
*/
void addFile(String content, {String name: '/main.dart'});
@@ -30,27 +35,10 @@
*/
CompilationUnitElement checkFile(String content);
- void test_blockBodiedLambdas_async_allReturnsAreValues() {
- var mainUnit = checkFile(r'''
-import 'dart:async';
-import 'dart:math' show Random;
-main() {
- var f = /*info:INFERRED_TYPE_CLOSURE*/() async {
- if (new Random().nextBool()) {
- return 1;
- } else {
- return 2.0;
+ void test_blockBodiedLambdas_async_allReturnsAreFutures() {
+ if (!mayCheckTypesOfLocals) {
+ return;
}
- };
- Future<num> g = f();
- Future<int> h = /*info:ASSIGNMENT_CAST*/f();
-}
-''');
- var f = mainUnit.functions[0].localVariables[0];
- expect(f.type.toString(), '() → Future<num>');
- }
-
- void test_blockBodiedLambdas_async_alReturnsAreFutures() {
var mainUnit = checkFile(r'''
import 'dart:async';
import 'dart:math' show Random;
@@ -70,40 +58,130 @@
expect(f.type.toString(), '() → Future<num>');
}
- void test_blockBodiedLambdas_async_mixOfValuesAndFutures() {
+ void test_blockBodiedLambdas_async_allReturnsAreFutures_topLevel() {
var mainUnit = checkFile(r'''
- import 'dart:async';
- import 'dart:math' show Random;
- main() {
- var f = /*info:INFERRED_TYPE_CLOSURE*/() async {
- if (new Random().nextBool()) {
- return new Future<int>.value(1);
- } else {
- return 2.0;
- }
- };
- Future<num> g = f();
- Future<int> h = /*info:ASSIGNMENT_CAST*/f();
+import 'dart:async';
+import 'dart:math' show Random;
+var f = /*info:INFERRED_TYPE_CLOSURE*/() async {
+ if (new Random().nextBool()) {
+ return new Future<int>.value(1);
+ } else {
+ return new Future<double>.value(2.0);
}
+};
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '() → Future<num>');
+ }
+
+ void test_blockBodiedLambdas_async_allReturnsAreValues() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
+ var mainUnit = checkFile(r'''
+import 'dart:async';
+import 'dart:math' show Random;
+main() {
+ var f = /*info:INFERRED_TYPE_CLOSURE*/() async {
+ if (new Random().nextBool()) {
+ return 1;
+ } else {
+ return 2.0;
+ }
+ };
+ Future<num> g = f();
+ Future<int> h = /*info:ASSIGNMENT_CAST*/f();
+}
''');
var f = mainUnit.functions[0].localVariables[0];
expect(f.type.toString(), '() → Future<num>');
}
- void test_blockBodiedLambdas_asyncStar() {
+ void test_blockBodiedLambdas_async_allReturnsAreValues_topLevel() {
var mainUnit = checkFile(r'''
- import 'dart:async';
- main() {
- var f = /*info:INFERRED_TYPE_CLOSURE*/() async* {
- yield 1;
- Stream<double> s;
- yield* s;
- };
- Stream<num> g = f();
- Stream<int> h = /*info:ASSIGNMENT_CAST*/f();
+import 'dart:async';
+import 'dart:math' show Random;
+var f = /*info:INFERRED_TYPE_CLOSURE*/() async {
+ if (new Random().nextBool()) {
+ return 1;
+ } else {
+ return 2.0;
}
+};
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '() → Future<num>');
+ }
+
+ void test_blockBodiedLambdas_async_mixOfValuesAndFutures() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
+ var mainUnit = checkFile(r'''
+import 'dart:async';
+import 'dart:math' show Random;
+main() {
+ var f = /*info:INFERRED_TYPE_CLOSURE*/() async {
+ if (new Random().nextBool()) {
+ return new Future<int>.value(1);
+ } else {
+ return 2.0;
+ }
+ };
+ Future<num> g = f();
+ Future<int> h = /*info:ASSIGNMENT_CAST*/f();
+}
''');
var f = mainUnit.functions[0].localVariables[0];
+ expect(f.type.toString(), '() → Future<num>');
+ }
+
+ void test_blockBodiedLambdas_async_mixOfValuesAndFutures_topLevel() {
+ var mainUnit = checkFile(r'''
+import 'dart:async';
+import 'dart:math' show Random;
+var f = /*info:INFERRED_TYPE_CLOSURE*/() async {
+ if (new Random().nextBool()) {
+ return new Future<int>.value(1);
+ } else {
+ return 2.0;
+ }
+};
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '() → Future<num>');
+ }
+
+ void test_blockBodiedLambdas_asyncStar() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
+ var mainUnit = checkFile(r'''
+import 'dart:async';
+main() {
+ var f = /*info:INFERRED_TYPE_CLOSURE*/() async* {
+ yield 1;
+ Stream<double> s;
+ yield* s;
+ };
+ Stream<num> g = f();
+ Stream<int> h = /*info:ASSIGNMENT_CAST*/f();
+}
+''');
+ var f = mainUnit.functions[0].localVariables[0];
+ expect(f.type.toString(), '() → Stream<num>');
+ }
+
+ void test_blockBodiedLambdas_asyncStar_topLevel() {
+ var mainUnit = checkFile(r'''
+ import 'dart:async';
+var f = /*info:INFERRED_TYPE_CLOSURE*/() async* {
+ yield 1;
+ Stream<double> s;
+ yield* s;
+};
+''');
+ var f = mainUnit.topLevelVariables[0];
expect(f.type.toString(), '() → Stream<num>');
}
@@ -126,6 +204,9 @@
}
void test_blockBodiedLambdas_doesNotInferBottom_async() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
var mainUnit = checkFile(r'''
import 'dart:async';
main() async {
@@ -135,12 +216,23 @@
String s = /*info:DYNAMIC_CAST*/await f();
}
''');
-
var f = mainUnit.functions[0].localVariables[0];
expect(f.type.toString(), '() → Future<dynamic>');
}
+ void test_blockBodiedLambdas_doesNotInferBottom_async_topLevel() {
+ var mainUnit = checkFile(r'''
+import 'dart:async';
+var f = () async { return null; };
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '() → Future<dynamic>');
+ }
+
void test_blockBodiedLambdas_doesNotInferBottom_asyncStar() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
var mainUnit = checkFile(r'''
import 'dart:async';
main() async {
@@ -150,12 +242,23 @@
String s = /*info:DYNAMIC_CAST*/await f().first;
}
''');
-
var f = mainUnit.functions[0].localVariables[0];
expect(f.type.toString(), '() → Stream<dynamic>');
}
+ void test_blockBodiedLambdas_doesNotInferBottom_asyncStar_topLevel() {
+ var mainUnit = checkFile(r'''
+import 'dart:async';
+var f = () async* { yield null; };
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '() → Stream<dynamic>');
+ }
+
void test_blockBodiedLambdas_doesNotInferBottom_sync() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
var mainUnit = checkFile(r'''
var h = null;
void foo(int f(Object _)) {}
@@ -175,7 +278,18 @@
expect(f.type.toString(), '(Object) → dynamic');
}
+ void test_blockBodiedLambdas_doesNotInferBottom_sync_topLevel() {
+ var mainUnit = checkFile(r'''
+var f = (Object x) { return null; };
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '(Object) → dynamic');
+ }
+
void test_blockBodiedLambdas_doesNotInferBottom_syncStar() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
var mainUnit = checkFile(r'''
main() {
var f = () sync* { yield null; };
@@ -184,12 +298,22 @@
String s = /*info:DYNAMIC_CAST*/f().first;
}
''');
-
var f = mainUnit.functions[0].localVariables[0];
expect(f.type.toString(), '() → Iterable<dynamic>');
}
+ void test_blockBodiedLambdas_doesNotInferBottom_syncStar_topLevel() {
+ var mainUnit = checkFile(r'''
+var f = () sync* { yield null; };
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '() → Iterable<dynamic>');
+ }
+
void test_blockBodiedLambdas_downwardsIncompatibleWithUpwardsInference() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
var mainUnit = checkFile(r'''
main() {
String f() => null;
@@ -201,6 +325,16 @@
expect(f.type.toString(), '() → String');
}
+ void
+ test_blockBodiedLambdas_downwardsIncompatibleWithUpwardsInference_topLevel() {
+ var mainUnit = checkFile(r'''
+String f() => null;
+var g = f;
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '() → String');
+ }
+
void test_blockBodiedLambdas_LUB() {
checkFile(r'''
import 'dart:math' show Random;
@@ -236,6 +370,9 @@
}
void test_blockBodiedLambdas_nestedLambdas() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
// Original feature request: https://github.com/dart-lang/sdk/issues/25487
var mainUnit = checkFile(r'''
main() {
@@ -248,7 +385,21 @@
expect(f.type.toString(), '() → (int) → num');
}
+ void test_blockBodiedLambdas_nestedLambdas_topLevel() {
+ // Original feature request: https://github.com/dart-lang/sdk/issues/25487
+ var mainUnit = checkFile(r'''
+var f = /*info:INFERRED_TYPE_CLOSURE*/() {
+ return /*info:INFERRED_TYPE_CLOSURE*/(int x) { return 2.0 * x; };
+};
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '() → (int) → num');
+ }
+
void test_blockBodiedLambdas_noReturn() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
var mainUnit = checkFile(r'''
test1() {
List<int> o;
@@ -260,7 +411,19 @@
expect(f.type.toString(), 'Iterable<dynamic>');
}
+ void test_blockBodiedLambdas_noReturn_topLevel() {
+ var mainUnit = checkFile(r'''
+final List<int> o = <int>[];
+var y = o.map((x) { });
+''');
+ var f = mainUnit.topLevelVariables[1];
+ expect(f.type.toString(), 'Iterable<dynamic>');
+ }
+
void test_blockBodiedLambdas_syncStar() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
var mainUnit = checkFile(r'''
main() {
var f = /*info:INFERRED_TYPE_CLOSURE*/() sync* {
@@ -275,6 +438,17 @@
expect(f.type.toString(), '() → Iterable<num>');
}
+ void test_blockBodiedLambdas_syncStar_topLevel() {
+ var mainUnit = checkFile(r'''
+var f = /*info:INFERRED_TYPE_CLOSURE*/() sync* {
+ yield 1;
+ yield* /*info:INFERRED_TYPE_LITERAL*/[3, 4.0];
+};
+''');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '() → Iterable<num>');
+ }
+
void test_canInferAlsoFromStaticAndInstanceFieldsFlagOn() {
addFile(
'''
@@ -1072,6 +1246,17 @@
''');
}
+ void test_fieldRefersToStaticGetter() {
+ var mainUnit = checkFile('''
+class C {
+ final x = _x;
+ static int get _x => null;
+}
+''');
+ var x = mainUnit.types[0].fields[0];
+ expect(x.type.toString(), 'int');
+ }
+
void test_genericMethods_basicDownwardInference() {
checkFile(r'''
/*=T*/ f/*<S, T>*/(/*=S*/ s) => null;
@@ -1086,7 +1271,7 @@
// Regression test for https://github.com/dart-lang/sdk/issues/25740.
checkFile(r'''
class Foo<T extends Pattern> {
-void method/*<U extends T>*/(dynamic/*=U*/ u) {}
+ void method/*<U extends T>*/(dynamic/*=U*/ u) {}
}
main() {
new Foo().method/*<String>*/("str");
@@ -1185,9 +1370,11 @@
checkFile('''
class C {
m(x) => x;
+ dynamic g(int x) => x;
}
class D extends C {
/*=T*/ m/*<T>*/(/*=T*/ x) => x;
+ /*=T*/ g/*<T>*/(/*=T*/ x) => x;
}
main() {
int y = /*info:DYNAMIC_CAST*/(new D() as C).m(42);
@@ -2437,6 +2624,58 @@
''');
}
+ void test_instantiateToBounds_generic2_hasBound_definedAfter() {
+ var unit = checkFile(r'''
+class B<T extends A> {}
+class A<T extends int> {}
+B v = null;
+''');
+ expect(unit.topLevelVariables[0].type.toString(), 'B<A<dynamic>>');
+ }
+
+ void test_instantiateToBounds_generic2_hasBound_definedBefore() {
+ var unit = checkFile(r'''
+class A<T extends int> {}
+class B<T extends A> {}
+B v = null;
+''');
+ expect(unit.topLevelVariables[0].type.toString(), 'B<A<dynamic>>');
+ }
+
+ void test_instantiateToBounds_generic2_noBound() {
+ var unit = checkFile(r'''
+class A<T> {}
+class B<T extends A> {}
+B v = null;
+''');
+ expect(unit.topLevelVariables[0].type.toString(), 'B<A<dynamic>>');
+ }
+
+ void test_instantiateToBounds_generic_hasBound_definedAfter() {
+ var unit = checkFile(r'''
+A v = null;
+class A<T extends int> {}
+''');
+ expect(unit.topLevelVariables[0].type.toString(), 'A<int>');
+ }
+
+ void test_instantiateToBounds_generic_hasBound_definedBefore() {
+ var unit = checkFile(r'''
+class A<T extends int> {}
+A v = null;
+''');
+ expect(unit.topLevelVariables[0].type.toString(), 'A<int>');
+ }
+
+ void test_instantiateToBounds_notGeneric() {
+ var unit = checkFile(r'''
+class A {}
+class B<T extends A> {}
+B v = null;
+''');
+ expect(unit.topLevelVariables[0].type.toString(), 'B<A>');
+ }
+
void test_listLiterals() {
checkFile(r'''
test1() {
@@ -2474,6 +2713,9 @@
}
void test_listLiteralsShouldNotInferBottom() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
var unit = checkFile(r'''
test1() {
var x = [null];
@@ -2484,6 +2726,14 @@
expect(x.type.toString(), 'List<dynamic>');
}
+ void test_listLiteralsShouldNotInferBottom_topLevel() {
+ var unit = checkFile(r'''
+var x = [null];
+''');
+ var x = unit.topLevelVariables[0];
+ expect(x.type.toString(), 'List<dynamic>');
+ }
+
void test_mapLiterals() {
checkFile(r'''
test1() {
@@ -2533,6 +2783,9 @@
}
void test_mapLiteralsShouldNotInferBottom() {
+ if (!mayCheckTypesOfLocals) {
+ return;
+ }
var unit = checkFile(r'''
test1() {
var x = { null: null };
@@ -2543,6 +2796,14 @@
expect(x.type.toString(), 'Map<dynamic, dynamic>');
}
+ void test_mapLiteralsShouldNotInferBottom_topLevel() {
+ var unit = checkFile(r'''
+var x = { null: null };
+''');
+ var x = unit.topLevelVariables[0];
+ expect(x.type.toString(), 'Map<dynamic, dynamic>');
+ }
+
void test_noErrorWhenDeclaredTypeIsNumAndAssignedNull() {
checkFile('''
test1() {
@@ -2651,7 +2912,7 @@
''');
}
- void test_staticRefersToNonstaticField_inOtherLibraryCycle() {
+ void test_staticRefersToNonStaticField_inOtherLibraryCycle() {
addFile(
'''
import 'b.dart';
@@ -2705,6 +2966,9 @@
@reflectiveTest
class InferredTypeTest extends InferredTypeMixin {
+ @override
+ bool get mayCheckTypesOfLocals => true;
+
/// Adds a file to check. The file should contain:
///
/// * all expected failures are listed in the source code using comments
diff --git a/pkg/analyzer/tool/summary/dump_inferred_types.dart b/pkg/analyzer/tool/summary/dump_inferred_types.dart
index 0668513..8b38e73 100644
--- a/pkg/analyzer/tool/summary/dump_inferred_types.dart
+++ b/pkg/analyzer/tool/summary/dump_inferred_types.dart
@@ -57,6 +57,10 @@
SummaryClass obj, Map<String, Object> properties, String path) {
if (obj is UnlinkedVariable) {
collectInferredType(obj.inferredTypeSlot, path);
+ // As a temporary measure, prevent recursion into the variable's
+ // initializer, since AST-based type inference doesn't infer its type
+ // correctly yet. TODO(paulberry): fix.
+ properties.remove('initializer');
} else if (obj is UnlinkedExecutable) {
collectInferredType(obj.inferredReturnTypeSlot, path);
} else if (obj is UnlinkedParam) {
@@ -246,16 +250,22 @@
}
Uri libraryUri = Uri.parse(libraryUriString);
UnlinkedUnit definingUnlinkedUnit = unlinkedUnits[libraryUriString];
- visitUnit(definingUnlinkedUnit, linkedLibrary.units[0], libraryUriString);
- for (int i = 0;
- i < definingUnlinkedUnit.publicNamespace.parts.length;
- i++) {
- Uri relativePartUri =
- Uri.parse(definingUnlinkedUnit.publicNamespace.parts[i]);
- String unitUriString =
- resolveRelativeUri(libraryUri, relativePartUri).toString();
- visitUnit(unlinkedUnits[unitUriString], linkedLibrary.units[i + 1],
- libraryUriString);
+ if (definingUnlinkedUnit != null) {
+ visitUnit(
+ definingUnlinkedUnit, linkedLibrary.units[0], libraryUriString);
+ for (int i = 0;
+ i < definingUnlinkedUnit.publicNamespace.parts.length;
+ i++) {
+ Uri relativePartUri =
+ Uri.parse(definingUnlinkedUnit.publicNamespace.parts[i]);
+ String unitUriString =
+ resolveRelativeUri(libraryUri, relativePartUri).toString();
+ UnlinkedUnit unlinkedUnit = unlinkedUnits[unitUriString];
+ if (unlinkedUnit != null) {
+ visitUnit(
+ unlinkedUnit, linkedLibrary.units[i + 1], libraryUriString);
+ }
+ }
}
});
}
diff --git a/pkg/analyzer/tool/task_dependency_graph/tasks.dot b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
index 75e8989..212dc2b 100644
--- a/pkg/analyzer/tool/task_dependency_graph/tasks.dot
+++ b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
@@ -47,23 +47,24 @@
CREATED_RESOLVED_UNIT [shape=box]
CREATED_RESOLVED_UNIT1 [shape=box]
CREATED_RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
- CREATED_RESOLVED_UNIT10 -> InferStaticVariableTypeTask
- CREATED_RESOLVED_UNIT10 -> PartiallyResolveUnitReferencesTask
- CREATED_RESOLVED_UNIT10 -> ResolveInstanceFieldsInUnitTask
- CREATED_RESOLVED_UNIT10 -> ResolveUnitTask
CREATED_RESOLVED_UNIT10 [shape=box]
- CREATED_RESOLVED_UNIT11 -> ResolveConstantExpressionTask
+ CREATED_RESOLVED_UNIT11 -> InferInstanceMembersInUnitTask
+ CREATED_RESOLVED_UNIT11 -> InferStaticVariableTypeTask
+ CREATED_RESOLVED_UNIT11 -> PartiallyResolveUnitReferencesTask
+ CREATED_RESOLVED_UNIT11 -> ResolveInstanceFieldsInUnitTask
+ CREATED_RESOLVED_UNIT11 -> ResolveUnitTask
CREATED_RESOLVED_UNIT11 [shape=box]
+ CREATED_RESOLVED_UNIT12 -> ResolveConstantExpressionTask
CREATED_RESOLVED_UNIT12 [shape=box]
+ CREATED_RESOLVED_UNIT13 [shape=box]
CREATED_RESOLVED_UNIT2 [shape=box]
CREATED_RESOLVED_UNIT3 [shape=box]
CREATED_RESOLVED_UNIT4 [shape=box]
CREATED_RESOLVED_UNIT5 [shape=box]
CREATED_RESOLVED_UNIT6 [shape=box]
CREATED_RESOLVED_UNIT7 [shape=box]
- CREATED_RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
CREATED_RESOLVED_UNIT8 [shape=box]
- CREATED_RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
+ CREATED_RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
CREATED_RESOLVED_UNIT9 [shape=box]
ComputeConstantDependenciesTask -> CONSTANT_DEPENDENCIES
ComputeConstantValueTask -> CONSTANT_VALUE
@@ -83,11 +84,12 @@
EXPORTED_LIBRARIES -> ReadyLibraryElement2Task
EXPORTED_LIBRARIES -> ReadyLibraryElement5Task
EXPORTED_LIBRARIES -> ReadyLibraryElement6Task
+ EXPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
EXPORTED_LIBRARIES [shape=box]
EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
EXPORT_SOURCE_CLOSURE [shape=box]
- EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT12
- EvaluateUnitConstantsTask -> RESOLVED_UNIT12
+ EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT13
+ EvaluateUnitConstantsTask -> RESOLVED_UNIT13
GatherUsedImportedElementsTask -> USED_IMPORTED_ELEMENTS
GatherUsedLocalElementsTask -> USED_LOCAL_ELEMENTS
GenerateHintsTask -> HINTS
@@ -98,7 +100,8 @@
IMPORTED_LIBRARIES -> ReadyLibraryElement2Task
IMPORTED_LIBRARIES -> ReadyLibraryElement5Task
IMPORTED_LIBRARIES -> ReadyLibraryElement6Task
- IMPORTED_LIBRARIES -> ResolveUnitTypeNamesTask
+ IMPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
+ IMPORTED_LIBRARIES -> ResolveTopLevelUnitTypeBoundsTask
IMPORTED_LIBRARIES [shape=box]
INCLUDED_PARTS -> BuildLibraryElementTask
INCLUDED_PARTS [shape=box]
@@ -110,11 +113,11 @@
INFERRED_STATIC_VARIABLE -> InferStaticVariableTypesInUnitTask
INFERRED_STATIC_VARIABLE [shape=box]
IS_LAUNCHABLE [shape=box]
- InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT10
- InferInstanceMembersInUnitTask -> RESOLVED_UNIT10
+ InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT11
+ InferInstanceMembersInUnitTask -> RESOLVED_UNIT11
InferStaticVariableTypeTask -> INFERRED_STATIC_VARIABLE
- InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
- InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT8
+ InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT9
+ InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT9
LIBRARY_CYCLE [shape=box]
LIBRARY_CYCLE_DEPENDENCIES -> InferInstanceMembersInUnitTask
LIBRARY_CYCLE_DEPENDENCIES -> InferStaticVariableTypeTask
@@ -139,29 +142,34 @@
LIBRARY_ELEMENT3 -> BuildExportNamespaceTask
LIBRARY_ELEMENT3 -> BuildTypeProviderTask
LIBRARY_ELEMENT3 [shape=box]
- LIBRARY_ELEMENT4 -> ResolveLibraryTypeNamesTask
- LIBRARY_ELEMENT4 -> ResolveUnitTypeNamesTask
+ LIBRARY_ELEMENT4 -> ResolveTopLevelLibraryTypeBoundsTask
+ LIBRARY_ELEMENT4 -> ResolveTopLevelUnitTypeBoundsTask
LIBRARY_ELEMENT4 [shape=box]
- LIBRARY_ELEMENT5 -> PartiallyResolveUnitReferencesTask
- LIBRARY_ELEMENT5 -> PropagateVariableTypesInLibraryTask
- LIBRARY_ELEMENT5 -> ReadyLibraryElement5Task
- LIBRARY_ELEMENT5 -> ResolveInstanceFieldsInUnitTask
+ LIBRARY_ELEMENT5 -> ResolveLibraryTypeNamesTask
+ LIBRARY_ELEMENT5 -> ResolveTopLevelLibraryTypeBoundsTask
+ LIBRARY_ELEMENT5 -> ResolveUnitTypeNamesTask
LIBRARY_ELEMENT5 [shape=box]
- LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryClosureTask
- LIBRARY_ELEMENT6 -> ReadyLibraryElement6Task
+ LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
+ LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryTask
+ LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
+ LIBRARY_ELEMENT6 -> ResolveInstanceFieldsInUnitTask
LIBRARY_ELEMENT6 [shape=box]
- LIBRARY_ELEMENT7 -> ResolveLibraryReferencesTask
- LIBRARY_ELEMENT7 -> ResolveUnitTask
+ LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
+ LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
LIBRARY_ELEMENT7 [shape=box]
- LIBRARY_ELEMENT8 -> EvaluateUnitConstantsTask
- LIBRARY_ELEMENT8 -> ResolveLibraryTask
+ LIBRARY_ELEMENT8 -> ResolveLibraryReferencesTask
+ LIBRARY_ELEMENT8 -> ResolveUnitTask
LIBRARY_ELEMENT8 [shape=box]
+ LIBRARY_ELEMENT9 -> EvaluateUnitConstantsTask
+ LIBRARY_ELEMENT9 -> ResolveLibraryTask
+ LIBRARY_ELEMENT9 [shape=box]
LIBRARY_ERRORS_READY [shape=box]
LIBRARY_SPECIFIC_UNITS -> GenerateHintsTask
LIBRARY_SPECIFIC_UNITS -> PropagateVariableTypesInLibraryTask
LIBRARY_SPECIFIC_UNITS -> ReadyResolvedUnitTask
LIBRARY_SPECIFIC_UNITS -> ResolveLibraryReferencesTask
LIBRARY_SPECIFIC_UNITS -> ResolveLibraryTypeNamesTask
+ LIBRARY_SPECIFIC_UNITS -> ResolveTopLevelLibraryTypeBoundsTask
LIBRARY_SPECIFIC_UNITS [shape=box]
LIBRARY_UNIT_ERRORS -> dartErrorsForUnit
LIBRARY_UNIT_ERRORS [shape=box]
@@ -199,24 +207,24 @@
ParseDartTask -> REFERENCED_SOURCES
ParseDartTask -> SOURCE_KIND
ParseDartTask -> UNITS
- PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT6
+ PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT7
PartiallyResolveUnitReferencesTask -> INFERABLE_STATIC_VARIABLES_IN_UNIT
PartiallyResolveUnitReferencesTask -> PROPAGABLE_VARIABLES_IN_UNIT
- PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT6
+ PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT7
PropagateVariableTypeTask -> PROPAGATED_VARIABLE
- PropagateVariableTypesInLibraryClosureTask -> LIBRARY_ELEMENT7
- PropagateVariableTypesInLibraryTask -> LIBRARY_ELEMENT6
- PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT7
- PropagateVariableTypesInUnitTask -> RESOLVED_UNIT7
+ PropagateVariableTypesInLibraryClosureTask -> LIBRARY_ELEMENT8
+ PropagateVariableTypesInLibraryTask -> LIBRARY_ELEMENT7
+ PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
+ PropagateVariableTypesInUnitTask -> RESOLVED_UNIT8
READY_LIBRARY_ELEMENT2 -> ComputeLibraryCycleTask
READY_LIBRARY_ELEMENT2 -> ReadyLibraryElement2Task
READY_LIBRARY_ELEMENT2 [shape=box]
- READY_LIBRARY_ELEMENT5 -> PartiallyResolveUnitReferencesTask
- READY_LIBRARY_ELEMENT5 -> ReadyLibraryElement5Task
- READY_LIBRARY_ELEMENT5 [shape=box]
- READY_LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryClosureTask
- READY_LIBRARY_ELEMENT6 -> ReadyLibraryElement6Task
+ READY_LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
+ READY_LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
READY_LIBRARY_ELEMENT6 [shape=box]
+ READY_LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
+ READY_LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
+ READY_LIBRARY_ELEMENT7 [shape=box]
READY_RESOLVED_UNIT -> ResolveLibraryTask
READY_RESOLVED_UNIT -> VerifyUnitTask
READY_RESOLVED_UNIT [shape=box]
@@ -233,63 +241,72 @@
RESOLVED_UNIT1 -> BuildLibraryElementTask
RESOLVED_UNIT1 -> ResolveDirectiveElementsTask
RESOLVED_UNIT1 [shape=box]
- RESOLVED_UNIT10 -> ResolveUnitTask
+ RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
RESOLVED_UNIT10 [shape=box]
- RESOLVED_UNIT11 -> EvaluateUnitConstantsTask
- RESOLVED_UNIT11 -> GatherUsedImportedElementsTask
- RESOLVED_UNIT11 -> GatherUsedLocalElementsTask
- RESOLVED_UNIT11 -> ResolveLibraryReferencesTask
+ RESOLVED_UNIT11 -> ResolveUnitTask
RESOLVED_UNIT11 [shape=box]
- RESOLVED_UNIT12 -> StrongModeVerifyUnitTask
+ RESOLVED_UNIT12 -> EvaluateUnitConstantsTask
+ RESOLVED_UNIT12 -> GatherUsedImportedElementsTask
+ RESOLVED_UNIT12 -> GatherUsedLocalElementsTask
+ RESOLVED_UNIT12 -> ResolveLibraryReferencesTask
RESOLVED_UNIT12 [shape=box]
+ RESOLVED_UNIT13 -> StrongModeVerifyUnitTask
+ RESOLVED_UNIT13 [shape=box]
RESOLVED_UNIT2 -> BuildEnumMemberElementsTask
RESOLVED_UNIT2 [shape=box]
- RESOLVED_UNIT3 -> ResolveUnitTypeNamesTask
+ RESOLVED_UNIT3 -> ResolveTopLevelUnitTypeBoundsTask
RESOLVED_UNIT3 [shape=box]
- RESOLVED_UNIT4 -> ResolveLibraryTypeNamesTask
- RESOLVED_UNIT4 -> ResolveVariableReferencesTask
+ RESOLVED_UNIT4 -> ResolveTopLevelLibraryTypeBoundsTask
+ RESOLVED_UNIT4 -> ResolveUnitTypeNamesTask
RESOLVED_UNIT4 [shape=box]
- RESOLVED_UNIT5 -> PartiallyResolveUnitReferencesTask
+ RESOLVED_UNIT5 -> ResolveLibraryTypeNamesTask
+ RESOLVED_UNIT5 -> ResolveVariableReferencesTask
RESOLVED_UNIT5 [shape=box]
- RESOLVED_UNIT6 -> ComputeInferableStaticVariableDependenciesTask
- RESOLVED_UNIT6 -> ComputePropagableVariableDependenciesTask
- RESOLVED_UNIT6 -> PropagateVariableTypeTask
- RESOLVED_UNIT6 -> PropagateVariableTypesInUnitTask
+ RESOLVED_UNIT6 -> PartiallyResolveUnitReferencesTask
RESOLVED_UNIT6 [shape=box]
- RESOLVED_UNIT7 -> InferStaticVariableTypeTask
- RESOLVED_UNIT7 -> InferStaticVariableTypesInUnitTask
- RESOLVED_UNIT7 -> PropagateVariableTypesInLibraryTask
+ RESOLVED_UNIT7 -> ComputeInferableStaticVariableDependenciesTask
+ RESOLVED_UNIT7 -> ComputePropagableVariableDependenciesTask
+ RESOLVED_UNIT7 -> PropagateVariableTypeTask
+ RESOLVED_UNIT7 -> PropagateVariableTypesInUnitTask
RESOLVED_UNIT7 [shape=box]
- RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
+ RESOLVED_UNIT8 -> InferStaticVariableTypeTask
+ RESOLVED_UNIT8 -> InferStaticVariableTypesInUnitTask
+ RESOLVED_UNIT8 -> PropagateVariableTypesInLibraryTask
RESOLVED_UNIT8 [shape=box]
- RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
+ RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
RESOLVED_UNIT9 [shape=box]
+ RESOLVE_TYPE_BOUNDS_ERRORS -> LibraryUnitErrorsTask
+ RESOLVE_TYPE_BOUNDS_ERRORS [shape=box]
RESOLVE_TYPE_NAMES_ERRORS -> LibraryUnitErrorsTask
RESOLVE_TYPE_NAMES_ERRORS [shape=box]
RESOLVE_UNIT_ERRORS -> LibraryUnitErrorsTask
RESOLVE_UNIT_ERRORS [shape=box]
ReadyLibraryElement2Task -> READY_LIBRARY_ELEMENT2
- ReadyLibraryElement5Task -> READY_LIBRARY_ELEMENT5
- ReadyLibraryElement6Task -> READY_LIBRARY_ELEMENT6
+ ReadyLibraryElement5Task -> READY_LIBRARY_ELEMENT6
+ ReadyLibraryElement6Task -> READY_LIBRARY_ELEMENT7
ReadyResolvedUnitTask -> READY_RESOLVED_UNIT
ResolveConstantExpressionTask -> CONSTANT_EXPRESSION_RESOLVED
ResolveDirectiveElementsTask -> CREATED_RESOLVED_UNIT2
ResolveDirectiveElementsTask -> RESOLVED_UNIT2
- ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT9
- ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT9
- ResolveLibraryReferencesTask -> LIBRARY_ELEMENT8
+ ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT10
+ ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT10
+ ResolveLibraryReferencesTask -> LIBRARY_ELEMENT9
ResolveLibraryReferencesTask -> REFERENCED_NAMES
ResolveLibraryTask -> LIBRARY_ELEMENT
- ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT5
+ ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT6
+ ResolveTopLevelLibraryTypeBoundsTask -> LIBRARY_ELEMENT5
+ ResolveTopLevelUnitTypeBoundsTask -> CREATED_RESOLVED_UNIT4
+ ResolveTopLevelUnitTypeBoundsTask -> RESOLVED_UNIT4
+ ResolveTopLevelUnitTypeBoundsTask -> RESOLVE_TYPE_BOUNDS_ERRORS
ResolveUnitTask -> CONSTANT_EXPRESSIONS_DEPENDENCIES
- ResolveUnitTask -> CREATED_RESOLVED_UNIT11
- ResolveUnitTask -> RESOLVED_UNIT11
+ ResolveUnitTask -> CREATED_RESOLVED_UNIT12
+ ResolveUnitTask -> RESOLVED_UNIT12
ResolveUnitTask -> RESOLVE_UNIT_ERRORS
- ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT4
- ResolveUnitTypeNamesTask -> RESOLVED_UNIT4
+ ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT5
+ ResolveUnitTypeNamesTask -> RESOLVED_UNIT5
ResolveUnitTypeNamesTask -> RESOLVE_TYPE_NAMES_ERRORS
- ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT5
- ResolveVariableReferencesTask -> RESOLVED_UNIT5
+ ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT6
+ ResolveVariableReferencesTask -> RESOLVED_UNIT6
ResolveVariableReferencesTask -> VARIABLE_REFERENCE_ERRORS
SCAN_ERRORS -> dartErrorsForSource
SCAN_ERRORS [shape=box]
@@ -315,6 +332,7 @@
TYPE_PROVIDER -> PropagateVariableTypeTask
TYPE_PROVIDER -> ResolveInstanceFieldsInUnitTask
TYPE_PROVIDER -> ResolveLibraryTypeNamesTask
+ TYPE_PROVIDER -> ResolveTopLevelUnitTypeBoundsTask
TYPE_PROVIDER -> ResolveUnitTask
TYPE_PROVIDER -> ResolveUnitTypeNamesTask
TYPE_PROVIDER -> ResolveVariableReferencesTask
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 173c27c..e802bd4 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -258,8 +258,7 @@
Duration duration = task.duration;
if (duration != Duration.ZERO) {
cumulatedDuration += duration;
- timings.writeln(
- ' $running${task.name} took'
+ timings.writeln(' $running${task.name} took'
' ${duration.inMilliseconds}msec');
for (String subtask in task.subtasks) {
int subtime = task.getSubtaskTime(subtask);
@@ -271,10 +270,9 @@
}
Duration unaccountedDuration =
totalDuration - cumulatedDuration - setupDuration - asyncDuration;
- double percent = unaccountedDuration.inMilliseconds * 100
- / totalDuration.inMilliseconds;
- timings.write(
- ' Total compile-time ${totalDuration.inMilliseconds}msec;'
+ double percent =
+ unaccountedDuration.inMilliseconds * 100 / totalDuration.inMilliseconds;
+ timings.write(' Total compile-time ${totalDuration.inMilliseconds}msec;'
' setup ${setupDuration.inMilliseconds}msec;'
' async ${asyncDuration.inMilliseconds}msec;'
' unaccounted ${unaccountedDuration.inMilliseconds}msec'
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index dfb5ba9..0e9f37f 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -55,10 +55,10 @@
return new ClosureClassMap(null, null, null, new ThisLocal(element));
} else {
assert(element.isField);
- VariableElement field = element;
- if (field.initializer != null) {
+ Node initializer = resolvedAst.body;
+ if (initializer != null) {
// The lazy initializer of a static.
- translator.translateLazyInitializer(element, node, field.initializer);
+ translator.translateLazyInitializer(element, node, initializer);
} else {
assert(element.isInstanceMember);
closureMappingCache[node] =
@@ -131,7 +131,8 @@
bool get hasResolvedAst => hasTreeElements;
ResolvedAst get resolvedAst {
- return new ParsedResolvedAst(this, null, null, treeElements);
+ return new ParsedResolvedAst(this, null, null, treeElements,
+ memberContext.compilationUnit.script.resourceUri);
}
Expression get initializer {
@@ -320,11 +321,13 @@
class SynthesizedCallMethodElementX extends BaseFunctionElementX
implements MethodElement {
final LocalFunctionElement expression;
+ final FunctionExpression node;
+ final TreeElements treeElements;
- SynthesizedCallMethodElementX(
- String name, LocalFunctionElementX other, ClosureClassElement enclosing)
+ SynthesizedCallMethodElementX(String name, LocalFunctionElement other,
+ ClosureClassElement enclosing, this.node, this.treeElements)
: expression = other,
- super(name, other.kind, other.modifiers, enclosing) {
+ super(name, other.kind, Modifiers.EMPTY, enclosing) {
asyncMarker = other.asyncMarker;
functionSignature = other.functionSignature;
}
@@ -339,18 +342,17 @@
return closureClass.methodElement.memberContext;
}
- bool get hasNode => expression.hasNode;
-
- FunctionExpression get node => expression.node;
+ bool get hasNode => node != null;
FunctionExpression parseNode(ParsingContext parsing) => node;
- ResolvedAst get resolvedAst {
- return new ParsedResolvedAst(this, node, node.body, treeElements);
- }
-
Element get analyzableElement => closureClass.methodElement.analyzableElement;
+ ResolvedAst get resolvedAst {
+ return new ParsedResolvedAst(this, node, node.body, treeElements,
+ expression.compilationUnit.script.resourceUri);
+ }
+
accept(ElementVisitor visitor, arg) {
return visitor.visitMethodElement(this, arg);
}
@@ -1032,7 +1034,7 @@
compiler.world
.registerClass(globalizedElement, isDirectlyInstantiated: true);
FunctionElement callElement = new SynthesizedCallMethodElementX(
- Identifiers.call, element, globalizedElement);
+ Identifiers.call, element, globalizedElement, node, elements);
backend.maybeMarkClosureAsNeededForReflection(
globalizedElement, callElement, element);
MemberElement enclosing = element.memberContext;
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index 4640bdb..8ad503c 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -234,9 +234,8 @@
// missing call of form registry.registerXXX. Alternatively, the code
// generation could spuriously be adding dependencies on things we know we
// don't need.
- assert(invariant(
- element, compiler.enqueuer.resolution.hasBeenProcessed(element),
- message: "$element has not been resolved."));
+ assert(invariant(element, compiler.backend.frontend.hasResolvedAst(element),
+ message: "$element has no resolved ast."));
ResolvedAst resolvedAst = compiler.backend.frontend.getResolvedAst(element);
return new CodegenWorkItem.internal(resolvedAst, compilationContext);
}
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index d049471..0b9f990 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -14,6 +14,7 @@
AstElement,
ClassElement,
Element,
+ ExecutableElement,
FunctionElement,
FunctionSignature,
MetadataAnnotation,
@@ -188,8 +189,11 @@
/// Interface for the accessing the front-end analysis.
// TODO(johnniwinther): Find a better name for this.
abstract class Frontend {
+ /// Returns `true` if [element] has a [ResolvedAst].
+ bool hasResolvedAst(ExecutableElement element);
+
/// Returns the `ResolvedAst` for the [element].
- ResolvedAst getResolvedAst(Element element);
+ ResolvedAst getResolvedAst(ExecutableElement element);
/// Returns the [ResolutionImpact] for [element].
ResolutionImpact getResolutionImpact(Element element);
@@ -225,10 +229,10 @@
Element element, ItemCompilationContext compilationContext);
/// Returns `true` if [element] as a fully computed [ResolvedAst].
- bool hasResolvedAst(Element element);
+ bool hasResolvedAst(ExecutableElement element);
/// Returns the `ResolvedAst` for the [element].
- ResolvedAst getResolvedAst(Element element);
+ ResolvedAst getResolvedAst(ExecutableElement element);
/// Returns `true` if the [ResolutionImpact] for [element] is cached.
bool hasResolutionImpact(Element element);
diff --git a/pkg/compiler/lib/src/common/tasks.dart b/pkg/compiler/lib/src/common/tasks.dart
index c5a77d3..42d5e7b 100644
--- a/pkg/compiler/lib/src/common/tasks.dart
+++ b/pkg/compiler/lib/src/common/tasks.dart
@@ -4,12 +4,8 @@
library dart2js.common.tasks;
-import 'dart:async' show
- Future,
- Zone,
- ZoneDelegate,
- ZoneSpecification,
- runZoned;
+import 'dart:async'
+ show Future, Zone, ZoneDelegate, ZoneSpecification, runZoned;
import '../common.dart';
import '../compiler.dart' show Compiler;
@@ -149,9 +145,8 @@
}
}
- return runZoned(
- action,
- zoneValues: { measurer: this },
+ return runZoned(action,
+ zoneValues: {measurer: this},
zoneSpecification: new ZoneSpecification(
run: run, runUnary: runUnary, runBinary: runBinary));
}
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 4020814..4aa08fd 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -403,17 +403,17 @@
// The resulting future will complete with true if the compilation
// succeeded.
Future<bool> run(Uri uri) => selfTask.measureSubtask("Compiler.run", () {
- measurer.startWallClock();
+ measurer.startWallClock();
- return new Future.sync(() => runInternal(uri))
- .catchError((error) => _reporter.onError(uri, error))
- .whenComplete(() {
- tracer.close();
- measurer.stopWallClock();
- }).then((_) {
- return !compilationFailed;
- });
- });
+ return new Future.sync(() => runInternal(uri))
+ .catchError((error) => _reporter.onError(uri, error))
+ .whenComplete(() {
+ tracer.close();
+ measurer.stopWallClock();
+ }).then((_) {
+ return !compilationFailed;
+ });
+ });
/// This method is called immediately after the [LibraryElement] [library] has
/// been created.
@@ -449,9 +449,7 @@
//
// This could for example happen if dart:async is disabled, then loading it
// should not try to find the given element.
- // TODO(johnniwinther): This should just be library.isSynthesized, but that
- // does not work yet for deserialized elements.
- if (!library.compilationUnit.script.isSynthesized) {
+ if (!library.isSynthesized) {
if (uri == Uris.dart_core) {
initializeCoreClasses();
identicalFunction = coreLibrary.find('identical');
@@ -809,112 +807,112 @@
}
/// Performs the compilation when all libraries have been loaded.
- void compileLoadedLibraries()
- => selfTask.measureSubtask("Compiler.compileLoadedLibraries", () {
+ void compileLoadedLibraries() =>
+ selfTask.measureSubtask("Compiler.compileLoadedLibraries", () {
+ computeMain();
- computeMain();
+ mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
- mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
+ // In order to see if a library is deferred, we must compute the
+ // compile-time constants that are metadata. This means adding
+ // something to the resolution queue. So we cannot wait with
+ // this until after the resolution queue is processed.
+ deferredLoadTask.beforeResolution(this);
+ impactStrategy = backend.createImpactStrategy(
+ supportDeferredLoad: deferredLoadTask.isProgramSplit,
+ supportDumpInfo: options.dumpInfo,
+ supportSerialization: serialization.supportSerialization);
- // In order to see if a library is deferred, we must compute the
- // compile-time constants that are metadata. This means adding
- // something to the resolution queue. So we cannot wait with
- // this until after the resolution queue is processed.
- deferredLoadTask.beforeResolution(this);
- impactStrategy = backend.createImpactStrategy(
- supportDeferredLoad: deferredLoadTask.isProgramSplit,
- supportDumpInfo: options.dumpInfo,
- supportSerialization: serialization.supportSerialization);
-
- phase = PHASE_RESOLVING;
- if (analyzeAll) {
- libraryLoader.libraries.forEach((LibraryElement library) {
- reporter.log('Enqueuing ${library.canonicalUri}');
- fullyEnqueueLibrary(library, enqueuer.resolution);
- });
- } else if (options.analyzeMain) {
- if (mainApp != null) {
- fullyEnqueueLibrary(mainApp, enqueuer.resolution);
- }
- if (librariesToAnalyzeWhenRun != null) {
- for (Uri libraryUri in librariesToAnalyzeWhenRun) {
- fullyEnqueueLibrary(
- libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution);
+ phase = PHASE_RESOLVING;
+ if (analyzeAll) {
+ libraryLoader.libraries.forEach((LibraryElement library) {
+ reporter.log('Enqueuing ${library.canonicalUri}');
+ fullyEnqueueLibrary(library, enqueuer.resolution);
+ });
+ } else if (options.analyzeMain) {
+ if (mainApp != null) {
+ fullyEnqueueLibrary(mainApp, enqueuer.resolution);
+ }
+ if (librariesToAnalyzeWhenRun != null) {
+ for (Uri libraryUri in librariesToAnalyzeWhenRun) {
+ fullyEnqueueLibrary(
+ libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution);
+ }
+ }
}
- }
- }
- // Elements required by enqueueHelpers are global dependencies
- // that are not pulled in by a particular element.
- backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
- resolveLibraryMetadata();
- reporter.log('Resolving...');
- processQueue(enqueuer.resolution, mainFunction);
- enqueuer.resolution.logSummary(reporter.log);
+ // Elements required by enqueueHelpers are global dependencies
+ // that are not pulled in by a particular element.
+ backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
+ resolveLibraryMetadata();
+ reporter.log('Resolving...');
+ processQueue(enqueuer.resolution, mainFunction);
+ enqueuer.resolution.logSummary(reporter.log);
- _reporter.reportSuppressedMessagesSummary();
+ _reporter.reportSuppressedMessagesSummary();
- if (compilationFailed) {
- if (!options.generateCodeWithCompileTimeErrors) return;
- if (!backend.enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) {
- return;
- }
- }
+ if (compilationFailed) {
+ if (!options.generateCodeWithCompileTimeErrors) return;
+ if (!backend
+ .enableCodegenWithErrorsIfSupported(NO_LOCATION_SPANNABLE)) {
+ return;
+ }
+ }
- if (options.analyzeOnly) {
- if (!analyzeAll && !compilationFailed) {
- // No point in reporting unused code when [analyzeAll] is true: all
- // code is artificially used.
- // If compilation failed, it is possible that the error prevents the
- // compiler from analyzing all the code.
- // TODO(johnniwinther): Reenable this when the reporting is more
- // precise.
- //reportUnusedCode();
- }
- return;
- }
- assert(mainFunction != null);
- phase = PHASE_DONE_RESOLVING;
+ if (options.analyzeOnly) {
+ if (!analyzeAll && !compilationFailed) {
+ // No point in reporting unused code when [analyzeAll] is true: all
+ // code is artificially used.
+ // If compilation failed, it is possible that the error prevents the
+ // compiler from analyzing all the code.
+ // TODO(johnniwinther): Reenable this when the reporting is more
+ // precise.
+ //reportUnusedCode();
+ }
+ return;
+ }
+ assert(mainFunction != null);
+ phase = PHASE_DONE_RESOLVING;
- world.populate();
- // Compute whole-program-knowledge that the backend needs. (This might
- // require the information computed in [world.populate].)
- backend.onResolutionComplete();
+ world.populate();
+ // Compute whole-program-knowledge that the backend needs. (This might
+ // require the information computed in [world.populate].)
+ backend.onResolutionComplete();
- deferredLoadTask.onResolutionComplete(mainFunction);
+ deferredLoadTask.onResolutionComplete(mainFunction);
- reporter.log('Inferring types...');
- typesTask.onResolutionComplete(mainFunction);
+ reporter.log('Inferring types...');
+ typesTask.onResolutionComplete(mainFunction);
- if (stopAfterTypeInference) return;
+ if (stopAfterTypeInference) return;
- backend.onTypeInferenceComplete();
+ backend.onTypeInferenceComplete();
- reporter.log('Compiling...');
- phase = PHASE_COMPILING;
- backend.onCodegenStart();
- // TODO(johnniwinther): Move these to [CodegenEnqueuer].
- if (hasIsolateSupport) {
- backend.enableIsolateSupport(enqueuer.codegen);
- }
- if (compileAll) {
- libraryLoader.libraries.forEach((LibraryElement library) {
- fullyEnqueueLibrary(library, enqueuer.codegen);
+ reporter.log('Compiling...');
+ phase = PHASE_COMPILING;
+ backend.onCodegenStart();
+ // TODO(johnniwinther): Move these to [CodegenEnqueuer].
+ if (hasIsolateSupport) {
+ backend.enableIsolateSupport(enqueuer.codegen);
+ }
+ if (compileAll) {
+ libraryLoader.libraries.forEach((LibraryElement library) {
+ fullyEnqueueLibrary(library, enqueuer.codegen);
+ });
+ }
+ processQueue(enqueuer.codegen, mainFunction);
+ enqueuer.codegen.logSummary(reporter.log);
+
+ int programSize = backend.assembleProgram();
+
+ if (options.dumpInfo) {
+ dumpInfoTask.reportSize(programSize);
+ dumpInfoTask.dumpInfo();
+ }
+
+ backend.sourceInformationStrategy.onComplete();
+
+ checkQueues();
});
- }
- processQueue(enqueuer.codegen, mainFunction);
- enqueuer.codegen.logSummary(reporter.log);
-
- int programSize = backend.assembleProgram();
-
- if (options.dumpInfo) {
- dumpInfoTask.reportSize(programSize);
- dumpInfoTask.dumpInfo();
- }
-
- backend.sourceInformationStrategy.onComplete();
-
- checkQueues();
- });
void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) {
void enqueueAll(Element element) {
@@ -950,48 +948,53 @@
/**
* Empty the [world] queue.
*/
- void emptyQueue(Enqueuer world)
- => selfTask.measureSubtask("Compiler.emptyQueue", () {
- world.forEach((WorkItem work) {
- reporter.withCurrentElement(
- work.element, () => selfTask.measureSubtask("world.applyImpact", () {
- world.applyImpact(
- work.element,
- selfTask.measureSubtask("work.run", () => work.run(this, world)));
- }));
- });
- });
+ void emptyQueue(Enqueuer world) =>
+ selfTask.measureSubtask("Compiler.emptyQueue", () {
+ world.forEach((WorkItem work) {
+ reporter.withCurrentElement(
+ work.element,
+ () => selfTask.measureSubtask("world.applyImpact", () {
+ world.applyImpact(
+ work.element,
+ selfTask.measureSubtask(
+ "work.run", () => work.run(this, world)));
+ }));
+ });
+ });
- void processQueue(Enqueuer world, Element main)
- => selfTask.measureSubtask("Compiler.processQueue", () {
- world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries);
- if (main != null && !main.isMalformed) {
- FunctionElement mainMethod = main;
- mainMethod.computeType(resolution);
- if (mainMethod.functionSignature.parameterCount != 0) {
- // The first argument could be a list of strings.
- backend.listImplementation.ensureResolved(resolution);
- backend.registerInstantiatedType(
- backend.listImplementation.rawType, world, globalDependencies);
- backend.stringImplementation.ensureResolved(resolution);
- backend.registerInstantiatedType(
- backend.stringImplementation.rawType, world, globalDependencies);
+ void processQueue(Enqueuer world, Element main) =>
+ selfTask.measureSubtask("Compiler.processQueue", () {
+ world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries);
+ if (main != null && !main.isMalformed) {
+ FunctionElement mainMethod = main;
+ mainMethod.computeType(resolution);
+ if (mainMethod.functionSignature.parameterCount != 0) {
+ // The first argument could be a list of strings.
+ backend.listImplementation.ensureResolved(resolution);
+ backend.registerInstantiatedType(
+ backend.listImplementation.rawType, world, globalDependencies);
+ backend.stringImplementation.ensureResolved(resolution);
+ backend.registerInstantiatedType(
+ backend.stringImplementation.rawType,
+ world,
+ globalDependencies);
- backend.registerMainHasArguments(world);
- }
- world.addToWorkList(main);
- }
- if (options.verbose) {
- progress.reset();
- }
- emptyQueue(world);
- world.queueIsClosed = true;
- // Notify the impact strategy impacts are no longer needed for this
- // enqueuer.
- impactStrategy.onImpactUsed(world.impactUse);
- backend.onQueueClosed();
- assert(compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods());
- });
+ backend.registerMainHasArguments(world);
+ }
+ world.addToWorkList(main);
+ }
+ if (options.verbose) {
+ progress.reset();
+ }
+ emptyQueue(world);
+ world.queueIsClosed = true;
+ // Notify the impact strategy impacts are no longer needed for this
+ // enqueuer.
+ impactStrategy.onImpactUsed(world.impactUse);
+ backend.onQueueClosed();
+ assert(
+ compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods());
+ });
/**
* Perform various checks of the queues. This includes checking that
@@ -1032,47 +1035,47 @@
}
}
- WorldImpact analyzeElement(Element element)
- => selfTask.measureSubtask("Compiler.analyzeElement", () {
- assert(invariant(
- element,
- element.impliesType ||
- element.isField ||
- element.isFunction ||
- element.isConstructor ||
- element.isGetter ||
- element.isSetter,
- message: 'Unexpected element kind: ${element.kind}'));
- assert(invariant(element, element is AnalyzableElement,
- message: 'Element $element is not analyzable.'));
- assert(invariant(element, element.isDeclaration));
- return resolution.computeWorldImpact(element);
- });
+ WorldImpact analyzeElement(Element element) =>
+ selfTask.measureSubtask("Compiler.analyzeElement", () {
+ assert(invariant(
+ element,
+ element.impliesType ||
+ element.isField ||
+ element.isFunction ||
+ element.isConstructor ||
+ element.isGetter ||
+ element.isSetter,
+ message: 'Unexpected element kind: ${element.kind}'));
+ assert(invariant(element, element is AnalyzableElement,
+ message: 'Element $element is not analyzable.'));
+ assert(invariant(element, element.isDeclaration));
+ return resolution.computeWorldImpact(element);
+ });
- WorldImpact analyze(ResolutionWorkItem work,
- ResolutionEnqueuer world)
- => selfTask.measureSubtask("Compiler.analyze", () {
- assert(invariant(work.element, identical(world, enqueuer.resolution)));
- assert(invariant(work.element, !work.isAnalyzed,
- message: 'Element ${work.element} has already been analyzed'));
- if (shouldPrintProgress) {
- // TODO(ahe): Add structured diagnostics to the compiler API and
- // use it to separate this from the --verbose option.
- if (phase == PHASE_RESOLVING) {
- reporter.log('Resolved ${enqueuer.resolution.processedElements.length} '
- 'elements.');
- progress.reset();
- }
- }
- AstElement element = work.element;
- if (world.hasBeenProcessed(element)) {
- return const WorldImpact();
- }
- WorldImpact worldImpact = analyzeElement(element);
- backend.onElementResolved(element);
- world.registerProcessedElement(element);
- return worldImpact;
- });
+ WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world) =>
+ selfTask.measureSubtask("Compiler.analyze", () {
+ assert(invariant(work.element, identical(world, enqueuer.resolution)));
+ assert(invariant(work.element, !work.isAnalyzed,
+ message: 'Element ${work.element} has already been analyzed'));
+ if (shouldPrintProgress) {
+ // TODO(ahe): Add structured diagnostics to the compiler API and
+ // use it to separate this from the --verbose option.
+ if (phase == PHASE_RESOLVING) {
+ reporter
+ .log('Resolved ${enqueuer.resolution.processedElements.length} '
+ 'elements.');
+ progress.reset();
+ }
+ }
+ AstElement element = work.element;
+ if (world.hasBeenProcessed(element)) {
+ return const WorldImpact();
+ }
+ WorldImpact worldImpact = analyzeElement(element);
+ backend.onElementResolved(element);
+ world.registerProcessedElement(element);
+ return worldImpact;
+ });
WorldImpact codegen(CodegenWorkItem work, CodegenEnqueuer world) {
assert(invariant(work.element, identical(world, enqueuer.codegen)));
@@ -1915,27 +1918,25 @@
}
@override
- bool hasResolvedAst(Element element) {
+ bool hasResolvedAst(ExecutableElement element) {
assert(invariant(element, element.isDeclaration,
message: "Element $element must be the declaration."));
if (compiler.serialization.isDeserialized(element)) {
return compiler.serialization.hasResolvedAst(element);
}
- return element is AstElement &&
- hasBeenResolved(element) &&
+ return hasBeenResolved(element.memberContext.declaration) &&
element.hasResolvedAst;
}
@override
- ResolvedAst getResolvedAst(Element element) {
+ ResolvedAst getResolvedAst(ExecutableElement element) {
assert(invariant(element, element.isDeclaration,
message: "Element $element must be the declaration."));
if (hasResolvedAst(element)) {
if (compiler.serialization.isDeserialized(element)) {
return compiler.serialization.getResolvedAst(element);
}
- AstElement astElement = element;
- return astElement.resolvedAst;
+ return element.resolvedAst;
}
assert(invariant(element, hasResolvedAst(element),
message: "ResolvedAst not available for $element."));
diff --git a/pkg/compiler/lib/src/constant_system_dart.dart b/pkg/compiler/lib/src/constant_system_dart.dart
index 60e8899..a19e003 100644
--- a/pkg/compiler/lib/src/constant_system_dart.dart
+++ b/pkg/compiler/lib/src/constant_system_dart.dart
@@ -450,6 +450,11 @@
compiler.backend.typeImplementation.computeType(compiler.resolution));
}
+ @override
+ ConstantValue createSymbol(Compiler compiler, String text) {
+ throw new UnsupportedError('DartConstantSystem.evaluate');
+ }
+
bool isInt(ConstantValue constant) => constant.isInt;
bool isDouble(ConstantValue constant) => constant.isDouble;
bool isString(ConstantValue constant) => constant.isString;
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index aae267f..e278612 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -68,6 +68,8 @@
List<ConstantValue> keys, List<ConstantValue> values);
// TODO(johnniwinther): Remove the need for [compiler].
ConstantValue createType(Compiler compiler, DartType type);
+ // TODO(johnniwinther): Remove the need for [compiler].
+ ConstantValue createSymbol(Compiler compiler, String text);
// We need to special case the subtype check for JavaScript constant
// system because an int is a double at runtime.
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index aa284cd..4019e16 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -680,8 +680,7 @@
@override
ConstantValue evaluate(
Environment environment, ConstantSystem constantSystem) {
- // TODO(johnniwinther): Implement this.
- throw new UnsupportedError('SymbolConstantExpression.evaluate');
+ return constantSystem.createSymbol(environment.compiler, name);
}
@override
@@ -1261,7 +1260,11 @@
sb.write('bool.fromEnvironment(name=');
name._createStructuredText(sb);
sb.write(',defaultValue=');
- defaultValue._createStructuredText(sb);
+ if (defaultValue != null) {
+ defaultValue._createStructuredText(sb);
+ } else {
+ sb.write('null');
+ }
sb.write(')');
}
@@ -1320,7 +1323,11 @@
sb.write('int.fromEnvironment(name=');
name._createStructuredText(sb);
sb.write(',defaultValue=');
- defaultValue._createStructuredText(sb);
+ if (defaultValue != null) {
+ defaultValue._createStructuredText(sb);
+ } else {
+ sb.write('null');
+ }
sb.write(')');
}
@@ -1381,7 +1388,11 @@
sb.write('String.fromEnvironment(name=');
name._createStructuredText(sb);
sb.write(',defaultValue=');
- defaultValue._createStructuredText(sb);
+ if (defaultValue != null) {
+ defaultValue._createStructuredText(sb);
+ } else {
+ sb.write('null');
+ }
sb.write(')');
}
@@ -1438,7 +1449,8 @@
@override
ConstantValue evaluate(
Environment environment, ConstantSystem constantSystem) {
- return expression.evaluate(environment, constantSystem);
+ return new DeferredConstantValue(
+ expression.evaluate(environment, constantSystem), prefix);
}
@override
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index fd0f5dd..37f5646 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -159,7 +159,7 @@
/** The value a Dart null is compiled to in JavaScript. */
static const String JsNull = "null";
- factory NullConstantValue() => const NullConstantValue._internal();
+ const factory NullConstantValue() = NullConstantValue._internal;
const NullConstantValue._internal();
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 49d3353..c382e4e 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
@@ -78,7 +78,7 @@
element = element.implementation;
return reporter.withCurrentElement(element, () {
SourceInformationBuilder sourceInformationBuilder =
- sourceInformationStrategy.createBuilderForContext(element);
+ sourceInformationStrategy.createBuilderForContext(resolvedAst);
IrBuilderVisitor builder = new IrBuilderVisitor(
resolvedAst, compiler, sourceInformationBuilder, typeMaskSystem);
@@ -502,8 +502,9 @@
/// Every visitor can only be applied to nodes in one context, because
/// the [elements] field is specific to that context.
IrBuilderVisitor makeVisitorForContext(AstElement context) {
- return new IrBuilderVisitor(context.resolvedAst, compiler,
- sourceInformationBuilder.forContext(context), typeMaskSystem);
+ ResolvedAst resolvedAst = backend.frontend.getResolvedAst(context);
+ return new IrBuilderVisitor(resolvedAst, compiler,
+ sourceInformationBuilder.forContext(resolvedAst), typeMaskSystem);
}
/// Builds the IR for an [expression] taken from a different [context].
@@ -1681,7 +1682,11 @@
}
ConstantValue getConstantForVariable(VariableElement element) {
- return irBuilder.state.constants.getConstantValue(element.constant);
+ ConstantExpression constant = element.constant;
+ if (constant != null) {
+ return irBuilder.state.constants.getConstantValue(constant);
+ }
+ return null;
}
ir.Primitive buildConstantExpression(
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
index 81eae70..03f0ba1 100644
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
@@ -495,6 +495,8 @@
: makeFunctionBody(exp.body);
result = new tree.FunctionExpression(
constructorName(exp),
+ // TODO(eernst): retrieve and pass the actual type variables.
+ null, // typeVariables
parameters,
body,
null, // return type
@@ -514,6 +516,8 @@
tree.Node body = makeFunctionBody(exp.body);
result = new tree.FunctionExpression(
functionName(exp),
+ // TODO(eernst): retrieve and pass the actual type variables.
+ null, // typeVariables
parameters,
body,
exp.returnType == null || exp.element.isConstructor
@@ -798,6 +802,8 @@
} else if (stmt is FunctionDeclaration) {
tree.FunctionExpression function = new tree.FunctionExpression(
stmt.name != null ? makeIdentifier(stmt.name) : null,
+ // TODO(eernst): retrieve and pass the actual type variables.
+ null, // typeVariables
makeParameters(stmt.parameters),
makeFunctionBody(stmt.body),
stmt.returnType != null ? makeType(stmt.returnType) : null,
@@ -965,6 +971,8 @@
if (param.isFunction) {
tree.Node definition = new tree.FunctionExpression(
makeIdentifier(param.name),
+ // TODO(eernst): retrieve and pass the actual type variables.
+ null, // typeVariables
makeParameters(param.parameters),
null, // body
param.type == null ? null : makeType(param.type),
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index db57839..b75a6ab 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -8,6 +8,8 @@
import 'common/tasks.dart' show CompilerTask;
import 'common.dart';
import 'compiler.dart' show Compiler;
+import 'constants/expressions.dart'
+ show ConstantExpression, ConstantExpressionKind;
import 'constants/values.dart'
show
ConstantValue,
@@ -334,15 +336,14 @@
TreeElements treeElements = analyzableElement.resolvedAst.elements;
assert(treeElements != null);
- treeElements.forEachConstantNode((Node node, _) {
+ treeElements
+ .forEachConstantNode((Node node, ConstantExpression expression) {
// Explicitly depend on the backend constants.
- ConstantValue value =
- backend.constants.getConstantValueForNode(node, treeElements);
- if (value != null) {
- // TODO(johnniwinther): Assert that all constants have values when
- // these are directly evaluated.
- constants.add(value);
- }
+ ConstantValue value = backend.constants.getConstantValue(expression);
+ assert(invariant(node, value != null,
+ message:
+ "No constant value for ${expression.toStructuredText()}."));
+ constants.add(value);
});
}
}
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 083068e..bbe777e 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -3240,10 +3240,9 @@
"""
]),
- MessageKind.ASYNC_AWAIT_NOT_SUPPORTED:
- const MessageTemplate(MessageKind.ASYNC_AWAIT_NOT_SUPPORTED,
- "The async/sync* syntax is not supported on the current platform."),
-
+ MessageKind.ASYNC_AWAIT_NOT_SUPPORTED: const MessageTemplate(
+ MessageKind.ASYNC_AWAIT_NOT_SUPPORTED,
+ "The async/sync* syntax is not supported on the current platform."),
MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD: const MessageTemplate(
MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
index 9cdce47..6c9a013 100644
--- a/pkg/compiler/lib/src/elements/common.dart
+++ b/pkg/compiler/lib/src/elements/common.dart
@@ -151,6 +151,13 @@
}
return null;
}
+
+ Element get enclosingClassOrCompilationUnit {
+ for (Element e = this; e != null; e = e.enclosingElement) {
+ if (e.isClass || e.isCompilationUnit) return e;
+ }
+ return null;
+ }
}
abstract class LibraryElementCommon implements LibraryElement {
@@ -465,6 +472,36 @@
bool get isNamedMixinApplication {
return isMixinApplication && !isUnnamedMixinApplication;
}
+
+ // backendMembers are members that have been added by the backend to simplify
+ // compilation. They don't have any user-side counter-part.
+ Link<Element> backendMembers = const Link<Element>();
+
+ bool get hasBackendMembers => !backendMembers.isEmpty;
+
+ void addBackendMember(Element member) {
+ // TODO(ngeoffray): Deprecate this method.
+ assert(member.isGenerativeConstructorBody);
+ backendMembers = backendMembers.prepend(member);
+ }
+
+ void reverseBackendMembers() {
+ backendMembers = backendMembers.reverse();
+ }
+
+ /// Lookup a synthetic element created by the backend.
+ Element lookupBackendMember(String memberName) {
+ for (Element element in backendMembers) {
+ if (element.name == memberName) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ void forEachBackendMember(void f(Element member)) {
+ backendMembers.forEach(f);
+ }
}
abstract class FunctionSignatureCommon implements FunctionSignature {
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index a6683cf..2e6adb0 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -329,6 +329,12 @@
bool get impliesType;
+ /// The character offset of the declaration of this element within its
+ /// compilation unit, if available.
+ ///
+ /// This is used to sort the elements.
+ int get sourceOffset;
+
// TODO(johnniwinther): Remove this.
Token get position;
@@ -480,7 +486,12 @@
return true;
}
- static bool hasAccessToTypeVariables(Element element) {
+ static bool hasAccessToTypeVariable(
+ Element element, TypeVariableElement typeVariable) {
+ GenericElement declaration = typeVariable.typeDeclaration;
+ if (declaration is FunctionElement || declaration is ParameterElement) {
+ return true;
+ }
Element outer = element.outermostEnclosingMemberOrTopLevel;
return (outer != null && outer.isFactoryConstructor) ||
!isInStaticContext(element);
@@ -683,10 +694,8 @@
if (r != 0) return r;
r = a.compilationUnit.compareTo(b.compilationUnit);
if (r != 0) return r;
- Token positionA = a.position;
- Token positionB = b.position;
- int offsetA = positionA == null ? -1 : positionA.charOffset;
- int offsetB = positionB == null ? -1 : positionB.charOffset;
+ int offsetA = a.sourceOffset ?? -1;
+ int offsetB = b.sourceOffset ?? -1;
r = offsetA.compareTo(offsetB);
if (r != 0) return r;
r = a.name.compareTo(b.name);
@@ -1103,6 +1112,7 @@
abstract class FunctionSignature {
FunctionType get type;
+ List<DartType> get typeVariables;
List<FormalElement> get requiredParameters;
List<FormalElement> get optionalParameters;
@@ -1130,7 +1140,8 @@
AstElement,
TypedElement,
FunctionTypedElement,
- ExecutableElement {
+ ExecutableElement,
+ GenericElement {
FunctionExpression get node;
FunctionElement get patch;
@@ -1138,7 +1149,7 @@
bool get hasFunctionSignature;
- /// The parameters of this functions.
+ /// The parameters of this function.
List<ParameterElement> get parameters;
/// The type of this function.
@@ -1228,7 +1239,7 @@
/// The effective target of this constructor, that is the non-redirecting
/// constructor that is called on invocation of this constructor.
///
- /// Consider for instance this hierachy:
+ /// Consider for instance this hierarchy:
///
/// class C { factory C.c() = D.d; }
/// class D { factory D.d() = E.e2; }
@@ -1241,7 +1252,7 @@
/// The immediate redirection target of a redirecting factory constructor.
///
- /// Consider for instance this hierachy:
+ /// Consider for instance this hierarchy:
///
/// class C { factory C() = D; }
/// class D { factory D() = E; }
@@ -1318,9 +1329,20 @@
FunctionElement get constructor;
}
+/// [GenericElement] defines the common interface for generic functions and
+/// [TypeDeclarationElement].
+abstract class GenericElement extends Element implements AstElement {
+ /**
+ * The type variables declared on this declaration. The type variables are not
+ * available until the type of the element has been computed through
+ * [computeType].
+ */
+ List<DartType> get typeVariables;
+}
+
/// [TypeDeclarationElement] defines the common interface for class/interface
/// declarations and typedefs.
-abstract class TypeDeclarationElement extends Element implements AstElement {
+abstract class TypeDeclarationElement extends GenericElement {
/// The name of this type declaration, taking privacy into account.
Name get memberName;
@@ -1362,13 +1384,6 @@
*/
GenericType get rawType;
- /**
- * The type variables declared on this declaration. The type variables are not
- * available until the type of the element has been computed through
- * [computeType].
- */
- List<DartType> get typeVariables;
-
bool get isResolved;
void ensureResolved(Resolution resolution);
@@ -1565,8 +1580,9 @@
@deprecated
get enclosingElement;
- /// The class or typedef on which this type variable is defined.
- TypeDeclarationElement get typeDeclaration;
+ /// The class, typedef, function, method, or function typed parameter on
+ /// which this type variable is defined.
+ GenericElement get typeDeclaration;
/// The index of this type variable within its type declaration.
int get index;
@@ -1608,7 +1624,7 @@
}
/// An [Element] that can define a function type.
-abstract class FunctionTypedElement extends Element {
+abstract class FunctionTypedElement extends Element implements GenericElement {
/// The function signature for the function type defined by this element,
/// if any.
FunctionSignature get functionSignature;
@@ -1682,6 +1698,10 @@
/// The [TreeElements] containing the resolution data for [node]. This only
/// available of [kind] is `ResolvedAstKind.PARSED`.
TreeElements get elements;
+
+ /// Returns the uri for the source file defining [node] and [body]. This
+ /// only available if [kind] is `ResolvedAstKind.PARSED`.
+ Uri get sourceUri;
}
/// [ResolvedAst] implementation used for elements whose semantics is defined in
@@ -1691,8 +1711,10 @@
final Node node;
final Node body;
final TreeElements elements;
+ final Uri sourceUri;
- ParsedResolvedAst(this.element, this.node, this.body, this.elements);
+ ParsedResolvedAst(
+ this.element, this.node, this.body, this.elements, this.sourceUri);
ResolvedAstKind get kind => ResolvedAstKind.PARSED;
@@ -1722,6 +1744,11 @@
throw new UnsupportedError('$this does not have a body AST node');
}
+ @override
+ Uri get sourceUri {
+ throw new UnsupportedError('$this does not have a source URI');
+ }
+
String toString() => '$kind:$element';
}
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 3a1e981..74ac6ad 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -109,13 +109,15 @@
return enclosingElement != null && enclosingElement.isCompilationUnit;
}
+ @override
+ int get sourceOffset => position?.charOffset;
+
Token get position => null;
SourceSpan get sourcePosition {
if (position == null) return null;
Uri uri = compilationUnit.script.resourceUri;
- return new SourceSpan(
- uri, position.charOffset, position.charOffset + position.charCount);
+ return new SourceSpan(uri, position.charOffset, position.charEnd);
}
Token findMyName(Token token) {
@@ -149,7 +151,7 @@
Name get memberName => new Name(name, library);
- LibraryElementX get implementationLibrary {
+ LibraryElement get implementationLibrary {
Element element = this;
while (!identical(element.kind, ElementKind.LIBRARY)) {
element = element.enclosingElement;
@@ -164,13 +166,6 @@
return null;
}
- Element get enclosingClassOrCompilationUnit {
- for (Element e = this; e != null; e = e.enclosingElement) {
- if (e.isClass || e.isCompilationUnit) return e;
- }
- return null;
- }
-
/**
* Creates the scope for this element.
*/
@@ -288,6 +283,9 @@
@override
bool get isFromEnvironmentConstructor => false;
+
+ @override
+ List<DartType> get typeVariables => unsupported();
}
/// A constructor that was synthesized to recover from a compile-time error.
@@ -721,7 +719,8 @@
localMembers = localMembers.prepend(element);
// Provide the member to the library to build scope.
if (enclosingElement.isPatch) {
- implementationLibrary.addMember(element, reporter);
+ LibraryElementX library = implementationLibrary;
+ library.addMember(element, reporter);
} else {
library.addMember(element, reporter);
}
@@ -1408,11 +1407,17 @@
originVariable.constant = value;
return;
}
+ if (constantCache != null &&
+ constantCache.kind == ConstantExpressionKind.ERRONEOUS) {
+ // TODO(johnniwinther): Find out why we sometimes compute a non-erroneous
+ // constant for a variable already known to be erroneous.
+ return;
+ }
assert(invariant(this, constantCache == null || constantCache == value,
message: "Constant has already been computed for $this. "
"Existing constant: "
- "${constantCache != null ? constantCache.toDartText() : ''}, "
- "New constant: ${value != null ? value.toDartText() : ''}."));
+ "${constantCache != null ? constantCache.toStructuredText() : ''}, "
+ "New constant: ${value != null ? value.toStructuredText() : ''}."));
constantCache = value;
}
}
@@ -1663,6 +1668,9 @@
final Identifier identifier;
DartType typeCache;
+ @override
+ List<DartType> get typeVariables => functionSignature.typeVariables;
+
/**
* Function signature for a variable with a function type. The signature is
* kept to provide full information about parameter names through the mirror
@@ -1892,6 +1900,7 @@
// TODO(karlklose): all these lists should have element type [FormalElement].
class FunctionSignatureX extends FunctionSignatureCommon
implements FunctionSignature {
+ final List<DartType> typeVariables;
final List<Element> requiredParameters;
final List<Element> optionalParameters;
final int requiredParameterCount;
@@ -1902,7 +1911,8 @@
final bool hasOptionalParameters;
FunctionSignatureX(
- {this.requiredParameters: const <Element>[],
+ {this.typeVariables: const <DartType>[],
+ this.requiredParameters: const <Element>[],
this.requiredParameterCount: 0,
List<Element> optionalParameters: const <Element>[],
this.optionalParameterCount: 0,
@@ -1983,6 +1993,9 @@
FunctionElement asFunctionElement() => this;
+ @override
+ Scope buildScope() => new TypeDeclarationScope(super.buildScope(), this);
+
String toString() {
if (isPatch) {
return 'patch ${super.toString()}';
@@ -1997,6 +2010,9 @@
// A function is defined by the implementation element.
AstElement get definingElement => implementation;
+
+ @override
+ List<DartType> get typeVariables => functionSignature.typeVariables;
}
abstract class FunctionElementX extends BaseFunctionElementX
@@ -2154,6 +2170,10 @@
enclosingClass.name == 'int' ||
enclosingClass.name == 'String');
}
+
+ /// Returns the empty list of type variables by default.
+ @override
+ List<DartType> get typeVariables => functionSignature.typeVariables;
}
abstract class ConstructorElementX extends FunctionElementX
@@ -2487,10 +2507,6 @@
bool isProxy = false;
bool hasIncompleteHierarchy = false;
- // backendMembers are members that have been added by the backend to simplify
- // compilation. They don't have any user-side counter-part.
- Link<Element> backendMembers = const Link<Element>();
-
OrderedTypeSet allSupertypesAndSelf;
BaseClassElementX(String name, Element enclosing, this.id, int initialState)
@@ -2500,8 +2516,6 @@
int get hashCode => id;
- bool get hasBackendMembers => !backendMembers.isEmpty;
-
bool get isUnnamedMixinApplication => false;
@override
@@ -2554,26 +2568,6 @@
void setDefaultConstructor(
FunctionElement constructor, DiagnosticReporter reporter);
- void addBackendMember(Element member) {
- // TODO(ngeoffray): Deprecate this method.
- assert(member.isGenerativeConstructorBody);
- backendMembers = backendMembers.prepend(member);
- }
-
- void reverseBackendMembers() {
- backendMembers = backendMembers.reverse();
- }
-
- /// Lookup a synthetic element created by the backend.
- Element lookupBackendMember(String memberName) {
- for (Element element in backendMembers) {
- if (element.name == memberName) {
- return element;
- }
- }
- return null;
- }
-
ConstructorElement lookupDefaultConstructor() {
ConstructorElement constructor = lookupConstructor("");
// This method might be called on constructors that have not been
@@ -2598,10 +2592,6 @@
return supertype == null ? null : supertype.element;
}
- void forEachBackendMember(void f(Element member)) {
- backendMembers.forEach(f);
- }
-
// TODO(johnniwinther): Remove these when issue 18630 is fixed.
ClassElement get patch => super.patch;
ClassElement get origin => super.origin;
@@ -3114,10 +3104,10 @@
DartType boundCache;
TypeVariableElementX(
- String name, TypeDeclarationElement enclosing, this.index, this.node)
+ String name, GenericElement enclosing, this.index, this.node)
: super(name, ElementKind.TYPE_VARIABLE, enclosing);
- TypeDeclarationElement get typeDeclaration => enclosingElement;
+ GenericElement get typeDeclaration => enclosingElement;
TypeVariableType computeType(Resolution resolution) => type;
@@ -3278,6 +3268,10 @@
body = node.asFunctionExpression().body;
}
return new ParsedResolvedAst(
- declaration, node, body, definingElement.treeElements);
+ declaration,
+ node,
+ body,
+ definingElement.treeElements,
+ definingElement.compilationUnit.script.resourceUri);
}
}
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 8f1f1b7..f619520 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -309,7 +309,8 @@
recentClasses.add(superclass);
superclass.ensureResolved(resolution);
superclass.implementation.forEachMember(processInstantiatedClassMember);
- if (isResolutionQueue && !superclass.isSynthesized) {
+ if (isResolutionQueue &&
+ !compiler.serialization.isDeserialized(superclass)) {
compiler.resolver.checkClass(superclass);
}
// We only tell the backend once that [superclass] was instantiated, so
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index 78ef6bb..65e7439 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -741,7 +741,10 @@
: this.analyzedElement = analyzedElement,
this.locals = handler {
if (handler != null) return;
- Node node = analyzedElement.node;
+ Node node;
+ if (resolvedAst.kind == ResolvedAstKind.PARSED) {
+ node = resolvedAst.node;
+ }
FieldInitializationScope<T> fieldScope =
analyzedElement.isGenerativeConstructor
? new FieldInitializationScope<T>(types)
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index d13b124..e800c0f 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -47,6 +47,10 @@
CoreTypes get coreTypes => compiler.coreTypes;
+ ResolvedAst getResolvedAst(Element element) {
+ return compiler.backend.frontend.getResolvedAst(element.declaration);
+ }
+
/**
* Records the default type of parameter [parameter].
*/
@@ -256,6 +260,7 @@
return returnType;
}
+ // TODO(johnniwinther): Pass the [ResolvedAst] instead of [owner].
void updateSelectorInTree(
AstElement owner, Spannable node, Selector selector, TypeMask mask) {
if (node is cps_ir.Node) {
@@ -263,7 +268,7 @@
throw "updateSelector for IR node $node";
}
ast.Node astNode = node;
- TreeElements elements = owner.resolvedAst.elements;
+ TreeElements elements = getResolvedAst(owner).elements;
if (astNode.asSendSet() != null) {
if (selector.isSetter || selector.isIndexSet) {
elements.setTypeMask(node, mask);
@@ -295,7 +300,7 @@
element.isField;
}
- void analyze(Element element, ArgumentsTypes arguments);
+ void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments);
bool checkIfExposesThis(Element element) {
element = element.implementation;
@@ -354,17 +359,24 @@
compiler,
handler);
+ ResolvedAst getResolvedAst(Element element) {
+ return compiler.backend.frontend.getResolvedAst(element.declaration);
+ }
+
void analyzeSuperConstructorCall(Element target, ArgumentsTypes arguments) {
- inferrer.analyze(target, arguments);
+ ResolvedAst resolvedAst = getResolvedAst(target);
+ inferrer.analyze(resolvedAst, arguments);
isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target);
}
T run() {
- var node = analyzedElement.node;
+ var node;
+ if (resolvedAst.kind == ResolvedAstKind.PARSED) {
+ node = resolvedAst.node;
+ }
ast.Expression initializer;
if (analyzedElement.isField) {
- VariableElement fieldElement = analyzedElement;
- initializer = fieldElement.initializer;
+ initializer = resolvedAst.body;
if (initializer == null) {
// Eagerly bailout, because computing the closure data only
// works for functions and field assignments.
@@ -475,7 +487,8 @@
cls.forEachInstanceField((_, FieldElement field) {
if (field.isFinal) return;
T type = locals.fieldScope.readField(field);
- if (type == null && field.initializer == null) {
+ ResolvedAst resolvedAst = getResolvedAst(field);
+ if (type == null && resolvedAst.body == null) {
inferrer.recordTypeOfNonFinalField(
spannable, field, types.nullType);
}
@@ -552,7 +565,7 @@
LocalsHandler closureLocals =
new LocalsHandler<T>.from(locals, node, useOtherTryBlock: false);
SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor<T>(
- element, element.resolvedAst, compiler, inferrer, closureLocals);
+ element, getResolvedAst(element), compiler, inferrer, closureLocals);
visitor.run();
inferrer.recordReturnType(element, visitor.returnType);
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 2936432..62a9efd 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -9,6 +9,7 @@
import '../common.dart';
import '../common/names.dart' show Identifiers;
import '../compiler.dart' show Compiler;
+import '../constants/expressions.dart' show ConstantExpression;
import '../constants/values.dart';
import '../dart_types.dart' show DartType;
import '../elements/elements.dart';
@@ -663,15 +664,15 @@
if (compiler.options.verbose) {
compiler.progress.reset();
}
- sortResolvedElements().forEach((Element element) {
- assert(compiler.enqueuer.resolution.hasBeenProcessed(element));
+ sortResolvedAsts().forEach((ResolvedAst resolvedAst) {
if (compiler.shouldPrintProgress) {
reporter.log('Added $addedInGraph elements in inferencing graph.');
compiler.progress.reset();
}
// This also forces the creation of the [ElementTypeInformation] to ensure
// it is in the graph.
- types.withMember(element, () => analyze(element, null));
+ types.withMember(
+ resolvedAst.element.implementation, () => analyze(resolvedAst, null));
});
reporter.log('Added $addedInGraph elements in inferencing graph.');
@@ -827,13 +828,13 @@
processLoopInformation();
}
- void analyze(AstElement element, ArgumentsTypes arguments) {
- element = element.implementation;
+ void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments) {
+ AstElement element = resolvedAst.element.implementation;
if (analyzedElements.contains(element)) return;
analyzedElements.add(element);
- SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor(
- element, element.resolvedAst, compiler, this);
+ SimpleTypeInferrerVisitor visitor =
+ new SimpleTypeInferrerVisitor(element, resolvedAst, compiler, this);
TypeInformation type;
reporter.withCurrentElement(element, () {
type = visitor.run();
@@ -842,17 +843,19 @@
if (element.isField) {
VariableElement fieldElement = element;
- ast.Node node = fieldElement.node;
+ ast.Node node = resolvedAst.node;
+ ast.Node initializer = resolvedAst.body;
if (element.isFinal || element.isConst) {
// If [element] is final and has an initializer, we record
// the inferred type.
- if (fieldElement.initializer != null) {
+ if (resolvedAst.body != null) {
if (type is! ListTypeInformation && type is! MapTypeInformation) {
// For non-container types, the constant handler does
// constant folding that could give more precise results.
- ConstantValue value = compiler.backend.constants
- .getConstantValue(fieldElement.constant);
- if (value != null) {
+ ConstantExpression constant = fieldElement.constant;
+ if (constant != null) {
+ ConstantValue value =
+ compiler.backend.constants.getConstantValue(constant);
if (value.isFunction) {
FunctionConstantValue functionConstant = value;
type = types.allocateClosure(node, functionConstant.element);
@@ -871,7 +874,7 @@
} else if (!element.isInstanceMember) {
recordType(element, types.nullType);
}
- } else if (fieldElement.initializer == null) {
+ } else if (initializer == null) {
// Only update types of static fields if there is no
// assignment. Instance fields are dealt with in the constructor.
if (Elements.isStaticOrTopLevelField(element)) {
@@ -881,9 +884,9 @@
recordTypeOfNonFinalField(node, element, type);
}
if (Elements.isStaticOrTopLevelField(element) &&
- fieldElement.initializer != null &&
+ resolvedAst.body != null &&
!element.isConst) {
- var argument = fieldElement.initializer;
+ var argument = resolvedAst.body;
// TODO(13429): We could do better here by using the
// constant handler to figure out if it's a lazy field or not.
if (argument.asSend() != null ||
@@ -1228,15 +1231,15 @@
// Sorts the resolved elements by size. We do this for this inferrer
// to get the same results for [ListTracer] compared to the
// [SimpleTypesInferrer].
- Iterable<Element> sortResolvedElements() {
+ Iterable<ResolvedAst> sortResolvedAsts() {
int max = 0;
- Map<int, Setlet<Element>> methodSizes = new Map<int, Setlet<Element>>();
+ Map<int, Setlet<ResolvedAst>> methodSizes = <int, Setlet<ResolvedAst>>{};
compiler.enqueuer.resolution.processedElements
.forEach((AstElement element) {
// TODO(ngeoffray): Not sure why the resolver would put a null
// mapping.
if (!compiler.enqueuer.resolution.hasBeenProcessed(element)) return;
- ResolvedAst resolvedAst = element.resolvedAst;
+ ResolvedAst resolvedAst = getResolvedAst(element);
element = element.implementation;
if (element.impliesType) return;
assert(invariant(
@@ -1256,14 +1259,14 @@
length = mapping.getSelectorCount();
}
max = length > max ? length : max;
- Setlet<Element> set =
- methodSizes.putIfAbsent(length, () => new Setlet<Element>());
- set.add(element);
+ Setlet<ResolvedAst> set =
+ methodSizes.putIfAbsent(length, () => new Setlet<ResolvedAst>());
+ set.add(resolvedAst);
});
- List<Element> result = <Element>[];
+ List<ResolvedAst> result = <ResolvedAst>[];
for (int i = 0; i <= max; i++) {
- Setlet<Element> set = methodSizes[i];
+ Setlet<ResolvedAst> set = methodSizes[i];
if (set != null) result.addAll(set);
}
return result;
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 3b01a6f..321943f 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -101,8 +101,8 @@
const PositionSourceInformationStrategy();
@override
- SourceInformationBuilder createBuilderForContext(AstElement element) {
- return new PositionSourceInformationBuilder(element);
+ SourceInformationBuilder createBuilderForContext(ResolvedAst resolvedAst) {
+ return new PositionSourceInformationBuilder(resolvedAst);
}
@override
@@ -141,12 +141,12 @@
class PositionSourceInformationBuilder implements SourceInformationBuilder {
final SourceFile sourceFile;
final String name;
- final AstElement element;
+ final ResolvedAst resolvedAst;
- PositionSourceInformationBuilder(AstElement element)
- : this.element = element,
- sourceFile = element.implementation.compilationUnit.script.file,
- name = computeElementNameForSourceMaps(element);
+ PositionSourceInformationBuilder(ResolvedAst resolvedAst)
+ : this.resolvedAst = resolvedAst,
+ sourceFile = computeSourceFile(resolvedAst),
+ name = computeElementNameForSourceMaps(resolvedAst.element);
SourceInformation buildDeclaration(ResolvedAst resolvedAst) {
if (resolvedAst.kind != ResolvedAstKind.PARSED) {
@@ -238,15 +238,10 @@
@override
SourceInformation buildVariableDeclaration() {
- if (element.hasNode) {
- Node node = element.node;
- if (node is FunctionExpression) {
- return buildBegin(node.body);
- } else if (element.isField) {
- FieldElement field = element;
- if (field.initializer != null) {
- return buildBegin(field.initializer);
- }
+ if (resolvedAst.kind == ResolvedAstKind.PARSED) {
+ Node body = resolvedAst.body;
+ if (body != null) {
+ return buildBegin(body);
}
// TODO(johnniwinther): Are there other cases?
}
@@ -254,8 +249,8 @@
}
@override
- SourceInformationBuilder forContext(AstElement element) {
- return new PositionSourceInformationBuilder(element);
+ SourceInformationBuilder forContext(ResolvedAst resolvedAst) {
+ return new PositionSourceInformationBuilder(resolvedAst);
}
@override
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index cf3872c..a84d8bf 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -5,8 +5,15 @@
library dart2js.source_information;
import '../common.dart';
-import '../elements/elements.dart' show AstElement, LocalElement, ResolvedAst;
+import '../elements/elements.dart'
+ show
+ AstElement,
+ CompilationUnitElement,
+ LocalElement,
+ ResolvedAst,
+ ResolvedAstKind;
import '../js/js.dart' show JavaScriptNodeSourceInformation;
+import '../script.dart';
import '../tree/tree.dart' show Node;
import 'source_file.dart';
@@ -37,8 +44,8 @@
class SourceInformationStrategy {
const SourceInformationStrategy();
- /// Create a [SourceInformationBuilder] for [element].
- SourceInformationBuilder createBuilderForContext(AstElement element) {
+ /// Create a [SourceInformationBuilder] for [resolvedAst].
+ SourceInformationBuilder createBuilderForContext(ResolvedAst resolvedAst) {
return const SourceInformationBuilder();
}
@@ -53,8 +60,8 @@
class SourceInformationBuilder {
const SourceInformationBuilder();
- /// Create a [SourceInformationBuilder] for [element].
- SourceInformationBuilder forContext(AstElement element) => this;
+ /// Create a [SourceInformationBuilder] for [resolvedAst].
+ SourceInformationBuilder forContext(ResolvedAst resolvedAst) => this;
/// Generate [SourceInformation] the declaration of the element in
/// [resolvedAst].
@@ -151,7 +158,9 @@
int _line;
SourceLocation(this._sourceFile) {
- assert(isValid);
+ assert(invariant(new SourceSpan(sourceUri, 0, 0), isValid,
+ message: "Invalid source location in ${sourceUri}: "
+ "offset=$offset, length=${_sourceFile.length}."));
}
/// The absolute URI of the source file of this source location.
@@ -244,3 +253,32 @@
return element.name;
}
}
+
+/// Computes the [SourceFile] for the source code of [resolvedAst].
+SourceFile computeSourceFile(ResolvedAst resolvedAst) {
+ SourceFile sourceFile;
+ if (resolvedAst.kind != ResolvedAstKind.PARSED) {
+ // Synthesized node. Use the enclosing element for the location.
+ sourceFile = resolvedAst.element.compilationUnit.script.file;
+ } else {
+ Uri uri = resolvedAst.sourceUri;
+ AstElement implementation = resolvedAst.element.implementation;
+ Script script = implementation.compilationUnit.script;
+ if (uri == script.resourceUri) {
+ sourceFile = script.file;
+ } else {
+ // Slow path, happens only for deserialized elements.
+ // TODO(johnniwinther): Support a way to get a [SourceFile] from a
+ // [Uri].
+ for (CompilationUnitElement compilationUnit
+ in implementation.library.compilationUnits) {
+ Script script = compilationUnit.script;
+ if (uri == script.resourceUri) {
+ sourceFile = script.file;
+ break;
+ }
+ }
+ }
+ }
+ return sourceFile;
+}
diff --git a/pkg/compiler/lib/src/io/start_end_information.dart b/pkg/compiler/lib/src/io/start_end_information.dart
index ccc4d6b..1734aa9 100644
--- a/pkg/compiler/lib/src/io/start_end_information.dart
+++ b/pkg/compiler/lib/src/io/start_end_information.dart
@@ -63,16 +63,13 @@
static StartEndSourceInformation _computeSourceInformation(
ResolvedAst resolvedAst) {
String name = computeElementNameForSourceMaps(resolvedAst.element);
- SourceFile sourceFile;
+ SourceFile sourceFile = computeSourceFile(resolvedAst);
int begin;
int end;
if (resolvedAst.kind != ResolvedAstKind.PARSED) {
// Synthesized node. Use the enclosing element for the location.
- sourceFile = resolvedAst.element.compilationUnit.script.file;
begin = end = resolvedAst.element.sourcePosition.begin;
} else {
- AstElement implementation = resolvedAst.element.implementation;
- sourceFile = implementation.compilationUnit.script.file;
Node node = resolvedAst.node;
begin = node.getBeginToken().charOffset;
end = node.getEndToken().charOffset;
@@ -116,8 +113,8 @@
const StartEndSourceInformationStrategy();
@override
- SourceInformationBuilder createBuilderForContext(AstElement element) {
- return new StartEndSourceInformationBuilder(element);
+ SourceInformationBuilder createBuilderForContext(ResolvedAst resolvedAst) {
+ return new StartEndSourceInformationBuilder(resolvedAst);
}
@override
@@ -158,9 +155,9 @@
final SourceFile sourceFile;
final String name;
- StartEndSourceInformationBuilder(AstElement element)
- : sourceFile = element.compilationUnit.script.file,
- name = computeElementNameForSourceMaps(element);
+ StartEndSourceInformationBuilder(ResolvedAst resolvedAst)
+ : sourceFile = computeSourceFile(resolvedAst),
+ name = computeElementNameForSourceMaps(resolvedAst.element);
SourceInformation buildDeclaration(ResolvedAst resolvedAst) {
return StartEndSourceInformation._computeSourceInformation(resolvedAst);
@@ -219,8 +216,8 @@
SourceInformation buildIf(Node node) => buildGeneric(node);
@override
- SourceInformationBuilder forContext(AstElement element,
+ SourceInformationBuilder forContext(ResolvedAst resolvedAst,
{SourceInformation sourceInformation}) {
- return new StartEndSourceInformationBuilder(element);
+ return new StartEndSourceInformationBuilder(resolvedAst);
}
}
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 83cab66..f5eac4a 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -1474,9 +1474,9 @@
}
if (kind.category == ElementCategory.VARIABLE) {
VariableElement variableElement = element;
- ConstantValue initialValue =
- constants.getConstantValue(variableElement.constant);
- if (initialValue != null) {
+ ConstantExpression constant = variableElement.constant;
+ if (constant != null) {
+ ConstantValue initialValue = constants.getConstantValue(constant);
registerCompileTimeConstant(initialValue, work.registry);
addCompileTimeConstantForEmission(initialValue);
// We don't need to generate code for static or top-level
@@ -1851,7 +1851,9 @@
if (library.isPlatformLibrary &&
// Don't patch library currently disallowed.
!library.isSynthesized &&
- !library.isPatched) {
+ !library.isPatched &&
+ // Don't patch deserialized libraries.
+ !compiler.serialization.isDeserialized(library)) {
// Apply patch, if any.
Uri patchUri = compiler.resolvePatchUri(library.canonicalUri.path);
if (patchUri != null) {
@@ -2505,11 +2507,33 @@
}
@override
- ResolvedAst getResolvedAst(Element element) {
+ bool hasResolvedAst(ExecutableElement element) {
+ if (element is SynthesizedCallMethodElementX) {
+ return true;
+ } else if (element is ConstructorBodyElementX) {
+ return true;
+ } else if (element is FieldElementX) {
+ return true;
+ } else if (element is DeferredLoaderGetterElementX) {
+ return true;
+ } else {
+ return resolution.hasResolvedAst(element);
+ }
+ }
+
+ @override
+ ResolvedAst getResolvedAst(ExecutableElement element) {
if (element is SynthesizedCallMethodElementX) {
return element.resolvedAst;
} else if (element is ConstructorBodyElementX) {
return element.resolvedAst;
+ } else if (element is DeferredLoaderGetterElementX) {
+ return element.resolvedAst;
+ } else if (element is FieldElementX) {
+ // TODO(johnniwinther): Find a good invariant for resolution of fields.
+ // Currently some but not all are resolved (maybe it has to do with
+ // initializers?)
+ return element.resolvedAst;
} else {
assert(invariant(element, resolution.hasResolvedAst(element.declaration),
message: 'No ResolvedAst for $element'));
diff --git a/pkg/compiler/lib/src/js_backend/backend_serialization.dart b/pkg/compiler/lib/src/js_backend/backend_serialization.dart
index cc7cc03f..d0594f4 100644
--- a/pkg/compiler/lib/src/js_backend/backend_serialization.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_serialization.dart
@@ -140,9 +140,9 @@
.getStrings(SPECIAL_TYPES_RETURNED, isOptional: true)
.map(SpecialType.fromName));
- behavior.typesReturned
+ behavior.typesInstantiated
.addAll(decoder.getTypes(DART_TYPES_INSTANTIATED, isOptional: true));
- behavior.typesReturned.addAll(decoder
+ behavior.typesInstantiated.addAll(decoder
.getStrings(SPECIAL_TYPES_INSTANTIATED, isOptional: true)
.map(SpecialType.fromName));
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
index cf21b0b..c293d5a 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/task.dart
@@ -336,7 +336,7 @@
code = backend.rewriteAsync(element, code);
work.registry.registerAsyncMarker(element);
}
- return attachPosition(code, element);
+ return attachPosition(code, work.resolvedAst);
}
Iterable<CompilerTask> get tasks {
@@ -348,9 +348,9 @@
]..addAll(fallbackCompiler.tasks);
}
- js.Node attachPosition(js.Node node, AstElement element) {
+ js.Node attachPosition(js.Node node, ResolvedAst resolvedAst) {
return node.withSourceInformation(sourceInformationFactory
- .createBuilderForContext(element)
- .buildDeclaration(backend.frontend.getResolvedAst(element)));
+ .createBuilderForContext(resolvedAst)
+ .buildDeclaration(resolvedAst));
}
}
diff --git a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
index 3bc94e5..2383662 100644
--- a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
@@ -245,7 +245,11 @@
}
}
+ @override
ConstantValue getConstantValue(ConstantExpression expression) {
+ assert(invariant(CURRENT_ELEMENT_SPANNABLE, expression != null,
+ message: "ConstantExpression is null in getConstantValue."));
+ evaluate(expression);
ConstantValue value = super.getConstantValue(expression);
if (value == null &&
expression != null &&
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
index add7563..f3d2b4c 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -10,7 +10,7 @@
import '../constant_system_dart.dart';
import '../core_types.dart' show CoreTypes;
import '../dart_types.dart';
-import '../elements/elements.dart' show ClassElement;
+import '../elements/elements.dart' show ClassElement, FieldElement;
import '../tree/tree.dart' show DartString, LiteralDartString;
import 'js_backend.dart';
@@ -345,6 +345,21 @@
return new JavaScriptMapConstant(
type, keysList, values, protoValue, onlyStringKeys);
}
+
+ @override
+ ConstantValue createSymbol(Compiler compiler, String text) {
+ // TODO(johnniwinther): Create a backend agnostic value.
+ InterfaceType type = compiler.coreTypes.symbolType;
+ ConstantValue argument = createString(new DartString.literal(text));
+ Map<FieldElement, ConstantValue> fields = <FieldElement, ConstantValue>{};
+ JavaScriptBackend backend = compiler.backend;
+ backend.helpers.symbolImplementationClass.forEachInstanceField(
+ (ClassElement enclosingClass, FieldElement field) {
+ fields[field] = argument;
+ });
+ assert(fields.length == 1);
+ return new ConstructedConstantValue(type, fields);
+ }
}
class JavaScriptMapConstant extends MapConstantValue {
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index 6be55db..900a965 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -38,7 +38,8 @@
import '../diagnostics/invariant.dart' show DEBUG_MODE;
import '../dump_info.dart' show DumpInfoTask;
import '../elements/elements.dart';
-import '../elements/modelx.dart' show ConstructorBodyElementX;
+import '../elements/modelx.dart'
+ show ConstructorBodyElementX, FieldElementX, DeferredLoaderGetterElementX;
import '../elements/visitor.dart' show BaseElementVisitor;
import '../enqueue.dart' show Enqueuer, ResolutionEnqueuer;
import '../io/code_output.dart';
diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart
index 9f6e18b..b5cb91d 100644
--- a/pkg/compiler/lib/src/parser/node_listener.dart
+++ b/pkg/compiler/lib/src/parser/node_listener.dart
@@ -344,13 +344,13 @@
AsyncModifier asyncModifier = popNode();
NodeList initializers = popNode();
NodeList formals = popNode();
- popNode(); // typeVariables
+ NodeList typeVariables = popNode();
// The name can be an identifier or a send in case of named constructors.
Expression name = popNode();
TypeAnnotation type = popNode();
Modifiers modifiers = popNode();
- pushNode(new FunctionExpression(name, formals, body, type, modifiers,
- initializers, getOrSet, asyncModifier));
+ pushNode(new FunctionExpression(name, typeVariables, formals, body, type,
+ modifiers, initializers, getOrSet, asyncModifier));
}
void endFunctionDeclaration(Token endToken) {
@@ -493,12 +493,12 @@
AsyncModifier asyncModifier = popNode();
NodeList initializers = popNode();
NodeList formalParameters = popNode();
- popNode(); // typeVariables
+ NodeList typeVariables = popNode();
Expression name = popNode();
TypeAnnotation returnType = popNode();
Modifiers modifiers = popNode();
- pushNode(new FunctionExpression(name, formalParameters, body, returnType,
- modifiers, initializers, getOrSet, asyncModifier));
+ pushNode(new FunctionExpression(name, typeVariables, formalParameters, body,
+ returnType, modifiers, initializers, getOrSet, asyncModifier));
}
void handleLiteralMap(
@@ -564,12 +564,12 @@
void handleFunctionTypedFormalParameter(Token endToken) {
NodeList formals = popNode();
- popNode(); // typeVariables
+ NodeList typeVariables = popNode();
Identifier name = popNode();
TypeAnnotation returnType = popNode();
pushNode(null); // Signal "no type" to endFormalParameter.
- pushNode(new FunctionExpression(
- name, formals, null, returnType, Modifiers.EMPTY, null, null, null));
+ pushNode(new FunctionExpression(name, typeVariables, formals, null,
+ returnType, Modifiers.EMPTY, null, null, null));
}
void handleValuedFormalParameter(Token equals, Token token) {
@@ -675,7 +675,7 @@
Modifiers modifiers = popNode();
pushNode(new FunctionExpression(
- name, formals, body, null, modifiers, null, null, asyncModifier));
+ name, null, formals, body, null, modifiers, null, null, asyncModifier));
}
void endForIn(
@@ -754,9 +754,9 @@
Statement body = popNode();
AsyncModifier asyncModifier = popNode();
NodeList formals = popNode();
- popNode(); // typeVariables
- pushNode(new FunctionExpression(
- null, formals, body, null, Modifiers.EMPTY, null, null, asyncModifier));
+ NodeList typeVariables = popNode();
+ pushNode(new FunctionExpression(null, typeVariables, formals, body, null,
+ Modifiers.EMPTY, null, null, asyncModifier));
}
void handleIsOperator(Token operathor, Token not, Token endToken) {
diff --git a/pkg/compiler/lib/src/resolution/enum_creator.dart b/pkg/compiler/lib/src/resolution/enum_creator.dart
index 6b0acfa..0dd861a 100644
--- a/pkg/compiler/lib/src/resolution/enum_creator.dart
+++ b/pkg/compiler/lib/src/resolution/enum_creator.dart
@@ -82,11 +82,12 @@
symbolToken(Precedence.SEMICOLON_INFO), expression);
}
- FunctionExpression functionExpression(
- Modifiers modifiers, String name, NodeList argumentList, Statement body,
+ FunctionExpression functionExpression(Modifiers modifiers, String name,
+ NodeList typeVariables, NodeList argumentList, Statement body,
[TypeAnnotation returnType]) {
return new FunctionExpression(
identifier(name),
+ typeVariables,
argumentList,
body,
returnType,
@@ -229,6 +230,7 @@
FunctionExpression constructorNode = builder.functionExpression(
builder.modifiers(isConst: true),
enumClass.name,
+ null, // typeVariables
builder.argumentList([indexDefinition]),
builder.emptyStatement());
@@ -247,15 +249,15 @@
enumClass.addMember(constructor, reporter);
List<EnumConstantElement> enumValues = <EnumConstantElement>[];
- VariableList variableList =
- new VariableList(builder.modifiers(isStatic: true, isConst: true));
- variableList.type = enumType;
int index = 0;
List<Node> valueReferences = <Node>[];
List<LiteralMapEntry> mapEntries = <LiteralMapEntry>[];
for (Link<Node> link = node.names.nodes; !link.isEmpty; link = link.tail) {
Identifier name = link.head;
AstBuilder valueBuilder = new AstBuilder(name.token.charOffset);
+ VariableList variableList = new VariableList(
+ valueBuilder.modifiers(isStatic: true, isConst: true));
+ variableList.type = enumType;
// Add reference for the `values` field.
valueReferences.add(valueBuilder.reference(name));
@@ -298,6 +300,7 @@
FunctionExpression toStringNode = builder.functionExpression(
Modifiers.EMPTY,
'toString',
+ null, // typeVariables
builder.argumentList([]),
builder.returnStatement(builder.indexGet(
builder.mapLiteral(mapEntries, isConst: true),
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index c8d9293..68f6f31 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -17,6 +17,7 @@
import '../elements/elements.dart';
import '../elements/modelx.dart'
show
+ BaseFunctionElementX,
ConstructorElementX,
ErroneousElementX,
FunctionElementX,
@@ -143,7 +144,7 @@
ResolverVisitor(
Compiler compiler, Element element, ResolutionRegistry registry,
- {bool useEnclosingScope: false})
+ {Scope scope, bool useEnclosingScope: false})
: this.enclosingElement = element,
// When the element is a field, we are actually resolving its
// initial value, which should not have access to instance
@@ -153,9 +154,10 @@
this.currentClass =
element.isClassMember ? element.enclosingClass : null,
this.statementScope = new StatementScope(),
- scope = useEnclosingScope
- ? Scope.buildEnclosingScope(element)
- : element.buildScope(),
+ this.scope = scope ??
+ (useEnclosingScope
+ ? Scope.buildEnclosingScope(element)
+ : element.buildScope()),
// The type annotations on a typedef do not imply type checks.
// TODO(karlklose): clean this up (dartbug.com/8870).
inCheckContext = compiler.options.enableTypeAssertions &&
@@ -408,16 +410,21 @@
if (node.modifiers.isStatic && enclosingElement.kind != ElementKind.CLASS) {
reporter.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC);
}
+ FunctionSignature functionSignature = function.functionSignature;
+ // Create the scope where the type variables are introduced, if any.
scope = new MethodScope(scope, function);
- // Put the parameters in scope.
- FunctionSignature functionParameters = function.functionSignature;
+ functionSignature.typeVariables
+ .forEach((DartType type) => addToScope(type.element));
+
+ // Create the scope for the function body, and put the parameters in scope.
+ scope = new BlockScope(scope);
Link<Node> parameterNodes =
(node.parameters == null) ? const Link<Node>() : node.parameters.nodes;
- functionParameters.forEachParameter((ParameterElementX element) {
+ functionSignature.forEachParameter((ParameterElementX element) {
// TODO(karlklose): should be a list of [FormalElement]s, but the actual
// implementation uses [Element].
- List<Element> optionals = functionParameters.optionalParameters;
+ List<Element> optionals = functionSignature.optionalParameters;
if (!optionals.isEmpty && element == optionals.first) {
NodeList nodes = parameterNodes.head;
parameterNodes = nodes.nodes;
@@ -446,14 +453,13 @@
parameterNodes = parameterNodes.tail;
});
addDeferredAction(enclosingElement, () {
- functionParameters
- .forEachOptionalParameter((ParameterElementX parameter) {
+ functionSignature.forEachOptionalParameter((ParameterElementX parameter) {
parameter.constant =
compiler.resolver.constantCompiler.compileConstant(parameter);
});
});
if (inCheckContext) {
- functionParameters.forEachParameter((ParameterElement element) {
+ functionSignature.forEachParameter((ParameterElement element) {
registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type));
});
}
@@ -570,7 +576,13 @@
name, node, ElementKind.FUNCTION, Modifiers.EMPTY, enclosingElement);
ResolverTask.processAsyncMarker(compiler, function, registry);
function.functionSignature = SignatureResolver.analyze(
- compiler, node.parameters, node.returnType, function, registry,
+ compiler,
+ scope,
+ node.typeVariables,
+ node.parameters,
+ node.returnType,
+ function,
+ registry,
createRealParameters: true,
isFunctionExpression: !inFunctionDeclaration);
checkLocalDefinitionName(node, function);
@@ -1864,7 +1876,7 @@
ResolutionResult handleTypeVariableTypeLiteralAccess(
Send node, Name name, TypeVariableElement element) {
AccessSemantics semantics;
- if (!Elements.hasAccessToTypeVariables(enclosingElement)) {
+ if (!Elements.hasAccessToTypeVariable(enclosingElement, element)) {
// TODO(johnniwinther): Add another access semantics for this.
ErroneousElement error = reportAndCreateErroneousElement(
node,
@@ -1905,7 +1917,7 @@
ResolutionResult handleTypeVariableTypeLiteralUpdate(
SendSet node, Name name, TypeVariableElement element) {
AccessSemantics semantics;
- if (!Elements.hasAccessToTypeVariables(enclosingElement)) {
+ if (!Elements.hasAccessToTypeVariable(enclosingElement, element)) {
// TODO(johnniwinther): Add another access semantics for this.
ErroneousElement error = reportAndCreateErroneousElement(
node,
@@ -3537,8 +3549,8 @@
ResolutionResult visitYield(Yield node) {
if (!compiler.backend.supportsAsyncAwait) {
- reporter.reportErrorMessage(node.yieldToken,
- MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
+ reporter.reportErrorMessage(
+ node.yieldToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
} else {
if (!currentAsyncMarker.isYielding) {
reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
@@ -3678,8 +3690,8 @@
ResolutionResult visitAwait(Await node) {
if (!compiler.backend.supportsAsyncAwait) {
- reporter.reportErrorMessage(node.awaitToken,
- MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
+ reporter.reportErrorMessage(
+ node.awaitToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
} else {
if (!currentAsyncMarker.isAsync) {
reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
@@ -4205,18 +4217,16 @@
ResolutionResult visitAsyncForIn(AsyncForIn node) {
if (!compiler.backend.supportsAsyncAwait) {
- reporter.reportErrorMessage(node.awaitToken,
- MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
+ reporter.reportErrorMessage(
+ node.awaitToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
} else {
if (!currentAsyncMarker.isAsync) {
reporter.reportErrorMessage(
node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN);
}
registry.registerFeature(Feature.ASYNC_FOR_IN);
- registry.registerDynamicUse(
- new DynamicUse(Selectors.current, null));
- registry.registerDynamicUse(
- new DynamicUse(Selectors.moveNext, null));
+ registry.registerDynamicUse(new DynamicUse(Selectors.current, null));
+ registry.registerDynamicUse(new DynamicUse(Selectors.moveNext, null));
}
visit(node.expression);
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 1439518..0676ba6 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -979,6 +979,8 @@
FunctionExpression node = element.parseNode(parsingContext);
return measure(() => SignatureResolver.analyze(
compiler,
+ element.enclosingElement.buildScope(),
+ node.typeVariables,
node.parameters,
node.returnType,
element,
diff --git a/pkg/compiler/lib/src/resolution/scope.dart b/pkg/compiler/lib/src/resolution/scope.dart
index 41df803..75c3de9 100644
--- a/pkg/compiler/lib/src/resolution/scope.dart
+++ b/pkg/compiler/lib/src/resolution/scope.dart
@@ -58,17 +58,14 @@
}
}
-/**
- * [TypeDeclarationScope] defines the outer scope of a type declaration in
- * which the declared type variables and the entities in the enclosing scope are
- * available but where declared and inherited members are not available. This
- * scope is only used for class declarations during resolution of the
- * class hierarchy. In all other cases [ClassScope] is used.
- */
-class TypeDeclarationScope extends NestedScope {
- final TypeDeclarationElement element;
+/// [TypeVariablesScope] defines the outer scope in a context where some type
+/// variables are declared and the entities in the enclosing scope are
+/// available, but where locally declared and inherited members are not
+/// available.
+abstract class TypeVariablesScope extends NestedScope {
+ List<DartType> get typeVariables;
- TypeDeclarationScope(parent, this.element) : super(parent) {
+ TypeVariablesScope(Scope parent) : super(parent) {
assert(parent != null);
}
@@ -77,7 +74,6 @@
}
Element lookupTypeVariable(String name) {
- List<DartType> typeVariables = element.typeVariables;
for (TypeVariableType type in typeVariables) {
if (type.name == name) {
return type.element;
@@ -87,6 +83,22 @@
}
Element localLookup(String name) => lookupTypeVariable(name);
+}
+
+/**
+ * [TypeDeclarationScope] defines the outer scope of a type declaration in
+ * which the declared type variables and the entities in the enclosing scope are
+ * available but where declared and inherited members are not available. This
+ * scope is used for class declarations during resolution of the class hierarchy
+ * and when resolving typedef signatures. In other cases [ClassScope] is used.
+ */
+class TypeDeclarationScope extends TypeVariablesScope {
+ final GenericElement element;
+
+ @override
+ List<DartType> get typeVariables => element.typeVariables;
+
+ TypeDeclarationScope(Scope parent, this.element) : super(parent);
String toString() => 'TypeDeclarationScope($element)';
}
diff --git a/pkg/compiler/lib/src/resolution/signatures.dart b/pkg/compiler/lib/src/resolution/signatures.dart
index 36ea970..33a8f2f 100644
--- a/pkg/compiler/lib/src/resolution/signatures.dart
+++ b/pkg/compiler/lib/src/resolution/signatures.dart
@@ -15,14 +15,15 @@
FormalElementX,
FunctionSignatureX,
InitializingFormalElementX,
- LocalParameterElementX;
+ LocalParameterElementX,
+ TypeVariableElementX;
import '../tree/tree.dart';
import '../universe/use.dart' show TypeUse;
import '../util/util.dart' show Link, LinkBuilder;
import 'members.dart' show ResolverVisitor;
import 'registry.dart' show ResolutionRegistry;
import 'resolution_common.dart' show MappingVisitor;
-import 'scope.dart' show Scope;
+import 'scope.dart' show Scope, TypeVariablesScope;
/**
* [SignatureResolver] resolves function signatures.
@@ -40,12 +41,13 @@
VariableDefinitions currentDefinitions;
SignatureResolver(Compiler compiler, FunctionTypedElement enclosingElement,
- ResolutionRegistry registry,
+ Scope scope, ResolutionRegistry registry,
{this.defaultValuesError, this.createRealParameters})
- : this.enclosingElement = enclosingElement,
- this.scope = enclosingElement.buildScope(),
- this.resolver =
- new ResolverVisitor(compiler, enclosingElement, registry),
+ : this.scope = scope,
+ this.enclosingElement = enclosingElement,
+ this.resolver = new ResolverVisitor(
+ compiler, enclosingElement, registry,
+ scope: scope),
super(compiler, registry);
bool get defaultValuesAllowed => defaultValuesError == null;
@@ -110,6 +112,8 @@
void computeFunctionType(FunctionExpression functionExpression) {
FunctionSignature functionSignature = SignatureResolver.analyze(
compiler,
+ scope,
+ functionExpression.typeVariables,
functionExpression.parameters,
functionExpression.returnType,
element,
@@ -287,6 +291,8 @@
*/
static FunctionSignature analyze(
Compiler compiler,
+ Scope scope,
+ NodeList typeVariables,
NodeList formalParameters,
Node returnNode,
FunctionTypedElement element,
@@ -296,8 +302,32 @@
bool isFunctionExpression: false}) {
DiagnosticReporter reporter = compiler.reporter;
+ List<DartType> createTypeVariables(NodeList typeVariableNodes) {
+ if (typeVariableNodes == null) return const <DartType>[];
+
+ // Create the types and elements corresponding to [typeVariableNodes].
+ Link<Node> nodes = typeVariableNodes.nodes;
+ List<DartType> arguments =
+ new List.generate(nodes.slowLength(), (int index) {
+ TypeVariable node = nodes.head;
+ String variableName = node.name.source;
+ nodes = nodes.tail;
+ TypeVariableElementX variableElement =
+ new TypeVariableElementX(variableName, element, index, node);
+ // TODO(eernst): When type variables are implemented fully we will need
+ // to resolve the actual bounds; currently we just claim [dynamic].
+ variableElement.boundCache = const DynamicType();
+ TypeVariableType variableType = new TypeVariableType(variableElement);
+ variableElement.typeCache = variableType;
+ return variableType;
+ }, growable: false);
+ return arguments;
+ }
+
+ List<DartType> typeVariableTypes = createTypeVariables(typeVariables);
+ scope = new FunctionSignatureBuildingScope(scope, typeVariableTypes);
SignatureResolver visitor = new SignatureResolver(
- compiler, element, registry,
+ compiler, element, scope, registry,
defaultValuesError: defaultValuesError,
createRealParameters: createRealParameters);
List<Element> parameters = const <Element>[];
@@ -411,6 +441,7 @@
namedParameters,
namedParameterTypes);
return new FunctionSignatureX(
+ typeVariables: typeVariableTypes,
requiredParameters: parameters,
optionalParameters: visitor.optionalParameters,
requiredParameterCount: requiredParameterCount,
@@ -437,3 +468,15 @@
return result;
}
}
+
+/// Used during `SignatureResolver.analyze` to provide access to the type
+/// variables of the function signature itself when its signature is analyzed.
+class FunctionSignatureBuildingScope extends TypeVariablesScope {
+ @override
+ final List<DartType> typeVariables;
+
+ FunctionSignatureBuildingScope(Scope parent, this.typeVariables)
+ : super(parent);
+
+ String toString() => 'FunctionSignatureBuildingScope($typeVariables)';
+}
diff --git a/pkg/compiler/lib/src/resolution/tree_elements.dart b/pkg/compiler/lib/src/resolution/tree_elements.dart
index 9c60745..1e52fca 100644
--- a/pkg/compiler/lib/src/resolution/tree_elements.dart
+++ b/pkg/compiler/lib/src/resolution/tree_elements.dart
@@ -365,7 +365,7 @@
}
@override
- FunctionElement getFunctionDefinition(FunctionExpression node) {
+ Element getFunctionDefinition(FunctionExpression node) {
return this[node];
}
diff --git a/pkg/compiler/lib/src/resolution/type_resolver.dart b/pkg/compiler/lib/src/resolution/type_resolver.dart
index 832279b..e1a076d 100644
--- a/pkg/compiler/lib/src/resolution/type_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/type_resolver.dart
@@ -18,6 +18,7 @@
ErroneousElement,
PrefixElement,
TypedefElement,
+ TypeDeclarationElement,
TypeVariableElement;
import '../elements/modelx.dart' show ErroneousElementX;
import '../tree/tree.dart';
@@ -205,12 +206,17 @@
}
}
} else if (element.isTypeVariable) {
+ // FIXME: check enclosing, which may be not class, not typedef (so
+ // it's a generic method) then set the type to `const DynamicType()`.
+ // This should later be fixed such that we don't tell the user that they
+ // wrote `dynamic` anywhere.
TypeVariableElement typeVariable = element;
Element outer =
visitor.enclosingElement.outermostEnclosingMemberOrTopLevel;
if (!outer.isClass &&
!outer.isTypedef &&
- !Elements.hasAccessToTypeVariables(visitor.enclosingElement)) {
+ !Elements.hasAccessToTypeVariable(
+ visitor.enclosingElement, typeVariable)) {
registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
type = reportFailureAndCreateType(
MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
diff --git a/pkg/compiler/lib/src/resolution/typedefs.dart b/pkg/compiler/lib/src/resolution/typedefs.dart
index ed6f741..cee72df 100644
--- a/pkg/compiler/lib/src/resolution/typedefs.dart
+++ b/pkg/compiler/lib/src/resolution/typedefs.dart
@@ -31,7 +31,13 @@
resolveTypeVariableBounds(node.typeParameters);
FunctionSignature signature = SignatureResolver.analyze(
- compiler, node.formals, node.returnType, element, registry,
+ compiler,
+ scope,
+ null /* typeVariables */,
+ node.formals,
+ node.returnType,
+ element,
+ registry,
defaultValuesError: MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT);
element.functionSignature = signature;
diff --git a/pkg/compiler/lib/src/serialization/element_serialization.dart b/pkg/compiler/lib/src/serialization/element_serialization.dart
index 6f5dc4d..ebb179a 100644
--- a/pkg/compiler/lib/src/serialization/element_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/element_serialization.dart
@@ -13,6 +13,7 @@
import 'keys.dart';
import 'modelz.dart';
import 'serialization.dart';
+import 'serialization_util.dart';
/// Enum kinds used for encoding [Element]s.
enum SerializedElementKind {
@@ -22,7 +23,9 @@
ENUM,
NAMED_MIXIN_APPLICATION,
GENERATIVE_CONSTRUCTOR,
+ DEFAULT_CONSTRUCTOR,
FACTORY_CONSTRUCTOR,
+ REDIRECTING_FACTORY_CONSTRUCTOR,
FORWARDING_CONSTRUCTOR,
TOPLEVEL_FIELD,
STATIC_FIELD,
@@ -340,13 +343,21 @@
SerializedElementKind getSerializedKind(Element element) {
if (element.isGenerativeConstructor) {
- if (element.enclosingClass.isNamedMixinApplication) {
+ ConstructorElement constructor = element;
+ if (constructor.enclosingClass.isNamedMixinApplication) {
return SerializedElementKind.FORWARDING_CONSTRUCTOR;
+ } else if (constructor.definingConstructor != null) {
+ return SerializedElementKind.DEFAULT_CONSTRUCTOR;
} else {
return SerializedElementKind.GENERATIVE_CONSTRUCTOR;
}
} else if (element.isFactoryConstructor) {
- return SerializedElementKind.FACTORY_CONSTRUCTOR;
+ ConstructorElement constructor = element;
+ if (constructor.isRedirectingFactory) {
+ return SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR;
+ } else {
+ return SerializedElementKind.FACTORY_CONSTRUCTOR;
+ }
}
return null;
}
@@ -363,13 +374,27 @@
SerializerUtil.serializeParameters(element, encoder);
encoder.setBool(Key.IS_CONST, element.isConst);
encoder.setBool(Key.IS_EXTERNAL, element.isExternal);
- if (element.isExternal) return;
if (element.isConst && !element.isFromEnvironmentConstructor) {
ConstantConstructor constantConstructor = element.constantConstructor;
ObjectEncoder constantEncoder = encoder.createObject(Key.CONSTRUCTOR);
const ConstantConstructorSerializer()
.visit(constantConstructor, constantEncoder);
}
+ if (kind == SerializedElementKind.GENERATIVE_CONSTRUCTOR) {
+ encoder.setBool(Key.IS_REDIRECTING, element.isRedirectingGenerative);
+ }
+ encoder.setElement(Key.EFFECTIVE_TARGET, element.effectiveTarget);
+ if (kind == SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR) {
+ encoder.setType(
+ Key.EFFECTIVE_TARGET_TYPE,
+ element
+ .computeEffectiveTargetType(element.enclosingClass.thisType));
+ encoder.setElement(Key.IMMEDIATE_REDIRECTION_TARGET,
+ element.immediateRedirectionTarget);
+ if (element.redirectionDeferredPrefix != null) {
+ encoder.setElement(Key.PREFIX, element.redirectionDeferredPrefix);
+ }
+ }
}
}
}
@@ -658,8 +683,12 @@
return new InstanceFieldElementZ(decoder);
case SerializedElementKind.GENERATIVE_CONSTRUCTOR:
return new GenerativeConstructorElementZ(decoder);
+ case SerializedElementKind.DEFAULT_CONSTRUCTOR:
+ return new DefaultConstructorElementZ(decoder);
case SerializedElementKind.FACTORY_CONSTRUCTOR:
return new FactoryConstructorElementZ(decoder);
+ case SerializedElementKind.REDIRECTING_FACTORY_CONSTRUCTOR:
+ return new RedirectingFactoryConstructorElementZ(decoder);
case SerializedElementKind.FORWARDING_CONSTRUCTOR:
return new ForwardingConstructorElementZ(
decoder.getElement(Key.CLASS), decoder.getElement(Key.ELEMENT));
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index acf3e71..969ef40 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -6,6 +6,7 @@
library dart2js.serialization.equivalence;
+import '../common.dart';
import '../common/resolution.dart';
import '../constants/expressions.dart';
import '../dart_types.dart';
@@ -770,7 +771,9 @@
'node', resolvedAst1.node, resolvedAst2.node) &&
new NodeEquivalenceVisitor(strategy).testNodes(resolvedAst1, resolvedAst2,
'body', resolvedAst1.body, resolvedAst2.body) &&
- testTreeElementsEquivalence(resolvedAst1, resolvedAst2, strategy);
+ testTreeElementsEquivalence(resolvedAst1, resolvedAst2, strategy) &&
+ strategy.test(resolvedAst1, resolvedAst2, 'sourceUri',
+ resolvedAst1.sourceUri, resolvedAst2.sourceUri);
}
/// Tests the equivalence of the data stored in the [TreeElements] of
@@ -1054,30 +1057,39 @@
bool testNodes(
var object1, var object2, String property, Node node1, Node node2) {
- if (node1 == node2) return true;
- if (node1 == null || node2 == null) return false;
- return node1.accept1(this, node2);
+ return strategy.test(object1, object2, property, node1, node2,
+ (Node n1, Node n2) {
+ if (n1 == n2) return true;
+ if (n1 == null || n2 == null) return false;
+ return n1.accept1(this, n2);
+ });
}
bool testNodeLists(var object1, var object2, String property,
Link<Node> list1, Link<Node> list2) {
- if (list1 == list2) return true;
- if (list1 == null || list2 == null) return false;
- while (list1.isNotEmpty && list2.isNotEmpty) {
- if (!list1.head.accept1(this, list2.head)) {
- return false;
+ return strategy.test(object1, object2, property, list1, list2,
+ (Link<Node> l1, Link<Node> l2) {
+ if (l1 == l2) return true;
+ if (l1 == null || l2 == null) return false;
+ while (l1.isNotEmpty && l2.isNotEmpty) {
+ if (!l1.head.accept1(this, l2.head)) {
+ return false;
+ }
+ l1 = l1.tail;
+ l2 = l2.tail;
}
- list1 = list1.tail;
- list2 = list2.tail;
- }
- return list1.isEmpty && list2.isEmpty;
+ return l1.isEmpty && l2.isEmpty;
+ });
}
bool testTokens(
var object1, var object2, String property, Token token1, Token token2) {
- if (token1 == token2) return true;
- if (token1 == null || token2 == null) return false;
- return token1.hashCode == token2.hashCode;
+ return strategy.test(object1, object2, property, token1, token2,
+ (Token t1, Token t2) {
+ if (t1 == t2) return true;
+ if (t1 == null || t2 == null) return false;
+ return strategy.test(t1, t2, 'hashCode', t1.hashCode, t2.hashCode);
+ });
}
@override
diff --git a/pkg/compiler/lib/src/serialization/keys.dart b/pkg/compiler/lib/src/serialization/keys.dart
index c7599b2..de805fe 100644
--- a/pkg/compiler/lib/src/serialization/keys.dart
+++ b/pkg/compiler/lib/src/serialization/keys.dart
@@ -26,6 +26,8 @@
static const Key DEFAULT = const Key('default');
static const Key DEFAULTS = const Key('defaults');
static const Key DYNAMIC_USES = const Key('dynamic-uses');
+ static const Key EFFECTIVE_TARGET = const Key('effectiveTarget');
+ static const Key EFFECTIVE_TARGET_TYPE = const Key('effectiveTargetType');
static const Key ELEMENT = const Key('element');
static const Key ELEMENTS = const Key('elements');
static const Key EXECUTABLE_CONTEXT = const Key('executable-context');
@@ -40,6 +42,8 @@
static const Key GET_OR_SET = const Key('getOrSet');
static const Key GETTER = const Key('getter');
static const Key ID = const Key('id');
+ static const Key IMMEDIATE_REDIRECTION_TARGET =
+ const Key('immediateRedirectionTarget');
static const Key IMPACTS = const Key('impacts');
static const Key IMPORT = const Key('import');
static const Key IMPORTS = const Key('imports');
@@ -58,6 +62,7 @@
static const Key IS_OPERATOR = const Key('isOperator');
static const Key IS_OPTIONAL = const Key('isOptional');
static const Key IS_PROXY = const Key('isProxy');
+ static const Key IS_REDIRECTING = const Key('isRedirecting');
static const Key IS_SETTER = const Key('isSetter');
static const Key IS_UNNAMED_MIXIN_APPLICATION =
const Key('isUnnamedMixinApplication');
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index e77d5c0..b280d69 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -30,6 +30,7 @@
import '../util/util.dart' show Link, LinkBuilder;
import 'keys.dart';
import 'serialization.dart';
+import 'serialization_util.dart';
/// Compute a [Link] from an [Iterable].
Link toLink(Iterable iterable) {
@@ -63,17 +64,12 @@
FunctionElement asFunctionElement() => null;
@override
- Scope buildScope() => _unsupported('analyzableElement');
+ Scope buildScope() => _unsupported('buildScope');
@override
ClassElement get enclosingClass => null;
@override
- Element get enclosingClassOrCompilationUnit {
- return _unsupported('enclosingClassOrCompilationUnit');
- }
-
- @override
LibraryElement get implementationLibrary => library;
@override
@@ -109,9 +105,8 @@
@override
bool get isStatic => false;
- // TODO(johnniwinther): Find a more precise semantics for this.
@override
- bool get isSynthesized => true;
+ bool get isSynthesized => false;
@override
bool get isTopLevel => false;
@@ -132,10 +127,14 @@
@override
String get name => _decoder.getString(Key.NAME);
+ // TODO(johnniwinther): Should this be cached?
+ @override
+ int get sourceOffset => _decoder.getInt(Key.OFFSET, isOptional: true);
+
@override
SourceSpan get sourcePosition {
// TODO(johnniwinther): Should this be cached?
- int offset = _decoder.getInt(Key.OFFSET, isOptional: true);
+ int offset = sourceOffset;
if (offset == null) return null;
Uri uri = _decoder.getUri(Key.URI, isOptional: true);
if (uri == null) {
@@ -327,6 +326,9 @@
Element get enclosingElement => _canonicalElement.enclosingElement;
@override
+ int get sourceOffset => _canonicalElement.sourceOffset;
+
+ @override
SourceSpan get sourcePosition => _canonicalElement.sourcePosition;
@override
@@ -746,9 +748,6 @@
abstract class FunctionTypedElementMixin
implements FunctionElement, DeserializedElementZ {
@override
- AsyncMarker get asyncMarker => _unsupported('asyncMarker');
-
- @override
FunctionElement asFunctionElement() => this;
@override
@@ -756,6 +755,9 @@
return _decoder.getBool(Key.IS_EXTERNAL,
isOptional: true, defaultValue: false);
}
+
+ @override
+ List<DartType> get typeVariables => functionSignature.typeVariables;
}
abstract class ClassElementMixin implements ElementZ, ClassElement {
@@ -767,23 +769,9 @@
ElementKind get kind => ElementKind.CLASS;
@override
- void addBackendMember(Element element) => _unsupported('addBackendMember');
-
- @override
- void forEachBackendMember(void f(Element member)) {
- _unsupported('forEachBackendMember');
- }
-
- @override
- bool get hasBackendMembers => _unsupported('hasBackendMembers');
-
- @override
bool get hasConstructor => _unsupported('hasConstructor');
@override
- bool hasFieldShadowedBy(Element fieldMember) => _unsupported('');
-
- @override
bool get hasIncompleteHierarchy => _unsupported('hasIncompleteHierarchy');
@override
@@ -793,11 +781,6 @@
bool get isEnumClass => false;
@override
- Element lookupBackendMember(String memberName) {
- return _unsupported('lookupBackendMember');
- }
-
- @override
ConstructorElement lookupDefaultConstructor() {
ConstructorElement constructor = lookupConstructor("");
if (constructor != null && constructor.parameters.isEmpty) {
@@ -807,9 +790,6 @@
}
@override
- void reverseBackendMembers() => _unsupported('reverseBackendMembers');
-
- @override
ClassElement get superclass => supertype != null ? supertype.element : null;
@override
@@ -1034,6 +1014,9 @@
InterfaceType get mixinType => interfaces.head;
@override
+ int get sourceOffset => _subclass.sourceOffset;
+
+ @override
SourceSpan get sourcePosition => _subclass.sourcePosition;
}
@@ -1063,8 +1046,12 @@
ParametersMixin,
TypedElementMixin,
MemberElementMixin
- implements ConstructorElement {
+ implements
+ ConstructorElement,
+ // TODO(johnniwinther): Sort out whether a constructor is a method.
+ MethodElement {
ConstantConstructor _constantConstructor;
+ ConstructorElement _effectiveTarget;
ConstructorElementZ(ObjectDecoder decoder) : super(decoder);
@@ -1103,43 +1090,42 @@
AsyncMarker get asyncMarker => AsyncMarker.SYNC;
@override
- InterfaceType computeEffectiveTargetType(InterfaceType newType) {
- return _unsupported('computeEffectiveTargetType');
- }
-
- @override
- ConstructorElement get definingConstructor {
- return _unsupported('definingConstructor');
- }
+ ConstructorElement get definingConstructor => null;
@override
ConstructorElement get effectiveTarget {
- return _unsupported('effectiveTarget');
+ if (_effectiveTarget == null) {
+ _effectiveTarget =
+ _decoder.getElement(Key.EFFECTIVE_TARGET, isOptional: true);
+ if (_effectiveTarget == null) {
+ _effectiveTarget = this;
+ }
+ }
+ return _effectiveTarget;
}
@override
- ConstructorElement get immediateRedirectionTarget {
- return _unsupported('immediateRedirectionTarget');
- }
+ ConstructorElement get immediateRedirectionTarget => null;
+
+ // TODO(johnniwinther): Should serialization support erroneous element
+ // relations?
+ @override
+ bool get isEffectiveTargetMalformed => false;
@override
- bool get isEffectiveTargetMalformed {
- return _unsupported('isEffectiveTargetMalformed');
- }
+ bool get isCyclicRedirection => false;
@override
- bool get isRedirectingFactory => _unsupported('isRedirectingFactory');
+ bool get isRedirectingFactory => false;
@override
- bool get isRedirectingGenerative => _unsupported('isRedirectingGenerative');
+ bool get isRedirectingGenerative => false;
@override
- bool get isCyclicRedirection => _unsupported('isCyclicRedirection');
+ PrefixElement get redirectionDeferredPrefix => null;
@override
- PrefixElement get redirectionDeferredPrefix {
- return _unsupported('redirectionDeferredPrefix');
- }
+ InterfaceType computeEffectiveTargetType(InterfaceType newType) => newType;
}
class GenerativeConstructorElementZ extends ConstructorElementZ {
@@ -1149,8 +1135,22 @@
ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
@override
- bool get isEffectiveTargetMalformed =>
- _unsupported('isEffectiveTargetMalformed');
+ bool get isRedirectingGenerative => _decoder.getBool(Key.IS_REDIRECTING);
+}
+
+class DefaultConstructorElementZ extends ConstructorElementZ {
+ DefaultConstructorElementZ(ObjectDecoder decoder) : super(decoder);
+
+ @override
+ ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
+
+ @override
+ bool get isSynthesized => true;
+
+ @override
+ ConstructorElement get definingConstructor {
+ return enclosingClass.superclass.lookupConstructor('');
+ }
}
class FactoryConstructorElementZ extends ConstructorElementZ {
@@ -1158,10 +1158,66 @@
@override
ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
+}
+
+class RedirectingFactoryConstructorElementZ extends ConstructorElementZ {
+ InterfaceType _effectiveTargetType;
+ ConstructorElement _immediateRedirectionTarget;
+ PrefixElement _redirectionDeferredPrefix;
+
+ RedirectingFactoryConstructorElementZ(ObjectDecoder decoder) : super(decoder);
@override
- bool get isEffectiveTargetMalformed =>
- _unsupported('isEffectiveTargetMalformed');
+ ElementKind get kind => ElementKind.FACTORY_CONSTRUCTOR;
+
+ @override
+ bool get isRedirectingFactory => true;
+
+ void _ensureEffectiveTarget() {
+ if (_effectiveTarget == null) {
+ _effectiveTarget =
+ _decoder.getElement(Key.EFFECTIVE_TARGET, isOptional: true);
+ if (_effectiveTarget == null) {
+ _effectiveTarget = this;
+ _effectiveTargetType = enclosingClass.thisType;
+ } else {
+ _effectiveTargetType = _decoder.getType(Key.EFFECTIVE_TARGET_TYPE);
+ }
+ }
+ }
+
+ @override
+ ConstructorElement get effectiveTarget {
+ _ensureEffectiveTarget();
+ return _effectiveTarget;
+ }
+
+ @override
+ InterfaceType computeEffectiveTargetType(InterfaceType newType) {
+ _ensureEffectiveTarget();
+ return _effectiveTargetType.substByContext(newType);
+ }
+
+ void _ensureRedirection() {
+ if (_immediateRedirectionTarget == null) {
+ _immediateRedirectionTarget =
+ _decoder.getElement(Key.IMMEDIATE_REDIRECTION_TARGET);
+ _redirectionDeferredPrefix =
+ _decoder.getElement(Key.PREFIX, isOptional: true);
+ }
+ }
+
+ @override
+ ConstructorElement get immediateRedirectionTarget {
+ _ensureRedirection();
+ return _immediateRedirectionTarget;
+ }
+
+ @override
+ PrefixElement get redirectionDeferredPrefix {
+ _ensureRedirection();
+ return _redirectionDeferredPrefix;
+ }
}
class ForwardingConstructorElementZ extends ElementZ
@@ -1235,6 +1291,9 @@
bool get isRedirectingGenerative => false;
@override
+ bool get isSynthesized => true;
+
+ @override
ElementKind get kind => ElementKind.GENERATIVE_CONSTRUCTOR;
@override
@@ -1264,6 +1323,9 @@
PrefixElement get redirectionDeferredPrefix => null;
@override
+ int get sourceOffset => enclosingClass.sourceOffset;
+
+ @override
SourceSpan get sourcePosition => enclosingClass.sourcePosition;
@override
@@ -1272,6 +1334,9 @@
// variables correctly.
return definingConstructor.type;
}
+
+ @override
+ List<DartType> get typeVariables => _unsupported("typeVariables");
}
abstract class MemberElementMixin
@@ -1283,7 +1348,7 @@
Name get memberName => new Name(name, library);
@override
- List<FunctionElement> get nestedClosures => const <FunctionElement>[];
+ List<FunctionElement> get nestedClosures => <FunctionElement>[];
}
abstract class FieldElementZ extends DeserializedElementZ
@@ -1449,6 +1514,11 @@
@override
ElementKind get kind => ElementKind.FUNCTION;
+
+ @override
+ AsyncMarker get asyncMarker {
+ return _decoder.getEnum(Key.ASYNC_MARKER, AsyncMarker.values);
+ }
}
abstract class GetterElementZ extends DeserializedElementZ
@@ -1743,6 +1813,9 @@
LibraryElement get library => typeDeclaration.library;
@override
+ int get sourceOffset => typeDeclaration.sourceOffset;
+
+ @override
SourceSpan get sourcePosition => typeDeclaration.sourcePosition;
}
@@ -1794,8 +1867,13 @@
@override
FunctionSignature get functionSignature => _unsupported('functionSignature');
+ // TODO(johnniwinther): HACK. Remove [initializer] and [node] on
+ // [ParameterElementZ] when the inference does need these.
@override
- Expression get initializer => _unsupported('initializer');
+ Expression get initializer => null;
+
+ @override
+ Node get node => null;
@override
bool get isNamed => _decoder.getBool(Key.IS_NAMED);
@@ -1808,6 +1886,9 @@
@override
MemberElement get memberContext => executableContext.memberContext;
+
+ @override
+ List<DartType> get typeVariables => functionSignature.typeVariables;
}
class LocalParameterElementZ extends ParameterElementZ
diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
index eb03860..613bd61 100644
--- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
@@ -110,9 +110,6 @@
Key.URI,
elements.analyzedElement.compilationUnit.script.resourceUri,
elements.analyzedElement.compilationUnit.script.resourceUri);
- if (resolvedAst.body != null) {
- objectEncoder.setInt(Key.BODY, nodeIndices[resolvedAst.body]);
- }
AstKind kind;
if (element.enclosingClass is EnumClassElement) {
if (element.name == 'index') {
@@ -148,6 +145,13 @@
}
objectEncoder.setEnum(Key.SUB_KIND, kind);
root.accept(indexComputer);
+ if (resolvedAst.body != null) {
+ int index = nodeIndices[resolvedAst.body];
+ assert(invariant(element, index != null,
+ message:
+ "No index for body of $element: ${resolvedAst.body} ($nodeIndices)."));
+ objectEncoder.setInt(Key.BODY, index);
+ }
root.accept(this);
if (jumpTargetMap.isNotEmpty) {
ListEncoder list = objectEncoder.createList(Key.JUMP_TARGETS);
@@ -290,6 +294,16 @@
.setInt(Key.LABEL_DEFINITION, getLabelDefinitionId(labelDefinition));
}
}
+
+ @override
+ visitFunctionExpression(FunctionExpression node) {
+ visitExpression(node);
+ Element function = elements.getFunctionDefinition(node);
+ if (function != null && function.isFunction && function.isLocal) {
+ // Mark root nodes of local functions; these need their own ResolvedAst.
+ getNodeDataEncoder(node).setElement(Key.FUNCTION, function);
+ }
+ }
}
class ResolvedAstDeserializer {
@@ -304,41 +318,47 @@
return null;
}
- /// Deserializes the [ResolvedAst] for [element] from [objectDecoder].
+ /// Deserializes the [ResolvedAst]s for [element] and its nested local
+ /// functions from [objectDecoder] and adds these to [resolvedAstMap].
/// [parsing] and [getBeginToken] are used for parsing the [Node] for
/// [element] from its source code.
- static ResolvedAst deserialize(
+ static void deserialize(
Element element,
ObjectDecoder objectDecoder,
ParsingContext parsing,
Token getBeginToken(Uri uri, int charOffset),
- DeserializerPlugin nativeDataDeserializer) {
+ DeserializerPlugin nativeDataDeserializer,
+ Map<Element, ResolvedAst> resolvedAstMap) {
ResolvedAstKind kind =
objectDecoder.getEnum(Key.KIND, ResolvedAstKind.values);
switch (kind) {
case ResolvedAstKind.PARSED:
- return deserializeParsed(element, objectDecoder, parsing, getBeginToken,
- nativeDataDeserializer);
+ deserializeParsed(element, objectDecoder, parsing, getBeginToken,
+ nativeDataDeserializer, resolvedAstMap);
+ break;
case ResolvedAstKind.DEFAULT_CONSTRUCTOR:
case ResolvedAstKind.FORWARDING_CONSTRUCTOR:
- return new SynthesizedResolvedAst(element, kind);
+ resolvedAstMap[element] = new SynthesizedResolvedAst(element, kind);
+ break;
}
}
- /// Deserialize a [ResolvedAst] that is defined in terms of an AST together
- /// with [TreeElements].
- static ResolvedAst deserializeParsed(
+ /// Deserialize the [ResolvedAst]s for the member [element] (constructor,
+ /// method, or field) and its nested closures. The [ResolvedAst]s are added
+ /// to [resolvedAstMap].
+ static void deserializeParsed(
Element element,
ObjectDecoder objectDecoder,
ParsingContext parsing,
Token getBeginToken(Uri uri, int charOffset),
- DeserializerPlugin nativeDataDeserializer) {
+ DeserializerPlugin nativeDataDeserializer,
+ Map<Element, ResolvedAst> resolvedAstMap) {
CompilationUnitElement compilationUnit = element.compilationUnit;
DiagnosticReporter reporter = parsing.reporter;
+ Uri uri = objectDecoder.getUri(Key.URI);
/// Returns the first [Token] for parsing the [Node] for [element].
Token readBeginToken() {
- Uri uri = objectDecoder.getUri(Key.URI);
int charOffset = objectDecoder.getInt(Key.OFFSET);
Token beginToken = getBeginToken(uri, charOffset);
if (beginToken == null) {
@@ -425,6 +445,7 @@
FunctionExpression toStringNode = builder.functionExpression(
Modifiers.EMPTY,
'toString',
+ null,
builder.argumentList([]),
builder.returnStatement(builder.indexGet(
builder.mapLiteral(mapEntries, isConst: true),
@@ -437,6 +458,7 @@
FunctionExpression constructorNode = builder.functionExpression(
builder.modifiers(isConst: true),
element.enclosingClass.name,
+ null,
builder.argumentList([indexDefinition]),
builder.emptyStatement());
return constructorNode;
@@ -489,12 +511,15 @@
AstIndexComputer indexComputer = new AstIndexComputer();
Map<Node, int> nodeIndices = indexComputer.nodeIndices;
List<Node> nodeList = indexComputer.nodeList;
+ root.accept(indexComputer);
Node body;
int bodyNodeIndex = objectDecoder.getInt(Key.BODY, isOptional: true);
if (bodyNodeIndex != null) {
+ assert(invariant(element, bodyNodeIndex < nodeList.length,
+ message: "Body node index ${bodyNodeIndex} out of range. "
+ "Node count: ${nodeList.length}"));
body = nodeList[bodyNodeIndex];
}
- root.accept(indexComputer);
List<JumpTarget> jumpTargets = <JumpTarget>[];
Map<JumpTarget, List<int>> jumpTargetLabels = <JumpTarget, List<int>>{};
@@ -545,7 +570,7 @@
jumpTarget.labels = linkBuilder.toLink();
});
- ListDecoder dataDecoder = objectDecoder.getList(Key.DATA);
+ ListDecoder dataDecoder = objectDecoder.getList(Key.DATA, isOptional: true);
if (dataDecoder != null) {
for (int i = 0; i < dataDecoder.length; i++) {
ObjectDecoder objectDecoder = dataDecoder.getObject(i);
@@ -616,8 +641,20 @@
elements.registerNativeData(node, nativeData);
}
}
+ FunctionElement function =
+ objectDecoder.getElement(Key.FUNCTION, isOptional: true);
+ if (function != null) {
+ FunctionExpression functionExpression = node;
+ assert(invariant(function, !resolvedAstMap.containsKey(function),
+ message: "ResolvedAst has already been computed for $function."));
+ resolvedAstMap[function] = new ParsedResolvedAst(function,
+ functionExpression, functionExpression.body, elements, uri);
+ }
}
}
- return new ParsedResolvedAst(element, root, body, elements);
+ assert(invariant(element, !resolvedAstMap.containsKey(element),
+ message: "ResolvedAst has already been computed for $element."));
+ resolvedAstMap[element] =
+ new ParsedResolvedAst(element, root, body, elements, uri);
}
}
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 0eb9db0..1639c32 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -65,11 +65,11 @@
element, context, deserializer.computeWorldImpact(element));
}
- bool hasResolvedAst(Element element) {
+ bool hasResolvedAst(ExecutableElement element) {
return deserializer != null ? deserializer.hasResolvedAst(element) : false;
}
- ResolvedAst getResolvedAst(Element element) {
+ ResolvedAst getResolvedAst(ExecutableElement element) {
return deserializer != null ? deserializer.getResolvedAst(element) : null;
}
}
@@ -102,8 +102,8 @@
abstract class DeserializerSystem {
Future<LibraryElement> readLibrary(Uri resolvedUri);
bool isDeserialized(Element element);
- bool hasResolvedAst(Element element);
- ResolvedAst getResolvedAst(Element element);
+ bool hasResolvedAst(ExecutableElement element);
+ ResolvedAst getResolvedAst(ExecutableElement element);
bool hasResolutionImpact(Element element);
ResolutionImpact getResolutionImpact(Element element);
WorldImpact computeWorldImpact(Element element);
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index e927971..50db1bf 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -1134,7 +1134,7 @@
localsHandler = new LocalsHandler(this, target, null);
sourceElementStack.add(target);
sourceInformationBuilder =
- sourceInformationFactory.createBuilderForContext(target);
+ sourceInformationFactory.createBuilderForContext(resolvedAst);
graph.sourceInformation =
sourceInformationBuilder.buildVariableDeclaration();
}
@@ -1182,7 +1182,7 @@
// that it can never be null (see result in buildFactory for instance).
var result;
if (target.isGenerativeConstructor) {
- result = buildFactory(target);
+ result = buildFactory(resolvedAst);
} else if (target.isGenerativeConstructorBody ||
target.isFactoryConstructor ||
target.isFunction ||
@@ -1535,11 +1535,11 @@
function, selector, providedArguments, currentNode);
enterInlinedMethod(function, functionResolvedAst, compiledArguments,
instanceType: instanceType);
- inlinedFrom(function, () {
+ inlinedFrom(functionResolvedAst, () {
if (!isReachable) {
emitReturn(graph.addConstantNull(compiler), null);
} else {
- doInline(function);
+ doInline(functionResolvedAst);
}
});
leaveInlinedMethod();
@@ -1572,14 +1572,15 @@
return allInlinedFunctionsCalledOnce && isFunctionCalledOnce(element);
}
- inlinedFrom(Element element, f()) {
+ inlinedFrom(ResolvedAst resolvedAst, f()) {
+ Element element = resolvedAst.element;
assert(element is FunctionElement || element is VariableElement);
- return reporter.withCurrentElement(element, () {
+ return reporter.withCurrentElement(element.implementation, () {
// The [sourceElementStack] contains declaration elements.
SourceInformationBuilder oldSourceInformationBuilder =
sourceInformationBuilder;
sourceInformationBuilder =
- sourceInformationBuilder.forContext(element.implementation);
+ sourceInformationBuilder.forContext(resolvedAst);
sourceElementStack.add(element.declaration);
var result = f();
sourceInformationBuilder = oldSourceInformationBuilder;
@@ -1753,12 +1754,15 @@
}
HGraph buildLazyInitializer(VariableElement variable) {
+ assert(invariant(variable, resolvedAst.element == variable,
+ message: "Unexpected variable $variable for $resolvedAst."));
inLazyInitializerExpression = true;
- assert(invariant(variable, variable.initializer != null,
+ ast.VariableDefinitions node = resolvedAst.node;
+ ast.Node initializer = resolvedAst.body;
+ assert(invariant(variable, initializer != null,
message: "Non-constant variable $variable has no initializer."));
- ast.VariableDefinitions node = variable.node;
openFunction(variable, node);
- visit(variable.initializer);
+ visit(initializer);
HInstruction value = pop();
value = potentiallyCheckOrTrustType(value, variable.type);
ast.SendSet sendSet = node.definitions.nodes.head;
@@ -1773,11 +1777,14 @@
*
* Returns [:null:] if the constructor does not have a body.
*/
- ConstructorBodyElement getConstructorBody(FunctionElement constructor) {
+ ConstructorBodyElement getConstructorBody(
+ ResolvedAst constructorResolvedAst) {
+ ConstructorElement constructor =
+ constructorResolvedAst.element.implementation;
assert(constructor.isGenerativeConstructor);
- assert(invariant(constructor, constructor.isImplementation));
- if (constructor.isSynthesized) return null;
- ast.FunctionExpression node = constructor.node;
+ if (constructorResolvedAst.kind != ResolvedAstKind.PARSED) return null;
+
+ ast.FunctionExpression node = constructorResolvedAst.node;
// If we know the body doesn't have any code, we don't generate it.
if (!node.hasBody) return null;
if (node.hasEmptyBody) return null;
@@ -1888,13 +1895,13 @@
/**
* Run this builder on the body of the [function] to be inlined.
*/
- void visitInlinedFunction(FunctionElement function) {
- potentiallyCheckInlinedParameterTypes(function);
+ void visitInlinedFunction(ResolvedAst resolvedAst) {
+ potentiallyCheckInlinedParameterTypes(resolvedAst.element.implementation);
- if (function.isGenerativeConstructor) {
- buildFactory(function);
+ if (resolvedAst.element.isGenerativeConstructor) {
+ buildFactory(resolvedAst);
} else {
- ast.FunctionExpression functionNode = function.node;
+ ast.FunctionExpression functionNode = resolvedAst.node;
functionNode.body.accept(this);
}
}
@@ -1941,14 +1948,14 @@
* Invariant: [constructors] must contain only implementation elements.
*/
void inlineSuperOrRedirect(
- ConstructorElement callee,
+ ResolvedAst constructorRecolvedAst,
List<HInstruction> compiledArguments,
- List<FunctionElement> constructors,
+ List<ResolvedAst> constructorResolvedAsts,
Map<Element, HInstruction> fieldValues,
FunctionElement caller) {
- callee = callee.implementation;
+ ConstructorElement callee = constructorRecolvedAst.element.implementation;
reporter.withCurrentElement(callee, () {
- constructors.add(callee);
+ constructorResolvedAsts.add(constructorRecolvedAst);
ClassElement enclosingClass = callee.enclosingClass;
if (backend.classNeedsRti(enclosingClass)) {
// If [enclosingClass] needs RTI, we have to give a value to its
@@ -1986,7 +1993,7 @@
// For redirecting constructors, the fields will be initialized later
// by the effective target.
if (!callee.isRedirectingGenerative) {
- inlinedFrom(callee, () {
+ inlinedFrom(constructorRecolvedAst, () {
buildFieldInitializers(
callee.enclosingClass.implementation, fieldValues);
});
@@ -2019,7 +2026,7 @@
if (resolvedAst.kind == ResolvedAstKind.PARSED) {
localsHandler.enterScope(resolvedAst.node, callee);
}
- buildInitializers(callee, constructors, fieldValues);
+ buildInitializers(callee, constructorResolvedAsts, fieldValues);
localsHandler.closureData = oldClosureData;
resolvedAst = oldResolvedAst;
});
@@ -2027,24 +2034,26 @@
void buildInitializers(
ConstructorElement constructor,
- List<FunctionElement> constructors,
+ List<ResolvedAst> constructorResolvedAsts,
Map<Element, HInstruction> fieldValues) {
assert(invariant(
constructor, resolvedAst.element == constructor.declaration,
message: "Expected ResolvedAst for $constructor, found $resolvedAst"));
if (resolvedAst.kind == ResolvedAstKind.PARSED) {
- buildParsedInitializers(constructor, constructors, fieldValues);
+ buildParsedInitializers(
+ constructor, constructorResolvedAsts, fieldValues);
} else {
buildSynthesizedConstructorInitializers(
- constructor, constructors, fieldValues);
+ constructor, constructorResolvedAsts, fieldValues);
}
}
void buildSynthesizedConstructorInitializers(
ConstructorElement constructor,
- List<FunctionElement> constructors,
+ List<ResolvedAst> constructorResolvedAsts,
Map<Element, HInstruction> fieldValues) {
- assert(invariant(constructor, constructor.isSynthesized));
+ assert(invariant(constructor, constructor.isSynthesized,
+ message: "Unexpected unsynthesized constructor: $constructor"));
List<HInstruction> arguments = <HInstruction>[];
HInstruction compileArgument(ParameterElement parameter) {
return localsHandler.readLocal(parameter);
@@ -2069,8 +2078,8 @@
reporter.internalError(
constructor, 'forwarding constructor call does not match');
}
- inlineSuperOrRedirect(
- target, arguments, constructors, fieldValues, constructor);
+ inlineSuperOrRedirect(backend.frontend.getResolvedAst(target), arguments,
+ constructorResolvedAsts, fieldValues, constructor);
}
/**
@@ -2085,12 +2094,14 @@
*/
void buildParsedInitializers(
ConstructorElement constructor,
- List<FunctionElement> constructors,
+ List<ResolvedAst> constructorResolvedAsts,
Map<Element, HInstruction> fieldValues) {
+ assert(
+ invariant(constructor, resolvedAst.element == constructor.declaration));
assert(invariant(constructor, constructor.isImplementation));
assert(invariant(constructor, !constructor.isSynthesized,
message: "Unexpected synthesized constructor: $constructor"));
- ast.FunctionExpression functionNode = constructor.node;
+ ast.FunctionExpression functionNode = resolvedAst.node;
bool foundSuperOrRedirect = false;
if (functionNode.initializers != null) {
@@ -2110,18 +2121,22 @@
elements.getSelector(call).callStructure;
Link<ast.Node> arguments = call.arguments;
List<HInstruction> compiledArguments;
- inlinedFrom(constructor, () {
+ inlinedFrom(resolvedAst, () {
compiledArguments =
makeStaticArgumentList(callStructure, arguments, target);
});
- inlineSuperOrRedirect(target, compiledArguments, constructors,
- fieldValues, constructor);
+ inlineSuperOrRedirect(
+ backend.frontend.getResolvedAst(target.declaration),
+ compiledArguments,
+ constructorResolvedAsts,
+ fieldValues,
+ constructor);
} else {
// A field initializer.
ast.SendSet init = link.head;
Link<ast.Node> arguments = init.arguments;
assert(!arguments.isEmpty && arguments.tail.isEmpty);
- inlinedFrom(constructor, () {
+ inlinedFrom(resolvedAst, () {
visit(arguments.head);
});
fieldValues[elements[init]] = pop();
@@ -2149,7 +2164,11 @@
null,
handleConstantForOptionalParameter);
inlineSuperOrRedirect(
- target, arguments, constructors, fieldValues, constructor);
+ backend.frontend.getResolvedAst(target.declaration),
+ arguments,
+ constructorResolvedAsts,
+ fieldValues,
+ constructor);
}
}
}
@@ -2164,11 +2183,12 @@
ClassElement classElement, Map<Element, HInstruction> fieldValues) {
assert(invariant(classElement, classElement.isImplementation));
classElement.forEachInstanceField(
- (ClassElement enclosingClass, VariableElement member) {
+ (ClassElement enclosingClass, FieldElement member) {
if (compiler.elementHasCompileTimeError(member)) return;
reporter.withCurrentElement(member, () {
- ast.Node node = member.node;
- ast.Expression initializer = member.initializer;
+ ResolvedAst fieldResolvedAst = backend.frontend.getResolvedAst(member);
+ ast.Node node = fieldResolvedAst.node;
+ ast.Expression initializer = fieldResolvedAst.body;
if (initializer == null) {
// Unassigned fields of native classes are not initialized to
// prevent overwriting pre-initialized native properties.
@@ -2178,12 +2198,12 @@
} else {
ast.Node right = initializer;
ResolvedAst savedResolvedAst = resolvedAst;
- resolvedAst = backend.frontend.getResolvedAst(member);
+ resolvedAst = fieldResolvedAst;
// In case the field initializer uses closures, run the
// closure to class mapper.
compiler.closureToClassMapper
.computeClosureToClassMapping(resolvedAst);
- inlinedFrom(member, () => right.accept(this));
+ inlinedFrom(fieldResolvedAst, () => right.accept(this));
resolvedAst = savedResolvedAst;
fieldValues[member] = pop();
}
@@ -2200,13 +2220,18 @@
* - Call the constructor bodies, starting from the constructor(s) in the
* super class(es).
*/
- HGraph buildFactory(ConstructorElement functionElement) {
+ HGraph buildFactory(ResolvedAst resolvedAst) {
+ ConstructorElement functionElement = resolvedAst.element;
functionElement = functionElement.implementation;
ClassElement classElement = functionElement.enclosingClass.implementation;
bool isNativeUpgradeFactory =
backend.isNativeOrExtendsNative(classElement) &&
!backend.isJsInterop(classElement);
- ast.FunctionExpression function = functionElement.node;
+ ast.FunctionExpression function;
+ if (resolvedAst.kind == ResolvedAstKind.PARSED) {
+ function = resolvedAst.node;
+ }
+
// Note that constructors (like any other static function) do not need
// to deal with optional arguments. It is the callers job to provide all
// arguments as if they were positional.
@@ -2239,8 +2264,8 @@
// Analyze the constructor and all referenced constructors and collect
// initializers and constructor bodies.
- List<FunctionElement> constructors = <FunctionElement>[functionElement];
- buildInitializers(functionElement, constructors, fieldValues);
+ List<ResolvedAst> constructorResolvedAsts = <ResolvedAst>[resolvedAst];
+ buildInitializers(functionElement, constructorResolvedAsts, fieldValues);
// Call the JavaScript constructor with the fields as argument.
List<HInstruction> constructorArguments = <HInstruction>[];
@@ -2369,10 +2394,9 @@
// Generate calls to the constructor bodies.
HInstruction interceptor = null;
- for (int index = constructors.length - 1; index >= 0; index--) {
- FunctionElement constructor = constructors[index];
- assert(invariant(functionElement, constructor.isImplementation));
- ConstructorBodyElement body = getConstructorBody(constructor);
+ for (int index = constructorResolvedAsts.length - 1; index >= 0; index--) {
+ ResolvedAst constructorResolvedAst = constructorResolvedAsts[index];
+ ConstructorBodyElement body = getConstructorBody(constructorResolvedAst);
if (body == null) continue;
List bodyCallInputs = <HInstruction>[];
@@ -2385,8 +2409,7 @@
bodyCallInputs.add(interceptor);
}
bodyCallInputs.add(newObject);
- ResolvedAst resolvedAst = backend.frontend.getResolvedAst(constructor);
- ast.Node node = resolvedAst.node;
+ ast.Node node = constructorResolvedAst.node;
ClosureClassMap parameterClosureData =
compiler.closureToClassMapper.getMappingForNestedFunction(node);
@@ -2409,6 +2432,8 @@
}
// Type variables arguments must come after the box (if there is one).
+ ConstructorElement constructor =
+ constructorResolvedAst.element.implementation;
ClassElement currentClass = constructor.enclosingClass;
if (backend.classNeedsRti(currentClass)) {
// If [currentClass] needs RTI, we add the type variables as
@@ -7913,8 +7938,8 @@
stack.add(result);
}
- void doInline(FunctionElement function) {
- visitInlinedFunction(function);
+ void doInline(ResolvedAst resolvedAst) {
+ visitInlinedFunction(resolvedAst);
}
void emitReturn(HInstruction value, ast.Node node) {
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 5938e1c..8b9ab16 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -51,7 +51,7 @@
return new js.Fun(parameters, body, asyncModifier: asyncModifier)
.withSourceInformation(sourceInformationFactory
- .createBuilderForContext(resolvedAst.element)
+ .createBuilderForContext(resolvedAst)
.buildDeclaration(resolvedAst));
}
@@ -67,7 +67,7 @@
return measure(() {
compiler.tracer.traceGraph("codegen", graph);
SourceInformation sourceInformation = sourceInformationFactory
- .createBuilderForContext(work.element)
+ .createBuilderForContext(work.resolvedAst)
.buildDeclaration(work.resolvedAst);
SsaCodeGenerator codegen = new SsaCodeGenerator(backend, work);
codegen.visitGraph(graph);
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index c9a4c2a..3b119bd 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -198,6 +198,10 @@
HConstant result = constants[constant];
// TODO(johnniwinther): Support source information per constant reference.
if (result == null) {
+ if (!constant.isConstant) {
+ // We use `null` as the value for invalid constant expressions.
+ constant = const NullConstantValue();
+ }
TypeMask type = computeTypeMask(compiler, constant);
result = new HConstant.internal(constant, type)
..sourceInformation = sourceInformation;
diff --git a/pkg/compiler/lib/src/tree/nodes.dart b/pkg/compiler/lib/src/tree/nodes.dart
index ae8111b..d2e9d96 100644
--- a/pkg/compiler/lib/src/tree/nodes.dart
+++ b/pkg/compiler/lib/src/tree/nodes.dart
@@ -1076,6 +1076,7 @@
class FunctionExpression extends Expression with StoredTreeElementMixin {
final Node name;
+ final NodeList typeVariables;
/**
* List of VariableDefinitions or NodeList.
@@ -1092,8 +1093,16 @@
final Token getOrSet;
final AsyncModifier asyncModifier;
- FunctionExpression(this.name, this.parameters, this.body, this.returnType,
- this.modifiers, this.initializers, this.getOrSet, this.asyncModifier) {
+ FunctionExpression(
+ this.name,
+ this.typeVariables,
+ this.parameters,
+ this.body,
+ this.returnType,
+ this.modifiers,
+ this.initializers,
+ this.getOrSet,
+ this.asyncModifier) {
assert(modifiers != null);
}
@@ -1111,6 +1120,7 @@
if (modifiers != null) modifiers.accept(visitor);
if (returnType != null) returnType.accept(visitor);
if (name != null) name.accept(visitor);
+ if (typeVariables != null) typeVariables.accept(visitor);
if (parameters != null) parameters.accept(visitor);
if (initializers != null) initializers.accept(visitor);
if (asyncModifier != null) asyncModifier.accept(visitor);
@@ -1121,6 +1131,7 @@
if (modifiers != null) modifiers.accept1(visitor, arg);
if (returnType != null) returnType.accept1(visitor, arg);
if (name != null) name.accept1(visitor, arg);
+ if (typeVariables != null) typeVariables.accept1(visitor, arg);
if (parameters != null) parameters.accept1(visitor, arg);
if (initializers != null) initializers.accept1(visitor, arg);
if (asyncModifier != null) asyncModifier.accept1(visitor, arg);
@@ -3102,6 +3113,7 @@
// FunctionExpression.
get asyncModifier => null;
+ get typeVariables => null;
get parameters => null;
get body => null;
get returnType => null;
diff --git a/runtime/bin/log_android.cc b/runtime/bin/log_android.cc
index 6e5a621..9dbbf05 100644
--- a/runtime/bin/log_android.cc
+++ b/runtime/bin/log_android.cc
@@ -17,10 +17,18 @@
// it when we see a '\n'.
void Log::VPrint(const char* format, va_list args) {
+ // If we launch the DartVM inside "adb shell" we will only get messages
+ // (critical ones or not) if we print them to stdout/stderr.
+ // We also log using android's logging system.
+ vprintf(format, args);
__android_log_vprint(ANDROID_LOG_INFO, "Dart", format, args);
}
void Log::VPrintErr(const char* format, va_list args) {
+ // If we launch the DartVM inside "adb shell" we will only get messages
+ // (critical ones or not) if we print them to stdout/stderr.
+ // We also log using android's logging system.
+ vfprintf(stderr, format, args);
__android_log_vprint(ANDROID_LOG_ERROR, "Dart", format, args);
}
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 0ef6653..fb8b338 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -1417,9 +1417,9 @@
uint8_t* assembly_buffer = NULL;
intptr_t assembly_size = 0;
uint8_t* instructions_blob_buffer = NULL;
- intptr_t instructions_blob_size = NULL;
+ intptr_t instructions_blob_size = 0;
uint8_t* rodata_blob_buffer = NULL;
- intptr_t rodata_blob_size = NULL;
+ intptr_t rodata_blob_size = 0;
if (use_blobs) {
result = Dart_CreatePrecompiledSnapshotBlob(
&vm_isolate_buffer,
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index d10e066..33b61c6 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -354,8 +354,7 @@
}
-static RawInstance* CreateLibraryMirror(const Library& lib) {
- Thread* thread = Thread::Current();
+static RawInstance* CreateLibraryMirror(Thread* thread, const Library& lib) {
Zone* zone = thread->zone();
ASSERT(!lib.IsNull());
const Array& args = Array::Handle(zone, Array::New(3));
@@ -405,14 +404,15 @@
}
-static RawInstance* CreateLibraryDependencyMirror(const Instance& importer,
+static RawInstance* CreateLibraryDependencyMirror(Thread* thread,
+ const Instance& importer,
const Namespace& ns,
const LibraryPrefix& prefix,
const bool is_import,
const bool is_deferred) {
const Library& importee = Library::Handle(ns.library());
const Instance& importee_mirror =
- Instance::Handle(CreateLibraryMirror(importee));
+ Instance::Handle(CreateLibraryMirror(thread, importee));
if (importee_mirror.IsNull()) {
// Imported library is censored: censor the import.
return Instance::null();
@@ -462,7 +462,7 @@
if (!deferred_lib.Loaded()) {
return Instance::null();
}
- return CreateLibraryMirror(deferred_lib);
+ return CreateLibraryMirror(thread, deferred_lib);
}
@@ -483,7 +483,8 @@
for (intptr_t i = 0; i < ports.Length(); i++) {
ns ^= ports.At(i);
if (!ns.IsNull()) {
- dep = CreateLibraryDependencyMirror(lib_mirror, ns, prefix, true, false);
+ dep = CreateLibraryDependencyMirror(
+ thread, lib_mirror, ns, prefix, true, false);
if (!dep.IsNull()) {
deps.Add(dep);
}
@@ -494,7 +495,8 @@
ports = lib.exports();
for (intptr_t i = 0; i < ports.Length(); i++) {
ns ^= ports.At(i);
- dep = CreateLibraryDependencyMirror(lib_mirror, ns, prefix, false, false);
+ dep = CreateLibraryDependencyMirror(
+ thread, lib_mirror, ns, prefix, false, false);
if (!dep.IsNull()) {
deps.Add(dep);
}
@@ -511,8 +513,8 @@
for (intptr_t i = 0; i < ports.Length(); i++) {
ns ^= ports.At(i);
if (!ns.IsNull()) {
- dep = CreateLibraryDependencyMirror(lib_mirror, ns, prefix, true,
- prefix.is_deferred_load());
+ dep = CreateLibraryDependencyMirror(
+ thread, lib_mirror, ns, prefix, true, prefix.is_deferred_load());
if (!dep.IsNull()) {
deps.Add(dep);
}
@@ -578,7 +580,7 @@
const Library& root_library = Library::Handle(thread->zone(),
isolate->object_store()->root_library());
const Instance& root_library_mirror =
- Instance::Handle(CreateLibraryMirror(root_library));
+ Instance::Handle(CreateLibraryMirror(thread, root_library));
const Array& args = Array::Handle(Array::New(2));
args.SetAt(0, debug_name);
@@ -800,7 +802,7 @@
for (int i = 0; i < num_libraries; i++) {
library ^= libraries.At(i);
- library_mirror = CreateLibraryMirror(library);
+ library_mirror = CreateLibraryMirror(thread, library);
if (!library_mirror.IsNull() && library.Loaded()) {
library_mirrors.Add(library_mirror);
}
@@ -1931,7 +1933,7 @@
}
const Class& owner = Class::Handle(func.Owner());
if (owner.IsTopLevel()) {
- return CreateLibraryMirror(Library::Handle(owner.library()));
+ return CreateLibraryMirror(thread, Library::Handle(owner.library()));
}
AbstractType& type = AbstractType::Handle(owner.DeclarationType());
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 78835a4..8fdd7ba 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -226,6 +226,7 @@
if ((_libraries == null) || dirty) {
_libraries = new Map<Uri, LibraryMirror>.fromIterable(
_computeLibraries(), key: (e) => e.uri);
+ dirty = false;
}
return _libraries;
}
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index 9313ce1..01f6ad0 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -91,7 +91,8 @@
DEFINE_NATIVE_ENTRY(StringBase_substringUnchecked, 3) {
- const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
+ const String& receiver = String::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2));
@@ -163,7 +164,8 @@
DEFINE_NATIVE_ENTRY(StringBase_joinReplaceAllResult, 4) {
- const String& base = String::CheckedHandle(arguments->NativeArgAt(0));
+ const String& base = String::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(GrowableObjectArray,
matches_growable, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, length_obj, arguments->NativeArgAt(2));
@@ -251,7 +253,8 @@
}
DEFINE_NATIVE_ENTRY(OneByteString_substringUnchecked, 3) {
- const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
+ const String& receiver = String::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
ASSERT(receiver.IsOneByteString());
GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2));
@@ -303,7 +306,8 @@
DEFINE_NATIVE_ENTRY(OneByteString_allocateFromOneByteList, 3) {
- Instance& list = Instance::CheckedHandle(arguments->NativeArgAt(0));
+ Instance& list = Instance::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2));
@@ -406,7 +410,8 @@
DEFINE_NATIVE_ENTRY(TwoByteString_allocateFromTwoByteList, 3) {
- Instance& list = Instance::CheckedHandle(arguments->NativeArgAt(0));
+ Instance& list = Instance::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_obj, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, end_obj, arguments->NativeArgAt(2));
@@ -492,7 +497,8 @@
DEFINE_NATIVE_ENTRY(String_getHashCode, 1) {
- const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
+ const String& receiver = String::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
intptr_t hash_val = receiver.Hash();
ASSERT(hash_val > 0);
ASSERT(Smi::IsValid(hash_val));
@@ -501,7 +507,8 @@
DEFINE_NATIVE_ENTRY(String_getLength, 1) {
- const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
+ const String& receiver = String::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
return Smi::New(receiver.Length());
}
@@ -521,7 +528,8 @@
DEFINE_NATIVE_ENTRY(String_charAt, 2) {
- const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
+ const String& receiver = String::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1));
uint16_t value = StringValueAt(receiver, index);
return Symbols::FromCharCode(thread, static_cast<int32_t>(value));
@@ -530,7 +538,8 @@
// Returns the 16-bit UTF-16 code unit at the given index.
DEFINE_NATIVE_ENTRY(String_codeUnitAt, 2) {
- const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
+ const String& receiver = String::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1));
uint16_t value = StringValueAt(receiver, index);
return Smi::New(static_cast<intptr_t>(value));
@@ -538,21 +547,24 @@
DEFINE_NATIVE_ENTRY(String_concat, 2) {
- const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
+ const String& receiver = String::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(String, b, arguments->NativeArgAt(1));
return String::Concat(receiver, b);
}
DEFINE_NATIVE_ENTRY(String_toLowerCase, 1) {
- const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
+ const String& receiver = String::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
ASSERT(!receiver.IsNull());
return String::ToLowerCase(receiver);
}
DEFINE_NATIVE_ENTRY(String_toUpperCase, 1) {
- const String& receiver = String::CheckedHandle(arguments->NativeArgAt(0));
+ const String& receiver = String::CheckedHandle(zone,
+ arguments->NativeArgAt(0));
ASSERT(!receiver.IsNull());
return String::ToUpperCase(receiver);
}
diff --git a/runtime/vm/assembler_arm64_test.cc b/runtime/vm/assembler_arm64_test.cc
index d27358e..ba0d646 100644
--- a/runtime/vm/assembler_arm64_test.cc
+++ b/runtime/vm/assembler_arm64_test.cc
@@ -1687,8 +1687,6 @@
}
-
-
// Loading immediate values with the object pool.
ASSEMBLER_TEST_GENERATE(LoadImmediatePPSmall, assembler) {
__ SetupDartSP(kTestStackSpace);
diff --git a/runtime/vm/assembler_dbc_test.cc b/runtime/vm/assembler_dbc_test.cc
new file mode 100644
index 0000000..2941f20
--- /dev/null
+++ b/runtime/vm/assembler_dbc_test.cc
@@ -0,0 +1,709 @@
+// 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.
+
+#include "vm/globals.h"
+#if defined(TARGET_ARCH_DBC)
+
+#include "vm/assembler.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+static RawObject* ExecuteTest(const Code& code) {
+ Thread* thread = Thread::Current();
+ TransitionToGenerated transition(thread);
+ return Simulator::Current()->Call(
+ code,
+ Array::Handle(ArgumentsDescriptor::New(0)),
+ Array::Handle(Array::New(0)),
+ thread);
+}
+
+
+#define EXECUTE_TEST_CODE_INTPTR(code) \
+ Smi::Value(Smi::RawCast(ExecuteTest(code)))
+#define EXECUTE_TEST_CODE_BOOL(code) \
+ (Bool::RawCast(ExecuteTest(code)) == Bool::True().raw())
+#define EXECUTE_TEST_CODE_OBJECT(code) \
+ Object::Handle(ExecuteTest(code))
+
+#define __ assembler->
+
+
+ASSEMBLER_TEST_GENERATE(Simple, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(Simple, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+// - AddTOS; SubTOS; MulTOS; BitOrTOS; BitAndTOS; EqualTOS; LessThanTOS;
+// GreaterThanTOS;
+//
+// Smi fast-path for a corresponding method. Checks if SP[0] and SP[-1] are
+// both smis and result of SP[0] <op> SP[-1] is a smi - if this is true
+// then pops operands and pushes result on the stack and skips the next
+// instruction (which implements a slow path fallback).
+ASSEMBLER_TEST_GENERATE(AddTOS, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(-42)));
+ __ PushConstant(Smi::Handle(Smi::New(84)));
+ __ AddTOS();
+ __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(AddTOS, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(AddTOSOverflow, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(Smi::kMaxValue)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ AddTOS();
+ __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(AddTOSOverflow, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(AddTOSNonSmi, assembler) {
+ const String& numstr =
+ String::Handle(String::New("98765432198765432100", Heap::kOld));
+ __ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ AddTOS();
+ __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(AddTOSNonSmi, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(SubTOS, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(30)));
+ __ PushConstant(Smi::Handle(Smi::New(-12)));
+ __ SubTOS();
+ __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(SubTOS, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(SubTOSOverflow, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(Smi::kMinValue)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ SubTOS();
+ __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(SubTOSOverflow, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(SubTOSNonSmi, assembler) {
+ const String& numstr =
+ String::Handle(String::New("98765432198765432100", Heap::kOld));
+ __ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ SubTOS();
+ __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(SubTOSNonSmi, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(MulTOS, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(-6)));
+ __ PushConstant(Smi::Handle(Smi::New(-7)));
+ __ MulTOS();
+ __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(MulTOS, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(MulTOSOverflow, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(Smi::kMaxValue)));
+ __ PushConstant(Smi::Handle(Smi::New(-8)));
+ __ MulTOS();
+ __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(MulTOSOverflow, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(MulTOSNonSmi, assembler) {
+ const String& numstr =
+ String::Handle(String::New("98765432198765432100", Heap::kOld));
+ __ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ MulTOS();
+ __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(MulTOSNonSmi, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(BitOrTOS, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(0x22)));
+ __ PushConstant(Smi::Handle(Smi::New(0x08)));
+ __ BitOrTOS();
+ __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(BitOrTOS, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(BitOrTOSNonSmi, assembler) {
+ const String& numstr =
+ String::Handle(String::New("98765432198765432100", Heap::kOld));
+ __ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
+ __ PushConstant(Smi::Handle(Smi::New(0x08)));
+ __ BitOrTOS();
+ __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(BitOrTOSNonSmi, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(BitAndTOS, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(0x2a)));
+ __ PushConstant(Smi::Handle(Smi::New(0xaa)));
+ __ BitAndTOS();
+ __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(BitAndTOS, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(BitAndTOSNonSmi, assembler) {
+ const String& numstr =
+ String::Handle(String::New("98765432198765432100", Heap::kOld));
+ __ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
+ __ PushConstant(Smi::Handle(Smi::New(0x08)));
+ __ BitAndTOS();
+ __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(BitAndTOSNonSmi, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(EqualTOSTrue, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ EqualTOS();
+ __ PushConstant(Bool::False()); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(EqualTOSTrue, test) {
+ EXPECT(EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(EqualTOSFalse, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ PushConstant(Smi::Handle(Smi::New(-42)));
+ __ EqualTOS();
+ __ PushConstant(Bool::True()); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(EqualTOSFalse, test) {
+ EXPECT(!EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(EqualTOSNonSmi, assembler) {
+ const String& numstr =
+ String::Handle(String::New("98765432198765432100", Heap::kOld));
+ __ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
+ __ PushConstant(Smi::Handle(Smi::New(-42)));
+ __ EqualTOS();
+ __ PushConstant(Bool::True()); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(EqualTOSNonSmi, test) {
+ EXPECT(EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(LessThanTOSTrue, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(-42)));
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ LessThanTOS();
+ __ PushConstant(Bool::False()); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(LessThanTOSTrue, test) {
+ EXPECT(EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(LessThanTOSFalse, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ PushConstant(Smi::Handle(Smi::New(-42)));
+ __ LessThanTOS();
+ __ PushConstant(Bool::False()); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(LessThanTOSFalse, test) {
+ EXPECT(!EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(LessThanTOSNonSmi, assembler) {
+ const String& numstr =
+ String::Handle(String::New("98765432198765432100", Heap::kOld));
+ __ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
+ __ PushConstant(Smi::Handle(Smi::New(-42)));
+ __ LessThanTOS();
+ __ PushConstant(Bool::True()); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(LessThanTOSNonSmi, test) {
+ EXPECT(EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(GreaterThanTOSTrue, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ PushConstant(Smi::Handle(Smi::New(-42)));
+ __ GreaterThanTOS();
+ __ PushConstant(Bool::False()); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(GreaterThanTOSTrue, test) {
+ EXPECT(EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(GreaterThanTOSFalse, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(-42)));
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ GreaterThanTOS();
+ __ PushConstant(Bool::False()); // Should be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(GreaterThanTOSFalse, test) {
+ EXPECT(!EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(GreaterThanTOSNonSmi, assembler) {
+ const String& numstr =
+ String::Handle(String::New("98765432198765432100", Heap::kOld));
+ __ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
+ __ PushConstant(Smi::Handle(Smi::New(-42)));
+ __ GreaterThanTOS();
+ __ PushConstant(Bool::True()); // Shouldn't be skipped.
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(GreaterThanTOSNonSmi, test) {
+ EXPECT(EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+// - IfNeStrictTOS; IfEqStrictTOS; IfNeStrictNumTOS; IfEqStrictNumTOS
+//
+// Skips the next instruction unless the given condition holds. 'Num'
+// variants perform number check while non-Num variants just compare
+// RawObject pointers.
+//
+// Used to implement conditional jump:
+//
+// IfNeStrictTOS
+// Jump T ;; jump if not equal
+ASSEMBLER_TEST_GENERATE(IfNeStrictTOSTaken, assembler) {
+ Label branch_taken;
+ const Array& array1 = Array::Handle(Array::New(1, Heap::kOld));
+ const Array& array2 = Array::Handle(Array::New(2, Heap::kOld));
+ __ PushConstant(array1);
+ __ PushConstant(array2);
+ __ IfNeStrictTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(IfNeStrictTOSTaken, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfNeStrictTOSNotTaken, assembler) {
+ Label branch_taken;
+ const Array& array1 = Array::Handle(Array::New(1, Heap::kOld));
+ __ PushConstant(array1);
+ __ PushConstant(array1);
+ __ IfNeStrictTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+}
+
+ASSEMBLER_TEST_RUN(IfNeStrictTOSNotTaken, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+// TODO(zra): Also add tests that use Mint, Bignum.
+ASSEMBLER_TEST_GENERATE(IfNeStrictNumTOSTaken, assembler) {
+ Label branch_taken;
+ __ PushConstant(Smi::Handle(Smi::New(-1)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ IfNeStrictNumTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(IfNeStrictNumTOSTaken, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfNeStrictNumTOSNotTaken, assembler) {
+ Label branch_taken;
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ IfNeStrictNumTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+}
+
+ASSEMBLER_TEST_RUN(IfNeStrictNumTOSNotTaken, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfNeStrictNumTOSTakenDouble, assembler) {
+ Label branch_taken;
+ __ PushConstant(Double::Handle(Double::New(-1.0, Heap::kOld)));
+ __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld)));
+ __ IfNeStrictNumTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(IfNeStrictNumTOSTakenDouble, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfNeStrictNumTOSNotTakenDouble, assembler) {
+ Label branch_taken;
+ __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld)));
+ __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld)));
+ __ IfNeStrictNumTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+}
+
+ASSEMBLER_TEST_RUN(IfNeStrictNumTOSNotTakenDouble, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfEqStrictTOSTaken, assembler) {
+ Label branch_taken;
+ const Array& array1 = Array::Handle(Array::New(1, Heap::kOld));
+ __ PushConstant(array1);
+ __ PushConstant(array1);
+ __ IfEqStrictTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(IfEqStrictTOSTaken, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfEqStrictTOSNotTaken, assembler) {
+ Label branch_taken;
+ const Array& array1 = Array::Handle(Array::New(1, Heap::kOld));
+ const Array& array2 = Array::Handle(Array::New(2, Heap::kOld));
+ __ PushConstant(array1);
+ __ PushConstant(array2);
+ __ IfEqStrictTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+}
+
+ASSEMBLER_TEST_RUN(IfEqStrictTOSNotTaken, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+// TODO(zra): Also add tests that use Mint, Bignum.
+ASSEMBLER_TEST_GENERATE(IfEqStrictNumTOSTaken, assembler) {
+ Label branch_taken;
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ IfEqStrictNumTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(IfEqStrictNumTOSTaken, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfEqStrictNumTOSNotTaken, assembler) {
+ Label branch_taken;
+ __ PushConstant(Smi::Handle(Smi::New(-1)));
+ __ PushConstant(Smi::Handle(Smi::New(1)));
+ __ IfEqStrictNumTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(IfEqStrictNumTOSNotTaken, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfEqStrictNumTOSTakenDouble, assembler) {
+ Label branch_taken;
+ __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld)));
+ __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld)));
+ __ IfEqStrictNumTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(IfEqStrictNumTOSTakenDouble, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(IfEqStrictNumTOSNotTakenDouble, assembler) {
+ Label branch_taken;
+ __ PushConstant(Double::Handle(Double::New(-1.0, Heap::kOld)));
+ __ PushConstant(Double::Handle(Double::New(1.0, Heap::kOld)));
+ __ IfEqStrictNumTOS();
+ __ Jump(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(42)));
+ __ ReturnTOS();
+ __ Bind(&branch_taken);
+ __ PushConstant(Smi::Handle(Smi::New(0)));
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(IfEqStrictNumTOSNotTakenDouble, test) {
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+// - BooleanNegateTOS
+//
+// SP[0] = !SP[0]
+ASSEMBLER_TEST_GENERATE(BooleanNegateTOSTrue, assembler) {
+ __ PushConstant(Bool::True());
+ __ BooleanNegateTOS();
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(BooleanNegateTOSTrue, test) {
+ EXPECT(!EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(BooleanNegateTOSFalse, assembler) {
+ __ PushConstant(Bool::False());
+ __ BooleanNegateTOS();
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(BooleanNegateTOSFalse, test) {
+ EXPECT(EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+// - AssertBoolean A
+//
+// Assert that TOS is a boolean (A = 1) or that TOS is not null (A = 0).
+ASSEMBLER_TEST_GENERATE(AssertBooleanTrue, assembler) {
+ __ PushConstant(Bool::True());
+ __ AssertBoolean(1);
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(AssertBooleanTrue, test) {
+ EXPECT(EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(AssertBooleanFalse, assembler) {
+ __ PushConstant(Bool::False());
+ __ AssertBoolean(1);
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(AssertBooleanFalse, test) {
+ EXPECT(!EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(AssertBooleanNotNull, assembler) {
+ __ PushConstant(Bool::True());
+ __ AssertBoolean(0);
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(AssertBooleanNotNull, test) {
+ EXPECT(EXECUTE_TEST_CODE_BOOL(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(AssertBooleanFail1, assembler) {
+ __ PushConstant(Smi::Handle(Smi::New(37)));
+ __ AssertBoolean(1);
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(AssertBooleanFail1, test) {
+ EXPECT(EXECUTE_TEST_CODE_OBJECT(test->code()).IsError());
+}
+
+
+ASSEMBLER_TEST_GENERATE(AssertBooleanFail2, assembler) {
+ __ PushConstant(Object::null_object());
+ __ AssertBoolean(0);
+ __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(AssertBooleanFail2, test) {
+ EXPECT(EXECUTE_TEST_CODE_OBJECT(test->code()).IsError());
+}
+
+} // namespace dart
+
+#endif // defined(TARGET_ARCH_DBC)
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 97b8fc8..1d26af8 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1282,6 +1282,14 @@
if (FLAG_support_debugger && do_stacktrace) {
String& var_name = String::Handle();
Instance& var_value = Instance::Handle();
+ // Collecting the stack trace and accessing local variables
+ // of frames may trigger parsing of functions to compute
+ // variable descriptors of functions. Parsing may trigger
+ // code execution, e.g. to compute compile-time constants. Thus,
+ // disable FLAG_stacktrace_every during trace collection to prevent
+ // recursive stack trace collection.
+ intptr_t saved_stacktrace_every = FLAG_stacktrace_every;
+ FLAG_stacktrace_every = 0;
DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
intptr_t num_frames = stack->Length();
for (intptr_t i = 0; i < num_frames; i++) {
@@ -1294,6 +1302,7 @@
frame->VariableAt(v, &var_name, &unused, &unused, &var_value);
}
}
+ FLAG_stacktrace_every = saved_stacktrace_every;
}
const Error& error = Error::Handle(thread->HandleInterrupts());
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 55afac1..49796c1 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1444,9 +1444,14 @@
intptr_t osr_id) {
NOT_IN_PRODUCT(
VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId);
- const char* event_name = IsBackgroundCompilation()
- ? "BackgroundCompileOptimizedFunction"
- : "CompileOptimizedFunction";
+ const char* event_name;
+ if (osr_id != kNoOSRDeoptId) {
+ event_name = "CompileFunctionOptimizedOSR";
+ } else if (IsBackgroundCompilation()) {
+ event_name = "CompileFunctionOptimizedBackground";
+ } else {
+ event_name = "CompileFunctionOptimized";
+ }
TIMELINE_FUNCTION_COMPILATION_DURATION(thread, event_name, function);
) // !PRODUCT
@@ -1494,9 +1499,7 @@
const Function& function = Function::Handle(code.function());
ParsedFunction* parsed_function = new ParsedFunction(
Thread::Current(), Function::ZoneHandle(function.raw()));
- LocalVarDescriptors& var_descs =
- LocalVarDescriptors::Handle(code.var_descriptors());
- ASSERT(var_descs.IsNull());
+ ASSERT(code.var_descriptors() == Object::null());
// IsIrregexpFunction have eager var descriptors generation.
ASSERT(!function.IsIrregexpFunction());
// In background compilation, parser can produce 'errors": bailouts
@@ -1505,8 +1508,8 @@
if (setjmp(*jump.Set()) == 0) {
Parser::ParseFunction(parsed_function);
parsed_function->AllocateVariables();
- var_descs = parsed_function->node_sequence()->scope()->
- GetVarDescriptors(function);
+ const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle(
+ parsed_function->node_sequence()->scope()->GetVarDescriptors(function));
ASSERT(!var_descs.IsNull());
code.set_var_descriptors(var_descs);
} else {
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index 4eb7b1b..f4144d6 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -340,6 +340,8 @@
V(Move, A_X, reg, xeg, ___) \
V(Push, X, xeg, ___, ___) \
V(LoadConstant, A_D, reg, lit, ___) \
+ V(LoadClassId, A_D, reg, reg, ___) \
+ V(LoadClassIdTOS, 0, ___, ___, ___) \
V(PushConstant, D, lit, ___, ___) \
V(StoreLocal, X, xeg, ___, ___) \
V(PopLocal, X, xeg, ___, ___) \
diff --git a/runtime/vm/cpu_dbc.cc b/runtime/vm/cpu_dbc.cc
index 8fcff5b..0e61fbd 100644
--- a/runtime/vm/cpu_dbc.cc
+++ b/runtime/vm/cpu_dbc.cc
@@ -6,11 +6,12 @@
#if defined(TARGET_ARCH_DBC)
#include "vm/cpu.h"
+#include "vm/cpu_dbc.h"
+#include "vm/cpuinfo.h"
namespace dart {
-
void CPU::FlushICache(uword start, uword size) {
// Nothing to do.
}
@@ -21,6 +22,31 @@
}
+const char* HostCPUFeatures::hardware_ = NULL;
+#if defined(DEBUG)
+bool HostCPUFeatures::initialized_ = false;
+#endif
+
+void HostCPUFeatures::InitOnce() {
+ CpuInfo::InitOnce();
+ hardware_ = CpuInfo::GetCpuModel();
+#if defined(DEBUG)
+ initialized_ = true;
+#endif
+}
+
+
+void HostCPUFeatures::Cleanup() {
+ DEBUG_ASSERT(initialized_);
+#if defined(DEBUG)
+ initialized_ = false;
+#endif
+ ASSERT(hardware_ != NULL);
+ free(const_cast<char*>(hardware_));
+ hardware_ = NULL;
+ CpuInfo::Cleanup();
+}
+
} // namespace dart
#endif // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/cpu_dbc.h b/runtime/vm/cpu_dbc.h
index b437beb..486acdb 100644
--- a/runtime/vm/cpu_dbc.h
+++ b/runtime/vm/cpu_dbc.h
@@ -12,13 +12,33 @@
class HostCPUFeatures: public AllStatic {
public:
- static const char* hardware() { return "simdbc"; }
+ static void InitOnce();
+ static void Cleanup();
+
+ static const char* hardware() {
+ DEBUG_ASSERT(initialized_);
+ return hardware_;
+ }
+
+ private:
+ static const char* hardware_;
+#if defined(DEBUG)
+ static bool initialized_;
+#endif
};
class TargetCPUFeatures : public AllStatic {
public:
- static void InitOnce() {}
- static void Cleanup() {}
+ static void InitOnce() {
+ HostCPUFeatures::InitOnce();
+ }
+ static void Cleanup() {
+ HostCPUFeatures::Cleanup();
+ }
+
+ static const char* hardware() {
+ return CPU::Id();
+ }
static bool double_truncate_round_supported() {
return true;
diff --git a/runtime/vm/cpuinfo_test.cc b/runtime/vm/cpuinfo_test.cc
index 2b587f1..0b6113b 100644
--- a/runtime/vm/cpuinfo_test.cc
+++ b/runtime/vm/cpuinfo_test.cc
@@ -9,13 +9,11 @@
namespace dart {
-#if !defined(TARGET_ARCH_DBC)
UNIT_TEST_CASE(GetCpuModelTest) {
const char* cpumodel = CpuInfo::GetCpuModel();
EXPECT_NE(strlen(cpumodel), 0UL);
// caller is responsible for deleting the returned cpumodel string.
free(const_cast<char*>(cpumodel));
}
-#endif
} // namespace dart
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 3fe6df5..cd7dbde 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -207,6 +207,9 @@
if (vm_isolate_snapshot != NULL) {
NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(),
"VMIsolateSnapshot"));
+ if (instructions_snapshot != NULL) {
+ vm_isolate_->SetupInstructionsSnapshotPage(instructions_snapshot);
+ }
if (data_snapshot != NULL) {
vm_isolate_->SetupDataSnapshotPage(data_snapshot);
}
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 6afad63..3cb92b2 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1402,6 +1402,7 @@
// that inline the function that contains the newly created breakpoint.
// We currently don't have this info so we deoptimize all functions.
void Debugger::DeoptimizeWorld() {
+ BackgroundCompiler::Stop(isolate_);
DeoptimizeFunctionsOnStack();
// Iterate over all classes, deoptimize functions.
// TODO(hausner): Could possibly be combined with RemoveOptimizedCode()
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 69f7f16..0a78c7b 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -3451,8 +3451,6 @@
load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength);
return ReturnDefinition(load);
}
-#if !defined(TARGET_ARCH_DBC)
- // TODO(vegorov) add bytecode to support this method.
case MethodRecognizer::kClassIDgetID: {
LocalVariable* value_var =
node->scope()->LookupVariable(Symbols::Value(), true);
@@ -3460,7 +3458,6 @@
LoadClassIdInstr* load = new(Z) LoadClassIdInstr(value);
return ReturnDefinition(load);
}
-#endif
case MethodRecognizer::kGrowableArrayCapacity: {
Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos));
LoadFieldInstr* data_load = new(Z) LoadFieldInstr(
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 9d448ab..006053f 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -32,6 +32,10 @@
DEFINE_FLAG(bool, enable_simd_inline, true,
"Enable inlining of SIMD related method calls.");
+DEFINE_FLAG(bool, inline_smi_string_hashcode, true,
+ "Inline hashcode for Smi and one-byte strings in case of megamorphic call");
+DEFINE_FLAG(int, inline_smi_string_hashcode_ratio, 50,
+ "Minimal hotness (0..100) of one-byte-string before inlining its hashcode");
DEFINE_FLAG(int, min_optimization_counter_threshold, 5000,
"The minimum invocation count for a function.");
DEFINE_FLAG(int, optimization_counter_scale, 2000,
@@ -156,6 +160,31 @@
}
+// Returns true if OnebyteString is a frequent receiver class. We inline
+// Smi check as well, since a Smi check must be done anyway.
+// TODO(srdjan): Add check and code if Smi class is hot.
+bool FlowGraphCompiler::ShouldInlineSmiStringHashCode(const ICData& ic_data) {
+ if (!FLAG_inline_smi_string_hashcode ||
+ (ic_data.target_name() != Symbols::hashCode().raw())) {
+ return false;
+ }
+ // Precompiled code has no ICData, optimistically inline it.
+ if (ic_data.IsNull() || (ic_data.NumberOfChecks() == 0)) {
+ return true;
+ }
+ // Check if OneByteString is hot enough.
+ const ICData& ic_data_sorted =
+ ICData::Handle(ic_data.AsUnaryClassChecksSortedByCount());
+ ASSERT(ic_data_sorted.NumberOfChecks() > 0);
+ if (ic_data_sorted.GetReceiverClassIdAt(0) == kOneByteStringCid) {
+ const intptr_t total_count = ic_data_sorted.AggregateCount();
+ const intptr_t ratio = (ic_data_sorted.GetCountAt(0) * 100) / total_count;
+ return ratio > FLAG_inline_smi_string_hashcode_ratio;
+ }
+ return false;
+}
+
+
FlowGraphCompiler::FlowGraphCompiler(
Assembler* assembler,
FlowGraph* flow_graph,
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 586dbdb..f7aa76e 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -616,6 +616,8 @@
private:
friend class CheckStackOverflowSlowPath; // For pending_deoptimization_env_.
+ static bool ShouldInlineSmiStringHashCode(const ICData& ic_data);
+
void EmitFrameEntry();
void AddStaticCallTarget(const Function& function);
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 9c58044..34172891 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -1322,7 +1322,7 @@
// Load receiver into R0.
__ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
Label done;
- if (name.raw() == Symbols::hashCode().raw()) {
+ if (ShouldInlineSmiStringHashCode(ic_data)) {
Label megamorphic_call;
__ Comment("Inlined get:hashCode for Smi and OneByteString");
__ tst(R0, Operand(kSmiTagMask));
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index d62a23a..07cff9e 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -1303,7 +1303,7 @@
// Load receiver into R0.
__ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
Label done;
- if (name.raw() == Symbols::hashCode().raw()) {
+ if (ShouldInlineSmiStringHashCode(ic_data)) {
Label megamorphic_call;
__ Comment("Inlined get:hashCode for Smi and OneByteString");
__ tsti(R0, Immediate(kSmiTagMask));
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 8a7c349..30cff6b2 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1303,15 +1303,13 @@
// Load receiver into EBX.
__ movl(EBX, Address(ESP, (argument_count - 1) * kWordSize));
Label done;
- if (name.raw() == Symbols::hashCode().raw()) {
- Label try_onebytestring, megamorphic_call;
+ if (ShouldInlineSmiStringHashCode(ic_data)) {
+ Label megamorphic_call;
__ Comment("Inlined get:hashCode for Smi and OneByteString");
+ __ movl(EAX, EBX); // Move Smi hashcode to EAX.
__ testl(EBX, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, &try_onebytestring, Assembler::kNearJump); // Non-smi value.
- __ movl(EAX, EBX);
- __ jmp(&done, Assembler::kNearJump);
+ __ j(ZERO, &done, Assembler::kNearJump); // It is Smi, we are done.
- __ Bind(&try_onebytestring);
__ CompareClassId(EBX, kOneByteStringCid, EAX);
__ j(NOT_EQUAL, &megamorphic_call, Assembler::kNearJump);
__ movl(EAX, FieldAddress(EBX, String::hash_offset()));
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 9fa5d9f..c63f850 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -1330,15 +1330,13 @@
// Load receiver into T0,
__ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
Label done;
- if (name.raw() == Symbols::hashCode().raw()) {
- Label try_onebytestring, megamorphic_call;
+ if (ShouldInlineSmiStringHashCode(ic_data)) {
+ Label megamorphic_call;
__ Comment("Inlined get:hashCode for Smi and OneByteString");
__ andi(CMPRES1, T0, Immediate(kSmiTagMask));
- __ bne(CMPRES1, ZR, &try_onebytestring); // Not Smi.
- __ mov(V0, T0);
- __ b(&done);
+ __ beq(CMPRES1, ZR, &done); // Is Smi.
+ __ delay_slot()->mov(V0, T0); // Move Smi hashcode to V0.
- __ Bind(&try_onebytestring);
__ LoadClassId(CMPRES1, T0); // Class ID check.
__ BranchNotEqual(
CMPRES1, Immediate(kOneByteStringCid), &megamorphic_call);
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index def75aa..c8ce4f5 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1332,15 +1332,13 @@
// Load receiver into RDI.
__ movq(RDI, Address(RSP, (argument_count - 1) * kWordSize));
Label done;
- if (name.raw() == Symbols::hashCode().raw()) {
- Label try_onebytestring, megamorphic_call;
+ if (ShouldInlineSmiStringHashCode(ic_data)) {
+ Label megamorphic_call;
__ Comment("Inlined get:hashCode for Smi and OneByteString");
+ __ movq(RAX, RDI); // Move Smi hashcode to RAX.
__ testq(RDI, Immediate(kSmiTagMask));
- __ j(NOT_ZERO, &try_onebytestring, Assembler::kNearJump); // Non-smi value.
- __ movq(RAX, RDI);
- __ jmp(&done, Assembler::kNearJump);
+ __ j(ZERO, &done, Assembler::kNearJump); // It is Smi, we are done.
- __ Bind(&try_onebytestring);
__ CompareClassId(RDI, kOneByteStringCid);
__ j(NOT_EQUAL, &megamorphic_call, Assembler::kNearJump);
__ movq(RAX, FieldAddress(RDI, String::hash_offset()));
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 8accbf4..b4a5f3b 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -251,17 +251,8 @@
void FlowGraphTypePropagator::VisitCheckClassId(CheckClassIdInstr* check) {
- if (!check->Dependencies().IsNone()) {
- // TODO(vegorov): If check is affected by side-effect we can still propagate
- // the type further but not the cid.
- return;
- }
-
- LoadClassIdInstr* load_cid =
- check->value()->definition()->OriginalDefinition()->AsLoadClassId();
- if (load_cid != NULL) {
- SetCid(load_cid->object()->definition(), check->cid());
- }
+ // Can't propagate the type/cid because it may cause illegal code motion and
+ // we don't track dependencies in all places via redefinitions.
}
diff --git a/runtime/vm/hash_table.h b/runtime/vm/hash_table.h
index 15317a1..8408f23 100644
--- a/runtime/vm/hash_table.h
+++ b/runtime/vm/hash_table.h
@@ -85,23 +85,21 @@
class HashTable : public ValueObject {
public:
typedef KeyTraits Traits;
+ // Uses the passed in handles for all handle operations.
+ // 'Release' must be called at the end to obtain the final table
+ // after potential growth/shrinkage.
+ HashTable(Object* key, Smi* index, Array* data)
+ : key_handle_(key),
+ smi_handle_(index),
+ data_(data),
+ released_data_(NULL) {}
// Uses 'zone' for handle allocation. 'Release' must be called at the end
// to obtain the final table after potential growth/shrinkage.
HashTable(Zone* zone, RawArray* data)
- : zone_(zone),
- key_handle_(Object::Handle(zone_)),
- smi_handle_(Smi::Handle(zone_)),
- data_(&Array::Handle(zone_, data)),
+ : key_handle_(&Object::Handle(zone)),
+ smi_handle_(&Smi::Handle(zone)),
+ data_(&Array::Handle(zone, data)),
released_data_(NULL) {}
- // Like above, except uses current zone.
- explicit HashTable(RawArray* data)
- : zone_(Thread::Current()->zone()),
- key_handle_(Object::Handle(zone_)),
- smi_handle_(Smi::Handle(zone_)),
- data_(&Array::Handle(zone_, data)),
- released_data_(NULL) {
- ASSERT(!data_->IsNull());
- }
// Returns the final table. The handle is cleared when this HashTable is
// destroyed.
@@ -134,15 +132,15 @@
// Initializes an empty table.
void Initialize() const {
ASSERT(data_->Length() >= ArrayLengthForNumOccupied(0));
- smi_handle_ = Smi::New(0);
- data_->SetAt(kOccupiedEntriesIndex, smi_handle_);
- data_->SetAt(kDeletedEntriesIndex, smi_handle_);
+ *smi_handle_ = Smi::New(0);
+ data_->SetAt(kOccupiedEntriesIndex, *smi_handle_);
+ data_->SetAt(kDeletedEntriesIndex, *smi_handle_);
NOT_IN_PRODUCT(
- data_->SetAt(kNumGrowsIndex, smi_handle_);
- data_->SetAt(kNumLT5LookupsIndex, smi_handle_);
- data_->SetAt(kNumLT25LookupsIndex, smi_handle_);
- data_->SetAt(kNumGT25LookupsIndex, smi_handle_);
+ data_->SetAt(kNumGrowsIndex, *smi_handle_);
+ data_->SetAt(kNumLT5LookupsIndex, *smi_handle_);
+ data_->SetAt(kNumLT25LookupsIndex, *smi_handle_);
+ data_->SetAt(kNumGT25LookupsIndex, *smi_handle_);
) // !PRODUCT
for (intptr_t i = kHeaderSize; i < data_->Length(); ++i) {
@@ -171,8 +169,8 @@
NOT_IN_PRODUCT(UpdateCollisions(collisions);)
return -1;
} else if (!IsDeleted(probe)) {
- key_handle_ = GetKey(probe);
- if (KeyTraits::IsMatch(key, key_handle_)) {
+ *key_handle_ = GetKey(probe);
+ if (KeyTraits::IsMatch(key, *key_handle_)) {
NOT_IN_PRODUCT(UpdateCollisions(collisions);)
return probe;
}
@@ -210,8 +208,8 @@
deleted = probe;
}
} else {
- key_handle_ = GetKey(probe);
- if (KeyTraits::IsMatch(key, key_handle_)) {
+ *key_handle_ = GetKey(probe);
+ if (KeyTraits::IsMatch(key, *key_handle_)) {
*entry = probe;
NOT_IN_PRODUCT(UpdateCollisions(collisions);)
return true;
@@ -289,10 +287,10 @@
return GetSmiValueAt(kDeletedEntriesIndex);
}
Object& KeyHandle() const {
- return key_handle_;
+ return *key_handle_;
}
Smi& SmiHandle() const {
- return smi_handle_;
+ return *smi_handle_;
}
NOT_IN_PRODUCT(
@@ -376,24 +374,21 @@
intptr_t GetSmiValueAt(intptr_t index) const {
ASSERT(!data_->IsNull());
- ASSERT(Object::Handle(zone(), data_->At(index)).IsSmi());
+ ASSERT(!data_->At(index)->IsHeapObject());
return Smi::Value(Smi::RawCast(data_->At(index)));
}
void SetSmiValueAt(intptr_t index, intptr_t value) const {
- smi_handle_ = Smi::New(value);
- data_->SetAt(index, smi_handle_);
+ *smi_handle_ = Smi::New(value);
+ data_->SetAt(index, *smi_handle_);
}
void AdjustSmiValueAt(intptr_t index, intptr_t delta) const {
SetSmiValueAt(index, (GetSmiValueAt(index) + delta));
}
- Zone* zone() const { return zone_; }
-
- Zone* zone_;
- Object& key_handle_;
- Smi& smi_handle_;
+ Object* key_handle_;
+ Smi* smi_handle_;
// Exactly one of these is non-NULL, depending on whether Release was called.
Array* data_;
Array* released_data_;
@@ -408,9 +403,11 @@
public:
typedef HashTable<KeyTraits, kUserPayloadSize, 0> BaseTable;
static const intptr_t kPayloadSize = kUserPayloadSize;
- explicit UnorderedHashTable(RawArray* data) : BaseTable(data) {}
- UnorderedHashTable(Zone* zone, RawArray* data)
- : BaseTable(zone, data) {}
+ explicit UnorderedHashTable(RawArray* data)
+ : BaseTable(Thread::Current()->zone(), data) {}
+ UnorderedHashTable(Zone* zone, RawArray* data) : BaseTable(zone, data) {}
+ UnorderedHashTable(Object* key, Smi* value, Array* data)
+ : BaseTable(key, value, data) {}
// Note: Does not check for concurrent modification.
class Iterator {
public:
@@ -447,9 +444,12 @@
typedef HashTable<KeyTraits, kUserPayloadSize + 1, 1> BaseTable;
static const intptr_t kPayloadSize = kUserPayloadSize;
static const intptr_t kNextEnumIndex = BaseTable::kMetaDataIndex;
+ EnumIndexHashTable(Object* key, Smi* value, Array* data)
+ : BaseTable(key, value, data) {}
EnumIndexHashTable(Zone* zone, RawArray* data)
: BaseTable(zone, data) {}
- explicit EnumIndexHashTable(RawArray* data) : BaseTable(data) {}
+ explicit EnumIndexHashTable(RawArray* data)
+ : BaseTable(Thread::Current()->zone(), data) {}
// Note: Does not check for concurrent modification.
class Iterator {
public:
@@ -509,7 +509,7 @@
template<typename Table>
static RawArray* New(intptr_t initial_capacity,
Heap::Space space = Heap::kNew) {
- Table table(Array::New(
+ Table table(Thread::Current()->zone(), Array::New(
Table::ArrayLengthForNumOccupied(initial_capacity), space));
table.Initialize();
return table.Release().raw();
@@ -517,7 +517,7 @@
template<typename Table>
static RawArray* New(const Array& array) {
- Table table(array.raw());
+ Table table(Thread::Current()->zone(), array.raw());
table.Initialize();
return table.Release().raw();
}
@@ -590,8 +590,11 @@
template<typename BaseIterTable>
class HashMap : public BaseIterTable {
public:
- explicit HashMap(RawArray* data) : BaseIterTable(data) {}
+ explicit HashMap(RawArray* data)
+ : BaseIterTable(Thread::Current()->zone(), data) {}
HashMap(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
+ HashMap(Object* key, Smi* value, Array* data)
+ : BaseIterTable(key, value, data) {}
template<typename Key>
RawObject* GetOrNull(const Key& key, bool* present = NULL) const {
intptr_t entry = BaseIterTable::FindKey(key);
@@ -676,8 +679,11 @@
class UnorderedHashMap : public HashMap<UnorderedHashTable<KeyTraits, 1> > {
public:
typedef HashMap<UnorderedHashTable<KeyTraits, 1> > BaseMap;
- explicit UnorderedHashMap(RawArray* data) : BaseMap(data) {}
+ explicit UnorderedHashMap(RawArray* data)
+ : BaseMap(Thread::Current()->zone(), data) {}
UnorderedHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
+ UnorderedHashMap(Object* key, Smi* value, Array* data)
+ : BaseMap(key, value, data) {}
};
@@ -685,16 +691,22 @@
class EnumIndexHashMap : public HashMap<EnumIndexHashTable<KeyTraits, 1> > {
public:
typedef HashMap<EnumIndexHashTable<KeyTraits, 1> > BaseMap;
- explicit EnumIndexHashMap(RawArray* data) : BaseMap(data) {}
+ explicit EnumIndexHashMap(RawArray* data)
+ : BaseMap(Thread::Current()->zone(), data) {}
EnumIndexHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
+ EnumIndexHashMap(Object* key, Smi* value, Array* data)
+ : BaseMap(key, value, data) {}
};
template<typename BaseIterTable>
class HashSet : public BaseIterTable {
public:
- explicit HashSet(RawArray* data) : BaseIterTable(data) {}
+ explicit HashSet(RawArray* data)
+ : BaseIterTable(Thread::Current()->zone(), data) {}
HashSet(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
+ HashSet(Object* key, Smi* value, Array* data)
+ : BaseIterTable(key, value, data) {}
bool Insert(const Object& key) {
EnsureCapacity();
intptr_t entry = -1;
@@ -770,10 +782,13 @@
class UnorderedHashSet : public HashSet<UnorderedHashTable<KeyTraits, 0> > {
public:
typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet;
- explicit UnorderedHashSet(RawArray* data) : BaseSet(data) {
+ explicit UnorderedHashSet(RawArray* data)
+ : BaseSet(Thread::Current()->zone(), data) {
ASSERT(data != Array::null());
}
UnorderedHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
+ UnorderedHashSet(Object* key, Smi* value, Array* data)
+ : BaseSet(key, value, data) {}
};
@@ -781,8 +796,11 @@
class EnumIndexHashSet : public HashSet<EnumIndexHashTable<KeyTraits, 0> > {
public:
typedef HashSet<EnumIndexHashTable<KeyTraits, 0> > BaseSet;
- explicit EnumIndexHashSet(RawArray* data) : BaseSet(data) {}
+ explicit EnumIndexHashSet(RawArray* data)
+ : BaseSet(Thread::Current()->zone(), data) {}
EnumIndexHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
+ EnumIndexHashSet(Object* key, Smi* value, Array* data)
+ : BaseSet(key, value, data) {}
};
} // namespace dart
diff --git a/runtime/vm/hash_table_test.cc b/runtime/vm/hash_table_test.cc
index 8e0ac23..158af48 100644
--- a/runtime/vm/hash_table_test.cc
+++ b/runtime/vm/hash_table_test.cc
@@ -63,7 +63,7 @@
TEST_CASE(HashTable) {
typedef HashTable<TestTraits, 2, 1> Table;
- Table table(HashTables::New<Table>(5));
+ Table table(Thread::Current()->zone(), HashTables::New<Table>(5));
// Ensure that we did get at least 5 entries.
EXPECT_LE(5, table.NumEntries());
EXPECT_EQ(0, table.NumOccupied());
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 6fd3c3a..ef4e14c 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -369,6 +369,7 @@
void Heap::CollectNewSpaceGarbage(Thread* thread,
ApiCallbacks api_callbacks,
GCReason reason) {
+ ASSERT((reason == kNewSpace) || (reason == kFull));
if (BeginNewSpaceGC(thread)) {
bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
RecordBeforeGC(kNew, reason);
@@ -381,7 +382,7 @@
RecordAfterGC(kNew);
PrintStats();
EndNewSpaceGC();
- if (old_space_.NeedsGarbageCollection()) {
+ if ((reason == kNewSpace) && old_space_.NeedsGarbageCollection()) {
// Old collections should call the API callbacks.
CollectOldSpaceGarbage(thread, kInvokeApiCallbacks, kPromotion);
}
@@ -392,6 +393,7 @@
void Heap::CollectOldSpaceGarbage(Thread* thread,
ApiCallbacks api_callbacks,
GCReason reason) {
+ ASSERT((reason != kNewSpace));
if (BeginOldSpaceGC(thread)) {
bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
RecordBeforeGC(kOld, reason);
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index cc62146..204725c 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -13,6 +13,8 @@
#ifndef PRODUCT
+DEFINE_FLAG(bool, display_sorted_ic_data, false,
+ "Calls display a unary, sorted-by count form of ICData");
DEFINE_FLAG(bool, print_environments, false, "Print SSA environments.");
DEFINE_FLAG(charp, print_flow_graph_filter, NULL,
"Print only IR of functions with matching names");
@@ -191,7 +193,9 @@
}
-static void PrintICDataHelper(BufferFormatter* f, const ICData& ic_data) {
+static void PrintICDataHelper(BufferFormatter* f,
+ const ICData& ic_data,
+ intptr_t num_checks_to_print) {
f->Print(" IC[");
if (ic_data.HasRangeFeedback()) {
f->Print("{%s",
@@ -205,7 +209,11 @@
}
f->Print("%" Pd ": ", ic_data.NumberOfChecks());
Function& target = Function::Handle();
- for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
+ if ((num_checks_to_print == FlowGraphPrinter::kPrintAll) ||
+ (num_checks_to_print > ic_data.NumberOfChecks())) {
+ num_checks_to_print = ic_data.NumberOfChecks();
+ }
+ for (intptr_t i = 0; i < num_checks_to_print; i++) {
GrowableArray<intptr_t> class_ids;
ic_data.GetCheckAt(i, &class_ids, &target);
const intptr_t count = ic_data.GetCountAt(i);
@@ -222,14 +230,35 @@
}
f->Print(" cnt:%" Pd " trgt:'%s'", count, target.ToQualifiedCString());
}
+ if (num_checks_to_print < ic_data.NumberOfChecks()) {
+ f->Print("...");
+ }
f->Print("]");
}
-void FlowGraphPrinter::PrintICData(const ICData& ic_data) {
+static void PrintICDataSortedHelper(BufferFormatter* f,
+ const ICData& ic_data_orig) {
+ const ICData& ic_data =
+ ICData::Handle(ic_data_orig.AsUnaryClassChecksSortedByCount());
+ f->Print(" IC[n:%" Pd"; ", ic_data.NumberOfChecks());
+ for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
+ const intptr_t count = ic_data.GetCountAt(i);
+ const intptr_t cid = ic_data.GetReceiverClassIdAt(i);
+ const Class& cls =
+ Class::Handle(Isolate::Current()->class_table()->At(cid));
+ f->Print("%s : %" Pd ", ",
+ String::Handle(cls.Name()).ToCString(), count);
+ }
+ f->Print("]");
+}
+
+
+void FlowGraphPrinter::PrintICData(const ICData& ic_data,
+ intptr_t num_checks_to_print) {
char buffer[1024];
BufferFormatter f(buffer, sizeof(buffer));
- PrintICDataHelper(&f, ic_data);
+ PrintICDataHelper(&f, ic_data, num_checks_to_print);
THR_Print("%s ", buffer);
const Array& a = Array::Handle(ic_data.arguments_descriptor());
THR_Print(" arg-desc %" Pd "\n", a.Length());
@@ -435,7 +464,11 @@
PushArgumentAt(i)->value()->PrintTo(f);
}
if (HasICData()) {
- PrintICDataHelper(f, *ic_data());
+ if (FLAG_display_sorted_ic_data) {
+ PrintICDataSortedHelper(f, *ic_data());
+ } else {
+ PrintICDataHelper(f, *ic_data(), FlowGraphPrinter::kPrintAll);
+ }
}
}
@@ -446,7 +479,11 @@
f->Print(", ");
PushArgumentAt(i)->value()->PrintTo(f);
}
- PrintICDataHelper(f, ic_data());
+ if (FLAG_display_sorted_ic_data) {
+ PrintICDataSortedHelper(f, ic_data());
+ } else {
+ PrintICDataHelper(f, ic_data(), FlowGraphPrinter::kPrintAll);
+ }
if (with_checks()) {
f->Print(" WITH-CHECKS");
}
@@ -947,7 +984,11 @@
void CheckClassInstr::PrintOperandsTo(BufferFormatter* f) const {
value()->PrintTo(f);
- PrintICDataHelper(f, unary_checks());
+ if (FLAG_display_sorted_ic_data) {
+ PrintICDataSortedHelper(f, unary_checks());
+ } else {
+ PrintICDataHelper(f, unary_checks(), FlowGraphPrinter::kPrintAll);
+ }
if (IsNullCheck()) {
f->Print(" nullcheck");
}
@@ -1263,7 +1304,8 @@
}
-void FlowGraphPrinter::PrintICData(const ICData& ic_data) {
+void FlowGraphPrinter::PrintICData(const ICData& ic_data,
+ intptr_t num_checks_to_print) {
UNREACHABLE();
}
diff --git a/runtime/vm/il_printer.h b/runtime/vm/il_printer.h
index bc19c75..b800ab7 100644
--- a/runtime/vm/il_printer.h
+++ b/runtime/vm/il_printer.h
@@ -35,6 +35,8 @@
// Graph printing.
class FlowGraphPrinter : public ValueObject {
public:
+ static const intptr_t kPrintAll = -1;
+
FlowGraphPrinter(const FlowGraph& flow_graph,
bool print_locations = false)
: function_(flow_graph.function()),
@@ -57,8 +59,10 @@
static void PrintGraph(const char* phase, FlowGraph* flow_graph);
- // Debugging helper function.
- static void PrintICData(const ICData& ic_data);
+ // Debugging helper function. If 'num_checks_to_print' is not specified
+ // all checks will be printed.
+ static void PrintICData(const ICData& ic_data,
+ intptr_t num_checks_to_print = kPrintAll);
static bool ShouldPrint(const Function& function);
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
index 293d239..7c87f8e 100644
--- a/runtime/vm/intermediate_language_dbc.cc
+++ b/runtime/vm/intermediate_language_dbc.cc
@@ -108,15 +108,15 @@
M(UnboxInteger32) \
M(CheckedSmiOp) \
M(CheckArrayBound) \
- M(CheckSmi) \
- M(LoadClassId) \
- M(CheckClassId) \
- M(CheckClass) \
- M(BinarySmiOp) \
- M(TestSmi) \
- M(RelationalOp) \
- M(EqualityCompare) \
- M(LoadIndexed) \
+ M(CheckSmi) \
+ M(CheckClassId) \
+ M(CheckClass) \
+ M(BinarySmiOp) \
+ M(TestSmi) \
+ M(RelationalOp) \
+ M(EqualityCompare) \
+ M(LoadIndexed)
+
// Location summaries actually are not used by the unoptimizing DBC compiler
// because we don't allocate any registers.
static LocationSummary* CreateLocationSummary(Zone* zone,
@@ -238,6 +238,15 @@
}
+EMIT_NATIVE_CODE(LoadClassId, 1, true) {
+ if (compiler->is_optimizing()) {
+ __ LoadClassId(locs()->out(0).reg(), locs()->in(0).reg());
+ } else {
+ __ LoadClassIdTOS();
+ }
+}
+
+
EMIT_NATIVE_CODE(Constant, 0, true) {
const intptr_t kidx = __ AddConstant(value());
if (compiler->is_optimizing()) {
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 287079a..44127c5 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -934,6 +934,23 @@
}
+void Isolate::SetupInstructionsSnapshotPage(
+ const uint8_t* instructions_snapshot_buffer) {
+ InstructionsSnapshot snapshot(instructions_snapshot_buffer);
+#if defined(DEBUG)
+ if (FLAG_trace_isolates) {
+ OS::Print("Precompiled instructions are at [0x%" Px ", 0x%" Px ")\n",
+ reinterpret_cast<uword>(snapshot.instructions_start()),
+ reinterpret_cast<uword>(snapshot.instructions_start()) +
+ snapshot.instructions_size());
+ }
+#endif
+ heap_->SetupExternalPage(snapshot.instructions_start(),
+ snapshot.instructions_size(),
+ /* is_executable = */ true);
+}
+
+
void Isolate::SetupDataSnapshotPage(const uint8_t* data_snapshot_buffer) {
DataSnapshot snapshot(data_snapshot_buffer);
#if defined(DEBUG)
@@ -1386,6 +1403,12 @@
void Isolate::AddClosureFunction(const Function& function) const {
+ // TODO(regis): remove once debugging complete.
+ if (Compiler::IsBackgroundCompilation()) {
+ NOT_IN_PRODUCT(Profiler::DumpStackTrace(true /*native*/));
+ UNREACHABLE();
+ }
+ ASSERT(!Compiler::IsBackgroundCompilation());
GrowableObjectArray& closures =
GrowableObjectArray::Handle(object_store()->closure_functions());
ASSERT(!closures.IsNull());
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 8061619..c2fc955 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -228,6 +228,8 @@
library_tag_handler_ = value;
}
+ void SetupInstructionsSnapshotPage(
+ const uint8_t* instructions_snapshot_buffer);
void SetupDataSnapshotPage(
const uint8_t* instructions_snapshot_buffer);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index ff46fbf..6f48c92 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2714,12 +2714,12 @@
class CHACodeArray : public WeakCodeReferences {
public:
explicit CHACodeArray(const Class& cls)
- : WeakCodeReferences(Array::Handle(cls.cha_codes())), cls_(cls) {
+ : WeakCodeReferences(Array::Handle(cls.dependent_code())), cls_(cls) {
}
virtual void UpdateArrayTo(const Array& value) {
// TODO(fschneider): Fails for classes in the VM isolate.
- cls_.set_cha_codes(value);
+ cls_.set_dependent_code(value);
}
virtual void ReportDeoptimization(const Code& code) {
@@ -2871,8 +2871,8 @@
}
-void Class::set_cha_codes(const Array& cache) const {
- StorePointer(&raw_ptr()->cha_codes_, cache.raw());
+void Class::set_dependent_code(const Array& array) const {
+ StorePointer(&raw_ptr()->dependent_code_, array.raw());
}
@@ -6418,23 +6418,6 @@
Heap::Space space) const {
AbstractType& other_param_type =
AbstractType::Handle(other.ParameterTypeAt(other_parameter_position));
-
- // TODO(regis): Remove this debugging code.
- if (other_param_type.IsNull()) {
- const Class& owner = Class::Handle(Owner());
- const Class& other_owner = Class::Handle(other.Owner());
- THR_Print("*** null other_param_type ***\n");
- THR_Print("parameter_position: %" Pd "\n", parameter_position);
- THR_Print("other_parameter_position: %" Pd "\n", other_parameter_position);
- THR_Print("function: %s\n", ToCString());
- THR_Print("function owner: %s\n", owner.ToCString());
- THR_Print("other function: %s\n", other.ToCString());
- THR_Print("other function owner: %s\n", other_owner.ToCString());
- AbstractType& param_type =
- AbstractType::Handle(ParameterTypeAt(parameter_position));
- THR_Print("param_type: %s\n", param_type.ToCString());
- }
-
if (!other_param_type.IsInstantiated()) {
other_param_type =
other_param_type.InstantiateFrom(other_type_arguments,
@@ -6452,16 +6435,40 @@
// TODO(regis): Remove this debugging code.
if (param_type.IsNull()) {
- const Class& owner = Class::Handle(Owner());
- const Class& other_owner = Class::Handle(other.Owner());
THR_Print("*** null param_type ***\n");
THR_Print("parameter_position: %" Pd "\n", parameter_position);
THR_Print("other_parameter_position: %" Pd "\n", other_parameter_position);
- THR_Print("function: %s\n", ToCString());
+ String& str = String::Handle();
+ str = QualifiedScrubbedName();
+ THR_Print("function name: %s\n", str.ToCString());
+ str = other.QualifiedScrubbedName();
+ THR_Print("other function name: %s\n", str.ToCString());
+ Class& owner = Class::Handle();
+ owner = Owner();
THR_Print("function owner: %s\n", owner.ToCString());
- THR_Print("other function: %s\n", other.ToCString());
- THR_Print("other function owner: %s\n", other_owner.ToCString());
+ owner = other.Owner();
+ THR_Print("other function owner: %s\n", owner.ToCString());
THR_Print("other_param_type: %s\n", other_param_type.ToCString());
+ AbstractType& type = AbstractType::Handle();
+ if (parameter_position > 0) {
+ type = ParameterTypeAt(0);
+ THR_Print("receiver type: %s\n",
+ type.IsNull()? "null" : type.ToCString());
+ }
+ THR_Print("has code: %s\n", HasCode() ? "yes" : "no");
+ str = Report::PrependSnippet(Report::kWarning,
+ Script::Handle(script()),
+ token_pos(),
+ Report::AtLocation,
+ Symbols::Empty());
+ THR_Print("function source: %s\n", str.ToCString());
+ for (intptr_t i = 0; i < NumParameters(); i++) {
+ THR_Print("function param %" Pd "\n", i);
+ str = ParameterNameAt(i);
+ THR_Print(" name: %s\n", str.IsNull() ? "null" : str.ToCString());
+ type = ParameterTypeAt(i);
+ THR_Print(" type: %s\n", type.IsNull() ? "null" : type.ToCString());
+ }
}
if (!param_type.IsInstantiated()) {
@@ -13024,6 +13031,81 @@
}
+// (cid, count) tuple used to sort ICData by count.
+struct CidCount {
+ CidCount(intptr_t cid_, intptr_t count_, Function* f_)
+ : cid(cid_), count(count_), function(f_) {}
+
+ static int HighestCountFirst(const CidCount* a, const CidCount* b);
+
+ intptr_t cid;
+ intptr_t count;
+ Function* function;
+};
+
+
+int CidCount::HighestCountFirst(const CidCount* a, const CidCount* b) {
+ if (a->count > b->count) {
+ return -1;
+ }
+ return (a->count < b->count) ? 1 : 0;
+}
+
+
+RawICData* ICData::AsUnaryClassChecksSortedByCount() const {
+ ASSERT(!IsNull());
+ const intptr_t kNumArgsTested = 1;
+ const intptr_t len = NumberOfChecks();
+ if (len <= 1) {
+ // No sorting needed.
+ return AsUnaryClassChecks();
+ }
+ GrowableArray<CidCount> aggregate;
+ for (intptr_t i = 0; i < len; i++) {
+ const intptr_t class_id = GetClassIdAt(i, 0);
+ const intptr_t count = GetCountAt(i);
+ if (count == 0) {
+ continue;
+ }
+ bool found = false;
+ for (intptr_t r = 0; r < aggregate.length(); r++) {
+ if (aggregate[r].cid == class_id) {
+ aggregate[r].count += count;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ aggregate.Add(CidCount(class_id, count,
+ &Function::ZoneHandle(GetTargetAt(i))));
+ }
+ }
+ aggregate.Sort(CidCount::HighestCountFirst);
+
+ ICData& result = ICData::Handle(ICData::NewFrom(*this, kNumArgsTested));
+ ASSERT(result.NumberOfChecks() == 0);
+ // Room for all entries and the sentinel.
+ const intptr_t data_len =
+ result.TestEntryLength() * (aggregate.length() + 1);
+ const Array& data = Array::Handle(Array::New(data_len, Heap::kOld));
+ result.set_ic_data_array(data);
+ ASSERT(result.NumberOfChecks() == aggregate.length());
+
+ intptr_t pos = 0;
+ for (intptr_t i = 0; i < aggregate.length(); i++) {
+ data.SetAt(pos + 0, Smi::Handle(Smi::New(aggregate[i].cid)));
+ data.SetAt(pos + TargetIndexFor(1), *aggregate[i].function);
+ data.SetAt(pos + CountIndexFor(1),
+ Smi::Handle(Smi::New(aggregate[i].count)));
+
+ pos += result.TestEntryLength();
+ }
+ WriteSentinel(data, result.TestEntryLength());
+ result.set_ic_data_array(data);
+ return result.raw();
+}
+
+
bool ICData::AllTargetsHaveSameOwner(intptr_t owner_cid) const {
if (NumberOfChecks() == 0) return false;
Class& cls = Class::Handle();
@@ -13443,26 +13525,6 @@
}
-uword Code::EntryPoint() const {
- RawObject* instr = instructions();
- if (!instr->IsHeapObject()) {
- return active_entry_point();
- } else {
- return Instructions::EntryPoint(instructions());
- }
-}
-
-
-intptr_t Code::Size() const {
- RawObject* instr = instructions();
- if (!instr->IsHeapObject()) {
- return Smi::Value(raw_ptr()->precompiled_instructions_size_);
- } else {
- return instructions()->ptr()->size_;
- }
-}
-
-
bool Code::HasBreakpoint() const {
if (!FLAG_support_debugger) {
return false;
@@ -13808,13 +13870,10 @@
}
// Hook up Code and Instructions objects.
- code.set_instructions(instrs.raw());
code.SetActiveInstructions(instrs.raw());
+ code.set_instructions(instrs.raw());
code.set_is_alive(true);
- ASSERT(code.EntryPoint() == instrs.EntryPoint());
- ASSERT(code.Size() == instrs.size());
-
// Set object pool in Instructions object.
INC_STAT(Thread::Current(),
total_code_size, object_pool.Length() * sizeof(uintptr_t));
@@ -14017,10 +14076,9 @@
void Code::DisableDartCode() const {
DEBUG_ASSERT(IsMutatorOrAtSafepoint());
ASSERT(IsFunctionCode());
- ASSERT(!IsDisabled());
+ ASSERT(instructions() == active_instructions());
const Code& new_code =
Code::Handle(StubCode::FixCallersTarget_entry()->code());
- ASSERT(new_code.instructions()->IsVMHeapObject());
SetActiveInstructions(new_code.instructions());
}
@@ -14029,10 +14087,9 @@
#if !defined(TARGET_ARCH_DBC)
ASSERT(Thread::Current()->IsMutatorThread());
ASSERT(IsAllocationStubCode());
- ASSERT(!IsDisabled());
+ ASSERT(instructions() == active_instructions());
const Code& new_code =
Code::Handle(StubCode::FixAllocationStubTarget_entry()->code());
- ASSERT(new_code.instructions()->IsVMHeapObject());
SetActiveInstructions(new_code.instructions());
#else
// DBC does not use allocation stubs.
@@ -14045,6 +14102,7 @@
DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive());
// RawInstructions are never allocated in New space and hence a
// store buffer update is not needed here.
+ StorePointer(&raw_ptr()->active_instructions_, instructions);
StoreNonPointer(&raw_ptr()->entry_point_,
reinterpret_cast<uword>(instructions->ptr()) +
Instructions::HeaderSize());
@@ -19968,7 +20026,8 @@
}
-RawString* String::SubString(const String& str,
+RawString* String::SubString(Thread* thread,
+ const String& str,
intptr_t begin_index,
intptr_t length,
Heap::Space space) {
@@ -19981,7 +20040,6 @@
if (begin_index > str.Length()) {
return String::null();
}
- String& result = String::Handle();
bool is_one_byte_string = true;
intptr_t char_size = str.CharSize();
if (char_size == kTwoByteChar) {
@@ -19992,6 +20050,8 @@
}
}
}
+ REUSABLE_STRING_HANDLESCOPE(thread);
+ String& result = thread->StringHandle();
if (is_one_byte_string) {
result = OneByteString::New(length, space);
} else {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 53a22fc..564db72 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1386,8 +1386,11 @@
void DisableCHAOptimizedCode(const Class& subclass);
- RawArray* cha_codes() const { return raw_ptr()->cha_codes_; }
- void set_cha_codes(const Array& value) const;
+ // Return the list of code objects that were compiled using CHA of this class.
+ // These code objects will be invalidated if new subclasses of this class
+ // are finalized.
+ RawArray* dependent_code() const { return raw_ptr()->dependent_code_; }
+ void set_dependent_code(const Array& array) const;
bool TraceAllocation(Isolate* isolate) const;
void SetTraceAllocation(bool trace_allocation) const;
@@ -1960,6 +1963,12 @@
RawICData* AsUnaryClassChecksForCid(
intptr_t cid, const Function& target) const;
+ // Returns ICData with aggregated receiver count, sorted by highest count.
+ // Smi not first!! (the convention for ICData used in code generation is that
+ // Smi check is first)
+ // Used for printing and optimizations.
+ RawICData* AsUnaryClassChecksSortedByCount() const;
+
// Consider only used entries.
bool AllTargetsHaveSameOwner(intptr_t owner_cid) const;
bool AllReceiversAreNumbers() const;
@@ -3955,7 +3964,8 @@
FINAL_HEAP_OBJECT_IMPLEMENTATION(Instructions, Object);
friend class Class;
friend class Code;
- friend class InstructionsWriter;
+ friend class AssemblyInstructionsWriter;
+ friend class BlobInstructionsWriter;
};
@@ -4368,7 +4378,9 @@
class Code : public Object {
public:
- uword active_entry_point() const { return raw_ptr()->entry_point_; }
+ RawInstructions* active_instructions() const {
+ return raw_ptr()->active_instructions_;
+ }
RawInstructions* instructions() const { return raw_ptr()->instructions_; }
@@ -4398,15 +4410,20 @@
}
void set_is_alive(bool value) const;
- uword EntryPoint() const;
- intptr_t Size() const;
-
+ uword EntryPoint() const {
+ return Instructions::Handle(instructions()).EntryPoint();
+ }
+ intptr_t Size() const {
+ const Instructions& instr = Instructions::Handle(instructions());
+ return instr.size();
+ }
RawObjectPool* GetObjectPool() const {
return object_pool();
}
bool ContainsInstructionAt(uword addr) const {
- const uword offset = addr - EntryPoint();
- return offset < static_cast<uword>(Size());
+ const Instructions& instr = Instructions::Handle(instructions());
+ const uword offset = addr - instr.EntryPoint();
+ return offset < static_cast<uword>(instr.size());
}
// Returns true if there is a debugger breakpoint set in this code object.
@@ -4645,11 +4662,12 @@
void Enable() const {
if (!IsDisabled()) return;
ASSERT(Thread::Current()->IsMutatorThread());
+ ASSERT(instructions() != active_instructions());
SetActiveInstructions(instructions());
}
bool IsDisabled() const {
- return active_entry_point() != EntryPoint();
+ return instructions() != active_instructions();
}
private:
@@ -6125,6 +6143,8 @@
friend class Api; // For ValueFromRaw
friend class Class;
friend class Object;
+ friend class ReusableSmiHandleScope;
+ friend class Thread;
};
@@ -6569,6 +6589,13 @@
static RawString* SubString(const String& str,
intptr_t begin_index,
intptr_t length,
+ Heap::Space space = Heap::kNew) {
+ return SubString(Thread::Current(), str, begin_index, length, space);
+ }
+ static RawString* SubString(Thread* thread,
+ const String& str,
+ intptr_t begin_index,
+ intptr_t length,
Heap::Space space = Heap::kNew);
static RawString* Transform(int32_t (*mapping)(int32_t ch),
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 6404df4..80c6021 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -12012,6 +12012,11 @@
void Parser::CacheConstantValue(TokenPosition token_pos,
const Instance& value) {
+ if (current_function().kind() == RawFunction::kImplicitStaticFinalGetter) {
+ // Don't cache constants in initializer expressions. They get
+ // evaluated only once.
+ return;
+ }
ConstantPosKey key(String::Handle(Z, script_.url()), token_pos);
if (isolate()->object_store()->compile_time_constants() == Array::null()) {
const intptr_t kInitialConstMapSize = 16;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index ff32dcd..12d5234 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -709,9 +709,22 @@
RawArray* invocation_dispatcher_cache_; // Cache for dispatcher functions.
RawCode* allocation_stub_; // Stub code for allocation of instances.
RawGrowableObjectArray* direct_subclasses_; // Array of Class.
- RawArray* cha_codes_; // CHA optimized codes.
+ RawArray* dependent_code_; // CHA optimized codes.
RawObject** to() {
- return reinterpret_cast<RawObject**>(&ptr()->cha_codes_);
+ return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
+ }
+ RawObject** to_snapshot(Snapshot::Kind kind) {
+ switch (kind) {
+ case Snapshot::kCore:
+ case Snapshot::kScript:
+ case Snapshot::kAppWithJIT:
+ case Snapshot::kAppNoJIT:
+ return reinterpret_cast<RawObject**>(&ptr()->direct_subclasses_);
+ case Snapshot::kMessage:
+ break;
+ }
+ UNREACHABLE();
+ return NULL;
}
cpp_vtable handle_vtable_;
@@ -922,17 +935,17 @@
// restore the value back to the original initial value.
RawInstance* saved_value_; // Saved initial value - static fields.
} initializer_;
- RawArray* dependent_code_;
RawSmi* guarded_list_length_;
+ RawArray* dependent_code_;
RawObject** to() {
- return reinterpret_cast<RawObject**>(&ptr()->guarded_list_length_);
+ return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
}
RawObject** to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kCore:
case Snapshot::kScript:
- return to();
case Snapshot::kAppWithJIT:
+ return reinterpret_cast<RawObject**>(&ptr()->guarded_list_length_);
case Snapshot::kAppNoJIT:
return reinterpret_cast<RawObject**>(&ptr()->initializer_);
case Snapshot::kMessage:
@@ -1107,12 +1120,10 @@
uword entry_point_;
RawObject** from() {
- return reinterpret_cast<RawObject**>(&ptr()->instructions_);
+ return reinterpret_cast<RawObject**>(&ptr()->active_instructions_);
}
- union {
- RawInstructions* instructions_;
- RawSmi* precompiled_instructions_size_;
- };
+ RawInstructions* active_instructions_;
+ RawInstructions* instructions_;
RawObjectPool* object_pool_;
// If owner_ is Function::null() the owner is a regular stub.
// If owner_ is a Class the owner is the allocation stub for that class.
@@ -1630,8 +1641,8 @@
switch (kind) {
case Snapshot::kCore:
case Snapshot::kScript:
- return to();
case Snapshot::kAppWithJIT:
+ return reinterpret_cast<RawObject**>(&ptr()->imports_);
case Snapshot::kAppNoJIT:
return reinterpret_cast<RawObject**>(&ptr()->importer_);
case Snapshot::kMessage:
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 2b715b2..eec2523 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -78,7 +78,11 @@
cls.set_state_bits(reader->Read<uint16_t>());
// Set all the object fields.
- READ_OBJECT_FIELDS(cls, cls.raw()->from(), cls.raw()->to(), kAsReference);
+ READ_OBJECT_FIELDS(cls,
+ cls.raw()->from(),
+ cls.raw()->to_snapshot(kind),
+ kAsReference);
+ cls.StorePointer(&cls.raw_ptr()->dependent_code_, Array::null());
ASSERT(!cls.IsInFullSnapshot() || (Snapshot::IsFull(kind)));
} else {
cls ^= reader->ReadClassId(object_id);
@@ -130,7 +134,7 @@
// Write out all the object pointer fields.
SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitPointers(from(), to());
+ visitor.VisitPointers(from(), to_snapshot(kind));
} else {
if (writer->can_send_any_object() ||
writer->AllowObjectsInDartLibrary(ptr()->library_)) {
@@ -853,7 +857,7 @@
reader->AddBackRef(object_id, &field, kIsDeserialized);
// Set all non object fields.
- if (Snapshot::IncludesCode(kind)) {
+ if (kind == Snapshot::kAppNoJIT) {
field.set_token_pos(TokenPosition::kNoSource);
ASSERT(!FLAG_use_field_guards);
} else {
@@ -869,6 +873,7 @@
field.raw()->from(),
field.raw()->to_snapshot(kind),
kAsReference);
+ field.StorePointer(&field.raw_ptr()->dependent_code_, Array::null());
if (!FLAG_use_field_guards) {
field.set_guarded_cid(kDynamicCid);
@@ -898,7 +903,7 @@
writer->WriteTags(writer->GetObjectTags(this));
// Write out all the non object fields.
- if (!Snapshot::IncludesCode(kind)) {
+ if (kind != Snapshot::kAppNoJIT) {
writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
writer->Write<int32_t>(ptr()->guarded_cid_);
writer->Write<int32_t>(ptr()->is_nullable_);
@@ -913,7 +918,7 @@
writer->WriteObjectImpl(ptr()->type_, kAsReference);
// Write out the initial static value or field offset.
if (Field::StaticBit::decode(ptr()->kind_bits_)) {
- if (Snapshot::IncludesCode(kind)) {
+ if (kind == Snapshot::kAppNoJIT) {
// For precompiled static fields, the value was already reset and
// initializer_ now contains a Function.
writer->WriteObjectImpl(ptr()->value_.static_value_, kAsReference);
@@ -925,14 +930,12 @@
writer->WriteObjectImpl(ptr()->value_.offset_, kAsReference);
}
// Write out the initializer function or saved initial value.
- if (Snapshot::IncludesCode(kind)) {
+ if (kind == Snapshot::kAppNoJIT) {
writer->WriteObjectImpl(ptr()->initializer_.precompiled_, kAsReference);
} else {
writer->WriteObjectImpl(ptr()->initializer_.saved_value_, kAsReference);
}
- if (!Snapshot::IncludesCode(kind)) {
- // Write out the dependent code.
- writer->WriteObjectImpl(ptr()->dependent_code_, kAsReference);
+ if (kind != Snapshot::kAppNoJIT) {
// Write out the guarded list length.
writer->WriteObjectImpl(ptr()->guarded_list_length_, kAsReference);
}
@@ -1253,12 +1256,12 @@
prefix.raw()->from(),
prefix.raw()->to_snapshot(kind),
kAsReference);
- if (Snapshot::IncludesCode(kind)) {
+ if (kind == Snapshot::kAppNoJIT) {
prefix.StorePointer(&prefix.raw_ptr()->imports_,
Array::null());
- prefix.StorePointer(&prefix.raw_ptr()->dependent_code_,
- Array::null());
}
+ prefix.StorePointer(&prefix.raw_ptr()->dependent_code_,
+ Array::null());
return prefix.raw();
}
@@ -1358,20 +1361,24 @@
result.set_lazy_deopt_pc_offset(-1);
int32_t text_offset = reader->Read<int32_t>();
- int32_t instructions_size = reader->Read<int32_t>();
- uword entry_point = reader->GetInstructionsAt(text_offset);
+ RawInstructions* instr = reinterpret_cast<RawInstructions*>(
+ reader->GetInstructionsAt(text_offset) + kHeapObjectTag);
+ uword entry_point = Instructions::EntryPoint(instr);
#if defined(DEBUG)
+ ASSERT(instr->IsMarked());
+ ASSERT(instr->IsVMHeapObject());
uword expected_check = reader->Read<uword>();
+ intptr_t instructions_size = Utils::RoundUp(instr->size_,
+ OS::PreferredCodeAlignment());
uword actual_check = Checksum(entry_point, instructions_size);
ASSERT(expected_check == actual_check);
#endif
result.StoreNonPointer(&result.raw_ptr()->entry_point_, entry_point);
- result.StorePointer(reinterpret_cast<RawSmi*const*>(
- &result.raw_ptr()->instructions_),
- Smi::New(instructions_size));
+ result.StorePointer(&result.raw_ptr()->active_instructions_, instr);
+ result.StorePointer(&result.raw_ptr()->instructions_, instr);
(*reader->PassiveObjectHandle()) ^= reader->ReadObjectImpl(kAsReference);
result.StorePointer(reinterpret_cast<RawObject*const*>(
@@ -1415,9 +1422,6 @@
result.StorePointer(&result.raw_ptr()->return_address_metadata_,
Object::null());
- ASSERT(result.Size() == instructions_size);
- ASSERT(result.EntryPoint() == entry_point);
-
return result.raw();
}
@@ -1446,14 +1450,18 @@
// Write out all the non object fields.
writer->Write<int32_t>(ptr()->state_bits_);
+ // No disabled code in precompilation.
+ ASSERT(ptr()->instructions_ == ptr()->active_instructions_);
+
RawInstructions* instr = ptr()->instructions_;
- intptr_t size = instr->ptr()->size_;
int32_t text_offset = writer->GetInstructionsId(instr, this);
writer->Write<int32_t>(text_offset);
- writer->Write<int32_t>(size);
+
#if defined(DEBUG)
uword entry = ptr()->entry_point_;
- uword check = Checksum(entry, size);
+ intptr_t instructions_size = Utils::RoundUp(instr->size_,
+ OS::PreferredCodeAlignment());
+ uword check = Checksum(entry, instructions_size);
writer->Write<uword>(check);
#endif
diff --git a/runtime/vm/reusable_handles.h b/runtime/vm/reusable_handles.h
index beae36b..25e5154 100644
--- a/runtime/vm/reusable_handles.h
+++ b/runtime/vm/reusable_handles.h
@@ -110,6 +110,8 @@
ReusableObjectHandleScope reused_object_handle(thread);
#define REUSABLE_PC_DESCRIPTORS_HANDLESCOPE(thread) \
ReusablePcDescriptorsHandleScope reused_pc_descriptors_handle(thread);
+#define REUSABLE_SMI_HANDLESCOPE(thread) \
+ ReusableSmiHandleScope reused_smi_handle(thread);
#define REUSABLE_STRING_HANDLESCOPE(thread) \
ReusableStringHandleScope reused_string_handle(thread);
#define REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread) \
diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc
index 9cbe84a..4b1e550 100644
--- a/runtime/vm/scanner.cc
+++ b/runtime/vm/scanner.cc
@@ -329,11 +329,13 @@
// We did not read a keyword.
current_token_.kind = Token::kIDENT;
- String& literal =
- String::ZoneHandle(Z, Symbols::New(T, source_, ident_pos, ident_length));
+ String& literal = String::ZoneHandle(Z);
if (ident_char0 == Library::kPrivateIdentifierStart) {
// Private identifiers are mangled on a per library basis.
+ literal = String::SubString(T, source_, ident_pos, ident_length);
literal = Symbols::FromConcat(T, literal, private_key_);
+ } else {
+ literal = Symbols::New(T, source_, ident_pos, ident_length);
}
current_token_.literal = &literal;
}
diff --git a/runtime/vm/signal_handler.h b/runtime/vm/signal_handler.h
index b204c55..ecdfe02 100644
--- a/runtime/vm/signal_handler.h
+++ b/runtime/vm/signal_handler.h
@@ -36,6 +36,17 @@
};
#endif
+
+// Old linux kernels on ARM might require a trampoline to
+// work around incorrect Thumb -> ARM transitions. See SignalHandlerTrampoline
+// below for more details.
+#if defined(HOST_ARCH_ARM) && \
+ (defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID)) && \
+ !defined(__thumb__)
+#define USE_SIGNAL_HANDLER_TRAMPOLINE
+#endif
+
+
namespace dart {
typedef void (*SignalAction)(int signal, siginfo_t* info,
@@ -43,17 +54,68 @@
class SignalHandler : public AllStatic {
public:
- static void Install(SignalAction action);
+ template<SignalAction action>
+ static void Install() {
+#if defined(USE_SIGNAL_HANDLER_TRAMPOLINE)
+ InstallImpl(SignalHandlerTrampoline<action>);
+#else
+ InstallImpl(action);
+#endif // defined(USE_SIGNAL_HANDLER_TRAMPOLINE)
+ }
static void Remove();
static uintptr_t GetProgramCounter(const mcontext_t& mcontext);
static uintptr_t GetFramePointer(const mcontext_t& mcontext);
static uintptr_t GetCStackPointer(const mcontext_t& mcontext);
static uintptr_t GetDartStackPointer(const mcontext_t& mcontext);
static uintptr_t GetLinkRegister(const mcontext_t& mcontext);
+
private:
+ static void InstallImpl(SignalAction action);
+
+#if defined(USE_SIGNAL_HANDLER_TRAMPOLINE)
+ // Work around for a bug in old kernels (only fixed in 3.18 Android kernel):
+ //
+ // Kernel does not clear If-Then execution state bits when entering ARM signal
+ // handler which violates requirements imposed by ARM architecture reference.
+ // Some CPUs look at these bits even while in ARM mode which causes them
+ // to skip some instructions in the prologue of the signal handler.
+ //
+ // To work around the issue we insert enough NOPs in the prologue to ensure
+ // that no actual instructions are skipped and then branch to the actual
+ // signal handler.
+ //
+ // For the kernel patch that fixes the issue see: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6ecf830e5029598732e04067e325d946097519cb
+ //
+ // Note: this function is marked "naked" because we must guarantee that
+ // our NOPs occur before any compiler generated prologue.
+ template <SignalAction action>
+ static __attribute__((naked)) void SignalHandlerTrampoline(int signal,
+ siginfo_t* info,
+ void* context_) {
+ // IT (If-Then) instruction makes up to four instructions that follow it
+ // conditional.
+ asm volatile("nop; nop; nop; nop" : : : "memory");
+
+ // Tail-call into the actual signal handler.
+ // Note: this code is split into a separate inline assembly block because
+ // any code that compiler generates to satisfy register constraints must
+ // be generated after four NOPs.
+ register int arg0 asm("r0") = signal;
+ register siginfo_t* arg1 asm("r1") = info;
+ register void* arg2 asm("r2") = context_;
+ asm volatile("bx %3"
+ :
+ : "r"(arg0), "r"(arg1), "r"(arg2),
+ "r"(action)
+ : "memory");
+ }
+#endif // defined(USE_SIGNAL_HANDLER_TRAMPOLINE)
};
+#undef USE_SIGNAL_HANDLER_TRAMPOLINE
+
+
} // namespace dart
#endif // VM_SIGNAL_HANDLER_H_
diff --git a/runtime/vm/signal_handler_android.cc b/runtime/vm/signal_handler_android.cc
index d41eb59..64670de 100644
--- a/runtime/vm/signal_handler_android.cc
+++ b/runtime/vm/signal_handler_android.cc
@@ -100,7 +100,7 @@
}
-void SignalHandler::Install(SignalAction action) {
+void SignalHandler::InstallImpl(SignalAction action) {
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_sigaction = action;
diff --git a/runtime/vm/signal_handler_linux.cc b/runtime/vm/signal_handler_linux.cc
index b49f90a..1df46f0 100644
--- a/runtime/vm/signal_handler_linux.cc
+++ b/runtime/vm/signal_handler_linux.cc
@@ -99,7 +99,7 @@
}
-void SignalHandler::Install(SignalAction action) {
+void SignalHandler::InstallImpl(SignalAction action) {
struct sigaction act;
act.sa_handler = NULL;
act.sa_sigaction = action;
diff --git a/runtime/vm/signal_handler_macos.cc b/runtime/vm/signal_handler_macos.cc
index ca6e64d..bfcc42c 100644
--- a/runtime/vm/signal_handler_macos.cc
+++ b/runtime/vm/signal_handler_macos.cc
@@ -102,7 +102,7 @@
}
-void SignalHandler::Install(SignalAction action) {
+void SignalHandler::InstallImpl(SignalAction action) {
struct sigaction act;
act.sa_handler = NULL;
act.sa_sigaction = action;
diff --git a/runtime/vm/signal_handler_win.cc b/runtime/vm/signal_handler_win.cc
index e3164f4..bb6b92d 100644
--- a/runtime/vm/signal_handler_win.cc
+++ b/runtime/vm/signal_handler_win.cc
@@ -38,7 +38,7 @@
}
-void SignalHandler::Install(SignalAction action) {
+void SignalHandler::InstallImpl(SignalAction action) {
UNIMPLEMENTED();
}
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 7329114..d9ff04e 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -1634,6 +1634,18 @@
BYTECODE(AssertAssignable, A_D); // Stack: instance, type args, type, name
RawObject** args = SP - 3;
if (args[0] != null_value) {
+ const AbstractType& dst_type =
+ AbstractType::Handle(static_cast<RawAbstractType*>(args[2]));
+ if (dst_type.IsMalformedOrMalbounded()) {
+ SP[1] = args[0]; // instance.
+ SP[2] = args[3]; // name.
+ SP[3] = args[2]; // type.
+ Exit(thread, FP, SP + 4, pc);
+ NativeArguments args(thread, 3, SP + 1, SP - 3);
+ INVOKE_RUNTIME(DRT_BadTypeError, args);
+ UNREACHABLE();
+ }
+
RawSubtypeTestCache* cache =
static_cast<RawSubtypeTestCache*>(LOAD_CONSTANT(rD));
if (cache != null_value) {
@@ -1778,6 +1790,21 @@
}
{
+ BYTECODE(LoadClassId, A_D);
+ const uint16_t object_reg = rD;
+ RawObject* obj = static_cast<RawObject*>(FP[object_reg]);
+ FP[rA] = SimulatorHelpers::GetClassIdAsSmi(obj);
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(LoadClassIdTOS, 0);
+ RawObject* obj = static_cast<RawObject*>(SP[0]);
+ SP[0] = SimulatorHelpers::GetClassIdAsSmi(obj);
+ DISPATCH();
+ }
+
+ {
BYTECODE(StoreIndexedTOS, 0);
SP -= 3;
RawArray* array = static_cast<RawArray*>(SP[1]);
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 6107c53..2f2ca6a 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -1160,13 +1160,9 @@
}
#endif
- intptr_t payload_size = instructions->ptr()->size_;
- payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment());
-
+ intptr_t heap_size = instructions->Size();
intptr_t offset = next_offset_;
- ASSERT(Utils::IsAligned(next_offset_, OS::PreferredCodeAlignment()));
- next_offset_ += payload_size;
- ASSERT(Utils::IsAligned(next_offset_, OS::PreferredCodeAlignment()));
+ next_offset_ += heap_size;
instructions_.Add(InstructionsData(instructions, code, offset));
return offset;
@@ -1235,7 +1231,32 @@
ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0);
- // 1. Write a label at the entry point.
+ // 1. Write from the header to the entry point.
+ {
+ NoSafepointScope no_safepoint;
+
+ uword beginning = reinterpret_cast<uword>(insns.raw_ptr());
+ uword entry = beginning + Instructions::HeaderSize();
+
+ ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t)));
+ ASSERT(Utils::IsAligned(entry, sizeof(uint64_t)));
+
+ // Write Instructions with the mark and VM heap bits set.
+ uword marked_tags = insns.raw_ptr()->tags_;
+ marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags);
+ marked_tags = RawObject::MarkBit::update(true, marked_tags);
+
+ WriteWordLiteral(marked_tags);
+ beginning += sizeof(uword);
+
+ for (uword* cursor = reinterpret_cast<uword*>(beginning);
+ cursor < reinterpret_cast<uword*>(entry);
+ cursor++) {
+ WriteWordLiteral(*cursor);
+ }
+ }
+
+ // 2. Write a label at the entry point.
owner = code.owner();
if (owner.IsNull()) {
const char* name = StubCode::NameOfStub(insns.EntryPoint());
@@ -1255,7 +1276,7 @@
}
{
- // 2. Write from the entry point to the end.
+ // 3. Write from the entry point to the end.
NoSafepointScope no_safepoint;
uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag;
uword entry = beginning + Instructions::HeaderSize();
@@ -1342,8 +1363,33 @@
for (intptr_t i = 0; i < instructions_.length(); i++) {
const Instructions& insns = *instructions_[i].insns_;
+ // 1. Write from the header to the entry point.
{
- // 2. Write from the entry point to the end.
+ NoSafepointScope no_safepoint;
+
+ uword beginning = reinterpret_cast<uword>(insns.raw_ptr());
+ uword entry = beginning + Instructions::HeaderSize();
+
+ ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t)));
+ ASSERT(Utils::IsAligned(entry, sizeof(uint64_t)));
+
+ // Write Instructions with the mark and VM heap bits set.
+ uword marked_tags = insns.raw_ptr()->tags_;
+ marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags);
+ marked_tags = RawObject::MarkBit::update(true, marked_tags);
+
+ instructions_blob_stream_.WriteWord(marked_tags);
+ beginning += sizeof(uword);
+
+ for (uword* cursor = reinterpret_cast<uword*>(beginning);
+ cursor < reinterpret_cast<uword*>(entry);
+ cursor++) {
+ instructions_blob_stream_.WriteWord(*cursor);
+ }
+ }
+
+ // 2. Write from the entry point to the end.
+ {
NoSafepointScope no_safepoint;
uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag;
uword entry = beginning + Instructions::HeaderSize();
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index aac196b..28636b8 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -69,10 +69,10 @@
void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
-#if !defined(TARGET_ARCH_DBC)
ASSERT(thread() == Thread::Current());
// Visit objects between SP and (FP - callee_save_area).
ASSERT(visitor != NULL);
+#if !defined(TARGET_ARCH_DBC)
RawObject** first = reinterpret_cast<RawObject**>(sp());
RawObject** last = reinterpret_cast<RawObject**>(
fp() + (kExitLinkSlotFromEntryFp - 1) * kWordSize);
@@ -87,6 +87,8 @@
void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
+ ASSERT(thread() == Thread::Current());
+ ASSERT(visitor != NULL);
#if !defined(TARGET_ARCH_DBC)
// NOTE: This code runs while GC is in progress and runs within
// a NoHandleScope block. Hence it is not ok to use regular Zone or
@@ -94,8 +96,6 @@
// these handles are not traversed. The use of handles is mainly to
// be able to reuse the handle based code and avoid having to add
// helper functions to the raw object interface.
- ASSERT(thread() == Thread::Current());
- ASSERT(visitor != NULL);
NoSafepointScope no_safepoint;
Code code;
code = LookupDartCode();
@@ -109,7 +109,8 @@
Array maps;
maps = Array::null();
Stackmap map;
- const uword entry = code.EntryPoint();
+ const uword entry = reinterpret_cast<uword>(code.instructions()->ptr()) +
+ Instructions::HeaderSize();
map = code.GetStackmap(pc() - entry, &maps, &map);
if (!map.IsNull()) {
RawObject** first = reinterpret_cast<RawObject**>(sp());
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index 04d6088..a138437 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -11,6 +11,7 @@
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/raw_object.h"
+#include "vm/reusable_handles.h"
#include "vm/snapshot_ids.h"
#include "vm/unicode.h"
#include "vm/visitor.h"
@@ -602,18 +603,25 @@
// StringType can be StringSlice, ConcatString, or {Latin1,UTF16,UTF32}Array.
template<typename StringType>
RawString* Symbols::NewSymbol(Thread* thread, const StringType& str) {
- Zone* zone = thread->zone();
- String& symbol = String::Handle(zone);
+ REUSABLE_OBJECT_HANDLESCOPE(thread);
+ REUSABLE_SMI_HANDLESCOPE(thread);
+ REUSABLE_ARRAY_HANDLESCOPE(thread);
+ String& symbol = String::Handle(thread->zone());
+ dart::Object& key = thread->ObjectHandle();
+ Smi& value = thread->SmiHandle();
+ Array& data = thread->ArrayHandle();
{
Isolate* vm_isolate = Dart::vm_isolate();
- SymbolTable table(zone, vm_isolate->object_store()->symbol_table());
+ data ^= vm_isolate->object_store()->symbol_table();
+ SymbolTable table(&key, &value, &data);
symbol ^= table.GetOrNull(str);
table.Release();
}
if (symbol.IsNull()) {
Isolate* isolate = thread->isolate();
SafepointMutexLocker ml(isolate->symbols_mutex());
- SymbolTable table(zone, isolate->object_store()->symbol_table());
+ data ^= isolate->object_store()->symbol_table();
+ SymbolTable table(&key, &value, &data);
symbol ^= table.InsertNewOrGet(str);
isolate->object_store()->set_symbol_table(table.Release());
}
@@ -625,18 +633,25 @@
template<typename StringType>
RawString* Symbols::Lookup(Thread* thread, const StringType& str) {
- Isolate* isolate = thread->isolate();
- Zone* zone = thread->zone();
- String& symbol = String::Handle(zone);
+ REUSABLE_OBJECT_HANDLESCOPE(thread);
+ REUSABLE_SMI_HANDLESCOPE(thread);
+ REUSABLE_ARRAY_HANDLESCOPE(thread);
+ String& symbol = String::Handle(thread->zone());
+ dart::Object& key = thread->ObjectHandle();
+ Smi& value = thread->SmiHandle();
+ Array& data = thread->ArrayHandle();
{
Isolate* vm_isolate = Dart::vm_isolate();
- SymbolTable table(zone, vm_isolate->object_store()->symbol_table());
+ data ^= vm_isolate->object_store()->symbol_table();
+ SymbolTable table(&key, &value, &data);
symbol ^= table.GetOrNull(str);
table.Release();
}
if (symbol.IsNull()) {
+ Isolate* isolate = thread->isolate();
SafepointMutexLocker ml(isolate->symbols_mutex());
- SymbolTable table(zone, isolate->object_store()->symbol_table());
+ data ^= isolate->object_store()->symbol_table();
+ SymbolTable table(&key, &value, &data);
symbol ^= table.GetOrNull(str);
table.Release();
}
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 4a21cc5..2201f36 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -45,6 +45,7 @@
class RawGrowableObjectArray;
class RawString;
class RuntimeEntry;
+class Smi;
class StackResource;
class String;
class TypeArguments;
@@ -65,6 +66,7 @@
V(Library) \
V(Object) \
V(PcDescriptors) \
+ V(Smi) \
V(String) \
V(TypeArguments) \
V(TypeParameter) \
diff --git a/runtime/vm/thread_interrupter_android.cc b/runtime/vm/thread_interrupter_android.cc
index 82be148..58f302f 100644
--- a/runtime/vm/thread_interrupter_android.cc
+++ b/runtime/vm/thread_interrupter_android.cc
@@ -57,8 +57,8 @@
void ThreadInterrupter::InstallSignalHandler() {
- SignalHandler::Install(
- ThreadInterrupterAndroid::ThreadInterruptSignalHandler);
+ SignalHandler::Install<
+ ThreadInterrupterAndroid::ThreadInterruptSignalHandler>();
}
diff --git a/runtime/vm/thread_interrupter_linux.cc b/runtime/vm/thread_interrupter_linux.cc
index 28ec681..4eb07f4 100644
--- a/runtime/vm/thread_interrupter_linux.cc
+++ b/runtime/vm/thread_interrupter_linux.cc
@@ -54,7 +54,8 @@
void ThreadInterrupter::InstallSignalHandler() {
- SignalHandler::Install(ThreadInterrupterLinux::ThreadInterruptSignalHandler);
+ SignalHandler::Install<
+ ThreadInterrupterLinux::ThreadInterruptSignalHandler>();
}
diff --git a/runtime/vm/thread_interrupter_macos.cc b/runtime/vm/thread_interrupter_macos.cc
index e46dbc7..222a294 100644
--- a/runtime/vm/thread_interrupter_macos.cc
+++ b/runtime/vm/thread_interrupter_macos.cc
@@ -55,7 +55,8 @@
void ThreadInterrupter::InstallSignalHandler() {
- SignalHandler::Install(ThreadInterrupterMacOS::ThreadInterruptSignalHandler);
+ SignalHandler::Install<
+ ThreadInterrupterMacOS::ThreadInterruptSignalHandler>();
}
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 24064f0..54352e5 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -210,9 +210,19 @@
void AssemblerTest::Assemble() {
const String& function_name = String::ZoneHandle(
Symbols::New(Thread::Current(), name_));
+
+ // We make a dummy script so that exception objects can be composed for
+ // assembler instructions that do runtime calls, in particular on DBC.
+ const char* kDummyScript = "assembler_test_dummy_function() {}";
+ const Script& script = Script::Handle(Script::New(
+ function_name,
+ String::Handle(String::New(kDummyScript)),
+ RawScript::kSourceTag));
+ script.Tokenize(String::Handle());
+
const Class& cls = Class::ZoneHandle(
Class::New(function_name,
- Script::Handle(),
+ script,
TokenPosition::kMinSource));
const Library& lib = Library::ZoneHandle(Library::New(function_name));
cls.set_library(lib);
@@ -221,6 +231,8 @@
true, false, false, false, false, cls,
TokenPosition::kMinSource));
code_ = Code::FinalizeCode(function, assembler_);
+ code_.set_owner(function);
+ code_.set_exception_handlers(Object::empty_exception_handlers());
if (FLAG_disassemble) {
OS::Print("Code for test '%s' {\n", name_);
const Instructions& instructions =
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index f170ffc..60f4057 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -201,7 +201,7 @@
bit_cast<int32_t, uword>(entry), \
bit_cast<int32_t, intptr_t>(pointer_arg), \
0, 0, 0))
-#endif
+#endif // defined(ARCH_IS_64_BIT)
#define EXECUTE_TEST_CODE_INT64_LL(name, entry, long_arg0, long_arg1) \
static_cast<int64_t>(Simulator::Current()->Call( \
bit_cast<int32_t, uword>(entry), \
@@ -224,7 +224,7 @@
Utils::High32Bits(bit_cast<int64_t, double>(double_arg)), \
0, 0, false, true))
#endif // defined(HOST_ARCH_ARM) || defined(HOST_ARCH_MIPS)
-#endif // defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
+#endif // defined(TARGET_ARCH_{ARM, ARM64, MIPS})
inline Dart_Handle NewString(const char* str) {
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index fa053a3..d51185b 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -21,6 +21,7 @@
'assembler_arm64_test.cc',
'assembler_dbc.cc',
'assembler_dbc.h',
+ 'assembler_dbc_test.cc',
'assembler_ia32.cc',
'assembler_ia32.h',
'assembler_ia32_test.cc',
diff --git a/sdk/bin/dart2js.bat b/sdk/bin/dart2js.bat
index 19f9ddb..d1a4095 100644
--- a/sdk/bin/dart2js.bat
+++ b/sdk/bin/dart2js.bat
@@ -57,7 +57,7 @@
for %%i in (%1) do set result=%%~fi
set current=
for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
- ^| find "> %~n1 ["`) do (
+ ^| %SystemRoot%\System32\find.exe "> %~n1 ["`) do (
set current=%%i
)
if not "%current%"=="" call :follow_links "%current%", result
diff --git a/sdk/bin/dartanalyzer.bat b/sdk/bin/dartanalyzer.bat
index a73427e..0f33752 100644
--- a/sdk/bin/dartanalyzer.bat
+++ b/sdk/bin/dartanalyzer.bat
@@ -67,7 +67,7 @@
for %%i in (%1) do set result=%%~fi
set current=
for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
- ^| find "> %~n1 ["`) do (
+ ^| %SystemRoot%\System32\find.exe "> %~n1 ["`) do (
set current=%%i
)
if not "%current%"=="" call :follow_links "%current%", result
diff --git a/sdk/bin/dartdoc.bat b/sdk/bin/dartdoc.bat
index c313e7f..880ae55 100644
--- a/sdk/bin/dartdoc.bat
+++ b/sdk/bin/dartdoc.bat
@@ -34,7 +34,7 @@
for %%i in (%1) do set result=%%~fi
set current=
for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
- ^| find "> %~n1 ["`) do (
+ ^| %SystemRoot%\System32\find.exe "> %~n1 ["`) do (
set current=%%i
)
if not "%current%"=="" call :follow_links "%current%", result
diff --git a/sdk/bin/dartfmt.bat b/sdk/bin/dartfmt.bat
index 321efe5..f063221 100644
--- a/sdk/bin/dartfmt.bat
+++ b/sdk/bin/dartfmt.bat
@@ -54,7 +54,7 @@
for %%i in (%1) do set result=%%~fi
set current=
for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
- ^| find "> %~n1 ["`) do (
+ ^| %SystemRoot%\System32\find.exe "> %~n1 ["`) do (
set current=%%i
)
if not "%current%"=="" call :follow_links "%current%", result
diff --git a/sdk/bin/pub.bat b/sdk/bin/pub.bat
index 06ba5f3..2b8f94b 100644
--- a/sdk/bin/pub.bat
+++ b/sdk/bin/pub.bat
@@ -47,7 +47,7 @@
for %%i in (%1) do set result=%%~fi
set current=
for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
- ^| find "> %~n1 ["`) do (
+ ^| %SystemRoot%\System32\find.exe "> %~n1 ["`) do (
set current=%%i
)
if not "%current%"=="" call :follow_links "%current%", result
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index b5ad1e8..9004574 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -20,7 +20,8 @@
patch_startup,
Primitives,
readHttp,
- stringJoinUnchecked;
+ stringJoinUnchecked,
+ getTraceFromException;
import 'dart:_foreign_helper' show JS;
@@ -743,16 +744,14 @@
@patch
@NoInline()
static StackTrace get current {
- var error = JS('', 'new Error()');
- var stack = JS('String|Null', '#.stack', error);
- if (stack is String) return new StackTrace.fromString(stack);
if (JS('', 'Error.captureStackTrace') != null) {
+ var error = JS('', 'new Error()');
JS('void', 'Error.captureStackTrace(#)', error);
- var stack = JS('String|Null', '#.stack', error);
- if (stack is String) return new StackTrace.fromString(stack);
+ return getTraceFromException(error);
}
+ // Fallback if Error.captureStackTrace does not exist.
try {
- throw 0;
+ throw '';
} catch (_, stackTrace) {
return stackTrace;
}
diff --git a/sdk/lib/async/async_error.dart b/sdk/lib/async/async_error.dart
index 650d503..2f3419e 100644
--- a/sdk/lib/async/async_error.dart
+++ b/sdk/lib/async/async_error.dart
@@ -14,11 +14,13 @@
}
}
-Function _registerErrorHandler(Function errorHandler, Zone zone) {
+Function _registerErrorHandler/*<R>*/(Function errorHandler, Zone zone) {
if (errorHandler is ZoneBinaryCallback) {
- return zone.registerBinaryCallback(errorHandler);
+ return zone.registerBinaryCallback/*<R, dynamic, StackTrace>*/(
+ errorHandler as dynamic/*=ZoneBinaryCallback<R, dynamic, StackTrace>*/);
} else {
- return zone.registerUnaryCallback(errorHandler);
+ return zone.registerUnaryCallback/*<R, dynamic>*/(
+ errorHandler as dynamic/*=ZoneUnaryCallback<R, dynamic>*/);
}
}
diff --git a/sdk/lib/async/broadcast_stream_controller.dart b/sdk/lib/async/broadcast_stream_controller.dart
index a926f1d..c34ec9f 100644
--- a/sdk/lib/async/broadcast_stream_controller.dart
+++ b/sdk/lib/async/broadcast_stream_controller.dart
@@ -5,18 +5,13 @@
part of dart.async;
class _BroadcastStream<T> extends _ControllerStream<T> {
- _BroadcastStream(_StreamControllerLifecycle controller) : super(controller);
+ _BroadcastStream(_StreamControllerLifecycle<T> controller)
+ : super(controller);
bool get isBroadcast => true;
}
-abstract class _BroadcastSubscriptionLink {
- _BroadcastSubscriptionLink _next;
- _BroadcastSubscriptionLink _previous;
-}
-
-class _BroadcastSubscription<T> extends _ControllerSubscription<T>
- implements _BroadcastSubscriptionLink {
+class _BroadcastSubscription<T> extends _ControllerSubscription<T> {
static const int _STATE_EVENT_ID = 1;
static const int _STATE_FIRING = 2;
static const int _STATE_REMOVE_AFTER_FIRING = 4;
@@ -25,10 +20,10 @@
// does not assume that it's use of the state integer is the only use.
int _eventState = 0; // Initialized to help dart2js type inference.
- _BroadcastSubscriptionLink _next;
- _BroadcastSubscriptionLink _previous;
+ _BroadcastSubscription<T> _next;
+ _BroadcastSubscription<T> _previous;
- _BroadcastSubscription(_StreamControllerLifecycle controller,
+ _BroadcastSubscription(_StreamControllerLifecycle<T> controller,
void onData(T data),
Function onError,
void onDone(),
@@ -37,8 +32,6 @@
_next = _previous = this;
}
- _BroadcastStreamController get _controller => super._controller;
-
bool _expectsEvent(int eventId) =>
(_eventState & _STATE_EVENT_ID) == eventId;
@@ -70,7 +63,6 @@
abstract class _BroadcastStreamController<T>
implements StreamController<T>,
_StreamControllerLifecycle<T>,
- _BroadcastSubscriptionLink,
_EventSink<T>,
_EventDispatch<T> {
static const int _STATE_INITIAL = 0;
@@ -86,8 +78,8 @@
int _state;
// Double-linked list of active listeners.
- _BroadcastSubscriptionLink _next;
- _BroadcastSubscriptionLink _previous;
+ _BroadcastSubscription<T> _firstSubscription;
+ _BroadcastSubscription<T> _lastSubscription;
// Extra state used during an [addStream] call.
_AddStreamState<T> _addStreamState;
@@ -108,9 +100,7 @@
_Future _doneFuture;
_BroadcastStreamController(this.onListen, this.onCancel)
- : _state = _STATE_INITIAL {
- _next = _previous = this;
- }
+ : _state = _STATE_INITIAL;
ControllerCallback get onPause {
throw new UnsupportedError(
@@ -158,7 +148,7 @@
*/
bool get _hasOneListener {
assert(!_isEmpty);
- return identical(_next._next, this);
+ return identical(_firstSubscription, _lastSubscription);
}
/** Whether an event is being fired (sent to some, but not all, listeners). */
@@ -175,26 +165,42 @@
// Linked list helpers
- bool get _isEmpty => identical(_next, this);
+ bool get _isEmpty => _firstSubscription == null;
/** Adds subscription to linked list of active listeners. */
void _addListener(_BroadcastSubscription<T> subscription) {
assert(identical(subscription._next, subscription));
- // Insert in linked list just before `this`.
- subscription._previous = _previous;
- subscription._next = this;
- this._previous._next = subscription;
- this._previous = subscription;
subscription._eventState = (_state & _STATE_EVENT_ID);
+ // Insert in linked list as last subscription.
+ _BroadcastSubscription<T> oldLast = _lastSubscription;
+ _lastSubscription = subscription;
+ subscription._next = null;
+ subscription._previous = oldLast;
+ if (oldLast == null) {
+ _firstSubscription = subscription;
+ } else {
+ oldLast._next = subscription;
+ }
}
void _removeListener(_BroadcastSubscription<T> subscription) {
assert(identical(subscription._controller, this));
assert(!identical(subscription._next, subscription));
- _BroadcastSubscriptionLink previous = subscription._previous;
- _BroadcastSubscriptionLink next = subscription._next;
- previous._next = next;
- next._previous = previous;
+ _BroadcastSubscription<T> previous = subscription._previous;
+ _BroadcastSubscription<T> next = subscription._next;
+ if (previous == null) {
+ // This was the first subscription.
+ _firstSubscription = next;
+ } else {
+ previous._next = next;
+ }
+ if (next == null) {
+ // This was the last subscription.
+ _lastSubscription = previous;
+ } else {
+ next._previous = previous;
+ }
+
subscription._next = subscription._previous = subscription;
}
@@ -209,25 +215,24 @@
if (onDone == null) onDone = _nullDoneHandler;
return new _DoneStreamSubscription<T>(onDone);
}
- StreamSubscription subscription =
+ StreamSubscription<T> subscription =
new _BroadcastSubscription<T>(this, onData, onError, onDone,
cancelOnError);
_addListener(subscription);
- if (identical(_next, _previous)) {
+ if (identical(_firstSubscription, _lastSubscription)) {
// Only one listener, so it must be the first listener.
_runGuarded(onListen);
}
return subscription;
}
- Future _recordCancel(_BroadcastSubscription<T> subscription) {
+ Future _recordCancel(StreamSubscription<T> sub) {
+ _BroadcastSubscription<T> subscription = sub;
// If already removed by the stream, don't remove it again.
if (identical(subscription._next, subscription)) return null;
- assert(!identical(subscription._next, subscription));
if (subscription._isFiring) {
subscription._setRemoveAfterFiring();
} else {
- assert(!identical(subscription._next, subscription));
_removeListener(subscription);
// If we are currently firing an event, the empty-check is performed at
// the end of the listener loop instead of here.
@@ -323,20 +328,20 @@
// Any listeners added while firing this event will expect the next event,
// not this one, and won't get notified.
_state ^= _STATE_EVENT_ID | _STATE_FIRING;
- _BroadcastSubscriptionLink link = _next;
- while (!identical(link, this)) {
- _BroadcastSubscription<T> subscription = link;
+ _BroadcastSubscription<T> subscription = _firstSubscription;
+ while (subscription != null) {
if (subscription._expectsEvent(id)) {
subscription._eventState |= _BroadcastSubscription._STATE_FIRING;
action(subscription);
subscription._toggleEventId();
- link = subscription._next;
+ _BroadcastSubscription<T> next = subscription._next;
if (subscription._removeAfterFiring) {
_removeListener(subscription);
}
subscription._eventState &= ~_BroadcastSubscription._STATE_FIRING;
+ subscription = next;
} else {
- link = subscription._next;
+ subscription = subscription._next;
}
}
_state &= ~_STATE_FIRING;
@@ -377,7 +382,7 @@
if (_isEmpty) return;
if (_hasOneListener) {
_state |= _BroadcastStreamController._STATE_FIRING;
- _BroadcastSubscription subscription = _next;
+ _BroadcastSubscription<T> subscription = _firstSubscription;
subscription._add(data);
_state &= ~_BroadcastStreamController._STATE_FIRING;
if (_isEmpty) {
@@ -399,7 +404,7 @@
void _sendDone() {
if (!_isEmpty) {
- _forEachListener((_BroadcastSubscription<T> subscription) {
+ _forEachListener((_BufferingStreamSubscription<T> subscription) {
subscription._close();
});
} else {
@@ -417,29 +422,26 @@
// EventDispatch interface.
void _sendData(T data) {
- for (_BroadcastSubscriptionLink link = _next;
- !identical(link, this);
- link = link._next) {
- _BroadcastSubscription<T> subscription = link;
- subscription._addPending(new _DelayedData(data));
+ for (_BroadcastSubscription<T> subscription = _firstSubscription;
+ subscription != null;
+ subscription = subscription._next) {
+ subscription._addPending(new _DelayedData<T>(data));
}
}
void _sendError(Object error, StackTrace stackTrace) {
- for (_BroadcastSubscriptionLink link = _next;
- !identical(link, this);
- link = link._next) {
- _BroadcastSubscription<T> subscription = link;
+ for (_BroadcastSubscription<T> subscription = _firstSubscription;
+ subscription != null;
+ subscription = subscription._next) {
subscription._addPending(new _DelayedError(error, stackTrace));
}
}
void _sendDone() {
if (!_isEmpty) {
- for (_BroadcastSubscriptionLink link = _next;
- !identical(link, this);
- link = link._next) {
- _BroadcastSubscription<T> subscription = link;
+ for (_BroadcastSubscription<T> subscription = _firstSubscription;
+ subscription != null;
+ subscription = subscription._next) {
subscription._addPending(const _DelayedDone());
}
} else {
@@ -464,7 +466,7 @@
class _AsBroadcastStreamController<T>
extends _SyncBroadcastStreamController<T>
implements _EventDispatch<T> {
- _StreamImplEvents _pending;
+ _StreamImplEvents<T> _pending;
_AsBroadcastStreamController(void onListen(), void onCancel())
: super(onListen, onCancel);
@@ -473,7 +475,7 @@
void _addPendingEvent(_DelayedEvent event) {
if (_pending == null) {
- _pending = new _StreamImplEvents();
+ _pending = new _StreamImplEvents<T>();
}
_pending.add(event);
}
@@ -538,5 +540,5 @@
}
Future cancel() { return new _Future.immediate(null); }
bool get isPaused => _pauseCount > 0;
- Future asFuture([Object value]) => new _Future();
+ Future/*<E>*/ asFuture/*<E>*/([Object/*=E*/ value]) => new _Future/*<E>*/();
}
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 9fd0ca1..23bf531 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -112,7 +112,7 @@
* with that value.
*/
factory Future(computation()) {
- _Future result = new _Future<T>();
+ _Future<T> result = new _Future<T>();
Timer.run(() {
try {
result._complete(computation());
@@ -138,7 +138,7 @@
* the returned future is completed with that value.
*/
factory Future.microtask(computation()) {
- _Future result = new _Future<T>();
+ _Future<T> result = new _Future<T>();
scheduleMicrotask(() {
try {
result._complete(computation());
@@ -222,7 +222,7 @@
* later time that isn't necessarily after a known fixed duration.
*/
factory Future.delayed(Duration duration, [computation()]) {
- _Future result = new _Future<T>();
+ _Future<T> result = new _Future<T>();
new Timer(duration, () {
try {
result._complete(computation?.call());
@@ -257,8 +257,8 @@
static Future<List/*<T>*/> wait/*<T>*/(Iterable<Future/*<T>*/> futures,
{bool eagerError: false,
void cleanUp(/*=T*/ successValue)}) {
- final _Future<List> result = new _Future<List>();
- List values; // Collects the values. Set to null on error.
+ final _Future<List/*<T>*/> result = new _Future<List/*<T>*/>();
+ List/*<T>*/ values; // Collects the values. Set to null on error.
int remaining = 0; // How many futures are we waiting for.
var error; // The first error from a future.
StackTrace stackTrace; // The stackTrace that came with the error.
@@ -291,7 +291,7 @@
// position in the list of values.
for (Future future in futures) {
int pos = remaining++;
- future.then((Object value) {
+ future.then((Object/*=T*/ value) {
remaining--;
if (values != null) {
values[pos] = value;
@@ -312,7 +312,7 @@
if (remaining == 0) {
return new Future.value(const []);
}
- values = new List(remaining);
+ values = new List/*<T>*/(remaining);
return result;
}
@@ -327,8 +327,8 @@
* the returned future never completes.
*/
static Future/*<T>*/ any/*<T>*/(Iterable<Future/*<T>*/> futures) {
- var completer = new Completer.sync();
- var onValue = (value) {
+ var completer = new Completer/*<T>*/.sync();
+ var onValue = (/*=T*/ value) {
if (!completer.isCompleted) completer.complete(value);
};
var onError = (error, stack) {
@@ -486,8 +486,17 @@
* }
*
*/
- Future catchError(Function onError,
- {bool test(Object error)});
+ // The `Function` below can stand for several types:
+ // - (dynamic) -> T
+ // - (dynamic, StackTrace) -> T
+ // - (dynamic) -> Future<T>
+ // - (dynamic, StackTrace) -> Future<T>
+ // Given that there is a `test` function that is usually used to do an
+ // `isCheck` we should also expect functions that take a specific argument.
+ // Note: making `catchError` return a `Future<T>` in non-strong mode could be
+ // a breaking change.
+ Future/*<T>*/ catchError(Function onError,
+ {bool test(Object error)});
/**
* Register a function to be called when this future completes.
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index a8e71f6..eb4d6cf 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -5,7 +5,7 @@
part of dart.async;
/** The onValue and onError handlers return either a value or a future */
-typedef dynamic _FutureOnValue<T>(T value);
+typedef dynamic/*T|Future<T>*/ _FutureOnValue<S, T>(S value);
/** Test used by [Future.catchError] to handle skip some errors. */
typedef bool _FutureErrorTest(var error);
/** Used by [WhenFuture]. */
@@ -57,7 +57,7 @@
}
}
-class _FutureListener {
+class _FutureListener<S, T> {
static const int MASK_VALUE = 1;
static const int MASK_ERROR = 2;
static const int MASK_TEST_ERROR = 4;
@@ -73,7 +73,7 @@
// Listeners on the same future are linked through this link.
_FutureListener _nextListener = null;
// The future to complete when this listener is activated.
- final _Future result;
+ final _Future<T> result;
// Which fields means what.
final int state;
// Used for then/whenDone callback and error test
@@ -82,7 +82,7 @@
final Function errorCallback;
_FutureListener.then(this.result,
- _FutureOnValue onValue, Function errorCallback)
+ _FutureOnValue<S, T> onValue, Function errorCallback)
: callback = onValue,
errorCallback = errorCallback,
state = (errorCallback == null) ? STATE_THEN : STATE_THEN_ONERROR;
@@ -104,18 +104,57 @@
bool get hasErrorTest => (state == STATE_CATCHERROR_TEST);
bool get handlesComplete => (state == STATE_WHENCOMPLETE);
- _FutureOnValue get _onValue {
+
+ _FutureOnValue<S, T> get _onValue {
assert(handlesValue);
- return callback;
+ return callback as Object /*=_FutureOnValue<S, T>*/;
}
Function get _onError => errorCallback;
_FutureErrorTest get _errorTest {
assert(hasErrorTest);
- return callback;
+ return callback as Object /*=_FutureErrorTest*/;
}
_FutureAction get _whenCompleteAction {
assert(handlesComplete);
- return callback;
+ return callback as Object /*=_FutureAction*/;
+ }
+
+ /// Whether this listener has an error callback.
+ ///
+ /// This function must only be called if the listener [handlesError].
+ bool get hasErrorCallback {
+ assert(handlesError);
+ return _onError != null;
+ }
+
+ dynamic/*T|Future<T>*/ handleValue(S sourceResult) {
+ return _zone.runUnary/*<dynamic/*T|Future<T>*/, S>*/(
+ _onValue, sourceResult);
+ }
+
+ bool matchesErrorTest(AsyncError asyncError) {
+ if (!hasErrorTest) return true;
+ _FutureErrorTest test = _errorTest;
+ return _zone.runUnary/*<bool, dynamic>*/(_errorTest, asyncError.error);
+ }
+
+ dynamic/*T|Future<T>*/ handleError(AsyncError asyncError) {
+ assert(handlesError && hasErrorCallback);
+ if (errorCallback is ZoneBinaryCallback) {
+ var typedErrorCallback = errorCallback as Object
+ /*=ZoneBinaryCallback<Object/*T|Future<T>*/, Object, StackTrace>*/;
+ return _zone.runBinary(typedErrorCallback,
+ asyncError.error,
+ asyncError.stackTrace);
+ } else {
+ return _zone.runUnary/*<dynamic/*T|Future<T>*/, dynamic>*/(
+ errorCallback, asyncError.error);
+ }
+ }
+
+ dynamic handleWhenComplete() {
+ assert(!handlesError);
+ return _zone.run(_whenCompleteAction);
}
}
@@ -191,40 +230,43 @@
_resultOrListeners = source;
}
- Future/*<S>*/ then/*<S>*/(f(T value), { Function onError }) {
+ Future/*<E>*/ then/*<E>*/(
+ /*=dynamic/*E|Future<E>*/*/ f(T value), { Function onError }) {
Zone currentZone = Zone.current;
+ ZoneUnaryCallback registered;
if (!identical(currentZone, _ROOT_ZONE)) {
- f = currentZone.registerUnaryCallback(f);
+ f = currentZone.registerUnaryCallback/*<dynamic, T>*/(f);
if (onError != null) {
- onError = _registerErrorHandler(onError, currentZone);
+ onError = _registerErrorHandler/*<T>*/(onError, currentZone);
}
}
- return _thenNoZoneRegistration(f, onError);
+ return _thenNoZoneRegistration/*<E>*/(f, onError);
}
// This method is used by async/await.
- Future _thenNoZoneRegistration(f(T value), Function onError) {
- _Future result = new _Future();
- _addListener(new _FutureListener.then(result, f, onError));
+ Future/*<E>*/ _thenNoZoneRegistration/*<E>*/(f(T value), Function onError) {
+ _Future/*<E>*/ result = new _Future/*<E>*/();
+ _addListener(new _FutureListener/*<T, E>*/.then(result, f, onError));
return result;
}
- Future catchError(Function onError, { bool test(error) }) {
- _Future result = new _Future();
+ Future/*<T>*/ catchError(Function onError, { bool test(error) }) {
+ _Future/*<T>*/ result = new _Future/*<T>*/();
if (!identical(result._zone, _ROOT_ZONE)) {
- onError = _registerErrorHandler(onError, result._zone);
+ onError = _registerErrorHandler/*<T>*/(onError, result._zone);
if (test != null) test = result._zone.registerUnaryCallback(test);
}
- _addListener(new _FutureListener.catchError(result, onError, test));
+ _addListener(new _FutureListener/*<T, T>*/.catchError(
+ result, onError, test));
return result;
}
Future<T> whenComplete(action()) {
- _Future result = new _Future<T>();
+ _Future<T> result = new _Future<T>();
if (!identical(result._zone, _ROOT_ZONE)) {
- action = result._zone.registerCallback(action);
+ action = result._zone.registerCallback/*<dynamic>*/(action);
}
- _addListener(new _FutureListener.whenComplete(result, action));
+ _addListener(new _FutureListener/*<T, T>*/.whenComplete(result, action));
return result;
}
@@ -412,12 +454,12 @@
}
} else {
_FutureListener listeners = _removeListeners();
- _setValue(value);
+ _setValue(value as Object /*=T*/);
_propagateToListeners(this, listeners);
}
}
- void _completeWithValue(value) {
+ void _completeWithValue(T value) {
assert(!_isComplete);
assert(value is! Future);
@@ -447,11 +489,9 @@
// unhandled error, even though we know we are already going to listen to
// it.
- if (value == null) {
- // No checks for `null`.
- } else if (value is Future) {
+ if (value is Future) {
// Assign to typed variables so we get earlier checks in checked mode.
- Future<T> typedFuture = value;
+ Future<T> typedFuture = value as Object /*=Future<T>*/;
if (typedFuture is _Future) {
_Future<T> coreFuture = typedFuture;
if (coreFuture._hasError) {
@@ -465,20 +505,18 @@
_chainCoreFuture(coreFuture, this);
}
} else {
- // Case 2 from above. Chain the future immidiately.
+ // Case 2 from above. Chain the future immediately.
// Note that we are still completing asynchronously (through
// _chainForeignFuture).
_chainForeignFuture(typedFuture, this);
}
return;
- } else {
- T typedValue = value;
- assert(typedValue is T); // Avoid warning that typedValue is unused.
}
+ T typedValue = value as Object /*=T*/;
_setPendingComplete();
_zone.scheduleMicrotask(() {
- _completeWithValue(value);
+ _completeWithValue(typedValue);
});
}
@@ -547,59 +585,17 @@
oldZone = Zone._enter(zone);
}
- void handleValueCallback() {
- assert(!hasError);
- try {
- listenerValueOrError = zone.runUnary(listener._onValue,
- sourceResult);
- listenerHasError = false;
- } catch (e, s) {
- listenerValueOrError = new AsyncError(e, s);
- listenerHasError = true;
- }
- }
-
- void handleError() {
- AsyncError asyncError = source._error;
- bool matchesTest = true;
- if (listener.hasErrorTest) {
- _FutureErrorTest test = listener._errorTest;
- try {
- matchesTest = zone.runUnary(test, asyncError.error);
- } catch (e, s) {
- listenerValueOrError = identical(asyncError.error, e)
- ? asyncError
- : new AsyncError(e, s);
- listenerHasError = true;
- return;
- }
- }
- Function errorCallback = listener._onError;
- if (matchesTest && errorCallback != null) {
- try {
- if (errorCallback is ZoneBinaryCallback) {
- listenerValueOrError = zone.runBinary(errorCallback,
- asyncError.error,
- asyncError.stackTrace);
- } else {
- listenerValueOrError = zone.runUnary(errorCallback,
- asyncError.error);
- }
- listenerHasError = false;
- } catch (e, s) {
- listenerValueOrError = identical(asyncError.error, e)
- ? asyncError
- : new AsyncError(e, s);
- listenerHasError = true;
- }
- }
- }
-
+ // These callbacks are abstracted to isolate the try/catch blocks
+ // from the rest of the code to work around a V8 glass jaw.
void handleWhenCompleteCallback() {
+ // The whenComplete-handler is not combined with normal value/error
+ // handling. This means at most one handleX method is called per
+ // listener.
+ assert(!listener.handlesValue);
assert(!listener.handlesError);
var completeResult;
try {
- completeResult = zone.run(listener._whenCompleteAction);
+ completeResult = listener.handleWhenComplete();
} catch (e, s) {
if (hasError && identical(source._error.error, e)) {
listenerValueOrError = source._error;
@@ -627,12 +623,35 @@
}
}
+ void handleValueCallback() {
+ try {
+ listenerValueOrError = listener.handleValue(sourceResult);
+ } catch (e, s) {
+ listenerValueOrError = new AsyncError(e, s);
+ listenerHasError = true;
+ }
+ }
+
+ void handleError() {
+ try {
+ AsyncError asyncError = source._error;
+ if (listener.matchesErrorTest(asyncError) &&
+ listener.hasErrorCallback) {
+ listenerValueOrError = listener.handleError(asyncError);
+ listenerHasError = false;
+ }
+ } catch (e, s) {
+ if (identical(source._error.error, e)) {
+ listenerValueOrError = source._error;
+ } else {
+ listenerValueOrError = new AsyncError(e, s);
+ }
+ listenerHasError = true;
+ }
+ }
+
+
if (listener.handlesComplete) {
- // The whenComplete-handler is not combined with normal value/error
- // handling. This means at most one handleX method is called per
- // listener.
- assert(!listener.handlesValue);
- assert(!listener.handlesError);
handleWhenCompleteCallback();
} else if (!hasError) {
if (listener.handlesValue) {
@@ -643,7 +662,7 @@
handleError();
}
}
-
+
// If we changed zone, oldZone will not be null.
if (oldZone != null) Zone._leave(oldZone);
@@ -684,7 +703,7 @@
Future<T> timeout(Duration timeLimit, {onTimeout()}) {
if (_isComplete) return new _Future.immediate(this);
- _Future result = new _Future<T>();
+ _Future<T> result = new _Future<T>();
Timer timer;
if (onTimeout == null) {
timer = new Timer(timeLimit, () {
diff --git a/sdk/lib/async/schedule_microtask.dart b/sdk/lib/async/schedule_microtask.dart
index fac3f7f..70fbeba 100644
--- a/sdk/lib/async/schedule_microtask.dart
+++ b/sdk/lib/async/schedule_microtask.dart
@@ -84,7 +84,7 @@
*
* Is always run in the root zone.
*/
-void _schedulePriorityAsyncCallback(callback) {
+void _schedulePriorityAsyncCallback(_AsyncCallback callback) {
if (_nextCallback == null) {
_scheduleAsyncCallback(callback);
_lastPriorityCallback = _lastCallback;
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 97b1244..6931373 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -8,6 +8,8 @@
// Core Stream types
// -------------------------------------------------------------------
+typedef void _TimerCallback();
+
/**
* A source of asynchronous data events.
*
@@ -127,9 +129,9 @@
* If no future is passed, the stream closes as soon as possible.
*/
factory Stream.fromFutures(Iterable<Future<T>> futures) {
- var controller = new StreamController<T>(sync: true);
+ _StreamController<T> controller = new StreamController<T>(sync: true);
int count = 0;
- var onValue = (value) {
+ var onValue = (T value) {
if (!controller.isClosed) {
controller._add(value);
if (--count == 0) controller._closeUnchecked();
@@ -384,18 +386,20 @@
*
* The returned stream is a broadcast stream if this stream is.
*/
- Stream asyncMap(convert(T event)) {
- StreamController controller;
- StreamSubscription subscription;
- void onListen () {
+ Stream/*<E>*/ asyncMap/*<E>*/(convert(T event)) {
+ StreamController/*<E>*/ controller;
+ StreamSubscription/*<T>*/ subscription;
+
+ void onListen() {
final add = controller.add;
assert(controller is _StreamController ||
controller is _BroadcastStreamController);
- final eventSink = controller;
+ final _EventSink/*<E>*/ eventSink =
+ controller as Object /*=_EventSink<E>*/;
final addError = eventSink._addError;
subscription = this.listen(
(T event) {
- var newValue;
+ dynamic newValue;
try {
newValue = convert(event);
} catch (e, s) {
@@ -407,21 +411,22 @@
newValue.then(add, onError: addError)
.whenComplete(subscription.resume);
} else {
- controller.add(newValue);
+ controller.add(newValue as Object/*=E*/);
}
},
onError: addError,
onDone: controller.close
);
}
+
if (this.isBroadcast) {
- controller = new StreamController.broadcast(
+ controller = new StreamController/*<E>*/.broadcast(
onListen: onListen,
onCancel: () { subscription.cancel(); },
sync: true
);
} else {
- controller = new StreamController(
+ controller = new StreamController/*<E>*/(
onListen: onListen,
onPause: () { subscription.pause(); },
onResume: () { subscription.resume(); },
@@ -445,16 +450,17 @@
*
* The returned stream is a broadcast stream if this stream is.
*/
- Stream asyncExpand(Stream convert(T event)) {
- StreamController controller;
- StreamSubscription subscription;
+ Stream/*<E>*/ asyncExpand/*<E>*/(Stream/*<E>*/ convert(T event)) {
+ StreamController/*<E>*/ controller;
+ StreamSubscription<T> subscription;
void onListen() {
assert(controller is _StreamController ||
controller is _BroadcastStreamController);
- final eventSink = controller;
+ final _EventSink/*<E>*/ eventSink =
+ controller as Object /*=_EventSink<E>*/;
subscription = this.listen(
(T event) {
- Stream newStream;
+ Stream/*<E>*/ newStream;
try {
newStream = convert(event);
} catch (e, s) {
@@ -472,13 +478,13 @@
);
}
if (this.isBroadcast) {
- controller = new StreamController.broadcast(
+ controller = new StreamController/*<E>*/.broadcast(
onListen: onListen,
onCancel: () { subscription.cancel(); },
sync: true
);
} else {
- controller = new StreamController(
+ controller = new StreamController/*<E>*/(
onListen: onListen,
onPause: () { subscription.pause(); },
onResume: () { subscription.resume(); },
@@ -611,14 +617,14 @@
Future/*<S>*/ fold/*<S>*/(var/*=S*/ initialValue,
/*=S*/ combine(var/*=S*/ previous, T element)) {
- _Future result = new _Future();
- var value = initialValue;
+ _Future/*<S>*/ result = new _Future/*<S>*/();
+ var/*=S*/ value = initialValue;
StreamSubscription subscription;
subscription = this.listen(
(T element) {
_runUserCode(
() => combine(value, element),
- (newValue) { value = newValue; },
+ (/*=S*/ newValue) { value = newValue; },
_cancelAndErrorClosure(subscription, result)
);
},
@@ -880,8 +886,8 @@
* In case of a `done` event the future completes with the given
* [futureValue].
*/
- Future drain([var futureValue]) => listen(null, cancelOnError: true)
- .asFuture(futureValue);
+ Future/*<E>*/ drain/*<E>*/([/*=E*/ futureValue])
+ => listen(null, cancelOnError: true).asFuture/*<E>*/(futureValue);
/**
* Provides at most the first [n] values of this stream.
@@ -1292,13 +1298,13 @@
* will have its individually timer that starts counting on listen,
* and the subscriptions' timers can be paused individually.
*/
- Stream timeout(Duration timeLimit, {void onTimeout(EventSink sink)}) {
- StreamController controller;
+ Stream<T> timeout(Duration timeLimit, {void onTimeout(EventSink<T> sink)}) {
+ StreamController<T> controller;
// The following variables are set on listen.
StreamSubscription<T> subscription;
Timer timer;
Zone zone;
- Function timeout;
+ _TimerCallback timeout;
void onData(T event) {
timer.cancel();
@@ -1309,7 +1315,7 @@
timer.cancel();
assert(controller is _StreamController ||
controller is _BroadcastStreamController);
- var eventSink = controller;
+ dynamic eventSink = controller;
eventSink._addError(error, stackTrace); // Avoid Zone error replacement.
timer = zone.createTimer(timeLimit, timeout);
}
@@ -1329,12 +1335,15 @@
timeLimit), null);
};
} else {
- onTimeout = zone.registerUnaryCallback(onTimeout);
+ // TODO(floitsch): the return type should be 'void', and the type
+ // should be inferred.
+ var registeredOnTimeout =
+ zone.registerUnaryCallback/*<dynamic, EventSink<T>>*/(onTimeout);
_ControllerEventSinkWrapper wrapper =
new _ControllerEventSinkWrapper(null);
timeout = () {
wrapper._sink = controller; // Only valid during call.
- zone.runUnaryGuarded(onTimeout, wrapper);
+ zone.runUnaryGuarded(registeredOnTimeout, wrapper);
wrapper._sink = null;
};
}
@@ -1349,8 +1358,8 @@
return result;
}
controller = isBroadcast
- ? new _SyncBroadcastStreamController(onListen, onCancel)
- : new _SyncStreamController(
+ ? new _SyncBroadcastStreamController<T>(onListen, onCancel)
+ : new _SyncStreamController<T>(
onListen,
() {
// Don't null the timer, onCancel may call cancel again.
@@ -1473,7 +1482,7 @@
* In case of a `done` event the future completes with the given
* [futureValue].
*/
- Future asFuture([var futureValue]);
+ Future/*<E>*/ asFuture/*<E>*/([var/*=E*/ futureValue]);
}
@@ -1500,8 +1509,9 @@
bool get isBroadcast => _stream.isBroadcast;
- Stream<T> asBroadcastStream({void onListen(StreamSubscription subscription),
- void onCancel(StreamSubscription subscription)})
+ Stream<T> asBroadcastStream(
+ {void onListen(StreamSubscription<T> subscription),
+ void onCancel(StreamSubscription<T> subscription)})
=> _stream.asBroadcastStream(onListen: onListen, onCancel: onCancel);
StreamSubscription<T> listen(void onData(T value),
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index cd69f44..87b64e8 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -494,37 +494,40 @@
// stream is listened to.
// While adding a stream, pending events are moved into the
// state object to allow the state object to use the _varData field.
- _PendingEvents get _pendingEvents {
+ _PendingEvents<T> get _pendingEvents {
assert(_isInitialState);
if (!_isAddingStream) {
- return _varData;
+ return _varData as Object /*=_PendingEvents<T>*/;
}
- _StreamControllerAddStreamState state = _varData;
- return state.varData;
+ _StreamControllerAddStreamState<T> state =
+ _varData as Object /*=_StreamControllerAddStreamState<T>*/;
+ return state.varData as Object /*=_PendingEvents<T>*/;
}
// Returns the pending events, and creates the object if necessary.
- _StreamImplEvents _ensurePendingEvents() {
+ _StreamImplEvents<T> _ensurePendingEvents() {
assert(_isInitialState);
if (!_isAddingStream) {
- if (_varData == null) _varData = new _StreamImplEvents();
- return _varData;
+ if (_varData == null) _varData = new _StreamImplEvents<T>();
+ return _varData as Object /*=_StreamImplEvents<T>*/;
}
- _StreamControllerAddStreamState state = _varData;
- if (state.varData == null) state.varData = new _StreamImplEvents();
- return state.varData;
+ _StreamControllerAddStreamState<T> state =
+ _varData as Object /*=_StreamControllerAddStreamState<T>*/;
+ if (state.varData == null) state.varData = new _StreamImplEvents<T>();
+ return state.varData as Object /*=_StreamImplEvents<T>*/;
}
// Get the current subscription.
// If we are adding a stream, the subscription is moved into the state
// object to allow the state object to use the _varData field.
- _ControllerSubscription get _subscription {
+ _ControllerSubscription<T> get _subscription {
assert(hasListener);
if (_isAddingStream) {
- _StreamControllerAddStreamState addState = _varData;
- return addState.varData;
+ _StreamControllerAddStreamState<T> addState =
+ _varData as Object /*=_StreamControllerAddStreamState<T>*/;
+ return addState.varData as Object /*=_ControllerSubscription<T>*/;
}
- return _varData;
+ return _varData as Object /*=_ControllerSubscription<T>*/;
}
/**
@@ -544,11 +547,11 @@
Future addStream(Stream<T> source, {bool cancelOnError: true}) {
if (!_mayAddEvent) throw _badEventState();
if (_isCanceled) return new _Future.immediate(null);
- _StreamControllerAddStreamState addState =
- new _StreamControllerAddStreamState(this,
- _varData,
- source,
- cancelOnError);
+ _StreamControllerAddStreamState<T> addState =
+ new _StreamControllerAddStreamState<T>(this,
+ _varData,
+ source,
+ cancelOnError);
_varData = addState;
_state |= _STATE_ADDSTREAM;
return addState.addStreamFuture;
@@ -646,7 +649,8 @@
void _close() {
// End of addStream stream.
assert(_isAddingStream);
- _StreamControllerAddStreamState addState = _varData;
+ _StreamControllerAddStreamState<T> addState =
+ _varData as Object /*=_StreamControllerAddStreamState<T>*/;
_varData = addState.varData;
_state &= ~_STATE_ADDSTREAM;
addState.complete();
@@ -662,14 +666,15 @@
if (!_isInitialState) {
throw new StateError("Stream has already been listened to.");
}
- _ControllerSubscription subscription =
+ _ControllerSubscription<T> subscription =
new _ControllerSubscription<T>(this, onData, onError, onDone,
cancelOnError);
- _PendingEvents pendingEvents = _pendingEvents;
+ _PendingEvents<T> pendingEvents = _pendingEvents;
_state |= _STATE_SUBSCRIBED;
if (_isAddingStream) {
- _StreamControllerAddStreamState addState = _varData;
+ _StreamControllerAddStreamState<T> addState =
+ _varData as Object /*=_StreamControllerAddStreamState<T>*/;
addState.varData = subscription;
addState.resume();
} else {
@@ -694,7 +699,8 @@
// returned future.
Future result;
if (_isAddingStream) {
- _StreamControllerAddStreamState addState = _varData;
+ _StreamControllerAddStreamState<T> addState =
+ _varData as Object /*=_StreamControllerAddStreamState<T>*/;
result = addState.cancel();
}
_varData = null;
@@ -736,7 +742,8 @@
void _recordPause(StreamSubscription<T> subscription) {
if (_isAddingStream) {
- _StreamControllerAddStreamState addState = _varData;
+ _StreamControllerAddStreamState<T> addState =
+ _varData as Object /*=_StreamControllerAddStreamState<T>*/;
addState.pause();
}
_runGuarded(onPause);
@@ -744,7 +751,8 @@
void _recordResume(StreamSubscription<T> subscription) {
if (_isAddingStream) {
- _StreamControllerAddStreamState addState = _varData;
+ _StreamControllerAddStreamState<T> addState =
+ _varData as Object /*=_StreamControllerAddStreamState<T>*/;
addState.resume();
}
_runGuarded(onResume);
@@ -772,7 +780,7 @@
abstract class _AsyncStreamControllerDispatch<T>
implements _StreamController<T> {
void _sendData(T data) {
- _subscription._addPending(new _DelayedData(data));
+ _subscription._addPending(new _DelayedData<dynamic /*=T*/>(data));
}
void _sendError(Object error, StackTrace stackTrace) {
@@ -928,7 +936,7 @@
// to store this state object.
var varData;
- _StreamControllerAddStreamState(_StreamController controller,
+ _StreamControllerAddStreamState(_StreamController<T> controller,
this.varData,
Stream source,
bool cancelOnError)
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 51f8b14..dffaa12 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -106,7 +106,7 @@
*
* Is created when necessary, or set in constructor for preconfigured events.
*/
- _PendingEvents _pending;
+ _PendingEvents<T> _pending;
_BufferingStreamSubscription(void onData(T data),
Function onError,
@@ -124,7 +124,7 @@
* This can only be done once. The pending events object is used for the
* rest of the subscription's life cycle.
*/
- void _setPendingEvents(_PendingEvents pendingEvents) {
+ void _setPendingEvents(_PendingEvents<T> pendingEvents) {
assert(_pending == null);
if (pendingEvents == null) return;
_pending = pendingEvents;
@@ -134,29 +134,18 @@
}
}
- /**
- * Extracts the pending events from a canceled stream.
- *
- * This can only be done during the [_onCancel] method call. After that,
- * any remaining pending events will be cleared.
- */
- _PendingEvents _extractPending() {
- assert(_isCanceled);
- _PendingEvents events = _pending;
- _pending = null;
- return events;
- }
-
// StreamSubscription interface.
void onData(void handleData(T event)) {
if (handleData == null) handleData = _nullDataHandler;
- _onData = _zone.registerUnaryCallback(handleData);
+ // TODO(floitsch): the return type should be 'void', and the type
+ // should be inferred.
+ _onData = _zone.registerUnaryCallback/*<dynamic, T>*/(handleData);
}
void onError(Function handleError) {
if (handleError == null) handleError = _nullErrorHandler;
- _onError = _registerErrorHandler(handleError, _zone);
+ _onError = _registerErrorHandler/*<T>*/(handleError, _zone);
}
void onDone(void handleDone()) {
@@ -202,8 +191,8 @@
return _cancelFuture;
}
- Future asFuture([var futureValue]) {
- _Future result = new _Future();
+ Future/*<E>*/ asFuture/*<E>*/([var/*=E*/ futureValue]) {
+ _Future/*<E>*/ result = new _Future/*<E>*/();
// Overwrite the onDone and onError handlers.
_onDone = () { result._complete(futureValue); };
@@ -269,7 +258,7 @@
if (_canFire) {
_sendData(data);
} else {
- _addPending(new _DelayedData(data));
+ _addPending(new _DelayedData<dynamic /*=T*/>(data));
}
}
@@ -319,8 +308,10 @@
* of pending events later (if necessary).
*/
void _addPending(_DelayedEvent event) {
- _StreamImplEvents pending = _pending;
- if (_pending == null) pending = _pending = new _StreamImplEvents();
+ _StreamImplEvents<T> pending = _pending;
+ if (_pending == null) {
+ pending = _pending = new _StreamImplEvents<dynamic /*=T*/>();
+ }
pending.add(event);
if (!_hasPending) {
_state |= _STATE_HAS_PENDING;
@@ -354,10 +345,13 @@
// future to finish we must not report the error.
if (_isCanceled && !_waitsForCancel) return;
_state |= _STATE_IN_CALLBACK;
- if (_onError is ZoneBinaryCallback) {
- _zone.runBinaryGuarded(_onError, error, stackTrace);
+ if (_onError is ZoneBinaryCallback<dynamic, Object, StackTrace>) {
+ ZoneBinaryCallback<dynamic, Object, StackTrace> errorCallback = _onError
+ as Object /*=ZoneBinaryCallback<dynamic, Object, StackTrace>*/;
+ _zone.runBinaryGuarded(errorCallback, error, stackTrace);
} else {
- _zone.runUnaryGuarded(_onError, error);
+ _zone.runUnaryGuarded/*<dynamic, dynamic>*/(
+ _onError as Object /*=ZoneUnaryCallback<dynamic, dynamic>*/, error);
}
_state &= ~_STATE_IN_CALLBACK;
}
@@ -470,7 +464,7 @@
void onDone(),
bool cancelOnError }) {
cancelOnError = identical(true, cancelOnError);
- StreamSubscription subscription =
+ StreamSubscription<T> subscription =
_createSubscription(onData, onError, onDone, cancelOnError);
_onListen(subscription);
return subscription;
@@ -478,7 +472,7 @@
// -------------------------------------------------------------------
/** Create a subscription object. Called by [subcribe]. */
- _BufferingStreamSubscription<T> _createSubscription(
+ StreamSubscription<T> _createSubscription(
void onData(T data),
Function onError,
void onDone(),
@@ -491,11 +485,11 @@
void _onListen(StreamSubscription subscription) {}
}
-typedef _PendingEvents _EventGenerator();
+typedef _PendingEvents<T> _EventGenerator<T>();
/** Stream that generates its own events. */
class _GeneratedStreamImpl<T> extends _StreamImpl<T> {
- final _EventGenerator _pending;
+ final _EventGenerator<T> _pending;
bool _isUsed = false;
/**
* Initializes the stream to have only the events provided by a
@@ -505,7 +499,7 @@
*/
_GeneratedStreamImpl(this._pending);
- StreamSubscription _createSubscription(
+ StreamSubscription<T> _createSubscription(
void onData(T data),
Function onError,
void onDone(),
@@ -519,7 +513,7 @@
/** Pending events object that gets its events from an [Iterable]. */
-class _IterablePendingEvents<T> extends _PendingEvents {
+class _IterablePendingEvents<T> extends _PendingEvents<T> {
// The iterator providing data for data events.
// Set to null when iteration has completed.
Iterator<T> _iterator;
@@ -528,7 +522,7 @@
bool get isEmpty => _iterator == null;
- void handleNext(_EventDispatch dispatch) {
+ void handleNext(_EventDispatch<T> dispatch) {
if (_iterator == null) {
throw new StateError("No events pending.");
}
@@ -580,15 +574,15 @@
/** A delayed event on a buffering stream subscription. */
-abstract class _DelayedEvent {
+abstract class _DelayedEvent<T> {
/** Added as a linked list on the [StreamController]. */
_DelayedEvent next;
/** Execute the delayed event on the [StreamController]. */
- void perform(_EventDispatch dispatch);
+ void perform(_EventDispatch<T> dispatch);
}
/** A delayed data event. */
-class _DelayedData<T> extends _DelayedEvent {
+class _DelayedData<T> extends _DelayedEvent<T> {
final T value;
_DelayedData(this.value);
void perform(_EventDispatch<T> dispatch) {
@@ -622,7 +616,7 @@
}
/** Superclass for provider of pending events. */
-abstract class _PendingEvents {
+abstract class _PendingEvents<T> {
// No async event has been scheduled.
static const int _STATE_UNSCHEDULED = 0;
// An async event has been scheduled to run a function.
@@ -656,7 +650,7 @@
* If called more than once, it should be called with the same dispatch as
* argument each time. It may reuse an earlier argument in some cases.
*/
- void schedule(_EventDispatch dispatch) {
+ void schedule(_EventDispatch<T> dispatch) {
if (isScheduled) return;
assert(!isEmpty);
if (_eventScheduled) {
@@ -677,7 +671,7 @@
if (isScheduled) _state = _STATE_CANCELED;
}
- void handleNext(_EventDispatch dispatch);
+ void handleNext(_EventDispatch<T> dispatch);
/** Throw away any pending events and cancel scheduled events. */
void clear();
@@ -685,7 +679,7 @@
/** Class holding pending events for a [_StreamImpl]. */
-class _StreamImplEvents extends _PendingEvents {
+class _StreamImplEvents<T> extends _PendingEvents<T> {
/// Single linked list of [_DelayedEvent] objects.
_DelayedEvent firstPendingEvent = null;
/// Last element in the list of pending events. New events are added after it.
@@ -701,7 +695,7 @@
}
}
- void handleNext(_EventDispatch dispatch) {
+ void handleNext(_EventDispatch<T> dispatch) {
assert(!isScheduled);
_DelayedEvent event = firstPendingEvent;
firstPendingEvent = event.next;
@@ -736,7 +730,7 @@
}
}
-typedef void _broadcastCallback(StreamSubscription subscription);
+typedef void _BroadcastCallback<T>(StreamSubscription<T> subscription);
/**
* Done subscription that will send one done event as soon as possible.
@@ -784,8 +778,8 @@
Future cancel() => null;
- Future asFuture([futureValue]) {
- _Future result = new _Future();
+ Future/*<E>*/ asFuture/*<E>*/([var/*=E*/ futureValue]) {
+ _Future/*<E>*/ result = new _Future/*<E>*/();
_onDone = () { result._completeWithValue(null); };
return result;
}
@@ -800,18 +794,22 @@
class _AsBroadcastStream<T> extends Stream<T> {
final Stream<T> _source;
- final _broadcastCallback _onListenHandler;
- final _broadcastCallback _onCancelHandler;
+ final _BroadcastCallback<T> _onListenHandler;
+ final _BroadcastCallback<T> _onCancelHandler;
final Zone _zone;
_AsBroadcastStreamController<T> _controller;
StreamSubscription<T> _subscription;
_AsBroadcastStream(this._source,
- void onListenHandler(StreamSubscription subscription),
- void onCancelHandler(StreamSubscription subscription))
- : _onListenHandler = Zone.current.registerUnaryCallback(onListenHandler),
- _onCancelHandler = Zone.current.registerUnaryCallback(onCancelHandler),
+ void onListenHandler(StreamSubscription<T> subscription),
+ void onCancelHandler(StreamSubscription<T> subscription))
+ // TODO(floitsch): the return type should be void and should be
+ // inferred.
+ : _onListenHandler = Zone.current.registerUnaryCallback
+ /*<dynamic, StreamSubscription<T>>*/(onListenHandler),
+ _onCancelHandler = Zone.current.registerUnaryCallback
+ /*<dynamic, StreamSubscription<T>>*/(onCancelHandler),
_zone = Zone.current {
_controller = new _AsBroadcastStreamController<T>(_onListen, _onCancel);
}
@@ -896,7 +894,7 @@
"Cannot change handlers of asBroadcastStream source subscription.");
}
- void onError(void handleError(Object data)) {
+ void onError(Function handleError) {
throw new UnsupportedError(
"Cannot change handlers of asBroadcastStream source subscription.");
}
@@ -923,7 +921,7 @@
return _stream._isSubscriptionPaused;
}
- Future asFuture([var futureValue]) {
+ Future/*<E>*/ asFuture/*<E>*/([var/*=E*/ futureValue]) {
throw new UnsupportedError(
"Cannot change handlers of asBroadcastStream source subscription.");
}
@@ -974,7 +972,7 @@
/// Also used to store the next value/error in case the stream provides an
/// event before [moveNext] is called again. In that case, the stream will
/// be paused to prevent further events.
- var _futureOrPrefetch = null;
+ var/*Future<bool> or T*/ _futureOrPrefetch = null;
/// The current state.
int _state = _STATE_FOUND;
@@ -998,14 +996,15 @@
if (_state == _STATE_FOUND) {
_state = _STATE_MOVING;
_current = null;
- _futureOrPrefetch = new _Future<bool>();
- return _futureOrPrefetch;
+ var result = new _Future<bool>();
+ _futureOrPrefetch = result;
+ return result;
} else {
assert(_state >= _STATE_EXTRA_DATA);
switch (_state) {
case _STATE_EXTRA_DATA:
_state = _STATE_FOUND;
- _current = _futureOrPrefetch;
+ _current = _futureOrPrefetch as Object /*=T*/;
_futureOrPrefetch = null;
_subscription.resume();
return new _Future<bool>.immediate(true);
@@ -1033,7 +1032,7 @@
StreamSubscription subscription = _subscription;
if (subscription == null) return null;
if (_state == _STATE_MOVING) {
- _Future<bool> hasNext = _futureOrPrefetch;
+ _Future<bool> hasNext = _futureOrPrefetch as Object /*=_Future<bool>*/;
_clear();
hasNext._complete(false);
} else {
@@ -1045,7 +1044,7 @@
void _onData(T data) {
if (_state == _STATE_MOVING) {
_current = data;
- _Future<bool> hasNext = _futureOrPrefetch;
+ _Future<bool> hasNext = _futureOrPrefetch as Object /*=_Future<bool>*/;
_futureOrPrefetch = null;
_state = _STATE_FOUND;
hasNext._complete(true);
@@ -1059,7 +1058,7 @@
void _onError(Object error, [StackTrace stackTrace]) {
if (_state == _STATE_MOVING) {
- _Future<bool> hasNext = _futureOrPrefetch;
+ _Future<bool> hasNext = _futureOrPrefetch as Object /*=_Future<bool>*/;
// We have cancelOnError: true, so the subscription is canceled.
_clear();
hasNext._completeError(error, stackTrace);
@@ -1073,7 +1072,7 @@
void _onDone() {
if (_state == _STATE_MOVING) {
- _Future<bool> hasNext = _futureOrPrefetch;
+ _Future<bool> hasNext = _futureOrPrefetch as Object /*=_Future<bool>*/;
_clear();
hasNext._complete(false);
return;
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index b3c3aaf..1125620 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -47,10 +47,15 @@
_cancelAndError(subscription, future, error, stackTrace);
}
+typedef void _ErrorCallback(error, StackTrace stackTrace);
+
/** Helper function to make an onError argument to [_runUserCode]. */
-_cancelAndErrorClosure(StreamSubscription subscription, _Future future) =>
- ((error, StackTrace stackTrace) => _cancelAndError(
- subscription, future, error, stackTrace));
+_ErrorCallback _cancelAndErrorClosure(
+ StreamSubscription subscription, _Future future) {
+ return (error, StackTrace stackTrace) {
+ _cancelAndError(subscription, future, error, stackTrace);
+ };
+}
/** Helper function to cancel a subscription and wait for the potential future,
before completing with a value. */
@@ -100,8 +105,7 @@
// Override the following methods in subclasses to change the behavior.
void _handleData(S data, _EventSink<T> sink) {
- var outputData = data;
- sink._add(outputData);
+ sink._add(data as Object /*=T*/);
}
void _handleError(error, StackTrace stackTrace, _EventSink<T> sink) {
@@ -224,7 +228,7 @@
* A stream pipe that converts data events before passing them on.
*/
class _MapStream<S, T> extends _ForwardingStream<S, T> {
- final _Transformation _transform;
+ final _Transformation<S, T> _transform;
_MapStream(Stream<S> source, T transform(S event))
: this._transform = transform, super(source);
@@ -327,7 +331,7 @@
}
void _handleData(T inputEvent, _EventSink<T> sink) {
- _StateStreamSubscription subscription = sink;
+ _StateStreamSubscription<T> subscription = sink;
int count = subscription._count;
if (count > 0) {
sink._add(inputEvent);
@@ -351,7 +355,7 @@
// Raw state field. Typed access provided by getters and setters below.
var _sharedState;
- _StateStreamSubscription(_ForwardingStream stream, void onData(T data),
+ _StateStreamSubscription(_ForwardingStream<T, T> stream, void onData(T data),
Function onError, void onDone(),
bool cancelOnError, this._sharedState)
: super(stream, onData, onError, onDone, cancelOnError);
@@ -407,7 +411,7 @@
}
void _handleData(T inputEvent, _EventSink<T> sink) {
- _StateStreamSubscription subscription = sink;
+ _StateStreamSubscription<T> subscription = sink;
int count = subscription._count;
if (count > 0) {
subscription._count = count - 1;
@@ -433,7 +437,7 @@
}
void _handleData(T inputEvent, _EventSink<T> sink) {
- _StateStreamSubscription subscription = sink;
+ _StateStreamSubscription<T> subscription = sink;
bool hasFailed = subscription._flag;
if (hasFailed) {
sink._add(inputEvent);
@@ -476,7 +480,7 @@
if (_equals == null) {
isEqual = (_previous == inputEvent);
} else {
- isEqual = _equals(_previous, inputEvent);
+ isEqual = _equals(_previous as Object /*=T*/, inputEvent);
}
} catch (e, s) {
_addErrorWithReplacement(sink, e, s);
diff --git a/sdk/lib/async/stream_transformers.dart b/sdk/lib/async/stream_transformers.dart
index 979ce3a..e0982da 100644
--- a/sdk/lib/async/stream_transformers.dart
+++ b/sdk/lib/async/stream_transformers.dart
@@ -28,13 +28,13 @@
class _SinkTransformerStreamSubscription<S, T>
extends _BufferingStreamSubscription<T> {
/// The transformer's input sink.
- EventSink _transformerSink;
+ EventSink<S> _transformerSink;
/// The subscription to the input stream.
StreamSubscription<S> _subscription;
_SinkTransformerStreamSubscription(Stream<S> source,
- _SinkMapper mapper,
+ _SinkMapper<S, T> mapper,
void onData(T data),
Function onError,
void onDone(),
@@ -183,8 +183,9 @@
void onDone(),
bool cancelOnError }) {
cancelOnError = identical(true, cancelOnError);
- StreamSubscription<T> subscription = new _SinkTransformerStreamSubscription(
- _stream, _sinkMapper, onData, onError, onDone, cancelOnError);
+ StreamSubscription<T> subscription =
+ new _SinkTransformerStreamSubscription<S, T>(
+ _stream, _sinkMapper, onData, onError, onDone, cancelOnError);
return subscription;
}
}
diff --git a/sdk/lib/async/timer.dart b/sdk/lib/async/timer.dart
index fafe652..1bbb65b 100644
--- a/sdk/lib/async/timer.dart
+++ b/sdk/lib/async/timer.dart
@@ -76,8 +76,11 @@
// be invoked in the root zone.
return Zone.current.createPeriodicTimer(duration, callback);
}
- return Zone.current.createPeriodicTimer(
- duration, Zone.current.bindUnaryCallback(callback, runGuarded: true));
+ // TODO(floitsch): the return type should be 'void', and the type
+ // should be inferred.
+ var boundCallback = Zone.current.bindUnaryCallback/*<dynamic, Timer>*/(
+ callback, runGuarded: true);
+ return Zone.current.createPeriodicTimer(duration, boundCallback);
}
/**
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index 5cc4d88..24f83f8 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -4,27 +4,37 @@
part of dart.async;
-typedef dynamic ZoneCallback();
-typedef dynamic ZoneUnaryCallback(arg);
-typedef dynamic ZoneBinaryCallback(arg1, arg2);
+typedef R ZoneCallback<R>();
+typedef R ZoneUnaryCallback<R, T>(T arg);
+typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2);
-typedef dynamic HandleUncaughtErrorHandler(
+// TODO(floitsch): we are abusing generic typedefs as typedefs for generic
+// functions.
+/*ABUSE*/
+typedef R HandleUncaughtErrorHandler<R>(
Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace);
-typedef dynamic RunHandler(Zone self, ZoneDelegate parent, Zone zone, f());
-typedef dynamic RunUnaryHandler(
- Zone self, ZoneDelegate parent, Zone zone, f(arg), arg);
-typedef dynamic RunBinaryHandler(
- Zone self, ZoneDelegate parent, Zone zone, f(arg1, arg2), arg1, arg2);
-typedef ZoneCallback RegisterCallbackHandler(
- Zone self, ZoneDelegate parent, Zone zone, f());
-typedef ZoneUnaryCallback RegisterUnaryCallbackHandler(
- Zone self, ZoneDelegate parent, Zone zone, f(arg));
-typedef ZoneBinaryCallback RegisterBinaryCallbackHandler(
- Zone self, ZoneDelegate parent, Zone zone, f(arg1, arg2));
+/*ABUSE*/
+typedef R RunHandler<R>(Zone self, ZoneDelegate parent, Zone zone, R f());
+/*ABUSE*/
+typedef R RunUnaryHandler<R, T>(
+ Zone self, ZoneDelegate parent, Zone zone, R f(T arg), T arg);
+/*ABUSE*/
+typedef R RunBinaryHandler<R, T1, T2>(
+ Zone self, ZoneDelegate parent, Zone zone,
+ R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2);
+/*ABUSE*/
+typedef ZoneCallback<R> RegisterCallbackHandler<R>(
+ Zone self, ZoneDelegate parent, Zone zone, R f());
+/*ABUSE*/
+typedef ZoneUnaryCallback<R, T> RegisterUnaryCallbackHandler<R, T>(
+ Zone self, ZoneDelegate parent, Zone zone, R f(T arg));
+/*ABUSE*/
+typedef ZoneBinaryCallback<R, T1, T2> RegisterBinaryCallbackHandler<R, T1, T2>(
+ Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2));
typedef AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent,
Zone zone, Object error, StackTrace stackTrace);
typedef void ScheduleMicrotaskHandler(
- Zone self, ZoneDelegate parent, Zone zone, f());
+ Zone self, ZoneDelegate parent, Zone zone, void f());
typedef Timer CreateTimerHandler(
Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f());
typedef Timer CreatePeriodicTimerHandler(
@@ -38,7 +48,7 @@
/** Pair of error and stack trace. Returned by [Zone.errorCallback]. */
class AsyncError implements Error {
- final error;
+ final Object error;
final StackTrace stackTrace;
AsyncError(this.error, this.stackTrace);
@@ -47,9 +57,9 @@
}
-class _ZoneFunction {
+class _ZoneFunction<T extends Function> {
final _Zone zone;
- final Function function;
+ final T function;
const _ZoneFunction(this.zone, this.function);
}
@@ -77,30 +87,19 @@
* Creates a specification with the provided handlers.
*/
const factory ZoneSpecification({
- dynamic handleUncaughtError(Zone self, ZoneDelegate parent, Zone zone,
- error, StackTrace stackTrace),
- dynamic run(Zone self, ZoneDelegate parent, Zone zone, f()),
- dynamic runUnary(
- Zone self, ZoneDelegate parent, Zone zone, f(arg), arg),
- dynamic runBinary(Zone self, ZoneDelegate parent, Zone zone,
- f(arg1, arg2), arg1, arg2),
- ZoneCallback registerCallback(
- Zone self, ZoneDelegate parent, Zone zone, f()),
- ZoneUnaryCallback registerUnaryCallback(
- Zone self, ZoneDelegate parent, Zone zone, f(arg)),
- ZoneBinaryCallback registerBinaryCallback(
- Zone self, ZoneDelegate parent, Zone zone, f(arg1, arg2)),
- AsyncError errorCallback(Zone self, ZoneDelegate parent, Zone zone,
- Object error, StackTrace stackTrace),
- void scheduleMicrotask(
- Zone self, ZoneDelegate parent, Zone zone, f()),
- Timer createTimer(Zone self, ZoneDelegate parent, Zone zone,
- Duration duration, void f()),
- Timer createPeriodicTimer(Zone self, ZoneDelegate parent, Zone zone,
- Duration period, void f(Timer timer)),
- void print(Zone self, ZoneDelegate parent, Zone zone, String line),
- Zone fork(Zone self, ZoneDelegate parent, Zone zone,
- ZoneSpecification specification, Map zoneValues)
+ HandleUncaughtErrorHandler handleUncaughtError,
+ RunHandler run,
+ RunUnaryHandler runUnary,
+ RunBinaryHandler runBinary,
+ RegisterCallbackHandler registerCallback,
+ RegisterUnaryCallbackHandler registerUnaryCallback,
+ RegisterBinaryCallbackHandler registerBinaryCallback,
+ ErrorCallbackHandler errorCallback,
+ ScheduleMicrotaskHandler scheduleMicrotask,
+ CreateTimerHandler createTimer,
+ CreatePeriodicTimerHandler createPeriodicTimer,
+ PrintHandler print,
+ ForkHandler fork
}) = _ZoneSpecification;
/**
@@ -108,31 +107,19 @@
* the ones in [other].
*/
factory ZoneSpecification.from(ZoneSpecification other, {
- dynamic handleUncaughtError(Zone self, ZoneDelegate parent, Zone zone,
- error, StackTrace stackTrace): null,
- dynamic run(Zone self, ZoneDelegate parent, Zone zone, f()): null,
- dynamic runUnary(
- Zone self, ZoneDelegate parent, Zone zone, f(arg), arg): null,
- dynamic runBinary(Zone self, ZoneDelegate parent, Zone zone,
- f(arg1, arg2), arg1, arg2): null,
- ZoneCallback registerCallback(
- Zone self, ZoneDelegate parent, Zone zone, f()): null,
- ZoneUnaryCallback registerUnaryCallback(
- Zone self, ZoneDelegate parent, Zone zone, f(arg)): null,
- ZoneBinaryCallback registerBinaryCallback(
- Zone self, ZoneDelegate parent, Zone zone, f(arg1, arg2)): null,
- AsyncError errorCallback(Zone self, ZoneDelegate parent, Zone zone,
- Object error, StackTrace stackTrace),
- void scheduleMicrotask(
- Zone self, ZoneDelegate parent, Zone zone, f()): null,
- Timer createTimer(Zone self, ZoneDelegate parent, Zone zone,
- Duration duration, void f()): null,
- Timer createPeriodicTimer(Zone self, ZoneDelegate parent, Zone zone,
- Duration period, void f(Timer timer)): null,
- void print(Zone self, ZoneDelegate parent, Zone zone, String line): null,
- Zone fork(Zone self, ZoneDelegate parent, Zone zone,
- ZoneSpecification specification,
- Map zoneValues): null
+ HandleUncaughtErrorHandler handleUncaughtError: null,
+ RunHandler run: null,
+ RunUnaryHandler runUnary: null,
+ RunBinaryHandler runBinary: null,
+ RegisterCallbackHandler registerCallback: null,
+ RegisterUnaryCallbackHandler registerUnaryCallback: null,
+ RegisterBinaryCallbackHandler registerBinaryCallback: null,
+ ErrorCallbackHandler errorCallback: null,
+ ScheduleMicrotaskHandler scheduleMicrotask: null,
+ CreateTimerHandler createTimer: null,
+ CreatePeriodicTimerHandler createPeriodicTimer: null,
+ PrintHandler print: null,
+ ForkHandler fork: null
}) {
return new ZoneSpecification(
handleUncaughtError: handleUncaughtError ?? other.handleUncaughtError,
@@ -217,15 +204,19 @@
* directly invoking the parent zone.
*/
abstract class ZoneDelegate {
- dynamic handleUncaughtError(Zone zone, error, StackTrace stackTrace);
- dynamic run(Zone zone, f());
- dynamic runUnary(Zone zone, f(arg), arg);
- dynamic runBinary(Zone zone, f(arg1, arg2), arg1, arg2);
- ZoneCallback registerCallback(Zone zone, f());
- ZoneUnaryCallback registerUnaryCallback(Zone zone, f(arg));
- ZoneBinaryCallback registerBinaryCallback(Zone zone, f(arg1, arg2));
+ /*=R*/ handleUncaughtError/*<R>*/(
+ Zone zone, error, StackTrace stackTrace);
+ /*=R*/ run/*<R>*/(Zone zone, /*=R*/ f());
+ /*=R*/ runUnary/*<R, T>*/(Zone zone, /*=R*/ f(/*=T*/ arg), /*=T*/ arg);
+ /*=R*/ runBinary/*<R, T1, T2>*/(Zone zone,
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2);
+ ZoneCallback/*<R>*/ registerCallback/*<R>*/(Zone zone, /*=R*/ f());
+ ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
+ Zone zone, /*=R*/ f(/*=T*/ arg));
+ ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
+ Zone zone, /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2));
AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace);
- void scheduleMicrotask(Zone zone, f());
+ void scheduleMicrotask(Zone zone, void f());
Timer createTimer(Zone zone, Duration duration, void f());
Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer));
void print(Zone zone, String line);
@@ -250,7 +241,7 @@
static Zone get current => _current;
- dynamic handleUncaughtError(error, StackTrace stackTrace);
+ /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace);
/**
* Returns the parent zone.
@@ -294,18 +285,19 @@
/**
* Executes the given function [f] in this zone.
*/
- dynamic run(f());
+ /*=R*/ run/*<R>*/(/*=R*/ f());
/**
* Executes the given callback [f] with argument [arg] in this zone.
*/
- dynamic runUnary(f(arg), var arg);
+ /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg);
/**
* Executes the given callback [f] with argument [arg1] and [arg2] in this
* zone.
*/
- dynamic runBinary(f(arg1, arg2), var arg1, var arg2);
+ /*=R*/ runBinary/*<R, T1, T2>*/(
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2);
/**
* Executes the given function [f] in this zone.
@@ -313,7 +305,7 @@
* Same as [run] but catches uncaught errors and gives them to
* [handleUncaughtError].
*/
- dynamic runGuarded(f());
+ /*=R*/ runGuarded/*<R>*/(/*=R*/ f());
/**
* Executes the given callback [f] in this zone.
@@ -321,7 +313,7 @@
* Same as [runUnary] but catches uncaught errors and gives them to
* [handleUncaughtError].
*/
- dynamic runUnaryGuarded(f(arg), var arg);
+ /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg);
/**
* Executes the given callback [f] in this zone.
@@ -329,7 +321,8 @@
* Same as [runBinary] but catches uncaught errors and gives them to
* [handleUncaughtError].
*/
- dynamic runBinaryGuarded(f(arg1, arg2), var arg1, var arg2);
+ /*=R*/ runBinaryGuarded/*<R, T1, T2>*/(
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2);
/**
* Registers the given callback in this zone.
@@ -343,21 +336,23 @@
* Returns a potentially new callback that should be used in place of the
* given [callback].
*/
- ZoneCallback registerCallback(callback());
+ ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback());
/**
* Registers the given callback in this zone.
*
* Similar to [registerCallback] but with a unary callback.
*/
- ZoneUnaryCallback registerUnaryCallback(callback(arg));
+ ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
+ /*=R*/ callback(/*=T*/ arg));
/**
* Registers the given callback in this zone.
*
* Similar to [registerCallback] but with a unary callback.
*/
- ZoneBinaryCallback registerBinaryCallback(callback(arg1, arg2));
+ ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
+ /*=R*/ callback(/*=T1*/ arg1, /*=T2*/ arg2));
/**
* Equivalent to:
@@ -367,7 +362,8 @@
* return () => this.run(registered);
*
*/
- ZoneCallback bindCallback(f(), { bool runGuarded: true });
+ ZoneCallback/*<R>*/ bindCallback/*<R>*/(
+ /*=R*/ f(), { bool runGuarded: true });
/**
* Equivalent to:
@@ -376,7 +372,8 @@
* if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg);
* return (arg) => thin.runUnary(registered, arg);
*/
- ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded: true });
+ ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/(
+ /*=R*/ f(/*=T*/ arg), { bool runGuarded: true });
/**
* Equivalent to:
@@ -387,11 +384,11 @@
* }
* return (arg1, arg2) => thin.runBinary(registered, arg1, arg2);
*/
- ZoneBinaryCallback bindBinaryCallback(
- f(arg1, arg2), { bool runGuarded: true });
+ ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/(
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true });
/**
- * Intercepts errors when added programmtically to a `Future` or `Stream`.
+ * Intercepts errors when added programmatically to a `Future` or `Stream`.
*
* When caling [Completer.completeError], [Stream.addError],
* or [Future] constructors that take an error or a callback that may throw,
@@ -475,60 +472,84 @@
_ZoneDelegate(this._delegationTarget);
- dynamic handleUncaughtError(Zone zone, error, StackTrace stackTrace) {
- _ZoneFunction implementation = _delegationTarget._handleUncaughtError;
+ /*=R*/ handleUncaughtError/*<R>*/(
+ Zone zone, error, StackTrace stackTrace) {
+ var implementation = _delegationTarget._handleUncaughtError;
_Zone implZone = implementation.zone;
HandleUncaughtErrorHandler handler = implementation.function;
+ // TODO(floitsch): make this a generic method call on '<R>' once it's
+ // supported. Remove the unnecessary cast.
return handler(
- implZone, _parentDelegate(implZone), zone, error, stackTrace);
+ implZone, _parentDelegate(implZone), zone, error, stackTrace)
+ as Object/*=R*/;
}
- dynamic run(Zone zone, f()) {
- _ZoneFunction implementation = _delegationTarget._run;
+ /*=R*/ run/*<R>*/(Zone zone, /*=R*/ f()) {
+ var implementation = _delegationTarget._run;
_Zone implZone = implementation.zone;
RunHandler handler = implementation.function;
- return handler(implZone, _parentDelegate(implZone), zone, f);
+ // TODO(floitsch): make this a generic method call on '<R>' once it's
+ // supported. Remove the unnecessary cast.
+ return handler(implZone, _parentDelegate(implZone), zone, f)
+ as Object/*=R*/;
}
- dynamic runUnary(Zone zone, f(arg), arg) {
- _ZoneFunction implementation = _delegationTarget._runUnary;
+ /*=R*/ runUnary/*<R, T>*/(Zone zone, /*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
+ var implementation = _delegationTarget._runUnary;
_Zone implZone = implementation.zone;
RunUnaryHandler handler = implementation.function;
+ // TODO(floitsch): make this a generic method call on '<R, T>' once it's
+ // supported. Remove the unnecessary cast.
return handler(
- implZone, _parentDelegate(implZone), zone, f, arg);
+ implZone, _parentDelegate(implZone), zone, f, arg) as Object/*=R*/;
}
- dynamic runBinary(Zone zone, f(arg1, arg2), arg1, arg2) {
- _ZoneFunction implementation = _delegationTarget._runBinary;
+ /*=R*/ runBinary/*<R, T1, T2>*/(Zone zone,
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
+ var implementation = _delegationTarget._runBinary;
_Zone implZone = implementation.zone;
RunBinaryHandler handler = implementation.function;
+ // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once
+ // it's supported. Remove the unnecessary cast.
return handler(
- implZone, _parentDelegate(implZone), zone, f, arg1, arg2);
+ implZone, _parentDelegate(implZone), zone, f, arg1, arg2)
+ as Object/*=R*/;
}
- ZoneCallback registerCallback(Zone zone, f()) {
- _ZoneFunction implementation = _delegationTarget._registerCallback;
+ ZoneCallback/*<R>*/ registerCallback/*<R>*/(Zone zone, /*=R*/ f()) {
+ var implementation = _delegationTarget._registerCallback;
_Zone implZone = implementation.zone;
RegisterCallbackHandler handler = implementation.function;
- return handler(implZone, _parentDelegate(implZone), zone, f);
+ // TODO(floitsch): make this a generic method call on '<R>' once it's
+ // supported. Remove the unnecessary cast.
+ return handler(implZone, _parentDelegate(implZone), zone, f)
+ as Object/*=ZoneCallback<R>*/;
}
- ZoneUnaryCallback registerUnaryCallback(Zone zone, f(arg)) {
- _ZoneFunction implementation = _delegationTarget._registerUnaryCallback;
+ ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
+ Zone zone, /*=R*/ f(/*=T*/ arg)) {
+ var implementation = _delegationTarget._registerUnaryCallback;
_Zone implZone = implementation.zone;
RegisterUnaryCallbackHandler handler = implementation.function;
- return handler(implZone, _parentDelegate(implZone), zone, f);
+ // TODO(floitsch): make this a generic method call on '<R, T>' once it's
+ // supported. Remove the unnecessary cast.
+ return handler(implZone, _parentDelegate(implZone), zone, f)
+ as Object/*=ZoneUnaryCallback<R, T>*/;
}
- ZoneBinaryCallback registerBinaryCallback(Zone zone, f(arg1, arg2)) {
- _ZoneFunction implementation = _delegationTarget._registerBinaryCallback;
+ ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
+ Zone zone, /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2)) {
+ var implementation = _delegationTarget._registerBinaryCallback;
_Zone implZone = implementation.zone;
RegisterBinaryCallbackHandler handler = implementation.function;
- return handler(implZone, _parentDelegate(implZone), zone, f);
+ // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once
+ // it's supported. Remove the unnecessary cast.
+ return handler(implZone, _parentDelegate(implZone), zone, f)
+ as Object/*=ZoneBinaryCallback<R, T1, T2>*/;
}
AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) {
- _ZoneFunction implementation = _delegationTarget._errorCallback;
+ var implementation = _delegationTarget._errorCallback;
_Zone implZone = implementation.zone;
if (identical(implZone, _ROOT_ZONE)) return null;
ErrorCallbackHandler handler = implementation.function;
@@ -537,28 +558,28 @@
}
void scheduleMicrotask(Zone zone, f()) {
- _ZoneFunction implementation = _delegationTarget._scheduleMicrotask;
+ var implementation = _delegationTarget._scheduleMicrotask;
_Zone implZone = implementation.zone;
ScheduleMicrotaskHandler handler = implementation.function;
handler(implZone, _parentDelegate(implZone), zone, f);
}
Timer createTimer(Zone zone, Duration duration, void f()) {
- _ZoneFunction implementation = _delegationTarget._createTimer;
+ var implementation = _delegationTarget._createTimer;
_Zone implZone = implementation.zone;
CreateTimerHandler handler = implementation.function;
return handler(implZone, _parentDelegate(implZone), zone, duration, f);
}
Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) {
- _ZoneFunction implementation = _delegationTarget._createPeriodicTimer;
+ var implementation = _delegationTarget._createPeriodicTimer;
_Zone implZone = implementation.zone;
CreatePeriodicTimerHandler handler = implementation.function;
return handler(implZone, _parentDelegate(implZone), zone, period, f);
}
void print(Zone zone, String line) {
- _ZoneFunction implementation = _delegationTarget._print;
+ var implementation = _delegationTarget._print;
_Zone implZone = implementation.zone;
PrintHandler handler = implementation.function;
handler(implZone, _parentDelegate(implZone), zone, line);
@@ -566,7 +587,7 @@
Zone fork(Zone zone, ZoneSpecification specification,
Map zoneValues) {
- _ZoneFunction implementation = _delegationTarget._fork;
+ var implementation = _delegationTarget._fork;
_Zone implZone = implementation.zone;
ForkHandler handler = implementation.function;
return handler(
@@ -581,21 +602,21 @@
abstract class _Zone implements Zone {
const _Zone();
- _ZoneFunction get _runUnary;
- _ZoneFunction get _run;
- _ZoneFunction get _runBinary;
- _ZoneFunction get _registerCallback;
- _ZoneFunction get _registerUnaryCallback;
- _ZoneFunction get _registerBinaryCallback;
- _ZoneFunction get _errorCallback;
- _ZoneFunction get _scheduleMicrotask;
- _ZoneFunction get _createTimer;
- _ZoneFunction get _createPeriodicTimer;
- _ZoneFunction get _print;
- _ZoneFunction get _fork;
- _ZoneFunction get _handleUncaughtError;
+ _ZoneFunction<RunHandler> get _run;
+ _ZoneFunction<RunUnaryHandler> get _runUnary;
+ _ZoneFunction<RunBinaryHandler> get _runBinary;
+ _ZoneFunction<RegisterCallbackHandler> get _registerCallback;
+ _ZoneFunction<RegisterUnaryCallbackHandler> get _registerUnaryCallback;
+ _ZoneFunction<RegisterBinaryCallbackHandler> get _registerBinaryCallback;
+ _ZoneFunction<ErrorCallbackHandler> get _errorCallback;
+ _ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask;
+ _ZoneFunction<CreateTimerHandler> get _createTimer;
+ _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer;
+ _ZoneFunction<PrintHandler> get _print;
+ _ZoneFunction<ForkHandler> get _fork;
+ _ZoneFunction<HandleUncaughtErrorHandler> get _handleUncaughtError;
_Zone get parent;
- _ZoneDelegate get _delegate;
+ ZoneDelegate get _delegate;
Map get _map;
bool inSameErrorZone(Zone otherZone) {
@@ -607,19 +628,19 @@
class _CustomZone extends _Zone {
// The actual zone and implementation of each of these
// inheritable zone functions.
- _ZoneFunction _runUnary;
- _ZoneFunction _run;
- _ZoneFunction _runBinary;
- _ZoneFunction _registerCallback;
- _ZoneFunction _registerUnaryCallback;
- _ZoneFunction _registerBinaryCallback;
- _ZoneFunction _errorCallback;
- _ZoneFunction _scheduleMicrotask;
- _ZoneFunction _createTimer;
- _ZoneFunction _createPeriodicTimer;
- _ZoneFunction _print;
- _ZoneFunction _fork;
- _ZoneFunction _handleUncaughtError;
+ _ZoneFunction<RunHandler> _run;
+ _ZoneFunction<RunUnaryHandler> _runUnary;
+ _ZoneFunction<RunBinaryHandler> _runBinary;
+ _ZoneFunction<RegisterCallbackHandler> _registerCallback;
+ _ZoneFunction<RegisterUnaryCallbackHandler> _registerUnaryCallback;
+ _ZoneFunction<RegisterBinaryCallbackHandler> _registerBinaryCallback;
+ _ZoneFunction<ErrorCallbackHandler> _errorCallback;
+ _ZoneFunction<ScheduleMicrotaskHandler> _scheduleMicrotask;
+ _ZoneFunction<CreateTimerHandler> _createTimer;
+ _ZoneFunction<CreatePeriodicTimerHandler> _createPeriodicTimer;
+ _ZoneFunction<PrintHandler> _print;
+ _ZoneFunction<ForkHandler> _fork;
+ _ZoneFunction<HandleUncaughtErrorHandler> _handleUncaughtError;
// A cached delegate to this zone.
ZoneDelegate _delegateCache;
@@ -643,43 +664,50 @@
// specification, so it will never try to access the (null) parent.
// All other zones have a non-null parent.
_run = (specification.run != null)
- ? new _ZoneFunction(this, specification.run)
+ ? new _ZoneFunction<RunHandler>(this, specification.run)
: parent._run;
_runUnary = (specification.runUnary != null)
- ? new _ZoneFunction(this, specification.runUnary)
+ ? new _ZoneFunction<RunUnaryHandler>(this, specification.runUnary)
: parent._runUnary;
_runBinary = (specification.runBinary != null)
- ? new _ZoneFunction(this, specification.runBinary)
+ ? new _ZoneFunction<RunBinaryHandler>(this, specification.runBinary)
: parent._runBinary;
_registerCallback = (specification.registerCallback != null)
- ? new _ZoneFunction(this, specification.registerCallback)
+ ? new _ZoneFunction<RegisterCallbackHandler>(
+ this, specification.registerCallback)
: parent._registerCallback;
_registerUnaryCallback = (specification.registerUnaryCallback != null)
- ? new _ZoneFunction(this, specification.registerUnaryCallback)
+ ? new _ZoneFunction<RegisterUnaryCallbackHandler>(
+ this, specification.registerUnaryCallback)
: parent._registerUnaryCallback;
_registerBinaryCallback = (specification.registerBinaryCallback != null)
- ? new _ZoneFunction(this, specification.registerBinaryCallback)
+ ? new _ZoneFunction<RegisterBinaryCallbackHandler>(
+ this, specification.registerBinaryCallback)
: parent._registerBinaryCallback;
_errorCallback = (specification.errorCallback != null)
- ? new _ZoneFunction(this, specification.errorCallback)
+ ? new _ZoneFunction<ErrorCallbackHandler>(
+ this, specification.errorCallback)
: parent._errorCallback;
_scheduleMicrotask = (specification.scheduleMicrotask != null)
- ? new _ZoneFunction(this, specification.scheduleMicrotask)
+ ? new _ZoneFunction<ScheduleMicrotaskHandler>(
+ this, specification.scheduleMicrotask)
: parent._scheduleMicrotask;
_createTimer = (specification.createTimer != null)
- ? new _ZoneFunction(this, specification.createTimer)
+ ? new _ZoneFunction<CreateTimerHandler>(this, specification.createTimer)
: parent._createTimer;
_createPeriodicTimer = (specification.createPeriodicTimer != null)
- ? new _ZoneFunction(this, specification.createPeriodicTimer)
+ ? new _ZoneFunction<CreatePeriodicTimerHandler>(
+ this, specification.createPeriodicTimer)
: parent._createPeriodicTimer;
_print = (specification.print != null)
- ? new _ZoneFunction(this, specification.print)
+ ? new _ZoneFunction<PrintHandler>(this, specification.print)
: parent._print;
_fork = (specification.fork != null)
- ? new _ZoneFunction(this, specification.fork)
+ ? new _ZoneFunction<ForkHandler>(this, specification.fork)
: parent._fork;
_handleUncaughtError = (specification.handleUncaughtError != null)
- ? new _ZoneFunction(this, specification.handleUncaughtError)
+ ? new _ZoneFunction<HandleUncaughtErrorHandler>(
+ this, specification.handleUncaughtError)
: parent._handleUncaughtError;
}
@@ -691,7 +719,7 @@
*/
Zone get errorZone => _handleUncaughtError.zone;
- dynamic runGuarded(f()) {
+ /*=R*/ runGuarded/*<R>*/(/*=R*/ f()) {
try {
return run(f);
} catch (e, s) {
@@ -699,7 +727,7 @@
}
}
- dynamic runUnaryGuarded(f(arg), arg) {
+ /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
try {
return runUnary(f, arg);
} catch (e, s) {
@@ -707,7 +735,8 @@
}
}
- dynamic runBinaryGuarded(f(arg1, arg2), arg1, arg2) {
+ /*=R*/ runBinaryGuarded/*<R, T1, T2>*/(
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
try {
return runBinary(f, arg1, arg2);
} catch (e, s) {
@@ -715,8 +744,9 @@
}
}
- ZoneCallback bindCallback(f(), { bool runGuarded: true }) {
- ZoneCallback registered = registerCallback(f);
+ ZoneCallback/*<R>*/ bindCallback/*<R>*/(
+ /*=R*/ f(), { bool runGuarded: true }) {
+ var registered = registerCallback(f);
if (runGuarded) {
return () => this.runGuarded(registered);
} else {
@@ -724,8 +754,9 @@
}
}
- ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded: true }) {
- ZoneUnaryCallback registered = registerUnaryCallback(f);
+ ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/(
+ /*=R*/ f(/*=T*/ arg), { bool runGuarded: true }) {
+ var registered = registerUnaryCallback(f);
if (runGuarded) {
return (arg) => this.runUnaryGuarded(registered, arg);
} else {
@@ -733,9 +764,9 @@
}
}
- ZoneBinaryCallback bindBinaryCallback(
- f(arg1, arg2), { bool runGuarded: true }) {
- ZoneBinaryCallback registered = registerBinaryCallback(f);
+ ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/(
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true }) {
+ var registered = registerBinaryCallback(f);
if (runGuarded) {
return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2);
} else {
@@ -764,17 +795,20 @@
// Methods that can be customized by the zone specification.
- dynamic handleUncaughtError(error, StackTrace stackTrace) {
- _ZoneFunction implementation = this._handleUncaughtError;
+ /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace) {
+ var implementation = this._handleUncaughtError;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
HandleUncaughtErrorHandler handler = implementation.function;
+ // TODO(floitsch): make this a generic method call on '<R>' once it's
+ // supported. Remove the unnecessary cast.
return handler(
- implementation.zone, parentDelegate, this, error, stackTrace);
+ implementation.zone, parentDelegate, this, error, stackTrace)
+ as Object/*=R*/;
}
Zone fork({ZoneSpecification specification, Map zoneValues}) {
- _ZoneFunction implementation = this._fork;
+ var implementation = this._fork;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
ForkHandler handler = implementation.function;
@@ -782,57 +816,78 @@
specification, zoneValues);
}
- dynamic run(f()) {
- _ZoneFunction implementation = this._run;
+ /*=R*/ run/*<R>*/(/*=R*/ f()) {
+ var implementation = this._run;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
RunHandler handler = implementation.function;
- return handler(implementation.zone, parentDelegate, this, f);
+ // TODO(floitsch): make this a generic method call on '<R>' once it's
+ // supported. Remove the unnecessary cast.
+ return handler(implementation.zone, parentDelegate, this, f)
+ as Object/*=R*/;
}
- dynamic runUnary(f(arg), arg) {
- _ZoneFunction implementation = this._runUnary;
+ /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
+ var implementation = this._runUnary;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
RunUnaryHandler handler = implementation.function;
- return handler(implementation.zone, parentDelegate, this, f, arg);
+ // TODO(floitsch): make this a generic method call on '<R, T>' once it's
+ // supported. Remove the unnecessary cast.
+ return handler(implementation.zone, parentDelegate, this, f, arg)
+ as Object/*=R*/;
}
- dynamic runBinary(f(arg1, arg2), arg1, arg2) {
- _ZoneFunction implementation = this._runBinary;
+ /*=R*/ runBinary/*<R, T1, T2>*/(
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
+ var implementation = this._runBinary;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
RunBinaryHandler handler = implementation.function;
+ // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once
+ // it's supported. Remove the unnecessary cast.
return handler(
- implementation.zone, parentDelegate, this, f, arg1, arg2);
+ implementation.zone, parentDelegate, this, f, arg1, arg2)
+ as Object/*=R*/;
}
- ZoneCallback registerCallback(f()) {
- _ZoneFunction implementation = this._registerCallback;
+ ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback()) {
+ var implementation = this._registerCallback;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
RegisterCallbackHandler handler = implementation.function;
- return handler(implementation.zone, parentDelegate, this, f);
+ // TODO(floitsch): make this a generic method call on '<R>' once it's
+ // supported. Remove the unnecessary cast.
+ return handler(implementation.zone, parentDelegate, this, callback)
+ as Object/*=ZoneCallback<R>*/;
}
- ZoneUnaryCallback registerUnaryCallback(f(arg)) {
- _ZoneFunction implementation = this._registerUnaryCallback;
+ ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
+ /*=R*/ callback(/*=T*/ arg)) {
+ var implementation = this._registerUnaryCallback;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
RegisterUnaryCallbackHandler handler = implementation.function;
- return handler(implementation.zone, parentDelegate, this, f);
+ // TODO(floitsch): make this a generic method call on '<R, T>' once it's
+ // supported. Remove the unnecessary cast.
+ return handler(implementation.zone, parentDelegate, this, callback)
+ as Object/*=ZoneUnaryCallback<R, T>*/;
}
- ZoneBinaryCallback registerBinaryCallback(f(arg1, arg2)) {
- _ZoneFunction implementation = this._registerBinaryCallback;
+ ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
+ /*=R*/ callback(/*=T1*/ arg1, /*=T2*/ arg2)) {
+ var implementation = this._registerBinaryCallback;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
RegisterBinaryCallbackHandler handler = implementation.function;
- return handler(implementation.zone, parentDelegate, this, f);
+ // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once
+ // it's supported. Remove the unnecessary cast.
+ return handler(implementation.zone, parentDelegate, this, callback)
+ as Object/*=ZoneBinaryCallback<R, T1, T2>*/;
}
AsyncError errorCallback(Object error, StackTrace stackTrace) {
- final _ZoneFunction implementation = this._errorCallback;
+ var implementation = this._errorCallback;
assert(implementation != null);
final Zone implementationZone = implementation.zone;
if (identical(implementationZone, _ROOT_ZONE)) return null;
@@ -843,7 +898,7 @@
}
void scheduleMicrotask(void f()) {
- _ZoneFunction implementation = this._scheduleMicrotask;
+ var implementation = this._scheduleMicrotask;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
ScheduleMicrotaskHandler handler = implementation.function;
@@ -851,7 +906,7 @@
}
Timer createTimer(Duration duration, void f()) {
- _ZoneFunction implementation = this._createTimer;
+ var implementation = this._createTimer;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
CreateTimerHandler handler = implementation.function;
@@ -859,7 +914,7 @@
}
Timer createPeriodicTimer(Duration duration, void f(Timer timer)) {
- _ZoneFunction implementation = this._createPeriodicTimer;
+ var implementation = this._createPeriodicTimer;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
CreatePeriodicTimerHandler handler = implementation.function;
@@ -868,7 +923,7 @@
}
void print(String line) {
- _ZoneFunction implementation = this._print;
+ var implementation = this._print;
assert(implementation != null);
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
PrintHandler handler = implementation.function;
@@ -876,7 +931,7 @@
}
}
-void _rootHandleUncaughtError(
+/*=R*/ _rootHandleUncaughtError/*<R>*/(
Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) {
_schedulePriorityAsyncCallback(() {
if (error == null) error = new NullThrownError();
@@ -887,7 +942,7 @@
external void _rethrow(Object error, StackTrace stackTrace);
-dynamic _rootRun(Zone self, ZoneDelegate parent, Zone zone, f()) {
+/*=R*/ _rootRun/*<R>*/(Zone self, ZoneDelegate parent, Zone zone, /*=R*/ f()) {
if (Zone._current == zone) return f();
Zone old = Zone._enter(zone);
@@ -898,7 +953,8 @@
}
}
-dynamic _rootRunUnary(Zone self, ZoneDelegate parent, Zone zone, f(arg), arg) {
+/*=R*/ _rootRunUnary/*<R, T>*/(Zone self, ZoneDelegate parent, Zone zone,
+ /*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
if (Zone._current == zone) return f(arg);
Zone old = Zone._enter(zone);
@@ -909,8 +965,8 @@
}
}
-dynamic _rootRunBinary(Zone self, ZoneDelegate parent, Zone zone,
- f(arg1, arg2), arg1, arg2) {
+/*=R*/ _rootRunBinary/*<R, T1, T2>*/(Zone self, ZoneDelegate parent, Zone zone,
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
if (Zone._current == zone) return f(arg1, arg2);
Zone old = Zone._enter(zone);
@@ -921,18 +977,19 @@
}
}
-ZoneCallback _rootRegisterCallback(
- Zone self, ZoneDelegate parent, Zone zone, f()) {
+ZoneCallback/*<R>*/ _rootRegisterCallback/*<R>*/(
+ Zone self, ZoneDelegate parent, Zone zone, /*=R*/ f()) {
return f;
}
-ZoneUnaryCallback _rootRegisterUnaryCallback(
- Zone self, ZoneDelegate parent, Zone zone, f(arg)) {
+ZoneUnaryCallback/*<R, T>*/ _rootRegisterUnaryCallback/*<R, T>*/(
+ Zone self, ZoneDelegate parent, Zone zone, /*=R*/ f(/*=T*/ arg)) {
return f;
}
-ZoneBinaryCallback _rootRegisterBinaryCallback(
- Zone self, ZoneDelegate parent, Zone zone, f(arg1, arg2)) {
+ZoneBinaryCallback/*<R, T1, T2>*/ _rootRegisterBinaryCallback/*<R, T1, T2>*/(
+ Zone self, ZoneDelegate parent, Zone zone,
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2)) {
return f;
}
@@ -961,7 +1018,8 @@
Zone self, ZoneDelegate parent, Zone zone,
Duration duration, void callback(Timer timer)) {
if (!identical(_ROOT_ZONE, zone)) {
- callback = zone.bindUnaryCallback(callback);
+ // TODO(floitsch): the return type should be 'void'.
+ callback = zone.bindUnaryCallback/*<dynamic, Timer>*/(callback);
}
return Timer._createPeriodicTimer(duration, callback);
}
@@ -1004,32 +1062,37 @@
class _RootZone extends _Zone {
const _RootZone();
- _ZoneFunction get _run =>
- const _ZoneFunction(_ROOT_ZONE, _rootRun);
- _ZoneFunction get _runUnary =>
- const _ZoneFunction(_ROOT_ZONE, _rootRunUnary);
- _ZoneFunction get _runBinary =>
- const _ZoneFunction(_ROOT_ZONE, _rootRunBinary);
- _ZoneFunction get _registerCallback =>
- const _ZoneFunction(_ROOT_ZONE, _rootRegisterCallback);
- _ZoneFunction get _registerUnaryCallback =>
- const _ZoneFunction(_ROOT_ZONE, _rootRegisterUnaryCallback);
- _ZoneFunction get _registerBinaryCallback =>
- const _ZoneFunction(_ROOT_ZONE, _rootRegisterBinaryCallback);
- _ZoneFunction get _errorCallback =>
- const _ZoneFunction(_ROOT_ZONE, _rootErrorCallback);
- _ZoneFunction get _scheduleMicrotask =>
- const _ZoneFunction(_ROOT_ZONE, _rootScheduleMicrotask);
- _ZoneFunction get _createTimer =>
- const _ZoneFunction(_ROOT_ZONE, _rootCreateTimer);
- _ZoneFunction get _createPeriodicTimer =>
- const _ZoneFunction(_ROOT_ZONE, _rootCreatePeriodicTimer);
- _ZoneFunction get _print =>
- const _ZoneFunction(_ROOT_ZONE, _rootPrint);
- _ZoneFunction get _fork =>
- const _ZoneFunction(_ROOT_ZONE, _rootFork);
- _ZoneFunction get _handleUncaughtError =>
- const _ZoneFunction(_ROOT_ZONE, _rootHandleUncaughtError);
+ _ZoneFunction<RunHandler> get _run =>
+ const _ZoneFunction<RunHandler>(_ROOT_ZONE, _rootRun);
+ _ZoneFunction<RunUnaryHandler> get _runUnary =>
+ const _ZoneFunction<RunUnaryHandler>(_ROOT_ZONE, _rootRunUnary);
+ _ZoneFunction<RunBinaryHandler> get _runBinary =>
+ const _ZoneFunction<RunBinaryHandler>(_ROOT_ZONE, _rootRunBinary);
+ _ZoneFunction<RegisterCallbackHandler> get _registerCallback =>
+ const _ZoneFunction<RegisterCallbackHandler>(
+ _ROOT_ZONE, _rootRegisterCallback);
+ _ZoneFunction<RegisterUnaryCallbackHandler> get _registerUnaryCallback =>
+ const _ZoneFunction<RegisterUnaryCallbackHandler>(
+ _ROOT_ZONE, _rootRegisterUnaryCallback);
+ _ZoneFunction<RegisterBinaryCallbackHandler> get _registerBinaryCallback =>
+ const _ZoneFunction<RegisterBinaryCallbackHandler>(
+ _ROOT_ZONE, _rootRegisterBinaryCallback);
+ _ZoneFunction<ErrorCallbackHandler> get _errorCallback =>
+ const _ZoneFunction<ErrorCallbackHandler>(_ROOT_ZONE, _rootErrorCallback);
+ _ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask =>
+ const _ZoneFunction<ScheduleMicrotaskHandler>(
+ _ROOT_ZONE, _rootScheduleMicrotask);
+ _ZoneFunction<CreateTimerHandler> get _createTimer =>
+ const _ZoneFunction<CreateTimerHandler>(_ROOT_ZONE, _rootCreateTimer);
+ _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer =>
+ const _ZoneFunction<CreatePeriodicTimerHandler>(_ROOT_ZONE, _rootCreatePeriodicTimer);
+ _ZoneFunction<PrintHandler> get _print =>
+ const _ZoneFunction<PrintHandler>(_ROOT_ZONE, _rootPrint);
+ _ZoneFunction<ForkHandler> get _fork =>
+ const _ZoneFunction<ForkHandler>(_ROOT_ZONE, _rootFork);
+ _ZoneFunction<HandleUncaughtErrorHandler> get _handleUncaughtError =>
+ const _ZoneFunction<HandleUncaughtErrorHandler>(
+ _ROOT_ZONE, _rootHandleUncaughtError);
// The parent zone.
_Zone get parent => null;
@@ -1058,61 +1121,65 @@
// Zone interface.
- dynamic runGuarded(f()) {
+ /*=R*/ runGuarded/*<R>*/(/*=R*/ f()) {
try {
if (identical(_ROOT_ZONE, Zone._current)) {
return f();
}
- return _rootRun(null, null, this, f);
+ return _rootRun/*<R>*/(null, null, this, f);
} catch (e, s) {
- return handleUncaughtError(e, s);
+ return handleUncaughtError/*<R>*/(e, s);
}
}
- dynamic runUnaryGuarded(f(arg), arg) {
+ /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
try {
if (identical(_ROOT_ZONE, Zone._current)) {
return f(arg);
}
- return _rootRunUnary(null, null, this, f, arg);
+ return _rootRunUnary/*<R, T>*/(null, null, this, f, arg);
} catch (e, s) {
- return handleUncaughtError(e, s);
+ return handleUncaughtError/*<R>*/(e, s);
}
}
- dynamic runBinaryGuarded(f(arg1, arg2), arg1, arg2) {
+ /*=R*/ runBinaryGuarded/*<R, T1, T2>*/(
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
try {
if (identical(_ROOT_ZONE, Zone._current)) {
return f(arg1, arg2);
}
- return _rootRunBinary(null, null, this, f, arg1, arg2);
+ return _rootRunBinary/*<R, T1, T2>*/(null, null, this, f, arg1, arg2);
} catch (e, s) {
- return handleUncaughtError(e, s);
+ return handleUncaughtError/*<R>*/(e, s);
}
}
- ZoneCallback bindCallback(f(), { bool runGuarded: true }) {
+ ZoneCallback/*<R>*/ bindCallback/*<R>*/(
+ /*=R*/ f(), { bool runGuarded: true }) {
if (runGuarded) {
- return () => this.runGuarded(f);
+ return () => this.runGuarded/*<R>*/(f);
} else {
- return () => this.run(f);
+ return () => this.run/*<R>*/(f);
}
}
- ZoneUnaryCallback bindUnaryCallback(f(arg), { bool runGuarded: true }) {
+ ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/(
+ /*=R*/ f(/*=T*/ arg), { bool runGuarded: true }) {
if (runGuarded) {
- return (arg) => this.runUnaryGuarded(f, arg);
+ return (arg) => this.runUnaryGuarded/*<R, T>*/(f, arg);
} else {
- return (arg) => this.runUnary(f, arg);
+ return (arg) => this.runUnary/*<R, T>*/(f, arg);
}
}
- ZoneBinaryCallback bindBinaryCallback(
- f(arg1, arg2), { bool runGuarded: true }) {
+ ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/(
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true }) {
if (runGuarded) {
- return (arg1, arg2) => this.runBinaryGuarded(f, arg1, arg2);
+ return (arg1, arg2) =>
+ this.runBinaryGuarded/*<R, T1, T2>*/(f, arg1, arg2);
} else {
- return (arg1, arg2) => this.runBinary(f, arg1, arg2);
+ return (arg1, arg2) => this.runBinary/*<R, T1, T2>*/(f, arg1, arg2);
}
}
@@ -1120,7 +1187,7 @@
// Methods that can be customized by the zone specification.
- dynamic handleUncaughtError(error, StackTrace stackTrace) {
+ /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace) {
return _rootHandleUncaughtError(null, null, this, error, stackTrace);
}
@@ -1128,26 +1195,29 @@
return _rootFork(null, null, this, specification, zoneValues);
}
- dynamic run(f()) {
+ /*=R*/ run/*<R>*/(/*=R*/ f()) {
if (identical(Zone._current, _ROOT_ZONE)) return f();
return _rootRun(null, null, this, f);
}
- dynamic runUnary(f(arg), arg) {
+ /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
if (identical(Zone._current, _ROOT_ZONE)) return f(arg);
return _rootRunUnary(null, null, this, f, arg);
}
- dynamic runBinary(f(arg1, arg2), arg1, arg2) {
+ /*=R*/ runBinary/*<R, T1, T2>*/(
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
if (identical(Zone._current, _ROOT_ZONE)) return f(arg1, arg2);
return _rootRunBinary(null, null, this, f, arg1, arg2);
}
- ZoneCallback registerCallback(f()) => f;
+ ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ f()) => f;
- ZoneUnaryCallback registerUnaryCallback(f(arg)) => f;
+ ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
+ /*=R*/ f(/*=T*/ arg)) => f;
- ZoneBinaryCallback registerBinaryCallback(f(arg1, arg2)) => f;
+ ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
+ /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2)) => f;
AsyncError errorCallback(Object error, StackTrace stackTrace) => null;
@@ -1195,7 +1265,7 @@
* new Future(() { throw "asynchronous error"; });
* }, onError: print); // Will print "asynchronous error".
*/
-dynamic runZoned(body(),
+/*=R*/ runZoned/*<R>*/(/*=R*/ body(),
{ Map zoneValues,
ZoneSpecification zoneSpecification,
Function onError }) {
@@ -1204,7 +1274,7 @@
errorHandler = (Zone self, ZoneDelegate parent, Zone zone,
error, StackTrace stackTrace) {
try {
- if (onError is ZoneBinaryCallback) {
+ if (onError is ZoneBinaryCallback<dynamic/*=R*/, dynamic, StackTrace>) {
return self.parent.runBinary(onError, error, stackTrace);
}
return self.parent.runUnary(onError, error);
diff --git a/sdk/lib/collection/linked_hash_set.dart b/sdk/lib/collection/linked_hash_set.dart
index a149692..e087b5f 100644
--- a/sdk/lib/collection/linked_hash_set.dart
+++ b/sdk/lib/collection/linked_hash_set.dart
@@ -102,7 +102,7 @@
* Iterable<SuperType> tmp = superSet.where((e) => e is SubType);
* Set<SubType> subSet = new LinkedHashSet<SubType>.from(tmp);
*/
- factory LinkedHashSet.from(Iterable<E> elements) {
+ factory LinkedHashSet.from(Iterable elements) {
LinkedHashSet<E> result = new LinkedHashSet<E>();
for (final E element in elements) {
result.add(element);
diff --git a/sdk/lib/convert/base64.dart b/sdk/lib/convert/base64.dart
index ff3a439..f3d7019 100644
--- a/sdk/lib/convert/base64.dart
+++ b/sdk/lib/convert/base64.dart
@@ -28,9 +28,9 @@
*
* Examples:
*
- * var encoded = BASE64.encode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6,
- * 0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
- * var decoded = BASE64.decode("YmzDpWLDpnJncsO4ZAo=");
+ * var encoded = BASE64URL.encode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6,
+ * 0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
+ * var decoded = BASE64URL.decode("YmzDpWLDpnJncsO4ZAo=");
*/
const Base64Codec BASE64URL = const Base64Codec.urlSafe();
diff --git a/sdk/lib/convert/chunked_conversion.dart b/sdk/lib/convert/chunked_conversion.dart
index a36c505..95e561c 100644
--- a/sdk/lib/convert/chunked_conversion.dart
+++ b/sdk/lib/convert/chunked_conversion.dart
@@ -122,7 +122,7 @@
* The input sink for new data. All data that is received with
* [handleData] is added into this sink.
*/
- ChunkedConversionSink<S> _chunkedSink;
+ final ChunkedConversionSink<S> _chunkedSink;
_ConverterStreamEventSink(
Converter/*=ChunkedConverter<dynamic, dynamic, S, T>*/ converter,
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 4f45744..a1967b7 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -106,9 +106,6 @@
*
* The empty iterable has no elements, and iterating it always stops
* immediately.
- *
- * An empty iterable can be used in places where you always that
- * the iterable you would otherwise create is empty.
*/
const factory Iterable.empty() = EmptyIterable<E>;
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 4ca1158..7be7e5d 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -43374,7 +43374,10 @@
if (callback == null) return null;
// TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
// generic method support in zones.
- return Zone.current.bindUnaryCallback(callback, runGuarded: true) as _wrapZoneCallback/*<A, R>*/;
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneCallback/*<A, R>*/ wrapped =
+ Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ return wrapped;
}
_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
@@ -43382,7 +43385,10 @@
if (callback == null) return null;
// We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
// generic method support in zones.
- return Zone.current.bindBinaryCallback(callback, runGuarded: true) as _wrapZoneBinaryCallback/*<A, B, R>*/;
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneBinaryCallback/*<A, B, R>*/ wrapped =
+ Zone.current.bindBinaryCallback(callback, runGuarded: true);
+ return wrapped;
}
/**
@@ -43613,10 +43619,21 @@
sanitizeNode(node, parent);
var child = node.lastChild;
- while (child != null) {
- // Child may be removed during the walk.
- var nextChild = child.previousNode;
- walk(child, node);
+ while (null != child) {
+ var nextChild;
+ try {
+ // Child may be removed during the walk, and we may not
+ // even be able to get its previousNode.
+ nextChild = child.previousNode;
+ } catch (e) {
+ // Child appears bad, remove it. We want to check the rest of the
+ // children of node and, but we have no way of getting to the next
+ // child, so start again from the last child.
+ _removeNode(child, node);
+ child = null;
+ nextChild = node.lastChild;
+ }
+ if (child != null) walk(child, node);
child = nextChild;
}
}
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 78de601..6d8873e 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -47194,10 +47194,21 @@
sanitizeNode(node, parent);
var child = node.lastChild;
- while (child != null) {
- // Child may be removed during the walk.
- var nextChild = child.previousNode;
- walk(child, node);
+ while (null != child) {
+ var nextChild;
+ try {
+ // Child may be removed during the walk, and we may not
+ // even be able to get its previousNode.
+ nextChild = child.previousNode;
+ } catch (e) {
+ // Child appears bad, remove it. We want to check the rest of the
+ // children of node and, but we have no way of getting to the next
+ // child, so start again from the last child.
+ _removeNode(child, node);
+ child = null;
+ nextChild = node.lastChild;
+ }
+ if (child != null) walk(child, node);
child = nextChild;
}
}
@@ -47852,7 +47863,10 @@
if (callback == null) return null;
// TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
// generic method support in zones.
- return Zone.current.bindUnaryCallback(callback, runGuarded: true) as _wrapZoneCallback/*<A, R>*/;
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneCallback/*<A, R>*/ wrapped =
+ Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ return wrapped;
}
_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
@@ -47860,7 +47874,10 @@
if (callback == null) return null;
// We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
// generic method support in zones.
- return Zone.current.bindBinaryCallback(callback, runGuarded: true) as _wrapZoneBinaryCallback/*<A, B, R>*/;
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneBinaryCallback/*<A, B, R>*/ wrapped =
+ Zone.current.bindBinaryCallback(callback, runGuarded: true);
+ return wrapped;
}
/**
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 0be5cac..f8105cc 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -656,7 +656,6 @@
LayoutTests/fast/canvas/webgl/buffer-data-array-buffer_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-lost-restored_t01: Pass, Timeout # Please triage this failure
-LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/css-webkit-canvas-repaint_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/css-webkit-canvas_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
@@ -1472,9 +1471,15 @@
WebPlatformTest/shadow-dom/events/event-retargeting/test-001_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/events/event-retargeting/test-004_t01: RuntimeError # Please triage this failure
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-004_t01: RuntimeError # Please triage this failure
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-005_t01: RuntimeError # Please triage this failure
-WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-007_t01: RuntimeError # Please triage this failure
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-001_t01: Pass, RuntimeError # Issue 52
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-002_t01: Pass, RuntimeError # Issue 52
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-003_t01: Pass, RuntimeError # Issue 52
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-004_t01: Pass, RuntimeError # Issue 52
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-005_t01: Pass, RuntimeError # Issue 52
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-006_t01: Pass, RuntimeError # Issue 52
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-007_t01: Pass, RuntimeError # Issue 52
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-008_t01: Pass, RuntimeError # Issue 52
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-009_t01: Pass, RuntimeError # Issue 52
WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Skip # Times out. Please triage this failure
WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t02: Skip # Times out. Please triage this failure
WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t05: Skip # Times out. Please triage this failure
@@ -1596,6 +1601,7 @@
LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-lost_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-lost-restored_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/draw-arrays-out-of-bounds_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/draw-elements-out-of-bounds_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: RuntimeError # Please triage this failure
@@ -2080,6 +2086,7 @@
LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-with-first-letter-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Document/CaretRangeFromPoint/hittest-relative-to-viewport_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Document/createElement-valid-names_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Document/createElementNS-namespace-err_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Document/document-title-get_t01: RuntimeError # Please triage this failure
@@ -3246,12 +3253,6 @@
LayoutTests/fast/canvas/setWidthResetAfterForcedRender_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Please triage this failure
@@ -3260,11 +3261,8 @@
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError, Timeout # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError, Timeout # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-input-validation_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/malformed-url_t01: RuntimeError # Please triage this failure
@@ -3335,6 +3333,7 @@
LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/draggable-region-parser_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/dynamic-class-backdrop-pseudo_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/ex-unit-with-no-x-height_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/font-face-cache-bug_t01: RuntimeError # Please triage this failure
@@ -3450,6 +3449,7 @@
LayoutTests/fast/dom/HTMLLinkElement/prefetch-onerror_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # Please triage this failure
@@ -3501,6 +3501,7 @@
LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/css-selectorText_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/custom/attribute-changed-callback_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/custom/constructor-calls-created-synchronously_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/custom/created-callback_t01: RuntimeError # Please triage this failure
@@ -3530,12 +3531,13 @@
LayoutTests/fast/dom/implementation-api-args_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/importNode-unsupported-node-type_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/location-hash_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/dom/mutation-event-remove-inserted-node_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # API not supported.
LayoutTests/fast/dom/navigatorcontentutils/register-protocol-handler_t01: Skip # API not supported.
LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: Skip # API not supported.
LayoutTests/fast/dom/object-plugin-hides-properties_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/option-properties_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/partial-layout-non-overlay-scrollbars_t01: Pass, RuntimeError # Issue 53
LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/access-document-of-detached-stylesheetlist-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/base-in-shadow-tree_t01: RuntimeError # Please triage this failure
@@ -3693,6 +3695,7 @@
LayoutTests/fast/forms/clone-input-with-dirty-value_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/color/color-setrangetext_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/color/input-value-sanitization-color_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/datalist/datalist-child-validation_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datalist/datalist_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datalist/input-list_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal_t01: RuntimeError # Dartium JSInterop failure
@@ -3978,6 +3981,7 @@
LibTest/html/Element/enteredView_A01_t01: RuntimeError # Please triage this failure
LibTest/html/Element/getAttributeNS_A01_t01: RuntimeError # Please triage this failure
LibTest/html/Element/getAttributeNS_A02_t01: RuntimeError # Please triage this failure
+LibTest/html/Element/getBoundingClientRect_A01_t02: Pass, RuntimeError # Issue 53
LibTest/html/Element/getClientRects_A01_t02: RuntimeError # Please triage this failure
LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # Please triage this failure
LibTest/html/Element/isTagSupported_A01_t01: RuntimeError # Please triage this failure
@@ -7782,7 +7786,6 @@
LayoutTests/fast/canvas/webgl/error-reporting_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/functions-returning-strings_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/get-active-test_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: Pass, RuntimeError # Please triage this failure
@@ -7828,7 +7831,6 @@
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-uniform-binding-bugs_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-webgl_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-input-validation_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Please triage this failure
@@ -7843,7 +7845,6 @@
LayoutTests/fast/canvas/webgl/triangle_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/uniform-location-length-limits_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/viewport-unchanged-upon-resize_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-composite-modes-repaint_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-composite-modes_t01: Pass, RuntimeError # Please triage this failure
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 1436313..545123a 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -1366,10 +1366,11 @@
LayoutTests/fast/dom/computed-style-set-property_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/custom/document-register-type-extensions_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/custom/document-register-namespace_t01: RuntimeError # Issue 26134
+LayoutTests/fast/dom/custom/element-type_t01: RuntimeError # Issue 26134
+LayoutTests/fast/dom/custom/element-upgrade_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/DOMException/prototype-object_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/shadow/shadow-hierarchy-exception_t01: RuntimeError # Issue 26134
LayoutTests/fast/dom/Node/contains-method_t01: RuntimeError # Issue 26134
-LayoutTests/fast/dom/MutationObserver/observe-attributes_t01: RuntimeError # Issue 26134
LayoutTests/fast/events/mutation-during-append-child_t01: RuntimeError # Issue 26134
LayoutTests/fast/events/mutation-during-insert-before_t01: RuntimeError # Issue 26134
LayoutTests/fast/events/clipboard-dataTransferItemList-remove_t01: Skip # Issue 26134, timesout
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 59ebaf3..d9a0814 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -168,3 +168,10 @@
# TODO(vegorov) These tests are very slow on unoptimized SIMDBC
LibTest/collection/ListMixin/ListMixin_class_A01_t02: Timeout
LibTest/collection/ListBase/ListBase_class_A01_t02: Timeout
+
+[ $compiler == precompiler && $runtime == dart_precompiled && $system == android ]
+LibTest/isolate/*: Skip # Issue #26373
+Language/Expressions/Spawning_an_Isolate/new_isolate_t01: Skip # Issue #26373
+
+LibTest/math/log_A01_t01: RuntimeError # Precision of Math.log (Issue #18998)
+Language/Expressions/Object_Identity/double_t02: RuntimeError # Issue #26374
diff --git a/tests/compiler/dart2js/analyze_test_test.dart b/tests/compiler/dart2js/analyze_test_test.dart
index 93cf7b9..a38c814 100644
--- a/tests/compiler/dart2js/analyze_test_test.dart
+++ b/tests/compiler/dart2js/analyze_test_test.dart
@@ -38,17 +38,15 @@
const List<String> SKIP_LIST = const <String>[
// Helper files:
- "dart2js_batch2_run.dart",
+ "/data/",
"http_launch_data/",
"mirrors_helper.dart",
"path%20with%20spaces/",
- "one_line_dart_program.dart",
- "sourcemaps/invokes_test_file.dart",
"cps_ir/input/",
// No longer maintained:
"backend_dart/",
// Broken tests:
- "http_test.dart",
+ "quarantined/http_test.dart",
// Package directory
"packages/",
];
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 6c26bdb..e6c7b74 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -2,6 +2,8 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
+packages/*: Skip # Skip packages folder
+
compile_with_empty_libraries_test: Fail # Issue 24223
boolified_operator_test: Fail # Issue 8001
@@ -34,7 +36,7 @@
patch_test/bug: RuntimeError # Issue 21132
-http_test: Pass, Slow
+quarantined/http_test: Pass, Slow
inference_stats_test: Pass, Slow
# These tests are for the now-deleted dart2dart variant of the CPS IR.
diff --git a/tests/compiler/dart2js/dart2js_batch2_test.dart b/tests/compiler/dart2js/dart2js_batch2_test.dart
index 644c790..2bd2495 100644
--- a/tests/compiler/dart2js/dart2js_batch2_test.dart
+++ b/tests/compiler/dart2js/dart2js_batch2_test.dart
@@ -38,8 +38,8 @@
return createTempDir().then((Directory directory) {
tmpDir = directory;
String newPath = path.join(directory.path, "dart2js_batch2_run.dart");
- File source =
- new File.fromUri(Platform.script.resolve("dart2js_batch2_run.dart"));
+ File source = new File.fromUri(
+ Platform.script.resolve("data/dart2js_batch2_run.dart"));
source.copySync(newPath);
});
}
diff --git a/tests/compiler/dart2js/dart2js_batch2_run.dart b/tests/compiler/dart2js/data/dart2js_batch2_run.dart
similarity index 100%
rename from tests/compiler/dart2js/dart2js_batch2_run.dart
rename to tests/compiler/dart2js/data/dart2js_batch2_run.dart
diff --git a/tests/compiler/dart2js/exit_code_helper.dart b/tests/compiler/dart2js/data/exit_code_helper.dart
similarity index 100%
rename from tests/compiler/dart2js/exit_code_helper.dart
rename to tests/compiler/dart2js/data/exit_code_helper.dart
diff --git a/tests/compiler/dart2js/mirrors_helper.dart b/tests/compiler/dart2js/data/mirrors_helper.dart
similarity index 100%
rename from tests/compiler/dart2js/mirrors_helper.dart
rename to tests/compiler/dart2js/data/mirrors_helper.dart
diff --git a/tests/compiler/dart2js/one_line_dart_program.dart b/tests/compiler/dart2js/data/one_line_dart_program.dart
similarity index 100%
rename from tests/compiler/dart2js/one_line_dart_program.dart
rename to tests/compiler/dart2js/data/one_line_dart_program.dart
diff --git a/tests/compiler/dart2js/deferred_follow_constant_dependencies_test.dart b/tests/compiler/dart2js/deferred_follow_constant_dependencies_test.dart
index d1175e7..0f10523 100644
--- a/tests/compiler/dart2js/deferred_follow_constant_dependencies_test.dart
+++ b/tests/compiler/dart2js/deferred_follow_constant_dependencies_test.dart
@@ -5,6 +5,7 @@
// Test that constants depended on by other constants are correctly deferred.
import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/common.dart';
import 'package:compiler/src/constants/values.dart';
import 'package:compiler/src/compiler.dart';
import 'package:expect/expect.dart';
@@ -34,8 +35,11 @@
return constant.isString
&& constant.primitiveValue.slowToString() == stringValue;
});
- Expect.notEquals(null, outputUnitForConstant(constant));
- Expect.notEquals(mainOutputUnit, outputUnitForConstant(constant));
+ Expect.notEquals(null, outputUnitForConstant(constant),
+ "Constant value ${constant.toStructuredText()} has no output unit.");
+ Expect.notEquals(mainOutputUnit, outputUnitForConstant(constant),
+ "Constant value ${constant.toStructuredText()} "
+ "is in the main output unit.");
}
});
}
diff --git a/tests/compiler/dart2js/exit_code_test.dart b/tests/compiler/dart2js/exit_code_test.dart
index b67b026..67a04bd 100644
--- a/tests/compiler/dart2js/exit_code_test.dart
+++ b/tests/compiler/dart2js/exit_code_test.dart
@@ -242,7 +242,7 @@
entry.compileFunc = compile;
List<String> args = new List<String>.from(options)
- ..add("tests/compiler/dart2js/exit_code_helper.dart");
+ ..add("tests/compiler/dart2js/data/exit_code_helper.dart");
Future result = entry.internalMain(args);
return result.catchError((e, s) {
// Capture crashes.
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 839c083..59dc3da 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -11,6 +11,7 @@
import 'package:compiler/src/common/names.dart' show
Uris;
import 'package:compiler/src/constants/expressions.dart';
+import 'package:compiler/src/dart_types.dart' show DartType;
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/diagnostics/source_span.dart';
import 'package:compiler/src/diagnostics/spannable.dart';
@@ -224,10 +225,15 @@
TreeElementMapping resolveNodeStatement(Node tree,
ExecutableElement element) {
ResolverVisitor visitor =
- new ResolverVisitor(this, element,
+ new ResolverVisitor(
+ this,
+ element,
new ResolutionRegistry(this,
- new CollectingTreeElements(element)));
- if (visitor.scope is LibraryScope) {
+ new CollectingTreeElements(element)),
+ scope: new MockTypeVariablesScope(
+ element.enclosingElement.buildScope()));
+ if (visitor.scope is LibraryScope ||
+ visitor.scope is MockTypeVariablesScope) {
visitor.scope = new MethodScope(visitor.scope, element);
}
visitor.visit(tree);
@@ -238,9 +244,12 @@
resolverVisitor() {
Element mockElement = new MockElement(mainApp.entryCompilationUnit);
ResolverVisitor visitor =
- new ResolverVisitor(this, mockElement,
- new ResolutionRegistry(this,
- new CollectingTreeElements(mockElement)));
+ new ResolverVisitor(
+ this,
+ mockElement,
+ new ResolutionRegistry(
+ this, new CollectingTreeElements(mockElement)),
+ scope: mockElement.enclosingElement.buildScope());
visitor.scope = new MethodScope(visitor.scope, mockElement);
return visitor;
}
@@ -321,6 +330,13 @@
}
}
+class MockTypeVariablesScope extends TypeVariablesScope {
+ @override
+ List<DartType> get typeVariables => <DartType>[];
+ MockTypeVariablesScope(Scope parent) : super(parent);
+ String toString() => 'MockTypeVariablesScope($parent)';
+}
+
// The mock compiler does not split the program in output units.
class MockDeferredLoadTask extends DeferredLoadTask {
MockDeferredLoadTask(Compiler compiler) : super(compiler);
diff --git a/tests/compiler/dart2js/http_test.dart b/tests/compiler/dart2js/quarantined/http_test.dart
similarity index 97%
rename from tests/compiler/dart2js/http_test.dart
rename to tests/compiler/dart2js/quarantined/http_test.dart
index aed6ddd..cdb1348 100644
--- a/tests/compiler/dart2js/http_test.dart
+++ b/tests/compiler/dart2js/quarantined/http_test.dart
@@ -15,7 +15,7 @@
import 'package:expect/expect.dart';
import 'package:path/path.dart' as path;
-Uri pathOfData = Platform.script.resolve('http_launch_data/');
+Uri pathOfData = Platform.script.resolve('../http_launch_data/');
Directory tempDir;
String outFilePath;
@@ -43,7 +43,7 @@
String ext = Platform.isWindows ? '.bat' : '';
String command =
path.normalize(path.join(path.fromUri(Platform.script),
- '../../../../sdk/bin/dart2js${ext}'));
+ '../../../../../sdk/bin/dart2js${ext}'));
return Process.run(command, args);
}
diff --git a/tests/compiler/dart2js/mirrors_test.dart b/tests/compiler/dart2js/quarantined/mirrors_test.dart
similarity index 99%
rename from tests/compiler/dart2js/mirrors_test.dart
rename to tests/compiler/dart2js/quarantined/mirrors_test.dart
index ef815e9..428442f 100644
--- a/tests/compiler/dart2js/mirrors_test.dart
+++ b/tests/compiler/dart2js/quarantined/mirrors_test.dart
@@ -43,9 +43,9 @@
main() {
Uri scriptUri = currentDirectory.resolveUri(Platform.script);
- Uri packageRoot = scriptUri.resolve('./packages/');
- Uri libUri = scriptUri.resolve('../../../sdk/');
- Uri inputUri = scriptUri.resolve('mirrors_helper.dart');
+ Uri packageRoot = scriptUri.resolve('../packages/');
+ Uri libUri = scriptUri.resolve('../../../../sdk/');
+ Uri inputUri = scriptUri.resolve('../data/mirrors_helper.dart');
var provider = new CompilerSourceFileProvider();
var diagnosticHandler = new FormattingDiagnosticHandler(provider);
asyncStart();
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index 6067a6c..2e1868a 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -222,10 +222,11 @@
ClassElement classA = compiler.mainApp.find("A");
FunctionElement fooA = classA.lookupLocalMember("foo");
- ResolverVisitor visitor =
- new ResolverVisitor(compiler, fooB,
- new ResolutionRegistry(compiler,
- new CollectingTreeElements(fooB)));
+ ResolverVisitor visitor = new ResolverVisitor(
+ compiler,
+ fooB,
+ new ResolutionRegistry(compiler, new CollectingTreeElements(fooB)),
+ scope: new MockTypeVariablesScope(classB.buildScope()));
FunctionExpression node =
(fooB as FunctionElementX).parseNode(compiler.parsingContext);
visitor.visit(node.body);
@@ -266,10 +267,12 @@
compiler.resolveStatement("Foo foo;");
ClassElement fooElement = compiler.mainApp.find("Foo");
FunctionElement funElement = fooElement.lookupLocalMember("foo");
- ResolverVisitor visitor =
- new ResolverVisitor(compiler, funElement,
- new ResolutionRegistry(compiler,
- new CollectingTreeElements(funElement)));
+ ResolverVisitor visitor = new ResolverVisitor(
+ compiler,
+ funElement,
+ new ResolutionRegistry(
+ compiler, new CollectingTreeElements(funElement)),
+ scope: new MockTypeVariablesScope(fooElement.buildScope()));
FunctionExpression function =
(funElement as FunctionElementX).parseNode(compiler.parsingContext);
visitor.visit(function.body);
@@ -292,9 +295,12 @@
compiler.resolveStatement("Foo foo;");
ClassElement fooElement = compiler.mainApp.find("Foo");
FunctionElement funElement = fooElement.lookupLocalMember("foo");
- ResolverVisitor visitor = new ResolverVisitor(compiler, funElement,
- new ResolutionRegistry(compiler,
- new CollectingTreeElements(funElement)));
+ ResolverVisitor visitor = new ResolverVisitor(
+ compiler,
+ funElement,
+ new ResolutionRegistry(
+ compiler, new CollectingTreeElements(funElement)),
+ scope: new MockTypeVariablesScope(fooElement.buildScope()));
FunctionExpression function =
(funElement as FunctionElementX).parseNode(compiler.parsingContext);
visitor.visit(function.body);
@@ -581,10 +587,10 @@
// correctly.
compiler.parseScript("abstract class Bar {}");
- ResolverVisitor visitor =
- new ResolverVisitor(compiler, null,
- new ResolutionRegistry(compiler,
- new CollectingTreeElements(null)));
+ ResolverVisitor visitor = new ResolverVisitor(
+ compiler,
+ null,
+ new ResolutionRegistry(compiler, new CollectingTreeElements(null)));
compiler.resolveStatement("Foo bar;");
ClassElement fooElement = compiler.mainApp.find('Foo');
@@ -619,7 +625,6 @@
Future testFunctionExpression() {
return MockCompiler.create((MockCompiler compiler) {
- ResolverVisitor visitor = compiler.resolverVisitor();
Map mapping = compiler.resolveStatement("int f() {}").map;
Expect.equals(2, mapping.length);
Element element;
@@ -701,10 +706,11 @@
Element element;
element = classElement.lookupConstructor(constructor);
FunctionExpression tree = (element as FunctionElement).node;
- ResolverVisitor visitor =
- new ResolverVisitor(compiler, element,
- new ResolutionRegistry(compiler,
- new CollectingTreeElements(element)));
+ ResolverVisitor visitor = new ResolverVisitor(
+ compiler,
+ element,
+ new ResolutionRegistry(compiler, new CollectingTreeElements(element)),
+ scope: classElement.buildScope());
new InitializerResolver(visitor, element, tree).resolveInitializers();
visitor.visit(tree.body);
Expect.equals(expectedElementCount, map(visitor).length,
diff --git a/tests/compiler/dart2js/serialization_analysis_test.dart b/tests/compiler/dart2js/serialization/analysis_test.dart
similarity index 94%
rename from tests/compiler/dart2js/serialization_analysis_test.dart
rename to tests/compiler/dart2js/serialization/analysis_test.dart
index 39c46de..b1a96b5 100644
--- a/tests/compiler/dart2js/serialization_analysis_test.dart
+++ b/tests/compiler/dart2js/serialization/analysis_test.dart
@@ -12,9 +12,9 @@
import 'package:compiler/src/common/names.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/filenames.dart';
-import 'memory_compiler.dart';
-import 'serialization_helper.dart';
-import 'serialization_test_data.dart';
+import '../memory_compiler.dart';
+import 'helper.dart';
+import 'test_data.dart';
main(List<String> arguments) {
asyncTest(() async {
diff --git a/tests/compiler/dart2js/serialization_compilation_test.dart b/tests/compiler/dart2js/serialization/compilation_test.dart
similarity index 88%
rename from tests/compiler/dart2js/serialization_compilation_test.dart
rename to tests/compiler/dart2js/serialization/compilation_test.dart
index 590f57a..e6601e1 100644
--- a/tests/compiler/dart2js/serialization_compilation_test.dart
+++ b/tests/compiler/dart2js/serialization/compilation_test.dart
@@ -12,10 +12,10 @@
import 'package:compiler/src/common/names.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/filenames.dart';
-import 'memory_compiler.dart';
-import 'serialization_helper.dart';
-import 'serialization_test_data.dart';
-import 'output_collector.dart';
+import '../memory_compiler.dart';
+import 'helper.dart';
+import 'test_data.dart';
+import '../output_collector.dart';
main(List<String> args) {
asyncTest(() async {
@@ -29,7 +29,7 @@
} else {
Uri entryPoint = Uri.parse('memory:main.dart');
// TODO(johnniwinther): Handle the remaining tests.
- for (Test test in TESTS.sublist(0, 1)) {
+ for (Test test in TESTS.sublist(0, 5)) {
await compile(serializedData, entryPoint, test,
verbose: arguments.verbose);
}
@@ -48,8 +48,7 @@
await runCompiler(
entryPoint: entryPoint,
memorySourceFiles: test != null ? test.sourceFiles : const {},
- options: [Flags.disableTypeInference,
- Flags.disableInlining],
+ options: [],
outputProvider: outputCollector,
beforeRun: (Compiler compiler) {
deserialize(compiler, serializedData, deserializeResolvedAst: true);
diff --git a/tests/compiler/dart2js/serialization_test.dart b/tests/compiler/dart2js/serialization/equivalence_test.dart
similarity index 94%
rename from tests/compiler/dart2js/serialization_test.dart
rename to tests/compiler/dart2js/serialization/equivalence_test.dart
index 7edeb4c..32a538a 100644
--- a/tests/compiler/dart2js/serialization_test.dart
+++ b/tests/compiler/dart2js/serialization/equivalence_test.dart
@@ -5,7 +5,7 @@
library dart2js.serialization_test;
import 'dart:io';
-import 'memory_compiler.dart';
+import '../memory_compiler.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common.dart';
@@ -21,7 +21,7 @@
import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/serialization/json_serializer.dart';
import 'package:compiler/src/serialization/serialization.dart';
-import 'serialization_test_helper.dart';
+import 'test_helper.dart';
main(List<String> arguments) {
// Ensure that we can print out constant expressions.
@@ -243,6 +243,8 @@
if (element1 == element2) return;
check(element1, element2, 'kind', element1.kind, element2.kind);
element1.accept(this, element2);
+ check(element1, element2, 'isSynthesized',
+ element1.isSynthesized, element2.isSynthesized);
}
@override
@@ -560,6 +562,24 @@
element1.constantConstructor,
element2.constantConstructor);
}
+ check(element1, element2, 'isRedirectingGenerative',
+ element1.isRedirectingGenerative, element2.isRedirectingGenerative);
+ check(element1, element2, 'isRedirectingFactory',
+ element1.isRedirectingFactory, element2.isRedirectingFactory);
+ checkElementIdentities(element1, element2, 'effectiveTarget',
+ element1.effectiveTarget, element2.effectiveTarget);
+ checkElementIdentities(element1, element2, 'definingConstructor',
+ element1.definingConstructor, element2.definingConstructor);
+ check(
+ element1, element2, 'effectiveTargetType',
+ element1.computeEffectiveTargetType(element1.enclosingClass.thisType),
+ element2.computeEffectiveTargetType(element2.enclosingClass.thisType),
+ areTypesEquivalent);
+ checkElementIdentities(element1, element2, 'immediateRedirectionTarget',
+ element1.immediateRedirectionTarget,
+ element2.immediateRedirectionTarget);
+ checkElementIdentities(element1, element2, 'redirectionDeferredPrefix',
+ element1.redirectionDeferredPrefix, element2.redirectionDeferredPrefix);
}
@override
diff --git a/tests/compiler/dart2js/serialization_helper.dart b/tests/compiler/dart2js/serialization/helper.dart
similarity index 92%
rename from tests/compiler/dart2js/serialization_helper.dart
rename to tests/compiler/dart2js/serialization/helper.dart
index 2d1ea1f..c7719b3 100644
--- a/tests/compiler/dart2js/serialization_helper.dart
+++ b/tests/compiler/dart2js/serialization/helper.dart
@@ -28,7 +28,7 @@
import 'package:compiler/src/universe/world_impact.dart';
import 'package:compiler/src/universe/use.dart';
-import 'memory_compiler.dart';
+import '../memory_compiler.dart';
class Arguments {
final String filename;
@@ -211,7 +211,7 @@
}
@override
- bool hasResolvedAst(Element element) {
+ bool hasResolvedAst(ExecutableElement element) {
if (_resolvedAstDeserializer != null) {
return _resolvedAstDeserializer.hasResolvedAst(element);
}
@@ -219,7 +219,7 @@
}
@override
- ResolvedAst getResolvedAst(Element element) {
+ ResolvedAst getResolvedAst(ExecutableElement element) {
if (_resolvedAstDeserializer != null) {
return _resolvedAstDeserializer.getResolvedAst(element);
}
@@ -300,27 +300,30 @@
final Backend backend;
final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{};
- Map<Element, ResolvedAst> _resolvedAstMap = <Element, ResolvedAst>{};
- Map<Element, ObjectDecoder> _decoderMap = <Element, ObjectDecoder>{};
+ Map<ExecutableElement, ResolvedAst> _resolvedAstMap =
+ <ExecutableElement, ResolvedAst>{};
+ Map<MemberElement, ObjectDecoder> _decoderMap =
+ <MemberElement, ObjectDecoder>{};
Map<Uri, Token> beginTokenMap = <Uri, Token>{};
ResolvedAstDeserializerPlugin(this.parsingContext, this.backend);
- bool hasResolvedAst(Element element) {
+ bool hasResolvedAst(ExecutableElement element) {
return _resolvedAstMap.containsKey(element) ||
- _decoderMap.containsKey(element);
+ _decoderMap.containsKey(element.memberContext);
}
- ResolvedAst getResolvedAst(Element element) {
+ ResolvedAst getResolvedAst(ExecutableElement element) {
ResolvedAst resolvedAst = _resolvedAstMap[element];
if (resolvedAst == null) {
- ObjectDecoder decoder = _decoderMap[element];
+ ObjectDecoder decoder = _decoderMap[element.memberContext];
if (decoder != null) {
- resolvedAst = _resolvedAstMap[element] =
- ResolvedAstDeserializer.deserialize(
- element, decoder, parsingContext, findToken,
- backend.serialization.deserializer);
+ ResolvedAstDeserializer.deserialize(
+ element.memberContext, decoder, parsingContext, findToken,
+ backend.serialization.deserializer,
+ _resolvedAstMap);
_decoderMap.remove(element);
+ resolvedAst = _resolvedAstMap[element];
}
}
return resolvedAst;
diff --git a/tests/compiler/dart2js/serialization_impact_test.dart b/tests/compiler/dart2js/serialization/impact_test.dart
similarity index 94%
rename from tests/compiler/dart2js/serialization_impact_test.dart
rename to tests/compiler/dart2js/serialization/impact_test.dart
index 6f5fd15..ea1d113 100644
--- a/tests/compiler/dart2js/serialization_impact_test.dart
+++ b/tests/compiler/dart2js/serialization/impact_test.dart
@@ -12,9 +12,9 @@
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/filenames.dart';
import 'package:compiler/src/serialization/equivalence.dart';
-import 'memory_compiler.dart';
-import 'serialization_helper.dart';
-import 'serialization_test_helper.dart';
+import '../memory_compiler.dart';
+import 'helper.dart';
+import 'test_helper.dart';
main(List<String> args) {
Arguments arguments = new Arguments.from(args);
diff --git a/tests/compiler/dart2js/serialization_library_test.dart b/tests/compiler/dart2js/serialization/library_test.dart
similarity index 98%
rename from tests/compiler/dart2js/serialization_library_test.dart
rename to tests/compiler/dart2js/serialization/library_test.dart
index df59fbc..81d90cf 100644
--- a/tests/compiler/dart2js/serialization_library_test.dart
+++ b/tests/compiler/dart2js/serialization/library_test.dart
@@ -5,7 +5,7 @@
library dart2js.serialization_library_test;
import 'dart:io';
-import 'memory_compiler.dart';
+import '../memory_compiler.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common/names.dart';
@@ -21,7 +21,7 @@
import 'package:compiler/src/serialization/json_serializer.dart';
import 'package:compiler/src/serialization/serialization.dart';
-import 'serialization_test.dart';
+import 'equivalence_test.dart';
main(List<String> arguments) {
// Ensure that we can print out constant expressions.
diff --git a/tests/compiler/dart2js/serialization_model_test.dart b/tests/compiler/dart2js/serialization/model_test.dart
similarity index 97%
rename from tests/compiler/dart2js/serialization_model_test.dart
rename to tests/compiler/dart2js/serialization/model_test.dart
index 52547ae..66ac6c5 100644
--- a/tests/compiler/dart2js/serialization_model_test.dart
+++ b/tests/compiler/dart2js/serialization/model_test.dart
@@ -25,10 +25,10 @@
import 'package:compiler/src/universe/world_impact.dart';
import 'package:compiler/src/universe/class_set.dart';
import 'package:compiler/src/universe/use.dart';
-import 'memory_compiler.dart';
-import 'serialization_helper.dart';
-import 'serialization_test_data.dart';
-import 'serialization_test_helper.dart';
+import '../memory_compiler.dart';
+import 'helper.dart';
+import 'test_data.dart';
+import 'test_helper.dart';
main(List<String> args) {
asyncTest(() async {
diff --git a/tests/compiler/dart2js/serialization_resolved_ast_test.dart b/tests/compiler/dart2js/serialization/resolved_ast_test.dart
similarity index 92%
rename from tests/compiler/dart2js/serialization_resolved_ast_test.dart
rename to tests/compiler/dart2js/serialization/resolved_ast_test.dart
index 7712f9a..0ca8672 100644
--- a/tests/compiler/dart2js/serialization_resolved_ast_test.dart
+++ b/tests/compiler/dart2js/serialization/resolved_ast_test.dart
@@ -14,10 +14,10 @@
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/filenames.dart';
import 'package:compiler/src/serialization/equivalence.dart';
-import 'memory_compiler.dart';
-import 'serialization_helper.dart';
-import 'serialization_test_data.dart';
-import 'serialization_test_helper.dart';
+import '../memory_compiler.dart';
+import 'helper.dart';
+import 'test_data.dart';
+import 'test_helper.dart';
main(List<String> args) {
@@ -68,7 +68,8 @@
compiler1,
compiler2,
(Element member1) {
- return compiler1.resolution.hasResolvedAst(member1);
+ return member1 is ExecutableElement &&
+ compiler1.resolution.hasResolvedAst(member1);
},
checkResolvedAsts,
verbose: verbose);
diff --git a/tests/compiler/dart2js/serialization_test_data.dart b/tests/compiler/dart2js/serialization/test_data.dart
similarity index 100%
rename from tests/compiler/dart2js/serialization_test_data.dart
rename to tests/compiler/dart2js/serialization/test_data.dart
diff --git a/tests/compiler/dart2js/serialization_test_helper.dart b/tests/compiler/dart2js/serialization/test_helper.dart
similarity index 99%
rename from tests/compiler/dart2js/serialization_test_helper.dart
rename to tests/compiler/dart2js/serialization/test_helper.dart
index 0c871a8..1a05c98 100644
--- a/tests/compiler/dart2js/serialization_test_helper.dart
+++ b/tests/compiler/dart2js/serialization/test_helper.dart
@@ -5,7 +5,7 @@
library dart2js.serialization_test_helper;
import 'dart:io';
-import 'memory_compiler.dart';
+import '../memory_compiler.dart';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/commandline_options.dart';
diff --git a/tests/compiler/dart2js/sourcemaps/invokes_test_file.dart b/tests/compiler/dart2js/sourcemaps/data/invokes_test_file.dart
similarity index 100%
rename from tests/compiler/dart2js/sourcemaps/invokes_test_file.dart
rename to tests/compiler/dart2js/sourcemaps/data/invokes_test_file.dart
diff --git a/tests/compiler/dart2js/sourcemaps/operators_test_file.dart b/tests/compiler/dart2js/sourcemaps/data/operators_test_file.dart
similarity index 100%
rename from tests/compiler/dart2js/sourcemaps/operators_test_file.dart
rename to tests/compiler/dart2js/sourcemaps/data/operators_test_file.dart
diff --git a/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart b/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
index 9bc1ac8..3a5befd 100644
--- a/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
+++ b/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
@@ -200,8 +200,8 @@
RecordingSourceInformationStrategy(this.strategy);
@override
- SourceInformationBuilder createBuilderForContext(AstElement element) {
- return strategy.createBuilderForContext(element);
+ SourceInformationBuilder createBuilderForContext(ResolvedAst resolvedAst) {
+ return strategy.createBuilderForContext(resolvedAst);
}
@override
diff --git a/tests/compiler/dart2js/zero_termination_test.dart b/tests/compiler/dart2js/zero_termination_test.dart
index 501fb42..fbfeab7 100644
--- a/tests/compiler/dart2js/zero_termination_test.dart
+++ b/tests/compiler/dart2js/zero_termination_test.dart
@@ -67,7 +67,8 @@
}
Future testFile() async {
- String inFilePath = pathOfData.resolve('one_line_dart_program.dart').path;
+ String inFilePath =
+ pathOfData.resolve('data/one_line_dart_program.dart').path;
List<String> args = [inFilePath, "--out=" + outFilePath];
await cleanup();
@@ -77,7 +78,7 @@
Future serverRunning(HttpServer server) async {
int port = server.port;
- String inFilePath = "http://127.0.0.1:$port/one_line_dart_program.dart";
+ String inFilePath = "http://127.0.0.1:$port/data/one_line_dart_program.dart";
List<String> args = [inFilePath, "--out=" + outFilePath];
server.listen(handleRequest);
diff --git a/tests/corelib/core_runtime_types_test.dart b/tests/corelib/core_runtime_types_test.dart
index 017df05..49b234c 100644
--- a/tests/corelib/core_runtime_types_test.dart
+++ b/tests/corelib/core_runtime_types_test.dart
@@ -262,7 +262,7 @@
assertEquals(d.year, 1970);
d = new DateTime.now();
- assertEquals(d.year >= 2011, true);
+ assertEquals(d.year >= 1970, true);
}
static testLiterals() {
diff --git a/tests/corelib/set_test.dart b/tests/corelib/set_test.dart
index 3711449..20a136a 100644
--- a/tests/corelib/set_test.dart
+++ b/tests/corelib/set_test.dart
@@ -445,6 +445,17 @@
Expect.isTrue(set4.isEmpty);
}
+class A {}
+class B {}
+class C implements A, B {}
+
+void testASetFrom(setFrom) {
+ List<B> bList= <B>[new C()];
+ // Set.from allows to cast elements.
+ Set<A> aSet = setFrom(bList);
+ Expect.isTrue(aSet.length == 1);
+}
+
main() {
testMain(() => new HashSet());
testMain(() => new LinkedHashSet());
@@ -508,4 +519,9 @@
testCESetFrom((x) => new SplayTreeSet<CE>.from(x,
customCompare(20), validKey));
testCESetFrom((x) => new SplayTreeSet<CE>.from(x, identityCompare));
+
+ testASetFrom((x) => new Set<A>.from(x));
+ testASetFrom((x) => new HashSet<A>.from(x));
+ testASetFrom((x) => new LinkedHashSet<A>.from(x));
+ testASetFrom((x) => new SplayTreeSet<A>.from(x));
}
diff --git a/tests/html/html.status b/tests/html/html.status
index 2b538fc..dfd1a25 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -60,7 +60,6 @@
fileapi_test/getFile: Pass, Fail # Issue 20488
async_test: RuntimeError, OK # Uses Isolate.spawn.
isolates_test: RuntimeError, OK # Uses Isolate.spawn.
-custom/created_callback_test: Fail # Support for created constructor. Issue 14835
[ $compiler == none && ($runtime == drt || $runtime == dartium ) && $mode == debug ]
websocket_test/websocket: Skip # Issue 17666
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 3508c2c..157f638 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -183,3 +183,6 @@
[ $compiler == dart2js && $cps_ir && $checked ]
*: Skip # `assert` not implemented
+
+[ $compiler == precompiler && $runtime == dart_precompiled && $system == android ]
+*: Skip # Issue #26373
diff --git a/tests/language/language.status b/tests/language/language.status
index c3a14b9..ca50f91 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -219,3 +219,7 @@
# TODO(vegorov) Encoding limitation: StoreField bytecode only supports 256
# fields in an object.
large_class_declaration_test: Skip
+
+[ $compiler == precompiler && $runtime == dart_precompiled && $system == android ]
+vm/optimized_guarded_field_isolates_test: Skip # Issue #26373
+issue23244_test: Skip # Issue #26373
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 46f4331..adb3a7d 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -295,3 +295,13 @@
# SIMDBC interpreter doesn't support --no_lazy_dispatchers
no_lazy_dispatchers_test: SkipByDesign
+
+[ $compiler == precompiler && $runtime == dart_precompiled && $system == android ]
+io/*: Skip # Issue #26376
+
+typed_data_isolate_test: Skip # Issue #26376
+typed_array_test: Skip # Issue #26376
+typed_array_int64_uint64_test: Skip # Issue #26376
+
+oom_error_stacktrace_test: Skip # Issue #26377
+out_of_memory_test: Skip # Issue #26377
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 074f02f..c819c4b 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -5,7 +5,7 @@
!.gitignore
!pkg
!pkg_tested
-!boringssl
+!/boringssl
!drt_resources
!d8
!7zip.tar.gz.sha1
diff --git a/third_party/boringssl/.gitignore b/third_party/boringssl/.gitignore
index 6eda124..a0cb5a8 100644
--- a/third_party/boringssl/.gitignore
+++ b/third_party/boringssl/.gitignore
@@ -1,2 +1,4 @@
# ignore the checkout of boringssl.
src/
+*.mk
+*.Makefile
diff --git a/tools/VERSION b/tools/VERSION
index 57ab3a2..ec6b498 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 1
MINOR 17
PATCH 0
-PRERELEASE 1
+PRERELEASE 2
PRERELEASE_PATCH 0
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index f4ddd0c..b7500f2 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -9,7 +9,7 @@
vars.update({
"dartium_chromium_commit": "18554681ff1dfb53a553375c1b0c641fb3d63a1a",
- "dartium_webkit_commit": "1ebe477439d73297f0e6090b474fd9b761407434",
+ "dartium_webkit_commit": "ef30dc04127c86283c1f5c5c6b0094d73b1e29df",
"chromium_base_revision": "338390",
# We use mirrors of all github repos to guarantee reproducibility and
diff --git a/tools/dom/src/Validators.dart b/tools/dom/src/Validators.dart
index 4dbe32c..ee42c51 100644
--- a/tools/dom/src/Validators.dart
+++ b/tools/dom/src/Validators.dart
@@ -167,10 +167,21 @@
sanitizeNode(node, parent);
var child = node.lastChild;
- while (child != null) {
- // Child may be removed during the walk.
- var nextChild = child.previousNode;
- walk(child, node);
+ while (null != child) {
+ var nextChild;
+ try {
+ // Child may be removed during the walk, and we may not
+ // even be able to get its previousNode.
+ nextChild = child.previousNode;
+ } catch (e) {
+ // Child appears bad, remove it. We want to check the rest of the
+ // children of node and, but we have no way of getting to the next
+ // child, so start again from the last child.
+ _removeNode(child, node);
+ child = null;
+ nextChild = node.lastChild;
+ }
+ if (child != null) walk(child, node);
child = nextChild;
}
}
diff --git a/tools/dom/src/shared_html.dart b/tools/dom/src/shared_html.dart
index 27fa2b7..7342cdf 100644
--- a/tools/dom/src/shared_html.dart
+++ b/tools/dom/src/shared_html.dart
@@ -14,7 +14,10 @@
if (callback == null) return null;
// TODO(jacobr): we cast to _wrapZoneCallback/*<A, R>*/ to hack around missing
// generic method support in zones.
- return Zone.current.bindUnaryCallback(callback, runGuarded: true) as _wrapZoneCallback/*<A, R>*/;
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneCallback/*<A, R>*/ wrapped =
+ Zone.current.bindUnaryCallback(callback, runGuarded: true);
+ return wrapped;
}
_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
@@ -22,7 +25,10 @@
if (callback == null) return null;
// We cast to _wrapZoneBinaryCallback/*<A, B, R>*/ to hack around missing
// generic method support in zones.
- return Zone.current.bindBinaryCallback(callback, runGuarded: true) as _wrapZoneBinaryCallback/*<A, B, R>*/;
+ // ignore: STRONG_MODE_DOWN_CAST_COMPOSITE
+ _wrapZoneBinaryCallback/*<A, B, R>*/ wrapped =
+ Zone.current.bindBinaryCallback(callback, runGuarded: true);
+ return wrapped;
}
/**
diff --git a/tools/sdks/README b/tools/sdks/README
index f1f1fd3..5771731 100644
--- a/tools/sdks/README
+++ b/tools/sdks/README
@@ -8,9 +8,9 @@
the subdirectories to have the special names "linux", "win", and "mac", which
the download script is hardcoded to recognize.
-The linux SDK has had two extra dart executables added to the bin directory.
-'dart-mips' and 'dart-arm' are executables compiled to run on mips and arm
-processors, respectively.
+The linux SDK has three extra dart executables added to the bin directory.
+'dart-mips', 'dart-arm', and 'dart-arm64' are executables compiled to run on
+mips, arm, and arm64 (aarch64) processors, respectively.
To upload new versions of these tar files, use the "upload_to_google_storage"
tool in depot_tools, and download the new stable SDKs from the dartlang.org
diff --git a/tools/sdks/linux/dart-sdk.tar.gz.sha1 b/tools/sdks/linux/dart-sdk.tar.gz.sha1
index 9083f2b..3a4aab2 100644
--- a/tools/sdks/linux/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/linux/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-360de5bc1ad8b525f2ccc98c80fd87131caaefe2
\ No newline at end of file
+0c27d9ced0e84a07ee98f99d5057121744138ac9
\ No newline at end of file
diff --git a/tools/sdks/mac/dart-sdk.tar.gz.sha1 b/tools/sdks/mac/dart-sdk.tar.gz.sha1
index 292199a..5e27c0c 100644
--- a/tools/sdks/mac/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/mac/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-45bb23f239c67de5e01a24e7efcf4b323eb9c36c
\ No newline at end of file
+78d5d490650f7cb834a6e67ba882be106dd6324f
\ No newline at end of file
diff --git a/tools/sdks/win/dart-sdk.tar.gz.sha1 b/tools/sdks/win/dart-sdk.tar.gz.sha1
index 54587b2..060bbb7 100644
--- a/tools/sdks/win/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/win/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-1264ca2ff3131284a53ccffadeb230835300c602
\ No newline at end of file
+6c0d135f57ac07f8ad70f21b29a3645bce2edb50
\ No newline at end of file
diff --git a/tools/test.dart b/tools/test.dart
index bbfdf25..e00357d 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -61,6 +61,9 @@
var optionsParser = new TestOptionsParser();
var configurations = optionsParser.parse(arguments);
if (configurations != null && configurations.length > 0) {
+ // All the testing is carried out asynchronously in tasks created by this
+ // call.
+ // TODO(26372): Ensure that all tasks complete before the returned future.
testConfigurations(configurations);
}
});
diff --git a/tools/test.py b/tools/test.py
index 9a32fa5..8db546e 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -18,6 +18,16 @@
dart_test_script = string.join([tools_dir, dart_script_name], os.sep)
command = [utils.CheckedInSdkExecutable(),
'--checked', dart_test_script] + args
+
+ # The testing script potentially needs the android platform tools in PATH so
+ # we do that in ./tools/test.py (a similar logic exists in ./tools/build.py).
+ android_platform_tools = os.path.normpath(os.path.join(
+ tools_dir,
+ '../third_party/android_tools/sdk/platform-tools'))
+ if os.path.isdir(android_platform_tools):
+ os.environ['PATH'] = '%s%s%s' % (
+ os.environ['PATH'], os.pathsep, android_platform_tools)
+
exit_code = subprocess.call(command)
utils.DiagnoseExitCode(exit_code, command)
return exit_code
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart
index 1d39071..bf83128 100644
--- a/tools/testing/dart/android.dart
+++ b/tools/testing/dart/android.dart
@@ -7,30 +7,44 @@
import "dart:async";
import "dart:convert" show LineSplitter, UTF8;
import "dart:core";
+import "dart:collection";
import "dart:io";
import "path.dart";
import "utils.dart";
-Future _executeCommand(String executable, List<String> args,
- [String stdin = ""]) {
- return _executeCommandRaw(executable, args, stdin).then((results) => null);
-}
+class AdbCommandResult {
+ final String command;
+ final String stdout;
+ final String stderr;
+ final int exitCode;
+ final bool timedOut;
-Future _executeCommandGetOutput(String executable, List<String> args,
- [String stdin = ""]) {
- return _executeCommandRaw(executable, args, stdin).then((output) => output);
+ AdbCommandResult(this.command, this.stdout, this.stderr, this.exitCode,
+ this.timedOut);
+
+ void throwIfFailed() {
+ if (exitCode != 0) {
+ var error = "Running: $command failed:"
+ "stdout:\n ${stdout.trim()}\n"
+ "stderr:\n ${stderr.trim()}\n"
+ "exitCode: $exitCode\n"
+ "timedOut: $timedOut";
+ throw new Exception(error);
+ }
+ }
}
/**
- * [_executeCommandRaw] will write [stdin] to the standard input of the created
+ * [_executeCommand] will write [stdin] to the standard input of the created
* process and will return a tuple (stdout, stderr).
*
* If the exit code of the process was nonzero it will complete with an error.
* If starting the process failed, it will complete with an error as well.
*/
-Future _executeCommandRaw(String executable, List<String> args,
- [String stdin = ""]) {
+Future<AdbCommandResult> _executeCommand(
+ String executable, List<String> args,
+ {String stdin, Duration timeout}) {
Future<String> getOutput(Stream<List<int>> stream) {
return stream
.transform(UTF8.decoder)
@@ -38,31 +52,32 @@
.then((data) => data.join(""));
}
- DebugLogger.info("Running: '\$ $executable ${args.join(' ')}'");
- return Process.start(executable, args).then((Process process) {
+ return Process.start(executable, args).then((Process process) async {
if (stdin != null && stdin != '') {
process.stdin.write(stdin);
}
process.stdin.close();
- var futures = [
- getOutput(process.stdout),
- getOutput(process.stderr),
- process.exitCode
- ];
- return Future.wait(futures).then((results) {
- bool success = results[2] == 0;
- if (!success) {
- var error = "Running: '\$ $executable ${args.join(' ')}' failed:"
- "stdout: \n ${results[0]}"
- "stderr: \n ${results[1]}"
- "exitCode: \n ${results[2]}";
- throw new Exception(error);
- } else {
- DebugLogger.info("Success: $executable finished");
- }
- return results[0];
- });
+ Timer timer;
+ bool timedOut = false;
+ if (timeout != null) {
+ timer = new Timer(timeout, () {
+ timedOut = true;
+ process.kill(ProcessSignal.SIGTERM);
+ timer = null;
+ });
+ }
+
+ var results = await Future.wait([
+ getOutput(process.stdout),
+ getOutput(process.stderr),
+ process.exitCode
+ ]);
+ if (timer != null) timer.cancel();
+
+ String command = "$executable ${args.join(' ')}";
+ return new AdbCommandResult(
+ command, results[0], results[1], results[2], timedOut);
});
}
@@ -152,7 +167,7 @@
* Helper class to create avd device configurations.
*/
class AndroidHelper {
- static Future createAvd(String name, String target) {
+ static Future createAvd(String name, String target) async {
var args = [
'--silent',
'create',
@@ -166,7 +181,8 @@
'armeabi-v7a'
];
// We're adding newlines to stdin to simulate <enter>.
- return _executeCommand("android", args, "\n\n\n\n");
+ var result = await _executeCommand("android", args, stdin: "\n\n\n\n");
+ result.throwIfFailed();
}
}
@@ -192,25 +208,15 @@
* Polls the 'sys.boot_completed' property. Returns as soon as the property is
* 1.
*/
- Future waitForBootCompleted() {
- var timeout = const Duration(seconds: 2);
- var completer = new Completer();
-
- checkUntilBooted() {
- _adbCommandGetOutput(['shell', 'getprop', 'sys.boot_completed'])
- .then((String stdout) {
- stdout = stdout.trim();
- if (stdout == '1') {
- completer.complete();
- } else {
- new Timer(timeout, checkUntilBooted);
- }
- }).catchError((error) {
- new Timer(timeout, checkUntilBooted);
- });
+ Future waitForBootCompleted() async {
+ while (true) {
+ try {
+ AdbCommandResult result =
+ await _adbCommand(['shell', 'getprop', 'sys.boot_completed']);
+ if (result.stdout.trim() == '1') return;
+ } catch (_) { }
+ await new Future.delayed(const Duration(seconds: 2));
}
- checkUntilBooted();
- return completer.future;
}
/**
@@ -299,22 +305,58 @@
return _adbCommand(arguments);
}
- Future _adbCommand(List<String> adbArgs) {
- if (_deviceId != null) {
- var extendedAdbArgs = ['-s', _deviceId];
- extendedAdbArgs.addAll(adbArgs);
- adbArgs = extendedAdbArgs;
- }
- return _executeCommand("adb", adbArgs);
+ Future<AdbCommandResult> runAdbCommand(List<String> adbArgs,
+ {Duration timeout}) {
+ return _executeCommand(
+ "adb", _deviceSpecificArgs(adbArgs), timeout: timeout);
}
- Future<String> _adbCommandGetOutput(List<String> adbArgs) {
+ Future<AdbCommandResult> runAdbShellCommand(List<String> shellArgs,
+ {Duration timeout}) async {
+ const MARKER = 'AdbShellExitCode: ';
+
+ // The exitcode of 'adb shell ...' can be 0 even though the command failed
+ // with a non-zero exit code. We therefore explicitly print it to stdout and
+ // search for it.
+
+ var args = ['shell',
+ "${shellArgs.join(' ')} ; echo $MARKER \$?"];
+ AdbCommandResult result = await _executeCommand(
+ "adb", _deviceSpecificArgs(args), timeout: timeout);
+ int exitCode = result.exitCode;
+ var lines = result
+ .stdout.split('\n')
+ .where((line) => line.trim().length > 0)
+ .toList();
+ if (lines.length > 0) {
+ int index = lines.last.indexOf(MARKER);
+ if (index >= 0) {
+ exitCode = int.parse(
+ lines.last.substring(index + MARKER.length).trim());
+ exitCode = exitCode.toSigned(8);
+ } else {
+ // In case of timeouts, for example, we won't get the exitcode marker.
+ assert(result.exitCode != 0);
+ }
+ }
+ return new AdbCommandResult(
+ result.command, result.stdout, result.stderr, exitCode,
+ result.timedOut);
+ }
+
+ Future<AdbCommandResult> _adbCommand(List<String> adbArgs) async {
+ var result = await _executeCommand("adb", _deviceSpecificArgs(adbArgs));
+ result.throwIfFailed();
+ return result;
+ }
+
+ List<String> _deviceSpecificArgs(List<String> adbArgs) {
if (_deviceId != null) {
var extendedAdbArgs = ['-s', _deviceId];
extendedAdbArgs.addAll(adbArgs);
adbArgs = extendedAdbArgs;
}
- return _executeCommandGetOutput("adb", adbArgs);
+ return adbArgs;
}
}
@@ -350,3 +392,45 @@
Intent(this.action, this.package, this.activity, [this.dataUri]);
}
+
+/**
+ * Discovers all available devices and supports acquire/release.
+ */
+class AdbDevicePool {
+ final Queue<AdbDevice> _idleDevices = new Queue<AdbDevice>();
+ final Queue<Completer> _waiter = new Queue<Completer>();
+
+ AdbDevicePool(List<AdbDevice> idleDevices) {
+ _idleDevices.addAll(idleDevices);
+ }
+
+ static Future<AdbDevicePool> create() async {
+ var names = await AdbHelper.listDevices();
+ var devices = names.map((id) => new AdbDevice(id)).toList();
+ if (devices.length == 0) {
+ throw new Exception(
+ 'No android devices found. '
+ 'Please make sure "adb devices" shows your device!');
+ }
+ return new AdbDevicePool(devices);
+ }
+
+ Future<AdbDevice> acquireDevice() async {
+ if (_idleDevices.length > 0) {
+ return _idleDevices.removeFirst();
+ } else {
+ var completer = new Completer();
+ _waiter.add(completer);
+ return completer.future;
+ }
+ }
+
+ void releaseDevice(AdbDevice device) {
+ if (_waiter.length > 0) {
+ Completer completer = _waiter.removeFirst();
+ completer.complete(device);
+ } else {
+ _idleDevices.add(device);
+ }
+ }
+}
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 161252a..7c0945e 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -79,7 +79,8 @@
isDebug: isDebug,
isChecked: isChecked,
arch: configuration['arch'],
- useBlobs: useBlobs);
+ useBlobs: useBlobs,
+ isAndroid: configuration['system'] == 'android');
case 'none':
return new NoneCompilerConfiguration(
isDebug: isDebug,
@@ -302,11 +303,11 @@
class PrecompilerCompilerConfiguration extends CompilerConfiguration {
final String arch;
final bool useBlobs;
+ final bool isAndroid;
- PrecompilerCompilerConfiguration({bool isDebug, bool isChecked, String arch, bool useBlobs})
- : super._subclass(isDebug: isDebug, isChecked: isChecked),
- arch = arch,
- useBlobs = useBlobs;
+ PrecompilerCompilerConfiguration({bool isDebug, bool isChecked,
+ this.arch, this.useBlobs, this.isAndroid})
+ : super._subclass(isDebug: isDebug, isChecked: isChecked);
int computeTimeoutMultiplier() {
int multiplier = 2;
@@ -345,6 +346,9 @@
if (useBlobs) {
args.add("--use_blobs");
}
+ if (isAndroid && arch == 'arm') {
+ args.add('--no-sim-use-hardfp');
+ }
args.addAll(arguments);
return commandBuilder.getCompilationCommand('precompiler', tempDir, !useSdk,
@@ -357,7 +361,8 @@
CommandBuilder commandBuilder,
List arguments,
Map<String, String> environmentOverrides) {
- var cc, cc_flags, shared, libname;
+
+ var cc, shared, libname;
if (Platform.isLinux) {
cc = 'gcc';
shared = '-shared';
@@ -369,17 +374,24 @@
} else {
throw "Platform not supported: ${Platform.operatingSystem}";
}
+ if (isAndroid) {
+ // TODO: If we're not using "--use_blobs" we need to use the arm cross
+ // compiler instead of just 'gcc' for .
+ }
+ var cc_flags;
if (arch == 'x64') {
cc_flags = "-m64";
} else if (arch == 'simarm64') {
cc_flags = "-m64";
+ } else if (arch == 'ia32') {
+ cc_flags = "-m32";
} else if (arch == 'simarm') {
cc_flags = "-m32";
} else if (arch == 'simmips') {
cc_flags = "-m32";
} else if (arch == 'arm') {
- cc_flags = "";
+ cc_flags = null;
} else if (arch == 'mips') {
cc_flags = "-EL";
} else {
@@ -387,13 +399,12 @@
}
var exec = cc;
- var args = [
- shared,
- cc_flags,
+ var args = (cc_flags != null) ? [ shared, cc_flags ] : [ shared ];
+ args.addAll([
'-o',
'$tempDir/$libname',
'$tempDir/precompiled.S'
- ];
+ ]);
return commandBuilder.getCompilationCommand('assemble', tempDir, !useSdk,
bootstrapDependencies(buildDir), exec, args, environmentOverrides);
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index 7191342..b8e9e3d7 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -54,6 +54,9 @@
return new DartProductRuntimeConfiguration();
case 'dart_precompiled':
+ if (configuration['system'] == 'android') {
+ return new DartPrecompiledAdbRuntimeConfiguration(useBlobs: useBlobs);
+ }
return new DartPrecompiledRuntimeConfiguration(useBlobs: useBlobs);
case 'drt':
@@ -275,6 +278,32 @@
}
}
+class DartPrecompiledAdbRuntimeConfiguration
+ extends DartVmRuntimeConfiguration {
+ final bool useBlobs;
+ DartPrecompiledAdbRuntimeConfiguration({bool useBlobs}) : useBlobs = useBlobs;
+
+ List<Command> computeRuntimeCommands(
+ TestSuite suite,
+ CommandBuilder commandBuilder,
+ CommandArtifact artifact,
+ List<String> arguments,
+ Map<String, String> environmentOverrides) {
+ String script = artifact.filename;
+ String type = artifact.mimeType;
+ if (script != null && type != 'application/dart-precompiled') {
+ throw "dart_precompiled cannot run files of type '$type'.";
+ }
+
+ String precompiledRunner = suite.dartPrecompiledBinaryFileName;
+ return <Command>[
+ commandBuilder.getAdbPrecompiledCommand(precompiledRunner,
+ script,
+ useBlobs)
+ ];
+ }
+}
+
/// Temporary runtime configuration for browser runtimes that haven't been
/// migrated yet.
// TODO(ahe): Remove this class.
diff --git a/tools/testing/dart/test_configurations.dart b/tools/testing/dart/test_configurations.dart
index ff48273..f8cd209 100644
--- a/tools/testing/dart/test_configurations.dart
+++ b/tools/testing/dart/test_configurations.dart
@@ -8,6 +8,7 @@
import 'dart:io';
import "dart:math" as math;
+import 'android.dart';
import "browser_controller.dart";
import "co19_test_config.dart";
import "http_server.dart";
@@ -49,7 +50,7 @@
new Path('utils/tests/peg'),
];
-void testConfigurations(List<Map> configurations) {
+Future testConfigurations(List<Map> configurations) async {
var startTime = new DateTime.now();
// Extract global options from first configuration.
var firstConf = configurations[0];
@@ -281,26 +282,34 @@
eventListener.add(new ExitCodeSetter());
}
- void startProcessQueue() {
- // [firstConf] is needed here, since the ProcessQueue needs to know the
- // settings of 'noBatch' and 'local_ip'
- new ProcessQueue(
- firstConf,
- maxProcesses,
- maxBrowserProcesses,
- startTime,
- testSuites,
- eventListener,
- allTestsFinished,
- verbose,
- recordingPath,
- recordingOutputPath);
+ // If any of the configurations need to access android devices we'll first
+ // make a pool of all available adb devices.
+ AdbDevicePool adbDevicePool;
+ bool needsAdbDevicePool = configurations.any((Map conf) {
+ return conf['runtime'] == 'dart_precompiled' &&
+ conf['system'] == 'android';
+ });
+ if (needsAdbDevicePool) {
+ adbDevicePool = await AdbDevicePool.create();
}
// Start all the HTTP servers required before starting the process queue.
- if (serverFutures.isEmpty) {
- startProcessQueue();
- } else {
- Future.wait(serverFutures).then((_) => startProcessQueue());
+ if (!serverFutures.isEmpty) {
+ await Future.wait(serverFutures);
}
+
+ // [firstConf] is needed here, since the ProcessQueue needs to know the
+ // settings of 'noBatch' and 'local_ip'
+ new ProcessQueue(
+ firstConf,
+ maxProcesses,
+ maxBrowserProcesses,
+ startTime,
+ testSuites,
+ eventListener,
+ allTestsFinished,
+ verbose,
+ recordingPath,
+ recordingOutputPath,
+ adbDevicePool);
}
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index d4849a4..bc83dc0 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -157,7 +157,7 @@
'system',
'The operating system to run tests on',
['-s', '--system'],
- ['linux', 'macos', 'windows'],
+ ['linux', 'macos', 'windows', 'android'],
Platform.operatingSystem),
new _TestOptionSpecification(
'checked', 'Run tests in checked mode', ['--checked'], [], false,
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 0d64136..8d189ae 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -18,6 +18,7 @@
// CommandOutput.exitCode in subclasses of CommandOutput.
import "dart:io" as io;
import "dart:math" as math;
+import 'android.dart';
import 'dependency_graph.dart' as dgraph;
import "browser_controller.dart";
import "path.dart";
@@ -344,6 +345,33 @@
: super._("vm", executable, arguments, environmentOverrides);
}
+class AdbPrecompilationCommand extends Command {
+ final String precompiledRunnerFilename;
+ final String precompiledTestDirectory;
+ final bool useBlobs;
+
+ AdbPrecompilationCommand._(this.precompiledRunnerFilename,
+ this.precompiledTestDirectory,
+ this.useBlobs)
+ : super._("adb_precompilation");
+
+ void _buildHashCode(HashCodeBuilder builder) {
+ super._buildHashCode(builder);
+ builder.add(precompiledRunnerFilename);
+ builder.add(precompiledTestDirectory);
+ builder.add(useBlobs);
+ }
+
+ bool _equal(AdbPrecompilationCommand other) =>
+ super._equal(other) &&
+ precompiledRunnerFilename == other.precompiledRunnerFilename &&
+ useBlobs == other.useBlobs &&
+ precompiledTestDirectory == other.precompiledTestDirectory;
+
+ String toString() => 'Steps to push precompiled runner and precompiled code '
+ 'to an attached device. Uses (and requires) adb.';
+}
+
class JSCommandlineCommand extends ProcessCommand {
JSCommandlineCommand._(
String displayName, String executable, List<String> arguments,
@@ -610,6 +638,14 @@
return _getUniqueCommand(command);
}
+ AdbPrecompilationCommand getAdbPrecompiledCommand(String precompiledRunner,
+ String testDirectory,
+ bool useBlobs) {
+ var command = new AdbPrecompilationCommand._(
+ precompiledRunner, testDirectory, useBlobs);
+ return _getUniqueCommand(command);
+ }
+
Command getJSCommandlineCommand(String displayName, executable, arguments,
[environment = null]) {
var command = new JSCommandlineCommand._(
@@ -1625,6 +1661,9 @@
} else if (command is VmCommand) {
return new VmCommandOutputImpl(
command, exitCode, timedOut, stdout, stderr, time, pid);
+ } else if (command is AdbPrecompilationCommand) {
+ return new VmCommandOutputImpl(
+ command, exitCode, timedOut, stdout, stderr, time, pid);
} else if (command is CompilationCommand) {
if (command.displayName == 'precompiler' ||
command.displayName == 'dart2snapshot') {
@@ -2396,6 +2435,7 @@
final Map globalConfiguration;
final int maxProcesses;
final int maxBrowserProcesses;
+ AdbDevicePool adbDevicePool;
// For dart2js and analyzer batch processing,
// we keep a list of batch processes.
@@ -2406,7 +2446,8 @@
bool _finishing = false;
CommandExecutorImpl(
- this.globalConfiguration, this.maxProcesses, this.maxBrowserProcesses);
+ this.globalConfiguration, this.maxProcesses, this.maxBrowserProcesses,
+ {this.adbDevicePool});
Future cleanup() {
assert(!_finishing);
@@ -2460,11 +2501,99 @@
.runCommand(command.flavor, command, timeout, command.arguments);
} else if (command is ScriptCommand) {
return command.run();
+ } else if (command is AdbPrecompilationCommand) {
+ assert(adbDevicePool != null);
+ return adbDevicePool.acquireDevice().then((AdbDevice device) {
+ return _runAdbPrecompilationCommand(
+ device, command, timeout).whenComplete(() {
+ adbDevicePool.releaseDevice(device);
+ });
+ });
} else {
return new RunningProcess(command, timeout).run();
}
}
+ Future<CommandOutput> _runAdbPrecompilationCommand(
+ AdbDevice device, AdbPrecompilationCommand command, int timeout) async {
+ var runner = command.precompiledRunnerFilename;
+ var testdir = command.precompiledTestDirectory;
+ var devicedir = '/data/local/tmp/precompilation-testing';
+ var deviceTestDir = '/data/local/tmp/precompilation-testing/test';
+
+ // We copy all the files which the vm precompiler puts into the test
+ // directory.
+ List<String> files = new io.Directory(testdir)
+ .listSync()
+ .where((fse) => fse is io.File)
+ .map((file) => file.path)
+ .map((path) => path.substring(path.lastIndexOf('/') + 1))
+ .toList();
+
+ var timeoutDuration = new Duration(seconds: timeout);
+
+ // All closures are of type "Future<AdbCommandResult> run()"
+ List<Function> steps = [];
+
+ steps.add(() => device.runAdbShellCommand(
+ ['rm', '-Rf', deviceTestDir]));
+ steps.add(() => device.runAdbShellCommand(
+ ['mkdir', '-p', deviceTestDir]));
+ // TODO: We should find a way for us to cache the runner binary and avoid
+ // pushhing it for every single test (this is bad for SSD cycle time, test
+ // timing).
+ steps.add(() => device.runAdbCommand(
+ ['push', runner, '$devicedir/runner']));
+ steps.add(() => device.runAdbShellCommand(
+ ['chmod', '777', '$devicedir/runner']));
+
+ for (var file in files) {
+ steps.add(() => device.runAdbCommand(
+ ['push', '$testdir/$file', '$deviceTestDir/$file']));
+ }
+
+ if (command.useBlobs) {
+ steps.add(() => device.runAdbShellCommand(
+ ['$devicedir/runner', '--run-precompiled-snapshot=$deviceTestDir',
+ '--use_blobs', 'ignored.dart'], timeout: timeoutDuration));
+ } else {
+ steps.add(() => device.runAdbShellCommand(
+ ['$devicedir/runner', '--run-precompiled-snapshot=$deviceTestDir',
+ 'ignored.dart'], timeout: timeoutDuration));
+ }
+
+ var stopwatch = new Stopwatch()..start();
+ var writer = new StringBuffer();
+
+ await device.waitForBootCompleted();
+ await device.waitForDevice();
+
+ AdbCommandResult result;
+ for (var i = 0; i < steps.length; i++) {
+ var fun = steps[i];
+ var commandStopwatch = new Stopwatch()..start();
+ result = await fun();
+
+ writer.writeln("Executing ${result.command}");
+ if (result.stdout.length > 0) {
+ writer.writeln("Stdout:\n${result.stdout.trim()}");
+ }
+ if (result.stderr.length > 0) {
+ writer.writeln("Stderr:\n${result.stderr.trim()}");
+ }
+ writer.writeln("ExitCode: ${result.exitCode}");
+ writer.writeln("Time: ${commandStopwatch.elapsed}");
+ writer.writeln("");
+
+ // If one command fails, we stop processing the others and return
+ // immediately.
+ if (result.exitCode != 0) break;
+ }
+ return createCommandOutput(
+ command, result.exitCode, result.timedOut, UTF8.encode('$writer'),
+ [], stopwatch.elapsed, false);
+ }
+
BatchRunnerProcess _getBatchRunner(String identifier) {
// Start batch processes if needed
var runners = _batchProcesses[identifier];
@@ -2716,7 +2845,8 @@
DateTime startTime, testSuites, this._eventListener, this._allDone,
[bool verbose = false,
String recordingOutputFile,
- String recordedInputFile]) {
+ String recordedInputFile,
+ AdbDevicePool adbDevicePool]) {
void setupForListing(TestCaseEnqueuer testCaseEnqueuer) {
_graph.events
.where((event) => event is dgraph.GraphSealedEvent)
@@ -2817,7 +2947,8 @@
executor = new ReplayingCommandExecutor(new Path(recordedInputFile));
} else {
executor = new CommandExecutorImpl(
- _globalConfiguration, maxProcesses, maxBrowserProcesses);
+ _globalConfiguration, maxProcesses,
+ maxBrowserProcesses, adbDevicePool: adbDevicePool);
}
// Run "runnable commands" using [executor] subject to
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index dbab65e..58b0937 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -2233,12 +2233,14 @@
static String outputDir(Map configuration) {
var result = '';
var system = configuration['system'];
- if (system == 'linux') {
+ if (system == 'linux' || system == 'android') {
result = 'out/';
} else if (system == 'macos') {
result = 'xcodebuild/';
} else if (system == 'windows') {
result = 'build/';
+ } else {
+ throw new Exception('Unknown operating system: "$system"');
}
return result;
}
@@ -2335,9 +2337,22 @@
default:
throw 'Unrecognized mode configuration: ${configuration['mode']}';
}
+ var os;
+ switch (configuration['system']) {
+ case 'android':
+ os = 'Android';
+ break;
+ case 'linux':
+ case 'macos':
+ case 'windows':
+ os = '';
+ break;
+ default:
+ throw 'Unrecognized operating system: ${configuration['system']}';
+ }
var arch = configuration['arch'].toUpperCase();
- var normal = '$mode$arch';
- var cross = '${mode}X$arch';
+ var normal = '$mode$os$arch';
+ var cross = '$mode${os}X$arch';
var outDir = outputDir(configuration);
var normalDir = new Directory(new Path('$outDir$normal').toNativePath());
var crossDir = new Directory(new Path('$outDir$cross').toNativePath());