Version 1.18.0-dev.0.0
Merge '0f061f1987061f5cc6e16b1d0f9bcae532c5360e' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca849bd..637e978 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-## 1.17.0
+## 1.17.0 - 2016-06-06
### Core library changes
* `dart:convert`
@@ -34,6 +34,13 @@
* Dartium and content shell
* Debugging Dart code inside iframes improved, was broken.
+## 1.16.1 - 2016-05-24
+
+Patch release, resolves one issue:
+
+* VM: Fixes a bug that caused intermittent hangs on Windows.
+(SDK issue [26400](https://github.com/dart-lang/sdk/issues/26400))
+
## 1.16.0 - 2016-04-26
### Core library changes
diff --git a/DEPS b/DEPS
index 1b74da6..7264d41 100644
--- a/DEPS
+++ b/DEPS
@@ -25,7 +25,7 @@
"github_dartlang": "https://github.com/dart-lang/%s.git",
"gyp_rev": "@6ee91ad8659871916f9aa840d42e1513befdf638",
- "co19_rev": "@3ed795ea02e022ef19c77cf1b6095b7c8f5584d0",
+ "co19_rev": "@3f0a4bc9a080a792cdf5f093147a900f99ea301f",
"chromium_git": "https://chromium.googlesource.com",
# Revisions of /third_party/* dependencies.
@@ -41,15 +41,16 @@
"charcode_tag": "@1.1.0",
"chrome_rev" : "@19997",
"cli_util_tag" : "@0.0.1+2",
+ "code_transformers_rev": "@bfe9799e88d9c231747435e1c1d2495ef5ecd966",
"collection_tag": "@1.6.0",
"convert_tag": "@1.0.0",
- "crypto_tag" : "@1.1.0",
+ "crypto_tag" : "@1.1.1",
"csslib_tag" : "@0.12.0",
"dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
"dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
"dart_style_tag": "@0.2.4",
"dartdoc_tag" : "@v0.9.0",
- "dev_compiler_rev": "@adda29b31dc8fe2f8d1a5c1304384988503384c8",
+ "dev_compiler_rev": "@7f68e5ef424dd26344572daf02595ab23fb16941",
"fixnum_tag": "@0.10.5",
"func_rev": "@8d4aea75c21be2179cb00dc2b94a71414653094e",
"glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
@@ -59,7 +60,8 @@
"http_tag" : "@0.11.3+3",
"http_throttle_rev" : "@a81f08be942cdd608883c7b67795c12226abc235",
"idl_parser_rev": "@7fbe68cab90c38147dee4f48c30ad0d496c17915",
- "intl_rev": "@a8b480b9c436f6c0ec16730804c914bdb4e30d53",
+ "initialize_rev": "@595d501a92c3716395ad2d81f9aabdb9f90879b6",
+ "intl_tag": "@0.13.0",
"jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "@2.0.0",
"linter_rev": "@ccd8dbf7562b7645dc8c54a578b78b38970c71d6",
@@ -98,7 +100,7 @@
"string_scanner_tag": "@0.1.4",
"sunflower_rev": "@879b704933413414679396b129f5dfa96f7a0b1e",
"test_reflective_loader_tag": "@0.0.3",
- "test_tag": "@0.12.12",
+ "test_tag": "@0.12.13+1",
"typed_data_tag": "@1.1.2",
"usage_rev": "@b5080dac0d26a5609b266f8fdb0d053bc4c1c638",
"utf_rev": "@1f55027068759e2d52f2c12de6a57cce5f3c5ee6",
@@ -170,6 +172,9 @@
(Var("github_mirror") % "crypto") + Var("crypto_tag"),
Var("dart_root") + "/third_party/pkg/csslib":
(Var("github_mirror") % "csslib") + Var("csslib_tag"),
+ Var("dart_root") + "/third_party/pkg/code_transformers":
+ (Var("github_dartlang") % "code_transformers") +
+ Var("code_transformers_rev"),
Var("dart_root") + "/third_party/dart-services":
(Var("github_mirror") % "dart-services") +
Var("dart_services_rev"),
@@ -199,8 +204,10 @@
Var("dart_root") + "/third_party/pkg/http_throttle":
(Var("github_mirror") % "http_throttle") +
Var("http_throttle_rev"),
+ Var("dart_root") + "/third_party/pkg/initialize":
+ (Var("github_dartlang") % "initialize") + Var("initialize_rev"),
Var("dart_root") + "/third_party/pkg/intl":
- (Var("github_mirror") % "intl") + Var("intl_rev"),
+ (Var("github_mirror") % "intl") + Var("intl_tag"),
Var("dart_root") + "/third_party/pkg/json_rpc_2":
(Var("github_mirror") % "json_rpc_2") + Var("json_rpc_2_tag"),
Var("dart_root") + "/third_party/pkg/linter":
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 6b328b2..5a8d8cb 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -77,6 +77,16 @@
}
@override
+ visitAsExpression(AsExpression node) {
+ if (identical(entity, node.asOperator) &&
+ node.expression is ParenthesizedExpression) {
+ _addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
+ _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+ _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+ }
+ }
+
+ @override
visitBlock(Block node) {
if (entity is ExpressionStatement) {
Expression expression = (entity as ExpressionStatement).expression;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
index 3a5608c..995ec27 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
@@ -211,8 +211,9 @@
optype.includeTypeNameSuggestions = true;
optype.typeNameSuggestionsFilter = (DartType dartType, int relevance) {
DartType staticType = node.expression.staticType;
- if (staticType.isDynamic ||
- (dartType.isSubtypeOf(staticType) && dartType != staticType)) {
+ if (staticType != null &&
+ (staticType.isDynamic ||
+ (dartType.isSubtypeOf(staticType) && dartType != staticType))) {
return relevance;
} else {
return null;
@@ -592,8 +593,9 @@
optype.includeTypeNameSuggestions = true;
optype.typeNameSuggestionsFilter = (DartType dartType, int relevance) {
DartType staticType = node.expression.staticType;
- if (staticType.isDynamic ||
- (dartType.isSubtypeOf(staticType) && dartType != staticType)) {
+ if (staticType != null &&
+ (staticType.isDynamic ||
+ (dartType.isSubtypeOf(staticType) && dartType != staticType))) {
return relevance;
} else {
return null;
@@ -770,6 +772,10 @@
if (identical(entity, node.expression)) {
optype.includeReturnValueSuggestions = true;
optype.includeTypeNameSuggestions = true;
+ } else if (node.statements.contains(entity)) {
+ optype.includeReturnValueSuggestions = true;
+ optype.includeTypeNameSuggestions = true;
+ optype.includeVoidReturnSuggestions = true;
}
}
@@ -875,14 +881,6 @@
}
}
- bool _isEntityPrevToken(TokenType expectedType) {
- Object entity = this.entity;
- if (entity is SimpleIdentifier && entity.token.isSynthetic) {
- return entity.token.previous.type == expectedType;
- }
- return false;
- }
-
bool _isEntityPrevTokenSynthetic() {
Object entity = this.entity;
if (entity is AstNode && entity.beginToken.previous?.isSynthetic ?? false) {
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 244fb3d..f58469d 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -338,7 +338,7 @@
}
// add edit
Token keyword = declarationList.keyword;
- if (keyword.keyword == Keyword.VAR) {
+ if (keyword?.keyword == Keyword.VAR) {
SourceRange range = rangeToken(keyword);
_addReplaceEdit(range, typeSource);
} else {
diff --git a/pkg/analysis_server/lib/src/status/ast_writer.dart b/pkg/analysis_server/lib/src/status/ast_writer.dart
index 7303f69..424132e 100644
--- a/pkg/analysis_server/lib/src/status/ast_writer.dart
+++ b/pkg/analysis_server/lib/src/status/ast_writer.dart
@@ -9,6 +9,7 @@
import 'package:analysis_server/src/status/tree_writer.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
/**
* A visitor that will produce an HTML representation of an AST structure.
@@ -41,34 +42,75 @@
Map<String, Object> properties = new HashMap<String, Object>();
properties['name'] = _getName(node);
- if (node is BinaryExpression) {
+ if (node is ArgumentListImpl) {
+ properties['static parameter types'] = node.correspondingStaticParameters;
+ properties['propagated parameter types'] =
+ node.correspondingPropagatedParameters;
+ } else if (node is Annotation) {
+ properties['element'] = node.element;
+ properties['element annotation'] = node.elementAnnotation;
+ } else if (node is BinaryExpression) {
properties['static element'] = node.staticElement;
properties['static type'] = node.staticType;
properties['propagated element'] = node.propagatedElement;
properties['propagated type'] = node.propagatedType;
+ } else if (node is ClassDeclaration) {
+ properties['element'] = node.element;
+ properties['abstract keyword'] = node.abstractKeyword;
+ } else if (node is ClassTypeAlias) {
+ properties['element'] = node.element;
+ properties['abstract keyword'] = node.abstractKeyword;
} else if (node is CompilationUnit) {
properties['element'] = node.element;
+ } else if (node is ConstructorName) {
+ properties['static element'] = node.staticElement;
+ } else if (node is DeclaredIdentifier) {
+ properties['element'] = node.element;
+ properties['keyword'] = node.keyword;
} else if (node is ExportDirective) {
properties['element'] = node.element;
properties['source'] = node.source;
+ } else if (node is FieldDeclaration) {
+ properties['static keyword'] = node.staticKeyword;
+ } else if (node is FormalParameter) {
+ properties['element'] = node.element;
+ properties['kind'] = node.kind;
} else if (node is FunctionDeclaration) {
+ properties['element'] = node.element;
properties['external keyword'] = node.externalKeyword;
properties['property keyword'] = node.propertyKeyword;
} else if (node is FunctionExpressionInvocation) {
properties['static element'] = node.staticElement;
+ properties['static invoke type'] = node.staticInvokeType;
properties['static type'] = node.staticType;
properties['propagated element'] = node.propagatedElement;
+ properties['propagated invoke type'] = node.propagatedInvokeType;
properties['propagated type'] = node.propagatedType;
} else if (node is ImportDirective) {
properties['element'] = node.element;
properties['source'] = node.source;
+ } else if (node is IndexExpression) {
+ properties['static element'] = node.staticElement;
+ properties['static type'] = node.staticType;
+ properties['propagated element'] = node.propagatedElement;
+ properties['propagated type'] = node.propagatedType;
+ } else if (node is InstanceCreationExpression) {
+ properties['static element'] = node.staticElement;
+ properties['static type'] = node.staticType;
+ properties['propagated type'] = node.propagatedType;
} else if (node is LibraryDirective) {
properties['element'] = node.element;
} else if (node is MethodDeclaration) {
+ properties['element'] = node.element;
properties['external keyword'] = node.externalKeyword;
properties['modifier keyword'] = node.modifierKeyword;
properties['operator keyword'] = node.operatorKeyword;
properties['property keyword'] = node.propertyKeyword;
+ } else if (node is MethodInvocation) {
+ properties['static invoke type'] = node.staticInvokeType;
+ properties['static type'] = node.staticType;
+ properties['propagated invoke type'] = node.propagatedInvokeType;
+ properties['propagated type'] = node.propagatedType;
} else if (node is PartDirective) {
properties['element'] = node.element;
properties['source'] = node.source;
@@ -84,6 +126,8 @@
properties['static type'] = node.staticType;
properties['propagated element'] = node.propagatedElement;
properties['propagated type'] = node.propagatedType;
+ } else if (node is RedirectingConstructorInvocation) {
+ properties['static element'] = node.staticElement;
} else if (node is SimpleIdentifier) {
properties['static element'] = node.staticElement;
properties['static type'] = node.staticType;
@@ -91,9 +135,25 @@
properties['propagated type'] = node.propagatedType;
} else if (node is SimpleStringLiteral) {
properties['value'] = node.value;
+ } else if (node is SuperConstructorInvocation) {
+ properties['static element'] = node.staticElement;
+ } else if (node is TypeName) {
+ properties['type'] = node.type;
+ } else if (node is VariableDeclarationList) {
+ properties['keyword'] = node.keyword;
+ } else if (node is Declaration) {
+ properties['element'] = node.element;
} else if (node is Expression) {
properties['static type'] = node.staticType;
properties['propagated type'] = node.propagatedType;
+ } else if (node is FunctionBody) {
+ properties['isAsynchronous'] = node.isAsynchronous;
+ properties['isGenerator'] = node.isGenerator;
+ } else if (node is Identifier) {
+ properties['static element'] = node.staticElement;
+ properties['static type'] = node.staticType;
+ properties['propagated element'] = node.propagatedElement;
+ properties['propagated type'] = node.propagatedType;
}
return properties;
@@ -169,10 +229,11 @@
buffer.write(node.offset);
buffer.write('..');
buffer.write(node.offset + node.length - 1);
- buffer.write(']</span>');
+ buffer.write(']');
if (node.isSynthetic) {
buffer.write(' (synthetic)');
}
+ buffer.write('</span>');
buffer.write('<br>');
}
}
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index c3e4bc2..6f5649b 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -42,8 +42,6 @@
Map<String, Object> _computeProperties(Element element) {
Map<String, Object> properties = new HashMap<String, Object>();
- properties['isDeprecated'] = element.isDeprecated;
- properties['isOverride'] = element.isOverride;
properties['metadata'] = element.metadata;
properties['nameOffset'] = element.nameOffset;
if (element is ClassElement) {
@@ -53,16 +51,18 @@
properties['interfaces'] = element.interfaces;
properties['isAbstract'] = element.isAbstract;
properties['isEnum'] = element.isEnum;
+ properties['isMixinApplication'] = element.isMixinApplication;
properties['isOrInheritsProxy'] = element.isOrInheritsProxy;
properties['isProxy'] = element.isProxy;
- properties['isTypedef'] = element.isMixinApplication;
properties['isValidMixin'] = element.isValidMixin;
properties['mixins'] = element.mixins;
properties['supertype'] = element.supertype;
- properties['type'] = element.type;
+ }
+ if (element is ClassMemberElement) {
+ properties['isStatic'] = element.isStatic;
}
if (element is CompilationUnitElement) {
- properties['isEnumConstant'] = element.hasLoadLibraryFunction;
+ properties['hasLoadLibraryFunction'] = element.hasLoadLibraryFunction;
properties['source'] = element.source;
}
if (element is ConstFieldElementImpl) {
@@ -81,7 +81,10 @@
properties['redirectedConstructor'] = element.redirectedConstructor;
}
if (element is ExecutableElement) {
+ properties['hasImplicitReturnType'] = element.hasImplicitReturnType;
+ properties['isAbstract'] = element.isAbstract;
properties['isAsynchronous'] = element.isAsynchronous;
+ properties['isExternal'] = element.isExternal;
properties['isGenerator'] = element.isGenerator;
properties['isOperator'] = element.isOperator;
properties['isStatic'] = element.isStatic;
@@ -99,12 +102,16 @@
if (element is FieldFormalParameterElement) {
properties['field'] = element.field;
}
- if (element is FunctionTypeAliasElement) {
+ if (element is FunctionElement) {
+ properties['isEntryPoint'] = element.isEntryPoint;
+ }
+ if (element is FunctionTypedElement) {
properties['returnType'] = element.returnType;
properties['type'] = element.type;
}
if (element is ImportElement) {
properties['combinators'] = element.combinators;
+ properties['isDeferred'] = element.isDeferred;
properties['library'] = element.library;
}
if (element is LibraryElement) {
@@ -113,20 +120,19 @@
properties['hasExtUri'] = element.hasExtUri;
properties['hasLoadLibraryFunction'] = element.hasLoadLibraryFunction;
properties['isBrowserApplication'] = element.isBrowserApplication;
+ properties['isDartAsync'] = element.isDartAsync;
+ properties['isDartCore'] = element.isDartCore;
+ properties['isInSdk'] = element.isInSdk;
}
if (element is LocalElement) {
properties['visibleRange'] = element.visibleRange;
}
- if (element is MethodElement) {
- properties['isAbstract'] = element.isAbstract;
- }
if (element is ParameterElement) {
properties['defaultValueCode'] = element.defaultValueCode;
properties['isInitializingFormal'] = element.isInitializingFormal;
properties['parameterKind'] = element.parameterKind;
}
if (element is PropertyAccessorElement) {
- properties['isAbstract'] = element.isAbstract;
properties['isGetter'] = element.isGetter;
properties['isSetter'] = element.isSetter;
}
@@ -134,15 +140,24 @@
properties['isStatic'] = element.isStatic;
properties['propagatedType'] = element.propagatedType;
}
+ if (element is TypeDefiningElement) {
+ properties['type'] = element.type;
+ }
if (element is TypeParameterElement) {
properties['bound'] = element.bound;
}
+ if (element is TypeParameterizedElement) {
+ properties['typeParameters'] = element.typeParameters;
+ }
if (element is UriReferencedElement) {
properties['uri'] = element.uri;
}
if (element is VariableElement) {
+ properties['constantValue'] = element.constantValue;
+ properties['hasImplicitType'] = element.hasImplicitType;
properties['isConst'] = element.isConst;
properties['isFinal'] = element.isFinal;
+ properties['isStatic'] = element.isStatic;
properties['type'] = element.type;
}
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index fccb189..2983b7d 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -27,7 +27,9 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/embedder.dart';
import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/source/sdk_ext.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
import 'package:analyzer/src/context/source.dart';
@@ -35,6 +37,8 @@
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/sdk_io.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
@@ -1313,7 +1317,8 @@
buffer.write('</table></p>');
}
}
- void writeOptions(StringBuffer buffer, AnalysisOptionsImpl options) {
+ void writeOptions(StringBuffer buffer, AnalysisOptionsImpl options,
+ {void writeAdditionalOptions(StringBuffer buffer)}) {
if (options == null) {
buffer.write('<p>No option information available.</p>');
return;
@@ -1339,8 +1344,10 @@
options.incrementalApi);
_writeOption(buffer, 'Preserve comments', options.preserveComments);
_writeOption(buffer, 'Strong mode', options.strongMode);
- _writeOption(buffer, 'Strong mode hints', options.strongModeHints,
- last: true);
+ _writeOption(buffer, 'Strong mode hints', options.strongModeHints);
+ if (writeAdditionalOptions != null) {
+ writeAdditionalOptions(buffer);
+ }
buffer.write('</p>');
}
@@ -1357,8 +1364,13 @@
},
(StringBuffer buffer) {
buffer.write('<p><b>SDK Context Options</b></p>');
- writeOptions(buffer,
- context?.sourceFactory?.dartSdk?.context?.analysisOptions);
+ DartSdk sdk = context?.sourceFactory?.dartSdk;
+ writeOptions(buffer, sdk?.context?.analysisOptions,
+ writeAdditionalOptions: (StringBuffer buffer) {
+ if (sdk is DirectoryBasedDartSdk) {
+ _writeOption(buffer, 'Use summaries', sdk.useSummary);
+ }
+ });
},
(StringBuffer buffer) {
List<Linter> lints =
@@ -1388,6 +1400,25 @@
for (UriResolver resolver in sourceFactory.resolvers) {
buffer.write('<p>');
buffer.write(resolver.runtimeType);
+ if (resolver is DartUriResolver) {
+ DartSdk sdk = resolver.dartSdk;
+ buffer.write(' (sdk = ');
+ buffer.write(sdk.runtimeType);
+ if (sdk is DirectoryBasedDartSdk) {
+ buffer.write(' (path = ');
+ buffer.write(sdk.directory.getAbsolutePath());
+ buffer.write(')');
+ } else if (sdk is EmbedderSdk) {
+ buffer.write(' (map = ');
+ _writeMapOfStringToString(buffer, sdk.urlMappings);
+ buffer.write(')');
+ }
+ buffer.write(')');
+ } else if (resolver is SdkExtUriResolver) {
+ buffer.write(' (map = ');
+ _writeMapOfStringToString(buffer, resolver.urlMappings);
+ buffer.write(')');
+ }
buffer.write('</p>');
}
}
@@ -2075,6 +2106,27 @@
}
/**
+ * Write to the given [buffer] a representation of the given [map] of strings
+ * to strings.
+ */
+ void _writeMapOfStringToString(StringBuffer buffer, Map<String, String> map) {
+ List<String> keys = map.keys.toList();
+ keys.sort();
+ int length = keys.length;
+ buffer.write('{');
+ for (int i = 0; i < length; i++) {
+ String key = keys[i];
+ if (i > 0) {
+ buffer.write(', ');
+ }
+ buffer.write(key);
+ buffer.write(' = ');
+ buffer.write(map[key]);
+ }
+ buffer.write('}');
+ }
+
+ /**
* Write a representation of an analysis option with the given [name] and
* [value] to the given [buffer]. The option should be separated from other
* options unless the [last] flag is true, indicating that this is the last
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index c238d59..2fcb049 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -338,12 +338,12 @@
subscriptions[service] = <String>[bar.path].toSet();
}
server.setAnalysisSubscriptions(subscriptions);
- await pumpEventQueue(1000);
+ await server.onAnalysisComplete;
expect(server.statusAnalyzing, isFalse);
channel.notificationsReceived.clear();
server.updateContent(
'0', {bar.path: new AddContentOverlay('library bar; void f() {}')});
- await pumpEventQueue(1000);
+ await server.onAnalysisComplete;
expect(server.statusAnalyzing, isFalse);
expect(channel.notificationsReceived, isNotEmpty);
Set<String> notificationTypesReceived = new Set<String>();
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 04d3d0e..3d719e3 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -249,9 +249,6 @@
Future<Response> waitForResponse(Request request) {
String id = request.id;
- pumpEventQueue().then((_) {
- responseController.addError(new NoResponseException(request));
- });
return new Future<Response>(() =>
responseController.stream.firstWhere((response) => response.id == id));
}
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index e51ed5f..2081aab 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -371,6 +371,22 @@
pseudoKeywords: ['async', 'async*', 'sync*']);
}
+ test_anonymous_function_async6() async {
+ addTestSource('main() {foo("bar", () as^{}}');
+ await computeSuggestions();
+ assertSuggestKeywords([],
+ pseudoKeywords: ['async', 'async*', 'sync*'],
+ relevance: DART_RELEVANCE_HIGH);
+ }
+
+ test_anonymous_function_async7() async {
+ addTestSource('main() {foo("bar", () as^ => null');
+ await computeSuggestions();
+ assertSuggestKeywords([],
+ pseudoKeywords: ['async', 'async*', 'sync*'],
+ relevance: DART_RELEVANCE_HIGH);
+ }
+
test_argument() async {
addTestSource('main() {foo(^);}');
await computeSuggestions();
@@ -1179,6 +1195,12 @@
assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH);
}
+ test_is_expression_partial() async {
+ addTestSource('main() {if (x i^)}');
+ await computeSuggestions();
+ assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH);
+ }
+
test_library() async {
addTestSource('library foo;^');
await computeSuggestions();
@@ -1340,6 +1362,18 @@
assertSuggestKeywords(EXPRESSION_START_INSTANCE);
}
+ test_method_invocation() async {
+ addTestSource('class A { foo() {bar.^}}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
+ test_method_invocation2() async {
+ addTestSource('class A { foo() {bar.as^}}');
+ await computeSuggestions();
+ assertNoSuggestions();
+ }
+
test_method_param() async {
addTestSource('class A { foo(^) {});}');
await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/optype_test.dart b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
index 9a6982b6..eeada57 100644
--- a/pkg/analysis_server/test/services/completion/dart/optype_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
@@ -142,6 +142,16 @@
assertOpType(typeNames: true);
}
+ test_AsIdentifier() {
+ addTestSource('class A {var asdf; foo() {as^}');
+ assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+ }
+
+ test_AsIdentifier2() {
+ addTestSource('class A {var asdf; foo() {A as^}');
+ assertOpType();
+ }
+
test_Assert() {
addTestSource('main() {assert(^)}');
assertOpType(returnValue: true, typeNames: true);
@@ -1359,6 +1369,11 @@
assertOpType(returnValue: true, typeNames: true, voidReturn: true);
}
+ test_SwitchStatement_body_end2() {
+ addTestSource('main() {switch(k) {case 1:as^}}');
+ assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+ }
+
test_SwitchStatement_expression1() {
// SimpleIdentifier SwitchStatement Block
addTestSource('main() {switch(^k) {case 1:{}}}');
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index b67ce1a..4bf728d 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -287,7 +287,7 @@
}
}
''');
- FieldElement element = findElement('field');
+ FieldElement element = findElement('field', ElementKind.FIELD);
Element main = findElement('main');
Element fieldParameter = findElement('field', ElementKind.PARAMETER);
var expected = [
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index f02706f..07f8a30 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,6 +1,10 @@
-## 0.27.4-alpha.7.1
+## 0.27.4-alpha.9
* Restore EmbedderUriResolver API.
+## 0.27.4-alpha.8
+* Ignore processing performance improvements.
+* EmbedderUriResolver API updates.
+
## 0.27.4
* Added support for 'analysis_options.yaml' files as an alternative to '.analysis_options' files.
diff --git a/pkg/analyzer/doc/tasks.html b/pkg/analyzer/doc/tasks.html
index b8b2e568..10147f7 100644
--- a/pkg/analyzer/doc/tasks.html
+++ b/pkg/analyzer/doc/tasks.html
@@ -104,6 +104,8 @@
GenerateLintsTask -> LINTS
HINTS -> LibraryUnitErrorsTask
HINTS [shape=box]
+ IGNORE_INFO -> DartErrorsTask
+ IGNORE_INFO [shape=box]
IMPORTED_LIBRARIES -> BuildDirectiveElementsTask
IMPORTED_LIBRARIES -> ReadyLibraryElement2Task
IMPORTED_LIBRARIES -> ReadyLibraryElement5Task
@@ -194,7 +196,6 @@
MODIFICATION_TIME -> VerifyUnitTask
MODIFICATION_TIME [shape=box]
PARSED_UNIT -> BuildCompilationUnitElementTask
- PARSED_UNIT -> DartErrorsTask
PARSED_UNIT [shape=box]
PARSE_ERRORS -> dartErrorsForSource
PARSE_ERRORS [shape=box]
@@ -327,6 +328,7 @@
SOURCE_KIND [shape=box]
STRONG_MODE_ERRORS -> LibraryUnitErrorsTask
STRONG_MODE_ERRORS [shape=box]
+ ScanDartTask -> IGNORE_INFO
ScanDartTask -> LINE_INFO
ScanDartTask -> SCAN_ERRORS
ScanDartTask -> TOKEN_STREAM
diff --git a/pkg/analyzer/lib/source/sdk_ext.dart b/pkg/analyzer/lib/source/sdk_ext.dart
index f4bcdb9..3e833df 100644
--- a/pkg/analyzer/lib/source/sdk_ext.dart
+++ b/pkg/analyzer/lib/source/sdk_ext.dart
@@ -43,6 +43,13 @@
/// Number of sdk extensions.
int get length => _urlMappings.length;
+ /**
+ * Return a table mapping the names of extensions to the paths where those
+ * extensions can be found.
+ */
+ Map<String, String> get urlMappings =>
+ new Map<String, String>.from(_urlMappings);
+
/// Return the path mapping for [libName] or null if there is none.
String operator [](String libName) => _urlMappings[libName];
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 23cae4a..6ad3363 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -466,13 +466,19 @@
@override
TypeProvider get typeProvider {
+ // The `AnalysisContextTarget.request` results go into the SDK partition,
+ // and the TYPE_PROVIDER result is computed and put into the SDK partition
+ // only by the first non-SDK analysis context. So, in order to reuse it
+ // in other analysis contexts, we need to ask for it from the cache.
+ _typeProvider ??= getResult(AnalysisContextTarget.request, TYPE_PROVIDER);
+ if (_typeProvider != null) {
+ return _typeProvider;
+ }
+
// Make sure a task didn't accidentally try to call back into the context
// to retrieve the type provider.
assert(!driver.isTaskRunning);
- if (_typeProvider != null) {
- return _typeProvider;
- }
Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
if (coreSource == null) {
throw new AnalysisException("Could not create a source for dart:core");
@@ -726,8 +732,6 @@
ClassElementImpl element =
new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
element.supertype = objType;
- InterfaceTypeImpl type = new InterfaceTypeImpl(element);
- element.type = type;
if (parameterNames != null) {
int count = parameterNames.length;
if (count > 0) {
@@ -744,7 +748,6 @@
typeParameter.type = typeArguments[i];
}
element.typeParameters = typeParameters;
- type.typeArguments = typeArguments;
}
}
return element;
diff --git a/pkg/analyzer/lib/src/context/context_factory.dart b/pkg/analyzer/lib/src/context/context_factory.dart
new file mode 100644
index 0000000..b96100d
--- /dev/null
+++ b/pkg/analyzer/lib/src/context/context_factory.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.context_factory;
+
+import 'dart:convert';
+import 'dart:core' hide Resource;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:yaml/yaml.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'dart:io' as io;
+
+/// (Placeholder)
+abstract class ContextFactory {
+ /// Create an analysis context for the given [source] directory or file, with
+ /// the given [defaultOptions].
+ AnalysisContext createContext(
+ io.FileSystemEntity source, AnalysisOptions defaultOptions);
+}
+
+/// Processes package maps, extracting SDK embedders and extenders, creating a
+/// consolidated [libraryMap].
+class PackageMapProcessor {
+ static const String _EMBEDDED_LIB_MAP_KEY = 'embedded_libs';
+ static const String _EMBEDDER_FILE_NAME = '_embedder.yaml';
+ static const String _SDK_EXT_NAME = '_sdkext';
+
+ /// Map of processed embedder libraries.
+ final LibraryMap embeddedLibraries = new LibraryMap();
+
+ /// Map of processed SDK extension libraries.
+ final LibraryMap extendedLibraries = new LibraryMap();
+
+ /// Combined map of processed libraries.
+ LibraryMap get libraryMap {
+ LibraryMap libraryMap = new LibraryMap();
+
+ // Add extenders first, allowing for overwrite by embedders who take precedence.
+ for (String uri in extendedLibraries.uris) {
+ libraryMap.setLibrary(uri, extendedLibraries.getLibrary(uri));
+ }
+ for (String uri in embeddedLibraries.uris) {
+ libraryMap.setLibrary(uri, embeddedLibraries.getLibrary(uri));
+ }
+ return libraryMap;
+ }
+
+ /// Create a processor for the given [packageMap].
+ PackageMapProcessor(Map<String, List<Folder>> packageMap) {
+ packageMap?.forEach(_processPackage);
+ }
+
+ /// Whether the package map contains an SDK embedder.
+ bool get hasEmbedder => embeddedLibraries.size() > 0;
+
+ /// Whether the package map contains an SDK extension.
+ bool get hasSdkExtension => extendedLibraries.size() > 0;
+
+ void _processEmbedderYaml(String embedderYaml, Folder libDir) {
+ try {
+ YamlNode map = loadYaml(embedderYaml);
+ if (map is YamlMap) {
+ YamlNode embedded_libs = map[_EMBEDDED_LIB_MAP_KEY];
+ if (embedded_libs is YamlMap) {
+ embedded_libs.forEach(
+ (k, v) => _processMapping(embeddedLibraries, k, v, libDir));
+ }
+ }
+ } catch (_) {
+ // Ignored.
+ }
+ }
+
+ void _processMapping(
+ LibraryMap libraryMap, String name, String file, Folder libDir) {
+ if (!_hasDartPrefix(name)) {
+ // SDK libraries must begin with 'dart:'.
+ return;
+ }
+ if (libraryMap.getLibrary(name) != null) {
+ // Libraries can't be redefined.
+ return;
+ }
+ String libPath = libDir.canonicalizePath(file);
+ SdkLibraryImpl library = new SdkLibraryImpl(name)..path = libPath;
+ libraryMap.setLibrary(name, library);
+ }
+
+ void _processPackage(String name, List<Folder> libDirs) {
+ for (Folder libDir in libDirs) {
+ String embedderYaml = _readEmbedderYaml(libDir);
+ if (embedderYaml != null) {
+ _processEmbedderYaml(embedderYaml, libDir);
+ }
+ String sdkExt = _readDotSdkExt(libDir);
+ if (sdkExt != null) {
+ _processSdkExt(sdkExt, libDir);
+ }
+ }
+ }
+
+ void _processSdkExt(String sdkExtJSON, Folder libDir) {
+ try {
+ var sdkExt = JSON.decode(sdkExtJSON);
+ if (sdkExt is Map) {
+ sdkExt.forEach(
+ (k, v) => _processMapping(extendedLibraries, k, v, libDir));
+ }
+ } catch (_) {
+ // Ignored.
+ }
+ }
+
+ static bool _hasDartPrefix(String uri) =>
+ uri.startsWith(DartSdk.DART_LIBRARY_PREFIX);
+
+ static String _readDotSdkExt(Folder libDir) =>
+ _safeRead(libDir.getChild(_SDK_EXT_NAME));
+
+ static String _readEmbedderYaml(Folder libDir) =>
+ _safeRead(libDir.getChild(_EMBEDDER_FILE_NAME));
+
+ static String _safeRead(Resource file) {
+ try {
+ if (file is File) {
+ return file.readAsStringSync();
+ }
+ } on FileSystemException {
+ // File can't be read.
+ }
+ return null;
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 5e2b646..97defa6 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -392,6 +392,9 @@
..addAll(_arguments)
..add(rightParenthesis);
+ List<ParameterElement> get correspondingPropagatedParameters =>
+ _correspondingPropagatedParameters;
+
@override
void set correspondingPropagatedParameters(
List<ParameterElement> parameters) {
@@ -402,6 +405,9 @@
_correspondingPropagatedParameters = parameters;
}
+ List<ParameterElement> get correspondingStaticParameters =>
+ _correspondingStaticParameters;
+
@override
void set correspondingStaticParameters(List<ParameterElement> parameters) {
if (parameters.length != _arguments.length) {
@@ -9037,6 +9043,10 @@
return false;
}
}
+ if (parent is ConstructorFieldInitializer &&
+ identical(parent.fieldName, target)) {
+ return false;
+ }
if (parent is ForEachStatement) {
if (identical(parent.identifier, target)) {
return false;
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index fb59f7b..e531a68 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -421,12 +421,7 @@
ClassElementImpl element = new ClassElementImpl.forNode(className);
_setCodeRange(element, node);
element.metadata = _createElementAnnotations(node.metadata);
- List<TypeParameterElement> typeParameters = holder.typeParameters;
- List<DartType> typeArguments = _createTypeParameterTypes(typeParameters);
- InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
- interfaceType.typeArguments = typeArguments;
- element.type = interfaceType;
- element.typeParameters = typeParameters;
+ element.typeParameters = holder.typeParameters;
setElementDocumentationComment(element, node);
element.abstract = node.isAbstract;
element.accessors = holder.accessors;
@@ -473,12 +468,7 @@
element.metadata = _createElementAnnotations(node.metadata);
element.abstract = node.abstractKeyword != null;
element.mixinApplication = true;
- List<TypeParameterElement> typeParameters = holder.typeParameters;
- element.typeParameters = typeParameters;
- List<DartType> typeArguments = _createTypeParameterTypes(typeParameters);
- InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
- interfaceType.typeArguments = typeArguments;
- element.type = interfaceType;
+ element.typeParameters = holder.typeParameters;
setElementDocumentationComment(element, node);
_currentHolder.addType(element);
className.staticElement = element;
@@ -617,18 +607,11 @@
@override
Object visitEnumDeclaration(EnumDeclaration node) {
SimpleIdentifier enumName = node.name;
- ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName);
+ EnumElementImpl enumElement = new EnumElementImpl.forNode(enumName);
_setCodeRange(enumElement, node);
enumElement.metadata = _createElementAnnotations(node.metadata);
- enumElement.enum2 = true;
setElementDocumentationComment(enumElement, node);
- InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement);
- enumElement.type = enumType;
- // The equivalent code for enums in the spec shows a single constructor,
- // but that constructor is not callable (since it is a compile-time error
- // to subclass, mix-in, implement, or explicitly instantiate an enum). So
- // we represent this as having no constructors.
- enumElement.constructors = ConstructorElement.EMPTY_LIST;
+ InterfaceTypeImpl enumType = enumElement.type;
//
// Build the elements for the constants. These are minimal elements; the
// rest of the constant elements (and elements for other fields) must be
@@ -645,7 +628,7 @@
constantField.type = enumType;
setElementDocumentationComment(constantField, constant);
fields.add(constantField);
- _createGetter(constantField);
+ new PropertyAccessorElementImpl_ImplicitGetter(constantField);
constantName.staticElement = constantField;
}
enumElement.fields = fields;
@@ -1247,25 +1230,13 @@
holder.validate();
}
if (element is PropertyInducingElementImpl) {
- PropertyAccessorElementImpl getter =
- new PropertyAccessorElementImpl.forVariable(element);
- getter.getter = true;
- if (element.hasImplicitType) {
- getter.hasImplicitReturnType = true;
- }
+ PropertyAccessorElementImpl_ImplicitGetter getter =
+ new PropertyAccessorElementImpl_ImplicitGetter(element);
_currentHolder.addAccessor(getter);
- element.getter = getter;
if (!isConst && !isFinal) {
- PropertyAccessorElementImpl setter =
- new PropertyAccessorElementImpl.forVariable(element);
- setter.setter = true;
- ParameterElementImpl parameter =
- new ParameterElementImpl("_${element.name}", element.nameOffset);
- parameter.synthetic = true;
- parameter.parameterKind = ParameterKind.REQUIRED;
- setter.parameters = <ParameterElement>[parameter];
+ PropertyAccessorElementImpl_ImplicitSetter setter =
+ new PropertyAccessorElementImpl_ImplicitSetter(element);
_currentHolder.addAccessor(setter);
- element.setter = setter;
}
}
return null;
@@ -1318,9 +1289,7 @@
ConstructorElementImpl constructor =
new ConstructorElementImpl.forNode(null);
constructor.synthetic = true;
- constructor.returnType = definingClass.type;
constructor.enclosingElement = definingClass;
- constructor.type = new FunctionTypeImpl(constructor);
return <ConstructorElement>[constructor];
}
@@ -1342,18 +1311,6 @@
}
/**
- * Create a getter that corresponds to the given [field].
- */
- void _createGetter(FieldElementImpl field) {
- PropertyAccessorElementImpl getter =
- new PropertyAccessorElementImpl.forVariable(field);
- getter.getter = true;
- getter.returnType = field.type;
- getter.type = new FunctionTypeImpl(getter);
- field.getter = getter;
- }
-
- /**
* Create the types associated with the given type parameters, setting the type of each type
* parameter, and return an array of types corresponding to the given parameters.
*
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 5e72951..0eb96cf 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -14,6 +14,7 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/constant/value.dart';
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart' show EvaluationResultImpl;
@@ -25,6 +26,7 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
@@ -32,140 +34,43 @@
import 'package:analyzer/src/task/dart.dart';
/**
- * For AST nodes that could be in both the getter and setter contexts
- * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
- * elements are stored in the AST node, in an [AuxiliaryElements]. Because
- * resolved elements are either statically resolved or resolved using propagated
- * type information, this class is a wrapper for a pair of [ExecutableElement]s,
- * not just a single [ExecutableElement].
- */
-class AuxiliaryElements {
- /**
- * The element based on propagated type information, or `null` if the AST
- * structure has not been resolved or if the node could not be resolved.
- */
- final ExecutableElement propagatedElement;
-
- /**
- * The element based on static type information, or `null` if the AST
- * structure has not been resolved or if the node could not be resolved.
- */
- final ExecutableElement staticElement;
-
- /**
- * Initialize a newly created pair to have both the [staticElement] and the
- * [propagatedElement].
- */
- AuxiliaryElements(this.staticElement, this.propagatedElement);
-}
-
-/**
* A concrete implementation of a [ClassElement].
*/
-class ClassElementImpl extends ElementImpl
- with TypeParameterizedElementMixin
+abstract class AbstractClassElementImpl extends ElementImpl
implements ClassElement {
/**
- * The unlinked representation of the class in the summary.
- */
- final UnlinkedClass _unlinkedClass;
-
- /**
* A list containing all of the accessors (getters and setters) contained in
* this class.
*/
- List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
-
- /**
- * For classes which are not mixin applications, a list containing all of the
- * constructors contained in this class, or `null` if the list of
- * constructors has not yet been built.
- *
- * For classes which are mixin applications, the list of constructors is
- * computed on the fly by the [constructors] getter, and this field is
- * `null`.
- */
- List<ConstructorElement> _constructors;
+ List<PropertyAccessorElement> _accessors;
/**
* A list containing all of the fields contained in this class.
*/
- List<FieldElement> _fields = FieldElement.EMPTY_LIST;
-
- /**
- * A list containing all of the mixins that are applied to the class being
- * extended in order to derive the superclass of this class.
- */
- @override
- List<InterfaceType> mixins = InterfaceType.EMPTY_LIST;
-
- /**
- * A list containing all of the interfaces that are implemented by this class.
- */
- @override
- List<InterfaceType> interfaces = InterfaceType.EMPTY_LIST;
-
- /**
- * A list containing all of the methods contained in this class.
- */
- List<MethodElement> _methods = MethodElement.EMPTY_LIST;
-
- /**
- * The superclass of the class, or `null` if the class does not have an
- * explicit superclass.
- */
- @override
- InterfaceType supertype;
-
- /**
- * The type defined by the class.
- */
- @override
- InterfaceType type;
-
- /**
- * A list containing all of the type parameters defined for this class.
- */
- List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
-
- /**
- * A flag indicating whether the types associated with the instance members of
- * this class have been inferred.
- */
- bool hasBeenInferred = false;
+ List<FieldElement> _fields;
/**
* Initialize a newly created class element to have the given [name] at the
* given [offset] in the file that contains the declaration of this element.
*/
- ClassElementImpl(String name, int offset)
- : _unlinkedClass = null,
- super(name, offset);
+ AbstractClassElementImpl(String name, int offset) : super(name, offset);
/**
* Initialize a newly created class element to have the given [name].
*/
- ClassElementImpl.forNode(Identifier name)
- : _unlinkedClass = null,
- super.forNode(name);
+ AbstractClassElementImpl.forNode(Identifier name) : super.forNode(name);
/**
* Initialize using the given serialized information.
*/
- ClassElementImpl.forSerialized(
- this._unlinkedClass, CompilationUnitElementImpl enclosingUnit)
+ AbstractClassElementImpl.forSerialized(
+ CompilationUnitElementImpl enclosingUnit)
: super.forSerialized(enclosingUnit);
- /**
- * Set whether this class is abstract.
- */
- void set abstract(bool isAbstract) {
- assert(_unlinkedClass == null);
- setModifier(Modifier.ABSTRACT, isAbstract);
- }
-
@override
- List<PropertyAccessorElement> get accessors => _accessors;
+ List<PropertyAccessorElement> get accessors {
+ return _accessors ?? const <PropertyAccessorElement>[];
+ }
/**
* Set the accessors contained in this class to the given [accessors].
@@ -178,129 +83,10 @@
}
@override
- List<InterfaceType> get allSupertypes {
- List<InterfaceType> list = new List<InterfaceType>();
- _collectAllSupertypes(list);
- return list;
- }
-
- @override
- int get codeLength {
- if (_unlinkedClass != null) {
- return _unlinkedClass.codeRange?.length;
- }
- return super.codeLength;
- }
-
- @override
- int get codeOffset {
- if (_unlinkedClass != null) {
- return _unlinkedClass.codeRange?.offset;
- }
- return super.codeOffset;
- }
-
- @override
- List<ConstructorElement> get constructors {
- if (!isMixinApplication) {
- assert(_constructors != null);
- return _constructors ?? ConstructorElement.EMPTY_LIST;
- }
- return _computeMixinAppConstructors();
- }
-
- /**
- * Set the constructors contained in this class to the given [constructors].
- *
- * Should only be used for class elements that are not mixin applications.
- */
- void set constructors(List<ConstructorElement> constructors) {
- assert(!isMixinApplication);
- for (ConstructorElement constructor in constructors) {
- (constructor as ConstructorElementImpl).enclosingElement = this;
- }
- this._constructors = constructors;
- }
-
- @override
String get displayName => name;
@override
- SourceRange get docRange {
- if (_unlinkedClass != null) {
- UnlinkedDocumentationComment comment =
- _unlinkedClass.documentationComment;
- return comment != null
- ? new SourceRange(comment.offset, comment.length)
- : null;
- }
- return super.docRange;
- }
-
- @override
- String get documentationComment {
- if (_unlinkedClass != null) {
- return _unlinkedClass?.documentationComment?.text;
- }
- return super.documentationComment;
- }
-
- /**
- * Return `true` if [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] should
- * be reported for this class.
- */
- bool get doesMixinLackConstructors {
- if (!isMixinApplication && mixins.isEmpty) {
- // This class is not a mixin application and it doesn't have a "with"
- // clause, so CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS is
- // inapplicable.
- return false;
- }
- if (supertype == null) {
- // Should never happen, since Object is the only class that has no
- // supertype, and it should have been caught by the test above.
- assert(false);
- return false;
- }
- // Find the nearest class in the supertype chain that is not a mixin
- // application.
- ClassElement nearestNonMixinClass = supertype.element;
- if (nearestNonMixinClass.isMixinApplication) {
- // Use a list to keep track of the classes we've seen, so that we won't
- // go into an infinite loop in the event of a non-trivial loop in the
- // class hierarchy.
- List<ClassElement> classesSeen = <ClassElement>[this];
- while (nearestNonMixinClass.isMixinApplication) {
- if (classesSeen.contains(nearestNonMixinClass)) {
- // Loop in the class hierarchy (which is reported elsewhere). Don't
- // confuse the user with further errors.
- return false;
- }
- classesSeen.add(nearestNonMixinClass);
- if (nearestNonMixinClass.supertype == null) {
- // Should never happen, since Object is the only class that has no
- // supertype, and it is not a mixin application.
- assert(false);
- return false;
- }
- nearestNonMixinClass = nearestNonMixinClass.supertype.element;
- }
- }
- return !nearestNonMixinClass.constructors.any(isSuperConstructorAccessible);
- }
-
- @override
- TypeParameterizedElementMixin get enclosingTypeParameterContext => null;
-
- /**
- * Set whether this class is defined by an enum declaration.
- */
- void set enum2(bool isEnum) {
- setModifier(Modifier.ENUM, isEnum);
- }
-
- @override
- List<FieldElement> get fields => _fields;
+ List<FieldElement> get fields => _fields ?? const <FieldElement>[];
/**
* Set the fields contained in this class to the given [fields].
@@ -313,249 +99,15 @@
}
@override
- bool get hasNonFinalField {
- List<ClassElement> classesToVisit = new List<ClassElement>();
- HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
- classesToVisit.add(this);
- while (!classesToVisit.isEmpty) {
- ClassElement currentElement = classesToVisit.removeAt(0);
- if (visitedClasses.add(currentElement)) {
- // check fields
- for (FieldElement field in currentElement.fields) {
- if (!field.isFinal &&
- !field.isConst &&
- !field.isStatic &&
- !field.isSynthetic) {
- return true;
- }
- }
- // check mixins
- for (InterfaceType mixinType in currentElement.mixins) {
- ClassElement mixinElement = mixinType.element;
- classesToVisit.add(mixinElement);
- }
- // check super
- InterfaceType supertype = currentElement.supertype;
- if (supertype != null) {
- ClassElement superElement = supertype.element;
- if (superElement != null) {
- classesToVisit.add(superElement);
- }
- }
- }
- }
- // not found
- return false;
- }
-
- @override
- bool get hasReferenceToSuper => hasModifier(Modifier.REFERENCES_SUPER);
-
- /**
- * Set whether this class references 'super'.
- */
- void set hasReferenceToSuper(bool isReferencedSuper) {
- setModifier(Modifier.REFERENCES_SUPER, isReferencedSuper);
- }
-
- @override
- bool get hasStaticMember {
- for (MethodElement method in _methods) {
- if (method.isStatic) {
- return true;
- }
- }
- for (PropertyAccessorElement accessor in _accessors) {
- if (accessor.isStatic) {
- return true;
- }
- }
- return false;
- }
-
- @override
- bool get isAbstract {
- if (_unlinkedClass != null) {
- return _unlinkedClass.isAbstract;
- }
- return hasModifier(Modifier.ABSTRACT);
- }
-
- @override
- bool get isEnum => hasModifier(Modifier.ENUM);
-
- @override
- bool get isMixinApplication {
- if (_unlinkedClass != null) {
- return _unlinkedClass.isMixinApplication;
- }
- return hasModifier(Modifier.MIXIN_APPLICATION);
- }
-
- @override
- bool get isOrInheritsProxy =>
- _safeIsOrInheritsProxy(this, new HashSet<ClassElement>());
-
- @override
- bool get isProxy {
- for (ElementAnnotation annotation in metadata) {
- if (annotation.isProxy) {
- return true;
- }
- }
- return false;
- }
-
- @override
- bool get isValidMixin {
- if (!context.analysisOptions.enableSuperMixins) {
- if (hasReferenceToSuper) {
- return false;
- }
- if (!supertype.isObject) {
- return false;
- }
- }
- for (ConstructorElement constructor in constructors) {
- if (!constructor.isSynthetic && !constructor.isFactory) {
- return false;
- }
- }
- return true;
- }
+ bool get isEnum;
@override
ElementKind get kind => ElementKind.CLASS;
@override
- List<ElementAnnotation> get metadata {
- if (_unlinkedClass != null) {
- return _metadata ??=
- _buildAnnotations(enclosingUnit, _unlinkedClass.annotations);
- }
- return super.metadata;
- }
-
- @override
- List<MethodElement> get methods => _methods;
-
- /**
- * Set the methods contained in this class to the given [methods].
- */
- void set methods(List<MethodElement> methods) {
- for (MethodElement method in methods) {
- (method as MethodElementImpl).enclosingElement = this;
- }
- this._methods = methods;
- }
-
- /**
- * Set whether this class is a mixin application.
- */
- void set mixinApplication(bool isMixinApplication) {
- assert(_unlinkedClass == null);
- setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
- }
-
- @override
- String get name {
- if (_unlinkedClass != null) {
- return _unlinkedClass.name;
- }
- return super.name;
- }
-
- @override
- int get nameOffset {
- if (_unlinkedClass != null) {
- return _unlinkedClass.nameOffset;
- }
- return super.nameOffset;
- }
-
- @override
- TypeParameterizedElementMixin get typeParameterContext => this;
-
- @override
- List<TypeParameterElement> get typeParameters {
- if (_unlinkedClass != null) {
- return super.typeParameters;
- }
- return _typeParameters;
- }
-
- /**
- * Set the type parameters defined for this class to the given
- * [typeParameters].
- */
- void set typeParameters(List<TypeParameterElement> typeParameters) {
- assert(_unlinkedClass == null);
- for (TypeParameterElement typeParameter in typeParameters) {
- (typeParameter as TypeParameterElementImpl).enclosingElement = this;
- }
- this._typeParameters = typeParameters;
- }
-
- @override
- List<UnlinkedTypeParam> get unlinkedTypeParams =>
- _unlinkedClass.typeParameters;
-
- @override
- ConstructorElement get unnamedConstructor {
- for (ConstructorElement element in constructors) {
- String name = element.displayName;
- if (name == null || name.isEmpty) {
- return element;
- }
- }
- return null;
- }
-
- @override
accept(ElementVisitor visitor) => visitor.visitClassElement(this);
@override
- void appendTo(StringBuffer buffer) {
- if (isAbstract) {
- buffer.write('abstract ');
- }
- if (isEnum) {
- buffer.write('enum ');
- } else {
- buffer.write('class ');
- }
- String name = displayName;
- if (name == null) {
- buffer.write("{unnamed class}");
- } else {
- buffer.write(name);
- }
- int variableCount = _typeParameters.length;
- if (variableCount > 0) {
- buffer.write("<");
- for (int i = 0; i < variableCount; i++) {
- if (i > 0) {
- buffer.write(", ");
- }
- (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
- }
- buffer.write(">");
- }
- if (supertype != null && !supertype.isObject) {
- buffer.write(' extends ');
- buffer.write(supertype.displayName);
- }
- if (mixins.isNotEmpty) {
- buffer.write(' with ');
- buffer.write(mixins.map((t) => t.displayName).join(', '));
- }
- if (interfaces.isNotEmpty) {
- buffer.write(' implements ');
- buffer.write(interfaces.map((t) => t.displayName).join(', '));
- }
- }
-
- @override
NamedCompilationUnitMember computeNode() {
if (isEnum) {
return getNodeMatching((node) => node is EnumDeclaration);
@@ -572,42 +124,24 @@
// thrown a CCE if any of the elements in the arrays were not of the
// expected types.
//
- for (PropertyAccessorElement accessor in _accessors) {
+ for (PropertyAccessorElement accessor in accessors) {
PropertyAccessorElementImpl accessorImpl = accessor;
if (accessorImpl.identifier == identifier) {
return accessorImpl;
}
}
- for (ConstructorElement constructor in _constructors) {
- ConstructorElementImpl constructorImpl = constructor;
- if (constructorImpl.identifier == identifier) {
- return constructorImpl;
- }
- }
- for (FieldElement field in _fields) {
+ for (FieldElement field in fields) {
FieldElementImpl fieldImpl = field;
if (fieldImpl.identifier == identifier) {
return fieldImpl;
}
}
- for (MethodElement method in _methods) {
- MethodElementImpl methodImpl = method;
- if (methodImpl.identifier == identifier) {
- return methodImpl;
- }
- }
- for (TypeParameterElement typeParameter in _typeParameters) {
- TypeParameterElementImpl typeParameterImpl = typeParameter;
- if (typeParameterImpl.identifier == identifier) {
- return typeParameterImpl;
- }
- }
return null;
}
@override
FieldElement getField(String name) {
- for (FieldElement fieldElement in _fields) {
+ for (FieldElement fieldElement in fields) {
if (name == fieldElement.name) {
return fieldElement;
}
@@ -617,9 +151,9 @@
@override
PropertyAccessorElement getGetter(String getterName) {
- int length = _accessors.length;
+ int length = accessors.length;
for (int i = 0; i < length; i++) {
- PropertyAccessorElement accessor = _accessors[i];
+ PropertyAccessorElement accessor = accessors[i];
if (accessor.isGetter && accessor.name == getterName) {
return accessor;
}
@@ -628,29 +162,6 @@
}
@override
- MethodElement getMethod(String methodName) {
- int length = _methods.length;
- for (int i = 0; i < length; i++) {
- MethodElement method = _methods[i];
- if (method.name == methodName) {
- return method;
- }
- }
- return null;
- }
-
- @override
- ConstructorElement getNamedConstructor(String name) {
- for (ConstructorElement element in constructors) {
- String elementName = element.name;
- if (elementName != null && elementName == name) {
- return element;
- }
- }
- return null;
- }
-
- @override
PropertyAccessorElement getSetter(String setterName) {
// TODO (jwren) revisit- should we append '=' here or require clients to
// include it?
@@ -658,7 +169,7 @@
if (!StringUtilities.endsWithChar(setterName, 0x3D)) {
setterName += '=';
}
- for (PropertyAccessorElement accessor in _accessors) {
+ for (PropertyAccessorElement accessor in accessors) {
if (accessor.isSetter && accessor.name == setterName) {
return accessor;
}
@@ -667,23 +178,6 @@
}
@override
- bool isSuperConstructorAccessible(ConstructorElement constructor) {
- // If this class has no mixins, then all superclass constructors are
- // accessible.
- if (mixins.isEmpty) {
- return true;
- }
- // Otherwise only constructors that lack optional parameters are
- // accessible (see dartbug.com/19576).
- for (ParameterElement parameter in constructor.parameters) {
- if (parameter.parameterKind != ParameterKind.REQUIRED) {
- return false;
- }
- }
- return true;
- }
-
- @override
MethodElement lookUpConcreteMethod(
String methodName, LibraryElement library) =>
_internalLookUpConcreteMethod(
@@ -729,132 +223,8 @@
@override
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
- safelyVisitChildren(_accessors, visitor);
- safelyVisitChildren(_constructors, visitor);
- safelyVisitChildren(_fields, visitor);
- safelyVisitChildren(_methods, visitor);
- safelyVisitChildren(_typeParameters, visitor);
- }
-
- void _collectAllSupertypes(List<InterfaceType> supertypes) {
- List<InterfaceType> typesToVisit = new List<InterfaceType>();
- List<ClassElement> visitedClasses = new List<ClassElement>();
- typesToVisit.add(this.type);
- while (!typesToVisit.isEmpty) {
- InterfaceType currentType = typesToVisit.removeAt(0);
- ClassElement currentElement = currentType.element;
- if (!visitedClasses.contains(currentElement)) {
- visitedClasses.add(currentElement);
- if (!identical(currentType, this.type)) {
- supertypes.add(currentType);
- }
- InterfaceType supertype = currentType.superclass;
- if (supertype != null) {
- typesToVisit.add(supertype);
- }
- for (InterfaceType type in currentElement.interfaces) {
- typesToVisit.add(type);
- }
- for (InterfaceType type in currentElement.mixins) {
- ClassElement element = type.element;
- if (!visitedClasses.contains(element)) {
- supertypes.add(type);
- }
- }
- }
- }
- }
-
- /**
- * Compute a list of constructors for this class, which is a mixin
- * application. If specified, [visitedClasses] is a list of the other mixin
- * application classes which have been visited on the way to reaching this
- * one (this is used to detect circularities).
- */
- List<ConstructorElement> _computeMixinAppConstructors(
- [List<ClassElementImpl> visitedClasses = null]) {
- // First get the list of constructors of the superclass which need to be
- // forwarded to this class.
- Iterable<ConstructorElement> constructorsToForward;
- if (supertype == null) {
- // Shouldn't ever happen, since the only class with no supertype is
- // Object, and it isn't a mixin application. But for safety's sake just
- // assume an empty list.
- assert(false);
- constructorsToForward = <ConstructorElement>[];
- } else if (!supertype.element.isMixinApplication) {
- List<ConstructorElement> superclassConstructors =
- supertype.element.constructors;
- // Filter out any constructors with optional parameters (see
- // dartbug.com/15101).
- constructorsToForward =
- superclassConstructors.where(isSuperConstructorAccessible);
- } else {
- if (visitedClasses == null) {
- visitedClasses = <ClassElementImpl>[this];
- } else {
- if (visitedClasses.contains(this)) {
- // Loop in the class hierarchy. Don't try to forward any
- // constructors.
- return <ConstructorElement>[];
- }
- visitedClasses.add(this);
- }
- try {
- constructorsToForward = getImpl(supertype.element)
- ._computeMixinAppConstructors(visitedClasses);
- } finally {
- visitedClasses.removeLast();
- }
- }
-
- // Figure out the type parameter substitution we need to perform in order
- // to produce constructors for this class. We want to be robust in the
- // face of errors, so drop any extra type arguments and fill in any missing
- // ones with `dynamic`.
- List<DartType> parameterTypes =
- TypeParameterTypeImpl.getTypes(supertype.typeParameters);
- List<DartType> argumentTypes = new List<DartType>.filled(
- parameterTypes.length, DynamicTypeImpl.instance);
- for (int i = 0; i < supertype.typeArguments.length; i++) {
- if (i >= argumentTypes.length) {
- break;
- }
- argumentTypes[i] = supertype.typeArguments[i];
- }
-
- // Now create an implicit constructor for every constructor found above,
- // substituting type parameters as appropriate.
- return constructorsToForward
- .map((ConstructorElement superclassConstructor) {
- ConstructorElementImpl implicitConstructor =
- new ConstructorElementImpl(superclassConstructor.name, -1);
- implicitConstructor.synthetic = true;
- implicitConstructor.redirectedConstructor = superclassConstructor;
- implicitConstructor.returnType = type;
- List<ParameterElement> superParameters = superclassConstructor.parameters;
- int count = superParameters.length;
- if (count > 0) {
- List<ParameterElement> implicitParameters =
- new List<ParameterElement>(count);
- for (int i = 0; i < count; i++) {
- ParameterElement superParameter = superParameters[i];
- ParameterElementImpl implicitParameter =
- new ParameterElementImpl(superParameter.name, -1);
- implicitParameter.const3 = superParameter.isConst;
- implicitParameter.final2 = superParameter.isFinal;
- implicitParameter.parameterKind = superParameter.parameterKind;
- implicitParameter.synthetic = true;
- implicitParameter.type =
- superParameter.type.substitute2(argumentTypes, parameterTypes);
- implicitParameters[i] = implicitParameter;
- }
- implicitConstructor.parameters = implicitParameters;
- }
- implicitConstructor.enclosingElement = this;
- implicitConstructor.type = new FunctionTypeImpl(implicitConstructor);
- return implicitConstructor;
- }).toList();
+ safelyVisitChildren(accessors, visitor);
+ safelyVisitChildren(fields, visitor);
}
PropertyAccessorElement _internalLookUpConcreteGetter(
@@ -1004,6 +374,875 @@
return null;
}
+ /**
+ * Return the [AbstractClassElementImpl] of the given [classElement]. May
+ * throw an exception if the [AbstractClassElementImpl] cannot be provided
+ * (should not happen though).
+ */
+ static AbstractClassElementImpl getImpl(ClassElement classElement) {
+ if (classElement is ClassElementHandle) {
+ return getImpl(classElement.actualElement);
+ }
+ return classElement as AbstractClassElementImpl;
+ }
+}
+
+/**
+ * For AST nodes that could be in both the getter and setter contexts
+ * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
+ * elements are stored in the AST node, in an [AuxiliaryElements]. Because
+ * resolved elements are either statically resolved or resolved using propagated
+ * type information, this class is a wrapper for a pair of [ExecutableElement]s,
+ * not just a single [ExecutableElement].
+ */
+class AuxiliaryElements {
+ /**
+ * The element based on propagated type information, or `null` if the AST
+ * structure has not been resolved or if the node could not be resolved.
+ */
+ final ExecutableElement propagatedElement;
+
+ /**
+ * The element based on static type information, or `null` if the AST
+ * structure has not been resolved or if the node could not be resolved.
+ */
+ final ExecutableElement staticElement;
+
+ /**
+ * Initialize a newly created pair to have both the [staticElement] and the
+ * [propagatedElement].
+ */
+ AuxiliaryElements(this.staticElement, this.propagatedElement);
+}
+
+/**
+ * An [AbstractClassElementImpl] which is a class.
+ */
+class ClassElementImpl extends AbstractClassElementImpl
+ with TypeParameterizedElementMixin {
+ /**
+ * The unlinked representation of the class in the summary.
+ */
+ final UnlinkedClass _unlinkedClass;
+
+ /**
+ * A list containing all of the type parameters defined for this class.
+ */
+ List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
+
+ /**
+ * The superclass of the class, or `null` for [Object].
+ */
+ InterfaceType _supertype;
+
+ /**
+ * The type defined by the class.
+ */
+ InterfaceType _type;
+
+ /**
+ * A list containing all of the mixins that are applied to the class being
+ * extended in order to derive the superclass of this class.
+ */
+ List<InterfaceType> _mixins;
+
+ /**
+ * A list containing all of the interfaces that are implemented by this class.
+ */
+ List<InterfaceType> _interfaces;
+
+ /**
+ * For classes which are not mixin applications, a list containing all of the
+ * constructors contained in this class, or `null` if the list of
+ * constructors has not yet been built.
+ *
+ * For classes which are mixin applications, the list of constructors is
+ * computed on the fly by the [constructors] getter, and this field is
+ * `null`.
+ */
+ List<ConstructorElement> _constructors;
+
+ /**
+ * A list containing all of the methods contained in this class.
+ */
+ List<MethodElement> _methods;
+
+ /**
+ * A flag indicating whether the types associated with the instance members of
+ * this class have been inferred.
+ */
+ bool _hasBeenInferred = false;
+
+ /**
+ * Initialize a newly created class element to have the given [name] at the
+ * given [offset] in the file that contains the declaration of this element.
+ */
+ ClassElementImpl(String name, int offset)
+ : _unlinkedClass = null,
+ super(name, offset);
+
+ /**
+ * Initialize a newly created class element to have the given [name].
+ */
+ ClassElementImpl.forNode(Identifier name)
+ : _unlinkedClass = null,
+ super.forNode(name);
+
+ /**
+ * Initialize using the given serialized information.
+ */
+ ClassElementImpl.forSerialized(
+ this._unlinkedClass, CompilationUnitElementImpl enclosingUnit)
+ : super.forSerialized(enclosingUnit);
+
+ /**
+ * Set whether this class is abstract.
+ */
+ void set abstract(bool isAbstract) {
+ assert(_unlinkedClass == null);
+ setModifier(Modifier.ABSTRACT, isAbstract);
+ }
+
+ @override
+ List<PropertyAccessorElement> get accessors {
+ if (_unlinkedClass != null && _accessors == null) {
+ _resynthesizeFieldsAndPropertyAccessors();
+ }
+ return _accessors ?? const <PropertyAccessorElement>[];
+ }
+
+ @override
+ void set accessors(List<PropertyAccessorElement> accessors) {
+ assert(_unlinkedClass == null);
+ super.accessors = accessors;
+ }
+
+ @override
+ List<InterfaceType> get allSupertypes {
+ List<InterfaceType> list = new List<InterfaceType>();
+ _collectAllSupertypes(list);
+ return list;
+ }
+
+ @override
+ int get codeLength {
+ if (_unlinkedClass != null) {
+ return _unlinkedClass.codeRange?.length;
+ }
+ return super.codeLength;
+ }
+
+ @override
+ int get codeOffset {
+ if (_unlinkedClass != null) {
+ return _unlinkedClass.codeRange?.offset;
+ }
+ return super.codeOffset;
+ }
+
+ @override
+ List<ConstructorElement> get constructors {
+ if (isMixinApplication) {
+ return _computeMixinAppConstructors();
+ }
+ if (_unlinkedClass != null && _constructors == null) {
+ _constructors = _unlinkedClass.executables
+ .where((e) => e.kind == UnlinkedExecutableKind.constructor)
+ .map((e) => new ConstructorElementImpl.forSerialized(e, this))
+ .toList(growable: false);
+ // Ensure at least implicit default constructor.
+ if (_constructors.isEmpty) {
+ ConstructorElementImpl constructor = new ConstructorElementImpl('', -1);
+ constructor.synthetic = true;
+ constructor.enclosingElement = this;
+ _constructors = <ConstructorElement>[constructor];
+ }
+ }
+ assert(_constructors != null);
+ return _constructors ?? const <ConstructorElement>[];
+ }
+
+ /**
+ * Set the constructors contained in this class to the given [constructors].
+ *
+ * Should only be used for class elements that are not mixin applications.
+ */
+ void set constructors(List<ConstructorElement> constructors) {
+ assert(_unlinkedClass == null);
+ assert(!isMixinApplication);
+ for (ConstructorElement constructor in constructors) {
+ (constructor as ConstructorElementImpl).enclosingElement = this;
+ }
+ this._constructors = constructors;
+ }
+
+ @override
+ SourceRange get docRange {
+ if (_unlinkedClass != null) {
+ UnlinkedDocumentationComment comment =
+ _unlinkedClass.documentationComment;
+ return comment != null
+ ? new SourceRange(comment.offset, comment.length)
+ : null;
+ }
+ return super.docRange;
+ }
+
+ @override
+ String get documentationComment {
+ if (_unlinkedClass != null) {
+ return _unlinkedClass?.documentationComment?.text;
+ }
+ return super.documentationComment;
+ }
+
+ /**
+ * Return `true` if [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] should
+ * be reported for this class.
+ */
+ bool get doesMixinLackConstructors {
+ if (!isMixinApplication && mixins.isEmpty) {
+ // This class is not a mixin application and it doesn't have a "with"
+ // clause, so CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS is
+ // inapplicable.
+ return false;
+ }
+ if (supertype == null) {
+ // Should never happen, since Object is the only class that has no
+ // supertype, and it should have been caught by the test above.
+ assert(false);
+ return false;
+ }
+ // Find the nearest class in the supertype chain that is not a mixin
+ // application.
+ ClassElement nearestNonMixinClass = supertype.element;
+ if (nearestNonMixinClass.isMixinApplication) {
+ // Use a list to keep track of the classes we've seen, so that we won't
+ // go into an infinite loop in the event of a non-trivial loop in the
+ // class hierarchy.
+ List<ClassElement> classesSeen = <ClassElement>[this];
+ while (nearestNonMixinClass.isMixinApplication) {
+ if (classesSeen.contains(nearestNonMixinClass)) {
+ // Loop in the class hierarchy (which is reported elsewhere). Don't
+ // confuse the user with further errors.
+ return false;
+ }
+ classesSeen.add(nearestNonMixinClass);
+ if (nearestNonMixinClass.supertype == null) {
+ // Should never happen, since Object is the only class that has no
+ // supertype, and it is not a mixin application.
+ assert(false);
+ return false;
+ }
+ nearestNonMixinClass = nearestNonMixinClass.supertype.element;
+ }
+ }
+ return !nearestNonMixinClass.constructors.any(isSuperConstructorAccessible);
+ }
+
+ @override
+ TypeParameterizedElementMixin get enclosingTypeParameterContext => null;
+
+ @override
+ List<FieldElement> get fields {
+ if (_unlinkedClass != null && _fields == null) {
+ _resynthesizeFieldsAndPropertyAccessors();
+ }
+ return _fields ?? const <FieldElement>[];
+ }
+
+ @override
+ void set fields(List<FieldElement> fields) {
+ assert(_unlinkedClass == null);
+ super.fields = fields;
+ }
+
+ bool get hasBeenInferred {
+ if (_unlinkedClass != null) {
+ return context.analysisOptions.strongMode;
+ }
+ return _hasBeenInferred;
+ }
+
+ void set hasBeenInferred(bool hasBeenInferred) {
+ assert(_unlinkedClass == null);
+ _hasBeenInferred = hasBeenInferred;
+ }
+
+ @override
+ bool get hasNonFinalField {
+ List<ClassElement> classesToVisit = new List<ClassElement>();
+ HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+ classesToVisit.add(this);
+ while (!classesToVisit.isEmpty) {
+ ClassElement currentElement = classesToVisit.removeAt(0);
+ if (visitedClasses.add(currentElement)) {
+ // check fields
+ for (FieldElement field in currentElement.fields) {
+ if (!field.isFinal &&
+ !field.isConst &&
+ !field.isStatic &&
+ !field.isSynthetic) {
+ return true;
+ }
+ }
+ // check mixins
+ for (InterfaceType mixinType in currentElement.mixins) {
+ ClassElement mixinElement = mixinType.element;
+ classesToVisit.add(mixinElement);
+ }
+ // check super
+ InterfaceType supertype = currentElement.supertype;
+ if (supertype != null) {
+ ClassElement superElement = supertype.element;
+ if (superElement != null) {
+ classesToVisit.add(superElement);
+ }
+ }
+ }
+ }
+ // not found
+ return false;
+ }
+
+ @override
+ bool get hasReferenceToSuper => hasModifier(Modifier.REFERENCES_SUPER);
+
+ /**
+ * Set whether this class references 'super'.
+ */
+ void set hasReferenceToSuper(bool isReferencedSuper) {
+ setModifier(Modifier.REFERENCES_SUPER, isReferencedSuper);
+ }
+
+ @override
+ bool get hasStaticMember {
+ for (MethodElement method in methods) {
+ if (method.isStatic) {
+ return true;
+ }
+ }
+ for (PropertyAccessorElement accessor in accessors) {
+ if (accessor.isStatic) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @override
+ List<InterfaceType> get interfaces {
+ if (_unlinkedClass != null && _interfaces == null) {
+ ResynthesizerContext context = enclosingUnit.resynthesizerContext;
+ _interfaces = _unlinkedClass.interfaces
+ .map((EntityRef t) => context.resolveTypeRef(t, this))
+ .toList(growable: false);
+ }
+ return _interfaces ?? const <InterfaceType>[];
+ }
+
+ void set interfaces(List<InterfaceType> interfaces) {
+ assert(_unlinkedClass == null);
+ _interfaces = interfaces;
+ }
+
+ @override
+ bool get isAbstract {
+ if (_unlinkedClass != null) {
+ return _unlinkedClass.isAbstract;
+ }
+ return hasModifier(Modifier.ABSTRACT);
+ }
+
+ @override
+ bool get isEnum => false;
+
+ @override
+ bool get isMixinApplication {
+ if (_unlinkedClass != null) {
+ return _unlinkedClass.isMixinApplication;
+ }
+ return hasModifier(Modifier.MIXIN_APPLICATION);
+ }
+
+ @override
+ bool get isOrInheritsProxy =>
+ _safeIsOrInheritsProxy(this, new HashSet<ClassElement>());
+
+ @override
+ bool get isProxy {
+ for (ElementAnnotation annotation in metadata) {
+ if (annotation.isProxy) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @override
+ bool get isValidMixin {
+ if (!context.analysisOptions.enableSuperMixins) {
+ if (hasReferenceToSuper) {
+ return false;
+ }
+ if (!supertype.isObject) {
+ return false;
+ }
+ }
+ for (ConstructorElement constructor in constructors) {
+ if (!constructor.isSynthetic && !constructor.isFactory) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @override
+ List<ElementAnnotation> get metadata {
+ if (_unlinkedClass != null) {
+ return _metadata ??=
+ _buildAnnotations(enclosingUnit, _unlinkedClass.annotations);
+ }
+ return super.metadata;
+ }
+
+ @override
+ List<MethodElement> get methods {
+ if (_unlinkedClass != null) {
+ _methods ??= _unlinkedClass.executables
+ .where((e) => e.kind == UnlinkedExecutableKind.functionOrMethod)
+ .map((e) => new MethodElementImpl.forSerialized(e, this))
+ .toList(growable: false);
+ }
+ return _methods ?? const <MethodElement>[];
+ }
+
+ /**
+ * Set the methods contained in this class to the given [methods].
+ */
+ void set methods(List<MethodElement> methods) {
+ assert(_unlinkedClass == null);
+ for (MethodElement method in methods) {
+ (method as MethodElementImpl).enclosingElement = this;
+ }
+ _methods = methods;
+ }
+
+ /**
+ * Set whether this class is a mixin application.
+ */
+ void set mixinApplication(bool isMixinApplication) {
+ assert(_unlinkedClass == null);
+ setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
+ }
+
+ @override
+ List<InterfaceType> get mixins {
+ if (_unlinkedClass != null && _mixins == null) {
+ ResynthesizerContext context = enclosingUnit.resynthesizerContext;
+ _mixins = _unlinkedClass.mixins
+ .map((EntityRef t) => context.resolveTypeRef(t, this))
+ .toList(growable: false);
+ }
+ return _mixins ?? const <InterfaceType>[];
+ }
+
+ void set mixins(List<InterfaceType> mixins) {
+ assert(_unlinkedClass == null);
+ _mixins = mixins;
+ }
+
+ @override
+ String get name {
+ if (_unlinkedClass != null) {
+ return _unlinkedClass.name;
+ }
+ return super.name;
+ }
+
+ @override
+ int get nameOffset {
+ if (_unlinkedClass != null) {
+ return _unlinkedClass.nameOffset;
+ }
+ return super.nameOffset;
+ }
+
+ @override
+ InterfaceType get supertype {
+ if (_unlinkedClass != null && _supertype == null) {
+ if (_unlinkedClass.supertype != null) {
+ _supertype = enclosingUnit.resynthesizerContext
+ .resolveTypeRef(_unlinkedClass.supertype, this);
+ } else if (_unlinkedClass.hasNoSupertype) {
+ return null;
+ } else {
+ _supertype = context.typeProvider.objectType;
+ }
+ }
+ return _supertype;
+ }
+
+ void set supertype(InterfaceType supertype) {
+ assert(_unlinkedClass == null);
+ _supertype = supertype;
+ }
+
+ @override
+ InterfaceType get type {
+ if (_type == null) {
+ InterfaceTypeImpl type = new InterfaceTypeImpl(this);
+ type.typeArguments = typeParameterTypes;
+ _type = type;
+ }
+ return _type;
+ }
+
+ @override
+ TypeParameterizedElementMixin get typeParameterContext => this;
+
+ @override
+ List<TypeParameterElement> get typeParameters {
+ if (_unlinkedClass != null) {
+ return super.typeParameters;
+ }
+ return _typeParameters;
+ }
+
+ /**
+ * Set the type parameters defined for this class to the given
+ * [typeParameters].
+ */
+ void set typeParameters(List<TypeParameterElement> typeParameters) {
+ assert(_unlinkedClass == null);
+ for (TypeParameterElement typeParameter in typeParameters) {
+ (typeParameter as TypeParameterElementImpl).enclosingElement = this;
+ }
+ this._typeParameters = typeParameters;
+ }
+
+ @override
+ List<UnlinkedTypeParam> get unlinkedTypeParams =>
+ _unlinkedClass.typeParameters;
+
+ @override
+ ConstructorElement get unnamedConstructor {
+ for (ConstructorElement element in constructors) {
+ String name = element.displayName;
+ if (name == null || name.isEmpty) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ @override
+ void appendTo(StringBuffer buffer) {
+ if (isAbstract) {
+ buffer.write('abstract ');
+ }
+ buffer.write('class ');
+ String name = displayName;
+ if (name == null) {
+ buffer.write("{unnamed class}");
+ } else {
+ buffer.write(name);
+ }
+ int variableCount = typeParameters.length;
+ if (variableCount > 0) {
+ buffer.write("<");
+ for (int i = 0; i < variableCount; i++) {
+ if (i > 0) {
+ buffer.write(", ");
+ }
+ (typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
+ }
+ buffer.write(">");
+ }
+ if (supertype != null && !supertype.isObject) {
+ buffer.write(' extends ');
+ buffer.write(supertype.displayName);
+ }
+ if (mixins.isNotEmpty) {
+ buffer.write(' with ');
+ buffer.write(mixins.map((t) => t.displayName).join(', '));
+ }
+ if (interfaces.isNotEmpty) {
+ buffer.write(' implements ');
+ buffer.write(interfaces.map((t) => t.displayName).join(', '));
+ }
+ }
+
+ @override
+ ElementImpl getChild(String identifier) {
+ ElementImpl child = super.getChild(identifier);
+ if (child != null) {
+ return child;
+ }
+ //
+ // The casts in this method are safe because the set methods would have
+ // thrown a CCE if any of the elements in the arrays were not of the
+ // expected types.
+ //
+ for (ConstructorElement constructor in _constructors) {
+ ConstructorElementImpl constructorImpl = constructor;
+ if (constructorImpl.identifier == identifier) {
+ return constructorImpl;
+ }
+ }
+ for (MethodElement method in methods) {
+ MethodElementImpl methodImpl = method;
+ if (methodImpl.identifier == identifier) {
+ return methodImpl;
+ }
+ }
+ for (TypeParameterElement typeParameter in typeParameters) {
+ TypeParameterElementImpl typeParameterImpl = typeParameter;
+ if (typeParameterImpl.identifier == identifier) {
+ return typeParameterImpl;
+ }
+ }
+ return null;
+ }
+
+ @override
+ MethodElement getMethod(String methodName) {
+ int length = methods.length;
+ for (int i = 0; i < length; i++) {
+ MethodElement method = methods[i];
+ if (method.name == methodName) {
+ return method;
+ }
+ }
+ return null;
+ }
+
+ @override
+ ConstructorElement getNamedConstructor(String name) {
+ for (ConstructorElement element in constructors) {
+ String elementName = element.name;
+ if (elementName != null && elementName == name) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ @override
+ bool isSuperConstructorAccessible(ConstructorElement constructor) {
+ // If this class has no mixins, then all superclass constructors are
+ // accessible.
+ if (mixins.isEmpty) {
+ return true;
+ }
+ // Otherwise only constructors that lack optional parameters are
+ // accessible (see dartbug.com/19576).
+ for (ParameterElement parameter in constructor.parameters) {
+ if (parameter.parameterKind != ParameterKind.REQUIRED) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @override
+ void visitChildren(ElementVisitor visitor) {
+ super.visitChildren(visitor);
+ safelyVisitChildren(_constructors, visitor);
+ safelyVisitChildren(methods, visitor);
+ safelyVisitChildren(_typeParameters, visitor);
+ }
+
+ void _collectAllSupertypes(List<InterfaceType> supertypes) {
+ List<InterfaceType> typesToVisit = new List<InterfaceType>();
+ List<ClassElement> visitedClasses = new List<ClassElement>();
+ typesToVisit.add(this.type);
+ while (!typesToVisit.isEmpty) {
+ InterfaceType currentType = typesToVisit.removeAt(0);
+ ClassElement currentElement = currentType.element;
+ if (!visitedClasses.contains(currentElement)) {
+ visitedClasses.add(currentElement);
+ if (!identical(currentType, this.type)) {
+ supertypes.add(currentType);
+ }
+ InterfaceType supertype = currentType.superclass;
+ if (supertype != null) {
+ typesToVisit.add(supertype);
+ }
+ for (InterfaceType type in currentElement.interfaces) {
+ typesToVisit.add(type);
+ }
+ for (InterfaceType type in currentElement.mixins) {
+ ClassElement element = type.element;
+ if (!visitedClasses.contains(element)) {
+ supertypes.add(type);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Compute a list of constructors for this class, which is a mixin
+ * application. If specified, [visitedClasses] is a list of the other mixin
+ * application classes which have been visited on the way to reaching this
+ * one (this is used to detect circularities).
+ */
+ List<ConstructorElement> _computeMixinAppConstructors(
+ [List<ClassElementImpl> visitedClasses = null]) {
+ // First get the list of constructors of the superclass which need to be
+ // forwarded to this class.
+ Iterable<ConstructorElement> constructorsToForward;
+ if (supertype == null) {
+ // Shouldn't ever happen, since the only class with no supertype is
+ // Object, and it isn't a mixin application. But for safety's sake just
+ // assume an empty list.
+ assert(false);
+ constructorsToForward = <ConstructorElement>[];
+ } else if (!supertype.element.isMixinApplication) {
+ List<ConstructorElement> superclassConstructors =
+ supertype.element.constructors;
+ // Filter out any constructors with optional parameters (see
+ // dartbug.com/15101).
+ constructorsToForward =
+ superclassConstructors.where(isSuperConstructorAccessible);
+ } else {
+ if (visitedClasses == null) {
+ visitedClasses = <ClassElementImpl>[this];
+ } else {
+ if (visitedClasses.contains(this)) {
+ // Loop in the class hierarchy. Don't try to forward any
+ // constructors.
+ return <ConstructorElement>[];
+ }
+ visitedClasses.add(this);
+ }
+ try {
+ ClassElementImpl superElement = AbstractClassElementImpl
+ .getImpl(supertype.element) as ClassElementImpl;
+ constructorsToForward =
+ superElement._computeMixinAppConstructors(visitedClasses);
+ } finally {
+ visitedClasses.removeLast();
+ }
+ }
+
+ // Figure out the type parameter substitution we need to perform in order
+ // to produce constructors for this class. We want to be robust in the
+ // face of errors, so drop any extra type arguments and fill in any missing
+ // ones with `dynamic`.
+ List<DartType> parameterTypes =
+ TypeParameterTypeImpl.getTypes(supertype.typeParameters);
+ List<DartType> argumentTypes = new List<DartType>.filled(
+ parameterTypes.length, DynamicTypeImpl.instance);
+ for (int i = 0; i < supertype.typeArguments.length; i++) {
+ if (i >= argumentTypes.length) {
+ break;
+ }
+ argumentTypes[i] = supertype.typeArguments[i];
+ }
+
+ // Now create an implicit constructor for every constructor found above,
+ // substituting type parameters as appropriate.
+ return constructorsToForward
+ .map((ConstructorElement superclassConstructor) {
+ ConstructorElementImpl implicitConstructor =
+ new ConstructorElementImpl(superclassConstructor.name, -1);
+ implicitConstructor.synthetic = true;
+ implicitConstructor.redirectedConstructor = superclassConstructor;
+ List<ParameterElement> superParameters = superclassConstructor.parameters;
+ int count = superParameters.length;
+ if (count > 0) {
+ List<ParameterElement> implicitParameters =
+ new List<ParameterElement>(count);
+ for (int i = 0; i < count; i++) {
+ ParameterElement superParameter = superParameters[i];
+ ParameterElementImpl implicitParameter =
+ new ParameterElementImpl(superParameter.name, -1);
+ implicitParameter.const3 = superParameter.isConst;
+ implicitParameter.final2 = superParameter.isFinal;
+ implicitParameter.parameterKind = superParameter.parameterKind;
+ implicitParameter.synthetic = true;
+ implicitParameter.type =
+ superParameter.type.substitute2(argumentTypes, parameterTypes);
+ implicitParameters[i] = implicitParameter;
+ }
+ implicitConstructor.parameters = implicitParameters;
+ }
+ implicitConstructor.enclosingElement = this;
+ return implicitConstructor;
+ }).toList(growable: false);
+ }
+
+ /**
+ * Resynthesize explicit fields and property accessors and fill [_fields] and
+ * [_accessors] with explicit and implicit elements.
+ */
+ void _resynthesizeFieldsAndPropertyAccessors() {
+ assert(_fields == null);
+ assert(_accessors == null);
+ // Build explicit fields and implicit property accessors.
+ var explicitFields = <FieldElement>[];
+ var implicitAccessors = <PropertyAccessorElement>[];
+ for (UnlinkedVariable v in _unlinkedClass.fields) {
+ FieldElementImpl field =
+ new FieldElementImpl.forSerializedFactory(v, this);
+ explicitFields.add(field);
+ implicitAccessors.add(
+ new PropertyAccessorElementImpl_ImplicitGetter(field)
+ ..enclosingElement = this);
+ if (!field.isConst && !field.isFinal) {
+ implicitAccessors.add(
+ new PropertyAccessorElementImpl_ImplicitSetter(field)
+ ..enclosingElement = this);
+ }
+ }
+ // Build explicit property accessors and implicit fields.
+ var explicitAccessors = <PropertyAccessorElement>[];
+ var implicitFields = <String, FieldElementImpl>{};
+ for (UnlinkedExecutable e in _unlinkedClass.executables) {
+ if (e.kind == UnlinkedExecutableKind.getter ||
+ e.kind == UnlinkedExecutableKind.setter) {
+ PropertyAccessorElementImpl accessor =
+ new PropertyAccessorElementImpl.forSerialized(e, this);
+ explicitAccessors.add(accessor);
+ // Prepare the field type.
+ DartType fieldType;
+ if (e.kind == UnlinkedExecutableKind.getter) {
+ fieldType = accessor.returnType;
+ } else {
+ fieldType = accessor.parameters[0].type;
+ }
+ // Create or update the implicit field.
+ String fieldName = accessor.displayName;
+ FieldElementImpl field = implicitFields[fieldName];
+ if (field == null) {
+ field = new FieldElementImpl(fieldName, -1);
+ implicitFields[fieldName] = field;
+ field.enclosingElement = this;
+ field.synthetic = true;
+ field.final2 = e.kind == UnlinkedExecutableKind.getter;
+ field.type = fieldType;
+ } else {
+ field.final2 = false;
+ }
+ accessor.variable = field;
+ if (e.kind == UnlinkedExecutableKind.getter) {
+ field.getter = accessor;
+ } else {
+ field.setter = accessor;
+ }
+ }
+ }
+ // Combine explicit and implicit fields and property accessors.
+ _fields = <FieldElement>[]
+ ..addAll(explicitFields)
+ ..addAll(implicitFields.values);
+ _accessors = <PropertyAccessorElement>[]
+ ..addAll(explicitAccessors)
+ ..addAll(implicitAccessors);
+ }
+
bool _safeIsOrInheritsProxy(
ClassElement classElt, HashSet<ClassElement> visitedClassElts) {
if (visitedClassElts.contains(classElt)) {
@@ -1030,19 +1269,6 @@
}
return false;
}
-
- /**
- * Return the [ClassElementImpl] of the given [classElement]. May throw an
- * exception if the [ClassElementImpl] cannot be provided (should not happen
- * though).
- */
- static ClassElementImpl getImpl(ClassElement classElement) {
- if (classElement is ClassElementHandle) {
- classElement.ensureActualElementComplete();
- return getImpl(classElement.actualElement);
- }
- return classElement as ClassElementImpl;
- }
}
/**
@@ -1097,7 +1323,7 @@
/**
* A list containing all of the enums contained in this compilation unit.
*/
- List<ClassElement> _enums = ClassElement.EMPTY_LIST;
+ List<ClassElement> _enums;
/**
* A list containing all of the top-level functions contained in this
@@ -1109,13 +1335,12 @@
* A list containing all of the function type aliases contained in this
* compilation unit.
*/
- List<FunctionTypeAliasElement> _typeAliases =
- FunctionTypeAliasElement.EMPTY_LIST;
+ List<FunctionTypeAliasElement> _typeAliases;
/**
* A list containing all of the types contained in this compilation unit.
*/
- List<ClassElement> _types = ClassElement.EMPTY_LIST;
+ List<ClassElement> _types;
/**
* A list containing all of the variables contained in this compilation unit.
@@ -1225,14 +1450,22 @@
}
@override
- List<ClassElement> get enums => _enums;
+ List<ClassElement> get enums {
+ if (_unlinkedUnit != null) {
+ _enums ??= _unlinkedUnit.enums
+ .map((e) => new EnumElementImpl.forSerialized(e, this))
+ .toList(growable: false);
+ }
+ return _enums ?? const <ClassElement>[];
+ }
/**
* Set the enums contained in this compilation unit to the given [enums].
*/
void set enums(List<ClassElement> enums) {
+ assert(_unlinkedUnit == null);
for (ClassElement enumDeclaration in enums) {
- (enumDeclaration as ClassElementImpl).enclosingElement = this;
+ (enumDeclaration as EnumElementImpl).enclosingElement = this;
}
this._enums = enums;
}
@@ -1240,9 +1473,12 @@
@override
List<FunctionElement> get functions {
if (_unlinkedUnit != null) {
- _functions ??= resynthesizerContext.buildTopLevelFunctions();
+ _functions ??= _unlinkedUnit.executables
+ .where((e) => e.kind == UnlinkedExecutableKind.functionOrMethod)
+ .map((e) => new FunctionElementImpl.forSerialized(e, this))
+ .toList(growable: false);
}
- return _functions ?? FunctionElement.EMPTY_LIST;
+ return _functions ?? const <FunctionElement>[];
}
/**
@@ -1257,7 +1493,14 @@
}
@override
- List<FunctionTypeAliasElement> get functionTypeAliases => _typeAliases;
+ List<FunctionTypeAliasElement> get functionTypeAliases {
+ if (_unlinkedUnit != null) {
+ _typeAliases ??= _unlinkedUnit.typedefs
+ .map((t) => new FunctionTypeAliasElementImpl.forSerialized(t, this))
+ .toList(growable: false);
+ }
+ return _typeAliases ?? const <FunctionTypeAliasElement>[];
+ }
@override
int get hashCode => source.hashCode;
@@ -1334,6 +1577,7 @@
* given [typeAliases].
*/
void set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
+ assert(_unlinkedUnit == null);
for (FunctionTypeAliasElement typeAlias in typeAliases) {
(typeAlias as FunctionTypeAliasElementImpl).enclosingElement = this;
}
@@ -1344,12 +1588,20 @@
TypeParameterizedElementMixin get typeParameterContext => null;
@override
- List<ClassElement> get types => _types;
+ List<ClassElement> get types {
+ if (_unlinkedUnit != null) {
+ _types ??= _unlinkedUnit.classes
+ .map((c) => new ClassElementImpl.forSerialized(c, this))
+ .toList(growable: false);
+ }
+ return _types ?? const <ClassElement>[];
+ }
/**
* Set the types contained in this compilation unit to the given [types].
*/
void set types(List<ClassElement> types) {
+ assert(_unlinkedUnit == null);
for (ClassElement type in types) {
// Another implementation of ClassElement is _DeferredClassElement,
// which is used to resynthesize classes lazily. We cannot cast it
@@ -1425,20 +1677,20 @@
return functionImpl;
}
}
- for (FunctionTypeAliasElement typeAlias in _typeAliases) {
+ for (FunctionTypeAliasElement typeAlias in functionTypeAliases) {
FunctionTypeAliasElementImpl typeAliasImpl = typeAlias;
if (typeAliasImpl.identifier == identifier) {
return typeAliasImpl;
}
}
- for (ClassElement type in _types) {
+ for (ClassElement type in types) {
ClassElementImpl typeImpl = type;
if (typeImpl.name == identifier) {
return typeImpl;
}
}
for (ClassElement type in _enums) {
- ClassElementImpl typeImpl = type;
+ EnumElementImpl typeImpl = type;
if (typeImpl.identifier == identifier) {
return typeImpl;
}
@@ -1466,7 +1718,7 @@
@override
ClassElement getType(String className) {
- for (ClassElement type in _types) {
+ for (ClassElement type in types) {
if (type.name == className) {
return type;
}
@@ -1507,8 +1759,8 @@
safelyVisitChildren(accessors, visitor);
safelyVisitChildren(_enums, visitor);
safelyVisitChildren(functions, visitor);
- safelyVisitChildren(_typeAliases, visitor);
- safelyVisitChildren(_types, visitor);
+ safelyVisitChildren(functionTypeAliases, visitor);
+ safelyVisitChildren(types, visitor);
safelyVisitChildren(topLevelVariables, visitor);
}
}
@@ -1544,6 +1796,149 @@
}
/**
+ * A field element representing an enum constant.
+ */
+class ConstFieldElementImpl_EnumValue extends ConstFieldElementImpl_ofEnum {
+ final UnlinkedEnumValue _unlinkedEnumValue;
+ final int _index;
+
+ ConstFieldElementImpl_EnumValue(
+ EnumElementImpl enumElement, this._unlinkedEnumValue, this._index)
+ : super(enumElement);
+
+ @override
+ SourceRange get docRange {
+ if (_unlinkedEnumValue != null) {
+ UnlinkedDocumentationComment comment =
+ _unlinkedEnumValue.documentationComment;
+ return comment != null
+ ? new SourceRange(comment.offset, comment.length)
+ : null;
+ }
+ return super.docRange;
+ }
+
+ @override
+ String get documentationComment {
+ if (_unlinkedEnumValue != null) {
+ return _unlinkedEnumValue?.documentationComment?.text;
+ }
+ return super.documentationComment;
+ }
+
+ @override
+ EvaluationResultImpl get evaluationResult {
+ if (_evaluationResult == null) {
+ Map<String, DartObjectImpl> fieldMap = <String, DartObjectImpl>{
+ name: new DartObjectImpl(
+ context.typeProvider.intType, new IntState(_index))
+ };
+ DartObjectImpl value =
+ new DartObjectImpl(type, new GenericState(fieldMap));
+ _evaluationResult = new EvaluationResultImpl(value);
+ }
+ return _evaluationResult;
+ }
+
+ @override
+ String get name {
+ if (_unlinkedEnumValue != null) {
+ return _unlinkedEnumValue.name;
+ }
+ return super.name;
+ }
+
+ @override
+ int get nameOffset {
+ if (_unlinkedEnumValue != null) {
+ return _unlinkedEnumValue.nameOffset;
+ }
+ return super.nameOffset;
+ }
+
+ @override
+ InterfaceType get type => _enum.type;
+}
+
+/**
+ * The synthetic `values` field of an enum.
+ */
+class ConstFieldElementImpl_EnumValues extends ConstFieldElementImpl_ofEnum {
+ ConstFieldElementImpl_EnumValues(EnumElementImpl enumElement)
+ : super(enumElement) {
+ synthetic = true;
+ }
+
+ @override
+ EvaluationResultImpl get evaluationResult {
+ if (_evaluationResult == null) {
+ List<DartObjectImpl> constantValues = <DartObjectImpl>[];
+ for (FieldElement field in _enum.fields) {
+ if (field is ConstFieldElementImpl_EnumValue) {
+ constantValues.add(field.evaluationResult.value);
+ }
+ }
+ _evaluationResult = new EvaluationResultImpl(
+ new DartObjectImpl(type, new ListState(constantValues)));
+ }
+ return _evaluationResult;
+ }
+
+ @override
+ String get name => 'values';
+
+ @override
+ InterfaceType get type {
+ if (_type == null) {
+ InterfaceType listType = context.typeProvider.listType;
+ return _type = listType.instantiate(<DartType>[_enum.type]);
+ }
+ return _type;
+ }
+}
+
+/**
+ * An abstract constant field of an enum.
+ */
+abstract class ConstFieldElementImpl_ofEnum extends ConstFieldElementImpl {
+ final EnumElementImpl _enum;
+
+ ConstFieldElementImpl_ofEnum(this._enum) : super(null, -1) {
+ enclosingElement = _enum;
+ }
+
+ @override
+ void set const3(bool isConst) {
+ assert(false);
+ }
+
+ @override
+ void set evaluationResult(_) {
+ assert(false);
+ }
+
+ @override
+ void set final2(bool isFinal) {
+ assert(false);
+ }
+
+ @override
+ bool get isConst => true;
+
+ @override
+ bool get isStatic => true;
+
+ @override
+ void set static(bool isStatic) {
+ assert(false);
+ }
+
+ void set type(DartType type) {
+ assert(false);
+ }
+}
+
+/**
* A [LocalVariableElement] for a local 'const' variable that has an
* initializer.
*/
@@ -1576,30 +1971,30 @@
/**
* The constructor to which this constructor is redirecting.
*/
- ConstructorElement redirectedConstructor;
+ ConstructorElement _redirectedConstructor;
/**
* The initializers for this constructor (used for evaluating constant
* instance creation expressions).
*/
- List<ConstructorInitializer> constantInitializers;
+ List<ConstructorInitializer> _constantInitializers;
/**
* The offset of the `.` before this constructor name or `null` if not named.
*/
- int periodOffset;
+ int _periodOffset;
/**
* Return the offset of the character immediately following the last character
* of this constructor's name, or `null` if not named.
*/
- int nameEnd;
+ int _nameEnd;
/**
* True if this constructor has been found by constant evaluation to be free
* of redirect cycles, and is thus safe to evaluate.
*/
- bool isCycleFree = false;
+ bool _isCycleFree = false;
/**
* Initialize a newly created constructor element to have the given [name] and
@@ -1627,8 +2022,24 @@
setModifier(Modifier.CONST, isConst);
}
+ List<ConstructorInitializer> get constantInitializers {
+ if (serializedExecutable != null && _constantInitializers == null) {
+ _constantInitializers ??= serializedExecutable.constantInitializers
+ .map((i) => _buildConstructorInitializer(i))
+ .toList(growable: false);
+ }
+ return _constantInitializers;
+ }
+
+ void set constantInitializers(
+ List<ConstructorInitializer> constantInitializers) {
+ assert(serializedExecutable == null);
+ _constantInitializers = constantInitializers;
+ }
+
@override
- ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+ ClassElementImpl get enclosingElement =>
+ super.enclosingElement as ClassElementImpl;
@override
TypeParameterizedElementMixin get enclosingTypeParameterContext =>
@@ -1650,6 +2061,21 @@
return hasModifier(Modifier.CONST);
}
+ bool get isCycleFree {
+ if (serializedExecutable != null) {
+ return serializedExecutable.isConst &&
+ !enclosingUnit.resynthesizerContext
+ .isInConstCycle(serializedExecutable.constCycleSlot);
+ }
+ return _isCycleFree;
+ }
+
+ void set isCycleFree(bool isCycleFree) {
+ // This property is updated in ConstantEvaluationEngine even for
+ // resynthesized constructors, so we don't have the usual assert here.
+ _isCycleFree = isCycleFree;
+ }
+
@override
bool get isDefaultConstructor {
// unnamed
@@ -1682,8 +2108,77 @@
ElementKind get kind => ElementKind.CONSTRUCTOR;
@override
+ int get nameEnd {
+ if (serializedExecutable != null) {
+ if (serializedExecutable.name.isNotEmpty) {
+ return serializedExecutable.nameEnd;
+ } else {
+ return serializedExecutable.nameOffset + enclosingElement.name.length;
+ }
+ }
+ return _nameEnd;
+ }
+
+ void set nameEnd(int nameEnd) {
+ assert(serializedExecutable == null);
+ _nameEnd = nameEnd;
+ }
+
+ @override
+ int get periodOffset {
+ if (serializedExecutable != null) {
+ if (serializedExecutable.name.isNotEmpty) {
+ return serializedExecutable.periodOffset;
+ }
+ }
+ return _periodOffset;
+ }
+
+ void set periodOffset(int periodOffset) {
+ assert(serializedExecutable == null);
+ _periodOffset = periodOffset;
+ }
+
+ @override
+ ConstructorElement get redirectedConstructor {
+ if (serializedExecutable != null && _redirectedConstructor == null) {
+ if (serializedExecutable.isRedirectedConstructor) {
+ if (serializedExecutable.isFactory) {
+ _redirectedConstructor = enclosingUnit.resynthesizerContext
+ .resolveConstructorRef(
+ enclosingElement, serializedExecutable.redirectedConstructor);
+ } else {
+ _redirectedConstructor = enclosingElement.getNamedConstructor(
+ serializedExecutable.redirectedConstructorName);
+ }
+ } else {
+ return null;
+ }
+ }
+ return _redirectedConstructor;
+ }
+
+ void set redirectedConstructor(ConstructorElement redirectedConstructor) {
+ assert(serializedExecutable == null);
+ _redirectedConstructor = redirectedConstructor;
+ }
+
+ @override
DartType get returnType => enclosingElement.type;
+ void set returnType(DartType returnType) {
+ assert(false);
+ }
+
+ @override
+ FunctionType get type {
+ return _type ??= new FunctionTypeImpl(this);
+ }
+
+ void set type(FunctionType type) {
+ assert(false);
+ }
+
@override
accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
@@ -1714,6 +2209,62 @@
@override
ConstructorDeclaration computeNode() =>
getNodeMatching((node) => node is ConstructorDeclaration);
+
+ /**
+ * Resynthesize the AST for the given serialized constructor initializer.
+ */
+ ConstructorInitializer _buildConstructorInitializer(
+ UnlinkedConstructorInitializer serialized) {
+ UnlinkedConstructorInitializerKind kind = serialized.kind;
+ String name = serialized.name;
+ List<Expression> arguments = <Expression>[];
+ {
+ int numArguments = serialized.arguments.length;
+ int numNames = serialized.argumentNames.length;
+ for (int i = 0; i < numArguments; i++) {
+ Expression expression = enclosingUnit.resynthesizerContext
+ .buildExpression(this, serialized.arguments[i]);
+ int nameIndex = numNames + i - numArguments;
+ if (nameIndex >= 0) {
+ expression = AstFactory.namedExpression2(
+ serialized.argumentNames[nameIndex], expression);
+ }
+ arguments.add(expression);
+ }
+ }
+ switch (kind) {
+ case UnlinkedConstructorInitializerKind.field:
+ ConstructorFieldInitializer initializer =
+ AstFactory.constructorFieldInitializer(
+ false,
+ name,
+ enclosingUnit.resynthesizerContext
+ .buildExpression(this, serialized.expression));
+ initializer.fieldName.staticElement = enclosingElement.getField(name);
+ return initializer;
+ case UnlinkedConstructorInitializerKind.superInvocation:
+ SuperConstructorInvocation initializer =
+ AstFactory.superConstructorInvocation2(
+ name.isNotEmpty ? name : null, arguments);
+ ClassElement superElement = enclosingElement.supertype.element;
+ ConstructorElement element = name.isEmpty
+ ? superElement.unnamedConstructor
+ : superElement.getNamedConstructor(name);
+ initializer.staticElement = element;
+ initializer.constructorName?.staticElement = element;
+ return initializer;
+ case UnlinkedConstructorInitializerKind.thisInvocation:
+ RedirectingConstructorInvocation initializer =
+ AstFactory.redirectingConstructorInvocation2(
+ name.isNotEmpty ? name : null, arguments);
+ ConstructorElement element = name.isEmpty
+ ? enclosingElement.unnamedConstructor
+ : enclosingElement.getNamedConstructor(name);
+ initializer.staticElement = element;
+ initializer.constructorName?.staticElement = element;
+ return initializer;
+ }
+ }
}
/**
@@ -1755,7 +2306,8 @@
*
* This class is not intended to be part of the public API for analyzer.
*/
-abstract class ConstVariableElement implements ConstantEvaluationTarget {
+abstract class ConstVariableElement
+ implements ElementImpl, ConstantEvaluationTarget {
/**
* If this element represents a constant variable, and it has an initializer,
* a copy of the initializer for the constant. Otherwise `null`.
@@ -1765,10 +2317,34 @@
* in which case there might be some constant variables that lack
* initializers.
*/
- Expression constantInitializer;
+ Expression _constantInitializer;
- @override
- EvaluationResultImpl evaluationResult;
+ EvaluationResultImpl _evaluationResult;
+
+ Expression get constantInitializer {
+ if (_constantInitializer == null && _unlinkedConst != null) {
+ _constantInitializer = enclosingUnit.resynthesizerContext
+ .buildExpression(this, _unlinkedConst);
+ }
+ return _constantInitializer;
+ }
+
+ void set constantInitializer(Expression constantInitializer) {
+ assert(_unlinkedConst == null);
+ _constantInitializer = constantInitializer;
+ }
+
+ EvaluationResultImpl get evaluationResult => _evaluationResult;
+
+ void set evaluationResult(EvaluationResultImpl evaluationResult) {
+ _evaluationResult = evaluationResult;
+ }
+
+ /**
+ * If this element is resynthesized from the summary, return the unlinked
+ * initializer, otherwise return `null`.
+ */
+ UnlinkedConst get _unlinkedConst;
/**
* Return a representation of the value of this variable, forcing the value
@@ -1808,25 +2384,6 @@
DefaultFieldFormalParameterElementImpl.forSerialized(
UnlinkedParam unlinkedParam, ElementImpl enclosingElement)
: super.forSerialized(unlinkedParam, enclosingElement);
-
- @override
- Expression get constantInitializer {
- if (_unlinkedParam != null) {
- UnlinkedConst defaultValue = _unlinkedParam.initializer?.bodyExpr;
- if (defaultValue == null) {
- return null;
- }
- return super.constantInitializer ??= enclosingUnit.resynthesizerContext
- .buildExpression(this, defaultValue);
- }
- return super.constantInitializer;
- }
-
- @override
- void set constantInitializer(Expression initializer) {
- assert(_unlinkedParam == null);
- super.constantInitializer = initializer;
- }
}
/**
@@ -1854,25 +2411,6 @@
: super.forSerialized(unlinkedParam, enclosingElement);
@override
- Expression get constantInitializer {
- if (_unlinkedParam != null) {
- UnlinkedConst defaultValue = _unlinkedParam.initializer?.bodyExpr;
- if (defaultValue == null) {
- return null;
- }
- return super.constantInitializer ??= enclosingUnit.resynthesizerContext
- .buildExpression(this, defaultValue);
- }
- return super.constantInitializer;
- }
-
- @override
- void set constantInitializer(Expression initializer) {
- assert(_unlinkedParam == null);
- super.constantInitializer = initializer;
- }
-
- @override
DefaultFormalParameter computeNode() =>
getNodeMatching((node) => node is DefaultFormalParameter);
}
@@ -2768,6 +3306,252 @@
}
/**
+ * An [AbstractClassElementImpl] which is an enum.
+ */
+class EnumElementImpl extends AbstractClassElementImpl {
+ /**
+ * The unlinked representation of the enum in the summary.
+ */
+ final UnlinkedEnum _unlinkedEnum;
+
+ /**
+ * The type defined by the enum.
+ */
+ InterfaceType _type;
+
+ /**
+ * Initialize a newly created class element to have the given [name] at the
+ * given [offset] in the file that contains the declaration of this element.
+ */
+ EnumElementImpl(String name, int offset)
+ : _unlinkedEnum = null,
+ super(name, offset);
+
+ /**
+ * Initialize a newly created class element to have the given [name].
+ */
+ EnumElementImpl.forNode(Identifier name)
+ : _unlinkedEnum = null,
+ super.forNode(name);
+
+ /**
+ * Initialize using the given serialized information.
+ */
+ EnumElementImpl.forSerialized(
+ this._unlinkedEnum, CompilationUnitElementImpl enclosingUnit)
+ : super.forSerialized(enclosingUnit);
+
+ /**
+ * Set whether this class is abstract.
+ */
+ void set abstract(bool isAbstract) {
+ assert(_unlinkedEnum == null);
+ }
+
+ @override
+ List<PropertyAccessorElement> get accessors {
+ if (_unlinkedEnum != null && _accessors == null) {
+ _resynthesizeFieldsAndPropertyAccessors();
+ }
+ return _accessors ?? const <PropertyAccessorElement>[];
+ }
+
+ @override
+ void set accessors(List<PropertyAccessorElement> accessors) {
+ assert(_unlinkedEnum == null);
+ super.accessors = accessors;
+ }
+
+ @override
+ List<InterfaceType> get allSupertypes => <InterfaceType>[supertype];
+
+ @override
+ int get codeLength {
+ if (_unlinkedEnum != null) {
+ return _unlinkedEnum.codeRange?.length;
+ }
+ return super.codeLength;
+ }
+
+ @override
+ int get codeOffset {
+ if (_unlinkedEnum != null) {
+ return _unlinkedEnum.codeRange?.offset;
+ }
+ return super.codeOffset;
+ }
+
+ @override
+ List<ConstructorElement> get constructors {
+ // The equivalent code for enums in the spec shows a single constructor,
+ // but that constructor is not callable (since it is a compile-time error
+ // to subclass, mix-in, implement, or explicitly instantiate an enum).
+ // So we represent this as having no constructors.
+ return const <ConstructorElement>[];
+ }
+
+ @override
+ SourceRange get docRange {
+ if (_unlinkedEnum != null) {
+ UnlinkedDocumentationComment comment = _unlinkedEnum.documentationComment;
+ return comment != null
+ ? new SourceRange(comment.offset, comment.length)
+ : null;
+ }
+ return super.docRange;
+ }
+
+ @override
+ String get documentationComment {
+ if (_unlinkedEnum != null) {
+ return _unlinkedEnum?.documentationComment?.text;
+ }
+ return super.documentationComment;
+ }
+
+ @override
+ List<FieldElement> get fields {
+ if (_unlinkedEnum != null && _fields == null) {
+ _resynthesizeFieldsAndPropertyAccessors();
+ }
+ return _fields ?? const <FieldElement>[];
+ }
+
+ @override
+ void set fields(List<FieldElement> fields) {
+ assert(_unlinkedEnum == null);
+ super.fields = fields;
+ }
+
+ @override
+ bool get hasNonFinalField => false;
+
+ @override
+ bool get hasReferenceToSuper => false;
+
+ @override
+ bool get hasStaticMember => true;
+
+ @override
+ List<InterfaceType> get interfaces => const <InterfaceType>[];
+
+ @override
+ bool get isAbstract => false;
+
+ @override
+ bool get isEnum => true;
+
+ @override
+ bool get isMixinApplication => false;
+
+ @override
+ bool get isOrInheritsProxy => false;
+
+ @override
+ bool get isProxy => false;
+
+ @override
+ bool get isValidMixin => false;
+
+ @override
+ List<ElementAnnotation> get metadata {
+ if (_unlinkedEnum != null) {
+ return _metadata ??=
+ _buildAnnotations(enclosingUnit, _unlinkedEnum.annotations);
+ }
+ return super.metadata;
+ }
+
+ @override
+ List<MethodElement> get methods => const <MethodElement>[];
+
+ @override
+ List<InterfaceType> get mixins => const <InterfaceType>[];
+
+ @override
+ String get name {
+ if (_unlinkedEnum != null) {
+ return _unlinkedEnum.name;
+ }
+ return super.name;
+ }
+
+ @override
+ int get nameOffset {
+ if (_unlinkedEnum != null) {
+ return _unlinkedEnum.nameOffset;
+ }
+ return super.nameOffset;
+ }
+
+ @override
+ InterfaceType get supertype => context.typeProvider.objectType;
+
+ @override
+ InterfaceType get type {
+ if (_type == null) {
+ InterfaceTypeImpl type = new InterfaceTypeImpl(this);
+ type.typeArguments = const <DartType>[];
+ _type = type;
+ }
+ return _type;
+ }
+
+ @override
+ List<TypeParameterElement> get typeParameters =>
+ const <TypeParameterElement>[];
+
+ @override
+ ConstructorElement get unnamedConstructor => null;
+
+ @override
+ void appendTo(StringBuffer buffer) {
+ buffer.write('enum ');
+ String name = displayName;
+ if (name == null) {
+ buffer.write("{unnamed enum}");
+ } else {
+ buffer.write(name);
+ }
+ }
+
+ @override
+ MethodElement getMethod(String name) => null;
+
+ @override
+ ConstructorElement getNamedConstructor(String name) => null;
+
+ @override
+ bool isSuperConstructorAccessible(ConstructorElement constructor) => false;
+
+ void _resynthesizeFieldsAndPropertyAccessors() {
+ List<FieldElementImpl> fields = <FieldElementImpl>[];
+ // Build the 'index' field.
+ fields.add(new FieldElementImpl('index', -1)
+ ..enclosingElement = this
+ ..synthetic = true
+ ..final2 = true
+ ..type = context.typeProvider.intType);
+ // Build the 'values' field.
+ fields.add(new ConstFieldElementImpl_EnumValues(this));
+ // Build fields for all enum constants.
+ for (int i = 0; i < _unlinkedEnum.values.length; i++) {
+ UnlinkedEnumValue unlinkedValue = _unlinkedEnum.values[i];
+ ConstFieldElementImpl_EnumValue field =
+ new ConstFieldElementImpl_EnumValue(this, unlinkedValue, i);
+ fields.add(field);
+ }
+ // done
+ _fields = fields;
+ _accessors = fields
+ .map((FieldElementImpl field) =>
+ new PropertyAccessorElementImpl_ImplicitGetter(field)
+ ..enclosingElement = this)
+ .toList(growable: false);
+ }
+}
+
+/**
* A base class for concrete implementations of an [ExecutableElement].
*/
abstract class ExecutableElementImpl extends ElementImpl
@@ -2782,29 +3566,29 @@
* A list containing all of the functions defined within this executable
* element.
*/
- List<FunctionElement> _functions = FunctionElement.EMPTY_LIST;
+ List<FunctionElement> _functions;
/**
* A list containing all of the labels defined within this executable element.
*/
- List<LabelElement> _labels = LabelElement.EMPTY_LIST;
+ List<LabelElement> _labels;
/**
* A list containing all of the local variables defined within this executable
* element.
*/
- List<LocalVariableElement> _localVariables = LocalVariableElement.EMPTY_LIST;
+ List<LocalVariableElement> _localVariables;
/**
* A list containing all of the parameters defined by this executable element.
*/
- List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
+ List<ParameterElement> _parameters;
/**
* A list containing all of the type parameters defined for this executable
* element.
*/
- List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
+ List<TypeParameterElement> _typeParameters;
/**
* The return type defined by this executable element.
@@ -2814,7 +3598,7 @@
/**
* The type of function defined by this executable element.
*/
- FunctionType type;
+ FunctionType _type;
/**
* Initialize a newly created executable element to have the given [name] and
@@ -2899,13 +3683,20 @@
}
@override
- List<FunctionElement> get functions => _functions;
+ List<FunctionElement> get functions {
+ if (serializedExecutable != null) {
+ _functions ??= FunctionElementImpl.resynthesizeList(
+ this, serializedExecutable.localFunctions);
+ }
+ return _functions ?? const <FunctionElement>[];
+ }
/**
* Set the functions defined within this executable element to the given
* [functions].
*/
void set functions(List<FunctionElement> functions) {
+ assert(serializedExecutable == null);
for (FunctionElement function in functions) {
(function as FunctionElementImpl).enclosingElement = this;
}
@@ -2976,13 +3767,20 @@
bool get isSynchronous => !isAsynchronous;
@override
- List<LabelElement> get labels => _labels;
+ List<LabelElement> get labels {
+ if (serializedExecutable != null) {
+ _labels ??= LabelElementImpl.resynthesizeList(
+ this, serializedExecutable.localLabels);
+ }
+ return _labels ?? const <LabelElement>[];
+ }
/**
* Set the labels defined within this executable element to the given
* [labels].
*/
void set labels(List<LabelElement> labels) {
+ assert(serializedExecutable == null);
for (LabelElement label in labels) {
(label as LabelElementImpl).enclosingElement = this;
}
@@ -2990,13 +3788,32 @@
}
@override
- List<LocalVariableElement> get localVariables => _localVariables;
+ List<LocalVariableElement> get localVariables {
+ if (serializedExecutable != null && _localVariables == null) {
+ List<UnlinkedVariable> unlinkedVariables =
+ serializedExecutable.localVariables;
+ int length = unlinkedVariables.length;
+ if (length != 0) {
+ List<LocalVariableElementImpl> localVariables =
+ new List<LocalVariableElementImpl>(length);
+ for (int i = 0; i < length; i++) {
+ localVariables[i] = new LocalVariableElementImpl.forSerializedFactory(
+ unlinkedVariables[i], this);
+ }
+ _localVariables = localVariables;
+ } else {
+ _localVariables = const <LocalVariableElement>[];
+ }
+ }
+ return _localVariables ?? const <LocalVariableElement>[];
+ }
/**
* Set the local variables defined within this executable element to the given
* [variables].
*/
void set localVariables(List<LocalVariableElement> variables) {
+ assert(serializedExecutable == null);
for (LocalVariableElement variable in variables) {
(variable as LocalVariableElementImpl).enclosingElement = this;
}
@@ -3029,13 +3846,20 @@
}
@override
- List<ParameterElement> get parameters => _parameters;
+ List<ParameterElement> get parameters {
+ if (serializedExecutable != null) {
+ _parameters ??= ParameterElementImpl.resynthesizeList(
+ serializedExecutable.parameters, this);
+ }
+ return _parameters ?? const <ParameterElement>[];
+ }
/**
* Set the parameters defined by this executable element to the given
* [parameters].
*/
void set parameters(List<ParameterElement> parameters) {
+ assert(serializedExecutable == null);
for (ParameterElement parameter in parameters) {
(parameter as ParameterElementImpl).enclosingElement = this;
}
@@ -3063,16 +3887,36 @@
}
@override
+ FunctionType get type {
+ if (serializedExecutable != null) {
+ _type ??= new FunctionTypeImpl.elementWithNameAndArgs(
+ this, null, allEnclosingTypeParameterTypes, false);
+ }
+ return _type;
+ }
+
+ void set type(FunctionType type) {
+ assert(serializedExecutable == null);
+ _type = type;
+ }
+
+ @override
TypeParameterizedElementMixin get typeParameterContext => this;
@override
- List<TypeParameterElement> get typeParameters => _typeParameters;
+ List<TypeParameterElement> get typeParameters {
+ if (serializedExecutable != null) {
+ return super.typeParameters;
+ }
+ return _typeParameters ?? const <TypeParameterElement>[];
+ }
/**
* Set the type parameters defined by this executable element to the given
* [typeParameters].
*/
void set typeParameters(List<TypeParameterElement> typeParameters) {
+ assert(serializedExecutable == null);
for (TypeParameterElement parameter in typeParameters) {
(parameter as TypeParameterElementImpl).enclosingElement = this;
}
@@ -3086,26 +3930,26 @@
@override
void appendTo(StringBuffer buffer) {
if (this.kind != ElementKind.GETTER) {
- int typeParameterCount = _typeParameters.length;
+ int typeParameterCount = typeParameters.length;
if (typeParameterCount > 0) {
buffer.write('<');
for (int i = 0; i < typeParameterCount; i++) {
if (i > 0) {
buffer.write(", ");
}
- (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
+ (typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
}
buffer.write('>');
}
buffer.write("(");
String closing = null;
ParameterKind kind = ParameterKind.REQUIRED;
- int parameterCount = _parameters.length;
+ int parameterCount = parameters.length;
for (int i = 0; i < parameterCount; i++) {
if (i > 0) {
buffer.write(", ");
}
- ParameterElement parameter = _parameters[i];
+ ParameterElement parameter = parameters[i];
ParameterKind parameterKind = parameter.parameterKind;
if (parameterKind != kind) {
if (closing != null) {
@@ -3155,7 +3999,7 @@
return variableImpl;
}
}
- for (ParameterElement parameter in _parameters) {
+ for (ParameterElement parameter in parameters) {
ParameterElementImpl parameterImpl = parameter;
if (parameterImpl.identifier == identifier) {
return parameterImpl;
@@ -3170,7 +4014,7 @@
safelyVisitChildren(_functions, visitor);
safelyVisitChildren(_labels, visitor);
safelyVisitChildren(_localVariables, visitor);
- safelyVisitChildren(_parameters, visitor);
+ safelyVisitChildren(parameters, visitor);
}
}
@@ -3348,6 +4192,22 @@
UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
: super.forSerialized(unlinkedVariable, enclosingElement);
+ /**
+ * Initialize using the given serialized information.
+ */
+ factory FieldElementImpl.forSerializedFactory(
+ UnlinkedVariable unlinkedVariable, ClassElementImpl enclosingClass) {
+ if (unlinkedVariable.initializer?.bodyExpr != null &&
+ (unlinkedVariable.isConst ||
+ unlinkedVariable.isFinal && !unlinkedVariable.isStatic)) {
+ return new ConstFieldElementImpl.forSerialized(
+ unlinkedVariable, enclosingClass);
+ } else {
+ return new FieldElementImpl.forSerialized(
+ unlinkedVariable, enclosingClass);
+ }
+ }
+
@override
ClassElement get enclosingElement => super.enclosingElement as ClassElement;
@@ -3356,12 +4216,21 @@
enclosingElement != null ? enclosingElement.isEnum : false;
@override
+ bool get isStatic {
+ if (_unlinkedVariable != null) {
+ return _unlinkedVariable.isStatic;
+ }
+ return hasModifier(Modifier.STATIC);
+ }
+
+ @override
ElementKind get kind => ElementKind.FIELD;
/**
* Set whether this field is static.
*/
void set static(bool isStatic) {
+ assert(_unlinkedVariable == null);
setModifier(Modifier.STATIC, isStatic);
}
@@ -3540,6 +4409,13 @@
@override
SourceRange get visibleRange {
+ if (serializedExecutable != null) {
+ if (serializedExecutable.visibleLength == 0) {
+ return null;
+ }
+ return new SourceRange(serializedExecutable.visibleOffset,
+ serializedExecutable.visibleLength);
+ }
if (_visibleRangeLength < 0) {
return null;
}
@@ -3567,6 +4443,7 @@
* [offset] with the given [length].
*/
void setVisibleRange(int offset, int length) {
+ assert(serializedExecutable == null);
_visibleRangeOffset = offset;
_visibleRangeLength = length;
}
@@ -3589,6 +4466,25 @@
void shareTypeParameters(List<TypeParameterElement> typeParameters) {
this._typeParameters = typeParameters;
}
+
+ /**
+ * Create and return [FunctionElement]s for the given [unlinkedFunctions].
+ */
+ static List<FunctionElement> resynthesizeList(
+ ExecutableElementImpl executableElement,
+ List<UnlinkedExecutable> unlinkedFunctions) {
+ int length = unlinkedFunctions.length;
+ if (length != 0) {
+ List<FunctionElement> elements = new List<FunctionElement>(length);
+ for (int i = 0; i < length; i++) {
+ elements[i] = new FunctionElementImpl.forSerialized(
+ unlinkedFunctions[i], executableElement);
+ }
+ return elements;
+ } else {
+ return const <FunctionElement>[];
+ }
+ }
}
/**
@@ -3627,12 +4523,47 @@
@override
final TypeParameterizedElementMixin enclosingTypeParameterContext;
+ final EntityRef _entityRef;
+
FunctionElementImpl_forLUB(
- this.enclosingUnit, this.enclosingTypeParameterContext)
+ this.enclosingUnit, this.enclosingTypeParameterContext, this._entityRef)
: super('', -1);
@override
bool get isSynthetic => true;
+
+ @override
+ List<ParameterElement> get parameters {
+ return _parameters ??= ParameterElementImpl
+ .resynthesizeList(_entityRef.syntheticParams, this, synthetic: true);
+ }
+
+ @override
+ void set parameters(List<ParameterElement> parameters) {
+ assert(false);
+ }
+
+ @override
+ DartType get returnType {
+ return _returnType ??= enclosingUnit.resynthesizerContext
+ .resolveTypeRef(_entityRef.syntheticReturnType, typeParameterContext);
+ }
+
+ @override
+ void set returnType(DartType returnType) {
+ assert(false);
+ }
+
+ @override
+ FunctionType get type {
+ return _type ??=
+ new FunctionTypeImpl.elementWithNameAndArgs(this, null, null, false);
+ }
+
+ @override
+ void set type(FunctionType type) {
+ assert(false);
+ }
}
/**
@@ -3649,7 +4580,7 @@
/**
* A list containing all of the parameters defined by this type alias.
*/
- List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
+ List<ParameterElement> _parameters;
/**
* The return type defined by this type alias.
@@ -3659,7 +4590,7 @@
/**
* The type of function defined by this type alias.
*/
- FunctionType type;
+ FunctionType _type;
/**
* A list containing all of the type parameters defined for this type.
@@ -3770,12 +4701,19 @@
}
@override
- List<ParameterElement> get parameters => _parameters;
+ List<ParameterElement> get parameters {
+ if (_unlinkedTypedef != null) {
+ _parameters ??= ParameterElementImpl.resynthesizeList(
+ _unlinkedTypedef.parameters, this);
+ }
+ return _parameters ?? const <ParameterElement>[];
+ }
/**
* Set the parameters defined by this type alias to the given [parameters].
*/
void set parameters(List<ParameterElement> parameters) {
+ assert(_unlinkedTypedef == null);
if (parameters != null) {
for (ParameterElement parameter in parameters) {
(parameter as ParameterElementImpl).enclosingElement = this;
@@ -3799,6 +4737,19 @@
}
@override
+ FunctionType get type {
+ if (_unlinkedTypedef != null && _type == null) {
+ _type = new FunctionTypeImpl.forTypedef(this);
+ }
+ return _type;
+ }
+
+ void set type(FunctionType type) {
+ assert(_unlinkedTypedef == null);
+ _type = type;
+ }
+
+ @override
TypeParameterizedElementMixin get typeParameterContext => this;
@override
@@ -3867,7 +4818,7 @@
@override
ElementImpl getChild(String identifier) {
- for (ParameterElement parameter in _parameters) {
+ for (ParameterElement parameter in parameters) {
ParameterElementImpl parameterImpl = parameter;
if (parameterImpl.identifier == identifier) {
return parameterImpl;
@@ -3885,7 +4836,7 @@
@override
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
- safelyVisitChildren(_parameters, visitor);
+ safelyVisitChildren(parameters, visitor);
safelyVisitChildren(_typeParameters, visitor);
}
}
@@ -4202,6 +5153,11 @@
*/
class LabelElementImpl extends ElementImpl implements LabelElement {
/**
+ * The unlinked representation of the label in the summary.
+ */
+ final UnlinkedLabel _unlinkedLabel;
+
+ /**
* A flag indicating whether this label is associated with a `switch`
* statement.
*/
@@ -4223,7 +5179,8 @@
*/
LabelElementImpl(String name, int nameOffset, this._onSwitchStatement,
this._onSwitchMember)
- : super(name, nameOffset);
+ : _unlinkedLabel = null,
+ super(name, nameOffset);
/**
* Initialize a newly created label element to have the given [name].
@@ -4233,7 +5190,21 @@
*/
LabelElementImpl.forNode(
Identifier name, this._onSwitchStatement, this._onSwitchMember)
- : super.forNode(name);
+ : _unlinkedLabel = null,
+ super.forNode(name);
+
+ /**
+ * Initialize using the given serialized information.
+ */
+ LabelElementImpl.forSerialized(
+ UnlinkedLabel unlinkedLabel, ExecutableElementImpl enclosingExecutable)
+ : _unlinkedLabel = unlinkedLabel,
+ _onSwitchStatement = unlinkedLabel.isOnSwitchStatement,
+ _onSwitchMember = unlinkedLabel.isOnSwitchMember,
+ super.forSerialized(enclosingExecutable);
+
+ @override
+ String get displayName => name;
@override
ExecutableElement get enclosingElement =>
@@ -4254,7 +5225,42 @@
ElementKind get kind => ElementKind.LABEL;
@override
+ String get name {
+ if (_unlinkedLabel != null) {
+ return _unlinkedLabel.name;
+ }
+ return super.name;
+ }
+
+ @override
+ int get nameOffset {
+ if (_unlinkedLabel != null) {
+ return _unlinkedLabel.nameOffset;
+ }
+ return super.nameOffset;
+ }
+
+ @override
accept(ElementVisitor visitor) => visitor.visitLabelElement(this);
+
+ /**
+ * Create and return [LabelElement]s for the given [unlinkedLabels].
+ */
+ static List<LabelElement> resynthesizeList(
+ ExecutableElementImpl enclosingExecutable,
+ List<UnlinkedLabel> unlinkedLabels) {
+ int length = unlinkedLabels.length;
+ if (length != 0) {
+ List<LabelElement> elements = new List<LabelElement>(length);
+ for (int i = 0; i < length; i++) {
+ elements[i] = new LabelElementImpl.forSerialized(
+ unlinkedLabels[i], enclosingExecutable);
+ }
+ return elements;
+ } else {
+ return const <LabelElement>[];
+ }
+ }
}
/**
@@ -4444,7 +5450,7 @@
libraries.add(library);
}
}
- return new List.from(libraries);
+ return libraries.toList(growable: false);
}
@override
@@ -4534,7 +5540,7 @@
libraries.add(library);
}
}
- return new List.from(libraries);
+ return libraries.toList(growable: false);
}
@override
@@ -4747,7 +5753,7 @@
prefixes.add(prefix);
}
}
- _prefixes = prefixes.toList();
+ _prefixes = prefixes.toList(growable: false);
}
return _prefixes;
}
@@ -4782,9 +5788,9 @@
@override
List<LibraryElement> get visibleLibraries {
- Set<LibraryElement> visibleLibraries = new Set();
+ HashSet<LibraryElement> visibleLibraries = new HashSet<LibraryElement>();
_addVisibleLibraries(visibleLibraries, false);
- return new List.from(visibleLibraries);
+ return visibleLibraries.toList(growable: false);
}
@override
@@ -5109,6 +6115,22 @@
ExecutableElementImpl enclosingExecutable)
: super.forSerialized(unlinkedVariable, enclosingExecutable);
+ /**
+ * Initialize using the given serialized information.
+ */
+ factory LocalVariableElementImpl.forSerializedFactory(
+ UnlinkedVariable unlinkedVariable,
+ ExecutableElementImpl enclosingExecutable) {
+ if (unlinkedVariable.isConst &&
+ unlinkedVariable.initializer?.bodyExpr != null) {
+ return new ConstLocalVariableElementImpl.forSerialized(
+ unlinkedVariable, enclosingExecutable);
+ } else {
+ return new LocalVariableElementImpl.forSerialized(
+ unlinkedVariable, enclosingExecutable);
+ }
+ }
+
@override
String get identifier {
int enclosingOffset =
@@ -5128,6 +6150,13 @@
@override
SourceRange get visibleRange {
+ if (_unlinkedVariable != null) {
+ if (_unlinkedVariable.visibleLength == 0) {
+ return null;
+ }
+ return new SourceRange(
+ _unlinkedVariable.visibleOffset, _unlinkedVariable.visibleLength);
+ }
if (_visibleRangeLength < 0) {
return null;
}
@@ -5153,6 +6182,7 @@
* [offset] with the given [length].
*/
void setVisibleRange(int offset, int length) {
+ assert(_unlinkedVariable == null);
_visibleRangeOffset = offset;
_visibleRangeLength = length;
}
@@ -5189,6 +6219,14 @@
}
@override
+ List<TypeParameterType> get allEnclosingTypeParameterTypes {
+ if (isStatic) {
+ return const <TypeParameterType>[];
+ }
+ return super.allEnclosingTypeParameterTypes;
+ }
+
+ @override
String get displayName {
String displayName = super.displayName;
if ("unary-" == displayName) {
@@ -5595,7 +6633,7 @@
HashSet<Element> elements = new HashSet<Element>();
_add(elements, firstElement);
_add(elements, secondElement);
- return new List.from(elements);
+ return elements.toList(growable: false);
}
}
@@ -5746,6 +6784,29 @@
}
@override
+ FunctionElement get initializer {
+ if (_unlinkedVariable != null && _initializer == null) {
+ UnlinkedExecutable unlinkedInitializer = _unlinkedVariable.initializer;
+ if (unlinkedInitializer != null) {
+ _initializer = new FunctionElementImpl.forSerialized(
+ unlinkedInitializer, this)..synthetic = true;
+ } else {
+ return null;
+ }
+ }
+ return super.initializer;
+ }
+
+ /**
+ * Set the function representing this variable's initializer to the given
+ * [function].
+ */
+ void set initializer(FunctionElement function) {
+ assert(_unlinkedVariable == null);
+ super.initializer = function;
+ }
+
+ @override
bool get isConst {
if (_unlinkedVariable != null) {
return _unlinkedVariable.isConst;
@@ -5785,6 +6846,27 @@
}
return super.nameOffset;
}
+
+ @override
+ DartType get type {
+ if (_unlinkedVariable != null && _type == null) {
+ _type = enclosingUnit.resynthesizerContext.resolveLinkedType(
+ _unlinkedVariable.inferredTypeSlot, typeParameterContext) ??
+ enclosingUnit.resynthesizerContext
+ .resolveTypeRef(_unlinkedVariable.type, typeParameterContext);
+ }
+ return super.type;
+ }
+
+ void set type(DartType type) {
+ assert(_unlinkedVariable == null);
+ _type = type;
+ }
+
+ /**
+ * Subclasses need this getter, see [ConstVariableElement._unlinkedConst].
+ */
+ UnlinkedConst get _unlinkedConst => _unlinkedVariable?.initializer?.bodyExpr;
}
/**
@@ -5856,6 +6938,34 @@
: super.forSerialized(enclosingElement);
/**
+ * Initialize using the given serialized information.
+ */
+ factory ParameterElementImpl.forSerializedFactory(
+ UnlinkedParam unlinkedParameter, ElementImpl enclosingElement,
+ {bool synthetic: false}) {
+ ParameterElementImpl element;
+ if (unlinkedParameter.isInitializingFormal) {
+ if (unlinkedParameter.kind == UnlinkedParamKind.required) {
+ element = new FieldFormalParameterElementImpl.forSerialized(
+ unlinkedParameter, enclosingElement);
+ } else {
+ element = new DefaultFieldFormalParameterElementImpl.forSerialized(
+ unlinkedParameter, enclosingElement);
+ }
+ } else {
+ if (unlinkedParameter.kind == UnlinkedParamKind.required) {
+ element = new ParameterElementImpl.forSerialized(
+ unlinkedParameter, enclosingElement);
+ } else {
+ element = new DefaultParameterElementImpl.forSerialized(
+ unlinkedParameter, enclosingElement);
+ }
+ }
+ element.synthetic = synthetic;
+ return element;
+ }
+
+ /**
* Creates a synthetic parameter with [name], [type] and [kind].
*/
factory ParameterElementImpl.synthetic(
@@ -5929,6 +7039,29 @@
}
@override
+ FunctionElement get initializer {
+ if (_unlinkedParam != null && _initializer == null) {
+ UnlinkedExecutable unlinkedInitializer = _unlinkedParam.initializer;
+ if (unlinkedInitializer != null) {
+ _initializer = new FunctionElementImpl.forSerialized(
+ unlinkedInitializer, this)..synthetic = true;
+ } else {
+ return null;
+ }
+ }
+ return super.initializer;
+ }
+
+ /**
+ * Set the function representing this variable's initializer to the given
+ * [function].
+ */
+ void set initializer(FunctionElement function) {
+ assert(_unlinkedParam == null);
+ super.initializer = function;
+ }
+
+ @override
bool get isConst {
if (_unlinkedParam != null) {
return false;
@@ -6008,7 +7141,10 @@
}
@override
- List<ParameterElement> get parameters => _parameters;
+ List<ParameterElement> get parameters {
+ _resynthesizeTypeAndParameters();
+ return _parameters;
+ }
/**
* Set the parameters defined by this executable element to the given
@@ -6023,12 +7159,7 @@
@override
DartType get type {
- if (_unlinkedParam != null && _type == null) {
- _type = enclosingUnit.resynthesizerContext.resolveLinkedType(
- _unlinkedParam.inferredTypeSlot, typeParameterContext) ??
- enclosingUnit.resynthesizerContext
- .resolveTypeRef(_unlinkedParam.type, typeParameterContext);
- }
+ _resynthesizeTypeAndParameters();
return super.type;
}
@@ -6061,6 +7192,11 @@
return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
}
+ /**
+ * Subclasses need this getter, see [ConstVariableElement._unlinkedConst].
+ */
+ UnlinkedConst get _unlinkedConst => _unlinkedParam?.initializer?.bodyExpr;
+
@override
accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
@@ -6111,7 +7247,90 @@
@override
void visitChildren(ElementVisitor visitor) {
super.visitChildren(visitor);
- safelyVisitChildren(_parameters, visitor);
+ safelyVisitChildren(parameters, visitor);
+ }
+
+ /**
+ * If this element is resynthesized, and its type and parameters have not
+ * been build yet, build them and remember in the corresponding fields.
+ */
+ void _resynthesizeTypeAndParameters() {
+ if (_unlinkedParam != null && _type == null) {
+ if (_unlinkedParam.isFunctionTyped) {
+ CompilationUnitElementImpl enclosingUnit = this.enclosingUnit;
+ FunctionElementImpl parameterTypeElement =
+ new FunctionElementImpl_forFunctionTypedParameter(
+ enclosingUnit, this);
+ if (!isSynthetic) {
+ parameterTypeElement.enclosingElement = this;
+ }
+ List<ParameterElement> subParameters = ParameterElementImpl
+ .resynthesizeList(_unlinkedParam.parameters, this,
+ synthetic: isSynthetic);
+ if (isSynthetic) {
+ parameterTypeElement.parameters = subParameters;
+ } else {
+ _parameters = subParameters;
+ parameterTypeElement.shareParameters(subParameters);
+ }
+ parameterTypeElement.returnType = enclosingUnit.resynthesizerContext
+ .resolveTypeRef(_unlinkedParam.type, typeParameterContext);
+ FunctionTypeImpl parameterType =
+ new FunctionTypeImpl.elementWithNameAndArgs(parameterTypeElement,
+ null, typeParameterContext.allTypeParameterTypes, false);
+ parameterTypeElement.type = parameterType;
+ _type = parameterType;
+ } else {
+ _type = enclosingUnit.resynthesizerContext.resolveLinkedType(
+ _unlinkedParam.inferredTypeSlot, typeParameterContext) ??
+ enclosingUnit.resynthesizerContext
+ .resolveTypeRef(_unlinkedParam.type, typeParameterContext);
+ }
+ }
+ }
+
+ /**
+ * Create and return [ParameterElement]s for the given [unlinkedParameters].
+ */
+ static List<ParameterElement> resynthesizeList(
+ List<UnlinkedParam> unlinkedParameters, ElementImpl enclosingElement,
+ {bool synthetic: false}) {
+ int length = unlinkedParameters.length;
+ if (length != 0) {
+ List<ParameterElement> parameters = new List<ParameterElement>(length);
+ for (int i = 0; i < length; i++) {
+ parameters[i] = new ParameterElementImpl.forSerializedFactory(
+ unlinkedParameters[i], enclosingElement,
+ synthetic: synthetic);
+ }
+ return parameters;
+ } else {
+ return const <ParameterElement>[];
+ }
+ }
+}
+
+/**
+ * The parameter of an implicit setter.
+ */
+class ParameterElementImpl_ofImplicitSetter extends ParameterElementImpl {
+ final PropertyAccessorElementImpl_ImplicitSetter setter;
+
+ ParameterElementImpl_ofImplicitSetter(
+ PropertyAccessorElementImpl_ImplicitSetter setter)
+ : setter = setter,
+ super('_${setter.variable.name}', setter.variable.nameOffset) {
+ enclosingElement = setter;
+ synthetic = true;
+ parameterKind = ParameterKind.REQUIRED;
+ }
+
+ @override
+ DartType get type => setter.variable.type;
+
+ @override
+ void set type(FunctionType type) {
+ assert(false); // Should never be called.
}
}
@@ -6263,6 +7482,14 @@
}
@override
+ List<TypeParameterType> get allEnclosingTypeParameterTypes {
+ if (isStatic) {
+ return const <TypeParameterType>[];
+ }
+ return super.allEnclosingTypeParameterTypes;
+ }
+
+ @override
PropertyAccessorElement get correspondingGetter {
if (isGetter || variable == null) {
return null;
@@ -6302,9 +7529,6 @@
}
@override
- int get hashCode => JenkinsSmiHash.hash2(super.hashCode, isGetter ? 1 : 2);
-
- @override
String get identifier {
String name = displayName;
String suffix = isGetter ? "?" : "=";
@@ -6372,11 +7596,6 @@
}
@override
- bool operator ==(Object object) =>
- super == object &&
- isGetter == (object as PropertyAccessorElement).isGetter;
-
- @override
accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
@override
@@ -6401,6 +7620,89 @@
}
/**
+ * Implicit getter for a [PropertyInducingElementImpl].
+ */
+class PropertyAccessorElementImpl_ImplicitGetter
+ extends PropertyAccessorElementImpl {
+ /**
+ * Create the implicit getter and bind it to the [property].
+ */
+ PropertyAccessorElementImpl_ImplicitGetter(
+ PropertyInducingElementImpl property)
+ : super.forVariable(property) {
+ property.getter = this;
+ enclosingElement = property.enclosingElement;
+ }
+
+ @override
+ bool get hasImplicitReturnType => variable.hasImplicitType;
+
+ @override
+ bool get isGetter => true;
+
+ @override
+ DartType get returnType => variable.type;
+
+ @override
+ void set returnType(DartType returnType) {
+ assert(false); // Should never be called.
+ }
+
+ @override
+ DartType get type {
+ return _type ??= new FunctionTypeImpl(this);
+ }
+
+ @override
+ void set type(FunctionType type) {
+ assert(false); // Should never be called.
+ }
+}
+
+/**
+ * Implicit setter for a [PropertyInducingElementImpl].
+ */
+class PropertyAccessorElementImpl_ImplicitSetter
+ extends PropertyAccessorElementImpl {
+ /**
+ * Create the implicit setter and bind it to the [property].
+ */
+ PropertyAccessorElementImpl_ImplicitSetter(
+ PropertyInducingElementImpl property)
+ : super.forVariable(property) {
+ property.setter = this;
+ }
+
+ @override
+ bool get isSetter => true;
+
+ @override
+ List<ParameterElement> get parameters {
+ return _parameters ??= <ParameterElement>[
+ new ParameterElementImpl_ofImplicitSetter(this)
+ ];
+ }
+
+ @override
+ DartType get returnType => VoidTypeImpl.instance;
+
+ @override
+ void set returnType(DartType returnType) {
+ assert(false); // Should never be called.
+ }
+
+ @override
+ DartType get type {
+ return _type ??= new FunctionTypeImpl(this);
+ }
+
+ @override
+ void set type(FunctionType type) {
+ assert(false); // Should never be called.
+ }
+}
+
+/**
* A concrete implementation of a [PropertyInducingElement].
*/
abstract class PropertyInducingElementImpl
@@ -6421,7 +7723,7 @@
* The propagated type of this variable, or `null` if type propagation has not
* been performed.
*/
- DartType propagatedType;
+ DartType _propagatedType;
/**
* Initialize a newly created synthetic element to have the given [name] and
@@ -6440,6 +7742,20 @@
PropertyInducingElementImpl.forSerialized(
UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
: super.forSerialized(unlinkedVariable, enclosingElement);
+
+ @override
+ DartType get propagatedType {
+ if (_unlinkedVariable != null && _propagatedType == null) {
+ _propagatedType = enclosingUnit.resynthesizerContext.resolveLinkedType(
+ _unlinkedVariable.propagatedTypeSlot, typeParameterContext);
+ }
+ return _propagatedType;
+ }
+
+ void set propagatedType(DartType propagatedType) {
+ assert(_unlinkedVariable == null);
+ _propagatedType = propagatedType;
+ }
}
/**
@@ -6462,16 +7778,23 @@
UnitExplicitTopLevelAccessors buildTopLevelAccessors();
/**
- * Build top-level functions.
- */
- List<FunctionElementImpl> buildTopLevelFunctions();
-
- /**
* Build explicit top-level variables.
*/
UnitExplicitTopLevelVariables buildTopLevelVariables();
/**
+ * Return `true` if the given const constructor [slot] is a part of a cycle.
+ */
+ bool isInConstCycle(int slot);
+
+ /**
+ * Resolve an [EntityRef] into a constructor. If the reference is
+ * unresolved, return `null`.
+ */
+ ConstructorElement resolveConstructorRef(
+ TypeParameterizedElementMixin typeParameterContext, EntityRef entry);
+
+ /**
* Build the appropriate [DartType] object corresponding to a slot id in the
* [LinkedUnit.types] table.
*/
@@ -6626,11 +7949,6 @@
final UnlinkedTypeParam _unlinkedTypeParam;
/**
- * The [TypeParameterizedElement] enclosing this one.
- */
- final TypeParameterizedElementMixin _enclosingTypeParameterizedElement;
-
- /**
* The number of type parameters whose scope overlaps this one, and which are
* declared earlier in the file.
*
@@ -6656,7 +7974,6 @@
TypeParameterElementImpl(String name, int offset)
: _unlinkedTypeParam = null,
nestingLevel = null,
- _enclosingTypeParameterizedElement = null,
super(name, offset);
/**
@@ -6665,17 +7982,13 @@
TypeParameterElementImpl.forNode(Identifier name)
: _unlinkedTypeParam = null,
nestingLevel = null,
- _enclosingTypeParameterizedElement = null,
super.forNode(name);
/**
* Initialize using the given serialized information.
*/
- TypeParameterElementImpl.forSerialized(
- this._unlinkedTypeParam,
- ElementImpl enclosingElement,
- this._enclosingTypeParameterizedElement,
- this.nestingLevel)
+ TypeParameterElementImpl.forSerialized(this._unlinkedTypeParam,
+ TypeParameterizedElementMixin enclosingElement, this.nestingLevel)
: super.forSerialized(enclosingElement);
/**
@@ -6685,7 +7998,6 @@
TypeParameterElementImpl.synthetic(String name)
: _unlinkedTypeParam = null,
nestingLevel = null,
- _enclosingTypeParameterizedElement = null,
super(name, -1) {
synthetic = true;
}
@@ -6727,14 +8039,6 @@
String get displayName => name;
@override
- Element get enclosingElement {
- if (_unlinkedTypeParam != null) {
- return _enclosingTypeParameterizedElement;
- }
- return super.enclosingElement;
- }
-
- @override
ElementKind get kind => ElementKind.TYPE_PARAMETER;
@override
@@ -6791,9 +8095,34 @@
*/
abstract class TypeParameterizedElementMixin
implements TypeParameterizedElement, ElementImpl {
- List<TypeParameterType> _typeParameterTypes;
- List<TypeParameterElement> _typeParameterElements;
int _nestingLevel;
+ List<TypeParameterElement> _typeParameterElements;
+ List<TypeParameterType> _typeParameterTypes;
+ List<TypeParameterType> _allTypeParameterTypes;
+
+ /**
+ * Return all type parameter types of the element that encloses element.
+ * Not `null`, but might be empty for top-level and static class members.
+ */
+ List<TypeParameterType> get allEnclosingTypeParameterTypes {
+ return enclosingTypeParameterContext?.allTypeParameterTypes ??
+ const <TypeParameterType>[];
+ }
+
+ /**
+ * Return all type parameter types of this element.
+ */
+ List<TypeParameterType> get allTypeParameterTypes {
+ if (_allTypeParameterTypes == null) {
+ _allTypeParameterTypes = <TypeParameterType>[];
+ // The most logical order would be (enclosing, this).
+ // But we have to have it like this to be consistent with (inconsistent
+ // by itself) element builder for generic functions.
+ _allTypeParameterTypes.addAll(typeParameterTypes);
+ _allTypeParameterTypes.addAll(allEnclosingTypeParameterTypes);
+ }
+ return _allTypeParameterTypes;
+ }
/**
* Get the type parameter context enclosing this one, if any.
@@ -6821,7 +8150,7 @@
new List<TypeParameterElement>(numTypeParameters);
for (int i = 0; i < numTypeParameters; i++) {
_typeParameterElements[i] = new TypeParameterElementImpl.forSerialized(
- unlinkedTypeParams[i], this, this, enclosingNestingLevel + i);
+ unlinkedTypeParams[i], this, enclosingNestingLevel + i);
}
}
return _typeParameterElements;
@@ -6832,11 +8161,9 @@
* element's type parameters.
*/
List<TypeParameterType> get typeParameterTypes {
- if (_typeParameterTypes == null) {
- _typeParameterTypes =
- typeParameters.map((TypeParameterElement e) => e.type).toList();
- }
- return _typeParameterTypes;
+ return _typeParameterTypes ??= typeParameters
+ .map((TypeParameterElement e) => e.type)
+ .toList(growable: false);
}
/**
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 0e71499..633fcb0 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -98,67 +98,29 @@
List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
@override
- ConstructorElement get unnamedConstructor {
- ensureConstructorsReady();
- return actualElement.unnamedConstructor;
- }
+ ConstructorElement get unnamedConstructor => actualElement.unnamedConstructor;
@override
NamedCompilationUnitMember computeNode() => super.computeNode();
- /**
- * Ensure that [ClassElement.accessors] and [ClassElement.fields] are ready
- * in [actualElement].
- */
- void ensureAccessorsReady() {}
-
- /**
- * The method is called by [ClassElementImpl.getImpl] before returning
- * the [actualElement] as [ClassElementImpl]. At this moment we must ensure
- * that [ClassElementImpl] is fully complete, we cannot continue filling it
- * lazily.
- */
- void ensureActualElementComplete() {}
-
- /**
- * Ensure that [ClassElement.constructors] are ready in [actualElement].
- */
- void ensureConstructorsReady() {}
-
- /**
- * Ensure that [ClassElement.methods] are ready in [actualElement].
- */
- void ensureMethodsReady() {}
+ @override
+ FieldElement getField(String fieldName) => actualElement.getField(fieldName);
@override
- FieldElement getField(String fieldName) {
- ensureAccessorsReady();
- return actualElement.getField(fieldName);
- }
+ PropertyAccessorElement getGetter(String getterName) =>
+ actualElement.getGetter(getterName);
@override
- PropertyAccessorElement getGetter(String getterName) {
- ensureAccessorsReady();
- return actualElement.getGetter(getterName);
- }
+ MethodElement getMethod(String methodName) =>
+ actualElement.getMethod(methodName);
@override
- MethodElement getMethod(String methodName) {
- ensureMethodsReady();
- return actualElement.getMethod(methodName);
- }
+ ConstructorElement getNamedConstructor(String name) =>
+ actualElement.getNamedConstructor(name);
@override
- ConstructorElement getNamedConstructor(String name) {
- ensureConstructorsReady();
- return actualElement.getNamedConstructor(name);
- }
-
- @override
- PropertyAccessorElement getSetter(String setterName) {
- ensureAccessorsReady();
- return actualElement.getSetter(setterName);
- }
+ PropertyAccessorElement getSetter(String setterName) =>
+ actualElement.getSetter(setterName);
@override
bool isSuperConstructorAccessible(ConstructorElement constructor) =>
@@ -166,10 +128,8 @@
@override
MethodElement lookUpConcreteMethod(
- String methodName, LibraryElement library) {
- ensureMethodsReady();
- return actualElement.lookUpConcreteMethod(methodName, library);
- }
+ String methodName, LibraryElement library) =>
+ actualElement.lookUpConcreteMethod(methodName, library);
@override
PropertyAccessorElement lookUpGetter(
@@ -178,44 +138,33 @@
@override
PropertyAccessorElement lookUpInheritedConcreteGetter(
- String methodName, LibraryElement library) {
- ensureAccessorsReady();
- return actualElement.lookUpInheritedConcreteGetter(methodName, library);
- }
+ String methodName, LibraryElement library) =>
+ actualElement.lookUpInheritedConcreteGetter(methodName, library);
@override
MethodElement lookUpInheritedConcreteMethod(
- String methodName, LibraryElement library) {
- ensureMethodsReady();
- return actualElement.lookUpInheritedConcreteMethod(methodName, library);
- }
+ String methodName, LibraryElement library) =>
+ actualElement.lookUpInheritedConcreteMethod(methodName, library);
@override
PropertyAccessorElement lookUpInheritedConcreteSetter(
- String methodName, LibraryElement library) {
- ensureAccessorsReady();
- return actualElement.lookUpInheritedConcreteSetter(methodName, library);
- }
+ String methodName, LibraryElement library) =>
+ actualElement.lookUpInheritedConcreteSetter(methodName, library);
@override
MethodElement lookUpInheritedMethod(
String methodName, LibraryElement library) {
- ensureMethodsReady();
return actualElement.lookUpInheritedMethod(methodName, library);
}
@override
- MethodElement lookUpMethod(String methodName, LibraryElement library) {
- ensureMethodsReady();
- return actualElement.lookUpMethod(methodName, library);
- }
+ MethodElement lookUpMethod(String methodName, LibraryElement library) =>
+ actualElement.lookUpMethod(methodName, library);
@override
PropertyAccessorElement lookUpSetter(
- String setterName, LibraryElement library) {
- ensureAccessorsReady();
- return actualElement.lookUpSetter(setterName, library);
- }
+ String setterName, LibraryElement library) =>
+ actualElement.lookUpSetter(setterName, library);
}
/**
@@ -1022,10 +971,10 @@
actualElement.correspondingSetter;
@override
- bool get isGetter => actualElement.isGetter;
+ bool get isGetter => !isSetter;
@override
- bool get isSetter => actualElement.isSetter;
+ bool get isSetter => location.components.last.endsWith('=');
@override
ElementKind get kind {
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 0ee0b97..8d6aec0 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -774,7 +774,8 @@
//
// Now instantiate([V]), and the result should be:
// {U/T, V/S} T -> S.
- List<DartType> newTypeArgs = typeArguments.toList();
+ List<DartType> newTypeArgs = <DartType>[];
+ newTypeArgs.addAll(typeArguments);
newTypeArgs.addAll(argumentTypes);
return new FunctionTypeImpl._(
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 724ddc5..2a49090 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -1136,7 +1136,7 @@
@override
Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
ClassElementImpl enclosingClass =
- ClassElementImpl.getImpl(_resolver.enclosingClass);
+ AbstractClassElementImpl.getImpl(_resolver.enclosingClass);
if (enclosingClass == null) {
// TODO(brianwilkerson) Report this error.
return null;
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 9fb06c5..633243a 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -11,6 +11,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart' show ScannerErrorCode;
import 'package:analyzer/src/generated/generated/shared_messages.dart'
@@ -21,7 +22,6 @@
import 'package:analyzer/src/task/model.dart';
import 'package:analyzer/task/model.dart';
import 'package:source_span/source_span.dart';
-import 'package:analyzer/src/dart/element/element.dart';
/**
* The descriptor used to associate error processors with analysis contexts in
@@ -123,6 +123,12 @@
}
/**
+ * Initialize a newly created analysis error with given values.
+ */
+ AnalysisError.forValues(this.source, this.offset, this.length, this.errorCode,
+ this._message, this._correction);
+
+ /**
* Return the template used to create the correction to be displayed for this
* error, or `null` if there is no correction information for this error. The
* correction should indicate how the user can fix the error.
@@ -3023,6 +3029,11 @@
];
/**
+ * The lazy initialized map from [uniqueName] to the [ErrorCode] instance.
+ */
+ static HashMap<String, ErrorCode> _uniqueNameToCodeMap;
+
+ /**
* An empty list of error codes.
*/
static const List<ErrorCode> EMPTY_LIST = const <ErrorCode>[];
@@ -3070,6 +3081,20 @@
@override
String toString() => uniqueName;
+
+ /**
+ * Return the [ErrorCode] with the given [uniqueName], or `null` if not
+ * found.
+ */
+ static ErrorCode byUniqueName(String uniqueName) {
+ if (_uniqueNameToCodeMap == null) {
+ _uniqueNameToCodeMap = new HashMap<String, ErrorCode>();
+ for (ErrorCode errorCode in values) {
+ _uniqueNameToCodeMap[errorCode.uniqueName] = errorCode;
+ }
+ }
+ return _uniqueNameToCodeMap[uniqueName];
+ }
}
/**
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 78b7cf3..4bf1d0e 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -211,6 +211,12 @@
ClassElementImpl _enclosingClass;
/**
+ * The enum containing the AST nodes being visited, or `null` if we are not
+ * in the scope of an enum.
+ */
+ ClassElement _enclosingEnum;
+
+ /**
* The method or function that we are currently visiting, or `null` if we are
* not inside a method or function.
*/
@@ -435,7 +441,7 @@
ClassElementImpl outerClass = _enclosingClass;
try {
_isInNativeClass = node.nativeClause != null;
- _enclosingClass = ClassElementImpl.getImpl(node.element);
+ _enclosingClass = AbstractClassElementImpl.getImpl(node.element);
ExtendsClause extendsClause = node.extendsClause;
ImplementsClause implementsClause = node.implementsClause;
WithClause withClause = node.withClause;
@@ -484,7 +490,7 @@
*/
void visitClassDeclarationIncrementally(ClassDeclaration node) {
_isInNativeClass = node.nativeClause != null;
- _enclosingClass = ClassElementImpl.getImpl(node.element);
+ _enclosingClass = AbstractClassElementImpl.getImpl(node.element);
// initialize initialFieldElementsMap
if (_enclosingClass != null) {
List<FieldElement> fieldElements = _enclosingClass.fields;
@@ -504,7 +510,7 @@
node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
ClassElementImpl outerClassElement = _enclosingClass;
try {
- _enclosingClass = ClassElementImpl.getImpl(node.element);
+ _enclosingClass = AbstractClassElementImpl.getImpl(node.element);
ImplementsClause implementsClause = node.implementsClause;
// Only check for all of the inheritance logic around clauses if there
// isn't an error code such as "Cannot extend double" already on the
@@ -622,13 +628,12 @@
@override
Object visitEnumDeclaration(EnumDeclaration node) {
- ClassElementImpl outerClass = _enclosingClass;
+ ClassElement outerEnum = _enclosingEnum;
try {
- _isInNativeClass = false;
- _enclosingClass = ClassElementImpl.getImpl(node.element);
+ _enclosingEnum = node.element;
return super.visitEnumDeclaration(node);
} finally {
- _enclosingClass = outerClass;
+ _enclosingEnum = outerEnum;
}
}
@@ -5199,7 +5204,7 @@
return;
}
Element element = type.element;
- if (element is TypeParameterizedElement) {
+ if (element is ClassElement) {
// prepare type parameters
List<TypeParameterElement> parameterElements = element.typeParameters;
List<DartType> parameterTypes = element.type.typeArguments;
@@ -5364,6 +5369,9 @@
if (identical(enclosingElement, _enclosingClass)) {
return;
}
+ if (identical(enclosingElement, _enclosingEnum)) {
+ return;
+ }
if (enclosingElement is! ClassElement) {
return;
}
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 04f9153..b23d188 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -77,6 +77,12 @@
ClassElementImpl _enclosingClass;
/**
+ * The enum containing the AST nodes being visited, or `null` if we are not
+ * in the scope of an enum.
+ */
+ EnumElementImpl _enclosingEnum;
+
+ /**
* The parameter containing the AST nodes being visited, or `null` if we are not in the
* scope of a parameter.
*/
@@ -214,7 +220,7 @@
@override
visitEnumConstantDeclaration(EnumConstantDeclaration node) {
String name = node.name.name;
- FieldElement element = _findElement(_enclosingClass.fields, name);
+ FieldElement element = _findElement(_enclosingEnum.fields, name);
_processElement(element);
}
@@ -222,7 +228,7 @@
visitEnumDeclaration(EnumDeclaration node) {
String name = node.name.name;
ClassElement element = _findElement(_enclosingUnit.enums, name);
- _enclosingClass = element;
+ _enclosingEnum = element;
_processElement(element);
_assertTrue(element.isEnum);
super.visitEnumDeclaration(node);
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index f63edfa..c90928f 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -216,16 +216,19 @@
8,
(Parser target, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) => target
._parseConstructor(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)),
- 'parseConstructorFieldInitializer_0': new MethodTrampoline(
- 0, (Parser target) => target._parseConstructorFieldInitializer()),
+ 'parseConstructorFieldInitializer_1': new MethodTrampoline(1,
+ (Parser target, arg0) => target._parseConstructorFieldInitializer(arg0)),
'parseContinueStatement_0': new MethodTrampoline(
0, (Parser target) => target._parseContinueStatement()),
'parseDirective_1': new MethodTrampoline(
1, (Parser target, arg0) => target._parseDirective(arg0)),
'parseDirectives_0':
new MethodTrampoline(0, (Parser target) => target._parseDirectives()),
- 'parseDocumentationComment_0': new MethodTrampoline(
- 0, (Parser target) => target._parseDocumentationComment()),
+ 'parseDocumentationComment_0': new MethodTrampoline(0, (Parser target) {
+ List<DocumentationCommentToken> tokens =
+ target._parseDocumentationCommentTokens();
+ return target._parseDocumentationComment(tokens);
+ }),
'parseDoStatement_0':
new MethodTrampoline(0, (Parser target) => target._parseDoStatement()),
'parseDottedName_0':
@@ -320,13 +323,15 @@
'parseOptionalReturnType_0': new MethodTrampoline(
0, (Parser target) => target._parseOptionalReturnType()),
'parsePartDirective_1': new MethodTrampoline(
- 1, (Parser target, arg0) => target._parsePartDirective(arg0)),
+ 1, (Parser target, arg0) => target._parsePartOrPartOfDirective(arg0)),
'parsePostfixExpression_0': new MethodTrampoline(
0, (Parser target) => target._parsePostfixExpression()),
'parsePrimaryExpression_0': new MethodTrampoline(
0, (Parser target) => target._parsePrimaryExpression()),
- 'parseRedirectingConstructorInvocation_0': new MethodTrampoline(
- 0, (Parser target) => target._parseRedirectingConstructorInvocation()),
+ 'parseRedirectingConstructorInvocation_1': new MethodTrampoline(
+ 1,
+ (Parser target, arg0) =>
+ target._parseRedirectingConstructorInvocation(arg0)),
'parseRelationalExpression_0': new MethodTrampoline(
0, (Parser target) => target._parseRelationalExpression()),
'parseRethrowExpression_0': new MethodTrampoline(
@@ -493,7 +498,7 @@
final Comment comment;
/**
- * The metadata that was parsed.
+ * The metadata that was parsed, or `null` if none was given.
*/
final List<Annotation> metadata;
@@ -501,6 +506,11 @@
* Initialize a newly created holder with the given [comment] and [metadata].
*/
CommentAndMetadata(this.comment, this.metadata);
+
+ /**
+ * Return `true` if some metadata was parsed.
+ */
+ bool get hasMetadata => metadata != null && metadata.isNotEmpty;
}
/**
@@ -2147,7 +2157,7 @@
/**
* A flag indicating whether the parser is currently in a function body marked
- * as being 'async'.
+ * (by a star) as being a generator.
*/
bool _inGenerator = false;
@@ -2163,7 +2173,7 @@
/**
* A flag indicating whether the parser is currently in a constructor field
- * initializer, with no intervening parens, braces, or brackets.
+ * initializer, with no intervening parentheses, braces, or brackets.
*/
bool _inInitializer = false;
@@ -2179,14 +2189,16 @@
bool parseGenericMethodComments = false;
/**
- * Initialize a newly created parser to parse the content of the given
- * [_source] and to report any errors that are found to the given
- * [_errorListener].
+ * Initialize a newly created parser to parse tokens in the given [_source]
+ * and to report any errors that are found to the given [_errorListener].
*/
Parser(this._source, this._errorListener);
- void set currentToken(Token currentToken) {
- this._currentToken = currentToken;
+ /**
+ * Set the token with which the parse is to begin to the given [token].
+ */
+ void set currentToken(Token token) {
+ this._currentToken = token;
}
/**
@@ -2195,6 +2207,7 @@
* parameters, followed by a left-parenthesis. This is used by
* [_parseTypeAlias] to determine whether or not to parse a return type.
*/
+ @deprecated
bool get hasReturnTypeInTypeAlias {
Token next = _skipReturnType(_currentToken);
if (next == null) {
@@ -2229,19 +2242,20 @@
*/
Token getAndAdvance() {
Token token = _currentToken;
- _advance();
+ _currentToken = _currentToken.next;
return token;
}
/**
* Parse an annotation. Return the annotation that was parsed.
*
+ * This method assumes that the current token matches [TokenType.AT].
+ *
* annotation ::=
* '@' qualified ('.' identifier)? arguments?
- *
*/
Annotation parseAnnotation() {
- Token atSign = _expect(TokenType.AT);
+ Token atSign = getAndAdvance();
Identifier name = parsePrefixedIdentifier();
Token period = null;
SimpleIdentifier constructorName = null;
@@ -2267,6 +2281,9 @@
* label expression
*/
Expression parseArgument() {
+ // TODO(brianwilkerson) Consider returning a wrapper indicating whether the
+ // expression is a named expression in order to remove the 'is' check in
+ // 'parseArgumentList'.
//
// Both namedArgument and expression can start with an identifier, but only
// namedArgument can have an identifier followed by a colon.
@@ -2281,6 +2298,8 @@
/**
* Parse a list of arguments. Return the argument list that was parsed.
*
+ * This method assumes that the current token matches [TokenType.OPEN_PAREN].
+ *
* arguments ::=
* '(' argumentList? ')'
*
@@ -2289,10 +2308,9 @@
* | expressionList (',' namedArgument)*
*/
ArgumentList parseArgumentList() {
- Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
- List<Expression> arguments = new List<Expression>();
+ Token leftParenthesis = getAndAdvance();
if (_matches(TokenType.CLOSE_PAREN)) {
- return new ArgumentList(leftParenthesis, arguments, getAndAdvance());
+ return new ArgumentList(leftParenthesis, null, getAndAdvance());
}
//
// Even though unnamed arguments must all appear before any named arguments,
@@ -2302,30 +2320,30 @@
_inInitializer = false;
try {
Expression argument = parseArgument();
- arguments.add(argument);
+ List<Expression> arguments = <Expression>[argument];
bool foundNamedArgument = argument is NamedExpression;
bool generatedError = false;
while (_optional(TokenType.COMMA)) {
argument = parseArgument();
arguments.add(argument);
- if (foundNamedArgument) {
- bool blankArgument =
- argument is SimpleIdentifier && argument.name.isEmpty;
- if (!generatedError &&
- !(argument is NamedExpression && !blankArgument)) {
- // Report the error, once, but allow the arguments to be in any
- // order in the AST.
- _reportErrorForCurrentToken(
- ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT);
- generatedError = true;
- }
- } else if (argument is NamedExpression) {
+ if (argument is NamedExpression) {
foundNamedArgument = true;
+ } else if (foundNamedArgument) {
+ if (!generatedError) {
+ if (!argument.isSynthetic) {
+ // Report the error, once, but allow the arguments to be in any
+ // order in the AST.
+ _reportErrorForCurrentToken(
+ ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT);
+ generatedError = true;
+ }
+ }
}
}
- // TODO(brianwilkerson) Recovery: Look at the left parenthesis to see
- // whether there is a matching right parenthesis. If there is, then we're
- // more likely missing a comma and should go back to parsing arguments.
+ // Recovery: If the next token is not a right parenthesis, look at the
+ // left parenthesis to see whether there is a matching right parenthesis.
+ // If there is, then we're more likely missing a comma and should go back
+ // to parsing arguments.
Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
return new ArgumentList(leftParenthesis, arguments, rightParenthesis);
} finally {
@@ -2343,16 +2361,15 @@
*/
Expression parseBitwiseOrExpression() {
Expression expression;
- if (_matchesKeyword(Keyword.SUPER) &&
- _tokenMatches(_peek(), TokenType.BAR)) {
+ if (_currentToken.keyword == Keyword.SUPER &&
+ _currentToken.next.type == TokenType.BAR) {
expression = new SuperExpression(getAndAdvance());
} else {
expression = _parseBitwiseXorExpression();
}
- while (_matches(TokenType.BAR)) {
- Token operator = getAndAdvance();
+ while (_currentToken.type == TokenType.BAR) {
expression = new BinaryExpression(
- expression, operator, _parseBitwiseXorExpression());
+ expression, getAndAdvance(), _parseBitwiseXorExpression());
}
return expression;
}
@@ -2360,27 +2377,37 @@
/**
* Parse a block. Return the block that was parsed.
*
+ * This method assumes that the current token matches
+ * [TokenType.OPEN_CURLY_BRACKET].
+ *
* block ::=
* '{' statements '}'
*/
Block parseBlock() {
- Token leftBracket = _expect(TokenType.OPEN_CURLY_BRACKET);
- List<Statement> statements = new List<Statement>();
+ bool isEndOfBlock() {
+ TokenType type = _currentToken.type;
+ return type == TokenType.EOF || type == TokenType.CLOSE_CURLY_BRACKET;
+ }
+
+ Token leftBracket = getAndAdvance();
+ List<Statement> statements = <Statement>[];
Token statementStart = _currentToken;
- while (
- !_matches(TokenType.EOF) && !_matches(TokenType.CLOSE_CURLY_BRACKET)) {
+ while (!isEndOfBlock()) {
Statement statement = parseStatement2();
- if (statement != null) {
- statements.add(statement);
- }
if (identical(_currentToken, statementStart)) {
// Ensure that we are making progress and report an error if we're not.
_reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken,
[_currentToken.lexeme]);
_advance();
+ } else if (statement != null) {
+ statements.add(statement);
}
statementStart = _currentToken;
}
+ // Recovery: If the next token is not a right curly bracket, look at the
+ // left curly bracket to see whether there is a matching right bracket. If
+ // there is, then we're more likely missing a semi-colon and should go back
+ // to parsing statements.
Token rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET);
return new Block(leftBracket, statements, rightBracket);
}
@@ -2397,21 +2424,25 @@
ClassMember parseClassMember(String className) {
CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata();
Modifiers modifiers = _parseModifiers();
- if (_matchesKeyword(Keyword.VOID)) {
- TypeName returnType = parseReturnType();
- if (_matchesKeyword(Keyword.GET) && _tokenMatchesIdentifier(_peek())) {
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.VOID) {
+ TypeName returnType =
+ new TypeName(new SimpleIdentifier(getAndAdvance()), null);
+ keyword = _currentToken.keyword;
+ Token next = _peek();
+ bool isFollowedByIdentifier = _tokenMatchesIdentifier(next);
+ if (keyword == Keyword.GET && isFollowedByIdentifier) {
_validateModifiersForGetterOrSetterOrMethod(modifiers);
return _parseGetter(commentAndMetadata, modifiers.externalKeyword,
modifiers.staticKeyword, returnType);
- } else if (_matchesKeyword(Keyword.SET) &&
- _tokenMatchesIdentifier(_peek())) {
+ } else if (keyword == Keyword.SET && isFollowedByIdentifier) {
_validateModifiersForGetterOrSetterOrMethod(modifiers);
return _parseSetter(commentAndMetadata, modifiers.externalKeyword,
modifiers.staticKeyword, returnType);
- } else if (_matchesKeyword(Keyword.OPERATOR) && _isOperator(_peek())) {
+ } else if (keyword == Keyword.OPERATOR && _isOperator(next)) {
_validateModifiersForOperator(modifiers);
- return _parseOperator(
- commentAndMetadata, modifiers.externalKeyword, returnType);
+ return _parseOperatorAfterKeyword(commentAndMetadata,
+ modifiers.externalKeyword, returnType, getAndAdvance());
} else if (_matchesIdentifier() &&
_peek().matchesAny(const <TokenType>[
TokenType.OPEN_PAREN,
@@ -2456,20 +2487,21 @@
ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken);
return null;
}
- } else if (_matchesKeyword(Keyword.GET) &&
- _tokenMatchesIdentifier(_peek())) {
+ }
+ Token next = _peek();
+ bool isFollowedByIdentifier = _tokenMatchesIdentifier(next);
+ if (keyword == Keyword.GET && isFollowedByIdentifier) {
_validateModifiersForGetterOrSetterOrMethod(modifiers);
return _parseGetter(commentAndMetadata, modifiers.externalKeyword,
modifiers.staticKeyword, null);
- } else if (_matchesKeyword(Keyword.SET) &&
- _tokenMatchesIdentifier(_peek())) {
+ } else if (keyword == Keyword.SET && isFollowedByIdentifier) {
_validateModifiersForGetterOrSetterOrMethod(modifiers);
return _parseSetter(commentAndMetadata, modifiers.externalKeyword,
modifiers.staticKeyword, null);
- } else if (_matchesKeyword(Keyword.OPERATOR) && _isOperator(_peek())) {
+ } else if (keyword == Keyword.OPERATOR && _isOperator(next)) {
_validateModifiersForOperator(modifiers);
- return _parseOperator(
- commentAndMetadata, modifiers.externalKeyword, null);
+ return _parseOperatorAfterKeyword(
+ commentAndMetadata, modifiers.externalKeyword, null, getAndAdvance());
} else if (!_matchesIdentifier()) {
//
// Recover from an error.
@@ -2514,9 +2546,9 @@
// We appear to have found an incomplete field declaration.
//
_reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER);
- List<VariableDeclaration> variables = new List<VariableDeclaration>();
- variables.add(
- new VariableDeclaration(_createSyntheticIdentifier(), null, null));
+ VariableDeclaration variable =
+ new VariableDeclaration(_createSyntheticIdentifier(), null, null);
+ List<VariableDeclaration> variables = <VariableDeclaration>[variable];
return new FieldDeclaration(
commentAndMetadata.comment,
commentAndMetadata.metadata,
@@ -2527,7 +2559,7 @@
_reportErrorForToken(
ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken);
if (commentAndMetadata.comment != null ||
- !commentAndMetadata.metadata.isEmpty) {
+ commentAndMetadata.hasMetadata) {
//
// We appear to have found an incomplete declaration at the end of the
// class. At this point it consists of a metadata, which we don't want
@@ -2549,7 +2581,7 @@
new EmptyFunctionBody(_createSyntheticToken(TokenType.SEMICOLON)));
}
return null;
- } else if (_tokenMatches(_peek(), TokenType.PERIOD) &&
+ } else if (_tokenMatches(next, TokenType.PERIOD) &&
_tokenMatchesIdentifier(_peekAt(2)) &&
_tokenMatches(_peekAt(3), TokenType.OPEN_PAREN)) {
return _parseConstructor(
@@ -2561,7 +2593,7 @@
getAndAdvance(),
parseSimpleIdentifier(isDeclaration: true),
parseFormalParameterList());
- } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
+ } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
TypeName returnType = _parseOptionalTypeNameComment();
SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true);
TypeParameterList typeParameters = _parseGenericCommentTypeParameters();
@@ -2589,7 +2621,7 @@
methodName,
typeParameters,
parameters);
- } else if (_peek().matchesAny(const <TokenType>[
+ } else if (next.matchesAny(const <TokenType>[
TokenType.EQ,
TokenType.COMMA,
TokenType.SEMICOLON
@@ -2602,7 +2634,7 @@
}
return _parseInitializedIdentifierList(commentAndMetadata,
modifiers.staticKeyword, _validateModifiersForField(modifiers), null);
- } else if (_matchesKeyword(Keyword.TYPEDEF)) {
+ } else if (keyword == Keyword.TYPEDEF) {
_reportErrorForCurrentToken(ParserErrorCode.TYPEDEF_IN_CLASS);
// TODO(brianwilkerson) We don't currently have any way to capture the
// function type alias that was parsed.
@@ -2615,20 +2647,22 @@
modifiers.externalKeyword, modifiers.staticKeyword, null);
}
}
- TypeName type = parseTypeName();
- if (_matchesKeyword(Keyword.GET) && _tokenMatchesIdentifier(_peek())) {
+ TypeName type = _parseTypeNameAfterIdentifier();
+ keyword = _currentToken.keyword;
+ next = _peek();
+ isFollowedByIdentifier = _tokenMatchesIdentifier(next);
+ if (keyword == Keyword.GET && isFollowedByIdentifier) {
_validateModifiersForGetterOrSetterOrMethod(modifiers);
return _parseGetter(commentAndMetadata, modifiers.externalKeyword,
modifiers.staticKeyword, type);
- } else if (_matchesKeyword(Keyword.SET) &&
- _tokenMatchesIdentifier(_peek())) {
+ } else if (keyword == Keyword.SET && isFollowedByIdentifier) {
_validateModifiersForGetterOrSetterOrMethod(modifiers);
return _parseSetter(commentAndMetadata, modifiers.externalKeyword,
modifiers.staticKeyword, type);
- } else if (_matchesKeyword(Keyword.OPERATOR) && _isOperator(_peek())) {
+ } else if (keyword == Keyword.OPERATOR && _isOperator(next)) {
_validateModifiersForOperator(modifiers);
- return _parseOperator(
- commentAndMetadata, modifiers.externalKeyword, type);
+ return _parseOperatorAfterKeyword(
+ commentAndMetadata, modifiers.externalKeyword, type, getAndAdvance());
} else if (!_matchesIdentifier()) {
if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
//
@@ -2668,8 +2702,9 @@
} finally {
_unlockErrorListener();
}
- } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
- SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true);
+ } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
+ SimpleIdentifier methodName =
+ _parseSimpleIdentifierUnchecked(isDeclaration: true);
TypeParameterList typeParameters = _parseGenericCommentTypeParameters();
FormalParameterList parameters = parseFormalParameterList();
if (methodName.name == className) {
@@ -2694,10 +2729,10 @@
methodName,
typeParameters,
parameters);
- } else if (parseGenericMethods && _tokenMatches(_peek(), TokenType.LT)) {
+ } else if (parseGenericMethods && _tokenMatches(next, TokenType.LT)) {
return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
modifiers.externalKeyword, modifiers.staticKeyword, type);
- } else if (_tokenMatches(_peek(), TokenType.OPEN_CURLY_BRACKET)) {
+ } else if (_tokenMatches(next, TokenType.OPEN_CURLY_BRACKET)) {
// We have found "TypeName identifier {", and are guessing that this is a
// getter without the keyword 'get'.
_validateModifiersForGetterOrSetterOrMethod(modifiers);
@@ -2720,14 +2755,10 @@
* | 'hide' identifier (',' identifier)*
*/
Combinator parseCombinator() {
- if (_matchesString(_SHOW) || _matchesString(_HIDE)) {
- Token keyword = getAndAdvance();
- List<SimpleIdentifier> names = _parseIdentifierList();
- if (keyword.lexeme == _SHOW) {
- return new ShowCombinator(keyword, names);
- } else {
- return new HideCombinator(keyword, names);
- }
+ if (_matchesString(_SHOW)) {
+ return new ShowCombinator(getAndAdvance(), _parseIdentifierList());
+ } else if (_matchesString(_HIDE)) {
+ return new HideCombinator(getAndAdvance(), _parseIdentifierList());
}
return null;
}
@@ -2773,70 +2804,72 @@
bool partOfDirectiveFound = false;
bool partDirectiveFound = false;
bool directiveFoundAfterDeclaration = false;
- List<Directive> directives = new List<Directive>();
- List<CompilationUnitMember> declarations =
- new List<CompilationUnitMember>();
+ List<Directive> directives = <Directive>[];
+ List<CompilationUnitMember> declarations = <CompilationUnitMember>[];
Token memberStart = _currentToken;
- while (!_matches(TokenType.EOF)) {
+ TokenType type = _currentToken.type;
+ while (type != TokenType.EOF) {
CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata();
- if ((_matchesKeyword(Keyword.IMPORT) ||
- _matchesKeyword(Keyword.EXPORT) ||
- _matchesKeyword(Keyword.LIBRARY) ||
- _matchesKeyword(Keyword.PART)) &&
- !_tokenMatches(_peek(), TokenType.PERIOD) &&
- !_tokenMatches(_peek(), TokenType.LT) &&
- !_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
- Directive directive = _parseDirective(commentAndMetadata);
+ Keyword keyword = _currentToken.keyword;
+ TokenType nextType = _currentToken.next.type;
+ if ((keyword == Keyword.IMPORT ||
+ keyword == Keyword.EXPORT ||
+ keyword == Keyword.LIBRARY ||
+ keyword == Keyword.PART) &&
+ nextType != TokenType.PERIOD &&
+ nextType != TokenType.LT &&
+ nextType != TokenType.OPEN_PAREN) {
+ Directive parseDirective() {
+ if (keyword == Keyword.IMPORT) {
+ if (partDirectiveFound) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE);
+ }
+ return _parseImportDirective(commentAndMetadata);
+ } else if (keyword == Keyword.EXPORT) {
+ if (partDirectiveFound) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE);
+ }
+ return _parseExportDirective(commentAndMetadata);
+ } else if (keyword == Keyword.LIBRARY) {
+ if (libraryDirectiveFound) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES);
+ } else {
+ if (directives.length > 0) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST);
+ }
+ libraryDirectiveFound = true;
+ }
+ return _parseLibraryDirective(commentAndMetadata);
+ } else if (keyword == Keyword.PART) {
+ if (_tokenMatchesString(_peek(), _OF)) {
+ partOfDirectiveFound = true;
+ return _parsePartOfDirective(commentAndMetadata);
+ } else {
+ partDirectiveFound = true;
+ return _parsePartDirective(commentAndMetadata);
+ }
+ } else {
+ // Internal error: this method should not have been invoked if the
+ // current token was something other than one of the above.
+ throw new IllegalStateException(
+ "parseDirective invoked in an invalid state (currentToken = $_currentToken)");
+ }
+ }
+ Directive directive = parseDirective();
if (declarations.length > 0 && !directiveFoundAfterDeclaration) {
_reportErrorForToken(ParserErrorCode.DIRECTIVE_AFTER_DECLARATION,
directive.beginToken);
directiveFoundAfterDeclaration = true;
}
- if (directive is LibraryDirective) {
- if (libraryDirectiveFound) {
- _reportErrorForCurrentToken(
- ParserErrorCode.MULTIPLE_LIBRARY_DIRECTIVES);
- } else {
- if (directives.length > 0) {
- _reportErrorForToken(ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST,
- directive.libraryKeyword);
- }
- libraryDirectiveFound = true;
- }
- } else if (directive is PartDirective) {
- partDirectiveFound = true;
- } else if (partDirectiveFound) {
- if (directive is ExportDirective) {
- _reportErrorForToken(
- ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE,
- directive.keyword);
- } else if (directive is ImportDirective) {
- _reportErrorForToken(
- ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE,
- directive.keyword);
- }
- }
- if (directive is PartOfDirective) {
- if (partOfDirectiveFound) {
- _reportErrorForCurrentToken(
- ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES);
- } else {
- int directiveCount = directives.length;
- for (int i = 0; i < directiveCount; i++) {
- _reportErrorForToken(
- ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART,
- directives[i].keyword);
- }
- partOfDirectiveFound = true;
- }
- } else {
- if (partOfDirectiveFound) {
- _reportErrorForToken(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART,
- directive.keyword);
- }
- }
directives.add(directive);
- } else if (_matches(TokenType.SEMICOLON)) {
+ } else if (type == TokenType.SEMICOLON) {
+ // TODO(brianwilkerson) Consider moving this error detection into
+ // _parseCompilationUnitMember (in the places where EXPECTED_EXECUTABLE
+ // is being generated).
_reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken,
[_currentToken.lexeme]);
_advance();
@@ -2857,6 +2890,38 @@
}
}
memberStart = _currentToken;
+ type = _currentToken.type;
+ }
+ if (partOfDirectiveFound && directives.length > 1) {
+ // TODO(brianwilkerson) Improve error reporting when both a library and
+ // part-of directive are found.
+// if (libraryDirectiveFound) {
+// int directiveCount = directives.length;
+// for (int i = 0; i < directiveCount; i++) {
+// Directive directive = directives[i];
+// if (directive is PartOfDirective) {
+// _reportErrorForToken(
+// ParserErrorCode.PART_OF_IN_LIBRARY, directive.partKeyword);
+// }
+// }
+// } else {
+ bool firstPartOf = true;
+ int directiveCount = directives.length;
+ for (int i = 0; i < directiveCount; i++) {
+ Directive directive = directives[i];
+ if (directive is PartOfDirective) {
+ if (firstPartOf) {
+ firstPartOf = false;
+ } else {
+ _reportErrorForToken(ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES,
+ directive.partKeyword);
+ }
+ } else {
+ _reportErrorForToken(ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART,
+ directives[i].keyword);
+ }
+// }
+ }
}
return new CompilationUnit(
firstToken, scriptTag, directives, declarations, _currentToken);
@@ -2871,7 +2936,7 @@
*/
Expression parseConditionalExpression() {
Expression condition = parseIfNullExpression();
- if (!_matches(TokenType.QUESTION)) {
+ if (_currentToken.type != TokenType.QUESTION) {
return condition;
}
Token question = getAndAdvance();
@@ -2932,9 +2997,10 @@
* | throwExpression
*/
Expression parseExpression2() {
- if (_matchesKeyword(Keyword.THROW)) {
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.THROW) {
return _parseThrowExpression();
- } else if (_matchesKeyword(Keyword.RETHROW)) {
+ } else if (keyword == Keyword.RETHROW) {
// TODO(brianwilkerson) Rethrow is a statement again.
return _parseRethrowExpression();
}
@@ -2945,18 +3011,17 @@
// grammar after making that determination.
//
Expression expression = parseConditionalExpression();
- TokenType tokenType = _currentToken.type;
- if (tokenType == TokenType.PERIOD_PERIOD) {
- List<Expression> cascadeSections = new List<Expression>();
- while (tokenType == TokenType.PERIOD_PERIOD) {
+ TokenType type = _currentToken.type;
+ if (type == TokenType.PERIOD_PERIOD) {
+ List<Expression> cascadeSections = <Expression>[];
+ do {
Expression section = _parseCascadeSection();
if (section != null) {
cascadeSections.add(section);
}
- tokenType = _currentToken.type;
- }
+ } while (_currentToken.type == TokenType.PERIOD_PERIOD);
return new CascadeExpression(expression, cascadeSections);
- } else if (tokenType.isAssignmentOperator) {
+ } else if (type.isAssignmentOperator) {
Token operator = getAndAdvance();
_ensureAssignable(expression);
return new AssignmentExpression(expression, operator, parseExpression2());
@@ -2999,11 +3064,13 @@
* Parse a class extends clause. Return the class extends clause that was
* parsed.
*
+ * This method assumes that the current token matches `Keyword.EXTENDS`.
+ *
* classExtendsClause ::=
* 'extends' type
*/
ExtendsClause parseExtendsClause() {
- Token keyword = _expectKeyword(Keyword.EXTENDS);
+ Token keyword = getAndAdvance();
TypeName superclass = parseTypeName();
return new ExtendsClause(keyword, superclass);
}
@@ -3031,145 +3098,16 @@
* '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
*/
FormalParameterList parseFormalParameterList() {
- Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
- if (_matches(TokenType.CLOSE_PAREN)) {
- return new FormalParameterList(
- leftParenthesis, null, null, null, getAndAdvance());
+ if (_matches(TokenType.OPEN_PAREN)) {
+ return _parseFormalParameterListUnchecked();
}
- //
- // Even though it is invalid to have default parameters outside of brackets,
- // required parameters inside of brackets, or multiple groups of default and
- // named parameters, we allow all of these cases so that we can recover
- // better.
- //
- List<FormalParameter> parameters = new List<FormalParameter>();
- Token leftSquareBracket = null;
- Token rightSquareBracket = null;
- Token leftCurlyBracket = null;
- Token rightCurlyBracket = null;
- ParameterKind kind = ParameterKind.REQUIRED;
- bool firstParameter = true;
- bool reportedMultiplePositionalGroups = false;
- bool reportedMultipleNamedGroups = false;
- bool reportedMixedGroups = false;
- bool wasOptionalParameter = false;
- Token initialToken = null;
- do {
- if (firstParameter) {
- firstParameter = false;
- } else if (!_optional(TokenType.COMMA)) {
- // TODO(brianwilkerson) The token is wrong, we need to recover from this
- // case.
- if (_getEndToken(leftParenthesis) != null) {
- _reportErrorForCurrentToken(
- ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]);
- } else {
- _reportErrorForToken(ParserErrorCode.MISSING_CLOSING_PARENTHESIS,
- _currentToken.previous);
- break;
- }
- }
- initialToken = _currentToken;
- //
- // Handle the beginning of parameter groups.
- //
- if (_matches(TokenType.OPEN_SQUARE_BRACKET)) {
- wasOptionalParameter = true;
- if (leftSquareBracket != null && !reportedMultiplePositionalGroups) {
- _reportErrorForCurrentToken(
- ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS);
- reportedMultiplePositionalGroups = true;
- }
- if (leftCurlyBracket != null && !reportedMixedGroups) {
- _reportErrorForCurrentToken(ParserErrorCode.MIXED_PARAMETER_GROUPS);
- reportedMixedGroups = true;
- }
- leftSquareBracket = getAndAdvance();
- kind = ParameterKind.POSITIONAL;
- } else if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
- wasOptionalParameter = true;
- if (leftCurlyBracket != null && !reportedMultipleNamedGroups) {
- _reportErrorForCurrentToken(
- ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS);
- reportedMultipleNamedGroups = true;
- }
- if (leftSquareBracket != null && !reportedMixedGroups) {
- _reportErrorForCurrentToken(ParserErrorCode.MIXED_PARAMETER_GROUPS);
- reportedMixedGroups = true;
- }
- leftCurlyBracket = getAndAdvance();
- kind = ParameterKind.NAMED;
- }
- //
- // Parse and record the parameter.
- //
- FormalParameter parameter = _parseFormalParameter(kind);
- parameters.add(parameter);
- if (kind == ParameterKind.REQUIRED && wasOptionalParameter) {
- _reportErrorForNode(
- ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS, parameter);
- }
- //
- // Handle the end of parameter groups.
- //
- // TODO(brianwilkerson) Improve the detection and reporting of missing and
- // mismatched delimiters.
- if (_matches(TokenType.CLOSE_SQUARE_BRACKET)) {
- rightSquareBracket = getAndAdvance();
- if (leftSquareBracket == null) {
- if (leftCurlyBracket != null) {
- _reportErrorForCurrentToken(
- ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]);
- rightCurlyBracket = rightSquareBracket;
- rightSquareBracket = null;
- } else {
- _reportErrorForCurrentToken(
- ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
- ["["]);
- }
- }
- kind = ParameterKind.REQUIRED;
- } else if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
- rightCurlyBracket = getAndAdvance();
- if (leftCurlyBracket == null) {
- if (leftSquareBracket != null) {
- _reportErrorForCurrentToken(
- ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, ["]"]);
- rightSquareBracket = rightCurlyBracket;
- rightCurlyBracket = null;
- } else {
- _reportErrorForCurrentToken(
- ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
- ["{"]);
- }
- }
- kind = ParameterKind.REQUIRED;
- }
- } while (!_matches(TokenType.CLOSE_PAREN) &&
- !identical(initialToken, _currentToken));
- Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
- //
- // Check that the groups were closed correctly.
- //
- if (leftSquareBracket != null && rightSquareBracket == null) {
- _reportErrorForCurrentToken(
- ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["]"]);
- }
- if (leftCurlyBracket != null && rightCurlyBracket == null) {
- _reportErrorForCurrentToken(
- ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]);
- }
- //
- // Build the parameter list.
- //
- if (leftSquareBracket == null) {
- leftSquareBracket = leftCurlyBracket;
- }
- if (rightSquareBracket == null) {
- rightSquareBracket = rightCurlyBracket;
- }
- return new FormalParameterList(leftParenthesis, parameters,
- leftSquareBracket, rightSquareBracket, rightParenthesis);
+ // TODO(brianwilkerson) Improve the error message.
+ _reportErrorForCurrentToken(
+ ParserErrorCode.EXPECTED_TOKEN, [TokenType.OPEN_PAREN.lexeme]);
+ // Recovery: Check for an unmatched closing paren and parse parameters until
+ // it is reached.
+ return _parseFormalParameterListAfterParen(
+ _createSyntheticToken(TokenType.OPEN_PAREN));
}
/**
@@ -3196,10 +3134,9 @@
*/
Expression parseIfNullExpression() {
Expression expression = parseLogicalOrExpression();
- while (_matches(TokenType.QUESTION_QUESTION)) {
- Token operator = getAndAdvance();
+ while (_currentToken.type == TokenType.QUESTION_QUESTION) {
expression = new BinaryExpression(
- expression, operator, parseLogicalOrExpression());
+ expression, getAndAdvance(), parseLogicalOrExpression());
}
return expression;
}
@@ -3207,12 +3144,14 @@
/**
* Parse an implements clause. Return the implements clause that was parsed.
*
+ * This method assumes that the current token matches `Keyword.IMPLEMENTS`.
+ *
* implementsClause ::=
* 'implements' type (',' type)*
*/
ImplementsClause parseImplementsClause() {
- Token keyword = _expectKeyword(Keyword.IMPLEMENTS);
- List<TypeName> interfaces = new List<TypeName>();
+ Token keyword = getAndAdvance();
+ List<TypeName> interfaces = <TypeName>[];
interfaces.add(parseTypeName());
while (_optional(TokenType.COMMA)) {
interfaces.add(parseTypeName());
@@ -3223,13 +3162,16 @@
/**
* Parse a label. Return the label that was parsed.
*
+ * This method assumes that the current token matches an identifier and that
+ * the following token matches `TokenType.COLON`.
+ *
* label ::=
* identifier ':'
*/
Label parseLabel({bool isDeclaration: false}) {
SimpleIdentifier label =
- parseSimpleIdentifier(isDeclaration: isDeclaration);
- Token colon = _expect(TokenType.COLON);
+ _parseSimpleIdentifierUnchecked(isDeclaration: isDeclaration);
+ Token colon = getAndAdvance();
return new Label(label, colon);
}
@@ -3240,10 +3182,9 @@
* identifier ('.' identifier)*
*/
LibraryIdentifier parseLibraryIdentifier() {
- List<SimpleIdentifier> components = new List<SimpleIdentifier>();
+ List<SimpleIdentifier> components = <SimpleIdentifier>[];
components.add(parseSimpleIdentifier());
- while (_matches(TokenType.PERIOD)) {
- _advance();
+ while (_optional(TokenType.PERIOD)) {
components.add(parseSimpleIdentifier());
}
return new LibraryIdentifier(components);
@@ -3258,10 +3199,9 @@
*/
Expression parseLogicalOrExpression() {
Expression expression = _parseLogicalAndExpression();
- while (_matches(TokenType.BAR_BAR)) {
- Token operator = getAndAdvance();
+ while (_currentToken.type == TokenType.BAR_BAR) {
expression = new BinaryExpression(
- expression, operator, _parseLogicalAndExpression());
+ expression, getAndAdvance(), _parseLogicalAndExpression());
}
return expression;
}
@@ -3310,7 +3250,7 @@
SimpleIdentifier identifier = parseSimpleIdentifier();
TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
if (_matches(TokenType.OPEN_PAREN)) {
- FormalParameterList parameters = parseFormalParameterList();
+ FormalParameterList parameters = _parseFormalParameterListUnchecked();
if (thisKeyword == null) {
if (holder.keyword != null) {
_reportErrorForToken(
@@ -3381,13 +3321,7 @@
* identifier ('.' identifier)?
*/
Identifier parsePrefixedIdentifier() {
- SimpleIdentifier qualifier = parseSimpleIdentifier();
- if (!_matches(TokenType.PERIOD) || _injectGenericCommentTypeList()) {
- return qualifier;
- }
- Token period = getAndAdvance();
- SimpleIdentifier qualified = parseSimpleIdentifier();
- return new PrefixedIdentifier(qualifier, period, qualified);
+ return _parsePrefixedIdentifierAfterIdentifier(parseSimpleIdentifier());
}
/**
@@ -3398,7 +3332,7 @@
* | type
*/
TypeName parseReturnType() {
- if (_matchesKeyword(Keyword.VOID)) {
+ if (_currentToken.keyword == Keyword.VOID) {
return new TypeName(new SimpleIdentifier(getAndAdvance()), null);
} else {
return parseTypeName();
@@ -3413,14 +3347,7 @@
*/
SimpleIdentifier parseSimpleIdentifier({bool isDeclaration: false}) {
if (_matchesIdentifier()) {
- String lexeme = _currentToken.lexeme;
- if ((_inAsync || _inGenerator) &&
- (lexeme == 'async' || lexeme == 'await' || lexeme == 'yield')) {
- _reportErrorForCurrentToken(
- ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER);
- }
- return new SimpleIdentifier(getAndAdvance(),
- isDeclaration: isDeclaration);
+ return _parseSimpleIdentifierUnchecked(isDeclaration: isDeclaration);
}
_reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER);
return _createSyntheticIdentifier(isDeclaration: isDeclaration);
@@ -3444,7 +3371,7 @@
*/
Statement parseStatement2() {
List<Label> labels = null;
- while (_matchesIdentifier() && _tokenMatches(_peek(), TokenType.COLON)) {
+ while (_matchesIdentifier() && _currentToken.next.type == TokenType.COLON) {
Label label = parseLabel(isDeclaration: true);
if (labels == null) {
labels = <Label>[label];
@@ -3477,31 +3404,19 @@
* | SINGLE_LINE_STRING+
*/
StringLiteral parseStringLiteral() {
- List<StringLiteral> strings = new List<StringLiteral>();
- while (_matches(TokenType.STRING)) {
- Token string = getAndAdvance();
- if (_matches(TokenType.STRING_INTERPOLATION_EXPRESSION) ||
- _matches(TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
- strings.add(_parseStringInterpolation(string));
- } else {
- strings.add(new SimpleStringLiteral(
- string, _computeStringValue(string.lexeme, true, true)));
- }
+ if (_matches(TokenType.STRING)) {
+ return _parseStringLiteralUnchecked();
}
- if (strings.length < 1) {
- _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_STRING_LITERAL);
- return _createSyntheticStringLiteral();
- } else if (strings.length == 1) {
- return strings[0];
- } else {
- return new AdjacentStrings(strings);
- }
+ _reportErrorForCurrentToken(ParserErrorCode.EXPECTED_STRING_LITERAL);
+ return _createSyntheticStringLiteral();
}
/**
* Parse a list of type arguments. Return the type argument list that was
* parsed.
*
+ * This method assumes that the current token matches `TokenType.LT`.
+ *
* typeArguments ::=
* '<' typeList '>'
*
@@ -3509,9 +3424,8 @@
* type (',' type)*
*/
TypeArgumentList parseTypeArgumentList() {
- Token leftBracket = _expect(TokenType.LT);
- List<TypeName> arguments = new List<TypeName>();
- arguments.add(parseTypeName());
+ Token leftBracket = getAndAdvance();
+ List<TypeName> arguments = <TypeName>[parseTypeName()];
while (_optional(TokenType.COMMA)) {
arguments.add(parseTypeName());
}
@@ -3531,8 +3445,8 @@
// type to replace the real type name.
// TODO(jmesserly): this feels like a big hammer. Can we restrict it to
// only work inside generic methods?
- TypeName typeComment = _parseOptionalTypeNameComment();
- return typeComment ?? realType;
+ TypeName typeFromComment = _parseOptionalTypeNameComment();
+ return typeFromComment ?? realType;
}
/**
@@ -3558,13 +3472,14 @@
* Parse a list of type parameters. Return the list of type parameters that
* were parsed.
*
+ * This method assumes that the current token matches `TokenType.LT`.
+ *
* typeParameterList ::=
* '<' typeParameter (',' typeParameter)* '>'
*/
TypeParameterList parseTypeParameterList() {
- Token leftBracket = _expect(TokenType.LT);
- List<TypeParameter> typeParameters = new List<TypeParameter>();
- typeParameters.add(parseTypeParameter());
+ Token leftBracket = getAndAdvance();
+ List<TypeParameter> typeParameters = <TypeParameter>[parseTypeParameter()];
while (_optional(TokenType.COMMA)) {
typeParameters.add(parseTypeParameter());
}
@@ -3575,17 +3490,18 @@
/**
* Parse a with clause. Return the with clause that was parsed.
*
+ * This method assumes that the current token matches `Keyword.WITH`.
+ *
* withClause ::=
* 'with' typeName (',' typeName)*
*/
WithClause parseWithClause() {
- Token with2 = _expectKeyword(Keyword.WITH);
- List<TypeName> types = new List<TypeName>();
- types.add(parseTypeName());
+ Token withKeyword = getAndAdvance();
+ List<TypeName> types = <TypeName>[parseTypeName()];
while (_optional(TokenType.COMMA)) {
types.add(parseTypeName());
}
- return new WithClause(with2, types);
+ return new WithClause(withKeyword, types);
}
/**
@@ -3669,30 +3585,33 @@
* member.
*/
bool _couldBeStartOfCompilationUnitMember() {
- if ((_matchesKeyword(Keyword.IMPORT) ||
- _matchesKeyword(Keyword.EXPORT) ||
- _matchesKeyword(Keyword.LIBRARY) ||
- _matchesKeyword(Keyword.PART)) &&
- !_tokenMatches(_peek(), TokenType.PERIOD) &&
- !_tokenMatches(_peek(), TokenType.LT)) {
+ Keyword keyword = _currentToken.keyword;
+ Token next = _currentToken.next;
+ TokenType nextType = next.type;
+ if ((keyword == Keyword.IMPORT ||
+ keyword == Keyword.EXPORT ||
+ keyword == Keyword.LIBRARY ||
+ keyword == Keyword.PART) &&
+ nextType != TokenType.PERIOD &&
+ nextType != TokenType.LT) {
// This looks like the start of a directive
return true;
- } else if (_matchesKeyword(Keyword.CLASS)) {
+ } else if (keyword == Keyword.CLASS) {
// This looks like the start of a class definition
return true;
- } else if (_matchesKeyword(Keyword.TYPEDEF) &&
- !_tokenMatches(_peek(), TokenType.PERIOD) &&
- !_tokenMatches(_peek(), TokenType.LT)) {
+ } else if (keyword == Keyword.TYPEDEF &&
+ nextType != TokenType.PERIOD &&
+ nextType != TokenType.LT) {
// This looks like the start of a typedef
return true;
- } else if (_matchesKeyword(Keyword.VOID) ||
- ((_matchesKeyword(Keyword.GET) || _matchesKeyword(Keyword.SET)) &&
- _tokenMatchesIdentifier(_peek())) ||
- (_matchesKeyword(Keyword.OPERATOR) && _isOperator(_peek()))) {
+ } else if (keyword == Keyword.VOID ||
+ ((keyword == Keyword.GET || keyword == Keyword.SET) &&
+ _tokenMatchesIdentifier(next)) ||
+ (keyword == Keyword.OPERATOR && _isOperator(next))) {
// This looks like the start of a function
return true;
} else if (_matchesIdentifier()) {
- if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
+ if (nextType == TokenType.OPEN_PAREN) {
// This looks like the start of a function
return true;
}
@@ -3700,9 +3619,10 @@
if (token == null) {
return false;
}
- if (_matchesKeyword(Keyword.GET) ||
- _matchesKeyword(Keyword.SET) ||
- (_matchesKeyword(Keyword.OPERATOR) && _isOperator(_peek())) ||
+ // TODO(brianwilkerson) This looks wrong; should we be checking 'token'?
+ if (keyword == Keyword.GET ||
+ keyword == Keyword.SET ||
+ (keyword == Keyword.OPERATOR && _isOperator(next)) ||
_matchesIdentifier()) {
return true;
}
@@ -3872,7 +3792,7 @@
* should be treated as code blocks.
*/
List<List<int>> _getCodeBlockRanges(String comment) {
- List<List<int>> ranges = new List<List<int>>();
+ List<List<int>> ranges = <List<int>>[];
int length = comment.length;
if (length < 3) {
return ranges;
@@ -4015,7 +3935,8 @@
* function declaration.
*/
bool _isFunctionDeclaration() {
- if (_matchesKeyword(Keyword.VOID)) {
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.VOID) {
return true;
}
Token afterReturnType = _skipTypeName(_currentToken);
@@ -4038,20 +3959,20 @@
}
// It's possible that we have found a getter. While this isn't valid at this
// point we test for it in order to recover better.
- if (_matchesKeyword(Keyword.GET)) {
+ if (keyword == Keyword.GET) {
Token afterName = _skipSimpleIdentifier(_currentToken.next);
if (afterName == null) {
return false;
}
- return _tokenMatches(afterName, TokenType.FUNCTION) ||
- _tokenMatches(afterName, TokenType.OPEN_CURLY_BRACKET);
+ TokenType type = afterName.type;
+ return type == TokenType.FUNCTION || type == TokenType.OPEN_CURLY_BRACKET;
} else if (_tokenMatchesKeyword(afterReturnType, Keyword.GET)) {
Token afterName = _skipSimpleIdentifier(afterReturnType.next);
if (afterName == null) {
return false;
}
- return _tokenMatches(afterName, TokenType.FUNCTION) ||
- _tokenMatches(afterName, TokenType.OPEN_CURLY_BRACKET);
+ TokenType type = afterName.type;
+ return type == TokenType.FUNCTION || type == TokenType.OPEN_CURLY_BRACKET;
}
return false;
}
@@ -4114,12 +4035,13 @@
* identifier ('=' expression)?
*/
bool _isInitializedVariableDeclaration() {
- if (_matchesKeyword(Keyword.FINAL) || _matchesKeyword(Keyword.VAR)) {
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.FINAL || keyword == Keyword.VAR) {
// An expression cannot start with a keyword other than 'const',
// 'rethrow', or 'throw'.
return true;
}
- if (_matchesKeyword(Keyword.CONST)) {
+ if (keyword == Keyword.CONST) {
// Look to see whether we might be at the start of a list or map literal,
// otherwise this should be the start of a variable declaration.
return !_peek().matchesAny(const <TokenType>[
@@ -4156,7 +4078,7 @@
if (type == TokenType.EQ ||
type == TokenType.COMMA ||
type == TokenType.SEMICOLON ||
- _tokenMatchesKeyword(token, Keyword.IN)) {
+ token.keyword == Keyword.IN) {
return true;
}
// It is OK to parse as a variable declaration in these cases:
@@ -4178,6 +4100,8 @@
}
bool _isLikelyArgumentList() {
+ // Try to reduce the amount of lookahead required here before enabling
+ // generic methods.
if (_matches(TokenType.OPEN_PAREN)) {
return true;
}
@@ -4228,7 +4152,7 @@
if (!startToken.isOperator) {
return false;
}
- // Token "=" means that it is actually field initializer.
+ // Token "=" means that it is actually a field initializer.
if (startToken.type == TokenType.EQ) {
return false;
}
@@ -4372,7 +4296,7 @@
* should not be invoked with an argument value of [TokenType.GT].
*/
bool _optional(TokenType type) {
- if (_matches(type)) {
+ if (_currentToken.type == type) {
_advance();
return true;
}
@@ -4389,28 +4313,45 @@
*/
Expression _parseAdditiveExpression() {
Expression expression;
- if (_matchesKeyword(Keyword.SUPER) &&
+ if (_currentToken.keyword == Keyword.SUPER &&
_currentToken.next.type.isAdditiveOperator) {
expression = new SuperExpression(getAndAdvance());
} else {
expression = _parseMultiplicativeExpression();
}
while (_currentToken.type.isAdditiveOperator) {
- Token operator = getAndAdvance();
expression = new BinaryExpression(
- expression, operator, _parseMultiplicativeExpression());
+ expression, getAndAdvance(), _parseMultiplicativeExpression());
}
return expression;
}
/**
+ * Parse an argument list when we need to check for an open paren and recover
+ * when there isn't one. Return the argument list that was parsed.
+ */
+ ArgumentList _parseArgumentListChecked() {
+ if (_matches(TokenType.OPEN_PAREN)) {
+ return parseArgumentList();
+ }
+ _reportErrorForCurrentToken(
+ ParserErrorCode.EXPECTED_TOKEN, [TokenType.OPEN_PAREN.lexeme]);
+ // Recovery: Look to see whether there is a close paren that isn't matched
+ // to an open paren and if so parse the list of arguments as normal.
+ return new ArgumentList(_createSyntheticToken(TokenType.OPEN_PAREN), null,
+ _createSyntheticToken(TokenType.CLOSE_PAREN));
+ }
+
+ /**
* Parse an assert statement. Return the assert statement.
*
+ * This method assumes that the current token matches `Keyword.ASSERT`.
+ *
* assertStatement ::=
* 'assert' '(' conditionalExpression ')' ';'
*/
AssertStatement _parseAssertStatement() {
- Token keyword = _expectKeyword(Keyword.ASSERT);
+ Token keyword = getAndAdvance();
Token leftParen = _expect(TokenType.OPEN_PAREN);
Expression expression = parseExpression2();
if (expression is AssignmentExpression) {
@@ -4454,6 +4395,17 @@
new SuperExpression(getAndAdvance()), false,
allowConditional: false);
}
+ return _parseAssignableExpressionNotStartingWithSuper(primaryAllowed);
+ }
+
+ /**
+ * Parse an assignable expression given that the current token is not 'super'.
+ * The [primaryAllowed] is `true` if the expression is allowed to be a primary
+ * without any assignable selector. Return the assignable expression that was
+ * parsed.
+ */
+ Expression _parseAssignableExpressionNotStartingWithSuper(
+ bool primaryAllowed) {
//
// A primary expression can start with an identifier. We resolve the
// ambiguity by determining whether the primary consists of anything other
@@ -4523,7 +4475,8 @@
*/
Expression _parseAssignableSelector(Expression prefix, bool optional,
{bool allowConditional: true}) {
- if (_matches(TokenType.OPEN_SQUARE_BRACKET)) {
+ TokenType type = _currentToken.type;
+ if (type == TokenType.OPEN_SQUARE_BRACKET) {
Token leftBracket = getAndAdvance();
bool wasInInitializer = _inInitializer;
_inInitializer = false;
@@ -4535,27 +4488,32 @@
} finally {
_inInitializer = wasInInitializer;
}
- } else if (_matches(TokenType.PERIOD) ||
- _matches(TokenType.QUESTION_PERIOD)) {
- if (_matches(TokenType.QUESTION_PERIOD) && !allowConditional) {
- _reportErrorForCurrentToken(
- ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [_currentToken.lexeme]);
- }
- Token operator = getAndAdvance();
- return new PropertyAccess(prefix, operator, parseSimpleIdentifier());
} else {
- if (!optional) {
- // Report the missing selector.
- _reportErrorForCurrentToken(
- ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR);
+ bool isQuestionPeriod = type == TokenType.QUESTION_PERIOD;
+ if (type == TokenType.PERIOD || isQuestionPeriod) {
+ if (isQuestionPeriod && !allowConditional) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.INVALID_OPERATOR_FOR_SUPER,
+ [_currentToken.lexeme]);
+ }
+ Token operator = getAndAdvance();
+ return new PropertyAccess(prefix, operator, parseSimpleIdentifier());
+ } else {
+ if (!optional) {
+ // Report the missing selector.
+ _reportErrorForCurrentToken(
+ ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR);
+ }
+ return prefix;
}
- return prefix;
}
}
/**
* Parse a await expression. Return the await expression that was parsed.
*
+ * This method assumes that the current token matches `_AWAIT`.
+ *
* awaitExpression ::=
* 'await' unaryExpression
*/
@@ -4575,16 +4533,15 @@
*/
Expression _parseBitwiseAndExpression() {
Expression expression;
- if (_matchesKeyword(Keyword.SUPER) &&
- _tokenMatches(_peek(), TokenType.AMPERSAND)) {
+ if (_currentToken.keyword == Keyword.SUPER &&
+ _currentToken.next.type == TokenType.AMPERSAND) {
expression = new SuperExpression(getAndAdvance());
} else {
expression = _parseShiftExpression();
}
- while (_matches(TokenType.AMPERSAND)) {
- Token operator = getAndAdvance();
- expression =
- new BinaryExpression(expression, operator, _parseShiftExpression());
+ while (_currentToken.type == TokenType.AMPERSAND) {
+ expression = new BinaryExpression(
+ expression, getAndAdvance(), _parseShiftExpression());
}
return expression;
}
@@ -4599,31 +4556,52 @@
*/
Expression _parseBitwiseXorExpression() {
Expression expression;
- if (_matchesKeyword(Keyword.SUPER) &&
- _tokenMatches(_peek(), TokenType.CARET)) {
+ if (_currentToken.keyword == Keyword.SUPER &&
+ _currentToken.next.type == TokenType.CARET) {
expression = new SuperExpression(getAndAdvance());
} else {
expression = _parseBitwiseAndExpression();
}
- while (_matches(TokenType.CARET)) {
- Token operator = getAndAdvance();
+ while (_currentToken.type == TokenType.CARET) {
expression = new BinaryExpression(
- expression, operator, _parseBitwiseAndExpression());
+ expression, getAndAdvance(), _parseBitwiseAndExpression());
}
return expression;
}
/**
+ * Parse a block when we need to check for an open curly brace and recover
+ * when there isn't one. Return the block that was parsed.
+ *
+ * block ::=
+ * '{' statements '}'
+ */
+ Block _parseBlockChecked() {
+ if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
+ return parseBlock();
+ }
+ // TODO(brianwilkerson) Improve the error message.
+ _reportErrorForCurrentToken(
+ ParserErrorCode.EXPECTED_TOKEN, [TokenType.OPEN_CURLY_BRACKET.lexeme]);
+ // Recovery: Check for an unmatched closing curly bracket and parse
+ // statements until it is reached.
+ return new Block(_createSyntheticToken(TokenType.OPEN_CURLY_BRACKET), null,
+ _createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET));
+ }
+
+ /**
* Parse a break statement. Return the break statement that was parsed.
*
+ * This method assumes that the current token matches `Keyword.BREAK`.
+ *
* breakStatement ::=
* 'break' identifier? ';'
*/
Statement _parseBreakStatement() {
- Token breakKeyword = _expectKeyword(Keyword.BREAK);
+ Token breakKeyword = getAndAdvance();
SimpleIdentifier label = null;
if (_matchesIdentifier()) {
- label = parseSimpleIdentifier();
+ label = _parseSimpleIdentifierUnchecked();
}
if (!_inLoop && !_inSwitch && label == null) {
_reportErrorForToken(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, breakKeyword);
@@ -4636,6 +4614,9 @@
* Parse a cascade section. Return the expression representing the cascaded
* method invocation.
*
+ * This method assumes that the current token matches
+ * `TokenType.PERIOD_PERIOD`.
+ *
* cascadeSection ::=
* '..' (cascadeSelector typeArguments? arguments*)
* (assignableSelector typeArguments? arguments*)* cascadeAssignment?
@@ -4648,11 +4629,11 @@
* assignmentOperator expressionWithoutCascade
*/
Expression _parseCascadeSection() {
- Token period = _expect(TokenType.PERIOD_PERIOD);
+ Token period = getAndAdvance();
Expression expression = null;
SimpleIdentifier functionName = null;
if (_matchesIdentifier()) {
- functionName = parseSimpleIdentifier();
+ functionName = _parseSimpleIdentifierUnchecked();
} else if (_currentToken.type == TokenType.OPEN_SQUARE_BRACKET) {
Token leftBracket = getAndAdvance();
bool wasInInitializer = _inInitializer;
@@ -4674,7 +4655,7 @@
assert((expression == null && functionName != null) ||
(expression != null && functionName == null));
if (_isLikelyArgumentList()) {
- while (_isLikelyArgumentList()) {
+ do {
TypeArgumentList typeArguments = _parseOptionalTypeArguments();
if (functionName != null) {
expression = new MethodInvocation(expression, period, functionName,
@@ -4689,7 +4670,7 @@
expression = new FunctionExpressionInvocation(
expression, typeArguments, parseArgumentList());
}
- }
+ } while (_isLikelyArgumentList());
} else if (functionName != null) {
expression = new PropertyAccess(expression, period, functionName);
period = null;
@@ -4734,31 +4715,33 @@
* keyword 'abstract', or `null` if the keyword was not given. Return the
* class declaration that was parsed.
*
+ * This method assumes that the current token matches `Keyword.CLASS`.
+ *
* classDeclaration ::=
* metadata 'abstract'? 'class' name typeParameterList? (extendsClause withClause?)? implementsClause? '{' classMembers '}' |
* metadata 'abstract'? 'class' mixinApplicationClass
*/
CompilationUnitMember _parseClassDeclaration(
CommentAndMetadata commentAndMetadata, Token abstractKeyword) {
- Token keyword = _expectKeyword(Keyword.CLASS);
- if (_matchesIdentifier()) {
- Token next = _peek();
- if (_tokenMatches(next, TokenType.LT)) {
- next = _skipTypeParameterList(next);
- if (next != null && _tokenMatches(next, TokenType.EQ)) {
- return _parseClassTypeAlias(
- commentAndMetadata, abstractKeyword, keyword);
- }
- } else if (_tokenMatches(next, TokenType.EQ)) {
- return _parseClassTypeAlias(
- commentAndMetadata, abstractKeyword, keyword);
- }
- }
+ //
+ // Parse the name and type parameters.
+ //
+ Token keyword = getAndAdvance();
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
String className = name.name;
TypeParameterList typeParameters = null;
- if (_matches(TokenType.LT)) {
+ TokenType type = _currentToken.type;
+ if (type == TokenType.LT) {
typeParameters = parseTypeParameterList();
+ type = _currentToken.type;
+ }
+ //
+ // Check to see whether this might be a class type alias rather than a class
+ // declaration.
+ //
+ if (type == TokenType.EQ) {
+ return _parseClassTypeAliasAfterName(
+ commentAndMetadata, abstractKeyword, keyword, name, typeParameters);
}
//
// Parse the clauses. The parser accepts clauses in any order, but will
@@ -4770,7 +4753,8 @@
ImplementsClause implementsClause = null;
bool foundClause = true;
while (foundClause) {
- if (_matchesKeyword(Keyword.EXTENDS)) {
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.EXTENDS) {
if (extendsClause == null) {
extendsClause = parseExtendsClause();
if (withClause != null) {
@@ -4785,7 +4769,7 @@
extendsClause.extendsKeyword);
parseExtendsClause();
}
- } else if (_matchesKeyword(Keyword.WITH)) {
+ } else if (keyword == Keyword.WITH) {
if (withClause == null) {
withClause = parseWithClause();
if (implementsClause != null) {
@@ -4799,7 +4783,7 @@
// TODO(brianwilkerson) Should we merge the list of applied mixins
// into a single list?
}
- } else if (_matchesKeyword(Keyword.IMPLEMENTS)) {
+ } else if (keyword == Keyword.IMPLEMENTS) {
if (implementsClause == null) {
implementsClause = parseImplementsClause();
} else {
@@ -4831,10 +4815,12 @@
List<ClassMember> members = null;
Token rightBracket = null;
if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
- leftBracket = _expect(TokenType.OPEN_CURLY_BRACKET);
+ leftBracket = getAndAdvance();
members = _parseClassMembers(className, _getEndToken(leftBracket));
rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET);
} else {
+ // Recovery: Check for an unmatched closing curly bracket and parse
+ // members until it is reached.
leftBracket = _createSyntheticToken(TokenType.OPEN_CURLY_BRACKET);
rightBracket = _createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET);
_reportErrorForCurrentToken(ParserErrorCode.MISSING_CLASS_BODY);
@@ -4866,14 +4852,15 @@
* (metadata memberDefinition)*
*/
List<ClassMember> _parseClassMembers(String className, Token closingBracket) {
- List<ClassMember> members = new List<ClassMember>();
+ List<ClassMember> members = <ClassMember>[];
Token memberStart = _currentToken;
- while (!_matches(TokenType.EOF) &&
- !_matches(TokenType.CLOSE_CURLY_BRACKET) &&
+ TokenType type = _currentToken.type;
+ Keyword keyword = _currentToken.keyword;
+ while (type != TokenType.EOF &&
+ type != TokenType.CLOSE_CURLY_BRACKET &&
(closingBracket != null ||
- (!_matchesKeyword(Keyword.CLASS) &&
- !_matchesKeyword(Keyword.TYPEDEF)))) {
- if (_matches(TokenType.SEMICOLON)) {
+ (keyword != Keyword.CLASS && keyword != Keyword.TYPEDEF))) {
+ if (type == TokenType.SEMICOLON) {
_reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken,
[_currentToken.lexeme]);
_advance();
@@ -4889,6 +4876,8 @@
_advance();
}
memberStart = _currentToken;
+ type = _currentToken.type;
+ keyword = _currentToken.keyword;
}
return members;
}
@@ -4899,6 +4888,8 @@
* the 'abstract' keyword. The [classKeyword] is the token representing the
* 'class' keyword. Return the class type alias that was parsed.
*
+ * This method assumes that the current token matches an identifier.
+ *
* classTypeAlias ::=
* identifier typeParameters? '=' 'abstract'? mixinApplication
*
@@ -4907,11 +4898,36 @@
*/
ClassTypeAlias _parseClassTypeAlias(CommentAndMetadata commentAndMetadata,
Token abstractKeyword, Token classKeyword) {
- SimpleIdentifier className = parseSimpleIdentifier(isDeclaration: true);
+ SimpleIdentifier className =
+ _parseSimpleIdentifierUnchecked(isDeclaration: true);
TypeParameterList typeParameters = null;
if (_matches(TokenType.LT)) {
typeParameters = parseTypeParameterList();
}
+ return _parseClassTypeAliasAfterName(commentAndMetadata, abstractKeyword,
+ classKeyword, className, typeParameters);
+ }
+
+ /**
+ * Parse a class type alias. The [commentAndMetadata] is the metadata to be
+ * associated with the member. The [abstractKeyword] is the token representing
+ * the 'abstract' keyword. The [classKeyword] is the token representing the
+ * 'class' keyword. The [className] is the name of the alias, and the
+ * [typeParameters] are the type parameters following the name. Return the
+ * class type alias that was parsed.
+ *
+ * classTypeAlias ::=
+ * identifier typeParameters? '=' 'abstract'? mixinApplication
+ *
+ * mixinApplication ::=
+ * type withClause implementsClause? ';'
+ */
+ ClassTypeAlias _parseClassTypeAliasAfterName(
+ CommentAndMetadata commentAndMetadata,
+ Token abstractKeyword,
+ Token classKeyword,
+ SimpleIdentifier className,
+ TypeParameterList typeParameters) {
Token equals = _expect(TokenType.EQ);
TypeName superclass = parseTypeName();
WithClause withClause = null;
@@ -4957,19 +4973,20 @@
/**
* Parse a list of combinators in a directive. Return the combinators that
- * were parsed.
+ * were parsed, or `null` if there are no combinators.
*
* combinator ::=
* 'show' identifier (',' identifier)*
* | 'hide' identifier (',' identifier)*
*/
List<Combinator> _parseCombinators() {
- List<Combinator> combinators = new List<Combinator>();
+ List<Combinator> combinators = null;
while (true) {
Combinator combinator = parseCombinator();
if (combinator == null) {
break;
}
+ combinators ??= <Combinator>[];
combinators.add(combinator);
}
return combinators;
@@ -4986,18 +5003,20 @@
* annotation*
*/
CommentAndMetadata _parseCommentAndMetadata() {
- Comment comment = _parseDocumentationComment();
+ // TODO(brianwilkerson) Consider making the creation of documentation
+ // comments be lazy.
+ List<DocumentationCommentToken> tokens = _parseDocumentationCommentTokens();
List<Annotation> metadata = null;
while (_matches(TokenType.AT)) {
- metadata ??= new List<Annotation>();
+ metadata ??= <Annotation>[];
metadata.add(parseAnnotation());
- Comment optionalComment = _parseDocumentationComment();
- if (optionalComment != null) {
- comment = optionalComment;
+ List<DocumentationCommentToken> optionalTokens =
+ _parseDocumentationCommentTokens();
+ if (optionalTokens != null) {
+ tokens = optionalTokens;
}
}
- metadata ??= const <Annotation>[];
- return new CommentAndMetadata(comment, metadata);
+ return new CommentAndMetadata(_parseDocumentationComment(tokens), metadata);
}
/**
@@ -5051,16 +5070,19 @@
return null;
}
return new CommentReference(newKeyword, identifier);
- } else if (_tokenMatchesKeyword(firstToken, Keyword.THIS) ||
- _tokenMatchesKeyword(firstToken, Keyword.NULL) ||
- _tokenMatchesKeyword(firstToken, Keyword.TRUE) ||
- _tokenMatchesKeyword(firstToken, Keyword.FALSE)) {
- // TODO(brianwilkerson) If we want to support this we will need to
- // extend the definition of CommentReference to take an expression
- // rather than an identifier. For now we just ignore it to reduce the
- // number of errors produced, but that's probably not a valid long term
- // approach.
- return null;
+ } else {
+ Keyword keyword = firstToken.keyword;
+ if (keyword == Keyword.THIS ||
+ keyword == Keyword.NULL ||
+ keyword == Keyword.TRUE ||
+ keyword == Keyword.FALSE) {
+ // TODO(brianwilkerson) If we want to support this we will need to
+ // extend the definition of CommentReference to take an expression
+ // rather than an identifier. For now we just ignore it to reduce the
+ // number of errors produced, but that's probably not a valid long term
+ // approach.
+ return null;
+ }
}
} catch (exception) {
// Ignored because we assume that it wasn't a real comment reference.
@@ -5082,7 +5104,7 @@
*/
List<CommentReference> _parseCommentReferences(
List<DocumentationCommentToken> tokens) {
- List<CommentReference> references = new List<CommentReference>();
+ List<CommentReference> references = <CommentReference>[];
for (DocumentationCommentToken token in tokens) {
String comment = token.lexeme;
comment = _removeCodeBlocksGitHub(comment);
@@ -5158,32 +5180,41 @@
CompilationUnitMember _parseCompilationUnitMember(
CommentAndMetadata commentAndMetadata) {
Modifiers modifiers = _parseModifiers();
- if (_matchesKeyword(Keyword.CLASS)) {
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.CLASS) {
return _parseClassDeclaration(
commentAndMetadata, _validateModifiersForClass(modifiers));
- } else if (_matchesKeyword(Keyword.TYPEDEF) &&
- !_tokenMatches(_peek(), TokenType.PERIOD) &&
- !_tokenMatches(_peek(), TokenType.LT) &&
- !_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
+ }
+ Token next = _peek();
+ TokenType nextType = next.type;
+ if (keyword == Keyword.TYPEDEF &&
+ nextType != TokenType.PERIOD &&
+ nextType != TokenType.LT &&
+ nextType != TokenType.OPEN_PAREN) {
_validateModifiersForTypedef(modifiers);
return _parseTypeAlias(commentAndMetadata);
- } else if (_matchesKeyword(Keyword.ENUM)) {
+ } else if (keyword == Keyword.ENUM) {
_validateModifiersForEnum(modifiers);
return _parseEnumDeclaration(commentAndMetadata);
- }
- if (_matchesKeyword(Keyword.VOID)) {
- TypeName returnType = parseReturnType();
- if ((_matchesKeyword(Keyword.GET) || _matchesKeyword(Keyword.SET)) &&
- _tokenMatchesIdentifier(_peek())) {
+ } else if (keyword == Keyword.VOID) {
+ TypeName returnType =
+ new TypeName(new SimpleIdentifier(getAndAdvance()), null);
+ keyword = _currentToken.keyword;
+ next = _peek();
+ if ((keyword == Keyword.GET || keyword == Keyword.SET) &&
+ _tokenMatchesIdentifier(next)) {
_validateModifiersForTopLevelFunction(modifiers);
return _parseFunctionDeclaration(
commentAndMetadata, modifiers.externalKeyword, returnType);
- } else if (_matchesKeyword(Keyword.OPERATOR) && _isOperator(_peek())) {
+ } else if (keyword == Keyword.OPERATOR && _isOperator(next)) {
_reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken);
- return _convertToFunctionDeclaration(_parseOperator(
- commentAndMetadata, modifiers.externalKeyword, returnType));
+ return _convertToFunctionDeclaration(_parseOperatorAfterKeyword(
+ commentAndMetadata,
+ modifiers.externalKeyword,
+ returnType,
+ getAndAdvance()));
} else if (_matchesIdentifier() &&
- _peek().matchesAny(const <TokenType>[
+ next.matchesAny(const <TokenType>[
TokenType.OPEN_PAREN,
TokenType.OPEN_CURLY_BRACKET,
TokenType.FUNCTION,
@@ -5197,7 +5228,7 @@
// We have found an error of some kind. Try to recover.
//
if (_matchesIdentifier()) {
- if (_peek().matchesAny(const <TokenType>[
+ if (next.matchesAny(const <TokenType>[
TokenType.EQ,
TokenType.COMMA,
TokenType.SEMICOLON
@@ -5218,15 +5249,18 @@
ParserErrorCode.EXPECTED_EXECUTABLE, _currentToken);
return null;
}
- } else if ((_matchesKeyword(Keyword.GET) || _matchesKeyword(Keyword.SET)) &&
- _tokenMatchesIdentifier(_peek())) {
+ } else if ((keyword == Keyword.GET || keyword == Keyword.SET) &&
+ _tokenMatchesIdentifier(next)) {
_validateModifiersForTopLevelFunction(modifiers);
return _parseFunctionDeclaration(
commentAndMetadata, modifiers.externalKeyword, null);
- } else if (_matchesKeyword(Keyword.OPERATOR) && _isOperator(_peek())) {
+ } else if (keyword == Keyword.OPERATOR && _isOperator(next)) {
_reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken);
- return _convertToFunctionDeclaration(
- _parseOperator(commentAndMetadata, modifiers.externalKeyword, null));
+ return _convertToFunctionDeclaration(_parseOperatorAfterKeyword(
+ commentAndMetadata,
+ modifiers.externalKeyword,
+ null,
+ getAndAdvance()));
} else if (!_matchesIdentifier()) {
Token keyword = modifiers.varKeyword;
if (keyword == null) {
@@ -5240,9 +5274,9 @@
// We appear to have found an incomplete top-level variable declaration.
//
_reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER);
- List<VariableDeclaration> variables = new List<VariableDeclaration>();
- variables.add(
- new VariableDeclaration(_createSyntheticIdentifier(), null, null));
+ VariableDeclaration variable =
+ new VariableDeclaration(_createSyntheticIdentifier(), null, null);
+ List<VariableDeclaration> variables = <VariableDeclaration>[variable];
return new TopLevelVariableDeclaration(
commentAndMetadata.comment,
commentAndMetadata.metadata,
@@ -5254,12 +5288,12 @@
} else if (_isPeekGenericTypeParametersAndOpenParen()) {
return _parseFunctionDeclaration(
commentAndMetadata, modifiers.externalKeyword, null);
- } else if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
+ } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
TypeName returnType = _parseOptionalTypeNameComment();
_validateModifiersForTopLevelFunction(modifiers);
return _parseFunctionDeclaration(
commentAndMetadata, modifiers.externalKeyword, returnType);
- } else if (_peek().matchesAny(const <TokenType>[
+ } else if (next.matchesAny(const <TokenType>[
TokenType.EQ,
TokenType.COMMA,
TokenType.SEMICOLON
@@ -5278,15 +5312,20 @@
_expect(TokenType.SEMICOLON));
}
TypeName returnType = parseReturnType();
- if ((_matchesKeyword(Keyword.GET) || _matchesKeyword(Keyword.SET)) &&
- _tokenMatchesIdentifier(_peek())) {
+ keyword = _currentToken.keyword;
+ next = _peek();
+ if ((keyword == Keyword.GET || keyword == Keyword.SET) &&
+ _tokenMatchesIdentifier(next)) {
_validateModifiersForTopLevelFunction(modifiers);
return _parseFunctionDeclaration(
commentAndMetadata, modifiers.externalKeyword, returnType);
- } else if (_matchesKeyword(Keyword.OPERATOR) && _isOperator(_peek())) {
+ } else if (keyword == Keyword.OPERATOR && _isOperator(next)) {
_reportErrorForToken(ParserErrorCode.TOP_LEVEL_OPERATOR, _currentToken);
- return _convertToFunctionDeclaration(_parseOperator(
- commentAndMetadata, modifiers.externalKeyword, returnType));
+ return _convertToFunctionDeclaration(_parseOperatorAfterKeyword(
+ commentAndMetadata,
+ modifiers.externalKeyword,
+ returnType,
+ getAndAdvance()));
} else if (_matches(TokenType.AT)) {
return new TopLevelVariableDeclaration(
commentAndMetadata.comment,
@@ -5304,16 +5343,15 @@
} else {
semicolon = _createSyntheticToken(TokenType.SEMICOLON);
}
- List<VariableDeclaration> variables = new List<VariableDeclaration>();
- variables.add(
- new VariableDeclaration(_createSyntheticIdentifier(), null, null));
+ VariableDeclaration variable =
+ new VariableDeclaration(_createSyntheticIdentifier(), null, null);
+ List<VariableDeclaration> variables = <VariableDeclaration>[variable];
return new TopLevelVariableDeclaration(
commentAndMetadata.comment,
commentAndMetadata.metadata,
new VariableDeclarationList(null, null, null, returnType, variables),
semicolon);
- }
- if (_peek().matchesAny(const <TokenType>[
+ } else if (next.matchesAny(const <TokenType>[
TokenType.OPEN_PAREN,
TokenType.FUNCTION,
TokenType.OPEN_CURLY_BRACKET,
@@ -5334,6 +5372,8 @@
/**
* Parse a configuration in either an import or export directive.
*
+ * This method assumes that the current token matches `Keyword.IF`.
+ *
* configuration ::=
* 'if' '(' test ')' uri
*
@@ -5344,7 +5384,7 @@
* identifier ('.' identifier)*
*/
Configuration _parseConfiguration() {
- Token ifKeyword = _expectKeyword(Keyword.IF);
+ Token ifKeyword = getAndAdvance();
Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
DottedName name = _parseDottedName();
Token equalToken = null;
@@ -5364,12 +5404,13 @@
}
/**
- * Parse a list of configurations. If conditional directives are not
- * supported, return an empty list without attempting to parse anything.
+ * Parse a list of configurations. Return the configurations that were parsed,
+ * or `null` if there are no configurations.
*/
List<Configuration> _parseConfigurations() {
- List<Configuration> configurations = <Configuration>[];
+ List<Configuration> configurations = null;
while (_matchesKeyword(Keyword.IF)) {
+ configurations ??= <Configuration>[];
configurations.add(_parseConfiguration());
}
return configurations;
@@ -5378,19 +5419,22 @@
/**
* Parse a const expression. Return the const expression that was parsed.
*
+ * This method assumes that the current token matches `Keyword.CONST`.
+ *
* constExpression ::=
* instanceCreationExpression
* | listLiteral
* | mapLiteral
*/
Expression _parseConstExpression() {
- Token keyword = _expectKeyword(Keyword.CONST);
- if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) {
+ Token keyword = getAndAdvance();
+ TokenType type = _currentToken.type;
+ if (type == TokenType.LT || _injectGenericCommentTypeList()) {
return _parseListOrMapLiteral(keyword);
- } else if (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
- _matches(TokenType.INDEX)) {
+ } else if (type == TokenType.OPEN_SQUARE_BRACKET ||
+ type == TokenType.INDEX) {
return _parseListLiteral(keyword, null);
- } else if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
+ } else if (type == TokenType.OPEN_CURLY_BRACKET) {
return _parseMapLiteral(keyword, null);
}
return _parseInstanceCreationExpression(keyword);
@@ -5410,26 +5454,28 @@
List<ConstructorInitializer> initializers = null;
if (_matches(TokenType.COLON)) {
separator = getAndAdvance();
- initializers = new List<ConstructorInitializer>();
+ initializers = <ConstructorInitializer>[];
do {
- if (_matchesKeyword(Keyword.THIS)) {
- if (_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.THIS) {
+ TokenType nextType = _peek().type;
+ if (nextType == TokenType.OPEN_PAREN) {
bodyAllowed = false;
- initializers.add(_parseRedirectingConstructorInvocation());
- } else if (_tokenMatches(_peek(), TokenType.PERIOD) &&
+ initializers.add(_parseRedirectingConstructorInvocation(false));
+ } else if (nextType == TokenType.PERIOD &&
_tokenMatches(_peekAt(3), TokenType.OPEN_PAREN)) {
bodyAllowed = false;
- initializers.add(_parseRedirectingConstructorInvocation());
+ initializers.add(_parseRedirectingConstructorInvocation(true));
} else {
- initializers.add(_parseConstructorFieldInitializer());
+ initializers.add(_parseConstructorFieldInitializer(true));
}
- } else if (_matchesKeyword(Keyword.SUPER)) {
+ } else if (keyword == Keyword.SUPER) {
initializers.add(_parseSuperConstructorInvocation());
} else if (_matches(TokenType.OPEN_CURLY_BRACKET) ||
_matches(TokenType.FUNCTION)) {
_reportErrorForCurrentToken(ParserErrorCode.MISSING_INITIALIZER);
} else {
- initializers.add(_parseConstructorFieldInitializer());
+ initializers.add(_parseConstructorFieldInitializer(false));
}
} while (_optional(TokenType.COMMA));
if (factoryKeyword != null) {
@@ -5492,54 +5538,55 @@
}
/**
- * Parse a field initializer within a constructor. Return the field
- * initializer that was parsed.
+ * Parse a field initializer within a constructor. The flag [hasThis] should
+ * be true if the current token is `this`. Return the field initializer that
+ * was parsed.
*
* fieldInitializer:
* ('this' '.')? identifier '=' conditionalExpression cascadeSection*
*/
- ConstructorFieldInitializer _parseConstructorFieldInitializer() {
- Token keyword = null;
+ ConstructorFieldInitializer _parseConstructorFieldInitializer(bool hasThis) {
+ Token keywordToken = null;
Token period = null;
- if (_matchesKeyword(Keyword.THIS)) {
- keyword = getAndAdvance();
+ if (hasThis) {
+ keywordToken = getAndAdvance();
period = _expect(TokenType.PERIOD);
}
SimpleIdentifier fieldName = parseSimpleIdentifier();
Token equals = null;
- if (_matches(TokenType.EQ)) {
+ TokenType type = _currentToken.type;
+ if (type == TokenType.EQ) {
equals = getAndAdvance();
- } else if (!_matchesKeyword(Keyword.THIS) &&
- !_matchesKeyword(Keyword.SUPER) &&
- !_matches(TokenType.OPEN_CURLY_BRACKET) &&
- !_matches(TokenType.FUNCTION)) {
- _reportErrorForCurrentToken(
- ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER);
- equals = _createSyntheticToken(TokenType.EQ);
} else {
_reportErrorForCurrentToken(
ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER);
- return new ConstructorFieldInitializer(keyword, period, fieldName,
- _createSyntheticToken(TokenType.EQ), _createSyntheticIdentifier());
+ Keyword keyword = _currentToken.keyword;
+ if (keyword != Keyword.THIS &&
+ keyword != Keyword.SUPER &&
+ type != TokenType.OPEN_CURLY_BRACKET &&
+ type != TokenType.FUNCTION) {
+ equals = _createSyntheticToken(TokenType.EQ);
+ } else {
+ return new ConstructorFieldInitializer(keywordToken, period, fieldName,
+ _createSyntheticToken(TokenType.EQ), _createSyntheticIdentifier());
+ }
}
bool wasInInitializer = _inInitializer;
_inInitializer = true;
try {
Expression expression = parseConditionalExpression();
- TokenType tokenType = _currentToken.type;
- if (tokenType == TokenType.PERIOD_PERIOD) {
- List<Expression> cascadeSections = new List<Expression>();
- while (tokenType == TokenType.PERIOD_PERIOD) {
+ if (_matches(TokenType.PERIOD_PERIOD)) {
+ List<Expression> cascadeSections = <Expression>[];
+ do {
Expression section = _parseCascadeSection();
if (section != null) {
cascadeSections.add(section);
}
- tokenType = _currentToken.type;
- }
+ } while (_matches(TokenType.PERIOD_PERIOD));
expression = new CascadeExpression(expression, cascadeSections);
}
return new ConstructorFieldInitializer(
- keyword, period, fieldName, equals, expression);
+ keywordToken, period, fieldName, equals, expression);
} finally {
_inInitializer = wasInInitializer;
}
@@ -5548,18 +5595,20 @@
/**
* Parse a continue statement. Return the continue statement that was parsed.
*
+ * This method assumes that the current token matches `Keyword.CONTINUE`.
+ *
* continueStatement ::=
* 'continue' identifier? ';'
*/
Statement _parseContinueStatement() {
- Token continueKeyword = _expectKeyword(Keyword.CONTINUE);
+ Token continueKeyword = getAndAdvance();
if (!_inLoop && !_inSwitch) {
_reportErrorForToken(
ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword);
}
SimpleIdentifier label = null;
if (_matchesIdentifier()) {
- label = parseSimpleIdentifier();
+ label = _parseSimpleIdentifierUnchecked();
}
if (_inSwitch && !_inLoop && label == null) {
_reportErrorForToken(
@@ -5587,7 +5636,7 @@
} else if (_matchesKeyword(Keyword.LIBRARY)) {
return _parseLibraryDirective(commentAndMetadata);
} else if (_matchesKeyword(Keyword.PART)) {
- return _parsePartDirective(commentAndMetadata);
+ return _parsePartOrPartOfDirective(commentAndMetadata);
} else {
// Internal error: this method should not have been invoked if the current
// token was something other than one of the above.
@@ -5609,16 +5658,18 @@
if (_matches(TokenType.SCRIPT_TAG)) {
scriptTag = new ScriptTag(getAndAdvance());
}
- List<Directive> directives = new List<Directive>();
+ List<Directive> directives = <Directive>[];
while (!_matches(TokenType.EOF)) {
CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata();
- if ((_matchesKeyword(Keyword.IMPORT) ||
- _matchesKeyword(Keyword.EXPORT) ||
- _matchesKeyword(Keyword.LIBRARY) ||
- _matchesKeyword(Keyword.PART)) &&
- !_tokenMatches(_peek(), TokenType.PERIOD) &&
- !_tokenMatches(_peek(), TokenType.LT) &&
- !_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
+ Keyword keyword = _currentToken.keyword;
+ TokenType type = _peek().type;
+ if ((keyword == Keyword.IMPORT ||
+ keyword == Keyword.EXPORT ||
+ keyword == Keyword.LIBRARY ||
+ keyword == Keyword.PART) &&
+ type != TokenType.PERIOD &&
+ type != TokenType.LT &&
+ type != TokenType.OPEN_PAREN) {
directives.add(_parseDirective(commentAndMetadata));
} else if (_matches(TokenType.SEMICOLON)) {
_advance();
@@ -5626,12 +5677,29 @@
while (!_matches(TokenType.EOF)) {
_advance();
}
- return new CompilationUnit(firstToken, scriptTag, directives,
- new List<CompilationUnitMember>(), _currentToken);
+ return new CompilationUnit(
+ firstToken, scriptTag, directives, null, _currentToken);
}
}
- return new CompilationUnit(firstToken, scriptTag, directives,
- new List<CompilationUnitMember>(), _currentToken);
+ return new CompilationUnit(
+ firstToken, scriptTag, directives, null, _currentToken);
+ }
+
+ /**
+ * Parse a documentation comment based on the given list of documentation
+ * comment tokens. Return the documentation comment that was parsed, or `null`
+ * if there was no comment.
+ *
+ * documentationComment ::=
+ * multiLineComment?
+ * | singleLineComment*
+ */
+ Comment _parseDocumentationComment(List<DocumentationCommentToken> tokens) {
+ if (tokens == null) {
+ return null;
+ }
+ List<CommentReference> references = _parseCommentReferences(tokens);
+ return Comment.createDocumentationCommentWithReferences(tokens, references);
}
/**
@@ -5642,37 +5710,32 @@
* multiLineComment?
* | singleLineComment*
*/
- Comment _parseDocumentationComment() {
- List<DocumentationCommentToken> documentationTokens =
- <DocumentationCommentToken>[];
+ List<DocumentationCommentToken> _parseDocumentationCommentTokens() {
+ List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[];
CommentToken commentToken = _currentToken.precedingComments;
while (commentToken != null) {
if (commentToken is DocumentationCommentToken) {
- if (documentationTokens.isNotEmpty) {
+ if (tokens.isNotEmpty) {
if (commentToken.type == TokenType.SINGLE_LINE_COMMENT) {
- if (documentationTokens[0].type != TokenType.SINGLE_LINE_COMMENT) {
- documentationTokens.clear();
+ if (tokens[0].type != TokenType.SINGLE_LINE_COMMENT) {
+ tokens.clear();
}
} else {
- documentationTokens.clear();
+ tokens.clear();
}
}
- documentationTokens.add(commentToken);
+ tokens.add(commentToken);
}
commentToken = commentToken.next;
}
- if (documentationTokens.isEmpty) {
- return null;
- }
- List<CommentReference> references =
- _parseCommentReferences(documentationTokens);
- return Comment.createDocumentationCommentWithReferences(
- documentationTokens, references);
+ return tokens.isEmpty ? null : tokens;
}
/**
* Parse a do statement. Return the do statement that was parsed.
*
+ * This method assumes that the current token matches `Keyword.DO`.
+ *
* doStatement ::=
* 'do' statement 'while' '(' expression ')' ';'
*/
@@ -5680,7 +5743,7 @@
bool wasInLoop = _inLoop;
_inLoop = true;
try {
- Token doKeyword = _expectKeyword(Keyword.DO);
+ Token doKeyword = getAndAdvance();
Statement body = parseStatement2();
Token whileKeyword = _expectKeyword(Keyword.WHILE);
Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
@@ -5701,10 +5764,10 @@
* identifier ('.' identifier)*
*/
DottedName _parseDottedName() {
- List<SimpleIdentifier> components = new List<SimpleIdentifier>();
- components.add(parseSimpleIdentifier());
- while (_matches(TokenType.PERIOD)) {
- _advance();
+ List<SimpleIdentifier> components = <SimpleIdentifier>[
+ parseSimpleIdentifier()
+ ];
+ while (_optional(TokenType.PERIOD)) {
components.add(parseSimpleIdentifier());
}
return new DottedName(components);
@@ -5713,20 +5776,36 @@
/**
* Parse an empty statement. Return the empty statement that was parsed.
*
+ * This method assumes that the current token matches `TokenType.SEMICOLON`.
+ *
* emptyStatement ::=
* ';'
*/
Statement _parseEmptyStatement() => new EmptyStatement(getAndAdvance());
+ /**
+ * Parse an enum constant declaration. Return the enum constant declaration
+ * that was parsed.
+ *
+ * Specified:
+ *
+ * enumConstant ::=
+ * id
+ *
+ * Actual:
+ *
+ * enumConstant ::=
+ * metadata id
+ */
EnumConstantDeclaration _parseEnumConstantDeclaration() {
CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata();
SimpleIdentifier name;
if (_matchesIdentifier()) {
- name = parseSimpleIdentifier(isDeclaration: true);
+ name = _parseSimpleIdentifierUnchecked(isDeclaration: true);
} else {
name = _createSyntheticIdentifier();
}
- if (commentAndMetadata.metadata.isNotEmpty) {
+ if (commentAndMetadata.hasMetadata) {
_reportErrorForNode(ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT,
commentAndMetadata.metadata[0]);
}
@@ -5738,18 +5817,19 @@
* Parse an enum declaration. The [commentAndMetadata] is the metadata to be
* associated with the member. Return the enum declaration that was parsed.
*
+ * This method assumes that the current token matches `Keyword.ENUM`.
+ *
* enumType ::=
* metadata 'enum' id '{' id (',' id)* (',')? '}'
*/
EnumDeclaration _parseEnumDeclaration(CommentAndMetadata commentAndMetadata) {
- Token keyword = _expectKeyword(Keyword.ENUM);
+ Token keyword = getAndAdvance();
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
Token leftBracket = null;
- List<EnumConstantDeclaration> constants =
- new List<EnumConstantDeclaration>();
+ List<EnumConstantDeclaration> constants = <EnumConstantDeclaration>[];
Token rightBracket = null;
if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
- leftBracket = _expect(TokenType.OPEN_CURLY_BRACKET);
+ leftBracket = getAndAdvance();
if (_matchesIdentifier() || _matches(TokenType.AT)) {
constants.add(_parseEnumConstantDeclaration());
} else if (_matches(TokenType.COMMA) &&
@@ -5792,7 +5872,7 @@
*/
Expression _parseEqualityExpression() {
Expression expression;
- if (_matchesKeyword(Keyword.SUPER) &&
+ if (_currentToken.keyword == Keyword.SUPER &&
_currentToken.next.type.isEqualityOperator) {
expression = new SuperExpression(getAndAdvance());
} else {
@@ -5800,13 +5880,12 @@
}
bool leftEqualityExpression = false;
while (_currentToken.type.isEqualityOperator) {
- Token operator = getAndAdvance();
if (leftEqualityExpression) {
_reportErrorForNode(
ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND, expression);
}
expression = new BinaryExpression(
- expression, operator, _parseRelationalExpression());
+ expression, getAndAdvance(), _parseRelationalExpression());
leftEqualityExpression = true;
}
return expression;
@@ -5816,11 +5895,13 @@
* Parse an export directive. The [commentAndMetadata] is the metadata to be
* associated with the directive. Return the export directive that was parsed.
*
+ * This method assumes that the current token matches `Keyword.EXPORT`.
+ *
* exportDirective ::=
* metadata 'export' stringLiteral configuration* combinator*';'
*/
ExportDirective _parseExportDirective(CommentAndMetadata commentAndMetadata) {
- Token exportKeyword = _expectKeyword(Keyword.EXPORT);
+ Token exportKeyword = getAndAdvance();
StringLiteral libraryUri = _parseUri();
List<Configuration> configurations = _parseConfigurations();
List<Combinator> combinators = _parseCombinators();
@@ -5842,8 +5923,7 @@
* expression (',' expression)*
*/
List<Expression> _parseExpressionList() {
- List<Expression> expressions = new List<Expression>();
- expressions.add(parseExpression2());
+ List<Expression> expressions = <Expression>[parseExpression2()];
while (_optional(TokenType.COMMA)) {
expressions.add(parseExpression2());
}
@@ -5862,23 +5942,24 @@
* | type
*/
FinalConstVarOrType _parseFinalConstVarOrType(bool optional) {
- Token keyword = null;
+ Token keywordToken = null;
TypeName type = null;
- if (_matchesKeyword(Keyword.FINAL) || _matchesKeyword(Keyword.CONST)) {
- keyword = getAndAdvance();
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.FINAL || keyword == Keyword.CONST) {
+ keywordToken = getAndAdvance();
if (_isTypedIdentifier(_currentToken)) {
type = parseTypeName();
} else {
// Support `final/*=T*/ x;`
type = _parseOptionalTypeNameComment();
}
- } else if (_matchesKeyword(Keyword.VAR)) {
- keyword = getAndAdvance();
+ } else if (keyword == Keyword.VAR) {
+ keywordToken = getAndAdvance();
// Support `var/*=T*/ x;`
type = _parseOptionalTypeNameComment();
if (type != null) {
// Clear the keyword to prevent an error.
- keyword = null;
+ keywordToken = null;
}
} else if (_isTypedIdentifier(_currentToken)) {
type = parseReturnType();
@@ -5890,7 +5971,7 @@
// This is not supported if the type is required.
type = _parseOptionalTypeNameComment();
}
- return new FinalConstVarOrType(keyword, type);
+ return new FinalConstVarOrType(keywordToken, type);
}
/**
@@ -5907,31 +5988,32 @@
*/
FormalParameter _parseFormalParameter(ParameterKind kind) {
NormalFormalParameter parameter = parseNormalFormalParameter();
- if (_matches(TokenType.EQ)) {
- Token seperator = getAndAdvance();
+ TokenType type = _currentToken.type;
+ if (type == TokenType.EQ) {
+ Token separator = getAndAdvance();
Expression defaultValue = parseExpression2();
if (kind == ParameterKind.NAMED) {
_reportErrorForToken(
- ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, seperator);
+ ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, separator);
} else if (kind == ParameterKind.REQUIRED) {
_reportErrorForNode(
ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP, parameter);
}
return new DefaultFormalParameter(
- parameter, kind, seperator, defaultValue);
- } else if (_matches(TokenType.COLON)) {
- Token seperator = getAndAdvance();
+ parameter, kind, separator, defaultValue);
+ } else if (type == TokenType.COLON) {
+ Token separator = getAndAdvance();
Expression defaultValue = parseExpression2();
if (kind == ParameterKind.POSITIONAL) {
_reportErrorForToken(
ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER,
- seperator);
+ separator);
} else if (kind == ParameterKind.REQUIRED) {
_reportErrorForNode(
ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, parameter);
}
return new DefaultFormalParameter(
- parameter, kind, seperator, defaultValue);
+ parameter, kind, separator, defaultValue);
} else if (kind != ParameterKind.REQUIRED) {
return new DefaultFormalParameter(parameter, kind, null, null);
}
@@ -5939,6 +6021,160 @@
}
/**
+ * Parse a list of formal parameters given that the list starts with the given
+ * [leftParenthesis]. Return the formal parameters that were parsed.
+ */
+ FormalParameterList _parseFormalParameterListAfterParen(
+ Token leftParenthesis) {
+ if (_matches(TokenType.CLOSE_PAREN)) {
+ return new FormalParameterList(
+ leftParenthesis, null, null, null, getAndAdvance());
+ }
+ //
+ // Even though it is invalid to have default parameters outside of brackets,
+ // required parameters inside of brackets, or multiple groups of default and
+ // named parameters, we allow all of these cases so that we can recover
+ // better.
+ //
+ List<FormalParameter> parameters = <FormalParameter>[];
+ Token leftSquareBracket = null;
+ Token rightSquareBracket = null;
+ Token leftCurlyBracket = null;
+ Token rightCurlyBracket = null;
+ ParameterKind kind = ParameterKind.REQUIRED;
+ bool firstParameter = true;
+ bool reportedMultiplePositionalGroups = false;
+ bool reportedMultipleNamedGroups = false;
+ bool reportedMixedGroups = false;
+ bool wasOptionalParameter = false;
+ Token initialToken = null;
+ do {
+ if (firstParameter) {
+ firstParameter = false;
+ } else if (!_optional(TokenType.COMMA)) {
+ // TODO(brianwilkerson) The token is wrong, we need to recover from this
+ // case.
+ if (_getEndToken(leftParenthesis) != null) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.EXPECTED_TOKEN, [TokenType.COMMA.lexeme]);
+ } else {
+ _reportErrorForToken(ParserErrorCode.MISSING_CLOSING_PARENTHESIS,
+ _currentToken.previous);
+ break;
+ }
+ }
+ initialToken = _currentToken;
+ //
+ // Handle the beginning of parameter groups.
+ //
+ TokenType type = _currentToken.type;
+ if (type == TokenType.OPEN_SQUARE_BRACKET) {
+ wasOptionalParameter = true;
+ if (leftSquareBracket != null && !reportedMultiplePositionalGroups) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS);
+ reportedMultiplePositionalGroups = true;
+ }
+ if (leftCurlyBracket != null && !reportedMixedGroups) {
+ _reportErrorForCurrentToken(ParserErrorCode.MIXED_PARAMETER_GROUPS);
+ reportedMixedGroups = true;
+ }
+ leftSquareBracket = getAndAdvance();
+ kind = ParameterKind.POSITIONAL;
+ } else if (type == TokenType.OPEN_CURLY_BRACKET) {
+ wasOptionalParameter = true;
+ if (leftCurlyBracket != null && !reportedMultipleNamedGroups) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS);
+ reportedMultipleNamedGroups = true;
+ }
+ if (leftSquareBracket != null && !reportedMixedGroups) {
+ _reportErrorForCurrentToken(ParserErrorCode.MIXED_PARAMETER_GROUPS);
+ reportedMixedGroups = true;
+ }
+ leftCurlyBracket = getAndAdvance();
+ kind = ParameterKind.NAMED;
+ }
+ //
+ // Parse and record the parameter.
+ //
+ FormalParameter parameter = _parseFormalParameter(kind);
+ parameters.add(parameter);
+ if (kind == ParameterKind.REQUIRED && wasOptionalParameter) {
+ _reportErrorForNode(
+ ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS, parameter);
+ }
+ //
+ // Handle the end of parameter groups.
+ //
+ // TODO(brianwilkerson) Improve the detection and reporting of missing and
+ // mismatched delimiters.
+ type = _currentToken.type;
+ if (type == TokenType.CLOSE_SQUARE_BRACKET) {
+ rightSquareBracket = getAndAdvance();
+ if (leftSquareBracket == null) {
+ if (leftCurlyBracket != null) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]);
+ rightCurlyBracket = rightSquareBracket;
+ rightSquareBracket = null;
+ } else {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
+ ["["]);
+ }
+ }
+ kind = ParameterKind.REQUIRED;
+ } else if (type == TokenType.CLOSE_CURLY_BRACKET) {
+ rightCurlyBracket = getAndAdvance();
+ if (leftCurlyBracket == null) {
+ if (leftSquareBracket != null) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP, ["]"]);
+ rightSquareBracket = rightCurlyBracket;
+ rightCurlyBracket = null;
+ } else {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
+ ["{"]);
+ }
+ }
+ kind = ParameterKind.REQUIRED;
+ }
+ } while (!_matches(TokenType.CLOSE_PAREN) &&
+ !identical(initialToken, _currentToken));
+ Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
+ //
+ // Check that the groups were closed correctly.
+ //
+ if (leftSquareBracket != null && rightSquareBracket == null) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["]"]);
+ }
+ if (leftCurlyBracket != null && rightCurlyBracket == null) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP, ["}"]);
+ }
+ //
+ // Build the parameter list.
+ //
+ leftSquareBracket ??= leftCurlyBracket;
+ rightSquareBracket ??= rightCurlyBracket;
+ return new FormalParameterList(leftParenthesis, parameters,
+ leftSquareBracket, rightSquareBracket, rightParenthesis);
+ }
+
+ /**
+ * Parse a list of formal parameters. Return the formal parameters that were
+ * parsed.
+ *
+ * This method assumes that the current token matches `TokenType.OPEN_PAREN`.
+ */
+ FormalParameterList _parseFormalParameterListUnchecked() {
+ return _parseFormalParameterListAfterParen(getAndAdvance());
+ }
+
+ /**
* Parse a for statement. Return the for statement that was parsed.
*
* forStatement ::=
@@ -5970,19 +6206,20 @@
if (_matchesIdentifier() &&
(_tokenMatchesKeyword(_peek(), Keyword.IN) ||
_tokenMatches(_peek(), TokenType.COLON))) {
- List<VariableDeclaration> variables = new List<VariableDeclaration>();
- SimpleIdentifier variableName = parseSimpleIdentifier();
- variables.add(new VariableDeclaration(variableName, null, null));
+ SimpleIdentifier variableName = _parseSimpleIdentifierUnchecked();
variableList = new VariableDeclarationList(commentAndMetadata.comment,
- commentAndMetadata.metadata, null, null, variables);
+ commentAndMetadata.metadata, null, null, <VariableDeclaration>[
+ new VariableDeclaration(variableName, null, null)
+ ]);
} else if (_isInitializedVariableDeclaration()) {
variableList =
_parseVariableDeclarationListAfterMetadata(commentAndMetadata);
} else {
initialization = parseExpression2();
}
- if (_matchesKeyword(Keyword.IN) || _matches(TokenType.COLON)) {
- if (_matches(TokenType.COLON)) {
+ TokenType type = _currentToken.type;
+ if (_matchesKeyword(Keyword.IN) || type == TokenType.COLON) {
+ if (type == TokenType.COLON) {
_reportErrorForCurrentToken(ParserErrorCode.COLON_IN_PLACE_OF_IN);
}
DeclaredIdentifier loopVariable = null;
@@ -6014,7 +6251,7 @@
new SimpleIdentifier(variable.name.token,
isDeclaration: true));
} else {
- if (!commentAndMetadata.metadata.isEmpty) {
+ if (commentAndMetadata.hasMetadata) {
// TODO(jwren) metadata isn't allowed before the identifier in
// "identifier in expression", add warning if commentAndMetadata
// has content
@@ -6106,45 +6343,47 @@
_inLoop = false;
_inSwitch = false;
try {
- if (_matches(TokenType.SEMICOLON)) {
+ TokenType type = _currentToken.type;
+ if (type == TokenType.SEMICOLON) {
if (!mayBeEmpty) {
_reportErrorForCurrentToken(emptyErrorCode);
}
return new EmptyFunctionBody(getAndAdvance());
- } else if (_matchesString(_NATIVE)) {
- Token nativeToken = getAndAdvance();
- StringLiteral stringLiteral = null;
- if (_matches(TokenType.STRING)) {
- stringLiteral = parseStringLiteral();
- }
- return new NativeFunctionBody(
- nativeToken, stringLiteral, _expect(TokenType.SEMICOLON));
}
Token keyword = null;
Token star = null;
- if (_matchesString(ASYNC)) {
- keyword = getAndAdvance();
- if (!_parseAsync) {
- _reportErrorForToken(ParserErrorCode.ASYNC_NOT_SUPPORTED, keyword);
- }
- if (_matches(TokenType.STAR)) {
- star = getAndAdvance();
- _inGenerator = true;
- }
- _inAsync = true;
- } else if (_matchesString(SYNC)) {
- keyword = getAndAdvance();
- if (!_parseAsync) {
- _reportErrorForToken(ParserErrorCode.ASYNC_NOT_SUPPORTED, keyword);
- }
- if (_matches(TokenType.STAR)) {
- star = getAndAdvance();
- _inGenerator = true;
+ bool foundAsync = false;
+ bool foundSync = false;
+ if (type == TokenType.IDENTIFIER) {
+ String lexeme = _currentToken.lexeme;
+ if (lexeme == ASYNC) {
+ foundAsync = true;
+ keyword = getAndAdvance();
+ if (!_parseAsync) {
+ _reportErrorForToken(ParserErrorCode.ASYNC_NOT_SUPPORTED, keyword);
+ }
+ if (_matches(TokenType.STAR)) {
+ star = getAndAdvance();
+ _inGenerator = true;
+ }
+ type = _currentToken.type;
+ _inAsync = true;
+ } else if (lexeme == SYNC) {
+ foundSync = true;
+ keyword = getAndAdvance();
+ if (!_parseAsync) {
+ _reportErrorForToken(ParserErrorCode.ASYNC_NOT_SUPPORTED, keyword);
+ }
+ if (_matches(TokenType.STAR)) {
+ star = getAndAdvance();
+ _inGenerator = true;
+ }
+ type = _currentToken.type;
}
}
- if (_matches(TokenType.FUNCTION)) {
+ if (type == TokenType.FUNCTION) {
if (keyword != null) {
- if (!_tokenMatchesString(keyword, ASYNC)) {
+ if (!foundAsync) {
_reportErrorForToken(ParserErrorCode.INVALID_SYNC, keyword);
keyword = null;
} else if (star != null) {
@@ -6169,9 +6408,9 @@
}
return new ExpressionFunctionBody(
keyword, functionDefinition, expression, semicolon);
- } else if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
+ } else if (type == TokenType.OPEN_CURLY_BRACKET) {
if (keyword != null) {
- if (_tokenMatchesString(keyword, SYNC) && star == null) {
+ if (foundSync && star == null) {
_reportErrorForToken(
ParserErrorCode.MISSING_STAR_AFTER_SYNC, keyword);
}
@@ -6182,6 +6421,14 @@
_createSyntheticToken(TokenType.SEMICOLON));
}
return new BlockFunctionBody(keyword, star, parseBlock());
+ } else if (_matchesString(_NATIVE)) {
+ Token nativeToken = getAndAdvance();
+ StringLiteral stringLiteral = null;
+ if (_matches(TokenType.STRING)) {
+ stringLiteral = _parseStringLiteralUnchecked();
+ }
+ return new NativeFunctionBody(
+ nativeToken, stringLiteral, _expect(TokenType.SEMICOLON));
} else {
// Invalid function body
_reportErrorForCurrentToken(emptyErrorCode);
@@ -6213,22 +6460,28 @@
CommentAndMetadata commentAndMetadata,
Token externalKeyword,
TypeName returnType) {
- Token keyword = null;
+ Token keywordToken = null;
bool isGetter = false;
- if (_matchesKeyword(Keyword.GET) &&
- !_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
- keyword = getAndAdvance();
+ Keyword keyword = _currentToken.keyword;
+ SimpleIdentifier name = null;
+ if (keyword == Keyword.GET) {
+ keywordToken = getAndAdvance();
isGetter = true;
- } else if (_matchesKeyword(Keyword.SET) &&
- !_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
- keyword = getAndAdvance();
+ } else if (keyword == Keyword.SET) {
+ keywordToken = getAndAdvance();
}
- SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
+ if (keywordToken != null && _matches(TokenType.OPEN_PAREN)) {
+ name = new SimpleIdentifier(keywordToken, isDeclaration: true);
+ keywordToken = null;
+ isGetter = false;
+ } else {
+ name = parseSimpleIdentifier(isDeclaration: true);
+ }
TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
FormalParameterList parameters = null;
if (!isGetter) {
if (_matches(TokenType.OPEN_PAREN)) {
- parameters = parseFormalParameterList();
+ parameters = _parseFormalParameterListUnchecked();
_validateFormalParameterList(parameters);
} else {
_reportErrorForCurrentToken(
@@ -6242,7 +6495,7 @@
}
} else if (_matches(TokenType.OPEN_PAREN)) {
_reportErrorForCurrentToken(ParserErrorCode.GETTER_WITH_PARAMETERS);
- parseFormalParameterList();
+ _parseFormalParameterListUnchecked();
}
FunctionBody body;
if (externalKeyword == null) {
@@ -6261,7 +6514,7 @@
commentAndMetadata.metadata,
externalKeyword,
returnType,
- keyword,
+ keywordToken,
name,
new FunctionExpression(typeParameters, parameters, body));
}
@@ -6328,7 +6581,8 @@
if (_matches(TokenType.LT)) {
typeParameters = parseTypeParameterList();
}
- if (_matches(TokenType.SEMICOLON) || _matches(TokenType.EOF)) {
+ TokenType type = _currentToken.type;
+ if (type == TokenType.SEMICOLON || type == TokenType.EOF) {
_reportErrorForCurrentToken(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS);
FormalParameterList parameters = new FormalParameterList(
_createSyntheticToken(TokenType.OPEN_PAREN),
@@ -6346,12 +6600,24 @@
typeParameters,
parameters,
semicolon);
- } else if (!_matches(TokenType.OPEN_PAREN)) {
+ } else if (type == TokenType.OPEN_PAREN) {
+ FormalParameterList parameters = _parseFormalParameterListUnchecked();
+ _validateFormalParameterList(parameters);
+ Token semicolon = _expect(TokenType.SEMICOLON);
+ return new FunctionTypeAlias(
+ commentAndMetadata.comment,
+ commentAndMetadata.metadata,
+ keyword,
+ returnType,
+ name,
+ typeParameters,
+ parameters,
+ semicolon);
+ } else {
_reportErrorForCurrentToken(ParserErrorCode.MISSING_TYPEDEF_PARAMETERS);
- // TODO(brianwilkerson) Recover from this error. At the very least we
- // should skip to the start of the next valid compilation unit member,
- // allowing for the possibility of finding the typedef parameters before
- // that point.
+ // Recovery: At the very least we should skip to the start of the next
+ // valid compilation unit member, allowing for the possibility of finding
+ // the typedef parameters before that point.
return new FunctionTypeAlias(
commentAndMetadata.comment,
commentAndMetadata.metadata,
@@ -6363,18 +6629,6 @@
null, null, null, _createSyntheticToken(TokenType.CLOSE_PAREN)),
_createSyntheticToken(TokenType.SEMICOLON));
}
- FormalParameterList parameters = parseFormalParameterList();
- _validateFormalParameterList(parameters);
- Token semicolon = _expect(TokenType.SEMICOLON);
- return new FunctionTypeAlias(
- commentAndMetadata.comment,
- commentAndMetadata.metadata,
- keyword,
- returnType,
- name,
- typeParameters,
- parameters,
- semicolon);
}
/**
@@ -6416,6 +6670,8 @@
* been parsed, or `null` if there was no return type. Return the getter that
* was parsed.
*
+ * This method assumes that the current token matches `Keyword.GET`.
+ *
* getter ::=
* getterSignature functionBody?
*
@@ -6424,7 +6680,7 @@
*/
MethodDeclaration _parseGetter(CommentAndMetadata commentAndMetadata,
Token externalKeyword, Token staticKeyword, TypeName returnType) {
- Token propertyKeyword = _expectKeyword(Keyword.GET);
+ Token propertyKeyword = getAndAdvance();
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
if (_matches(TokenType.OPEN_PAREN) &&
_tokenMatches(_peek(), TokenType.CLOSE_PAREN)) {
@@ -6461,10 +6717,10 @@
* identifier (',' identifier)*
*/
List<SimpleIdentifier> _parseIdentifierList() {
- List<SimpleIdentifier> identifiers = new List<SimpleIdentifier>();
- identifiers.add(parseSimpleIdentifier());
- while (_matches(TokenType.COMMA)) {
- _advance();
+ List<SimpleIdentifier> identifiers = <SimpleIdentifier>[
+ parseSimpleIdentifier()
+ ];
+ while (_optional(TokenType.COMMA)) {
identifiers.add(parseSimpleIdentifier());
}
return identifiers;
@@ -6473,11 +6729,13 @@
/**
* Parse an if statement. Return the if statement that was parsed.
*
+ * This method assumes that the current token matches `Keyword.IF`.
+ *
* ifStatement ::=
* 'if' '(' expression ')' statement ('else' statement)?
*/
Statement _parseIfStatement() {
- Token ifKeyword = _expectKeyword(Keyword.IF);
+ Token ifKeyword = getAndAdvance();
Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
Expression condition = parseExpression2();
Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
@@ -6496,11 +6754,13 @@
* Parse an import directive. The [commentAndMetadata] is the metadata to be
* associated with the directive. Return the import directive that was parsed.
*
+ * This method assumes that the current token matches `Keyword.IMPORT`.
+ *
* importDirective ::=
* metadata 'import' stringLiteral configuration* (deferred)? ('as' identifier)? combinator*';'
*/
ImportDirective _parseImportDirective(CommentAndMetadata commentAndMetadata) {
- Token importKeyword = _expectKeyword(Keyword.IMPORT);
+ Token importKeyword = getAndAdvance();
StringLiteral libraryUri = _parseUri();
List<Configuration> configurations = _parseConfigurations();
Token deferredToken = null;
@@ -6590,7 +6850,7 @@
*/
InstanceCreationExpression _parseInstanceCreationExpression(Token keyword) {
ConstructorName constructorName = parseConstructorName();
- ArgumentList argumentList = parseArgumentList();
+ ArgumentList argumentList = _parseArgumentListChecked();
return new InstanceCreationExpression(
keyword, constructorName, argumentList);
}
@@ -6600,12 +6860,14 @@
* associated with the directive. Return the library directive that was
* parsed.
*
+ * This method assumes that the current token matches `Keyword.LIBRARY`.
+ *
* libraryDirective ::=
* metadata 'library' identifier ';'
*/
LibraryDirective _parseLibraryDirective(
CommentAndMetadata commentAndMetadata) {
- Token keyword = _expectKeyword(Keyword.LIBRARY);
+ Token keyword = getAndAdvance();
LibraryIdentifier libraryName = _parseLibraryName(
ParserErrorCode.MISSING_NAME_IN_LIBRARY_DIRECTIVE, keyword);
Token semicolon = _expect(TokenType.SEMICOLON);
@@ -6627,17 +6889,15 @@
if (_matchesIdentifier()) {
return parseLibraryIdentifier();
} else if (_matches(TokenType.STRING)) {
- // TODO(brianwilkerson) Recovery: This should be extended to handle
- // arbitrary tokens until we can find a token that can start a compilation
- // unit member.
+ // Recovery: This should be extended to handle arbitrary tokens until we
+ // can find a token that can start a compilation unit member.
StringLiteral string = parseStringLiteral();
_reportErrorForNode(ParserErrorCode.NON_IDENTIFIER_LIBRARY_NAME, string);
} else {
_reportErrorForToken(missingNameError, missingNameToken);
}
- List<SimpleIdentifier> components = new List<SimpleIdentifier>();
- components.add(_createSyntheticIdentifier());
- return new LibraryIdentifier(components);
+ return new LibraryIdentifier(
+ <SimpleIdentifier>[_createSyntheticIdentifier()]);
}
/**
@@ -6646,13 +6906,16 @@
* is the type arguments appearing before the literal, or `null` if there are
* no type arguments. Return the list literal that was parsed.
*
+ * This method assumes that the current token matches either
+ * `TokenType.OPEN_SQUARE_BRACKET` or `TokenType.INDEX`.
+ *
* listLiteral ::=
* 'const'? typeArguments? '[' (expressionList ','?)? ']'
*/
ListLiteral _parseListLiteral(
Token modifier, TypeArgumentList typeArguments) {
- // may be empty list literal
if (_matches(TokenType.INDEX)) {
+ // Split the token into two separate tokens.
BeginToken leftBracket = _createToken(
_currentToken, TokenType.OPEN_SQUARE_BRACKET,
isBegin: true);
@@ -6666,8 +6929,7 @@
return new ListLiteral(
modifier, typeArguments, leftBracket, null, rightBracket);
}
- // open
- Token leftBracket = _expect(TokenType.OPEN_SQUARE_BRACKET);
+ Token leftBracket = getAndAdvance();
if (_matches(TokenType.CLOSE_SQUARE_BRACKET)) {
return new ListLiteral(
modifier, typeArguments, leftBracket, null, getAndAdvance());
@@ -6675,8 +6937,7 @@
bool wasInInitializer = _inInitializer;
_inInitializer = false;
try {
- List<Expression> elements = new List<Expression>();
- elements.add(parseExpression2());
+ List<Expression> elements = <Expression>[parseExpression2()];
while (_optional(TokenType.COMMA)) {
if (_matches(TokenType.CLOSE_SQUARE_BRACKET)) {
return new ListLiteral(
@@ -6727,10 +6988,9 @@
*/
Expression _parseLogicalAndExpression() {
Expression expression = _parseEqualityExpression();
- while (_matches(TokenType.AMPERSAND_AMPERSAND)) {
- Token operator = getAndAdvance();
+ while (_currentToken.type == TokenType.AMPERSAND_AMPERSAND) {
expression = new BinaryExpression(
- expression, operator, _parseEqualityExpression());
+ expression, getAndAdvance(), _parseEqualityExpression());
}
return expression;
}
@@ -6741,20 +7001,22 @@
* is the type arguments that were declared, or `null` if there are no type
* arguments. Return the map literal that was parsed.
*
+ * This method assumes that the current token matches
+ * `TokenType.OPEN_CURLY_BRACKET`.
+ *
* mapLiteral ::=
* 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
*/
MapLiteral _parseMapLiteral(Token modifier, TypeArgumentList typeArguments) {
- Token leftBracket = _expect(TokenType.OPEN_CURLY_BRACKET);
- List<MapLiteralEntry> entries = new List<MapLiteralEntry>();
+ Token leftBracket = getAndAdvance();
if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
return new MapLiteral(
- modifier, typeArguments, leftBracket, entries, getAndAdvance());
+ modifier, typeArguments, leftBracket, null, getAndAdvance());
}
bool wasInInitializer = _inInitializer;
_inInitializer = false;
try {
- entries.add(parseMapLiteralEntry());
+ List<MapLiteralEntry> entries = <MapLiteralEntry>[parseMapLiteralEntry()];
while (_optional(TokenType.COMMA)) {
if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
return new MapLiteral(
@@ -6838,9 +7100,11 @@
SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true);
TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
FormalParameterList parameters;
- if (!_matches(TokenType.OPEN_PAREN) &&
- (_matches(TokenType.OPEN_CURLY_BRACKET) ||
- _matches(TokenType.FUNCTION))) {
+ TokenType type = _currentToken.type;
+ // TODO(brianwilkerson) Figure out why we care what the current token is if
+ // it isn't a paren.
+ if (type != TokenType.OPEN_PAREN &&
+ (type == TokenType.OPEN_CURLY_BRACKET || type == TokenType.FUNCTION)) {
_reportErrorForToken(
ParserErrorCode.MISSING_METHOD_PARAMETERS, _currentToken.previous);
parameters = new FormalParameterList(
@@ -6878,12 +7142,14 @@
Modifiers modifiers = new Modifiers();
bool progress = true;
while (progress) {
- if (_tokenMatches(_peek(), TokenType.PERIOD) ||
- _tokenMatches(_peek(), TokenType.LT) ||
- _tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
+ TokenType nextType = _peek().type;
+ if (nextType == TokenType.PERIOD ||
+ nextType == TokenType.LT ||
+ nextType == TokenType.OPEN_PAREN) {
return modifiers;
}
- if (_matchesKeyword(Keyword.ABSTRACT)) {
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.ABSTRACT) {
if (modifiers.abstractKeyword != null) {
_reportErrorForCurrentToken(
ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
@@ -6891,7 +7157,7 @@
} else {
modifiers.abstractKeyword = getAndAdvance();
}
- } else if (_matchesKeyword(Keyword.CONST)) {
+ } else if (keyword == Keyword.CONST) {
if (modifiers.constKeyword != null) {
_reportErrorForCurrentToken(
ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
@@ -6899,9 +7165,7 @@
} else {
modifiers.constKeyword = getAndAdvance();
}
- } else if (_matchesKeyword(Keyword.EXTERNAL) &&
- !_tokenMatches(_peek(), TokenType.PERIOD) &&
- !_tokenMatches(_peek(), TokenType.LT)) {
+ } else if (keyword == Keyword.EXTERNAL) {
if (modifiers.externalKeyword != null) {
_reportErrorForCurrentToken(
ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
@@ -6909,9 +7173,7 @@
} else {
modifiers.externalKeyword = getAndAdvance();
}
- } else if (_matchesKeyword(Keyword.FACTORY) &&
- !_tokenMatches(_peek(), TokenType.PERIOD) &&
- !_tokenMatches(_peek(), TokenType.LT)) {
+ } else if (keyword == Keyword.FACTORY) {
if (modifiers.factoryKeyword != null) {
_reportErrorForCurrentToken(
ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
@@ -6919,7 +7181,7 @@
} else {
modifiers.factoryKeyword = getAndAdvance();
}
- } else if (_matchesKeyword(Keyword.FINAL)) {
+ } else if (keyword == Keyword.FINAL) {
if (modifiers.finalKeyword != null) {
_reportErrorForCurrentToken(
ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
@@ -6927,9 +7189,7 @@
} else {
modifiers.finalKeyword = getAndAdvance();
}
- } else if (_matchesKeyword(Keyword.STATIC) &&
- !_tokenMatches(_peek(), TokenType.PERIOD) &&
- !_tokenMatches(_peek(), TokenType.LT)) {
+ } else if (keyword == Keyword.STATIC) {
if (modifiers.staticKeyword != null) {
_reportErrorForCurrentToken(
ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
@@ -6937,7 +7197,7 @@
} else {
modifiers.staticKeyword = getAndAdvance();
}
- } else if (_matchesKeyword(Keyword.VAR)) {
+ } else if (keyword == Keyword.VAR) {
if (modifiers.varKeyword != null) {
_reportErrorForCurrentToken(
ParserErrorCode.DUPLICATED_MODIFIER, [_currentToken.lexeme]);
@@ -6962,16 +7222,15 @@
*/
Expression _parseMultiplicativeExpression() {
Expression expression;
- if (_matchesKeyword(Keyword.SUPER) &&
+ if (_currentToken.keyword == Keyword.SUPER &&
_currentToken.next.type.isMultiplicativeOperator) {
expression = new SuperExpression(getAndAdvance());
} else {
expression = _parseUnaryExpression();
}
while (_currentToken.type.isMultiplicativeOperator) {
- Token operator = getAndAdvance();
- expression =
- new BinaryExpression(expression, operator, _parseUnaryExpression());
+ expression = new BinaryExpression(
+ expression, getAndAdvance(), _parseUnaryExpression());
}
return expression;
}
@@ -6979,6 +7238,8 @@
/**
* Parse a class native clause. Return the native clause that was parsed.
*
+ * This method assumes that the current token matches `_NATIVE`.
+ *
* classNativeClause ::=
* 'native' name
*/
@@ -6991,11 +7252,13 @@
/**
* Parse a new expression. Return the new expression that was parsed.
*
+ * This method assumes that the current token matches `Keyword.NEW`.
+ *
* newExpression ::=
* instanceCreationExpression
*/
InstanceCreationExpression _parseNewExpression() =>
- _parseInstanceCreationExpression(_expectKeyword(Keyword.NEW));
+ _parseInstanceCreationExpression(getAndAdvance());
/**
* Parse a non-labeled statement. Return the non-labeled statement that was
@@ -7020,7 +7283,8 @@
Statement _parseNonLabeledStatement() {
// TODO(brianwilkerson) Pass the comment and metadata on where appropriate.
CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata();
- if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
+ TokenType type = _currentToken.type;
+ if (type == TokenType.OPEN_CURLY_BRACKET) {
if (_tokenMatches(_peek(), TokenType.STRING)) {
Token afterString = _skipStringLiteral(_currentToken.next);
if (afterString != null && afterString.type == TokenType.COLON) {
@@ -7029,7 +7293,7 @@
}
}
return parseBlock();
- } else if (_matches(TokenType.KEYWORD) &&
+ } else if (type == TokenType.KEYWORD &&
!_currentToken.keyword.isPseudoKeyword) {
Keyword keyword = _currentToken.keyword;
// TODO(jwren) compute some metrics to figure out a better order for this
@@ -7064,9 +7328,11 @@
return _parseVariableDeclarationStatementAfterMetadata(
commentAndMetadata);
} else if (keyword == Keyword.VOID) {
- TypeName returnType = parseReturnType();
+ TypeName returnType =
+ new TypeName(new SimpleIdentifier(getAndAdvance()), null);
+ Token next = _currentToken.next;
if (_matchesIdentifier() &&
- _peek().matchesAny(const <TokenType>[
+ next.matchesAny(const <TokenType>[
TokenType.OPEN_PAREN,
TokenType.OPEN_CURLY_BRACKET,
TokenType.FUNCTION,
@@ -7079,7 +7345,7 @@
// We have found an error of some kind. Try to recover.
//
if (_matchesIdentifier()) {
- if (_peek().matchesAny(const <TokenType>[
+ if (next.matchesAny(const <TokenType>[
TokenType.EQ,
TokenType.COMMA,
TokenType.SEMICOLON
@@ -7104,7 +7370,8 @@
return new EmptyStatement(_createSyntheticToken(TokenType.SEMICOLON));
}
} else if (keyword == Keyword.CONST) {
- if (_peek().matchesAny(const <TokenType>[
+ Token next = _currentToken.next;
+ if (next.matchesAny(const <TokenType>[
TokenType.LT,
TokenType.OPEN_CURLY_BRACKET,
TokenType.OPEN_SQUARE_BRACKET,
@@ -7112,8 +7379,8 @@
])) {
return new ExpressionStatement(
parseExpression2(), _expect(TokenType.SEMICOLON));
- } else if (_tokenMatches(_peek(), TokenType.IDENTIFIER)) {
- Token afterType = _skipTypeName(_peek());
+ } else if (_tokenMatches(next, TokenType.IDENTIFIER)) {
+ Token afterType = _skipTypeName(next);
if (afterType != null) {
if (_tokenMatches(afterType, TokenType.OPEN_PAREN) ||
(_tokenMatches(afterType, TokenType.PERIOD) &&
@@ -7158,14 +7425,14 @@
CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT, awaitToken);
}
return statement;
- } else if (_matches(TokenType.SEMICOLON)) {
+ } else if (type == TokenType.SEMICOLON) {
return _parseEmptyStatement();
} else if (_isInitializedVariableDeclaration()) {
return _parseVariableDeclarationStatementAfterMetadata(
commentAndMetadata);
} else if (_isFunctionDeclaration()) {
return _parseFunctionDeclarationStatement();
- } else if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
+ } else if (type == TokenType.CLOSE_CURLY_BRACKET) {
_reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT);
return new EmptyStatement(_createSyntheticToken(TokenType.SEMICOLON));
} else {
@@ -7197,6 +7464,29 @@
ParserErrorCode.MISSING_KEYWORD_OPERATOR, _currentToken);
operatorKeyword = _createSyntheticKeyword(Keyword.OPERATOR);
}
+ return _parseOperatorAfterKeyword(
+ commentAndMetadata, externalKeyword, returnType, operatorKeyword);
+ }
+
+ /**
+ * Parse an operator declaration starting after the 'operator' keyword. The
+ * [commentAndMetadata] is the documentation comment and metadata to be
+ * associated with the declaration. The [externalKeyword] is the 'external'
+ * token. The [returnType] is the return type that has already been parsed, or
+ * `null` if there was no return type. The [operatorKeyword] is the 'operator'
+ * keyword. Return the operator declaration that was parsed.
+ *
+ * operatorDeclaration ::=
+ * operatorSignature (';' | functionBody)
+ *
+ * operatorSignature ::=
+ * 'external'? returnType? 'operator' operator formalParameterList
+ */
+ MethodDeclaration _parseOperatorAfterKeyword(
+ CommentAndMetadata commentAndMetadata,
+ Token externalKeyword,
+ TypeName returnType,
+ Token operatorKeyword) {
if (!_currentToken.isUserDefinableOperator) {
_reportErrorForCurrentToken(
ParserErrorCode.NON_USER_DEFINABLE_OPERATOR, [_currentToken.lexeme]);
@@ -7242,21 +7532,27 @@
TypeName typeComment = _parseOptionalTypeNameComment();
if (typeComment != null) {
return typeComment;
- } else if (_matchesKeyword(Keyword.VOID)) {
- return parseReturnType();
- } else if (_matchesIdentifier() &&
- !_matchesKeyword(Keyword.GET) &&
- !_matchesKeyword(Keyword.SET) &&
- !_matchesKeyword(Keyword.OPERATOR) &&
- (_tokenMatchesIdentifier(_peek()) ||
- _tokenMatches(_peek(), TokenType.LT))) {
- return parseReturnType();
- } else if (_matchesIdentifier() &&
- _tokenMatches(_peek(), TokenType.PERIOD) &&
- _tokenMatchesIdentifier(_peekAt(2)) &&
- (_tokenMatchesIdentifier(_peekAt(3)) ||
- _tokenMatches(_peekAt(3), TokenType.LT))) {
- return parseReturnType();
+ }
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.VOID) {
+ return new TypeName(new SimpleIdentifier(getAndAdvance()), null);
+ } else if (_matchesIdentifier()) {
+ Token next = _peek();
+ if (keyword != Keyword.GET &&
+ keyword != Keyword.SET &&
+ keyword != Keyword.OPERATOR &&
+ (_tokenMatchesIdentifier(next) ||
+ _tokenMatches(next, TokenType.LT))) {
+ return parseReturnType();
+ }
+ Token next2 = next.next;
+ Token next3 = next2.next;
+ if (_tokenMatches(next, TokenType.PERIOD) &&
+ _tokenMatchesIdentifier(next2) &&
+ (_tokenMatchesIdentifier(next3) ||
+ _tokenMatches(next3, TokenType.LT))) {
+ return parseReturnType();
+ }
}
return null;
}
@@ -7280,35 +7576,67 @@
}
/**
+ * Parse a part directive. The [commentAndMetadata] is the metadata to be
+ * associated with the directive. Return the part or part-of directive that
+ * was parsed.
+ *
+ * This method assumes that the current token matches `Keyword.PART`.
+ *
+ * partDirective ::=
+ * metadata 'part' stringLiteral ';'
+ */
+ Directive _parsePartDirective(CommentAndMetadata commentAndMetadata) {
+ Token partKeyword = getAndAdvance();
+ StringLiteral partUri = _parseUri();
+ Token semicolon = _expect(TokenType.SEMICOLON);
+ return new PartDirective(commentAndMetadata.comment,
+ commentAndMetadata.metadata, partKeyword, partUri, semicolon);
+ }
+
+ /**
+ * Parse a part-of directive. The [commentAndMetadata] is the metadata to be
+ * associated with the directive. Return the part or part-of directive that
+ * was parsed.
+ *
+ * This method assumes that the current token matches [Keyword.PART] and that
+ * the following token matches the identifier 'of'.
+ *
+ * partOfDirective ::=
+ * metadata 'part' 'of' identifier ';'
+ */
+ Directive _parsePartOfDirective(CommentAndMetadata commentAndMetadata) {
+ Token partKeyword = getAndAdvance();
+ Token ofKeyword = getAndAdvance();
+ LibraryIdentifier libraryName = _parseLibraryName(
+ ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE, ofKeyword);
+ Token semicolon = _expect(TokenType.SEMICOLON);
+ return new PartOfDirective(
+ commentAndMetadata.comment,
+ commentAndMetadata.metadata,
+ partKeyword,
+ ofKeyword,
+ libraryName,
+ semicolon);
+ }
+
+ /**
* Parse a part or part-of directive. The [commentAndMetadata] is the metadata
* to be associated with the directive. Return the part or part-of directive
* that was parsed.
*
+ * This method assumes that the current token matches `Keyword.PART`.
+ *
* partDirective ::=
* metadata 'part' stringLiteral ';'
*
* partOfDirective ::=
* metadata 'part' 'of' identifier ';'
*/
- Directive _parsePartDirective(CommentAndMetadata commentAndMetadata) {
- Token partKeyword = _expectKeyword(Keyword.PART);
- if (_matchesString(_OF)) {
- Token ofKeyword = getAndAdvance();
- LibraryIdentifier libraryName = _parseLibraryName(
- ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE, ofKeyword);
- Token semicolon = _expect(TokenType.SEMICOLON);
- return new PartOfDirective(
- commentAndMetadata.comment,
- commentAndMetadata.metadata,
- partKeyword,
- ofKeyword,
- libraryName,
- semicolon);
+ Directive _parsePartOrPartOfDirective(CommentAndMetadata commentAndMetadata) {
+ if (_tokenMatchesString(_peek(), _OF)) {
+ return _parsePartOfDirective(commentAndMetadata);
}
- StringLiteral partUri = _parseUri();
- Token semicolon = _expect(TokenType.SEMICOLON);
- return new PartDirective(commentAndMetadata.comment,
- commentAndMetadata.metadata, partKeyword, partUri, semicolon);
+ return _parsePartDirective(commentAndMetadata);
}
/**
@@ -7324,11 +7652,12 @@
*/
Expression _parsePostfixExpression() {
Expression operand = _parseAssignableExpression(true);
- if (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
- _matches(TokenType.PERIOD) ||
- _matches(TokenType.QUESTION_PERIOD) ||
- _matches(TokenType.OPEN_PAREN) ||
- (parseGenericMethods && _matches(TokenType.LT))) {
+ TokenType type = _currentToken.type;
+ if (type == TokenType.OPEN_SQUARE_BRACKET ||
+ type == TokenType.PERIOD ||
+ type == TokenType.QUESTION_PERIOD ||
+ type == TokenType.OPEN_PAREN ||
+ (parseGenericMethods && type == TokenType.LT)) {
do {
if (_isLikelyArgumentList()) {
TypeArgumentList typeArguments = _parseOptionalTypeArguments();
@@ -7348,10 +7677,11 @@
} else {
operand = _parseAssignableSelector(operand, true);
}
- } while (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
- _matches(TokenType.PERIOD) ||
- _matches(TokenType.QUESTION_PERIOD) ||
- _matches(TokenType.OPEN_PAREN));
+ type = _currentToken.type;
+ } while (type == TokenType.OPEN_SQUARE_BRACKET ||
+ type == TokenType.PERIOD ||
+ type == TokenType.QUESTION_PERIOD ||
+ type == TokenType.OPEN_PAREN);
return operand;
}
if (!_currentToken.type.isIncrementOperator) {
@@ -7363,6 +7693,37 @@
}
/**
+ * Parse a prefixed identifier given that the given [qualifier] was already
+ * parsed. Return the prefixed identifier that was parsed.
+ *
+ * prefixedIdentifier ::=
+ * identifier ('.' identifier)?
+ */
+ Identifier _parsePrefixedIdentifierAfterIdentifier(
+ SimpleIdentifier qualifier) {
+ if (!_matches(TokenType.PERIOD) || _injectGenericCommentTypeList()) {
+ return qualifier;
+ }
+ Token period = getAndAdvance();
+ SimpleIdentifier qualified = parseSimpleIdentifier();
+ return new PrefixedIdentifier(qualifier, period, qualified);
+ }
+
+ /**
+ * Parse a prefixed identifier. Return the prefixed identifier that was
+ * parsed.
+ *
+ * This method assumes that the current token matches an identifier.
+ *
+ * prefixedIdentifier ::=
+ * identifier ('.' identifier)?
+ */
+ Identifier _parsePrefixedIdentifierUnchecked() {
+ return _parsePrefixedIdentifierAfterIdentifier(
+ _parseSimpleIdentifierUnchecked());
+ }
+
+ /**
* Parse a primary expression. Return the primary expression that was parsed.
*
* primary ::=
@@ -7386,39 +7747,24 @@
* | listLiteral
*/
Expression _parsePrimaryExpression() {
- if (_matchesKeyword(Keyword.THIS)) {
- return new ThisExpression(getAndAdvance());
- } else if (_matchesKeyword(Keyword.SUPER)) {
- // TODO(paulberry): verify with Gilad that "super" must be followed by
- // unconditionalAssignableSelector in this case.
- return _parseAssignableSelector(
- new SuperExpression(getAndAdvance()), false,
- allowConditional: false);
- } else if (_matchesKeyword(Keyword.NULL)) {
- return new NullLiteral(getAndAdvance());
- } else if (_matchesKeyword(Keyword.FALSE)) {
- return new BooleanLiteral(getAndAdvance(), false);
- } else if (_matchesKeyword(Keyword.TRUE)) {
- return new BooleanLiteral(getAndAdvance(), true);
- } else if (_matches(TokenType.DOUBLE)) {
- Token token = getAndAdvance();
- double value = 0.0;
- try {
- value = double.parse(token.lexeme);
- } on FormatException {
- // The invalid format should have been reported by the scanner.
- }
- return new DoubleLiteral(token, value);
- } else if (_matches(TokenType.HEXADECIMAL)) {
- Token token = getAndAdvance();
- int value = null;
- try {
- value = int.parse(token.lexeme.substring(2), radix: 16);
- } on FormatException {
- // The invalid format should have been reported by the scanner.
- }
- return new IntegerLiteral(token, value);
- } else if (_matches(TokenType.INT)) {
+ if (_matchesIdentifier()) {
+ // TODO(brianwilkerson) The code below was an attempt to recover from an
+ // error case, but it needs to be applied as a recovery only after we
+ // know that parsing it as an identifier doesn't work. Leaving the code as
+ // a reminder of how to recover.
+// if (isFunctionExpression(_peek())) {
+// //
+// // Function expressions were allowed to have names at one point, but this is now illegal.
+// //
+// reportError(ParserErrorCode.NAMED_FUNCTION_EXPRESSION, getAndAdvance());
+// return parseFunctionExpression();
+// }
+ return _parsePrefixedIdentifierUnchecked();
+ }
+ TokenType type = _currentToken.type;
+ if (type == TokenType.STRING) {
+ return parseStringLiteral();
+ } else if (type == TokenType.INT) {
Token token = getAndAdvance();
int value = null;
try {
@@ -7427,26 +7773,46 @@
// The invalid format should have been reported by the scanner.
}
return new IntegerLiteral(token, value);
- } else if (_matches(TokenType.STRING)) {
- return parseStringLiteral();
- } else if (_matchesIdentifier()) {
- // TODO(brianwilkerson) The code below was an attempt to recover from an
- // error case, but it needs to be applied as a recovery only after we
- // know that parsing it as an identifier doesn't work. Leaving the code as
- // a reminder of how to recover.
-// if (isFunctionExpression(peek())) {
-// //
-// // Function expressions were allowed to have names at one point, but this is now illegal.
-// //
-// reportError(ParserErrorCode.NAMED_FUNCTION_EXPRESSION, getAndAdvance());
-// return parseFunctionExpression();
-// }
- return parsePrefixedIdentifier();
- } else if (_matchesKeyword(Keyword.NEW)) {
+ }
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.NULL) {
+ return new NullLiteral(getAndAdvance());
+ } else if (keyword == Keyword.NEW) {
return _parseNewExpression();
- } else if (_matchesKeyword(Keyword.CONST)) {
+ } else if (keyword == Keyword.THIS) {
+ return new ThisExpression(getAndAdvance());
+ } else if (keyword == Keyword.SUPER) {
+ // TODO(paulberry): verify with Gilad that "super" must be followed by
+ // unconditionalAssignableSelector in this case.
+ return _parseAssignableSelector(
+ new SuperExpression(getAndAdvance()), false,
+ allowConditional: false);
+ } else if (keyword == Keyword.FALSE) {
+ return new BooleanLiteral(getAndAdvance(), false);
+ } else if (keyword == Keyword.TRUE) {
+ return new BooleanLiteral(getAndAdvance(), true);
+ }
+ if (type == TokenType.DOUBLE) {
+ Token token = getAndAdvance();
+ double value = 0.0;
+ try {
+ value = double.parse(token.lexeme);
+ } on FormatException {
+ // The invalid format should have been reported by the scanner.
+ }
+ return new DoubleLiteral(token, value);
+ } else if (type == TokenType.HEXADECIMAL) {
+ Token token = getAndAdvance();
+ int value = null;
+ try {
+ value = int.parse(token.lexeme.substring(2), radix: 16);
+ } on FormatException {
+ // The invalid format should have been reported by the scanner.
+ }
+ return new IntegerLiteral(token, value);
+ } else if (keyword == Keyword.CONST) {
return _parseConstExpression();
- } else if (_matches(TokenType.OPEN_PAREN)) {
+ } else if (type == TokenType.OPEN_PAREN) {
if (_isFunctionExpression(_currentToken)) {
return parseFunctionExpression();
}
@@ -7461,20 +7827,20 @@
} finally {
_inInitializer = wasInInitializer;
}
- } else if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) {
+ } else if (type == TokenType.LT || _injectGenericCommentTypeList()) {
return _parseListOrMapLiteral(null);
- } else if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
+ } else if (type == TokenType.OPEN_CURLY_BRACKET) {
return _parseMapLiteral(null, null);
- } else if (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
- _matches(TokenType.INDEX)) {
+ } else if (type == TokenType.OPEN_SQUARE_BRACKET ||
+ type == TokenType.INDEX) {
return _parseListLiteral(null, null);
- } else if (_matches(TokenType.QUESTION) &&
+ } else if (type == TokenType.QUESTION &&
_tokenMatches(_peek(), TokenType.IDENTIFIER)) {
_reportErrorForCurrentToken(
ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
_advance();
return _parsePrimaryExpression();
- } else if (_matchesKeyword(Keyword.VOID)) {
+ } else if (keyword == Keyword.VOID) {
//
// Recover from having a return type of "void" where a return type is not
// expected.
@@ -7484,7 +7850,7 @@
ParserErrorCode.UNEXPECTED_TOKEN, [_currentToken.lexeme]);
_advance();
return _parsePrimaryExpression();
- } else if (_matches(TokenType.HASH)) {
+ } else if (type == TokenType.HASH) {
return _parseSymbolLiteral();
} else {
_reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER);
@@ -7493,21 +7859,31 @@
}
/**
- * Parse a redirecting constructor invocation. Return the redirecting
+ * Parse a redirecting constructor invocation. The flag [hasPeriod] should be
+ * `true` if the `this` is followed by a period. Return the redirecting
* constructor invocation that was parsed.
*
+ * This method assumes that the current token matches `Keyword.THIS`.
+ *
* redirectingConstructorInvocation ::=
* 'this' ('.' identifier)? arguments
*/
- RedirectingConstructorInvocation _parseRedirectingConstructorInvocation() {
- Token keyword = _expectKeyword(Keyword.THIS);
+ RedirectingConstructorInvocation _parseRedirectingConstructorInvocation(
+ bool hasPeriod) {
+ Token keyword = getAndAdvance();
Token period = null;
SimpleIdentifier constructorName = null;
- if (_matches(TokenType.PERIOD)) {
+ if (hasPeriod) {
period = getAndAdvance();
- constructorName = parseSimpleIdentifier();
+ if (_matchesIdentifier()) {
+ constructorName = _parseSimpleIdentifierUnchecked(isDeclaration: false);
+ } else {
+ _reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER);
+ constructorName = _createSyntheticIdentifier(isDeclaration: false);
+ _advance();
+ }
}
- ArgumentList argumentList = parseArgumentList();
+ ArgumentList argumentList = _parseArgumentListChecked();
return new RedirectingConstructorInvocation(
keyword, period, constructorName, argumentList);
}
@@ -7521,29 +7897,29 @@
* | 'super' relationalOperator bitwiseOrExpression
*/
Expression _parseRelationalExpression() {
- if (_matchesKeyword(Keyword.SUPER) &&
+ if (_currentToken.keyword == Keyword.SUPER &&
_currentToken.next.type.isRelationalOperator) {
Expression expression = new SuperExpression(getAndAdvance());
Token operator = getAndAdvance();
- expression = new BinaryExpression(
+ return new BinaryExpression(
expression, operator, parseBitwiseOrExpression());
- return expression;
}
Expression expression = parseBitwiseOrExpression();
- if (_matchesKeyword(Keyword.AS)) {
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.AS) {
Token asOperator = getAndAdvance();
- expression = new AsExpression(expression, asOperator, parseTypeName());
- } else if (_matchesKeyword(Keyword.IS)) {
+ return new AsExpression(expression, asOperator, parseTypeName());
+ } else if (keyword == Keyword.IS) {
Token isOperator = getAndAdvance();
Token notOperator = null;
if (_matches(TokenType.BANG)) {
notOperator = getAndAdvance();
}
- expression = new IsExpression(
+ return new IsExpression(
expression, isOperator, notOperator, parseTypeName());
} else if (_currentToken.type.isRelationalOperator) {
Token operator = getAndAdvance();
- expression = new BinaryExpression(
+ return new BinaryExpression(
expression, operator, parseBitwiseOrExpression());
}
return expression;
@@ -7552,20 +7928,24 @@
/**
* Parse a rethrow expression. Return the rethrow expression that was parsed.
*
+ * This method assumes that the current token matches `Keyword.RETHROW`.
+ *
* rethrowExpression ::=
* 'rethrow'
*/
Expression _parseRethrowExpression() =>
- new RethrowExpression(_expectKeyword(Keyword.RETHROW));
+ new RethrowExpression(getAndAdvance());
/**
* Parse a return statement. Return the return statement that was parsed.
*
+ * This method assumes that the current token matches `Keyword.RETURN`.
+ *
* returnStatement ::=
* 'return' expression? ';'
*/
Statement _parseReturnStatement() {
- Token returnKeyword = _expectKeyword(Keyword.RETURN);
+ Token returnKeyword = getAndAdvance();
if (_matches(TokenType.SEMICOLON)) {
return new ReturnStatement(returnKeyword, null, getAndAdvance());
}
@@ -7582,6 +7962,8 @@
* already been parsed, or `null` if there was no return type. Return the
* setter that was parsed.
*
+ * This method assumes that the current token matches `Keyword.SET`.
+ *
* setter ::=
* setterSignature functionBody?
*
@@ -7590,7 +7972,7 @@
*/
MethodDeclaration _parseSetter(CommentAndMetadata commentAndMetadata,
Token externalKeyword, Token staticKeyword, TypeName returnType) {
- Token propertyKeyword = _expectKeyword(Keyword.SET);
+ Token propertyKeyword = getAndAdvance();
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
FormalParameterList parameters = parseFormalParameterList();
_validateFormalParameterList(parameters);
@@ -7624,21 +8006,39 @@
*/
Expression _parseShiftExpression() {
Expression expression;
- if (_matchesKeyword(Keyword.SUPER) &&
+ if (_currentToken.keyword == Keyword.SUPER &&
_currentToken.next.type.isShiftOperator) {
expression = new SuperExpression(getAndAdvance());
} else {
expression = _parseAdditiveExpression();
}
while (_currentToken.type.isShiftOperator) {
- Token operator = getAndAdvance();
expression = new BinaryExpression(
- expression, operator, _parseAdditiveExpression());
+ expression, getAndAdvance(), _parseAdditiveExpression());
}
return expression;
}
/**
+ * Parse a simple identifier. Return the simple identifier that was parsed.
+ *
+ * This method assumes that the current token matches an identifier.
+ *
+ * identifier ::=
+ * IDENTIFIER
+ */
+ SimpleIdentifier _parseSimpleIdentifierUnchecked(
+ {bool isDeclaration: false}) {
+ String lexeme = _currentToken.lexeme;
+ if ((_inAsync || _inGenerator) &&
+ (lexeme == ASYNC || lexeme == _AWAIT || lexeme == _YIELD)) {
+ _reportErrorForCurrentToken(
+ ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER);
+ }
+ return new SimpleIdentifier(getAndAdvance(), isDeclaration: isDeclaration);
+ }
+
+ /**
* Parse a list of statements within a switch statement. Return the statements
* that were parsed.
*
@@ -7646,10 +8046,11 @@
* statement*
*/
List<Statement> _parseStatementList() {
- List<Statement> statements = new List<Statement>();
+ List<Statement> statements = <Statement>[];
Token statementStart = _currentToken;
- while (!_matches(TokenType.EOF) &&
- !_matches(TokenType.CLOSE_CURLY_BRACKET) &&
+ TokenType type = _currentToken.type;
+ while (type != TokenType.EOF &&
+ type != TokenType.CLOSE_CURLY_BRACKET &&
!_isSwitchMember()) {
statements.add(parseStatement2());
if (identical(_currentToken, statementStart)) {
@@ -7658,6 +8059,7 @@
_advance();
}
statementStart = _currentToken;
+ type = _currentToken.type;
}
return statements;
}
@@ -7665,15 +8067,20 @@
/**
* Parse a string literal that contains interpolations. Return the string
* literal that was parsed.
+ *
+ * This method assumes that the current token matches either
+ * [TokenType.STRING_INTERPOLATION_EXPRESSION] or
+ * [TokenType.STRING_INTERPOLATION_IDENTIFIER].
*/
StringInterpolation _parseStringInterpolation(Token string) {
- List<InterpolationElement> elements = new List<InterpolationElement>();
- bool hasMore = _matches(TokenType.STRING_INTERPOLATION_EXPRESSION) ||
- _matches(TokenType.STRING_INTERPOLATION_IDENTIFIER);
- elements.add(new InterpolationString(
- string, _computeStringValue(string.lexeme, true, !hasMore)));
+ List<InterpolationElement> elements = <InterpolationElement>[
+ new InterpolationString(
+ string, _computeStringValue(string.lexeme, true, false))
+ ];
+ bool hasMore = true;
+ bool isExpression = _matches(TokenType.STRING_INTERPOLATION_EXPRESSION);
while (hasMore) {
- if (_matches(TokenType.STRING_INTERPOLATION_EXPRESSION)) {
+ if (isExpression) {
Token openToken = getAndAdvance();
bool wasInInitializer = _inInitializer;
_inInitializer = false;
@@ -7697,8 +8104,9 @@
}
if (_matches(TokenType.STRING)) {
string = getAndAdvance();
- hasMore = _matches(TokenType.STRING_INTERPOLATION_EXPRESSION) ||
- _matches(TokenType.STRING_INTERPOLATION_IDENTIFIER);
+ isExpression = _matches(TokenType.STRING_INTERPOLATION_EXPRESSION);
+ hasMore =
+ isExpression || _matches(TokenType.STRING_INTERPOLATION_IDENTIFIER);
elements.add(new InterpolationString(
string, _computeStringValue(string.lexeme, false, !hasMore)));
} else {
@@ -7709,21 +8117,47 @@
}
/**
+ * Parse a string literal. Return the string literal that was parsed.
+ *
+ * This method assumes that the current token matches `TokenType.STRING`.
+ *
+ * stringLiteral ::=
+ * MULTI_LINE_STRING+
+ * | SINGLE_LINE_STRING+
+ */
+ StringLiteral _parseStringLiteralUnchecked() {
+ List<StringLiteral> strings = <StringLiteral>[];
+ do {
+ Token string = getAndAdvance();
+ if (_matches(TokenType.STRING_INTERPOLATION_EXPRESSION) ||
+ _matches(TokenType.STRING_INTERPOLATION_IDENTIFIER)) {
+ strings.add(_parseStringInterpolation(string));
+ } else {
+ strings.add(new SimpleStringLiteral(
+ string, _computeStringValue(string.lexeme, true, true)));
+ }
+ } while (_matches(TokenType.STRING));
+ return strings.length == 1 ? strings[0] : new AdjacentStrings(strings);
+ }
+
+ /**
* Parse a super constructor invocation. Return the super constructor
* invocation that was parsed.
*
+ * This method assumes that the current token matches [Keyword.SUPER].
+ *
* superConstructorInvocation ::=
* 'super' ('.' identifier)? arguments
*/
SuperConstructorInvocation _parseSuperConstructorInvocation() {
- Token keyword = _expectKeyword(Keyword.SUPER);
+ Token keyword = getAndAdvance();
Token period = null;
SimpleIdentifier constructorName = null;
if (_matches(TokenType.PERIOD)) {
period = getAndAdvance();
constructorName = parseSimpleIdentifier();
}
- ArgumentList argumentList = parseArgumentList();
+ ArgumentList argumentList = _parseArgumentListChecked();
return new SuperConstructorInvocation(
keyword, period, constructorName, argumentList);
}
@@ -7751,14 +8185,14 @@
Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
Token leftBracket = _expect(TokenType.OPEN_CURLY_BRACKET);
Token defaultKeyword = null;
- List<SwitchMember> members = new List<SwitchMember>();
- while (!_matches(TokenType.EOF) &&
- !_matches(TokenType.CLOSE_CURLY_BRACKET)) {
- List<Label> labels = new List<Label>();
+ List<SwitchMember> members = <SwitchMember>[];
+ TokenType type = _currentToken.type;
+ while (type != TokenType.EOF && type != TokenType.CLOSE_CURLY_BRACKET) {
+ List<Label> labels = <Label>[];
while (
_matchesIdentifier() && _tokenMatches(_peek(), TokenType.COLON)) {
SimpleIdentifier identifier =
- parseSimpleIdentifier(isDeclaration: true);
+ _parseSimpleIdentifierUnchecked(isDeclaration: true);
String label = identifier.token.lexeme;
if (definedLabels.contains(label)) {
_reportErrorForToken(
@@ -7768,10 +8202,11 @@
} else {
definedLabels.add(label);
}
- Token colon = _expect(TokenType.COLON);
+ Token colon = getAndAdvance();
labels.add(new Label(identifier, colon));
}
- if (_matchesKeyword(Keyword.CASE)) {
+ Keyword keyword = _currentToken.keyword;
+ if (keyword == Keyword.CASE) {
Token caseKeyword = getAndAdvance();
Expression caseExpression = parseExpression2();
Token colon = _expect(TokenType.COLON);
@@ -7782,7 +8217,7 @@
ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE,
caseKeyword);
}
- } else if (_matchesKeyword(Keyword.DEFAULT)) {
+ } else if (keyword == Keyword.DEFAULT) {
if (defaultKeyword != null) {
_reportErrorForToken(
ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES, _peek());
@@ -7795,13 +8230,20 @@
// We need to advance, otherwise we could end up in an infinite loop,
// but this could be a lot smarter about recovering from the error.
_reportErrorForCurrentToken(ParserErrorCode.EXPECTED_CASE_OR_DEFAULT);
- while (!_matches(TokenType.EOF) &&
- !_matches(TokenType.CLOSE_CURLY_BRACKET) &&
- !_matchesKeyword(Keyword.CASE) &&
- !_matchesKeyword(Keyword.DEFAULT)) {
+ bool atEndOrNextMember() {
+ TokenType type = _currentToken.type;
+ if (type == TokenType.EOF ||
+ type == TokenType.CLOSE_CURLY_BRACKET) {
+ return true;
+ }
+ Keyword keyword = _currentToken.keyword;
+ return keyword == Keyword.CASE || keyword == Keyword.DEFAULT;
+ }
+ while (!atEndOrNextMember()) {
_advance();
}
}
+ type = _currentToken.type;
}
Token rightBracket = _expect(TokenType.CLOSE_CURLY_BRACKET);
return new SwitchStatement(keyword, leftParenthesis, expression,
@@ -7814,16 +8256,17 @@
/**
* Parse a symbol literal. Return the symbol literal that was parsed.
*
+ * This method assumes that the current token matches [TokenType.HASH].
+ *
* symbolLiteral ::=
* '#' identifier ('.' identifier)*
*/
SymbolLiteral _parseSymbolLiteral() {
Token poundSign = getAndAdvance();
- List<Token> components = new List<Token>();
+ List<Token> components = <Token>[];
if (_matchesIdentifier()) {
components.add(getAndAdvance());
- while (_matches(TokenType.PERIOD)) {
- _advance();
+ while (_optional(TokenType.PERIOD)) {
if (_matchesIdentifier()) {
components.add(getAndAdvance());
} else {
@@ -7834,7 +8277,7 @@
}
} else if (_currentToken.isOperator) {
components.add(getAndAdvance());
- } else if (_tokenMatchesKeyword(_currentToken, Keyword.VOID)) {
+ } else if (_matchesKeyword(Keyword.VOID)) {
components.add(getAndAdvance());
} else {
_reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER);
@@ -7846,12 +8289,15 @@
/**
* Parse a throw expression. Return the throw expression that was parsed.
*
+ * This method assumes that the current token matches [Keyword.THROW].
+ *
* throwExpression ::=
* 'throw' expression
*/
Expression _parseThrowExpression() {
- Token keyword = _expectKeyword(Keyword.THROW);
- if (_matches(TokenType.SEMICOLON) || _matches(TokenType.CLOSE_PAREN)) {
+ Token keyword = getAndAdvance();
+ TokenType type = _currentToken.type;
+ if (type == TokenType.SEMICOLON || type == TokenType.CLOSE_PAREN) {
_reportErrorForToken(
ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken);
return new ThrowExpression(keyword, _createSyntheticIdentifier());
@@ -7863,12 +8309,15 @@
/**
* Parse a throw expression. Return the throw expression that was parsed.
*
+ * This method assumes that the current token matches [Keyword.THROW].
+ *
* throwExpressionWithoutCascade ::=
* 'throw' expressionWithoutCascade
*/
Expression _parseThrowExpressionWithoutCascade() {
- Token keyword = _expectKeyword(Keyword.THROW);
- if (_matches(TokenType.SEMICOLON) || _matches(TokenType.CLOSE_PAREN)) {
+ Token keyword = getAndAdvance();
+ TokenType type = _currentToken.type;
+ if (type == TokenType.SEMICOLON || type == TokenType.CLOSE_PAREN) {
_reportErrorForToken(
ParserErrorCode.MISSING_EXPRESSION_IN_THROW, _currentToken);
return new ThrowExpression(keyword, _createSyntheticIdentifier());
@@ -7880,6 +8329,8 @@
/**
* Parse a try statement. Return the try statement that was parsed.
*
+ * This method assumes that the current token matches [Keyword.TRY].
+ *
* tryStatement ::=
* 'try' block (onPart+ finallyPart? | finallyPart)
*
@@ -7894,9 +8345,9 @@
* 'finally' block
*/
Statement _parseTryStatement() {
- Token tryKeyword = _expectKeyword(Keyword.TRY);
- Block body = parseBlock();
- List<CatchClause> catchClauses = new List<CatchClause>();
+ Token tryKeyword = getAndAdvance();
+ Block body = _parseBlockChecked();
+ List<CatchClause> catchClauses = <CatchClause>[];
Block finallyClause = null;
while (_matchesString(_ON) || _matchesKeyword(Keyword.CATCH)) {
Token onKeyword = null;
@@ -7921,7 +8372,7 @@
}
rightParenthesis = _expect(TokenType.CLOSE_PAREN);
}
- Block catchBody = parseBlock();
+ Block catchBody = _parseBlockChecked();
catchClauses.add(new CatchClause(
onKeyword,
exceptionType,
@@ -7936,11 +8387,9 @@
Token finallyKeyword = null;
if (_matchesKeyword(Keyword.FINALLY)) {
finallyKeyword = getAndAdvance();
- finallyClause = parseBlock();
- } else {
- if (catchClauses.isEmpty) {
- _reportErrorForCurrentToken(ParserErrorCode.MISSING_CATCH_OR_FINALLY);
- }
+ finallyClause = _parseBlockChecked();
+ } else if (catchClauses.isEmpty) {
+ _reportErrorForCurrentToken(ParserErrorCode.MISSING_CATCH_OR_FINALLY);
}
return new TryStatement(
tryKeyword, body, catchClauses, finallyKeyword, finallyClause);
@@ -7950,6 +8399,8 @@
* Parse a type alias. The [commentAndMetadata] is the metadata to be
* associated with the member. Return the type alias that was parsed.
*
+ * This method assumes that the current token matches [Keyword.TYPEDEF].
+ *
* typeAlias ::=
* 'typedef' typeAliasBody
*
@@ -7970,7 +8421,7 @@
* returnType? name
*/
TypeAlias _parseTypeAlias(CommentAndMetadata commentAndMetadata) {
- Token keyword = _expectKeyword(Keyword.TYPEDEF);
+ Token keyword = getAndAdvance();
if (_matchesIdentifier()) {
Token next = _peek();
if (_tokenMatches(next, TokenType.LT)) {
@@ -7995,11 +8446,11 @@
TypeName _parseTypeName() {
Identifier typeName;
- if (_matchesKeyword(Keyword.VAR)) {
+ if (_matchesIdentifier()) {
+ typeName = _parsePrefixedIdentifierUnchecked();
+ } else if (_matchesKeyword(Keyword.VAR)) {
_reportErrorForCurrentToken(ParserErrorCode.VAR_AS_TYPE_NAME);
typeName = new SimpleIdentifier(getAndAdvance());
- } else if (_matchesIdentifier()) {
- typeName = parsePrefixedIdentifier();
} else {
typeName = _createSyntheticIdentifier();
_reportErrorForCurrentToken(ParserErrorCode.EXPECTED_TYPE_NAME);
@@ -8009,6 +8460,25 @@
}
/**
+ * Parse a type name. Return the type name that was parsed.
+ *
+ * This method assumes that the current token is an identifier.
+ *
+ * type ::=
+ * qualified typeArguments?
+ */
+ TypeName _parseTypeNameAfterIdentifier() {
+ Identifier typeName = _parsePrefixedIdentifierUnchecked();
+ TypeArgumentList typeArguments = _parseOptionalTypeArguments();
+ // If this is followed by a generic method type comment, allow the comment
+ // type to replace the real type name.
+ // TODO(jmesserly): this feels like a big hammer. Can we restrict it to
+ // only work inside generic methods?
+ TypeName typeFromComment = _parseOptionalTypeNameComment();
+ return typeFromComment ?? new TypeName(typeName, typeArguments);
+ }
+
+ /**
* Parse a unary expression. Return the unary expression that was parsed.
*
* unaryExpression ::=
@@ -8020,13 +8490,15 @@
* | incrementOperator assignableExpression
*/
Expression _parseUnaryExpression() {
- if (_matches(TokenType.MINUS) ||
- _matches(TokenType.BANG) ||
- _matches(TokenType.TILDE)) {
+ TokenType type = _currentToken.type;
+ if (type == TokenType.MINUS ||
+ type == TokenType.BANG ||
+ type == TokenType.TILDE) {
Token operator = getAndAdvance();
if (_matchesKeyword(Keyword.SUPER)) {
- if (_tokenMatches(_peek(), TokenType.OPEN_SQUARE_BRACKET) ||
- _tokenMatches(_peek(), TokenType.PERIOD)) {
+ TokenType nextType = _peek().type;
+ if (nextType == TokenType.OPEN_SQUARE_BRACKET ||
+ nextType == TokenType.PERIOD) {
// "prefixOperator unaryExpression"
// --> "prefixOperator postfixExpression"
// --> "prefixOperator primary selector*"
@@ -8040,8 +8512,9 @@
} else if (_currentToken.type.isIncrementOperator) {
Token operator = getAndAdvance();
if (_matchesKeyword(Keyword.SUPER)) {
- if (_tokenMatches(_peek(), TokenType.OPEN_SQUARE_BRACKET) ||
- _tokenMatches(_peek(), TokenType.PERIOD)) {
+ TokenType nextType = _peek().type;
+ if (nextType == TokenType.OPEN_SQUARE_BRACKET ||
+ nextType == TokenType.PERIOD) {
// --> "prefixOperator 'super' assignableSelector selector*"
return new PrefixExpression(operator, _parseUnaryExpression());
}
@@ -8052,7 +8525,7 @@
// we cannot do the same for "++super" because "+super" is also not
// valid.
//
- if (operator.type == TokenType.MINUS_MINUS) {
+ if (type == TokenType.MINUS_MINUS) {
Token firstOperator = _createToken(operator, TokenType.MINUS);
Token secondOperator =
new Token(TokenType.MINUS, operator.offset + 1);
@@ -8063,16 +8536,16 @@
firstOperator,
new PrefixExpression(
secondOperator, new SuperExpression(getAndAdvance())));
- } else {
- // Invalid operator before 'super'
- _reportErrorForCurrentToken(
- ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.lexeme]);
- return new PrefixExpression(
- operator, new SuperExpression(getAndAdvance()));
}
+ // Invalid operator before 'super'
+ _reportErrorForCurrentToken(
+ ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, [operator.lexeme]);
+ return new PrefixExpression(
+ operator, new SuperExpression(getAndAdvance()));
}
- return new PrefixExpression(operator, _parseAssignableExpression(false));
- } else if (_matches(TokenType.PLUS)) {
+ return new PrefixExpression(
+ operator, _parseAssignableExpressionNotStartingWithSuper(false));
+ } else if (type == TokenType.PLUS) {
_reportErrorForCurrentToken(ParserErrorCode.MISSING_IDENTIFIER);
return _createSyntheticIdentifier();
} else if (_inAsync && _matchesString(_AWAIT)) {
@@ -8086,28 +8559,35 @@
* was parsed.
*/
StringLiteral _parseUri() {
- bool iskeywordAfterUri(Token token) =>
+ // TODO(brianwilkerson) Should this function also return true for valid
+ // top-level keywords?
+ bool isKeywordAfterUri(Token token) =>
token.lexeme == Keyword.AS.syntax ||
token.lexeme == _HIDE ||
token.lexeme == _SHOW;
- if (!_matches(TokenType.STRING) &&
- !_matches(TokenType.SEMICOLON) &&
- !iskeywordAfterUri(_currentToken)) {
+ TokenType type = _currentToken.type;
+ if (type != TokenType.STRING &&
+ type != TokenType.SEMICOLON &&
+ !isKeywordAfterUri(_currentToken)) {
// Attempt to recover in the case where the URI was not enclosed in
// quotes.
Token token = _currentToken;
- while ((_tokenMatchesIdentifier(token) && !iskeywordAfterUri(token)) ||
- _tokenMatches(token, TokenType.COLON) ||
- _tokenMatches(token, TokenType.SLASH) ||
- _tokenMatches(token, TokenType.PERIOD) ||
- _tokenMatches(token, TokenType.PERIOD_PERIOD) ||
- _tokenMatches(token, TokenType.PERIOD_PERIOD_PERIOD) ||
- _tokenMatches(token, TokenType.INT) ||
- _tokenMatches(token, TokenType.DOUBLE)) {
+ bool isValidInUri(Token token) {
+ TokenType type = token.type;
+ return type == TokenType.COLON ||
+ type == TokenType.SLASH ||
+ type == TokenType.PERIOD ||
+ type == TokenType.PERIOD_PERIOD ||
+ type == TokenType.PERIOD_PERIOD_PERIOD ||
+ type == TokenType.INT ||
+ type == TokenType.DOUBLE;
+ }
+ while ((_tokenMatchesIdentifier(token) && !isKeywordAfterUri(token)) ||
+ isValidInUri(token)) {
token = token.next;
}
if (_tokenMatches(token, TokenType.SEMICOLON) ||
- iskeywordAfterUri(token)) {
+ isKeywordAfterUri(token)) {
Token endToken = token.previous;
token = _currentToken;
int endOffset = token.end;
@@ -8193,10 +8673,10 @@
_tokenMatchesKeyword(keyword, Keyword.VAR)) {
_reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, keyword);
}
- List<VariableDeclaration> variables = new List<VariableDeclaration>();
- variables.add(_parseVariableDeclaration());
- while (_matches(TokenType.COMMA)) {
- _advance();
+ List<VariableDeclaration> variables = <VariableDeclaration>[
+ _parseVariableDeclaration()
+ ];
+ while (_optional(TokenType.COMMA)) {
variables.add(_parseVariableDeclaration());
}
return new VariableDeclarationList(commentAndMetadata?.comment,
@@ -8250,6 +8730,8 @@
/**
* Parse a while statement. Return the while statement that was parsed.
*
+ * This method assumes that the current token matches [Keyword.WHILE].
+ *
* whileStatement ::=
* 'while' '(' expression ')' statement
*/
@@ -8257,7 +8739,7 @@
bool wasInLoop = _inLoop;
_inLoop = true;
try {
- Token keyword = _expectKeyword(Keyword.WHILE);
+ Token keyword = getAndAdvance();
Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
Expression condition = parseExpression2();
Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
@@ -8272,6 +8754,8 @@
/**
* Parse a yield statement. Return the yield statement that was parsed.
*
+ * This method assumes that the current token matches [Keyword.YIELD].
+ *
* yieldStatement ::=
* 'yield' '*'? expression ';'
*/
@@ -8415,8 +8899,8 @@
* | type
*/
Token _skipFinalConstVarOrType(Token startToken) {
- if (_tokenMatchesKeyword(startToken, Keyword.FINAL) ||
- _tokenMatchesKeyword(startToken, Keyword.CONST)) {
+ Keyword keyword = startToken.keyword;
+ if (keyword == Keyword.FINAL || keyword == Keyword.CONST) {
Token next = startToken.next;
if (_tokenMatchesIdentifier(next)) {
Token next2 = next.next;
@@ -8429,7 +8913,7 @@
// "parameter"
return next;
}
- } else if (_tokenMatchesKeyword(startToken, Keyword.VAR)) {
+ } else if (keyword == Keyword.VAR) {
return startToken.next;
} else if (_tokenMatchesIdentifier(startToken)) {
Token next = startToken.next;
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index cf2ced8..d74e925 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -262,7 +262,6 @@
@override
Object visitMethodInvocation(MethodInvocation node) {
_checkForCanBeNullAfterNullAware(node.realTarget, node.operator);
- _checkForInvalidProtectedMethodCalls(node);
DartType staticInvokeType = node.staticInvokeType;
if (staticInvokeType is InterfaceType) {
MethodElement methodElement = staticInvokeType.lookUpMethod(
@@ -300,7 +299,7 @@
@override
Object visitSimpleIdentifier(SimpleIdentifier node) {
_checkForDeprecatedMemberUseAtIdentifier(node);
- _checkForInvalidProtectedPropertyAccess(node);
+ _checkForInvalidProtectedMemberAccess(node);
return super.visitSimpleIdentifier(node);
}
@@ -678,61 +677,35 @@
}
/**
- * Produces a hint if the given invocation is of a protected method outside
- * a subclass instance method.
+ * Produces a hint if the given identifier is a protected closure, field or
+ * getter/setter, method closure or invocation accessed outside a subclass.
*/
- void _checkForInvalidProtectedMethodCalls(MethodInvocation node) {
- Element element = node.methodName.bestElement;
- if (element == null || !element.isProtected) {
- return;
- }
-
- ClassElement definingClass = element.enclosingElement;
-
- MethodDeclaration decl =
- node.getAncestor((AstNode node) => node is MethodDeclaration);
- if (decl == null) {
- _errorReporter.reportErrorForNode(
- HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
- node,
- [node.methodName.toString(), definingClass.name]);
- return;
- }
-
- ClassElement invokingClass = decl.element?.enclosingElement;
- if (invokingClass != null) {
- if (!_hasSuperClassOrMixin(invokingClass, definingClass.type)) {
- _errorReporter.reportErrorForNode(
- HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
- node,
- [node.methodName.toString(), definingClass.name]);
- }
- }
- }
-
- /**
- * Produces a hint if the given identifier is a protected field or getter
- * accessed outside a subclass.
- */
- void _checkForInvalidProtectedPropertyAccess(SimpleIdentifier identifier) {
+ void _checkForInvalidProtectedMemberAccess(SimpleIdentifier identifier) {
if (identifier.inDeclarationContext()) {
return;
}
+
+ bool isProtected(Element element) {
+ if (element is PropertyAccessorElement &&
+ element.enclosingElement is ClassElement &&
+ (element.isProtected || element.variable.isProtected)) {
+ return true;
+ }
+ if (element is MethodElement &&
+ element.enclosingElement is ClassElement &&
+ element.isProtected) {
+ return true;
+ }
+ return false;
+ }
+
Element element = identifier.bestElement;
- if (element is PropertyAccessorElement &&
- element.enclosingElement is ClassElement &&
- (element.isProtected || element.variable.isProtected)) {
+ if (isProtected(element)) {
ClassElement definingClass = element.enclosingElement;
ClassDeclaration accessingClass =
identifier.getAncestor((AstNode node) => node is ClassDeclaration);
-
- if (accessingClass == null) {
- _errorReporter.reportErrorForNode(
- HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
- identifier,
- [identifier.name.toString(), definingClass.name]);
- } else if (!_hasSuperClassOrMixin(
- accessingClass.element, definingClass.type)) {
+ if (accessingClass == null ||
+ !_hasTypeOrSuperType(accessingClass.element, definingClass.type)) {
_errorReporter.reportErrorForNode(
HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
identifier,
@@ -962,6 +935,25 @@
}
/**
+ * Check for situations where the result of a method or function is used, when
+ * it returns 'void'.
+ *
+ * See [HintCode.USE_OF_VOID_RESULT].
+ */
+ void _checkForUseOfVoidResult(Expression expression) {
+ // TODO(jwren) Many other situations of use could be covered. We currently
+ // cover the cases var x = m() and x = m(), but we could also cover cases
+ // such as m().x, m()[k], a + m(), f(m()), return m().
+ if (expression is MethodInvocation) {
+ if (identical(expression.staticType, VoidTypeImpl.instance)) {
+ SimpleIdentifier methodName = expression.methodName;
+ _errorReporter.reportErrorForNode(
+ HintCode.USE_OF_VOID_RESULT, methodName, [methodName.name]);
+ }
+ }
+ }
+
+ /**
* Check for the passed class declaration for the
* [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
*
@@ -990,41 +982,14 @@
// return false;
// }
- /**
- * Check for situations where the result of a method or function is used, when
- * it returns 'void'.
- *
- * See [HintCode.USE_OF_VOID_RESULT].
- */
- void _checkForUseOfVoidResult(Expression expression) {
- // TODO(jwren) Many other situations of use could be covered. We currently
- // cover the cases var x = m() and x = m(), but we could also cover cases
- // such as m().x, m()[k], a + m(), f(m()), return m().
- if (expression is MethodInvocation) {
- if (identical(expression.staticType, VoidTypeImpl.instance)) {
- SimpleIdentifier methodName = expression.methodName;
- _errorReporter.reportErrorForNode(
- HintCode.USE_OF_VOID_RESULT, methodName, [methodName.name]);
- }
+ bool _hasTypeOrSuperType(ClassElement element, InterfaceType type) {
+ if (element == null) {
+ return false;
}
- }
-
- bool _hasSuperClassOrMixin(ClassElement element, InterfaceType type) {
- List<ClassElement> seenClasses = <ClassElement>[];
- while (element != null && !seenClasses.contains(element)) {
- if (element.type == type) {
- return true;
- }
-
- if (element.mixins.any((InterfaceType t) => t == type)) {
- return true;
- }
-
- seenClasses.add(element);
- element = element.supertype?.element;
- }
-
- return false;
+ ClassElement typeElement = type.element;
+ return element == typeElement ||
+ element.allSupertypes
+ .any((InterfaceType t) => t.element == typeElement);
}
/**
@@ -2079,22 +2044,25 @@
/**
* Given some [NodeList] of [Statement]s, from either a [Block] or
- * [SwitchMember], this loops through the list in reverse order searching for statements
- * after a return, unlabeled break or unlabeled continue statement to mark them as dead code.
+ * [SwitchMember], this loops through the list searching for dead statements.
*
* @param statements some ordered list of statements in a [Block] or [SwitchMember]
*/
void _checkForDeadStatementsInNodeList(NodeList<Statement> statements) {
+ bool statementExits(Statement statement) {
+ if (statement is BreakStatement) {
+ return statement.label == null;
+ } else if (statement is ContinueStatement) {
+ return statement.label == null;
+ }
+ return ExitDetector.exits(statement);
+ }
+
int size = statements.length;
for (int i = 0; i < size; i++) {
Statement currentStatement = statements[i];
currentStatement?.accept(this);
- bool returnOrBreakingStatement = currentStatement is ReturnStatement ||
- (currentStatement is BreakStatement &&
- currentStatement.label == null) ||
- (currentStatement is ContinueStatement &&
- currentStatement.label == null);
- if (returnOrBreakingStatement && i != size - 1) {
+ if (statementExits(currentStatement) && i != size - 1) {
Statement nextStatement = statements[i + 1];
Statement lastStatement = statements[size - 1];
int offset = nextStatement.offset;
@@ -3346,9 +3314,8 @@
//
// Finish building the enum.
//
- ClassElementImpl enumElement = node.name.staticElement as ClassElementImpl;
+ EnumElementImpl enumElement = node.name.staticElement as EnumElementImpl;
InterfaceType enumType = enumElement.type;
- enumElement.supertype = _typeProvider.objectType;
//
// Populate the fields.
//
@@ -3407,19 +3374,10 @@
}
/**
- * Create a getter that corresponds to the given field.
- *
- * @param field the field for which a getter is to be created
- * @return the getter that was created
+ * Create a getter that corresponds to the given [field].
*/
PropertyAccessorElement _createGetter(FieldElementImpl field) {
- PropertyAccessorElementImpl getter =
- new PropertyAccessorElementImpl.forVariable(field);
- getter.getter = true;
- getter.returnType = field.type;
- getter.type = new FunctionTypeImpl(getter);
- field.getter = getter;
- return getter;
+ return new PropertyAccessorElementImpl_ImplicitGetter(field);
}
}
@@ -3817,18 +3775,7 @@
return false;
}
}
- // All of the members exit, determine whether there are possible cases
- // that are not caught by the members.
- DartType type = node.expression?.bestType;
- if (type is InterfaceType) {
- ClassElement element = type.element;
- if (element != null && element.isEnum) {
- // If some of the enum values are not covered, then a warning will
- // have already been generated, so there's no point in generating a
- // hint.
- return true;
- }
- }
+ // As all cases exit, return whether that list includes `default`.
return hasDefault;
} finally {
_enclosingBlockContainsBreak = outerBreakValue;
@@ -3905,6 +3852,9 @@
}
}
+ @override
+ bool visitYieldStatement(YieldStatement node) => _nodeExits(node.expression);
+
/**
* Return `true` if the given node exits.
*
@@ -9995,8 +9945,7 @@
@override
Object visitConstructorDeclaration(ConstructorDeclaration node) {
super.visitConstructorDeclaration(node);
- ExecutableElementImpl element = node.element as ExecutableElementImpl;
- if (element == null) {
+ if (node.element == null) {
ClassDeclaration classNode =
node.getAncestor((node) => node is ClassDeclaration);
StringBuffer buffer = new StringBuffer();
@@ -10013,10 +9962,6 @@
buffer.write(" was not set while trying to resolve types.");
AnalysisEngine.instance.logger.logError(buffer.toString(),
new CaughtException(new AnalysisException(), null));
- } else {
- ClassElement definingClass = element.enclosingElement as ClassElement;
- element.returnType = definingClass.type;
- element.type = new FunctionTypeImpl(element);
}
return null;
}
@@ -10216,26 +10161,8 @@
declaredType = _typeNameResolver._getType(typeName);
}
Element element = node.name.staticElement;
- if (element is VariableElement) {
- (element as VariableElementImpl).type = declaredType;
- if (element is PropertyInducingElement) {
- PropertyAccessorElementImpl getter =
- element.getter as PropertyAccessorElementImpl;
- getter.returnType = declaredType;
- getter.type = new FunctionTypeImpl(getter);
- PropertyAccessorElementImpl setter =
- element.setter as PropertyAccessorElementImpl;
- if (setter != null) {
- List<ParameterElement> parameters = setter.parameters;
- if (parameters.length > 0) {
- (parameters[0] as ParameterElementImpl).type = declaredType;
- }
- setter.returnType = VoidTypeImpl.instance;
- setter.type = new FunctionTypeImpl(setter);
- }
- }
- } else {
- // TODO(brianwilkerson) Report the internal error.
+ if (element is VariableElementImpl) {
+ element.type = declaredType;
}
return null;
}
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 6f50b44..cd813a0 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -38,6 +38,11 @@
static const String DART_HTML = "dart:html";
/**
+ * The prefix shared by all dart library URIs.
+ */
+ static const String DART_LIBRARY_PREFIX = "dart:";
+
+ /**
* The version number that is returned when the real version number could not
* be determined.
*/
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 9fd53dd..106977c 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -47,16 +47,8 @@
ClassElementImpl element = new ClassElementImpl(typeName, 0);
element.constructors = const <ConstructorElement>[];
element.supertype = superclassType;
- InterfaceTypeImpl type = new InterfaceTypeImpl(element);
- element.type = type;
if (parameterNames != null) {
- int count = parameterNames.length;
- if (count > 0) {
- element.typeParameters = typeParameters(parameterNames);
- type.typeArguments = new List<DartType>.from(
- element.typeParameters.map((p) => p.type),
- growable: false);
- }
+ element.typeParameters = typeParameters(parameterNames);
}
return element;
}
@@ -96,7 +88,6 @@
static ConstructorElementImpl constructorElement(
ClassElement definingClass, String name, bool isConst,
[List<DartType> argumentTypes]) {
- DartType type = definingClass.type;
ConstructorElementImpl constructor = name == null
? new ConstructorElementImpl("", -1)
: new ConstructorElementImpl(name, 0);
@@ -123,9 +114,7 @@
} else {
constructor.parameters = <ParameterElement>[];
}
- constructor.returnType = type;
constructor.enclosingElement = definingClass;
- constructor.type = new FunctionTypeImpl(constructor);
if (!constructor.isSynthetic) {
constructor.constantInitializers = <ConstructorInitializer>[];
}
@@ -137,17 +126,13 @@
[List<DartType> argumentTypes]) =>
constructorElement(definingClass, name, false, argumentTypes);
- static ClassElementImpl enumElement(
- TypeProvider typeProvider, String enumName,
+ static EnumElementImpl enumElement(TypeProvider typeProvider, String enumName,
[List<String> constantNames]) {
//
// Build the enum.
//
- ClassElementImpl enumElement = new ClassElementImpl(enumName, -1);
- InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement);
- enumElement.type = enumType;
- enumElement.supertype = objectType;
- enumElement.enum2 = true;
+ EnumElementImpl enumElement = new EnumElementImpl(enumName, -1);
+ InterfaceTypeImpl enumType = enumElement.type;
//
// Populate the fields.
//
@@ -222,27 +207,9 @@
if (isConst) {
(field as ConstFieldElementImpl).constantInitializer = initializer;
}
- PropertyAccessorElementImpl getter =
- new PropertyAccessorElementImpl.forVariable(field);
- getter.getter = true;
- getter.synthetic = true;
- getter.variable = field;
- getter.returnType = type;
- field.getter = getter;
- FunctionTypeImpl getterType = new FunctionTypeImpl(getter);
- getter.type = getterType;
+ new PropertyAccessorElementImpl_ImplicitGetter(field);
if (!isConst && !isFinal) {
- PropertyAccessorElementImpl setter =
- new PropertyAccessorElementImpl.forVariable(field);
- setter.setter = true;
- setter.synthetic = true;
- setter.variable = field;
- setter.parameters = <ParameterElement>[
- requiredParameter2("_$name", type)
- ];
- setter.returnType = VoidTypeImpl.instance;
- setter.type = new FunctionTypeImpl(setter);
- field.setter = setter;
+ new PropertyAccessorElementImpl_ImplicitSetter(field);
}
return field;
}
@@ -564,7 +531,7 @@
field.synthetic = true;
field.type = type;
PropertyAccessorElementImpl getter =
- new PropertyAccessorElementImpl.forVariable(field);
+ new PropertyAccessorElementImpl(name, -1);
getter.getter = true;
getter.variable = field;
getter.returnType = type;
@@ -573,7 +540,7 @@
getter.type = getterType;
ParameterElementImpl parameter = requiredParameter2("a", type);
PropertyAccessorElementImpl setter =
- new PropertyAccessorElementImpl.forVariable(field);
+ new PropertyAccessorElementImpl(name, -1);
setter.setter = true;
setter.synthetic = true;
setter.variable = field;
@@ -614,28 +581,9 @@
variable.final2 = isFinal;
variable.synthetic = false;
variable.type = type;
- PropertyAccessorElementImpl getter =
- new PropertyAccessorElementImpl.forVariable(variable);
- getter.getter = true;
- getter.synthetic = true;
- getter.variable = variable;
- getter.returnType = type;
- variable.getter = getter;
- FunctionTypeImpl getterType = new FunctionTypeImpl(getter);
- getter.type = getterType;
+ new PropertyAccessorElementImpl_ImplicitGetter(variable);
if (!isConst && !isFinal) {
- PropertyAccessorElementImpl setter =
- new PropertyAccessorElementImpl.forVariable(variable);
- setter.setter = true;
- setter.static = true;
- setter.synthetic = true;
- setter.variable = variable;
- setter.parameters = <ParameterElement>[
- requiredParameter2("_$name", type)
- ];
- setter.returnType = VoidTypeImpl.instance;
- setter.type = new FunctionTypeImpl(setter);
- variable.setter = setter;
+ new PropertyAccessorElementImpl_ImplicitSetter(variable);
}
return variable;
}
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index 64dadf2..0a524fa 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -149,7 +149,7 @@
InterfaceType _typeType;
/**
- * The type representing typenames that can't be resolved.
+ * The type representing type names that can't be resolved.
*/
DartType _undefinedType;
@@ -684,10 +684,6 @@
for (MethodElement method in classElement.methods) {
(method as ExecutableElementImpl).type = new FunctionTypeImpl(method);
}
- for (ConstructorElement constructor in classElement.constructors) {
- (constructor as ExecutableElementImpl).type =
- new FunctionTypeImpl(constructor);
- }
}
/**
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 19b5be5..7e4103d 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -73,7 +73,6 @@
}
/// Computes the greatest lower bound of [type1] and [type2].
- @override
DartType getGreatestLowerBound(
TypeProvider provider, DartType type1, DartType type2) {
// The greatest lower bound relation is reflexive.
@@ -203,6 +202,23 @@
var inferringTypeSystem =
new _StrongInferenceTypeSystem(typeProvider, fnType.typeFormals);
+ // Special case inference for Future.then.
+ //
+ // We don't have union types, so Future<T>.then<S> is typed to take a
+ // callback `T -> S`. However, the lambda might actually return a
+ // Future<S>. So we handle that special case here.
+ if (argumentTypes.isNotEmpty && argumentTypes[0] is FunctionType) {
+ Element element = fnType?.element;
+ bool isFutureThen = element is MethodElement &&
+ element.name == 'then' &&
+ element.enclosingElement.type.isDartAsyncFuture;
+ if (isFutureThen) {
+ // Ignore return context. We'll let the onValue function's return type
+ // drive inference.
+ returnContextType = null;
+ }
+ }
+
if (returnContextType != null) {
inferringTypeSystem.isSubtypeOf(fnType.returnType, returnContextType);
}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 701b10e..0a5b904 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -141,6 +141,198 @@
}
}
+class CacheAnalysisErrorBuilder extends Object with _CacheAnalysisErrorMixin implements idl.CacheAnalysisError {
+ bool _finished = false;
+
+ String _correction;
+ String _errorCodeUniqueName;
+ int _length;
+ String _message;
+ int _offset;
+
+ @override
+ String get correction => _correction ??= '';
+
+ /**
+ * The correction to be displayed for this error, or `null` if there is no
+ * correction information for this error. The correction should indicate how
+ * the user can fix the error.
+ */
+ void set correction(String _value) {
+ assert(!_finished);
+ _correction = _value;
+ }
+
+ @override
+ String get errorCodeUniqueName => _errorCodeUniqueName ??= '';
+
+ /**
+ * The unique name of the error code.
+ */
+ void set errorCodeUniqueName(String _value) {
+ assert(!_finished);
+ _errorCodeUniqueName = _value;
+ }
+
+ @override
+ int get length => _length ??= 0;
+
+ /**
+ * Length of the error range.
+ */
+ void set length(int _value) {
+ assert(!_finished);
+ assert(_value == null || _value >= 0);
+ _length = _value;
+ }
+
+ @override
+ String get message => _message ??= '';
+
+ /**
+ * The message to be displayed for this error. The message should indicate
+ * what is wrong and why it is wrong.
+ */
+ void set message(String _value) {
+ assert(!_finished);
+ _message = _value;
+ }
+
+ @override
+ int get offset => _offset ??= 0;
+
+ /**
+ * Offset of the error range relative to the beginning of the file.
+ */
+ void set offset(int _value) {
+ assert(!_finished);
+ assert(_value == null || _value >= 0);
+ _offset = _value;
+ }
+
+ CacheAnalysisErrorBuilder({String correction, String errorCodeUniqueName, int length, String message, int offset})
+ : _correction = correction,
+ _errorCodeUniqueName = errorCodeUniqueName,
+ _length = length,
+ _message = message,
+ _offset = offset;
+
+ /**
+ * Flush [informative] data recursively.
+ */
+ void flushInformative() {
+ }
+
+ fb.Offset finish(fb.Builder fbBuilder) {
+ assert(!_finished);
+ _finished = true;
+ fb.Offset offset_correction;
+ fb.Offset offset_errorCodeUniqueName;
+ fb.Offset offset_message;
+ if (_correction != null) {
+ offset_correction = fbBuilder.writeString(_correction);
+ }
+ if (_errorCodeUniqueName != null) {
+ offset_errorCodeUniqueName = fbBuilder.writeString(_errorCodeUniqueName);
+ }
+ if (_message != null) {
+ offset_message = fbBuilder.writeString(_message);
+ }
+ fbBuilder.startTable();
+ if (offset_correction != null) {
+ fbBuilder.addOffset(4, offset_correction);
+ }
+ if (offset_errorCodeUniqueName != null) {
+ fbBuilder.addOffset(0, offset_errorCodeUniqueName);
+ }
+ if (_length != null && _length != 0) {
+ fbBuilder.addUint32(2, _length);
+ }
+ if (offset_message != null) {
+ fbBuilder.addOffset(3, offset_message);
+ }
+ if (_offset != null && _offset != 0) {
+ fbBuilder.addUint32(1, _offset);
+ }
+ return fbBuilder.endTable();
+ }
+}
+
+class _CacheAnalysisErrorReader extends fb.TableReader<_CacheAnalysisErrorImpl> {
+ const _CacheAnalysisErrorReader();
+
+ @override
+ _CacheAnalysisErrorImpl createObject(fb.BufferContext bc, int offset) => new _CacheAnalysisErrorImpl(bc, offset);
+}
+
+class _CacheAnalysisErrorImpl extends Object with _CacheAnalysisErrorMixin implements idl.CacheAnalysisError {
+ final fb.BufferContext _bc;
+ final int _bcOffset;
+
+ _CacheAnalysisErrorImpl(this._bc, this._bcOffset);
+
+ String _correction;
+ String _errorCodeUniqueName;
+ int _length;
+ String _message;
+ int _offset;
+
+ @override
+ String get correction {
+ _correction ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 4, '');
+ return _correction;
+ }
+
+ @override
+ String get errorCodeUniqueName {
+ _errorCodeUniqueName ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+ return _errorCodeUniqueName;
+ }
+
+ @override
+ int get length {
+ _length ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
+ return _length;
+ }
+
+ @override
+ String get message {
+ _message ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
+ return _message;
+ }
+
+ @override
+ int get offset {
+ _offset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
+ return _offset;
+ }
+}
+
+abstract class _CacheAnalysisErrorMixin implements idl.CacheAnalysisError {
+ @override
+ Map<String, Object> toJson() {
+ Map<String, Object> _result = <String, Object>{};
+ if (correction != '') _result["correction"] = correction;
+ if (errorCodeUniqueName != '') _result["errorCodeUniqueName"] = errorCodeUniqueName;
+ if (length != 0) _result["length"] = length;
+ if (message != '') _result["message"] = message;
+ if (offset != 0) _result["offset"] = offset;
+ return _result;
+ }
+
+ @override
+ Map<String, Object> toMap() => {
+ "correction": correction,
+ "errorCodeUniqueName": errorCodeUniqueName,
+ "length": length,
+ "message": message,
+ "offset": offset,
+ };
+
+ @override
+ String toString() => convert.JSON.encode(toJson());
+}
+
class CacheSourceContentBuilder extends Object with _CacheSourceContentMixin implements idl.CacheSourceContent {
bool _finished = false;
@@ -316,6 +508,96 @@
String toString() => convert.JSON.encode(toJson());
}
+class CacheSourceErrorsInLibraryBuilder extends Object with _CacheSourceErrorsInLibraryMixin implements idl.CacheSourceErrorsInLibrary {
+ bool _finished = false;
+
+ List<CacheAnalysisErrorBuilder> _errors;
+
+ @override
+ List<CacheAnalysisErrorBuilder> get errors => _errors ??= <CacheAnalysisErrorBuilder>[];
+
+ /**
+ * The list of errors in the source in the library.
+ */
+ void set errors(List<CacheAnalysisErrorBuilder> _value) {
+ assert(!_finished);
+ _errors = _value;
+ }
+
+ CacheSourceErrorsInLibraryBuilder({List<CacheAnalysisErrorBuilder> errors})
+ : _errors = errors;
+
+ /**
+ * Flush [informative] data recursively.
+ */
+ void flushInformative() {
+ _errors?.forEach((b) => b.flushInformative());
+ }
+
+ List<int> toBuffer() {
+ fb.Builder fbBuilder = new fb.Builder();
+ return fbBuilder.finish(finish(fbBuilder), "CSEL");
+ }
+
+ fb.Offset finish(fb.Builder fbBuilder) {
+ assert(!_finished);
+ _finished = true;
+ fb.Offset offset_errors;
+ if (!(_errors == null || _errors.isEmpty)) {
+ offset_errors = fbBuilder.writeList(_errors.map((b) => b.finish(fbBuilder)).toList());
+ }
+ fbBuilder.startTable();
+ if (offset_errors != null) {
+ fbBuilder.addOffset(0, offset_errors);
+ }
+ return fbBuilder.endTable();
+ }
+}
+
+idl.CacheSourceErrorsInLibrary readCacheSourceErrorsInLibrary(List<int> buffer) {
+ fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);
+ return const _CacheSourceErrorsInLibraryReader().read(rootRef, 0);
+}
+
+class _CacheSourceErrorsInLibraryReader extends fb.TableReader<_CacheSourceErrorsInLibraryImpl> {
+ const _CacheSourceErrorsInLibraryReader();
+
+ @override
+ _CacheSourceErrorsInLibraryImpl createObject(fb.BufferContext bc, int offset) => new _CacheSourceErrorsInLibraryImpl(bc, offset);
+}
+
+class _CacheSourceErrorsInLibraryImpl extends Object with _CacheSourceErrorsInLibraryMixin implements idl.CacheSourceErrorsInLibrary {
+ final fb.BufferContext _bc;
+ final int _bcOffset;
+
+ _CacheSourceErrorsInLibraryImpl(this._bc, this._bcOffset);
+
+ List<idl.CacheAnalysisError> _errors;
+
+ @override
+ List<idl.CacheAnalysisError> get errors {
+ _errors ??= const fb.ListReader<idl.CacheAnalysisError>(const _CacheAnalysisErrorReader()).vTableGet(_bc, _bcOffset, 0, const <idl.CacheAnalysisError>[]);
+ return _errors;
+ }
+}
+
+abstract class _CacheSourceErrorsInLibraryMixin implements idl.CacheSourceErrorsInLibrary {
+ @override
+ Map<String, Object> toJson() {
+ Map<String, Object> _result = <String, Object>{};
+ if (errors.isNotEmpty) _result["errors"] = errors.map((_value) => _value.toJson()).toList();
+ return _result;
+ }
+
+ @override
+ Map<String, Object> toMap() => {
+ "errors": errors,
+ };
+
+ @override
+ String toString() => convert.JSON.encode(toJson());
+}
+
class CodeRangeBuilder extends Object with _CodeRangeMixin implements idl.CodeRange {
bool _finished = false;
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 26c6256..d08851c 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -561,8 +561,11 @@
* stack (where `m` is obtained from [UnlinkedConst.ints]) into a list (filled
* from the end) and use them as positional arguments. Use the lists of
* positional and names arguments to invoke a method (or a function) with
- * the reference from [UnlinkedConst.references]. Push the result of
- * invocation value into the stack.
+ * the reference from [UnlinkedConst.references]. If `k` is nonzero (where
+ * `k` is obtained from [UnlinkedConst.ints]), obtain `k` type arguments from
+ * [UnlinkedConst.references] and use them as generic type arguments for the
+ * aforementioned method or function. Push the result of the invocation onto
+ * the stack.
*
* In general `a.b` cannot not be distinguished between: `a` is a prefix and
* `b` is a top-level function; or `a` is an object and `b` is the name of a
@@ -579,11 +582,14 @@
* stack (where `m` is obtained from [UnlinkedConst.ints]) into a list (filled
* from the end) and use them as positional arguments. Use the lists of
* positional and names arguments to invoke the method with the name from
- * [UnlinkedConst.strings] of the target popped from the stack, and push the
- * resulting value into the stack.
+ * [UnlinkedConst.strings] of the target popped from the stack. If `k` is
+ * nonzero (where `k` is obtained from [UnlinkedConst.ints]), obtain `k` type
+ * arguments from [UnlinkedConst.references] and use them as generic type
+ * arguments for the aforementioned method. Push the result of the
+ * invocation onto the stack.
*
* This operation should be used for invocation of a method invocation
- * where `target` is know to be an object instance.
+ * where `target` is known to be an object instance.
*/
invokeMethod,
@@ -785,6 +791,39 @@
}
/**
+ * Information about an analysis error in a source.
+ */
+table CacheAnalysisError {
+ /**
+ * The correction to be displayed for this error, or `null` if there is no
+ * correction information for this error. The correction should indicate how
+ * the user can fix the error.
+ */
+ correction:string (id: 4);
+
+ /**
+ * The unique name of the error code.
+ */
+ errorCodeUniqueName:string (id: 0);
+
+ /**
+ * Length of the error range.
+ */
+ length:uint (id: 2);
+
+ /**
+ * The message to be displayed for this error. The message should indicate
+ * what is wrong and why it is wrong.
+ */
+ message:string (id: 3);
+
+ /**
+ * Offset of the error range relative to the beginning of the file.
+ */
+ offset:uint (id: 1);
+}
+
+/**
* Information about a source that depends only on its content.
*/
table CacheSourceContent {
@@ -813,6 +852,17 @@
}
/**
+ * Errors of a source in a library, which depends on the import/export closure
+ * of the containing library and the source.
+ */
+table CacheSourceErrorsInLibrary {
+ /**
+ * The list of errors in the source in the library.
+ */
+ errors:[CacheAnalysisError] (id: 0);
+}
+
+/**
* Information about an element code range.
*/
table CodeRange {
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 7f2fe39..505ade8 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -58,6 +58,44 @@
const informative = null;
/**
+ * Information about an analysis error in a source.
+ */
+abstract class CacheAnalysisError extends base.SummaryClass {
+ /**
+ * The correction to be displayed for this error, or `null` if there is no
+ * correction information for this error. The correction should indicate how
+ * the user can fix the error.
+ */
+ @Id(4)
+ String get correction;
+
+ /**
+ * The unique name of the error code.
+ */
+ @Id(0)
+ String get errorCodeUniqueName;
+
+ /**
+ * Length of the error range.
+ */
+ @Id(2)
+ int get length;
+
+ /**
+ * The message to be displayed for this error. The message should indicate
+ * what is wrong and why it is wrong.
+ */
+ @Id(3)
+ String get message;
+
+ /**
+ * Offset of the error range relative to the beginning of the file.
+ */
+ @Id(1)
+ int get offset;
+}
+
+/**
* Information about a source that depends only on its content.
*/
@TopLevel('CaSS')
@@ -94,6 +132,21 @@
}
/**
+ * Errors of a source in a library, which depends on the import/export closure
+ * of the containing library and the source.
+ */
+@TopLevel('CSEL')
+abstract class CacheSourceErrorsInLibrary extends base.SummaryClass {
+ factory CacheSourceErrorsInLibrary.fromBuffer(List<int> buffer) =>
+ generated.readCacheSourceErrorsInLibrary(buffer);
+ /**
+ * The list of errors in the source in the library.
+ */
+ @Id(0)
+ List<CacheAnalysisError> get errors;
+}
+
+/**
* Kind of a source in the cache.
*/
enum CacheSourceKind { library, part }
@@ -1401,8 +1454,11 @@
* stack (where `m` is obtained from [UnlinkedConst.ints]) into a list (filled
* from the end) and use them as positional arguments. Use the lists of
* positional and names arguments to invoke a method (or a function) with
- * the reference from [UnlinkedConst.references]. Push the result of
- * invocation value into the stack.
+ * the reference from [UnlinkedConst.references]. If `k` is nonzero (where
+ * `k` is obtained from [UnlinkedConst.ints]), obtain `k` type arguments from
+ * [UnlinkedConst.references] and use them as generic type arguments for the
+ * aforementioned method or function. Push the result of the invocation onto
+ * the stack.
*
* In general `a.b` cannot not be distinguished between: `a` is a prefix and
* `b` is a top-level function; or `a` is an object and `b` is the name of a
@@ -1419,11 +1475,14 @@
* stack (where `m` is obtained from [UnlinkedConst.ints]) into a list (filled
* from the end) and use them as positional arguments. Use the lists of
* positional and names arguments to invoke the method with the name from
- * [UnlinkedConst.strings] of the target popped from the stack, and push the
- * resulting value into the stack.
+ * [UnlinkedConst.strings] of the target popped from the stack. If `k` is
+ * nonzero (where `k` is obtained from [UnlinkedConst.ints]), obtain `k` type
+ * arguments from [UnlinkedConst.references] and use them as generic type
+ * arguments for the aforementioned method. Push the result of the
+ * invocation onto the stack.
*
* This operation should be used for invocation of a method invocation
- * where `target` is know to be an object instance.
+ * where `target` is known to be an object instance.
*/
invokeMethod,
diff --git a/pkg/analyzer/lib/src/summary/incremental_cache.dart b/pkg/analyzer/lib/src/summary/incremental_cache.dart
index 1d913be..cadeffb 100644
--- a/pkg/analyzer/lib/src/summary/incremental_cache.dart
+++ b/pkg/analyzer/lib/src/summary/incremental_cache.dart
@@ -2,12 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:convert' show ChunkedConversionSink, UTF8;
+import 'dart:convert';
import 'dart:core' hide Resource;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
@@ -139,9 +140,6 @@
List<Source> closureSources = _getLibraryClosure(librarySource);
List<LibraryBundleWithId> closureBundles = <LibraryBundleWithId>[];
for (Source source in closureSources) {
- if (source.isInSystemLibrary) {
- continue;
- }
if (getSourceKind(source) == SourceKind.PART) {
continue;
}
@@ -159,6 +157,48 @@
}
/**
+ * Return the parts of the given [librarySource], or `null` if unknown.
+ */
+ List<Source> getLibraryParts(Source librarySource) {
+ try {
+ CacheSourceContent contentSource = _getCacheSourceContent(librarySource);
+ if (contentSource != null) {
+ return contentSource.partUris.map((String partUri) {
+ Source partSource = _resolveUri(librarySource, partUri);
+ if (partSource == null) {
+ throw new StateError(
+ 'Unable to resolve $partUri in $librarySource');
+ }
+ return partSource;
+ }).toList();
+ }
+ } catch (e) {}
+ return null;
+ }
+
+ /**
+ * Return cached errors in the given [source] in the context of the given
+ * [librarySource], or `null` if the cache does not have this information.
+ */
+ List<AnalysisError> getSourceErrorsInLibrary(
+ Source librarySource, Source source) {
+ try {
+ String key = _getSourceErrorsKey(librarySource, source);
+ List<int> bytes = storage.get(key);
+ if (bytes == null) {
+ return null;
+ }
+ CacheSourceErrorsInLibrary errorsObject =
+ new CacheSourceErrorsInLibrary.fromBuffer(bytes);
+ return errorsObject.errors
+ .map((e) => _convertErrorFromCached(source, e))
+ .toList();
+ } catch (e) {
+ return null;
+ }
+ }
+
+ /**
* Return the kind of the given [source], or `null` if unknown.
*/
SourceKind getSourceKind(Source source) {
@@ -189,11 +229,27 @@
}
/**
+ * Associate the given [errors] with the [source] in the [librarySource].
+ */
+ void putSourceErrorsInLibrary(
+ Source librarySource, Source source, List<AnalysisError> errors) {
+ CacheSourceErrorsInLibraryBuilder builder =
+ new CacheSourceErrorsInLibraryBuilder(
+ errors: errors.map(_convertErrorToCached).toList());
+ String key = _getSourceErrorsKey(librarySource, source);
+ List<int> bytes = builder.toBuffer();
+ storage.put(key, bytes);
+ }
+
+ /**
* Fill the whole source closure of the library with the given
* [librarySource]. It includes defining units and parts of the library and
* all its directly or indirectly imported or exported libraries.
*/
void _appendLibraryClosure(Set<Source> closure, Source librarySource) {
+ if (librarySource.isInSystemLibrary) {
+ return;
+ }
if (closure.add(librarySource)) {
CacheSourceContent contentSource = _getCacheSourceContent(librarySource);
if (contentSource == null) {
@@ -220,6 +276,48 @@
}
}
+ List<int> _computeSaltedMD5OfBytes(addData(ByteConversionSink byteSink)) {
+ Digest digest;
+ ChunkedConversionSink<Digest> digestSink =
+ new ChunkedConversionSink<Digest>.withCallback((List<Digest> digests) {
+ digest = digests.single;
+ });
+ ByteConversionSink byteSink = md5.startChunkedConversion(digestSink);
+ // Add data.
+ addData(byteSink);
+ byteSink.add(configSalt);
+ // Done.
+ byteSink.close();
+ return digest.bytes;
+ }
+
+ /**
+ * Return the [AnalysisError] for the given [cachedError].
+ */
+ AnalysisError _convertErrorFromCached(
+ Source source, CacheAnalysisError cachedError) {
+ ErrorCode errorCode = _getErrorCode(cachedError);
+ return new AnalysisError.forValues(
+ source,
+ cachedError.offset,
+ cachedError.length,
+ errorCode,
+ cachedError.message,
+ cachedError.correction);
+ }
+
+ /**
+ * Return the [CacheAnalysisError] for the given [error].
+ */
+ CacheAnalysisError _convertErrorToCached(AnalysisError error) {
+ return new CacheAnalysisErrorBuilder(
+ errorCodeUniqueName: error.errorCode.uniqueName,
+ offset: error.offset,
+ length: error.length,
+ message: error.message,
+ correction: error.correction);
+ }
+
/**
* Get the content based information about the given [source], maybe `null`
* if the information is not in the cache.
@@ -248,6 +346,18 @@
}
/**
+ * Return the [ErrorCode] of the given [error], throws if not found.
+ */
+ ErrorCode _getErrorCode(CacheAnalysisError error) {
+ String uniqueName = error.errorCodeUniqueName;
+ ErrorCode errorCode = ErrorCode.byUniqueName(uniqueName);
+ if (errorCode != null) {
+ return errorCode;
+ }
+ throw new StateError('Unable to find ErrorCode: $uniqueName');
+ }
+
+ /**
* Get the bundle for the given key.
*/
PackageBundle _getLibraryBundle(String key) {
@@ -292,31 +402,12 @@
List<int> _getLibraryClosureHash(Source librarySource) {
return _libraryClosureHashMap.putIfAbsent(librarySource, () {
List<Source> closure = _getLibraryClosure(librarySource);
-
- Digest digest;
-
- var digestSink = new ChunkedConversionSink<Digest>.withCallback(
- (List<Digest> digests) {
- digest = digests.single;
+ return _computeSaltedMD5OfBytes((ByteConversionSink byteSink) {
+ for (Source source in closure) {
+ List<int> sourceHash = _getSourceContentHash(source);
+ byteSink.add(sourceHash);
+ }
});
-
- var byteSink = md5.startChunkedConversion(digestSink);
-
- for (Source source in closure) {
- List<int> sourceHash = _getSourceContentHash(source);
- byteSink.add(sourceHash);
- }
- byteSink.add(configSalt);
-
- byteSink.close();
- // TODO(paulberry): this call to `close` should not be needed.
- // Can be removed once
- // https://github.com/dart-lang/crypto/issues/33
- // is fixed – ensure the min version constraint on crypto is updated, tho.
- // Does not cause any problems in the mean time.
- digestSink.close();
-
- return digest.bytes;
});
}
@@ -332,6 +423,18 @@
}
/**
+ * Return the key for errors in the [source] in the [librarySource].
+ */
+ String _getSourceErrorsKey(Source librarySource, Source source) {
+ List<int> hash = _computeSaltedMD5OfBytes((ByteConversionSink byteSink) {
+ byteSink.add(_getLibraryClosureHash(librarySource));
+ byteSink.add(_getSourceContentHash(source));
+ });
+ String hashStr = hex.encode(hash);
+ return '$hashStr.errorsInLibrary';
+ }
+
+ /**
* Return a source representing the URI that results from resolving the given
* (possibly relative) [containedUri] against the URI associated with the
* [containingSource], whether or not the resulting source exists, or `null`
@@ -354,11 +457,13 @@
* Write the content based information about the given [source].
*/
void _writeCacheSourceContent(Source source, CacheSourceContentBuilder b) {
- String key = _getCacheSourceContentKey(source);
- List<int> bytes = b.toBuffer();
- storage.put(key, bytes);
- // Put into the cache to avoid reading it later.
- _sourceContentMap[source] = new CacheSourceContent.fromBuffer(bytes);
+ if (!_sourceContentMap.containsKey(source)) {
+ String key = _getCacheSourceContentKey(source);
+ List<int> bytes = b.toBuffer();
+ storage.put(key, bytes);
+ // Put into the cache to avoid reading it later.
+ _sourceContentMap[source] = new CacheSourceContent.fromBuffer(bytes);
+ }
}
/**
@@ -368,10 +473,6 @@
void _writeCacheSourceContents(LibraryElement library,
[Set<LibraryElement> writtenLibraries]) {
Source librarySource = library.source;
- // Do nothing if already cached.
- if (_sourceContentMap.containsKey(librarySource)) {
- return;
- }
// Stop recursion cycle.
writtenLibraries ??= new Set<LibraryElement>();
if (!writtenLibraries.add(library)) {
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 77c86f2..81ae854 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -242,6 +242,13 @@
throw new UnimplementedError('${type.runtimeType}');
}
+DartType _dynamicIfNull(DartType type) {
+ if (type == null || type.isBottom || type.isVoid) {
+ return DynamicTypeImpl.instance;
+ }
+ return type;
+}
+
/**
* Create an [UnlinkedParam] representing the given [parameter], which should be
* a parameter of a synthetic function type (e.g. one produced during type
@@ -334,7 +341,7 @@
*/
abstract class ClassElementForLink extends Object
with ReferenceableElementForLink
- implements ClassElementImpl {
+ implements AbstractClassElementImpl {
Map<String, ReferenceableElementForLink> _containedNames;
@override
@@ -381,9 +388,6 @@
String get name;
@override
- ResynthesizerContext get resynthesizerContext => enclosingElement;
-
- @override
ConstructorElementForLink get unnamedConstructor;
@override
@@ -420,7 +424,8 @@
* linking.
*/
class ClassElementForLink_Class extends ClassElementForLink
- with TypeParameterizedElementMixin {
+ with TypeParameterizedElementMixin
+ implements ClassElementImpl {
/**
* The unlinked representation of the class in the summary.
*/
@@ -668,7 +673,8 @@
* Element representing an enum resynthesized from a summary during
* linking.
*/
-class ClassElementForLink_Enum extends ClassElementForLink {
+class ClassElementForLink_Enum extends ClassElementForLink
+ implements EnumElementImpl {
/**
* The unlinked representation of the enum in the summary.
*/
@@ -1491,10 +1497,20 @@
return;
}
int refPtr = 0;
+ int intPtr = 0;
for (UnlinkedConstOperation operation in unlinkedConst.operations) {
switch (operation) {
+ case UnlinkedConstOperation.pushInt:
+ intPtr++;
+ break;
+ case UnlinkedConstOperation.pushLongInt:
+ int numInts = unlinkedConst.ints[intPtr++];
+ intPtr += numInts;
+ break;
+ case UnlinkedConstOperation.concatenate:
+ intPtr++;
+ break;
case UnlinkedConstOperation.pushReference:
- case UnlinkedConstOperation.invokeMethodRef:
EntityRef ref = unlinkedConst.references[refPtr++];
ConstVariableNode variable =
compilationUnit.resolveRef(ref.reference).asConstVariable;
@@ -1502,11 +1518,36 @@
dependencies.add(variable);
}
break;
+ case UnlinkedConstOperation.makeUntypedList:
+ case UnlinkedConstOperation.makeUntypedMap:
+ intPtr++;
+ break;
+ case UnlinkedConstOperation.assignToRef:
+ refPtr++;
+ break;
+ case UnlinkedConstOperation.invokeMethodRef:
+ EntityRef ref = unlinkedConst.references[refPtr++];
+ ConstVariableNode variable =
+ compilationUnit.resolveRef(ref.reference).asConstVariable;
+ if (variable != null) {
+ dependencies.add(variable);
+ }
+ intPtr += 2;
+ int numTypeArguments = unlinkedConst.ints[intPtr++];
+ refPtr += numTypeArguments;
+ break;
+ case UnlinkedConstOperation.invokeMethod:
+ intPtr += 2;
+ int numTypeArguments = unlinkedConst.ints[intPtr++];
+ refPtr += numTypeArguments;
+ break;
case UnlinkedConstOperation.makeTypedList:
refPtr++;
+ intPtr++;
break;
case UnlinkedConstOperation.makeTypedMap:
refPtr += 2;
+ intPtr++;
break;
case UnlinkedConstOperation.invokeConstructor:
EntityRef ref = unlinkedConst.references[refPtr++];
@@ -1515,12 +1556,21 @@
if (element?._constNode != null) {
dependencies.add(element._constNode);
}
+ intPtr += 2;
+ break;
+ case UnlinkedConstOperation.typeCast:
+ case UnlinkedConstOperation.typeCheck:
+ refPtr++;
+ break;
+ case UnlinkedConstOperation.pushLocalFunctionReference:
+ intPtr += 2;
break;
default:
break;
}
}
assert(refPtr == unlinkedConst.references.length);
+ assert(intPtr == unlinkedConst.ints.length);
}
}
@@ -1972,13 +2022,12 @@
}
class ExprTypeComputer {
- VariableElementForLink variable;
- FunctionElementForLink_Initializer initializer;
- CompilationUnitElementForLink unit;
- LibraryElementForLink library;
- Linker linker;
- TypeProvider typeProvider;
- UnlinkedConst unlinkedConst;
+ final FunctionElementForLink_Local function;
+ final CompilationUnitElementForLink unit;
+ final LibraryElementForLink library;
+ final Linker linker;
+ final TypeProvider typeProvider;
+ final UnlinkedConst unlinkedConst;
final List<DartType> stack = <DartType>[];
int intPtr = 0;
@@ -1986,17 +2035,25 @@
int strPtr = 0;
int assignmentOperatorPtr = 0;
- ExprTypeComputer(VariableElementForLink variableElement) {
- this.variable = variableElement;
- initializer = variableElement.initializer;
- unit = variableElement.compilationUnit;
- library = unit.enclosingElement;
- linker = library._linker;
- typeProvider = linker.typeProvider;
- unlinkedConst = variableElement.unlinkedVariable.initializer?.bodyExpr;
+ factory ExprTypeComputer(FunctionElementForLink_Local functionElement) {
+ CompilationUnitElementForLink unit = functionElement.compilationUnit;
+ LibraryElementForLink library = unit.enclosingElement;
+ Linker linker = library._linker;
+ TypeProvider typeProvider = linker.typeProvider;
+ UnlinkedConst unlinkedConst = functionElement._unlinkedExecutable.bodyExpr;
+ return new ExprTypeComputer._(
+ functionElement, unit, library, linker, typeProvider, unlinkedConst);
}
+ ExprTypeComputer._(this.function, this.unit, this.library, this.linker,
+ this.typeProvider, this.unlinkedConst);
+
DartType compute() {
+ if (unlinkedConst == null) {
+ // No function body was stored for this function, so we can't infer its
+ // return type. Assume `dynamic`.
+ return DynamicTypeImpl.instance;
+ }
// Perform RPN evaluation of the constant, using a stack of inferred types.
for (UnlinkedConstOperation operation in unlinkedConst.operations) {
switch (operation) {
@@ -2158,7 +2215,10 @@
case UnlinkedConstOperation.pushLocalFunctionReference:
int popCount = _getNextInt();
assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
- stack.add(initializer.functions[_getNextInt()].type);
+ stack.add(function.functions[_getNextInt()].type);
+ break;
+ case UnlinkedConstOperation.pushParameter:
+ stack.add(_findParameterType(_getNextString()));
break;
default:
// TODO(paulberry): implement.
@@ -2170,7 +2230,7 @@
assert(strPtr == unlinkedConst.strings.length);
assert(assignmentOperatorPtr == unlinkedConst.assignmentOperators.length);
assert(stack.length == 1);
- return _dynamicIfNull(stack[0]);
+ return stack[0];
}
void _computeBinaryExpressionType(TokenType operator) {
@@ -2315,7 +2375,7 @@
// Type argument explicitly specified.
if (i < ref.typeArguments.length) {
return unit.resolveTypeRef(
- ref.typeArguments[i], variable._typeParameterContext);
+ ref.typeArguments[i], function.typeParameterContext);
} else {
return null;
}
@@ -2334,14 +2394,21 @@
// TODO(scheglov) if we pushed target and method name first, we might be
// able to move work with arguments in _inferExecutableType()
String methodName = _getNextString();
+ List<DartType> typeArguments = _getTypeArguments();
DartType target = stack.removeLast();
stack.add(() {
if (target is InterfaceType) {
MethodElement method =
target.lookUpInheritedMethod(methodName, library: library);
FunctionType rawType = method?.type;
- FunctionType inferredType = _inferExecutableType(rawType, numNamed,
- numPositional, namedArgNames, namedArgTypeList, positionalArgTypes);
+ FunctionType inferredType = _inferExecutableType(
+ rawType,
+ numNamed,
+ numPositional,
+ namedArgNames,
+ namedArgTypeList,
+ positionalArgTypes,
+ typeArguments);
if (inferredType != null) {
return inferredType.returnType;
}
@@ -2358,11 +2425,18 @@
List<DartType> positionalArgTypes = _popList(numPositional);
EntityRef ref = _getNextRef();
ReferenceableElementForLink element = unit.resolveRef(ref.reference);
+ List<DartType> typeArguments = _getTypeArguments();
stack.add(() {
DartType rawType = element.asStaticType;
if (rawType is FunctionType) {
- FunctionType inferredType = _inferExecutableType(rawType, numNamed,
- numPositional, namedArgNames, namedArgTypeList, positionalArgTypes);
+ FunctionType inferredType = _inferExecutableType(
+ rawType,
+ numNamed,
+ numPositional,
+ namedArgNames,
+ namedArgTypeList,
+ positionalArgTypes,
+ typeArguments);
if (inferredType != null) {
return inferredType.returnType;
}
@@ -2428,6 +2502,29 @@
}
}
+ /**
+ * Find the parameter in scope called [parameterName] and return its type.
+ */
+ DartType _findParameterType(String parameterName) {
+ FunctionElementForLink_Local f = this.function;
+ while (true) {
+ for (ParameterElement parameter in f.parameters) {
+ if (parameter.name == parameterName) {
+ return parameter.type;
+ }
+ }
+ Element parent = f.enclosingElement;
+ if (parent is FunctionElementForLink_Local) {
+ f = parent;
+ } else {
+ // Parameter not found. This should never happen in a well-formed
+ // summary.
+ assert(false);
+ return DynamicTypeImpl.instance;
+ }
+ }
+ }
+
int _getNextInt() {
return unlinkedConst.ints[intPtr++];
}
@@ -2448,7 +2545,7 @@
DartType _getNextTypeRef() {
EntityRef ref = _getNextRef();
- return unit.resolveTypeRef(ref, variable._typeParameterContext);
+ return unit.resolveTypeRef(ref, function.typeParameterContext);
}
/**
@@ -2464,16 +2561,33 @@
: DynamicTypeImpl.instance;
}
+ List<DartType> _getTypeArguments() {
+ int numTypeArguments = _getNextInt();
+ List<DartType> typeArguments = new List<DartType>(numTypeArguments);
+ for (int i = 0; i < numTypeArguments; i++) {
+ typeArguments[i] = _getNextTypeRef();
+ }
+ return typeArguments;
+ }
+
FunctionType _inferExecutableType(
FunctionType rawMethodType,
int numNamed,
int numPositional,
List<String> namedArgNames,
List<DartType> namedArgTypeList,
- List<DartType> positionalArgTypes) {
+ List<DartType> positionalArgTypes,
+ List<DartType> typeArguments) {
TypeSystem ts = linker.typeSystem;
if (rawMethodType != null) {
- if (rawMethodType.typeFormals.isNotEmpty && ts is StrongTypeSystemImpl) {
+ if (rawMethodType.typeFormals.isNotEmpty && typeArguments.isNotEmpty) {
+ Element methodElement = rawMethodType.element;
+ if (methodElement is TypeParameterizedElement &&
+ methodElement.typeParameters.length == typeArguments.length) {
+ return rawMethodType.instantiate(typeArguments);
+ }
+ } else if (rawMethodType.typeFormals.isNotEmpty &&
+ ts is StrongTypeSystemImpl) {
List<DartType> paramTypes = <DartType>[];
List<DartType> argTypes = <DartType>[];
// Add positional parameter and argument types.
@@ -2587,13 +2701,6 @@
return TokenType.MINUS_MINUS;
}
}
-
- static DartType _dynamicIfNull(DartType type) {
- if (type == null || type.isBottom || type.isVoid) {
- return DynamicTypeImpl.instance;
- }
- return type;
- }
}
/**
@@ -2650,6 +2757,7 @@
unlinkedVariable.inferredTypeSlot,
isStatic ? inferredType : _inferredInstanceType,
_typeParameterContext);
+ initializer?.link(compilationUnit);
}
}
@@ -2758,18 +2866,33 @@
* Element representing the initializer expression of a variable.
*/
class FunctionElementForLink_Initializer extends Object
- with ReferenceableElementForLink
+ with ReferenceableElementForLink, TypeParameterizedElementMixin
implements FunctionElementForLink_Local {
/**
* The variable for which this element is the initializer.
*/
final VariableElementForLink _variable;
+ /**
+ * The type inference node for this function, or `null` if it hasn't been
+ * computed yet.
+ */
+ TypeInferenceNode _typeInferenceNode;
+
List<FunctionElementForLink_Local_NonSynthetic> _functions;
+ DartType _inferredReturnType;
FunctionElementForLink_Initializer(this._variable);
@override
+ TypeInferenceNode get asTypeInferenceNode =>
+ _typeInferenceNode ??= new TypeInferenceNode(this);
+
+ @override
+ CompilationUnitElementForLink get compilationUnit =>
+ _variable.compilationUnit;
+
+ @override
VariableElementForLink get enclosingElement => _variable;
TypeParameterizedElementMixin get enclosingTypeParameterContext =>
@@ -2778,6 +2901,9 @@
: null;
@override
+ CompilationUnitElementForLink get enclosingUnit => _variable.compilationUnit;
+
+ @override
List<FunctionElementForLink_Local_NonSynthetic> get functions =>
_functions ??= _variable.unlinkedVariable.initializer.localFunctions
.map((UnlinkedExecutable ex) =>
@@ -2807,10 +2933,17 @@
}
@override
- int get typeParameterNestingLevel =>
- enclosingTypeParameterContext?.typeParameterNestingLevel ?? 0;
+ TypeParameterizedElementMixin get typeParameterContext => this;
- List<TypeParameterElement> get typeParameters => const [];
+ @override
+ List<UnlinkedTypeParam> get unlinkedTypeParams => const [];
+
+ @override
+ bool get _hasTypeBeenInferred => _inferredReturnType != null;
+
+ @override
+ UnlinkedExecutable get _unlinkedExecutable =>
+ _variable.unlinkedVariable.initializer;
@override
FunctionElementForLink_Local getLocalFunction(int index) {
@@ -2818,8 +2951,27 @@
return index < functions.length ? functions[index] : null;
}
+ /**
+ * Store the results of type inference for this initializer in
+ * [compilationUnit].
+ */
+ void link(CompilationUnitElementInBuildUnit compilationUnit) {
+ compilationUnit._storeLinkedType(_unlinkedExecutable.inferredReturnTypeSlot,
+ _inferredReturnType, typeParameterContext);
+ for (FunctionElementForLink_Local_NonSynthetic function in functions) {
+ function.link(compilationUnit);
+ }
+ }
+
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ @override
+ void _setInferredType(DartType type) {
+ assert(!_hasTypeBeenInferred);
+ _inferredReturnType = type;
+ _variable._inferredType = _dynamicIfNull(type);
+ }
}
/**
@@ -2829,7 +2981,18 @@
implements
ExecutableElementForLink,
FunctionElementImpl,
- ReferenceableElementForLink {}
+ ReferenceableElementForLink {
+ /**
+ * Indicates whether type inference has completed for this function.
+ */
+ bool get _hasTypeBeenInferred;
+
+ /**
+ * Stores the given [type] as the inferred return type for this function.
+ * Should only be called if [_hasTypeBeenInferred] is `false`.
+ */
+ void _setInferredType(DartType type);
+}
/**
* Element representing a local function (possibly a closure) inside another
@@ -2841,6 +3004,14 @@
@override
final ExecutableElementForLink enclosingElement;
+ List<FunctionElementForLink_Local_NonSynthetic> _functions;
+
+ /**
+ * The type inference node for this function, or `null` if it hasn't been
+ * computed yet.
+ */
+ TypeInferenceNode _typeInferenceNode;
+
FunctionElementForLink_Local_NonSynthetic(
CompilationUnitElementForLink compilationUnit,
this.enclosingElement,
@@ -2848,10 +3019,25 @@
: super(compilationUnit, unlinkedExecutable);
@override
+ TypeInferenceNode get asTypeInferenceNode =>
+ _typeInferenceNode ??= new TypeInferenceNode(this);
+
+ @override
TypeParameterizedElementMixin get enclosingTypeParameterContext =>
enclosingElement;
@override
+ List<FunctionElementForLink_Local_NonSynthetic> get functions =>
+ _functions ??= _unlinkedExecutable.localFunctions
+ .map((UnlinkedExecutable ex) =>
+ new FunctionElementForLink_Local_NonSynthetic(
+ compilationUnit, this, ex))
+ .toList();
+
+ @override
+ bool get _hasTypeBeenInferred => _inferredReturnType != null;
+
+ @override
DartType buildType(
DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
assert(implicitFunctionTypeIndices.isEmpty);
@@ -2860,12 +3046,30 @@
@override
FunctionElementForLink_Local getLocalFunction(int index) {
- // TODO(paulberry): implement.
- throw new UnimplementedError();
+ List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions;
+ return index < functions.length ? functions[index] : null;
+ }
+
+ /**
+ * Store the results of type inference for this function in [compilationUnit].
+ */
+ void link(CompilationUnitElementInBuildUnit compilationUnit) {
+ compilationUnit._storeLinkedType(
+ _unlinkedExecutable.inferredReturnTypeSlot, inferredReturnType, this);
+ for (FunctionElementForLink_Local_NonSynthetic function in functions) {
+ function.link(compilationUnit);
+ }
}
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ @override
+ void _setInferredType(DartType type) {
+ // TODO(paulberry): store the inferred return type in the summary.
+ assert(!_hasTypeBeenInferred);
+ _inferredReturnType = _dynamicIfNull(type);
+ }
}
/**
@@ -4290,6 +4494,7 @@
compilationUnit._storeLinkedType(
unlinkedVariable.inferredTypeSlot, inferredType, null);
}
+ initializer?.link(compilationUnit);
}
}
}
@@ -4319,32 +4524,43 @@
*/
class TypeInferenceNode extends Node<TypeInferenceNode> {
/**
- * The [FieldElement] or [TopLevelVariableElement] to which this
- * node refers.
+ * The [FunctionElementForLink_Local] to which this node refers.
*/
- final VariableElementForLink variableElement;
+ final FunctionElementForLink_Local functionElement;
- TypeInferenceNode(this.variableElement);
+ TypeInferenceNode(this.functionElement);
@override
- bool get isEvaluated => variableElement._inferredType != null;
+ bool get isEvaluated => functionElement._hasTypeBeenInferred;
/**
- * Collect the type inference dependencies in [unlinkedConst] (which should be
- * interpreted relative to [compilationUnit]) and store them in
+ * Collect the type inference dependencies in [unlinkedExecutable] (which
+ * should be interpreted relative to [compilationUnit]) and store them in
* [dependencies].
*/
void collectDependencies(
List<TypeInferenceNode> dependencies,
- UnlinkedConst unlinkedConst,
+ UnlinkedExecutable unlinkedExecutable,
CompilationUnitElementForLink compilationUnit) {
+ UnlinkedConst unlinkedConst = unlinkedExecutable?.bodyExpr;
if (unlinkedConst == null) {
return;
}
int refPtr = 0;
+ int intPtr = 0;
for (UnlinkedConstOperation operation in unlinkedConst.operations) {
switch (operation) {
+ case UnlinkedConstOperation.pushInt:
+ intPtr++;
+ break;
+ case UnlinkedConstOperation.pushLongInt:
+ int numInts = unlinkedConst.ints[intPtr++];
+ intPtr += numInts;
+ break;
+ case UnlinkedConstOperation.concatenate:
+ intPtr++;
+ break;
case UnlinkedConstOperation.pushReference:
EntityRef ref = unlinkedConst.references[refPtr++];
// TODO(paulberry): cache these resolved references for
@@ -4355,12 +4571,21 @@
dependencies.add(dependency);
}
break;
- case UnlinkedConstOperation.makeTypedList:
case UnlinkedConstOperation.invokeConstructor:
refPtr++;
+ intPtr += 2;
+ break;
+ case UnlinkedConstOperation.makeUntypedList:
+ case UnlinkedConstOperation.makeUntypedMap:
+ intPtr++;
+ break;
+ case UnlinkedConstOperation.makeTypedList:
+ refPtr++;
+ intPtr++;
break;
case UnlinkedConstOperation.makeTypedMap:
refPtr += 2;
+ intPtr++;
break;
case UnlinkedConstOperation.assignToRef:
// TODO(paulberry): if this reference refers to a variable, should it
@@ -4371,39 +4596,53 @@
// TODO(paulberry): if this reference refers to a variable, should it
// be considered a type inference dependency?
refPtr++;
+ intPtr += 2;
+ int numTypeArguments = unlinkedConst.ints[intPtr++];
+ refPtr += numTypeArguments;
+ break;
+ case UnlinkedConstOperation.invokeMethod:
+ intPtr += 2;
+ int numTypeArguments = unlinkedConst.ints[intPtr++];
+ refPtr += numTypeArguments;
break;
case UnlinkedConstOperation.typeCast:
case UnlinkedConstOperation.typeCheck:
refPtr++;
break;
+ case UnlinkedConstOperation.pushLocalFunctionReference:
+ int popCount = unlinkedConst.ints[intPtr++];
+ assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
+ dependencies.add(functionElement
+ .getLocalFunction(unlinkedConst.ints[intPtr++])
+ .asTypeInferenceNode);
+ break;
default:
break;
}
}
assert(refPtr == unlinkedConst.references.length);
+ assert(intPtr == unlinkedConst.ints.length);
}
@override
List<TypeInferenceNode> computeDependencies() {
List<TypeInferenceNode> dependencies = <TypeInferenceNode>[];
- collectDependencies(
- dependencies,
- variableElement.unlinkedVariable.initializer?.bodyExpr,
- variableElement.compilationUnit);
+ collectDependencies(dependencies, functionElement._unlinkedExecutable,
+ functionElement.compilationUnit);
return dependencies;
}
void evaluate(bool inCycle) {
if (inCycle) {
- variableElement._inferredType = DynamicTypeImpl.instance;
+ functionElement._setInferredType(DynamicTypeImpl.instance);
} else {
- variableElement._inferredType =
- new ExprTypeComputer(variableElement).compute();
+ functionElement
+ ._setInferredType(new ExprTypeComputer(functionElement).compute());
}
}
@override
- String toString() => 'TypeInferenceNode($variableElement)';
+ String toString() => 'TypeInferenceNode($functionElement)';
}
class TypeProviderForLink implements TypeProvider {
@@ -4606,7 +4845,7 @@
unlinkedVariable.initializer?.bodyExpr != null) {
_constNode = new ConstVariableNode(this);
if (unlinkedVariable.type == null) {
- _typeInferenceNode = new TypeInferenceNode(this);
+ _typeInferenceNode = initializer.asTypeInferenceNode;
}
}
}
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 7c6ee32..a3c1d0c 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -11,7 +11,6 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/resynthesize.dart';
-import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/model.dart';
@@ -20,114 +19,18 @@
/**
* The [ResultProvider] that provides results from input package summaries.
*/
-class InputPackagesResultProvider extends ResultProvider {
- final InternalAnalysisContext _context;
-
- _FileBasedSummaryResynthesizer _resynthesizer;
- SummaryResultProvider _sdkProvider;
-
- InputPackagesResultProvider(this._context, SummaryDataStore dataStore) {
- InternalAnalysisContext sdkContext = _context.sourceFactory.dartSdk.context;
- _sdkProvider = sdkContext.resultProvider;
- // Set the type provider to prevent the context from computing it.
- _context.typeProvider = sdkContext.typeProvider;
- // Create a chained resynthesizer.
- _resynthesizer = new _FileBasedSummaryResynthesizer(
- _sdkProvider.resynthesizer,
- _context,
- _context.typeProvider,
- _context.sourceFactory,
- _context.analysisOptions.strongMode,
- dataStore);
+class InputPackagesResultProvider extends ResynthesizerResultProvider {
+ InputPackagesResultProvider(
+ InternalAnalysisContext context, SummaryDataStore dataStore)
+ : super(context, dataStore) {
+ AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
+ createResynthesizer(sdkContext, sdkContext.typeProvider);
}
@override
- bool compute(CacheEntry entry, ResultDescriptor result) {
- if (_sdkProvider.compute(entry, result)) {
- return true;
- }
- AnalysisTarget target = entry.target;
- // Only library results are supported for now.
- if (target is Source) {
- Uri uri = target.uri;
- // We know how to server results to input packages.
- String uriString = uri.toString();
- if (!_resynthesizer.hasLibrarySummary(uriString)) {
- return false;
- }
- // Provide known results.
- if (result == LIBRARY_ELEMENT1 ||
- result == LIBRARY_ELEMENT2 ||
- result == LIBRARY_ELEMENT3 ||
- result == LIBRARY_ELEMENT4 ||
- result == LIBRARY_ELEMENT5 ||
- result == LIBRARY_ELEMENT6 ||
- result == LIBRARY_ELEMENT7 ||
- result == LIBRARY_ELEMENT8 ||
- result == LIBRARY_ELEMENT9 ||
- result == LIBRARY_ELEMENT ||
- false) {
- LibraryElement libraryElement =
- _resynthesizer.getLibraryElement(uriString);
- entry.setValue(result, libraryElement, TargetedResult.EMPTY_LIST);
- return true;
- } else if (result == READY_LIBRARY_ELEMENT2 ||
- result == READY_LIBRARY_ELEMENT6 ||
- result == READY_LIBRARY_ELEMENT7) {
- entry.setValue(result, true, TargetedResult.EMPTY_LIST);
- return true;
- } else if (result == SOURCE_KIND) {
- if (_resynthesizer._dataStore.linkedMap.containsKey(uriString)) {
- entry.setValue(result, SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
- return true;
- }
- if (_resynthesizer._dataStore.unlinkedMap.containsKey(uriString)) {
- entry.setValue(result, SourceKind.PART, TargetedResult.EMPTY_LIST);
- return true;
- }
- return false;
- }
- } else if (target is LibrarySpecificUnit) {
- String uriString = target.library.uri.toString();
- if (!_resynthesizer.hasLibrarySummary(uriString)) {
- return false;
- }
- if (result == CREATED_RESOLVED_UNIT1 ||
- result == CREATED_RESOLVED_UNIT2 ||
- result == CREATED_RESOLVED_UNIT3 ||
- result == CREATED_RESOLVED_UNIT4 ||
- result == CREATED_RESOLVED_UNIT5 ||
- result == CREATED_RESOLVED_UNIT6 ||
- result == CREATED_RESOLVED_UNIT7 ||
- result == CREATED_RESOLVED_UNIT8 ||
- result == CREATED_RESOLVED_UNIT9 ||
- result == CREATED_RESOLVED_UNIT10 ||
- result == CREATED_RESOLVED_UNIT11 ||
- result == CREATED_RESOLVED_UNIT12) {
- entry.setValue(result, true, TargetedResult.EMPTY_LIST);
- return true;
- }
- if (result == COMPILATION_UNIT_ELEMENT) {
- String libraryUri = target.library.uri.toString();
- String unitUri = target.unit.uri.toString();
- CompilationUnitElement unit = _resynthesizer.getElement(
- new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
- if (unit != null) {
- entry.setValue(result, unit, TargetedResult.EMPTY_LIST);
- return true;
- }
- }
- } else if (target is VariableElement) {
- if (!_resynthesizer
- .hasLibrarySummary(target.library.source.uri.toString())) {
- return false;
- }
- if (result == PROPAGATED_VARIABLE || result == INFERRED_STATIC_VARIABLE) {
- entry.setValue(result, target, TargetedResult.EMPTY_LIST);
- return true;
- }
- }
- return false;
+ bool hasResultsForSource(Source source) {
+ String uriString = source.uri.toString();
+ return resynthesizer.hasLibrarySummary(uriString);
}
}
@@ -211,6 +114,147 @@
}
/**
+ * The [ResultProvider] that provides results using summary resynthesizer.
+ */
+abstract class ResynthesizerResultProvider extends ResultProvider {
+ final InternalAnalysisContext context;
+ final SummaryDataStore _dataStore;
+
+ _FileBasedSummaryResynthesizer _resynthesizer;
+ ResynthesizerResultProvider _sdkProvider;
+
+ ResynthesizerResultProvider(this.context, this._dataStore);
+
+ SummaryResynthesizer get resynthesizer => _resynthesizer;
+
+ /**
+ * Add a new [bundle] to the resynthesizer.
+ */
+ void addBundle(String path, PackageBundle bundle) {
+ _dataStore.addBundle(path, bundle);
+ }
+
+ @override
+ bool compute(CacheEntry entry, ResultDescriptor result) {
+ if (_sdkProvider != null && _sdkProvider.compute(entry, result)) {
+ return true;
+ }
+ AnalysisTarget target = entry.target;
+ // Check whether there are results for the source.
+ if (!hasResultsForSource(target.source)) {
+ return false;
+ }
+ // Constant expressions are always resolved in summaries.
+ if (result == CONSTANT_EXPRESSION_RESOLVED &&
+ target is ConstantEvaluationTarget) {
+ entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ // Provide results for Source.
+ if (target is Source) {
+ String uriString = target.uri.toString();
+ // Provide known results.
+ if (result == LIBRARY_ELEMENT1 ||
+ result == LIBRARY_ELEMENT2 ||
+ result == LIBRARY_ELEMENT3 ||
+ result == LIBRARY_ELEMENT4 ||
+ result == LIBRARY_ELEMENT5 ||
+ result == LIBRARY_ELEMENT6 ||
+ result == LIBRARY_ELEMENT7 ||
+ result == LIBRARY_ELEMENT8 ||
+ result == LIBRARY_ELEMENT9 ||
+ result == LIBRARY_ELEMENT) {
+ LibraryElement libraryElement =
+ resynthesizer.getLibraryElement(uriString);
+ entry.setValue(result, libraryElement, TargetedResult.EMPTY_LIST);
+ return true;
+ } else if (result == READY_LIBRARY_ELEMENT2 ||
+ result == READY_LIBRARY_ELEMENT6 ||
+ result == READY_LIBRARY_ELEMENT7) {
+ entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+ return true;
+ } else if (result == SOURCE_KIND) {
+ if (_dataStore.linkedMap.containsKey(uriString)) {
+ entry.setValue(result, SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ if (_dataStore.unlinkedMap.containsKey(uriString)) {
+ entry.setValue(result, SourceKind.PART, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ return false;
+ }
+ } else if (target is LibrarySpecificUnit) {
+ if (!hasResultsForSource(target.library)) {
+ return false;
+ }
+ if (result == CREATED_RESOLVED_UNIT1 ||
+ result == CREATED_RESOLVED_UNIT2 ||
+ result == CREATED_RESOLVED_UNIT3 ||
+ result == CREATED_RESOLVED_UNIT4 ||
+ result == CREATED_RESOLVED_UNIT5 ||
+ result == CREATED_RESOLVED_UNIT6 ||
+ result == CREATED_RESOLVED_UNIT7 ||
+ result == CREATED_RESOLVED_UNIT8 ||
+ result == CREATED_RESOLVED_UNIT9 ||
+ result == CREATED_RESOLVED_UNIT10 ||
+ result == CREATED_RESOLVED_UNIT11 ||
+ result == CREATED_RESOLVED_UNIT12) {
+ entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ if (result == COMPILATION_UNIT_ELEMENT) {
+ String libraryUri = target.library.uri.toString();
+ String unitUri = target.unit.uri.toString();
+ CompilationUnitElement unit = resynthesizer.getElement(
+ new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
+ if (unit != null) {
+ entry.setValue(result, unit, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ }
+ } else if (target is VariableElement) {
+ if (!hasResultsForSource(target.library.source)) {
+ return false;
+ }
+ if (result == PROPAGATED_VARIABLE || result == INFERRED_STATIC_VARIABLE) {
+ entry.setValue(result, target, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ }
+ // Unknown target.
+ return false;
+ }
+
+ /**
+ * Create the [resynthesizer] instance.
+ *
+ * Subclasses must call this method in their constructors.
+ */
+ void createResynthesizer(
+ InternalAnalysisContext sdkContext, TypeProvider typeProvider) {
+ // Set the type provider to prevent the context from computing it.
+ context.typeProvider = typeProvider;
+ // Create a chained resynthesizer.
+ _sdkProvider = sdkContext?.resultProvider;
+ _resynthesizer = new _FileBasedSummaryResynthesizer(
+ _sdkProvider?.resynthesizer,
+ context,
+ typeProvider,
+ context.sourceFactory,
+ context.analysisOptions.strongMode,
+ _dataStore);
+ }
+
+ /**
+ * Return `true` if this result provider can provide a result for the
+ * given [source]. The provider must ensure that [addBundle] is invoked for
+ * every bundle that would be required to provide results for the [source].
+ */
+ bool hasResultsForSource(Source source);
+}
+
+/**
* A [SummaryDataStore] is a container for the data extracted from a set of
* summary package bundles. It contains maps which can be used to find linked
* and unlinked summaries by URI.
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 298c20d..d757b80 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -14,13 +14,11 @@
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/idl.dart';
/**
@@ -310,6 +308,19 @@
_ConstExprBuilder(this.resynthesizer, this.context, this.uc);
+ /**
+ * Return the [ConstructorElement] enclosing [context].
+ */
+ ConstructorElement get _enclosingConstructor {
+ for (Element e = context; e != null; e = e.enclosingElement) {
+ if (e is ConstructorElement) {
+ return e;
+ }
+ }
+ throw new StateError(
+ 'Unable to find the enclosing constructor of $context');
+ }
+
Expression build() {
if (!uc.isValidConst) {
return AstFactory.identifier3(r'$$invalidConstExpr$$');
@@ -471,7 +482,7 @@
case UnlinkedConstOperation.pushParameter:
String name = uc.strings[stringPtr++];
SimpleIdentifier identifier = AstFactory.identifier3(name);
- identifier.staticElement = resynthesizer.currentConstructor.parameters
+ identifier.staticElement = _enclosingConstructor.parameters
.firstWhere((parameter) => parameter.name == name,
orElse: () => throw new StateError(
'Unable to resolve constructor parameter: $name'));
@@ -575,8 +586,8 @@
*/
TypeName _newTypeName() {
EntityRef typeRef = uc.references[refPtr++];
- DartType type = resynthesizer.buildType(
- typeRef, resynthesizer._currentTypeParameterizedElement);
+ DartType type =
+ resynthesizer.buildType(typeRef, context?.typeParameterContext);
return _buildTypeAst(type);
}
@@ -622,7 +633,7 @@
InterfaceType definingType = resynthesizer._createConstructorDefiningType(
context?.typeParameterContext, info, ref.typeArguments);
constructorElement =
- resynthesizer._createConstructorElement(definingType, info);
+ resynthesizer._getConstructorForInfo(definingType, info);
typeNode = _buildTypeAst(definingType);
} else {
if (info.enclosing != null) {
@@ -675,12 +686,21 @@
EntityRef ref = uc.references[refPtr++];
_ReferenceInfo info = resynthesizer.getReferenceInfo(ref.reference);
Expression node = _buildIdentifierSequence(info);
+ TypeArgumentList typeArguments;
+ int numTypeArguments = uc.ints[intPtr++];
+ if (numTypeArguments > 0) {
+ List<TypeName> typeNames = new List<TypeName>(numTypeArguments);
+ for (int i = 0; i < numTypeArguments; i++) {
+ typeNames[i] = _newTypeName();
+ }
+ typeArguments = AstFactory.typeArgumentList(typeNames);
+ }
if (node is SimpleIdentifier) {
_push(new MethodInvocation(
null,
TokenFactory.tokenFromType(TokenType.PERIOD),
node,
- null,
+ typeArguments,
AstFactory.argumentList(arguments)));
} else {
throw new UnimplementedError('For ${node?.runtimeType}: $node');
@@ -729,184 +749,6 @@
}
/**
- * Temporary [TypeParameterizedElementMixin] implementation.
- *
- * TODO(scheglov) remove after moving resynthesize logic to Impl.
- */
-class _CurrentTypeParameterizedElement
- implements TypeParameterizedElementMixin {
- final _UnitResynthesizer unitResynthesizer;
-
- _CurrentTypeParameterizedElement(this.unitResynthesizer);
-
- @override
- TypeParameterType getTypeParameterType(int index) {
- return unitResynthesizer.getTypeParameterFromScope(index);
- }
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/**
- * A class element that has been resynthesized from a summary. The actual
- * element won't be constructed until it is requested. But properties
- * [context], [displayName], [enclosingElement] and [name] can be used without
- * creating the actual element. This allows to put these elements into
- * namespaces without creating actual elements until they are really needed.
- */
-class _DeferredClassElement extends ClassElementHandle {
- final _UnitResynthesizer unitResynthesizer;
- final CompilationUnitElement unitElement;
- final UnlinkedClass serializedClass;
-
- ClassElementImpl _actualElement;
-
- /**
- * We don't resynthesize executables of classes until they are requested.
- * TODO(scheglov) Check whether we need separate flags for separate kinds.
- */
- bool _executablesResynthesized = false;
-
- @override
- final String name;
-
- factory _DeferredClassElement(_UnitResynthesizer unitResynthesizer,
- CompilationUnitElement unitElement, UnlinkedClass serializedClass) {
- String name = serializedClass.name;
- List<String> components =
- unitResynthesizer.unit.location.components.toList();
- components.add(name);
- ElementLocationImpl location = new ElementLocationImpl.con3(components);
- return new _DeferredClassElement._(
- unitResynthesizer, unitElement, serializedClass, name, location);
- }
-
- _DeferredClassElement._(this.unitResynthesizer, this.unitElement,
- this.serializedClass, this.name, ElementLocation location)
- : super(null, location);
-
- @override
- List<PropertyAccessorElement> get accessors {
- _ensureExecutables();
- return actualElement.accessors;
- }
-
- @override
- ClassElementImpl get actualElement {
- if (_actualElement == null) {
- _actualElement = unitResynthesizer.buildClassImpl(serializedClass, this);
- _actualElement.enclosingElement = unitElement;
- }
- return _actualElement;
- }
-
- @override
- List<ConstructorElement> get constructors {
- _ensureExecutables();
- return actualElement.constructors;
- }
-
- @override
- AnalysisContext get context => unitElement.context;
-
- @override
- String get displayName => name;
-
- @override
- CompilationUnitElement get enclosingElement {
- return unitElement;
- }
-
- @override
- List<FieldElement> get fields {
- _ensureExecutables();
- return actualElement.fields;
- }
-
- @override
- List<MethodElement> get methods {
- _ensureExecutables();
- return actualElement.methods;
- }
-
- @override
- void ensureAccessorsReady() {
- _ensureExecutables();
- }
-
- @override
- void ensureActualElementComplete() {
- _ensureExecutables();
- }
-
- @override
- void ensureConstructorsReady() {
- _ensureExecutables();
- }
-
- @override
- void ensureMethodsReady() {
- _ensureExecutables();
- }
-
- /**
- * Ensure that we have [actualElement], and it has all executables.
- */
- void _ensureExecutables() {
- if (!_executablesResynthesized) {
- _executablesResynthesized = true;
- unitResynthesizer.buildClassExecutables(actualElement, serializedClass);
- }
- }
-}
-
-/**
- * The constructor element that has been resynthesized from a summary. The
- * actual element won't be constructed until it is requested. But properties
- * [displayName], [enclosingElement] and [name] can be used without creating
- * the actual element.
- */
-class _DeferredConstructorElement extends ConstructorElementHandle {
- /**
- * The type defining this constructor element. If [_isMember] is `false`,
- * then the type parameters of [_definingType] are not guaranteed to be
- * valid.
- */
- final InterfaceType _definingType;
-
- /**
- * The constructor name.
- */
- final String name;
-
- factory _DeferredConstructorElement(InterfaceType definingType, String name) {
- List<String> components = definingType.element.location.components.toList();
- components.add(name);
- ElementLocationImpl location = new ElementLocationImpl.con3(components);
- return new _DeferredConstructorElement._(definingType, name, location);
- }
-
- _DeferredConstructorElement._(
- this._definingType, this.name, ElementLocation location)
- : super(null, location);
-
- @override
- ConstructorElement get actualElement =>
- enclosingElement.getNamedConstructor(name);
-
- @override
- AnalysisContext get context => _definingType.element.context;
-
- @override
- String get displayName => name;
-
- @override
- ClassElement get enclosingElement {
- return _definingType.element;
- }
-}
-
-/**
* Local function element representing the initializer for a variable that has
* been resynthesized from a summary. The actual element won't be constructed
* until it is requested. But properties [context] and [enclosingElement] can
@@ -1043,12 +885,6 @@
LibraryElementImpl library;
/**
- * Classes which should have their supertype set to "object" once
- * resynthesis is complete. Only used if [isCoreLibrary] is `true`.
- */
- List<ClassElementImpl> delayedObjectSubclasses = <ClassElementImpl>[];
-
- /**
* Map of compilation unit elements that have been resynthesized so far. The
* key is the URI of the compilation unit.
*/
@@ -1170,17 +1006,9 @@
}
library.parts = partResynthesizers.map((r) => r.unit).toList();
// Populate units.
- populateUnit(definingUnitResynthesizer);
+ rememberUriToUnit(definingUnitResynthesizer);
for (_UnitResynthesizer partResynthesizer in partResynthesizers) {
- populateUnit(partResynthesizer);
- }
- // Update delayed Object class references.
- if (isCoreLibrary) {
- ClassElement objectElement = library.getType('Object');
- assert(objectElement != null);
- for (ClassElementImpl classElement in delayedObjectSubclasses) {
- classElement.supertype = objectElement.type;
- }
+ rememberUriToUnit(partResynthesizer);
}
// Create the synthetic element for `loadLibrary`.
// Until the client received dart:core and dart:async, we cannot do this,
@@ -1261,13 +1089,12 @@
}
/**
- * Populate a [CompilationUnitElement] by deserializing all the elements
- * contained in it.
+ * Remember the absolute URI to the corresponding unit mapping.
*/
- void populateUnit(_UnitResynthesizer unitResynthesized) {
- unitResynthesized.populateUnit();
- String absoluteUri = unitResynthesized.unit.source.uri.toString();
- resynthesizedUnits[absoluteUri] = unitResynthesized.unit;
+ void rememberUriToUnit(_UnitResynthesizer unitResynthesized) {
+ CompilationUnitElementImpl unit = unitResynthesized.unit;
+ String absoluteUri = unit.source.uri.toString();
+ resynthesizedUnits[absoluteUri] = unit;
}
}
@@ -1536,13 +1363,20 @@
}
@override
- List<FunctionElementImpl> buildTopLevelFunctions() {
- return _unitResynthesizer.buildTopLevelFunctions();
+ UnitExplicitTopLevelVariables buildTopLevelVariables() {
+ return _unitResynthesizer.buildUnitExplicitTopLevelVariables();
}
@override
- UnitExplicitTopLevelVariables buildTopLevelVariables() {
- return _unitResynthesizer.buildUnitExplicitTopLevelVariables();
+ bool isInConstCycle(int slot) {
+ return _unitResynthesizer.constCycles.contains(slot);
+ }
+
+ @override
+ ConstructorElement resolveConstructorRef(
+ TypeParameterizedElementMixin typeParameterContext, EntityRef entry) {
+ return _unitResynthesizer._getConstructorForEntry(
+ typeParameterContext, entry);
}
@override
@@ -1588,13 +1422,6 @@
CompilationUnitElementImpl unit;
/**
- * [ElementHolder] into which resynthesized elements should be placed. This
- * object is recreated afresh for each unit in the library, and is used to
- * populate the [CompilationUnitElement].
- */
- final ElementHolder unitHolder = new ElementHolder();
-
- /**
* Map from slot id to the corresponding [EntityRef] object for linked types
* (i.e. propagated and inferred types).
*/
@@ -1606,39 +1433,6 @@
*/
Set<int> constCycles;
- /**
- * The [ConstructorElementImpl] for the constructor currently being
- * resynthesized.
- */
- ConstructorElementImpl currentConstructor;
-
- /**
- * Type parameters for the generic class, typedef, or executable currently
- * being resynthesized, if any. This is a list of lists; if multiple
- * entities with type parameters are nested (e.g. a generic executable inside
- * a generic class), then the zeroth element of [currentTypeParameters]
- * contains the type parameters for the outermost nested entity, and further
- * elements contain the type parameters for entities that are more deeply
- * nested. If we are not currently resynthesizing a class, typedef, or
- * executable, then this is an empty list.
- */
- final List<List<TypeParameterElement>> currentTypeParameters =
- <List<TypeParameterElement>>[];
-
- /**
- * If a class is currently being resynthesized, map from field name to the
- * corresponding field element. This is used when resynthesizing
- * initializing formal parameters.
- */
- Map<String, FieldElementImpl> fields;
-
- /**
- * If a class is currently being resynthesized, map from constructor name to
- * the corresponding constructor element. This is used when resynthesizing
- * constructor initializers.
- */
- Map<String, ConstructorElementImpl> constructors;
-
int numLinkedReferences;
int numUnlinkedReferences;
@@ -1654,11 +1448,6 @@
*/
ResynthesizerContext _resynthesizerContext;
- /**
- * TODO(scheglov) clean up after moving resynthesize logic to Impl.
- */
- TypeParameterizedElementMixin _currentTypeParameterizedElement;
-
_UnitResynthesizer(this.libraryResynthesizer, this.unlinkedUnit,
this.linkedUnit, Source unitSource, UnlinkedPart unlinkedPart) {
_resynthesizerContext = new _ResynthesizerContext(this);
@@ -1675,8 +1464,6 @@
numLinkedReferences = linkedUnit.references.length;
numUnlinkedReferences = unlinkedUnit.references.length;
referenceInfos = new List<_ReferenceInfo>(numLinkedReferences);
- _currentTypeParameterizedElement =
- new _CurrentTypeParameterizedElement(this);
}
SummaryResynthesizer get summaryResynthesizer =>
@@ -1713,499 +1500,14 @@
}
/**
- * Build the annotations for the given [element].
- */
- void buildAnnotations(
- ElementImpl element, List<UnlinkedConst> serializedAnnotations) {
- if (serializedAnnotations.isNotEmpty) {
- element.metadata = serializedAnnotations
- .map((a) => buildAnnotation(element, a))
- .toList();
- }
- }
-
- /**
- * Resynthesize a [ClassElement] and place it in [unitHolder].
- */
- void buildClass(UnlinkedClass serializedClass) {
- ClassElement classElement;
- if (libraryResynthesizer.isCoreLibrary &&
- serializedClass.supertype == null) {
- classElement = buildClassImpl(serializedClass, null);
- if (!serializedClass.hasNoSupertype) {
- libraryResynthesizer.delayedObjectSubclasses.add(classElement);
- }
- } else {
- classElement = new _DeferredClassElement(this, unit, serializedClass);
- }
- unitHolder.addType(classElement);
- }
-
- /**
- * Fill the given [ClassElementImpl] with executable elements and fields.
- */
- void buildClassExecutables(
- ClassElementImpl classElement, UnlinkedClass serializedClass) {
- currentTypeParameters.add(classElement.typeParameters);
- ElementHolder memberHolder = new ElementHolder();
- fields = <String, FieldElementImpl>{};
- for (UnlinkedVariable serializedVariable in serializedClass.fields) {
- buildVariable(classElement, serializedVariable, memberHolder);
- }
- bool constructorFound = false;
- constructors = <String, ConstructorElementImpl>{};
- for (UnlinkedExecutable serializedExecutable
- in serializedClass.executables) {
- switch (serializedExecutable.kind) {
- case UnlinkedExecutableKind.constructor:
- constructorFound = true;
- buildConstructor(serializedExecutable, classElement, memberHolder);
- break;
- case UnlinkedExecutableKind.functionOrMethod:
- case UnlinkedExecutableKind.getter:
- case UnlinkedExecutableKind.setter:
- if (serializedExecutable.isStatic) {
- currentTypeParameters.removeLast();
- }
- buildExecutable(serializedExecutable, classElement, memberHolder);
- if (serializedExecutable.isStatic) {
- currentTypeParameters.add(classElement.typeParameters);
- }
- break;
- }
- }
- if (!serializedClass.isMixinApplication) {
- if (!constructorFound) {
- // Synthesize implicit constructors.
- ConstructorElementImpl constructor = new ConstructorElementImpl('', -1);
- constructor.synthetic = true;
- constructor.returnType = classElement.type;
- constructor.type = new FunctionTypeImpl.elementWithNameAndArgs(
- constructor, null, getCurrentTypeArguments(), false);
- memberHolder.addConstructor(constructor);
- }
- classElement.constructors = memberHolder.constructors;
- }
- classElement.accessors = memberHolder.accessors;
- classElement.fields = memberHolder.fields;
- classElement.methods = memberHolder.methods;
- resolveConstructorInitializers(classElement);
- currentTypeParameters.removeLast();
- assert(currentTypeParameters.isEmpty);
- }
-
- /**
- * Resynthesize a [ClassElementImpl]. If [handle] is not `null`, then
- * executables are not resynthesized, and [InterfaceTypeImpl] is created
- * around the [handle], so that executables are resynthesized lazily.
- */
- ClassElementImpl buildClassImpl(
- UnlinkedClass serializedClass, ClassElementHandle handle) {
- ClassElementImpl classElement =
- new ClassElementImpl.forSerialized(serializedClass, unit);
- classElement.hasBeenInferred = summaryResynthesizer.strongMode;
- InterfaceTypeImpl correspondingType =
- new InterfaceTypeImpl(handle ?? classElement);
- if (serializedClass.supertype != null) {
- classElement.supertype =
- buildType(serializedClass.supertype, classElement);
- } else if (!libraryResynthesizer.isCoreLibrary) {
- classElement.supertype = typeProvider.objectType;
- }
- classElement.interfaces = serializedClass.interfaces
- .map((EntityRef t) => buildType(t, classElement))
- .toList();
- classElement.mixins = serializedClass.mixins
- .map((EntityRef t) => buildType(t, classElement))
- .toList();
- // TODO(scheglov) move to ClassElementImpl
- correspondingType.typeArguments = classElement.typeParameterTypes;
- classElement.type = correspondingType;
- assert(currentTypeParameters.isEmpty);
- // TODO(scheglov) Somehow Observatory shows too much time spent here
- // during DDC run on the large codebase. I would expect only Object here.
- if (handle == null) {
- buildClassExecutables(classElement, serializedClass);
- }
- fields = null;
- constructors = null;
- return classElement;
- }
-
- void buildCodeRange(ElementImpl element, CodeRange codeRange) {
- if (codeRange != null) {
- element.setCodeRange(codeRange.offset, codeRange.length);
- }
- }
-
- /**
- * Resynthesize a [NamespaceCombinator].
- */
- NamespaceCombinator buildCombinator(UnlinkedCombinator serializedCombinator) {
- if (serializedCombinator.shows.isNotEmpty) {
- ShowElementCombinatorImpl combinator = new ShowElementCombinatorImpl();
- // Note: we call toList() so that we don't retain a reference to the
- // deserialized data structure.
- combinator.shownNames = serializedCombinator.shows.toList();
- combinator.offset = serializedCombinator.offset;
- combinator.end = serializedCombinator.end;
- return combinator;
- } else {
- HideElementCombinatorImpl combinator = new HideElementCombinatorImpl();
- // Note: we call toList() so that we don't retain a reference to the
- // deserialized data structure.
- combinator.hiddenNames = serializedCombinator.hides.toList();
- return combinator;
- }
- }
-
- /**
- * Resynthesize a [ConstructorElement] and place it in the given [holder].
- * [classElement] is the element of the class for which this element is a
- * constructor.
- */
- void buildConstructor(UnlinkedExecutable serializedExecutable,
- ClassElementImpl classElement, ElementHolder holder) {
- assert(serializedExecutable.kind == UnlinkedExecutableKind.constructor);
- currentConstructor = new ConstructorElementImpl.forSerialized(
- serializedExecutable, classElement);
- currentConstructor.isCycleFree = serializedExecutable.isConst &&
- !constCycles.contains(serializedExecutable.constCycleSlot);
- if (serializedExecutable.name.isEmpty) {
- currentConstructor.nameEnd =
- serializedExecutable.nameOffset + classElement.name.length;
- } else {
- currentConstructor.nameEnd = serializedExecutable.nameEnd;
- currentConstructor.periodOffset = serializedExecutable.periodOffset;
- }
- constructors[serializedExecutable.name] = currentConstructor;
- buildExecutableCommonParts(currentConstructor, serializedExecutable);
- currentConstructor.constantInitializers = serializedExecutable
- .constantInitializers
- .map((i) => buildConstructorInitializer(currentConstructor, i))
- .toList();
- if (serializedExecutable.isRedirectedConstructor) {
- if (serializedExecutable.isFactory) {
- EntityRef redirectedConstructor =
- serializedExecutable.redirectedConstructor;
- _ReferenceInfo info = getReferenceInfo(redirectedConstructor.reference);
- List<EntityRef> typeArguments = redirectedConstructor.typeArguments;
- currentConstructor.redirectedConstructor = _createConstructorElement(
- _createConstructorDefiningType(classElement, info, typeArguments),
- info);
- } else {
- List<String> locationComponents = unit.location.components.toList();
- locationComponents.add(classElement.name);
- locationComponents.add(serializedExecutable.redirectedConstructorName);
- currentConstructor.redirectedConstructor =
- new _DeferredConstructorElement._(
- classElement.type,
- serializedExecutable.redirectedConstructorName,
- new ElementLocationImpl.con3(locationComponents));
- }
- }
- holder.addConstructor(currentConstructor);
- currentConstructor = null;
- }
-
- /**
- * Resynthesize the [ConstructorInitializer] in context of
- * [currentConstructor], which is used to resolve constructor parameter names.
- */
- ConstructorInitializer buildConstructorInitializer(
- ConstructorElementImpl enclosingConstructor,
- UnlinkedConstructorInitializer serialized) {
- UnlinkedConstructorInitializerKind kind = serialized.kind;
- String name = serialized.name;
- List<Expression> arguments = <Expression>[];
- {
- int numArguments = serialized.arguments.length;
- int numNames = serialized.argumentNames.length;
- for (int i = 0; i < numArguments; i++) {
- Expression expression = _buildConstExpression(
- enclosingConstructor, serialized.arguments[i]);
- int nameIndex = numNames + i - numArguments;
- if (nameIndex >= 0) {
- expression = AstFactory.namedExpression2(
- serialized.argumentNames[nameIndex], expression);
- }
- arguments.add(expression);
- }
- }
- switch (kind) {
- case UnlinkedConstructorInitializerKind.field:
- return AstFactory.constructorFieldInitializer(false, name,
- _buildConstExpression(enclosingConstructor, serialized.expression));
- case UnlinkedConstructorInitializerKind.superInvocation:
- return AstFactory.superConstructorInvocation2(
- name.isNotEmpty ? name : null, arguments);
- case UnlinkedConstructorInitializerKind.thisInvocation:
- return AstFactory.redirectingConstructorInvocation2(
- name.isNotEmpty ? name : null, arguments);
- }
- }
-
- /**
- * Build the documentation for the given [element]. Does nothing if
- * [serializedDocumentationComment] is `null`.
- */
- void buildDocumentation(ElementImpl element,
- UnlinkedDocumentationComment serializedDocumentationComment) {
- if (serializedDocumentationComment != null) {
- element.documentationComment = serializedDocumentationComment.text;
- element.setDocRange(serializedDocumentationComment.offset,
- serializedDocumentationComment.length);
- }
- }
-
- /**
- * Resynthesize the [ClassElement] corresponding to an enum, along with the
- * associated fields and implicit accessors.
- */
- void buildEnum(UnlinkedEnum serializedEnum) {
- assert(!libraryResynthesizer.isCoreLibrary);
- ClassElementImpl classElement =
- new ClassElementImpl(serializedEnum.name, serializedEnum.nameOffset);
- classElement.enum2 = true;
- InterfaceType enumType = new InterfaceTypeImpl(classElement);
- classElement.type = enumType;
- classElement.supertype = typeProvider.objectType;
- buildDocumentation(classElement, serializedEnum.documentationComment);
- buildAnnotations(classElement, serializedEnum.annotations);
- buildCodeRange(classElement, serializedEnum.codeRange);
- ElementHolder memberHolder = new ElementHolder();
- // Build the 'index' field.
- FieldElementImpl indexField = new FieldElementImpl('index', -1);
- indexField.final2 = true;
- indexField.synthetic = true;
- indexField.type = typeProvider.intType;
- memberHolder.addField(indexField);
- buildImplicitAccessors(indexField, memberHolder);
- // Build the 'values' field.
- FieldElementImpl valuesField = new ConstFieldElementImpl('values', -1);
- valuesField.synthetic = true;
- valuesField.const3 = true;
- valuesField.static = true;
- valuesField.type = typeProvider.listType.instantiate(<DartType>[enumType]);
- memberHolder.addField(valuesField);
- buildImplicitAccessors(valuesField, memberHolder);
- // Build fields for all enum constants.
- List<DartObjectImpl> constantValues = <DartObjectImpl>[];
- for (int i = 0; i < serializedEnum.values.length; i++) {
- UnlinkedEnumValue serializedEnumValue = serializedEnum.values[i];
- String fieldName = serializedEnumValue.name;
- ConstFieldElementImpl field =
- new ConstFieldElementImpl(fieldName, serializedEnumValue.nameOffset);
- buildDocumentation(field, serializedEnumValue.documentationComment);
- field.const3 = true;
- field.static = true;
- field.type = enumType;
- // Create a value for the constant.
- Map<String, DartObjectImpl> fieldMap = <String, DartObjectImpl>{
- fieldName: new DartObjectImpl(typeProvider.intType, new IntState(i))
- };
- DartObjectImpl value =
- new DartObjectImpl(enumType, new GenericState(fieldMap));
- constantValues.add(value);
- field.evaluationResult = new EvaluationResultImpl(value);
- // Add the field.
- memberHolder.addField(field);
- buildImplicitAccessors(field, memberHolder);
- }
- // Build the value of the 'values' field.
- valuesField.evaluationResult = new EvaluationResultImpl(
- new DartObjectImpl(valuesField.type, new ListState(constantValues)));
- // done
- classElement.fields = memberHolder.fields;
- classElement.accessors = memberHolder.accessors;
- classElement.constructors = <ConstructorElement>[];
- unitHolder.addEnum(classElement);
- }
-
- /**
- * Resynthesize an [ExecutableElement] and place it in the given [holder].
- */
- void buildExecutable(
- UnlinkedExecutable serializedExecutable, ElementImpl enclosingElement,
- [ElementHolder holder]) {
- bool isTopLevel = holder == null;
- if (holder == null) {
- holder = unitHolder;
- }
- UnlinkedExecutableKind kind = serializedExecutable.kind;
- String name = serializedExecutable.name;
- if (kind == UnlinkedExecutableKind.setter) {
- assert(name.endsWith('='));
- name = name.substring(0, name.length - 1);
- }
- switch (kind) {
- case UnlinkedExecutableKind.functionOrMethod:
- if (isTopLevel) {
- // Created lazily.
- } else {
- MethodElementImpl executableElement =
- new MethodElementImpl.forSerialized(
- serializedExecutable, enclosingElement);
- buildExecutableCommonParts(executableElement, serializedExecutable);
- holder.addMethod(executableElement);
- }
- break;
- case UnlinkedExecutableKind.getter:
- case UnlinkedExecutableKind.setter:
- // Top-level accessors are created lazily.
- if (isTopLevel) {
- break;
- }
- // Class member accessors.
- PropertyAccessorElementImpl executableElement =
- new PropertyAccessorElementImpl.forSerialized(
- serializedExecutable, enclosingElement);
- buildExecutableCommonParts(executableElement, serializedExecutable);
- DartType type;
- if (kind == UnlinkedExecutableKind.getter) {
- type = executableElement.returnType;
- } else {
- type = executableElement.parameters[0].type;
- }
- holder.addAccessor(executableElement);
- FieldElementImpl field = buildImplicitField(name, type, kind, holder);
- field.static = serializedExecutable.isStatic;
- executableElement.variable = field;
- if (kind == UnlinkedExecutableKind.getter) {
- field.getter = executableElement;
- } else {
- field.setter = executableElement;
- }
- break;
- default:
- // The only other executable type is a constructor, and that is handled
- // separately (in [buildConstructor]. So this code should be
- // unreachable.
- assert(false);
- }
- }
-
- /**
- * Handle the parts of an executable element that are common to constructors,
- * functions, methods, getters, and setters.
- */
- void buildExecutableCommonParts(ExecutableElementImpl executableElement,
- UnlinkedExecutable serializedExecutable) {
- executableElement.typeParameters =
- buildTypeParameters(serializedExecutable.typeParameters);
- {
- List<UnlinkedParam> unlinkedParameters = serializedExecutable.parameters;
- int length = unlinkedParameters.length;
- if (length != 0) {
- List<ParameterElementImpl> parameters =
- new List<ParameterElementImpl>(length);
- for (int i = 0; i < length; i++) {
- parameters[i] =
- buildParameter(unlinkedParameters[i], executableElement);
- }
- executableElement.parameters = parameters;
- }
- }
- executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
- executableElement, null, getCurrentTypeArguments(skipLevels: 1), false);
- {
- List<UnlinkedExecutable> unlinkedFunctions =
- serializedExecutable.localFunctions;
- int length = unlinkedFunctions.length;
- if (length != 0) {
- List<FunctionElementImpl> localFunctions =
- new List<FunctionElementImpl>(length);
- for (int i = 0; i < length; i++) {
- localFunctions[i] =
- buildLocalFunction(unlinkedFunctions[i], executableElement);
- }
- executableElement.functions = localFunctions;
- }
- }
- {
- List<UnlinkedLabel> unlinkedLabels = serializedExecutable.localLabels;
- int length = unlinkedLabels.length;
- if (length != 0) {
- List<LabelElementImpl> localLabels = new List<LabelElementImpl>(length);
- for (int i = 0; i < length; i++) {
- localLabels[i] = buildLocalLabel(unlinkedLabels[i]);
- }
- executableElement.labels = localLabels;
- }
- }
- {
- List<UnlinkedVariable> unlinkedVariables =
- serializedExecutable.localVariables;
- int length = unlinkedVariables.length;
- if (length != 0) {
- List<LocalVariableElementImpl> localVariables =
- new List<LocalVariableElementImpl>(length);
- for (int i = 0; i < length; i++) {
- localVariables[i] =
- buildLocalVariable(unlinkedVariables[i], executableElement);
- }
- executableElement.localVariables = localVariables;
- }
- }
- currentTypeParameters.removeLast();
- }
-
- /**
- * Build the implicit getter and setter associated with [element], and place
- * them in [holder].
- */
- void buildImplicitAccessors(
- PropertyInducingElementImpl element, ElementHolder holder) {
- String name = element.name;
- DartType type = element.type;
- PropertyAccessorElementImpl getter =
- buildImplicitGetter(element, name, type);
- holder?.addAccessor(getter);
- if (!(element.isConst || element.isFinal)) {
- PropertyAccessorElementImpl setter =
- buildImplicitSetter(element, name, type);
- holder?.addAccessor(setter);
- }
- }
-
- /**
- * Build the implicit field associated with a getter or setter, and place it
- * in [holder].
- */
- FieldElementImpl buildImplicitField(String name, DartType type,
- UnlinkedExecutableKind kind, ElementHolder holder) {
- FieldElementImpl field = holder.getField(name);
- if (field == null) {
- field = new FieldElementImpl(name, -1);
- field.synthetic = true;
- field.final2 = kind == UnlinkedExecutableKind.getter;
- field.type = type;
- holder.addField(field);
- return field;
- } else {
- // TODO(paulberry): what if the getter and setter have a type mismatch?
- field.final2 = false;
- return field;
- }
- }
-
- /**
* Build an implicit getter for the given [property] and bind it to the
* [property] and to its enclosing element.
*/
PropertyAccessorElementImpl buildImplicitGetter(
- PropertyInducingElementImpl property, String name, DartType type) {
- PropertyAccessorElementImpl getter =
- new PropertyAccessorElementImpl(name, property.nameOffset);
+ PropertyInducingElementImpl property) {
+ PropertyAccessorElementImpl_ImplicitGetter getter =
+ new PropertyAccessorElementImpl_ImplicitGetter(property);
getter.enclosingElement = property.enclosingElement;
- getter.getter = true;
- getter.static = property.isStatic;
- getter.synthetic = true;
- getter.returnType = type;
- getter.type = new FunctionTypeImpl(getter);
- getter.variable = property;
- getter.hasImplicitReturnType = property.hasImplicitType;
- property.getter = getter;
return getter;
}
@@ -2214,23 +1516,10 @@
* [property] and to its enclosing element.
*/
PropertyAccessorElementImpl buildImplicitSetter(
- PropertyInducingElementImpl property, String name, DartType type) {
- PropertyAccessorElementImpl setter =
- new PropertyAccessorElementImpl(name, property.nameOffset);
+ PropertyInducingElementImpl property) {
+ PropertyAccessorElementImpl_ImplicitSetter setter =
+ new PropertyAccessorElementImpl_ImplicitSetter(property);
setter.enclosingElement = property.enclosingElement;
- setter.setter = true;
- setter.static = property.isStatic;
- setter.synthetic = true;
- setter.parameters = <ParameterElement>[
- new ParameterElementImpl('_$name', property.nameOffset)
- ..synthetic = true
- ..type = type
- ..parameterKind = ParameterKind.REQUIRED
- ];
- setter.returnType = VoidTypeImpl.instance;
- setter.type = new FunctionTypeImpl(setter);
- setter.variable = property;
- property.setter = setter;
return setter;
}
@@ -2254,137 +1543,6 @@
}
/**
- * Resynthesize a local [FunctionElement].
- */
- FunctionElementImpl buildLocalFunction(
- UnlinkedExecutable serializedExecutable, ElementImpl enclosingElement) {
- FunctionElementImpl element = new FunctionElementImpl.forSerialized(
- serializedExecutable, enclosingElement);
- if (serializedExecutable.visibleOffset != 0) {
- element.setVisibleRange(serializedExecutable.visibleOffset,
- serializedExecutable.visibleLength);
- }
- buildExecutableCommonParts(element, serializedExecutable);
- return element;
- }
-
- /**
- * Resynthesize a [LabelElement].
- */
- LabelElement buildLocalLabel(UnlinkedLabel serializedLabel) {
- return new LabelElementImpl(
- serializedLabel.name,
- serializedLabel.nameOffset,
- serializedLabel.isOnSwitchStatement,
- serializedLabel.isOnSwitchMember);
- }
-
- /**
- * Resynthesize a [LocalVariableElement].
- */
- LocalVariableElement buildLocalVariable(UnlinkedVariable serializedVariable,
- ExecutableElementImpl enclosingExecutable) {
- LocalVariableElementImpl element;
- if (serializedVariable.initializer?.bodyExpr != null &&
- serializedVariable.isConst) {
- ConstLocalVariableElementImpl constElement =
- new ConstLocalVariableElementImpl.forSerialized(
- serializedVariable, enclosingExecutable);
- element = constElement;
- constElement.constantInitializer = _buildConstExpression(
- enclosingExecutable, serializedVariable.initializer.bodyExpr);
- } else {
- element = new LocalVariableElementImpl.forSerialized(
- serializedVariable, enclosingExecutable);
- }
- if (serializedVariable.visibleOffset != 0) {
- element.setVisibleRange(
- serializedVariable.visibleOffset, serializedVariable.visibleLength);
- }
- buildVariableCommonParts(element, serializedVariable);
- return element;
- }
-
- /**
- * Resynthesize a [ParameterElement].
- */
- ParameterElement buildParameter(
- UnlinkedParam serializedParameter, ElementImpl enclosingElement,
- {bool synthetic: false}) {
- ParameterElementImpl parameterElement;
- if (serializedParameter.isInitializingFormal) {
- if (serializedParameter.kind == UnlinkedParamKind.required) {
- parameterElement = new FieldFormalParameterElementImpl.forSerialized(
- serializedParameter, enclosingElement);
- } else {
- parameterElement =
- new DefaultFieldFormalParameterElementImpl.forSerialized(
- serializedParameter, enclosingElement);
- }
- } else {
- if (serializedParameter.kind == UnlinkedParamKind.required) {
- parameterElement = new ParameterElementImpl.forSerialized(
- serializedParameter, enclosingElement);
- } else {
- parameterElement = new DefaultParameterElementImpl.forSerialized(
- serializedParameter, enclosingElement);
- }
- }
- parameterElement.synthetic = synthetic;
- if (serializedParameter.isFunctionTyped) {
- FunctionElementImpl parameterTypeElement =
- new FunctionElementImpl_forFunctionTypedParameter(
- unit, parameterElement);
- if (!synthetic) {
- parameterTypeElement.enclosingElement = parameterElement;
- }
- List<ParameterElement> subParameters = serializedParameter.parameters
- .map((UnlinkedParam p) =>
- buildParameter(p, parameterTypeElement, synthetic: synthetic))
- .toList();
- if (synthetic) {
- parameterTypeElement.parameters = subParameters;
- } else {
- parameterElement.parameters = subParameters;
- parameterTypeElement.shareParameters(subParameters);
- }
- parameterTypeElement.returnType =
- buildType(serializedParameter.type, _currentTypeParameterizedElement);
- parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
- parameterTypeElement, null, getCurrentTypeArguments(), false);
- parameterTypeElement.type = parameterElement.type;
- }
- buildVariableInitializer(parameterElement, serializedParameter.initializer);
- return parameterElement;
- }
-
- /**
- * Handle the parts that are common to top level variables and fields.
- */
- void buildPropertyIntroducingElementCommonParts(
- PropertyInducingElementImpl element,
- UnlinkedVariable serializedVariable) {
- buildVariableCommonParts(element, serializedVariable);
- element.propagatedType = buildLinkedType(
- serializedVariable.propagatedTypeSlot,
- _currentTypeParameterizedElement);
- }
-
- List<FunctionElementImpl> buildTopLevelFunctions() {
- List<FunctionElementImpl> functions = <FunctionElementImpl>[];
- List<UnlinkedExecutable> executables = unlinkedUnit.executables;
- for (UnlinkedExecutable unlinkedExecutable in executables) {
- if (unlinkedExecutable.kind == UnlinkedExecutableKind.functionOrMethod) {
- FunctionElementImpl function =
- new FunctionElementImpl.forSerialized(unlinkedExecutable, unit);
- buildExecutableCommonParts(function, unlinkedExecutable);
- functions.add(function);
- }
- }
- return functions;
- }
-
- /**
* Build a [DartType] object based on a [EntityRef]. This [DartType]
* may refer to elements in other libraries than the library being
* deserialized, so handles are used to avoid having to deserialize other
@@ -2404,17 +1562,8 @@
return typeParameterContext.getTypeParameterType(type.paramReference);
} else if (type.syntheticReturnType != null) {
FunctionElementImpl element =
- new FunctionElementImpl_forLUB(unit, typeParameterContext);
- element.parameters = type.syntheticParams
- .map((UnlinkedParam param) =>
- buildParameter(param, element, synthetic: true))
- .toList();
- element.returnType =
- buildType(type.syntheticReturnType, typeParameterContext);
- FunctionTypeImpl result = new FunctionTypeImpl.elementWithNameAndArgs(
- element, null, null, false);
- element.type = result;
- return result;
+ new FunctionElementImpl_forLUB(unit, typeParameterContext, type);
+ return element.type;
} else {
DartType getTypeArgument(int i) {
if (i < type.typeArguments.length) {
@@ -2432,72 +1581,6 @@
}
}
- /**
- * Resynthesize a [FunctionTypeAliasElement] and place it in the
- * [unitHolder].
- */
- void buildTypedef(UnlinkedTypedef serializedTypedef) {
- FunctionTypeAliasElementImpl functionTypeAliasElement =
- new FunctionTypeAliasElementImpl.forSerialized(serializedTypedef, unit);
- // TODO(scheglov) remove this after delaying parameters and their types
- currentTypeParameters.add(functionTypeAliasElement.typeParameters);
- functionTypeAliasElement.parameters = serializedTypedef.parameters
- .map((p) => buildParameter(p, functionTypeAliasElement))
- .toList();
- functionTypeAliasElement.type =
- new FunctionTypeImpl.forTypedef(functionTypeAliasElement);
- unitHolder.addTypeAlias(functionTypeAliasElement);
- // TODO(scheglov) remove this after delaying parameters and their types
- currentTypeParameters.removeLast();
- assert(currentTypeParameters.isEmpty);
- }
-
- /**
- * Resynthesize a [TypeParameterElement], handling all parts of its except
- * its bound.
- *
- * The bound is deferred until later since it may refer to other type
- * parameters that have not been resynthesized yet. To handle the bound,
- * call [finishTypeParameter].
- */
- TypeParameterElement buildTypeParameter(
- UnlinkedTypeParam serializedTypeParameter) {
- TypeParameterElementImpl typeParameterElement =
- new TypeParameterElementImpl(
- serializedTypeParameter.name, serializedTypeParameter.nameOffset);
- typeParameterElement.type = new TypeParameterTypeImpl(typeParameterElement);
- buildAnnotations(typeParameterElement, serializedTypeParameter.annotations);
- buildCodeRange(typeParameterElement, serializedTypeParameter.codeRange);
- return typeParameterElement;
- }
-
- /**
- * Build [TypeParameterElement]s corresponding to the type parameters in
- * [serializedTypeParameters] and store them in [currentTypeParameters].
- * Also return them.
- */
- List<TypeParameterElement> buildTypeParameters(
- List<UnlinkedTypeParam> serializedTypeParameters) {
- int length = serializedTypeParameters.length;
- if (length != 0) {
- List<TypeParameterElement> typeParameters =
- new List<TypeParameterElement>(length);
- for (int i = 0; i < length; i++) {
- typeParameters[i] = buildTypeParameter(serializedTypeParameters[i]);
- }
- currentTypeParameters.add(typeParameters);
- for (int i = 0; i < length; i++) {
- finishTypeParameter(serializedTypeParameters[i], typeParameters[i]);
- }
- return typeParameters;
- } else {
- List<TypeParameterElement> typeParameters =
- const <TypeParameterElement>[];
- currentTypeParameters.add(typeParameters);
- return typeParameters;
- }
- }
-
UnitExplicitTopLevelAccessors buildUnitExplicitTopLevelAccessors() {
HashMap<String, TopLevelVariableElementImpl> implicitVariables =
new HashMap<String, TopLevelVariableElementImpl>();
@@ -2518,7 +1601,6 @@
new PropertyAccessorElementImpl.forSerialized(
unlinkedExecutable, unit);
accessorsData.accessors.add(accessor);
- buildExecutableCommonParts(accessor, unlinkedExecutable);
// implicit variable
TopLevelVariableElementImpl variable = implicitVariables[name];
if (variable == null) {
@@ -2553,120 +1635,23 @@
TopLevelVariableElementImpl element;
if (unlinkedVariable.initializer?.bodyExpr != null &&
unlinkedVariable.isConst) {
- ConstTopLevelVariableElementImpl constElement =
- new ConstTopLevelVariableElementImpl.forSerialized(
- unlinkedVariable, unit);
- element = constElement;
- constElement.constantInitializer =
- _buildConstExpression(null, unlinkedVariable.initializer.bodyExpr);
+ element = new ConstTopLevelVariableElementImpl.forSerialized(
+ unlinkedVariable, unit);
} else {
element = new TopLevelVariableElementImpl.forSerialized(
unlinkedVariable, unit);
}
- buildPropertyIntroducingElementCommonParts(element, unlinkedVariable);
variablesData.variables[i] = element;
// implicit accessors
- String name = element.name;
- DartType type = element.type;
- variablesData.implicitAccessors
- .add(buildImplicitGetter(element, name, type));
+ variablesData.implicitAccessors.add(buildImplicitGetter(element));
if (!(element.isConst || element.isFinal)) {
- variablesData.implicitAccessors
- .add(buildImplicitSetter(element, name, type));
+ variablesData.implicitAccessors.add(buildImplicitSetter(element));
}
}
return variablesData;
}
/**
- * Resynthesize a [TopLevelVariableElement] or [FieldElement].
- */
- void buildVariable(
- ClassElementImpl enclosingClass, UnlinkedVariable serializedVariable,
- [ElementHolder holder]) {
- if (holder == null) {
- throw new UnimplementedError('Must be lazy');
- } else {
- FieldElementImpl element;
- if (serializedVariable.initializer?.bodyExpr != null &&
- (serializedVariable.isConst ||
- serializedVariable.isFinal && !serializedVariable.isStatic)) {
- ConstFieldElementImpl constElement =
- new ConstFieldElementImpl.forSerialized(
- serializedVariable, enclosingClass);
- element = constElement;
- constElement.constantInitializer = _buildConstExpression(
- enclosingClass, serializedVariable.initializer.bodyExpr);
- } else {
- element = new FieldElementImpl.forSerialized(
- serializedVariable, enclosingClass);
- }
- buildPropertyIntroducingElementCommonParts(element, serializedVariable);
- element.static = serializedVariable.isStatic;
- holder.addField(element);
- buildImplicitAccessors(element, holder);
- fields[element.name] = element;
- }
- }
-
- /**
- * Handle the parts that are common to variables.
- */
- void buildVariableCommonParts(
- VariableElementImpl element, UnlinkedVariable serializedVariable) {
- element.type = buildLinkedType(serializedVariable.inferredTypeSlot,
- element.typeParameterContext) ??
- buildType(serializedVariable.type, element.typeParameterContext);
- buildVariableInitializer(element, serializedVariable.initializer);
- }
-
- /**
- * If the given [serializedInitializer] is not `null`, create the
- * corresponding [FunctionElementImpl] and set it for the [variable].
- */
- void buildVariableInitializer(
- VariableElementImpl variable, UnlinkedExecutable serializedInitializer) {
- if (serializedInitializer == null) {
- return null;
- }
- FunctionElementImpl initializerElement =
- buildLocalFunction(serializedInitializer, variable);
- initializerElement.synthetic = true;
- variable.initializer = initializerElement;
- }
-
- /**
- * Finish creating a [TypeParameterElement] by deserializing its bound.
- */
- void finishTypeParameter(UnlinkedTypeParam serializedTypeParameter,
- TypeParameterElementImpl typeParameterElement) {
- if (serializedTypeParameter.bound != null) {
- typeParameterElement.bound = buildType(
- serializedTypeParameter.bound, _currentTypeParameterizedElement,
- instantiateToBoundsAllowed: false);
- }
- }
-
- /**
- * Return a list of type arguments corresponding to [currentTypeParameters],
- * skipping the innermost [skipLevels] nesting levels.
- *
- * Type parameters are listed in nesting order from innermost to outermost,
- * and then in declaration order. So for instance if we are resynthesizing a
- * method declared as `class C<T, U> { void m<V, W>() { ... } }`, then the
- * type parameters will be returned in the order `[V, W, T, U]`.
- */
- List<DartType> getCurrentTypeArguments({int skipLevels: 0}) {
- assert(currentTypeParameters.length >= skipLevels);
- List<DartType> result = <DartType>[];
- for (int i = currentTypeParameters.length - 1 - skipLevels; i >= 0; i--) {
- result.addAll(currentTypeParameters[i]
- .map((TypeParameterElement param) => param.type));
- }
- return result;
- }
-
- /**
* Return [_ReferenceInfo] with the given [index], lazily resolving it.
*/
_ReferenceInfo getReferenceInfo(int index) {
@@ -2782,72 +1767,6 @@
return result;
}
- /**
- * Get the type parameter from the surrounding scope whose De Bruijn index is
- * [index].
- */
- DartType getTypeParameterFromScope(int index) {
- for (int i = currentTypeParameters.length - 1; i >= 0; i--) {
- List<TypeParameterElement> paramsAtThisNestingLevel =
- currentTypeParameters[i];
- int numParamsAtThisNestingLevel = paramsAtThisNestingLevel.length;
- if (index <= numParamsAtThisNestingLevel) {
- return paramsAtThisNestingLevel[numParamsAtThisNestingLevel - index]
- .type;
- }
- index -= numParamsAtThisNestingLevel;
- }
- throw new StateError('Type parameter not found');
- }
-
- /**
- * Populate a [CompilationUnitElement] by deserializing all the elements
- * contained in it.
- */
- void populateUnit() {
- unlinkedUnit.classes.forEach(buildClass);
- unlinkedUnit.enums.forEach(buildEnum);
- unlinkedUnit.typedefs.forEach(buildTypedef);
- unit.enums = unitHolder.enums;
- List<FunctionTypeAliasElement> typeAliases = unitHolder.typeAliases;
- for (FunctionTypeAliasElementImpl typeAlias in typeAliases) {
- if (typeAlias.isSynthetic) {
- typeAlias.enclosingElement = unit;
- }
- }
- unit.typeAliases = typeAliases.where((e) => !e.isSynthetic).toList();
- unit.types = unitHolder.types;
- assert(currentTypeParameters.isEmpty);
- }
-
- /**
- * Constructor initializers can reference fields and other constructors of
- * the same class, including forward references. So, we need to delay
- * resolution until after class elements are built.
- */
- void resolveConstructorInitializers(ClassElementImpl classElement) {
- for (ConstructorElementImpl constructor in constructors.values) {
- for (ConstructorInitializer initializer
- in constructor.constantInitializers) {
- if (initializer is ConstructorFieldInitializer) {
- SimpleIdentifier nameNode = initializer.fieldName;
- nameNode.staticElement = fields[nameNode.name];
- } else if (initializer is SuperConstructorInvocation) {
- SimpleIdentifier nameNode = initializer.constructorName;
- ConstructorElement element = new _DeferredConstructorElement(
- classElement.supertype, nameNode?.name ?? '');
- initializer.staticElement = element;
- nameNode?.staticElement = element;
- } else if (initializer is RedirectingConstructorInvocation) {
- SimpleIdentifier nameNode = initializer.constructorName;
- ConstructorElement element = constructors[nameNode?.name ?? ''];
- initializer.staticElement = element;
- nameNode?.staticElement = element;
- }
- }
- }
- }
-
Expression _buildConstExpression(ElementImpl context, UnlinkedConst uc) {
return new _ConstExprBuilder(this, context, uc).build();
}
@@ -2856,7 +1775,7 @@
* Return the defining type for a [ConstructorElement] by applying
* [typeArgumentRefs] to the given linked [info].
*/
- InterfaceType _createConstructorDefiningType(
+ DartType _createConstructorDefiningType(
TypeParameterizedElementMixin typeParameterContext,
_ReferenceInfo info,
List<EntityRef> typeArgumentRefs) {
@@ -2875,22 +1794,38 @@
}
/**
+ * Return the [ConstructorElement] corresponding to the given [entry].
+ */
+ ConstructorElement _getConstructorForEntry(
+ TypeParameterizedElementMixin typeParameterContext, EntityRef entry) {
+ _ReferenceInfo info = getReferenceInfo(entry.reference);
+ DartType type = _createConstructorDefiningType(
+ typeParameterContext, info, entry.typeArguments);
+ if (type is InterfaceType) {
+ return _getConstructorForInfo(type, info);
+ }
+ return null;
+ }
+
+ /**
* Return the [ConstructorElement] corresponding to the given linked [info],
* using the [classType] which has already been computed (e.g. by
* [_createConstructorDefiningType]). Both cases when [info] is a
* [ClassElement] and [ConstructorElement] are supported.
*/
- ConstructorElement _createConstructorElement(
+ ConstructorElement _getConstructorForInfo(
InterfaceType classType, _ReferenceInfo info) {
- bool isClass = info.element is ClassElement;
- String name = isClass ? '' : info.name;
- _DeferredConstructorElement element =
- new _DeferredConstructorElement(classType, name);
- if (info.numTypeParameters != 0) {
- return new ConstructorMember(element, classType);
- } else {
- return element;
+ ConstructorElement element;
+ Element infoElement = info.element;
+ if (infoElement is ConstructorElement) {
+ element = infoElement;
+ } else if (infoElement is ClassElement) {
+ element = infoElement.unnamedConstructor;
}
+ if (element != null && info.numTypeParameters != 0) {
+ return new ConstructorMember(element, classType);
+ }
+ return element;
}
/**
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 8be5f21..18db39f 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -137,11 +137,6 @@
TypeArgumentList typeArguments, SimpleIdentifier name);
/**
- * Return [EntityRefBuilder] that corresponds to the given [identifier].
- */
- EntityRefBuilder serializeIdentifier(Identifier identifier);
-
- /**
* Return a pair of ints showing how the given [functionExpression] is nested
* within the constant currently being serialized. The first int indicates
* how many levels of function nesting must be popped in order to reach the
@@ -154,6 +149,11 @@
List<int> serializeFunctionExpression(FunctionExpression functionExpression);
/**
+ * Return [EntityRefBuilder] that corresponds to the given [identifier].
+ */
+ EntityRefBuilder serializeIdentifier(Identifier identifier);
+
+ /**
* Return [EntityRefBuilder] that corresponds to the given [expr], which
* must be a sequence of identifiers.
*/
@@ -198,6 +198,34 @@
}
/**
+ * Return `true` if the given [expr] is a sequence of identifiers.
+ */
+ bool _isIdentifierSequence(Expression expr) {
+ while (expr != null) {
+ if (expr is SimpleIdentifier) {
+ AstNode parent = expr.parent;
+ if (parent is MethodInvocation && parent.methodName == expr) {
+ if (parent.isCascaded) {
+ return false;
+ }
+ return parent.target == null || _isIdentifierSequence(parent.target);
+ }
+ if (isParameterName(expr.name)) {
+ return false;
+ }
+ return true;
+ } else if (expr is PrefixedIdentifier) {
+ expr = (expr as PrefixedIdentifier).prefix;
+ } else if (expr is PropertyAccess) {
+ expr = (expr as PropertyAccess).target;
+ } else {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
* Push the operation for the given assignable [expr].
*/
void _pushAssignable(Expression expr) {
@@ -217,6 +245,11 @@
}
_serialize(expr.index);
operations.add(UnlinkedConstOperation.assignToIndex);
+ } else if (expr is PrefixedIdentifier) {
+ strings.add(expr.prefix.name);
+ operations.add(UnlinkedConstOperation.pushParameter);
+ strings.add(expr.identifier.name);
+ operations.add(UnlinkedConstOperation.assignToProperty);
} else {
throw new StateError('Unsupported assignable: $expr');
}
@@ -269,6 +302,12 @@
if (expr is SimpleIdentifier && isParameterName(expr.name)) {
strings.add(expr.name);
operations.add(UnlinkedConstOperation.pushParameter);
+ } else if (expr is PrefixedIdentifier &&
+ isParameterName(expr.prefix.name)) {
+ strings.add(expr.prefix.name);
+ operations.add(UnlinkedConstOperation.pushParameter);
+ strings.add(expr.identifier.name);
+ operations.add(UnlinkedConstOperation.extractProperty);
} else {
references.add(serializeIdentifier(expr));
operations.add(UnlinkedConstOperation.pushReference);
@@ -501,6 +540,7 @@
EntityRefBuilder ref = serializeIdentifierSequence(methodName);
_serializeArguments(argumentList);
references.add(ref);
+ _serializeTypeArguments(invocation.typeArguments);
operations.add(UnlinkedConstOperation.invokeMethodRef);
} else {
if (!invocation.isCascaded) {
@@ -508,6 +548,7 @@
}
_serializeArguments(argumentList);
strings.add(methodName.name);
+ _serializeTypeArguments(invocation.typeArguments);
operations.add(UnlinkedConstOperation.invokeMethod);
}
}
@@ -596,28 +637,14 @@
}
}
- /**
- * Return `true` if the given [expr] is a sequence of identifiers.
- */
- static bool _isIdentifierSequence(Expression expr) {
- while (expr != null) {
- if (expr is SimpleIdentifier) {
- AstNode parent = expr.parent;
- if (parent is MethodInvocation && parent.methodName == expr) {
- if (parent.isCascaded) {
- return false;
- }
- return parent.target == null || _isIdentifierSequence(parent.target);
- }
- return true;
- } else if (expr is PrefixedIdentifier) {
- expr = (expr as PrefixedIdentifier).prefix;
- } else if (expr is PropertyAccess) {
- expr = (expr as PropertyAccess).target;
- } else {
- return false;
+ void _serializeTypeArguments(TypeArgumentList typeArguments) {
+ if (typeArguments == null) {
+ ints.add(0);
+ } else {
+ ints.add(typeArguments.arguments.length);
+ for (TypeName typeName in typeArguments.arguments) {
+ references.add(serializeTypeName(typeName));
}
}
- return false;
}
}
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index ec9c988..987a187 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -8,33 +8,27 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/context/cache.dart' show CacheEntry;
import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart'
- show DartUriResolver, Source, SourceFactory, SourceKind;
+ show DartUriResolver, Source, SourceFactory;
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary/resynthesize.dart';
import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/model.dart'
- show AnalysisTarget, ResultDescriptor, TargetedResult;
+import 'package:analyzer/task/model.dart' show ResultDescriptor, TargetedResult;
-class SdkSummaryResultProvider implements SummaryResultProvider {
- final InternalAnalysisContext context;
- final PackageBundle bundle;
+class SdkSummaryResultProvider extends ResynthesizerResultProvider {
final SummaryTypeProvider typeProvider = new SummaryTypeProvider();
- @override
- SummaryResynthesizer resynthesizer;
-
- SdkSummaryResultProvider(this.context, this.bundle, bool strongMode) {
- resynthesizer = new SdkSummaryResynthesizer(
- context, typeProvider, context.sourceFactory, bundle, strongMode);
+ SdkSummaryResultProvider(
+ InternalAnalysisContext context, PackageBundle bundle, bool strongMode)
+ : super(context, new SummaryDataStore(const <String>[])) {
+ addBundle(null, bundle);
+ createResynthesizer(null, typeProvider);
_buildCoreLibrary();
_buildAsyncLibrary();
resynthesizer.finalizeCoreAsyncLibraries();
@@ -47,87 +41,12 @@
entry.setValue(result, typeProvider, TargetedResult.EMPTY_LIST);
return true;
}
- AnalysisTarget target = entry.target;
- // Only SDK sources after this point.
- if (target.source == null || !target.source.isInSystemLibrary) {
- return false;
- }
- // Constant expressions are always resolved in summaries.
- if (result == CONSTANT_EXPRESSION_RESOLVED &&
- target is ConstantEvaluationTarget) {
- entry.setValue(result, true, TargetedResult.EMPTY_LIST);
- return true;
- }
- if (target is Source) {
- if (result == LIBRARY_ELEMENT1 ||
- result == LIBRARY_ELEMENT2 ||
- result == LIBRARY_ELEMENT3 ||
- result == LIBRARY_ELEMENT4 ||
- result == LIBRARY_ELEMENT5 ||
- 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"
- String uri = target.uri.toString();
- LibraryElement libraryElement = resynthesizer.getLibraryElement(uri);
- entry.setValue(result, libraryElement, TargetedResult.EMPTY_LIST);
- return true;
- } else if (result == READY_LIBRARY_ELEMENT2 ||
- result == READY_LIBRARY_ELEMENT6 ||
- result == READY_LIBRARY_ELEMENT7) {
- entry.setValue(result, true, TargetedResult.EMPTY_LIST);
- return true;
- } else if (result == SOURCE_KIND) {
- String uri = target.uri.toString();
- SourceKind kind = _getSourceKind(uri);
- if (kind != null) {
- entry.setValue(result, kind, TargetedResult.EMPTY_LIST);
- return true;
- }
- return false;
- } else {
-// throw new UnimplementedError('$result of $target');
- }
- }
- if (target is LibrarySpecificUnit) {
- if (target.library == null || !target.library.isInSystemLibrary) {
- return false;
- }
- if (result == CREATED_RESOLVED_UNIT1 ||
- result == CREATED_RESOLVED_UNIT2 ||
- result == CREATED_RESOLVED_UNIT3 ||
- result == CREATED_RESOLVED_UNIT4 ||
- result == CREATED_RESOLVED_UNIT5 ||
- result == CREATED_RESOLVED_UNIT6 ||
- result == CREATED_RESOLVED_UNIT7 ||
- result == CREATED_RESOLVED_UNIT8 ||
- result == CREATED_RESOLVED_UNIT9 ||
- result == CREATED_RESOLVED_UNIT10 ||
- result == CREATED_RESOLVED_UNIT11 ||
- result == CREATED_RESOLVED_UNIT12) {
- entry.setValue(result, true, TargetedResult.EMPTY_LIST);
- return true;
- }
- if (result == COMPILATION_UNIT_ELEMENT) {
- String libraryUri = target.library.uri.toString();
- String unitUri = target.unit.uri.toString();
- CompilationUnitElement unit = resynthesizer.getElement(
- new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
- if (unit != null) {
- entry.setValue(result, unit, TargetedResult.EMPTY_LIST);
- return true;
- }
- }
- } else if (target is VariableElement) {
- if (result == PROPAGATED_VARIABLE || result == INFERRED_STATIC_VARIABLE) {
- entry.setValue(result, target, TargetedResult.EMPTY_LIST);
- return true;
- }
- }
- return false;
+ return super.compute(entry, result);
+ }
+
+ @override
+ bool hasResultsForSource(Source source) {
+ return source.source != null && source.isInSystemLibrary;
}
void _buildAsyncLibrary() {
@@ -139,19 +58,6 @@
LibraryElement library = resynthesizer.getLibraryElement('dart:core');
typeProvider.initializeCore(library);
}
-
- /**
- * Return the [SourceKind] of the given [uri] or `null` if it is unknown.
- */
- SourceKind _getSourceKind(String uri) {
- if (bundle.linkedLibraryUris.contains(uri)) {
- return SourceKind.LIBRARY;
- }
- if (bundle.unlinkedUnitUris.contains(uri)) {
- return SourceKind.PART;
- }
- return null;
- }
}
/**
@@ -266,22 +172,12 @@
}
/**
- * Provider for analysis results.
- */
-abstract class SummaryResultProvider extends ResultProvider {
- /**
- * The [SummaryResynthesizer] of this context, maybe `null`.
- */
- SummaryResynthesizer get resynthesizer;
-}
-
-/**
* Implementation of [TypeProvider] which can be initialized separately with
* `dart:core` and `dart:async` libraries.
*/
class SummaryTypeProvider implements TypeProvider {
- bool _isCoreInitialized = false;
- bool _isAsyncInitialized = false;
+ LibraryElement _coreLibrary;
+ LibraryElement _asyncLibrary;
InterfaceType _boolType;
InterfaceType _deprecatedType;
@@ -308,7 +204,8 @@
@override
InterfaceType get boolType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _boolType ??= _getType(_coreLibrary, "bool");
return _boolType;
}
@@ -317,13 +214,15 @@
@override
InterfaceType get deprecatedType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _deprecatedType ??= _getType(_coreLibrary, "Deprecated");
return _deprecatedType;
}
@override
InterfaceType get doubleType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _doubleType ??= _getType(_coreLibrary, "double");
return _doubleType;
}
@@ -332,55 +231,64 @@
@override
InterfaceType get functionType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _functionType ??= _getType(_coreLibrary, "Function");
return _functionType;
}
@override
InterfaceType get futureDynamicType {
- assert(_isAsyncInitialized);
+ assert(_asyncLibrary != null);
+ _futureDynamicType ??= futureType.instantiate(<DartType>[dynamicType]);
return _futureDynamicType;
}
@override
InterfaceType get futureNullType {
- assert(_isAsyncInitialized);
+ assert(_asyncLibrary != null);
+ _futureNullType ??= futureType.instantiate(<DartType>[nullType]);
return _futureNullType;
}
@override
InterfaceType get futureType {
- assert(_isAsyncInitialized);
+ assert(_asyncLibrary != null);
+ _futureType ??= _getType(_asyncLibrary, "Future");
return _futureType;
}
@override
InterfaceType get intType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _intType ??= _getType(_coreLibrary, "int");
return _intType;
}
@override
InterfaceType get iterableDynamicType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _iterableDynamicType ??= iterableType.instantiate(<DartType>[dynamicType]);
return _iterableDynamicType;
}
@override
InterfaceType get iterableType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _iterableType ??= _getType(_coreLibrary, "Iterable");
return _iterableType;
}
@override
InterfaceType get listType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _listType ??= _getType(_coreLibrary, "List");
return _listType;
}
@override
InterfaceType get mapType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _mapType ??= _getType(_coreLibrary, "Map");
return _mapType;
}
@@ -404,55 +312,64 @@
@override
InterfaceType get nullType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _nullType ??= _getType(_coreLibrary, "Null");
return _nullType;
}
@override
InterfaceType get numType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _numType ??= _getType(_coreLibrary, "num");
return _numType;
}
@override
InterfaceType get objectType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _objectType ??= _getType(_coreLibrary, "Object");
return _objectType;
}
@override
InterfaceType get stackTraceType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _stackTraceType ??= _getType(_coreLibrary, "StackTrace");
return _stackTraceType;
}
@override
InterfaceType get streamDynamicType {
- assert(_isAsyncInitialized);
+ assert(_asyncLibrary != null);
+ _streamDynamicType ??= streamType.instantiate(<DartType>[dynamicType]);
return _streamDynamicType;
}
@override
InterfaceType get streamType {
- assert(_isAsyncInitialized);
+ assert(_asyncLibrary != null);
+ _streamType ??= _getType(_asyncLibrary, "Stream");
return _streamType;
}
@override
InterfaceType get stringType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _stringType ??= _getType(_coreLibrary, "String");
return _stringType;
}
@override
InterfaceType get symbolType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _symbolType ??= _getType(_coreLibrary, "Symbol");
return _symbolType;
}
@override
InterfaceType get typeType {
- assert(_isCoreInitialized);
+ assert(_coreLibrary != null);
+ _typeType ??= _getType(_coreLibrary, "Type");
return _typeType;
}
@@ -463,39 +380,18 @@
* Initialize the `dart:async` types provided by this type provider.
*/
void initializeAsync(LibraryElement library) {
- assert(_isCoreInitialized);
- assert(!_isAsyncInitialized);
- _isAsyncInitialized = true;
- _futureType = _getType(library, "Future");
- _streamType = _getType(library, "Stream");
- _futureDynamicType = _futureType.instantiate(<DartType>[dynamicType]);
- _futureNullType = _futureType.instantiate(<DartType>[_nullType]);
- _streamDynamicType = _streamType.instantiate(<DartType>[dynamicType]);
+ assert(_coreLibrary != null);
+ assert(_asyncLibrary == null);
+ _asyncLibrary = library;
}
/**
* Initialize the `dart:core` types provided by this type provider.
*/
void initializeCore(LibraryElement library) {
- assert(!_isCoreInitialized);
- assert(!_isAsyncInitialized);
- _isCoreInitialized = true;
- _boolType = _getType(library, "bool");
- _deprecatedType = _getType(library, "Deprecated");
- _doubleType = _getType(library, "double");
- _functionType = _getType(library, "Function");
- _intType = _getType(library, "int");
- _iterableType = _getType(library, "Iterable");
- _listType = _getType(library, "List");
- _mapType = _getType(library, "Map");
- _nullType = _getType(library, "Null");
- _numType = _getType(library, "num");
- _objectType = _getType(library, "Object");
- _stackTraceType = _getType(library, "StackTrace");
- _stringType = _getType(library, "String");
- _symbolType = _getType(library, "Symbol");
- _typeType = _getType(library, "Type");
- _iterableDynamicType = _iterableType.instantiate(<DartType>[dynamicType]);
+ assert(_coreLibrary == null);
+ assert(_asyncLibrary == null);
+ _coreLibrary = library;
}
/**
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 3d9d552..ea97f79 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -335,6 +335,12 @@
'HINT_ERRORS', AnalysisError.NO_ERRORS);
/**
+ * The ignore information for a [Source].
+ */
+final ResultDescriptor<IgnoreInfo> IGNORE_INFO =
+ new ResultDescriptor<IgnoreInfo>('IGNORE_INFO', null);
+
+/**
* A list of the [VariableElement]s whose type should be inferred that another
* inferable static variable (the target) depends on.
*
@@ -2520,8 +2526,6 @@
* of errors.
*/
class DartErrorsTask extends SourceBasedAnalysisTask {
- static final RegExp spacesRegExp = new RegExp(r'\s+');
-
/**
* The task descriptor describing this kind of task.
*/
@@ -2529,18 +2533,15 @@
createTask, buildInputs, <ResultDescriptor>[DART_ERRORS]);
/**
+ * The name of the [IGNORE_INFO_INPUT] input.
+ */
+ static const String IGNORE_INFO_INPUT = 'IGNORE_INFO_INPUT';
+
+ /**
* The name of the [LINE_INFO_INPUT] input.
*/
static const String LINE_INFO_INPUT = 'LINE_INFO_INPUT';
- /**
- * The name of the [PARSED_UNIT_INPUT] input.
- */
- static const String PARSED_UNIT_INPUT = 'PARSED_UNIT_INPUT';
-
- // Prefix for comments ignoring error codes.
- static const String _normalizedIgnorePrefix = '//ignore:';
-
DartErrorsTask(InternalAnalysisContext context, AnalysisTarget target)
: super(context, target);
@@ -2584,69 +2585,19 @@
outputs[DART_ERRORS] = errors;
}
- Token _advanceToLine(Token token, LineInfo lineInfo, int line) {
- int offset = lineInfo.getOffsetOfLine(line - 1); // 0-based
- while (token.offset < offset) {
- token = token.next;
- }
- return token;
- }
-
List<AnalysisError> _filterIgnores(List<AnalysisError> errors) {
if (errors.isEmpty) {
return errors;
}
- // Sort errors.
- errors.sort((AnalysisError e1, AnalysisError e2) => e1.offset - e2.offset);
+ IgnoreInfo ignoreInfo = getRequiredInput(IGNORE_INFO_INPUT);
+ if (!ignoreInfo.hasIgnores) {
+ return errors;
+ }
- CompilationUnit cu = getRequiredInput(PARSED_UNIT_INPUT);
- Token token = cu.beginToken;
LineInfo lineInfo = getRequiredInput(LINE_INFO_INPUT);
- bool isIgnored(AnalysisError error) {
- int errorLine = lineInfo.getLocation(error.offset).lineNumber;
- token = _advanceToLine(token, lineInfo, errorLine);
-
- //Check for leading comment.
- Token comments = token.precedingComments;
- while (comments?.next != null) {
- comments = comments.next;
- }
- if (_isIgnoredBy(error, comments)) {
- return true;
- }
-
- //Check for trailing comment.
- int lineNumber = errorLine + 1;
- if (lineNumber <= lineInfo.lineCount) {
- Token nextLine = _advanceToLine(token, lineInfo, lineNumber);
- comments = nextLine.precedingComments;
- if (comments != null && nextLine.previous.type != TokenType.EOF) {
- int commentLine = lineInfo.getLocation(comments.offset).lineNumber;
- if (commentLine == errorLine) {
- return _isIgnoredBy(error, comments);
- }
- }
- }
-
- return false;
- }
-
- return errors.where((AnalysisError e) => !isIgnored(e)).toList();
- }
-
- bool _isIgnoredBy(AnalysisError error, Token comment) {
- //Normalize first.
- String contents =
- comment?.lexeme?.toLowerCase()?.replaceAll(spacesRegExp, '');
- if (contents == null || !contents.startsWith(_normalizedIgnorePrefix)) {
- return false;
- }
- return contents
- .substring(_normalizedIgnorePrefix.length)
- .split(',')
- .contains(error.errorCode.name.toLowerCase());
+ return filterIgnored(errors, ignoreInfo, lineInfo);
}
/**
@@ -2658,7 +2609,7 @@
Source source = target;
Map<String, TaskInput> inputs = <String, TaskInput>{};
inputs[LINE_INFO_INPUT] = LINE_INFO.of(source);
- inputs[PARSED_UNIT_INPUT] = PARSED_UNIT.of(source);
+ inputs[IGNORE_INFO_INPUT] = IGNORE_INFO.of(source);
EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin;
// for Source
List<ResultDescriptor> errorsForSource = enginePlugin.dartErrorsForSource;
@@ -2691,6 +2642,27 @@
AnalysisContext context, AnalysisTarget target) {
return new DartErrorsTask(context, target);
}
+
+ /**
+ * Return a new list with items from [errors] which are not filtered out by
+ * the [ignoreInfo].
+ */
+ static List<AnalysisError> filterIgnored(
+ List<AnalysisError> errors, IgnoreInfo ignoreInfo, LineInfo lineInfo) {
+ if (errors.isEmpty || !ignoreInfo.hasIgnores) {
+ return errors;
+ }
+
+ bool isIgnored(AnalysisError error) {
+ int errorLine = lineInfo.getLocation(error.offset).lineNumber;
+ String errorCode = error.errorCode.name.toLowerCase();
+ // Ignores can be on the line or just preceding the error.
+ return ignoreInfo.ignoredAt(errorCode, errorLine) ||
+ ignoreInfo.ignoredAt(errorCode, errorLine - 1);
+ }
+
+ return errors.where((AnalysisError e) => !isIgnored(e)).toList();
+ }
}
/**
@@ -3100,6 +3072,78 @@
}
/**
+ * Information about analysis `//ignore:` comments within a source file.
+ */
+class IgnoreInfo {
+ /**
+ * Instance shared by all cases without matches.
+ */
+ static final IgnoreInfo _EMPTY_INFO = new IgnoreInfo();
+
+ /**
+ * A regular expression for matching 'ignore' comments. Produces matches
+ * containing 2 groups. For example:
+ *
+ * * ['//ignore: error_code', 'error_code']
+ *
+ * Resulting codes may be in a list ('error_code_1,error_code2').
+ */
+ static final RegExp _IGNORE_MATCHER =
+ new RegExp(r'//[ ]*ignore:(.*)$', multiLine: true);
+
+ final Map<int, List<String>> _ignoreMap = new HashMap<int, List<String>>();
+
+ /**
+ * Whether this info object defines any ignores.
+ */
+ bool get hasIgnores => ignores.isNotEmpty;
+
+ /**
+ * Map of line numbers to associated ignored error codes.
+ */
+ Map<int, Iterable<String>> get ignores => _ignoreMap;
+
+ /**
+ * Ignore this [errorCode] at [line].
+ */
+ void add(int line, String errorCode) {
+ _ignoreMap.putIfAbsent(line, () => new List<String>()).add(errorCode);
+ }
+
+ /**
+ * Ignore these [errorCodes] at [line].
+ */
+ void addAll(int line, Iterable<String> errorCodes) {
+ _ignoreMap.putIfAbsent(line, () => new List<String>()).addAll(errorCodes);
+ }
+
+ /**
+ * Test whether this [errorCode] is ignored at the given [line].
+ */
+ bool ignoredAt(String errorCode, int line) =>
+ _ignoreMap[line]?.contains(errorCode) == true;
+
+ /**
+ * Calculate ignores for the given [content] with line [info].
+ */
+ static IgnoreInfo calculateIgnores(String content, LineInfo info) {
+ Iterable<Match> matches = _IGNORE_MATCHER.allMatches(content);
+ if (matches.isEmpty) {
+ return _EMPTY_INFO;
+ }
+
+ IgnoreInfo ignoreInfo = new IgnoreInfo();
+ for (Match match in matches) {
+ // See _IGNORE_MATCHER for format --- note the possibility of error lists.
+ Iterable<String> codes =
+ match.group(1).split(',').map((String code) => code.trim());
+ ignoreInfo.addAll(info.getLocation(match.start).lineNumber, codes);
+ }
+ return ignoreInfo;
+ }
+}
+
+/**
* A task that ensures that all of the inferable instance members in a
* compilation unit have had their type inferred.
*/
@@ -5429,7 +5473,7 @@
'ScanDartTask',
createTask,
buildInputs,
- <ResultDescriptor>[LINE_INFO, SCAN_ERRORS, TOKEN_STREAM],
+ <ResultDescriptor>[IGNORE_INFO, LINE_INFO, SCAN_ERRORS, TOKEN_STREAM],
suitabilityFor: suitabilityFor);
/**
@@ -5482,8 +5526,12 @@
scanner.preserveComments = context.analysisOptions.preserveComments;
scanner.scanGenericMethodComments = context.analysisOptions.strongMode;
+ LineInfo lineInfo = new LineInfo(scanner.lineStarts);
+
outputs[TOKEN_STREAM] = scanner.tokenize();
- outputs[LINE_INFO] = new LineInfo(scanner.lineStarts);
+ outputs[LINE_INFO] = lineInfo;
+ outputs[IGNORE_INFO] =
+ IgnoreInfo.calculateIgnores(fragment.content, lineInfo);
outputs[SCAN_ERRORS] = getUniqueErrors(errorListener.errors);
} else if (target is Source) {
String content = getRequiredInput(CONTENT_INPUT_NAME);
@@ -5493,8 +5541,11 @@
scanner.preserveComments = context.analysisOptions.preserveComments;
scanner.scanGenericMethodComments = context.analysisOptions.strongMode;
+ LineInfo lineInfo = new LineInfo(scanner.lineStarts);
+
outputs[TOKEN_STREAM] = scanner.tokenize();
- outputs[LINE_INFO] = new LineInfo(scanner.lineStarts);
+ outputs[LINE_INFO] = lineInfo;
+ outputs[IGNORE_INFO] = IgnoreInfo.calculateIgnores(content, lineInfo);
outputs[SCAN_ERRORS] = getUniqueErrors(errorListener.errors);
} else {
throw new AnalysisException(
diff --git a/pkg/analyzer/lib/src/task/strong/info.dart b/pkg/analyzer/lib/src/task/strong/info.dart
index 408c05d..ec8626f 100644
--- a/pkg/analyzer/lib/src/task/strong/info.dart
+++ b/pkg/analyzer/lib/src/task/strong/info.dart
@@ -92,12 +92,6 @@
// types, but the function type is not assignable to the class
assert(toType.isSubtypeOf(fromType) || fromType.isAssignableTo(toType));
- // Handle null call specially.
- if (expression is NullLiteral) {
- // TODO(vsm): Create a NullCast for this once we revisit nonnullability.
- return new DownCastImplicit(rules, expression, fromType, toType);
- }
-
// Inference "casts":
if (expression is Literal || expression is FunctionExpression) {
// fromT should be an exact type - this will almost certainly fail at
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index 2e3d3c0..420fd61 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -27,15 +27,6 @@
if (field.initializer != null) {
(field.initializer as ExecutableElementImpl).returnType = newType;
}
- if (field is PropertyInducingElementImpl) {
- (field.getter as ExecutableElementImpl).returnType = newType;
- if (!field.isFinal && !field.isConst) {
- List<ParameterElement> setterParameters = field.setter.parameters;
- if (setterParameters.isNotEmpty) {
- (setterParameters[0] as ParameterElementImpl).type = newType;
- }
- }
- }
}
/**
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 82bd902..4c65104 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.27.4-alpha.7.1
+version: 0.27.4-alpha.10
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -7,7 +7,7 @@
sdk: '>=1.12.0 <2.0.0'
dependencies:
args: '>=0.12.1 <0.14.0'
- crypto: '>=0.9.2 <2.0.0'
+ crypto: '>=1.1.1 <3.0.0'
glob: ^1.0.3
html: ^0.12.0
package_config: ^0.1.1
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index 35ff9a9..122a93e 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -592,6 +592,13 @@
}
}
+ void test_inGetterContext_constructorFieldInitializer() {
+ ConstructorFieldInitializer initializer = AstFactory
+ .constructorFieldInitializer(false, 'f', AstFactory.integer(0));
+ SimpleIdentifier identifier = initializer.fieldName;
+ expect(identifier.inGetterContext(), isFalse);
+ }
+
void test_inGetterContext_forEachLoop() {
SimpleIdentifier identifier = AstFactory.identifier3("a");
Expression iterator = AstFactory.listLiteral();
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index c4a47ca..fcf09de 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -3916,10 +3916,10 @@
}
}
''');
- _assertNthStatementExits(source, 0);
+ _assertNthStatementDoesNotExit(source, 0);
}
- void test_switch_withEnum_true_withDefault() {
+ void test_switch_withEnum_true_withExitingDefault() {
Source source = addSource(r'''
enum E { A, B }
String f(E e) {
@@ -3934,6 +3934,22 @@
_assertNthStatementExits(source, 0);
}
+ void test_switch_withEnum_true_withNonExitingDefault() {
+ Source source = addSource(r'''
+enum E { A, B }
+String f(E e) {
+ var x;
+ switch (e) {
+ case A:
+ return 'A';
+ default:
+ x = '?';
+ }
+}
+''');
+ _assertNthStatementDoesNotExit(source, 1);
+ }
+
void test_whileStatement_breakWithLabel() {
Source source = addSource(r'''
void f() {
@@ -3962,6 +3978,42 @@
_assertNthStatementExits(source, 0);
}
+ void test_yieldStatement_plain() {
+ Source source = addSource(r'''
+void f() sync* {
+ yield 1;
+}
+''');
+ _assertNthStatementDoesNotExit(source, 0);
+ }
+
+ void test_yieldStatement_throw() {
+ Source source = addSource(r'''
+void f() sync* {
+ yield throw '';
+}
+''');
+ _assertNthStatementExits(source, 0);
+ }
+
+ void test_yieldStatement_star_plain() {
+ Source source = addSource(r'''
+void f() sync* {
+ yield* 1;
+}
+''');
+ _assertNthStatementDoesNotExit(source, 0);
+ }
+
+ void test_yieldStatement_star_throw() {
+ Source source = addSource(r'''
+void f() sync* {
+ yield* throw '';
+}
+''');
+ _assertNthStatementExits(source, 0);
+ }
+
void _assertHasReturn(bool expectedResult, Source source, int n) {
LibraryElement element = resolve2(source);
CompilationUnit unit = resolveCompilationUnit(source, element);
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index 5eb564a..da95f04 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -353,7 +353,7 @@
void test_visitEnumDeclaration() {
CompilationUnitElementImpl compilationUnitElement =
ElementFactory.compilationUnit('foo.dart');
- ClassElementImpl enumElement =
+ EnumElementImpl enumElement =
ElementFactory.enumElement(_typeProvider, ('E'));
compilationUnitElement.enums = <ClassElement>[enumElement];
EnumDeclaration enumNode = AstFactory.enumDeclaration2('E', []);
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 3975270..77b127f 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -21,33 +21,6 @@
@reflectiveTest
class HintCodeTest extends ResolverTestCase {
- void fail_deadCode_statementAfterRehrow() {
- Source source = addSource(r'''
-f() {
- try {
- var one = 1;
- } catch (e) {
- rethrow;
- var two = 2;
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
- void fail_deadCode_statementAfterThrow() {
- Source source = addSource(r'''
-f() {
- var one = 1;
- throw 'Stop here';
- var two = 2;
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.DEAD_CODE]);
- verify([source]);
- }
-
void fail_isInt() {
Source source = addSource("var v = 1 is int;");
computeLibrarySourceErrors(source);
@@ -553,6 +526,36 @@
verify([source]);
}
+ void test_deadCode_statementAfterExitingIf_returns() {
+ Source source = addSource(r'''
+f() {
+ if (1 > 2) {
+ return;
+ } else {
+ return;
+ }
+ var one = 1;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ void test_deadCode_statementAfterRethrow() {
+ Source source = addSource(r'''
+f() {
+ try {
+ var one = 1;
+ } catch (e) {
+ rethrow;
+ var two = 2;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
void test_deadCode_statementAfterReturn_function() {
Source source = addSource(r'''
f() {
@@ -619,6 +622,18 @@
verify([source]);
}
+ void test_deadCode_statementAfterThrow() {
+ Source source = addSource(r'''
+f() {
+ var one = 1;
+ throw 'Stop here';
+ var two = 2;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
void test_deprecatedAnnotationUse_assignment() {
Source source = addSource(r'''
class A {
@@ -634,6 +649,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_deprecatedAnnotationUse_Deprecated() {
Source source = addSource(r'''
class A {
@@ -658,28 +688,6 @@
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(
@@ -778,6 +786,17 @@
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_operator() {
Source source = addSource(r'''
class A {
@@ -793,6 +812,17 @@
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_setter() {
Source source = addSource(r'''
class A {
@@ -835,21 +865,6 @@
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) {
@@ -1029,6 +1044,23 @@
verify([source]);
}
+ void test_invalidUseOfProtectedMember_closure() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+class A {
+ @protected
+ int a() => 42;
+}
+void main() {
+ var leak = new A().a;
+ print(leak);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ verify([source]);
+ }
+
void test_invalidUseOfProtectedMember_field() {
Source source = addSource(r'''
import 'package:meta/meta.dart';
@@ -1036,11 +1068,26 @@
@protected
int a;
}
+abstract class B {
+ int b() => new A().a;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_field_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ int a;
+}
abstract class B implements A {
int b() => a;
}''');
computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
verify([source]);
}
@@ -1059,6 +1106,22 @@
verify([source]);
}
+ void test_invalidUseOfProtectedMember_function_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ int a() => 0;
+}
+
+abstract class B implements A {
+ int b() => a();
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_invalidUseOfProtectedMember_getter() {
Source source = addSource(r'''
import 'package:meta/meta.dart';
@@ -1066,11 +1129,27 @@
@protected
int get a => 42;
}
+class B {
+ A a;
+ int b() => a.a;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_getter_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ int get a => 42;
+}
abstract class B implements A {
int b() => a;
}''');
computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
verify([source]);
}
@@ -1105,18 +1184,26 @@
verify([source]);
}
- void test_invalidUseOfProtectedMember_method_2() {
+ void test_invalidUseOfProtectedMember_method_OK() {
+ // https://github.com/dart-lang/linter/issues/257
Source source = addSource(r'''
import 'package:meta/meta.dart';
-class A {
+
+typedef void VoidCallback();
+
+class State<E> {
@protected
- void a(){ }
+ void setState(VoidCallback fn) {}
}
-abstract class B implements A {
- void b() => a();
-}''');
+
+class Button extends State<Object> {
+ void handleSomething() {
+ setState(() {});
+ }
+}
+''');
computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
verify([source]);
}
@@ -1131,7 +1218,7 @@
void b() => a();
}''');
computeLibrarySourceErrors(source);
- assertErrors(source, []);
+ assertNoErrors(source);
verify([source]);
}
@@ -1146,7 +1233,7 @@
void b() => a();
}''');
computeLibrarySourceErrors(source);
- assertErrors(source, []);
+ assertNoErrors(source);
verify([source]);
}
@@ -1160,7 +1247,7 @@
static m2(A a) => a.m1();
}''');
computeLibrarySourceErrors(source);
- assertErrors(source, []);
+ assertNoErrors(source);
verify([source]);
}
@@ -1178,7 +1265,7 @@
new B().a();
}''');
computeLibrarySourceErrors(source);
- assertErrors(source, []);
+ assertNoErrors(source);
verify([source]);
}
@@ -1194,7 +1281,7 @@
}
''');
computeLibrarySourceErrors(source);
- assertErrors(source, []);
+ assertNoErrors(source);
verify([source]);
}
@@ -1210,7 +1297,7 @@
}
''');
computeLibrarySourceErrors(source);
- assertErrors(source, []);
+ assertNoErrors(source);
verify([source]);
}
@@ -1228,7 +1315,24 @@
}
''');
computeLibrarySourceErrors(source);
- assertErrors(source, []);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_OK_setter_2() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ int _a;
+ @protected
+ void set a(int a) { _a = a; }
+ A(int a) {
+ this.a = a;
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
verify([source]);
}
@@ -1239,13 +1343,31 @@
@protected
void set a(int i) { }
}
+class B{
+ A a;
+ b(int i) {
+ a.a = i;
+ }
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ verify([source]);
+ }
+
+ void test_invalidUseOfProtectedMember_setter_OK() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @protected
+ void set a(int i) { }
+}
abstract class B implements A {
b(int i) {
a = i;
}
}''');
computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+ assertNoErrors(source);
verify([source]);
}
@@ -1353,13 +1475,6 @@
verify([source]);
}
- void test_missingReturn_function() {
- Source source = addSource("int f() {}");
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.MISSING_RETURN]);
- verify([source]);
- }
-
void test_missingReturn_factory() {
Source source = addSource(r'''
class A {
@@ -1371,6 +1486,13 @@
verify([source]);
}
+ void test_missingReturn_function() {
+ Source source = addSource("int f() {}");
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.MISSING_RETURN]);
+ verify([source]);
+ }
+
void test_missingReturn_method() {
Source source = addSource(r'''
class A {
@@ -1781,26 +1903,24 @@
verify([source]);
}
- void test_undefinedIdentifier_importHide() {
+ void test_undefinedGetter() {
Source source = addSource(r'''
-library L;
-import 'lib1.dart' hide a;''');
- addNamedSource("/lib1.dart", "library lib1;");
+class A {}
+f(var a) {
+ if(a is A) {
+ return a.m;
+ }
+}''');
computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.UNUSED_IMPORT, HintCode.UNDEFINED_HIDDEN_NAME]);
- verify([source]);
+ assertErrors(source, [HintCode.UNDEFINED_GETTER]);
}
- void test_undefinedIdentifier_importShow() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' show a;''');
- addNamedSource("/lib1.dart", "library lib1;");
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.UNUSED_IMPORT, HintCode.UNDEFINED_SHOWN_NAME]);
- verify([source]);
+ void test_undefinedGetter_message() {
+ // The implementation of HintCode.UNDEFINED_SETTER assumes that
+ // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
+ // same, this verifies that assumption.
+ expect(StaticWarningCode.UNDEFINED_GETTER.message,
+ StaticTypeWarningCode.UNDEFINED_GETTER.message);
}
void test_undefinedIdentifier_exportHide() {
@@ -1823,24 +1943,26 @@
verify([source]);
}
- void test_undefinedGetter() {
+ void test_undefinedIdentifier_importHide() {
Source source = addSource(r'''
-class A {}
-f(var a) {
- if(a is A) {
- return a.m;
- }
-}''');
+library L;
+import 'lib1.dart' hide a;''');
+ addNamedSource("/lib1.dart", "library lib1;");
computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNDEFINED_GETTER]);
+ assertErrors(
+ source, [HintCode.UNUSED_IMPORT, HintCode.UNDEFINED_HIDDEN_NAME]);
+ verify([source]);
}
- void test_undefinedGetter_message() {
- // The implementation of HintCode.UNDEFINED_SETTER assumes that
- // UNDEFINED_SETTER in StaticTypeWarningCode and StaticWarningCode are the
- // same, this verifies that assumption.
- expect(StaticWarningCode.UNDEFINED_GETTER.message,
- StaticTypeWarningCode.UNDEFINED_GETTER.message);
+ void test_undefinedIdentifier_importShow() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart' show a;''');
+ addNamedSource("/lib1.dart", "library lib1;");
+ computeLibrarySourceErrors(source);
+ assertErrors(
+ source, [HintCode.UNUSED_IMPORT, HintCode.UNDEFINED_SHOWN_NAME]);
+ verify([source]);
}
void test_undefinedMethod() {
@@ -2886,6 +3008,30 @@
verify([source]);
}
+ void test_unusedField_notUsed_constructorFieldInitializers() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+ A() : _f = 0;
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_FIELD]);
+ verify([source]);
+ }
+
+ void test_unusedField_notUsed_fieldFormalParameter() {
+ enableUnusedElement = true;
+ Source source = addSource(r'''
+class A {
+ int _f;
+ A(this._f);
+}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_FIELD]);
+ verify([source]);
+ }
+
void test_unusedField_notUsed_noReference() {
enableUnusedElement = true;
Source source = addSource(r'''
@@ -3016,84 +3162,6 @@
verify([source, source2]);
}
- void test_unusedShownName() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' show A, B;
-A a;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_SHOWN_NAME]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedShownName_topLevelVariable() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' show var1, var2;
-import 'lib1.dart' show var3, var4;
-int a = var1;
-int b = var2;
-int c = var3;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-const int var1 = 1;
-const int var2 = 2;
-const int var3 = 3;
-const int var4 = 4;''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_SHOWN_NAME]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedShownName_as() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' as p show A, B;
-p.A a;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [HintCode.UNUSED_SHOWN_NAME]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
- void test_unusedShownName_duplicates() {
- Source source = addSource(r'''
-library L;
-import 'lib1.dart' show A, B;
-import 'lib1.dart' show C, D;
-A a;
-C c;''');
- Source source2 = addNamedSource(
- "/lib1.dart",
- r'''
-library lib1;
-class A {}
-class B {}
-class C {}
-class D {}''');
- computeLibrarySourceErrors(source);
- assertErrors(
- source, [HintCode.UNUSED_SHOWN_NAME, HintCode.UNUSED_SHOWN_NAME]);
- assertNoErrors(source2);
- verify([source, source2]);
- }
-
void test_unusedLocalVariable_inCatch_exception() {
enableUnusedLocalVariable = true;
Source source = addSource(r'''
@@ -3281,6 +3349,84 @@
verify([source]);
}
+ void test_unusedShownName() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart' show A, B;
+A a;''');
+ Source source2 = addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}
+class B {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_SHOWN_NAME]);
+ assertNoErrors(source2);
+ verify([source, source2]);
+ }
+
+ void test_unusedShownName_as() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart' as p show A, B;
+p.A a;''');
+ Source source2 = addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}
+class B {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_SHOWN_NAME]);
+ assertNoErrors(source2);
+ verify([source, source2]);
+ }
+
+ void test_unusedShownName_duplicates() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart' show A, B;
+import 'lib1.dart' show C, D;
+A a;
+C c;''');
+ Source source2 = addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+class A {}
+class B {}
+class C {}
+class D {}''');
+ computeLibrarySourceErrors(source);
+ assertErrors(
+ source, [HintCode.UNUSED_SHOWN_NAME, HintCode.UNUSED_SHOWN_NAME]);
+ assertNoErrors(source2);
+ verify([source, source2]);
+ }
+
+ void test_unusedShownName_topLevelVariable() {
+ Source source = addSource(r'''
+library L;
+import 'lib1.dart' show var1, var2;
+import 'lib1.dart' show var3, var4;
+int a = var1;
+int b = var2;
+int c = var3;''');
+ Source source2 = addNamedSource(
+ "/lib1.dart",
+ r'''
+library lib1;
+const int var1 = 1;
+const int var2 = 2;
+const int var3 = 3;
+const int var4 = 4;''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.UNUSED_SHOWN_NAME]);
+ assertNoErrors(source2);
+ verify([source, source2]);
+ }
+
void test_useOfVoidResult_assignmentExpression_function() {
Source source = addSource(r'''
void f() {}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 41a5185..1be8c5b 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -5125,6 +5125,19 @@
verify([source]);
}
+ void test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_hasBound2() {
+ Source source = addSource(r'''
+class MyClass<T> {}
+typedef MyFunction<T, P extends MyClass<T>>();
+class A<T, P extends MyClass<T>> {
+ MyFunction<T, P> f;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_noBound() {
Source source = addSource(r'''
typedef F<T>();
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index 9fc1dfb..226f5e5 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -158,6 +158,19 @@
verify([source]);
}
+ void test_deadCode_statementAfterIfWithoutElse() {
+ Source source = addSource(r'''
+f() {
+ if (1 < 0) {
+ return;
+ }
+ int a = 1;
+}''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_deprecatedMemberUse_inDeprecatedClass() {
Source source = addSource(r'''
@deprecated
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 47be73f..0e0ee77 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -6121,7 +6121,7 @@
CommentAndMetadata commentAndMetadata =
parse4("parseCommentAndMetadata", "/** 1 */ void");
expect(commentAndMetadata.comment, isNotNull);
- expect(commentAndMetadata.metadata, hasLength(0));
+ expect(commentAndMetadata.metadata, isNull);
}
void test_parseCommentAndMetadata_cmc() {
@@ -6177,7 +6177,7 @@
CommentAndMetadata commentAndMetadata =
parse4("parseCommentAndMetadata", "void");
expect(commentAndMetadata.comment, isNull);
- expect(commentAndMetadata.metadata, hasLength(0));
+ expect(commentAndMetadata.metadata, isNull);
}
void test_parseCommentAndMetadata_singleLine() {
@@ -6188,7 +6188,7 @@
/// 2
void''');
expect(commentAndMetadata.comment, isNotNull);
- expect(commentAndMetadata.metadata, hasLength(0));
+ expect(commentAndMetadata.metadata, isNull);
}
void test_parseCommentReference_new_prefixed() {
@@ -6999,7 +6999,7 @@
void test_parseConstructorFieldInitializer_qualified() {
ConstructorFieldInitializer invocation =
- parse4("parseConstructorFieldInitializer", "this.a = b");
+ parse2("parseConstructorFieldInitializer", [true], "this.a = b");
expect(invocation.equals, isNotNull);
expect(invocation.expression, isNotNull);
expect(invocation.fieldName, isNotNull);
@@ -7009,7 +7009,7 @@
void test_parseConstructorFieldInitializer_unqualified() {
ConstructorFieldInitializer invocation =
- parse4("parseConstructorFieldInitializer", "a = b");
+ parse2("parseConstructorFieldInitializer", [false], "a = b");
expect(invocation.equals, isNotNull);
expect(invocation.expression, isNotNull);
expect(invocation.fieldName, isNotNull);
@@ -9691,7 +9691,7 @@
void test_parseRedirectingConstructorInvocation_named() {
RedirectingConstructorInvocation invocation =
- parse4("parseRedirectingConstructorInvocation", "this.a()");
+ parse2("parseRedirectingConstructorInvocation", [true], "this.a()");
expect(invocation.argumentList, isNotNull);
expect(invocation.constructorName, isNotNull);
expect(invocation.thisKeyword, isNotNull);
@@ -9700,7 +9700,7 @@
void test_parseRedirectingConstructorInvocation_unnamed() {
RedirectingConstructorInvocation invocation =
- parse4("parseRedirectingConstructorInvocation", "this()");
+ parse2("parseRedirectingConstructorInvocation", [false], "this()");
expect(invocation.argumentList, isNotNull);
expect(invocation.constructorName, isNull);
expect(invocation.thisKeyword, isNotNull);
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index fd39ad5..11eee0b 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -2922,8 +2922,6 @@
ClassElementImpl element =
new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
element.supertype = superclassType;
- InterfaceTypeImpl type = new InterfaceTypeImpl(element);
- element.type = type;
if (parameterNames != null) {
int count = parameterNames.length;
if (count > 0) {
@@ -2940,7 +2938,6 @@
typeParameter.type = typeArguments[i];
}
element.typeParameters = typeParameters;
- type.typeArguments = typeArguments;
}
}
return element;
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 0e0e3a1..a8f9105 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -990,9 +990,6 @@
String constructorName = "m";
ConstructorElementImpl constructor =
ElementFactory.constructorElement2(classElement, constructorName);
- constructor.returnType = classElement.type;
- FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
- constructor.type = constructorType;
classElement.constructors = <ConstructorElement>[constructor];
InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
null,
@@ -1010,9 +1007,6 @@
ConstructorElementImpl constructor =
ElementFactory.constructorElement2(elementC, null);
elementC.constructors = <ConstructorElement>[constructor];
- constructor.returnType = elementC.type;
- FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
- constructor.type = constructorType;
TypeName typeName =
AstFactory.typeName(elementC, [AstFactory.typeName(elementI)]);
typeName.type = elementC.type.instantiate(<DartType>[elementI.type]);
@@ -1031,9 +1025,6 @@
ClassElementImpl classElement = ElementFactory.classElement2("C");
ConstructorElementImpl constructor =
ElementFactory.constructorElement2(classElement, null);
- constructor.returnType = classElement.type;
- FunctionTypeImpl constructorType = new FunctionTypeImpl(constructor);
- constructor.type = constructorType;
classElement.constructors = <ConstructorElement>[constructor];
InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
null, AstFactory.typeName(classElement));
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 381313e..241e3af 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1381,7 +1381,7 @@
[StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
}
- void test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias() {
+ void fail_typeArgumentNotMatchingBounds_ofFunctionTypeAlias() {
assertErrorsInCode(
r'''
class A {}
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index e169167..277f8bb 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -1795,10 +1795,12 @@
errors.sort((AnalysisError e1, AnalysisError e2) =>
e1.errorCode.name.compareTo(e2.errorCode.name));
- expect(errors.map((e) => e.errorCode.name), [
- 'INVALID_METHOD_OVERRIDE_RETURN_TYPE',
- 'STRONG_MODE_INVALID_METHOD_OVERRIDE'
- ]);
+ expect(
+ errors.map((e) => e.errorCode.name),
+ unorderedEquals([
+ 'INVALID_METHOD_OVERRIDE_RETURN_TYPE',
+ 'STRONG_MODE_INVALID_METHOD_OVERRIDE'
+ ]));
expect(errors[0].message, contains('Iterable<S>'),
reason: 'errors should be in terms of the type parameters '
'at the error location');
@@ -1818,11 +1820,12 @@
// TODO(jmesserly): this is modified code from assertErrors, which we can't
// use directly because STRONG_MODE_* errors don't have working equality.
List<AnalysisError> errors = analysisContext2.computeErrors(source);
- List errorNames = errors.map((e) => e.errorCode.name).toList();
- expect(errorNames, hasLength(2));
- expect(errorNames, contains('STRONG_MODE_INVALID_METHOD_OVERRIDE'));
expect(
- errorNames, contains('INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND'));
+ errors.map((e) => e.errorCode.name),
+ unorderedEquals([
+ 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND',
+ 'STRONG_MODE_INVALID_METHOD_OVERRIDE'
+ ]));
verify([source]);
}
@@ -1837,10 +1840,12 @@
// TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
// from CodeChecker don't have working equality.
List<AnalysisError> errors = analysisContext2.computeErrors(source);
- expect(errors.map((e) => e.errorCode.name), [
- 'STRONG_MODE_INVALID_METHOD_OVERRIDE',
- 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS'
- ]);
+ expect(
+ errors.map((e) => e.errorCode.name),
+ unorderedEquals([
+ 'STRONG_MODE_INVALID_METHOD_OVERRIDE',
+ 'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS'
+ ]));
verify([source]);
}
diff --git a/pkg/analyzer/test/src/context/context_factory_test.dart b/pkg/analyzer/test/src/context/context_factory_test.dart
new file mode 100644
index 0000000..a116d29
--- /dev/null
+++ b/pkg/analyzer/test/src/context/context_factory_test.dart
@@ -0,0 +1,159 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.src.context.context_factory_test;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/context/context_factory.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+
+main() {
+ initializeTestEnvironment();
+ runReflectiveTests(PackageMapProcessorTest);
+}
+
+@reflectiveTest
+class PackageMapProcessorTest {
+ MemoryResourceProvider resourceProvider;
+
+ Folder empty;
+ Folder tmp_sdk_ext;
+ Folder tmp_embedder;
+ Map<String, List<Folder>> packageMap;
+
+ void setUp() {
+ resourceProvider = new MemoryResourceProvider();
+ empty = resourceProvider.newFolder('/empty');
+ tmp_sdk_ext = resourceProvider.newFolder('/tmp_sdk_ext');
+ tmp_embedder = resourceProvider.newFolder('/tmp_embedder');
+ packageMap = <String, List<Folder>>{
+ 'empty': [empty],
+ 'tmp_embedder': [tmp_embedder],
+ 'tmp_sdk_ext': [tmp_sdk_ext]
+ };
+ }
+
+ void test_basic_processing() {
+ resourceProvider.newFile(
+ '/tmp_sdk_ext/_sdkext',
+ r'''
+ {
+ "dart:ui": "ui.dart"
+ }''');
+ resourceProvider.newFile(
+ '/tmp_embedder/_embedder.yaml',
+ r'''
+embedded_libs:
+ "dart:core" : "core.dart"
+ "dart:fox": "slippy.dart"
+ "dart:bear": "grizzly.dart"
+ "dart:relative": "../relative.dart"
+ "dart:deep": "deep/directory/file.dart"
+''');
+
+ PackageMapProcessor proc = new PackageMapProcessor(packageMap);
+ expect(proc.embeddedLibraries.size(), 5);
+ expect(proc.embeddedLibraries.getLibrary('dart:core').path,
+ '/tmp_embedder/core.dart');
+ expect(proc.extendedLibraries.size(), 1);
+ expect(proc.extendedLibraries.getLibrary('dart:ui').path,
+ '/tmp_sdk_ext/ui.dart');
+ }
+
+ void test_empty_package_map() {
+ PackageMapProcessor proc =
+ new PackageMapProcessor(<String, List<Folder>>{});
+ expect(proc.embeddedLibraries.size(), 0);
+ expect(proc.extendedLibraries.size(), 0);
+ expect(proc.libraryMap.size(), 0);
+ }
+
+ void test_extenders_do_not_override() {
+ resourceProvider.newFile(
+ '/tmp_sdk_ext/_sdkext',
+ r'''
+ {
+ "dart:ui": "ui2.dart"
+ }''');
+ resourceProvider.newFile(
+ '/tmp_embedder/_embedder.yaml',
+ r'''
+embedded_libs:
+ "dart:core" : "core.dart"
+ "dart:ui": "ui.dart"
+''');
+
+ PackageMapProcessor proc = new PackageMapProcessor(packageMap);
+ expect(proc.embeddedLibraries.size(), 2);
+ expect(proc.extendedLibraries.size(), 1);
+ expect(proc.libraryMap.size(), 2);
+ expect(proc.libraryMap.getLibrary('dart:ui').path, '/tmp_embedder/ui.dart');
+ }
+
+ void test_invalid_embedder() {
+ resourceProvider.newFile(
+ '/tmp_embedder/_embedder.yaml',
+ r'''
+invalid contents, will not parse
+''');
+
+ PackageMapProcessor proc = new PackageMapProcessor(packageMap);
+ expect(proc.embeddedLibraries.size(), 0);
+ expect(proc.extendedLibraries.size(), 0);
+ expect(proc.libraryMap.size(), 0);
+ }
+
+ void test_invalid_extender() {
+ resourceProvider.newFile(
+ '/tmp_sdk_ext/_sdkext',
+ r'''
+invalid contents, will not parse
+''');
+
+ PackageMapProcessor proc = new PackageMapProcessor(packageMap);
+ expect(proc.embeddedLibraries.size(), 0);
+ expect(proc.extendedLibraries.size(), 0);
+ expect(proc.libraryMap.size(), 0);
+ }
+
+ void test_no_embedder() {
+ resourceProvider.newFile(
+ '/tmp_sdk_ext/_sdkext',
+ r'''
+ {
+ "dart:ui": "ui2.dart"
+ }''');
+
+ PackageMapProcessor proc = new PackageMapProcessor(packageMap);
+ expect(proc.embeddedLibraries.size(), 0);
+ expect(proc.extendedLibraries.size(), 1);
+ expect(proc.libraryMap.size(), 1);
+ }
+
+ void test_no_embedder_or_extender() {
+ PackageMapProcessor proc = new PackageMapProcessor(packageMap);
+ expect(proc.embeddedLibraries.size(), 0);
+ expect(proc.extendedLibraries.size(), 0);
+ expect(proc.libraryMap.size(), 0);
+ }
+
+ void test_no_extender() {
+ resourceProvider.newFile(
+ '/tmp_embedder/_embedder.yaml',
+ r'''
+embedded_libs:
+ "dart:core" : "core.dart"
+ "dart:ui": "ui.dart"
+''');
+
+ PackageMapProcessor proc = new PackageMapProcessor(packageMap);
+ expect(proc.embeddedLibraries.size(), 2);
+ expect(proc.extendedLibraries.size(), 0);
+ expect(proc.libraryMap.size(), 2);
+ }
+}
diff --git a/pkg/analyzer/test/src/context/test_all.dart b/pkg/analyzer/test/src/context/test_all.dart
index 301b13c..6b9127c 100644
--- a/pkg/analyzer/test/src/context/test_all.dart
+++ b/pkg/analyzer/test/src/context/test_all.dart
@@ -8,6 +8,7 @@
import '../../utils.dart';
import 'cache_test.dart' as cache_test;
+import 'context_factory_test.dart' as context_factory_test;
import 'context_test.dart' as context_test;
/// Utility for manually running all tests.
@@ -15,6 +16,7 @@
initializeTestEnvironment();
group('context tests', () {
cache_test.main();
+ context_factory_test.main();
context_test.main();
});
}
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index ff2f9568..3de6bdf 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -44,6 +44,7 @@
runReflectiveTests(MethodElementImplTest);
runReflectiveTests(MultiplyDefinedElementImplTest);
runReflectiveTests(ParameterElementImplTest);
+ runReflectiveTests(PropertyAccessorElementImplTest);
runReflectiveTests(TopLevelVariableElementImplTest);
}
@@ -308,7 +309,7 @@
void test_isEnum() {
String firstConst = "A";
String secondConst = "B";
- ClassElementImpl enumE = ElementFactory
+ EnumElementImpl enumE = ElementFactory
.enumElement(new TestTypeProvider(), "E", [firstConst, secondConst]);
// E is an enum
@@ -4184,6 +4185,39 @@
}
}
+@reflectiveTest
+class PropertyAccessorElementImplTest extends EngineTestCase {
+ void test_matchesHandle_getter() {
+ CompilationUnitElementImpl compilationUnitElement =
+ ElementFactory.compilationUnit('foo.dart');
+ LibraryElementImpl libraryElement = ElementFactory.library(null, '')
+ ..definingCompilationUnit = compilationUnitElement;
+ PropertyAccessorElementImpl element =
+ ElementFactory.getterElement('x', true, DynamicTypeImpl.instance);
+ compilationUnitElement.accessors = <PropertyAccessorElement>[element];
+ PropertyAccessorElementHandle handle =
+ new PropertyAccessorElementHandle(null, element.location);
+ expect(element.hashCode, handle.hashCode);
+ expect(element == handle, isTrue);
+ expect(handle == element, isTrue);
+ }
+
+ void test_matchesHandle_setter() {
+ CompilationUnitElementImpl compilationUnitElement =
+ ElementFactory.compilationUnit('foo.dart');
+ LibraryElementImpl libraryElement = ElementFactory.library(null, '')
+ ..definingCompilationUnit = compilationUnitElement;
+ PropertyAccessorElementImpl element =
+ ElementFactory.setterElement('x', true, DynamicTypeImpl.instance);
+ compilationUnitElement.accessors = <PropertyAccessorElement>[element];
+ PropertyAccessorElementHandle handle =
+ new PropertyAccessorElementHandle(null, element.location);
+ expect(element.hashCode, handle.hashCode);
+ expect(element == handle, isTrue);
+ expect(handle == element, isTrue);
+ }
+}
+
class TestElementResynthesizer extends ElementResynthesizer {
Map<ElementLocation, Element> locationMap;
diff --git a/pkg/analyzer/test/src/summary/incremental_cache_test.dart b/pkg/analyzer/test/src/summary/incremental_cache_test.dart
index bf7620a..695cb51 100644
--- a/pkg/analyzer/test/src/summary/incremental_cache_test.dart
+++ b/pkg/analyzer/test/src/summary/incremental_cache_test.dart
@@ -3,10 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/incremental_cache.dart';
import 'package:unittest/unittest.dart';
+import '../../generated/test_support.dart';
import '../../reflective_tests.dart';
import '../abstract_single_unit.dart';
@@ -119,6 +121,63 @@
expect(bundles, isNotNull);
}
+ void test_getLibraryParts_hasParts() {
+ Source part1Source = addSource('/part1.dart', r'part of test;');
+ Source part2Source = addSource('/part2.dart', r'part of test;');
+ putTestLibrary(r'''
+library test;
+part 'part1.dart';
+part 'part2.dart';
+''');
+ expect(cache.getLibraryParts(testSource),
+ unorderedEquals([part1Source, part2Source]));
+ }
+
+ void test_getLibraryParts_noParts() {
+ putTestLibrary(r'''
+main() {}
+''');
+ expect(cache.getLibraryParts(testSource), isEmpty);
+ }
+
+ void test_getSourceErrorsInLibrary_library() {
+ verifyNoTestUnitErrors = false;
+ putTestLibrary(r'''
+main() {
+ int unusedVar = 42;
+}
+''');
+ List<AnalysisError> computedErrors = context.computeErrors(testSource);
+ cache.putSourceErrorsInLibrary(testSource, testSource, computedErrors);
+ List<AnalysisError> readErrors =
+ cache.getSourceErrorsInLibrary(testSource, testSource);
+ new GatheringErrorListener()
+ ..addAll(readErrors)
+ ..assertErrors(computedErrors);
+ }
+
+ void test_getSourceErrorsInLibrary_part() {
+ verifyNoTestUnitErrors = false;
+ Source partSource = addSource(
+ '/foo.dart',
+ r'''
+main() {
+ int unusedVar = 42;
+}
+''');
+ putTestLibrary(r'''
+library lib;
+part 'foo.dart';
+''');
+ List<AnalysisError> computedErrors = context.computeErrors(partSource);
+ cache.putSourceErrorsInLibrary(testSource, partSource, computedErrors);
+ List<AnalysisError> readErrors =
+ cache.getSourceErrorsInLibrary(testSource, partSource);
+ new GatheringErrorListener()
+ ..addAll(readErrors)
+ ..assertErrors(computedErrors);
+ }
+
void test_getSourceKind_library() {
putTestLibrary(r'''
main() {}
diff --git a/pkg/analyzer/test/src/summary/index_unit_test.dart b/pkg/analyzer/test/src/summary/index_unit_test.dart
index 9a269b0..1bf2cf5 100644
--- a/pkg/analyzer/test/src/summary/index_unit_test.dart
+++ b/pkg/analyzer/test/src/summary/index_unit_test.dart
@@ -699,7 +699,7 @@
new A(field: 4);
}
''');
- FieldElement field = findElement('field');
+ FieldElement field = findElement('field', ElementKind.FIELD);
PropertyAccessorElement getter = field.getter;
PropertyAccessorElement setter = field.setter;
// A()
@@ -729,7 +729,7 @@
''');
// aaa
{
- FieldElement field = findElement('aaa');
+ FieldElement field = findElement('aaa', ElementKind.FIELD);
PropertyAccessorElement getter = field.getter;
PropertyAccessorElement setter = field.setter;
assertThat(field)..isWrittenAt('aaa, ', true);
@@ -738,7 +738,7 @@
}
// bbb
{
- FieldElement field = findElement('bbb');
+ FieldElement field = findElement('bbb', ElementKind.FIELD);
PropertyAccessorElement getter = field.getter;
PropertyAccessorElement setter = field.setter;
assertThat(field)..isWrittenAt('bbb) {}', true);
@@ -964,7 +964,7 @@
A.bar() : field = 5;
}
''');
- FieldElement element = findElement('field');
+ FieldElement element = findElement('field', ElementKind.FIELD);
assertThat(element)
..isWrittenAt('field})', true)
..isWrittenAt('field = 5', true);
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index f64a448..674ce9b 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -194,16 +194,32 @@
var y = x;
''');
LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
- expect(
- library
- .getContainedName('y')
- .asTypeInferenceNode
- .variableElement
- .inferredType
- .toString(),
+ expect(_getVariable(library.getContainedName('y')).inferredType.toString(),
'() → dynamic');
}
+ void test_inferredType_closure_fromBundle_identifierSequence() {
+ var bundle = createPackageBundle(
+ '''
+class C {
+ static final x = (D d) => d.e;
+}
+class D {
+ E e;
+}
+class E {}
+''',
+ path: '/a.dart');
+ addBundle(bundle);
+ createLinker('''
+import 'a.dart';
+var y = C.x;
+''');
+ LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+ expect(_getVariable(library.getContainedName('y')).inferredType.toString(),
+ '(D) → E');
+ }
+
void test_inferredType_instanceField_dynamic() {
createLinker('''
var x;
@@ -277,12 +293,10 @@
}
''');
expect(
- linker
- .getLibrary(linkerInputs.testDartUri)
- .getContainedName('C')
- .getContainedName('y')
- .asTypeInferenceNode
- .variableElement
+ _getVariable(linker
+ .getLibrary(linkerInputs.testDartUri)
+ .getContainedName('C')
+ .getContainedName('y'))
.inferredType
.toString(),
'dynamic');
@@ -294,11 +308,9 @@
var y = x;
''');
expect(
- linker
- .getLibrary(linkerInputs.testDartUri)
- .getContainedName('y')
- .asTypeInferenceNode
- .variableElement
+ _getVariable(linker
+ .getLibrary(linkerInputs.testDartUri)
+ .getContainedName('y'))
.inferredType
.toString(),
'dynamic');
@@ -317,13 +329,7 @@
var z = y; // Inferred type: dynamic
''');
LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
- expect(
- library
- .getContainedName('z')
- .asTypeInferenceNode
- .variableElement
- .inferredType
- .toString(),
+ expect(_getVariable(library.getContainedName('z')).inferredType.toString(),
'dynamic');
}
@@ -341,13 +347,7 @@
var x = new C().f; // Inferred type: int
''');
LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
- expect(
- library
- .getContainedName('x')
- .asTypeInferenceNode
- .variableElement
- .inferredType
- .toString(),
+ expect(_getVariable(library.getContainedName('x')).inferredType.toString(),
'int');
}
@@ -388,13 +388,7 @@
var x = new C().f(0); // Inferred type: int
''');
LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
- expect(
- library
- .getContainedName('x')
- .asTypeInferenceNode
- .variableElement
- .inferredType
- .toString(),
+ expect(_getVariable(library.getContainedName('x')).inferredType.toString(),
'int');
}
@@ -442,13 +436,7 @@
var x = new C().f(); // Inferred type: int
''');
LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
- expect(
- library
- .getContainedName('x')
- .asTypeInferenceNode
- .variableElement
- .inferredType
- .toString(),
+ expect(_getVariable(library.getContainedName('x')).inferredType.toString(),
'int');
}
@@ -483,11 +471,9 @@
addBundle(bundle);
createLinker('import "a.dart"; var x = C.f;', path: '/b.dart');
expect(
- linker
- .getLibrary(linkerInputs.testDartUri)
- .getContainedName('x')
- .asTypeInferenceNode
- .variableElement
+ _getVariable(linker
+ .getLibrary(linkerInputs.testDartUri)
+ .getContainedName('x'))
.inferredType
.toString(),
'int');
@@ -498,11 +484,9 @@
addBundle(bundle);
createLinker('import "a.dart"; var b = a;', path: '/b.dart');
expect(
- linker
- .getLibrary(linkerInputs.testDartUri)
- .getContainedName('b')
- .asTypeInferenceNode
- .variableElement
+ _getVariable(linker
+ .getLibrary(linkerInputs.testDartUri)
+ .getContainedName('b'))
.inferredType
.toString(),
'int');
@@ -674,16 +658,19 @@
var y = x;
''');
LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
- expect(
- library
- .getContainedName('y')
- .asTypeInferenceNode
- .variableElement
- .inferredType
- .toString(),
+ expect(_getVariable(library.getContainedName('y')).inferredType.toString(),
'dynamic');
}
+ @failingTest
+ void test_methodCall_withTypeArguments_topLevelVariable() {
+ // The following code is incorrect but it shouldn't crash analyzer.
+ // TODO(paulberry): fix this.
+ createLinker('var f = f/*<int>*/();');
+ LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+ library.libraryCycleForLink.ensureLinked();
+ }
+
void test_multiplyInheritedExecutable_differentSignatures() {
createLinker('''
class B {
@@ -823,4 +810,8 @@
PropertyAccessorElementForLink_Variable v = library.getContainedName('v');
expect(v.variable.initializer, isNotNull);
}
+
+ VariableElementForLink _getVariable(ReferenceableElementForLink element) {
+ return (element as PropertyAccessorElementForLink_Variable).variable;
+ }
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 164d8a7..1adaae0 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -47,9 +47,6 @@
bool get mayCheckTypesOfLocals => false;
@override
- bool get skipBrokenAstInference => true;
-
- @override
void addFile(String content, {String name: '/main.dart'}) {
addLibrarySource(name, content);
}
@@ -154,6 +151,12 @@
@override
@failingTest
+ void test_circularReference_viaClosures_initializerTypes() {
+ super.test_circularReference_viaClosures_initializerTypes();
+ }
+
+ @override
+ @failingTest
void test_genericMethods_inferJSBuiltin() {
super.test_genericMethods_inferJSBuiltin();
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index 100dbcb..881ad8f 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -51,16 +51,6 @@
bool get checkPropagatedTypes => true;
- /**
- * Derived classes can override this getter to return `true` in order to
- * cause certain checks to be skipped if they are known to fail with
- * AST-based type inference.
- *
- * TODO(paulberry): remove this flag once AST-based type inference is fully
- * working.
- */
- bool get skipBrokenAstInference => false;
-
void addLibrary(String uri) {
otherLibrarySources.add(context.sourceFactory.forUri(uri));
}
@@ -211,10 +201,7 @@
}
}
- void compareClassElements(
- ClassElement resynthesized, ClassElement original, String desc) {
- ClassElementImpl r = ClassElementImpl.getImpl(resynthesized);
- ClassElementImpl o = ClassElementImpl.getImpl(original);
+ void compareClassElements(ClassElement r, ClassElement o, String desc) {
compareElements(r, o, desc);
expect(r.fields.length, o.fields.length, reason: '$desc fields.length');
for (int i = 0; i < r.fields.length; i++) {
@@ -222,16 +209,18 @@
compareFieldElements(r.fields[i], o.fields[i], '$desc.field $name');
}
compareTypes(r.supertype, o.supertype, '$desc supertype');
- expect(r.interfaces.length, o.interfaces.length);
+ expect(r.interfaces.length, o.interfaces.length,
+ reason: '$desc interfaces.length');
for (int i = 0; i < r.interfaces.length; i++) {
compareTypes(r.interfaces[i], o.interfaces[i],
'$desc interface ${o.interfaces[i].name}');
}
- expect(r.mixins.length, o.mixins.length);
+ expect(r.mixins.length, o.mixins.length, reason: '$desc mixins.length');
for (int i = 0; i < r.mixins.length; i++) {
compareTypes(r.mixins[i], o.mixins[i], '$desc mixin ${o.mixins[i].name}');
}
- expect(r.typeParameters.length, o.typeParameters.length);
+ expect(r.typeParameters.length, o.typeParameters.length,
+ reason: '$desc typeParameters.length');
for (int i = 0; i < r.typeParameters.length; i++) {
compareTypeParameterElements(r.typeParameters[i], o.typeParameters[i],
'$desc type parameter ${o.typeParameters[i].name}');
@@ -242,18 +231,23 @@
compareConstructorElements(r.constructors[i], o.constructors[i],
'$desc constructor ${o.constructors[i].name}');
}
- expect(r.accessors.length, o.accessors.length);
+ expect(r.accessors.length, o.accessors.length,
+ reason: '$desc accessors.length');
+ List<PropertyAccessorElement> rAccessors = _getSortedPropertyAccessors(r);
+ List<PropertyAccessorElement> oAccessors = _getSortedPropertyAccessors(o);
for (int i = 0; i < r.accessors.length; i++) {
- comparePropertyAccessorElements(r.accessors[i], o.accessors[i],
- '$desc accessor ${o.accessors[i].name}');
+ comparePropertyAccessorElements(
+ rAccessors[i], oAccessors[i], '$desc accessor ${oAccessors[i].name}');
}
- expect(r.methods.length, o.methods.length);
+ expect(r.methods.length, o.methods.length, reason: '$desc methods.length');
for (int i = 0; i < r.methods.length; i++) {
compareMethodElements(
r.methods[i], o.methods[i], '$desc.${o.methods[i].name}');
}
compareTypes(r.type, o.type, desc);
- expect(r.hasBeenInferred, o.hasBeenInferred, reason: desc);
+ if (r is ClassElementImpl && o is ClassElementImpl) {
+ expect(r.hasBeenInferred, o.hasBeenInferred, reason: desc);
+ }
}
void compareCompilationUnitElements(CompilationUnitElementImpl resynthesized,
@@ -677,7 +671,9 @@
expect(rImpl.evaluationResult, isNull);
} else {
Type rRuntimeType;
- if (rImpl is FunctionElementImpl) {
+ if (rImpl is ConstFieldElementImpl) {
+ rRuntimeType = ConstFieldElementImpl;
+ } else if (rImpl is FunctionElementImpl) {
rRuntimeType = FunctionElementImpl;
} else {
rRuntimeType = rImpl.runtimeType;
@@ -1040,7 +1036,7 @@
expect(resynthesized.element.type, same(resynthesized));
}
expect(resynthesized.typeArguments.length, original.typeArguments.length,
- reason: desc);
+ reason: '$desc typeArguments.length');
for (int i = 0; i < resynthesized.typeArguments.length; i++) {
if (resynthesized.typeArguments[i].isDynamic &&
original.typeArguments[i] is TypeParameterType) {
@@ -1108,10 +1104,8 @@
VariableElementImpl resynthesizedActual =
getActualElement(resynthesized, desc);
VariableElementImpl originalActual = getActualElement(original, desc);
- if (!skipBrokenAstInference) {
- compareFunctionElements(resynthesizedActual.initializer,
- originalActual.initializer, '$desc initializer');
- }
+ compareFunctionElements(resynthesizedActual.initializer,
+ originalActual.initializer, '$desc initializer');
if (originalActual is ConstVariableElement) {
Element oEnclosing = original.enclosingElement;
if (oEnclosing is ClassElement && oEnclosing.isEnum) {
@@ -1247,6 +1241,13 @@
expect(identifier.staticElement, isNull, reason: desc);
}
+ List<PropertyAccessorElement> _getSortedPropertyAccessors(
+ ClassElement classElement) {
+ List<PropertyAccessorElement> accessors = classElement.accessors.toList();
+ accessors.sort((a, b) => a.displayName.compareTo(b.displayName));
+ return accessors;
+ }
+
bool _hasModifier(Element element, Modifier modifier) {
if (modifier == Modifier.ABSTRACT) {
if (element is ClassElement) {
@@ -3662,7 +3663,8 @@
}
test_localLabels_inConstructor() {
- checkLibrary(r'''
+ checkLibrary(
+ r'''
class C {
C() {
aaa: while (true) {}
@@ -3672,11 +3674,13 @@
}
}
}
-''');
+''',
+ allowErrors: true);
}
test_localLabels_inMethod() {
- checkLibrary(r'''
+ checkLibrary(
+ r'''
class C {
m() {
aaa: while (true) {}
@@ -3686,11 +3690,13 @@
}
}
}
-''');
+''',
+ allowErrors: true);
}
test_localLabels_inTopLevelFunction() {
- checkLibrary(r'''
+ checkLibrary(
+ r'''
main() {
aaa: while (true) {}
bbb: switch (42) {
@@ -3698,7 +3704,8 @@
break;
}
}
-''');
+''',
+ allowErrors: true);
}
test_localVariables_inConstructor() {
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index d50f60d..a3e2695 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -1790,7 +1790,8 @@
0,
0,
0,
- 2
+ 2,
+ 0
],
referenceValidators: [
(EntityRef r) => checkTypeRef(r, null, null, 'foo',
@@ -1821,7 +1822,8 @@
0,
1,
0,
- 3
+ 3,
+ 0
],
referenceValidators: [
(EntityRef r) => checkTypeRef(r, null, null, 'foo',
@@ -2322,7 +2324,8 @@
], ints: [
42,
0,
- 2
+ 2,
+ 0
], referenceValidators: [
(EntityRef r) {
checkTypeRef(r, 'dart:core', 'dart:core', 'identical',
@@ -6881,9 +6884,9 @@
UnlinkedConstOperation.cascadeSectionEnd,
],
ints: [
- 5, 0, 1, // m(5)
- 0, 0, // abs()
- 6, 0, 1, // m(5)
+ 5, 0, 1, 0, // m(5)
+ 0, 0, 0, // abs()
+ 6, 0, 1, 0, // m(5)
],
strings: [
'm',
@@ -6977,7 +6980,8 @@
0,
0,
0,
- 2
+ 2,
+ 0
],
referenceValidators: [
(EntityRef r) => checkTypeRef(r, null, null, 'foo',
@@ -7008,7 +7012,8 @@
0,
1,
0,
- 3
+ 3,
+ 0
],
referenceValidators: [
(EntityRef r) => checkTypeRef(r, null, null, 'foo',
@@ -7101,6 +7106,53 @@
operators: [UnlinkedConstOperation.pushParameter], strings: ['x']);
}
+ test_expr_inClosure_refersToParam_methodCall() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('var v = (x) => x.f();');
+ _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
+ isValidConst: false,
+ operators: [
+ UnlinkedConstOperation.pushParameter,
+ UnlinkedConstOperation.invokeMethod
+ ],
+ strings: [
+ 'x',
+ 'f'
+ ],
+ ints: [
+ 0,
+ 0,
+ 0
+ ]);
+ }
+
+ test_expr_inClosure_refersToParam_methodCall_prefixed() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable =
+ serializeVariableText('var v = (x) => x.y.f();');
+ _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
+ isValidConst: false,
+ operators: [
+ UnlinkedConstOperation.pushParameter,
+ UnlinkedConstOperation.extractProperty,
+ UnlinkedConstOperation.invokeMethod
+ ],
+ strings: [
+ 'x',
+ 'y',
+ 'f'
+ ],
+ ints: [
+ 0,
+ 0,
+ 0
+ ]);
+ }
+
test_expr_inClosure_refersToParam_outOfScope() {
if (skipNonConstInitializers) {
return;
@@ -7128,6 +7180,86 @@
]);
}
+ test_expr_inClosure_refersToParam_prefixedIdentifier() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('var v = (x) => x.y;');
+ _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
+ operators: [
+ UnlinkedConstOperation.pushParameter,
+ UnlinkedConstOperation.extractProperty
+ ],
+ strings: [
+ 'x',
+ 'y'
+ ]);
+ }
+
+ test_expr_inClosure_refersToParam_prefixedIdentifier_assign() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable =
+ serializeVariableText('var v = (x) => x.y = null;');
+ _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
+ isValidConst: false,
+ operators: [
+ UnlinkedConstOperation.pushNull,
+ UnlinkedConstOperation.pushParameter,
+ UnlinkedConstOperation.assignToProperty
+ ],
+ strings: [
+ 'x',
+ 'y'
+ ],
+ assignmentOperators: [
+ UnlinkedExprAssignOperator.assign
+ ]);
+ }
+
+ test_expr_inClosure_refersToParam_prefixedPrefixedIdentifier() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('var v = (x) => x.y.z;');
+ _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
+ operators: [
+ UnlinkedConstOperation.pushParameter,
+ UnlinkedConstOperation.extractProperty,
+ UnlinkedConstOperation.extractProperty
+ ],
+ strings: [
+ 'x',
+ 'y',
+ 'z'
+ ]);
+ }
+
+ test_expr_inClosure_refersToParam_prefixedPrefixedIdentifier_assign() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable =
+ serializeVariableText('var v = (x) => x.y.z = null;');
+ _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
+ isValidConst: false,
+ operators: [
+ UnlinkedConstOperation.pushNull,
+ UnlinkedConstOperation.pushParameter,
+ UnlinkedConstOperation.extractProperty,
+ UnlinkedConstOperation.assignToProperty
+ ],
+ strings: [
+ 'x',
+ 'y',
+ 'z'
+ ],
+ assignmentOperators: [
+ UnlinkedExprAssignOperator.assign
+ ]);
+ }
+
test_expr_invokeMethod_instance() {
if (skipNonConstInitializers) {
return;
@@ -7154,7 +7286,8 @@
2,
3,
2,
- 1
+ 1,
+ 0
],
strings: [
'b',
@@ -7167,6 +7300,39 @@
]);
}
+ test_expr_invokeMethod_withTypeParameters() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+class C {
+ f<T, U>() => null;
+}
+final v = new C().f<int, String>();
+''');
+ _assertUnlinkedConst(variable.initializer.bodyExpr,
+ isValidConst: false,
+ operators: [
+ UnlinkedConstOperation.invokeConstructor,
+ UnlinkedConstOperation.invokeMethod
+ ],
+ ints: [
+ 0,
+ 0,
+ 0,
+ 0,
+ 2
+ ],
+ strings: [
+ 'f'
+ ],
+ referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'C'),
+ (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'int'),
+ (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'String')
+ ]);
+ }
+
test_expr_invokeMethodRef_instance() {
if (skipNonConstInitializers) {
return;
@@ -7195,7 +7361,8 @@
10,
20,
0,
- 2
+ 2,
+ 0
],
strings: [],
referenceValidators: [
@@ -7232,6 +7399,7 @@
],
ints: [
0,
+ 0,
0
],
strings: [],
@@ -7263,7 +7431,8 @@
],
ints: [
0,
- 1
+ 1,
+ 0
],
referenceValidators: [
(EntityRef r) => checkTypeRef(r, null, null, 'u',
@@ -7273,6 +7442,33 @@
]);
}
+ test_expr_invokeMethodRef_withTypeParameters() {
+ if (skipNonConstInitializers) {
+ return;
+ }
+ UnlinkedVariable variable = serializeVariableText('''
+f<T, U>() => null;
+final v = f<int, String>();
+''');
+ _assertUnlinkedConst(variable.initializer.bodyExpr,
+ isValidConst: false,
+ operators: [
+ UnlinkedConstOperation.invokeMethodRef
+ ],
+ ints: [
+ 0,
+ 0,
+ 2
+ ],
+ referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, null, null, 'f',
+ expectedKind: ReferenceKind.topLevelFunction,
+ numTypeParameters: 2),
+ (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'int'),
+ (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'String')
+ ]);
+ }
+
test_expr_throwException() {
if (skipNonConstInitializers) {
return;
@@ -7399,6 +7595,7 @@
ints: [
1,
0,
+ 0,
0
],
strings: [],
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index cddc662..f71c6ff 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -4464,20 +4464,41 @@
@reflectiveTest
class ScanDartTaskTest extends _AbstractDartTaskTest {
+ test_ignore_info() {
+ _performScanTask('''
+//ignore: error_code
+var x = '';
+foo(); // ignore: error_code_2
+bar(); //ignore: error_code, error_code_2
+''');
+
+ IgnoreInfo info = outputs[IGNORE_INFO];
+ expect(info.ignores.keys, hasLength(3));
+ expect(info.ignores[1].first, 'error_code');
+ expect(info.ignores[3].first, 'error_code_2');
+ expect(info.ignores[4], unorderedEquals(['error_code', 'error_code_2']));
+ }
+
test_perform_errors() {
_performScanTask('import "');
- expect(outputs, hasLength(3));
+ expect(outputs, hasLength(4));
expect(outputs[LINE_INFO], isNotNull);
expect(outputs[SCAN_ERRORS], hasLength(1));
expect(outputs[TOKEN_STREAM], isNotNull);
+ IgnoreInfo ignoreInfo = outputs[IGNORE_INFO];
+ expect(ignoreInfo, isNotNull);
+ expect(ignoreInfo.hasIgnores, isFalse);
}
test_perform_noErrors() {
_performScanTask('class A {}');
- expect(outputs, hasLength(3));
+ expect(outputs, hasLength(4));
expect(outputs[LINE_INFO], isNotNull);
expect(outputs[SCAN_ERRORS], hasLength(0));
expect(outputs[TOKEN_STREAM], isNotNull);
+ IgnoreInfo ignoreInfo = outputs[IGNORE_INFO];
+ expect(ignoreInfo, isNotNull);
+ expect(ignoreInfo.hasIgnores, isFalse);
}
test_perform_script() {
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 5fbc192..8a6376d 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -7,3310 +7,3296 @@
/// General type checking tests
library analyzer.test.src.task.strong.checker_test;
-import 'package:unittest/unittest.dart';
-
+import '../../../reflective_tests.dart';
import 'strong_test_helper.dart';
void main() {
initStrongModeTests();
+ runReflectiveTests(CheckerTest);
+}
- test('ternary operator', () {
+@reflectiveTest
+class CheckerTest {
+ void test_awaitForInCastsStreamElementToVariable() {
checkFile('''
- abstract class Comparable<T> {
- int compareTo(T other);
- static int compare(Comparable a, Comparable b) => a.compareTo(b);
- }
- typedef int Comparator<T>(T a, T b);
+import 'dart:async';
+main() async {
+ // Don't choke if sequence is not stream.
+ await for (var i in /*warning:FOR_IN_OF_INVALID_TYPE*/1234) {}
- typedef bool _Predicate<T>(T value);
+ // Dynamic cast.
+ await for (String /*info:DYNAMIC_CAST*/s in new Stream<dynamic>()) {}
- class SplayTreeMap<K, V> {
- Comparator<K> _comparator;
- _Predicate _validKey;
+ // Identity cast.
+ await for (String s in new Stream<String>()) {}
- // The warning on assigning to _comparator is legitimate. Since K has
- // no bound, all we know is that it's object. _comparator's function
- // type is effectively: (Object, Object) -> int
- // We are assigning it a fn of type: (Comparable, Comparable) -> int
- // There's no telling if that will work. For example, consider:
- //
- // new SplayTreeMap<Uri>();
- //
- // This would end up calling .compareTo() on a Uri, which doesn't
- // define that since it doesn't implement Comparable.
- SplayTreeMap([int compare(K key1, K key2),
- bool isValidKey(potentialKey)])
- : _comparator = /*warning:DOWN_CAST_COMPOSITE*/(compare == null) ? Comparable.compare : compare,
- _validKey = (isValidKey != null) ? isValidKey : ((v) => true) {
- _Predicate<Object> v = (isValidKey != null)
- ? isValidKey : (/*info:INFERRED_TYPE_CLOSURE*/(_) => true);
+ // Untyped.
+ await for (var s in new Stream<String>()) {}
- v = (isValidKey != null)
- ? v : (/*info:INFERRED_TYPE_CLOSURE*/(_) => true);
- }
- }
- void main() {
- Object obj = 42;
- dynamic dyn = 42;
- int i = 42;
+ // Downcast.
+ await for (int /*info:DOWN_CAST_IMPLICIT*/i in new Stream<num>()) {}
+}
+''');
+ }
- // Check the boolean conversion of the condition.
- print(/*warning:NON_BOOL_CONDITION*/i ? false : true);
- print((/*info:DOWN_CAST_IMPLICIT*/obj) ? false : true);
- print((/*info:DYNAMIC_CAST*/dyn) ? false : true);
- }
- ''');
- });
-
- test('least upper bounds', () {
+ void test_awaitForInCastsSupertypeSequenceToStream() {
checkFile('''
- typedef T Returns<T>();
+main() async {
+ dynamic d;
+ await for (var i in /*info:DYNAMIC_CAST*/d) {}
- // regression test for https://github.com/dart-lang/sdk/issues/26094
- class A <S extends Returns<S>, T extends Returns<T>> {
- int test(bool b) {
- S s;
- T t;
- if (b) {
- return /*warning:RETURN_OF_INVALID_TYPE*/b ? s : t;
- } else {
- return /*warning:RETURN_OF_INVALID_TYPE*/s ?? t;
- }
- }
- }
+ Object o;
+ await for (var i in /*info:DOWN_CAST_IMPLICIT*/o) {}
+}
+''');
+ }
- class B<S, T extends S> {
- T t;
- S s;
- int test(bool b) {
- return /*warning:RETURN_OF_INVALID_TYPE*/b ? t : s;
- }
- }
-
- class C {
- // Check that the least upper bound of two types with the same
- // class but different type arguments produces the pointwise
- // least upper bound of the type arguments
- int test1(bool b) {
- List<int> li;
- List<double> ld;
- return /*warning:RETURN_OF_INVALID_TYPE*/b ? li : ld;
- }
- // TODO(leafp): This case isn't handled yet. This test checks
- // the case where two related classes are instantiated with related
- // but different types.
- Iterable<num> test2(bool b) {
- List<int> li;
- Iterable<double> id;
- int x =
- /*info:ASSIGNMENT_CAST should be warning:INVALID_ASSIGNMENT*/
- b ? li : id;
- return /*warning:DOWN_CAST_COMPOSITE should be pass*/b ? li : id;
- }
- }
- ''');
- });
-
- test('setter return types', () {
+ void test_binaryAndIndexOperators() {
checkFile('''
- void voidFn() => null;
- class A {
- set a(y) => 4;
- set b(y) => voidFn();
- void set c(y) => /*warning:RETURN_OF_INVALID_TYPE*/4;
- void set d(y) => voidFn();
- /*warning:NON_VOID_RETURN_FOR_SETTER*/int set e(y) => 4;
- /*warning:NON_VOID_RETURN_FOR_SETTER*/int set f(y) =>
- /*warning:RETURN_OF_INVALID_TYPE*/voidFn();
- set g(y) {return /*warning:RETURN_OF_INVALID_TYPE*/4;}
- void set h(y) {return /*warning:RETURN_OF_INVALID_TYPE*/4;}
- /*warning:NON_VOID_RETURN_FOR_SETTER*/int set i(y) {return 4;}
- }
- ''');
- });
+class A {
+ A operator *(B b) => null;
+ A operator /(B b) => null;
+ A operator ~/(B b) => null;
+ A operator %(B b) => null;
+ A operator +(B b) => null;
+ A operator -(B b) => null;
+ A operator <<(B b) => null;
+ A operator >>(B b) => null;
+ A operator &(B b) => null;
+ A operator ^(B b) => null;
+ A operator |(B b) => null;
+ A operator[](B b) => null;
+}
- test('if/for/do/while statements use boolean conversion', () {
+class B {
+ A operator -(B b) => null;
+}
+
+foo() => new A();
+
+test() {
+ A a = new A();
+ B b = new B();
+ var c = foo();
+ a = a * b;
+ a = a * /*info:DYNAMIC_CAST*/c;
+ a = a / b;
+ a = a ~/ b;
+ a = a % b;
+ a = a + b;
+ a = a + /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
+ a = a - b;
+ b = /*warning:INVALID_ASSIGNMENT*/b - b;
+ a = a << b;
+ a = a >> b;
+ a = a & b;
+ a = a ^ b;
+ a = a | b;
+ c = (/*info:DYNAMIC_INVOKE*/c + b);
+
+ String x = 'hello';
+ int y = 42;
+ x = x + x;
+ x = x + /*info:DYNAMIC_CAST*/c;
+ x = x + /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y;
+
+ bool p = true;
+ p = p && p;
+ p = p && /*info:DYNAMIC_CAST*/c;
+ p = (/*info:DYNAMIC_CAST*/c) && p;
+ p = (/*info:DYNAMIC_CAST*/c) && /*info:DYNAMIC_CAST*/c;
+ p = /*warning:NON_BOOL_OPERAND*/y && p;
+ p = c == y;
+
+ a = a[b];
+ a = a[/*info:DYNAMIC_CAST*/c];
+ c = (/*info:DYNAMIC_INVOKE*/c[b]);
+ a[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y];
+}
+''');
+ }
+
+ void test_castsInConditions() {
checkFile('''
- main() {
- dynamic dyn = 42;
- Object obj = 42;
- int i = 42;
- bool b = false;
+main() {
+ bool b = true;
+ num x = b ? 1 : 2.3;
+ int y = /*info:ASSIGNMENT_CAST*/b ? 1 : 2.3;
+ String z = !b ? "hello" : null;
+ z = b ? null : "hello";
+}
+''');
+ }
- if (b) {}
- if (/*info:DYNAMIC_CAST*/dyn) {}
- if (/*info:DOWN_CAST_IMPLICIT*/obj) {}
- if (/*warning:NON_BOOL_CONDITION*/i) {}
-
- while (b) {}
- while (/*info:DYNAMIC_CAST*/dyn) {}
- while (/*info:DOWN_CAST_IMPLICIT*/obj) {}
- while (/*warning:NON_BOOL_CONDITION*/i) {}
-
- do {} while (b);
- do {} while (/*info:DYNAMIC_CAST*/dyn);
- do {} while (/*info:DOWN_CAST_IMPLICIT*/obj);
- do {} while (/*warning:NON_BOOL_CONDITION*/i);
-
- for (;b;) {}
- for (;/*info:DYNAMIC_CAST*/dyn;) {}
- for (;/*info:DOWN_CAST_IMPLICIT*/obj;) {}
- for (;/*warning:NON_BOOL_CONDITION*/i;) {}
- }
- ''');
- });
-
- test('for-in casts supertype sequence to iterable', () {
+ void test_castsInConstantContexts() {
checkFile('''
- main() {
- dynamic d;
- for (var i in /*info:DYNAMIC_CAST*/d) {}
+class A {
+ static const num n = 3.0;
+ // The severe error is from constant evaluation where we know the
+ // concrete type.
+ static const int /*severe:VARIABLE_TYPE_MISMATCH*/i = /*info:ASSIGNMENT_CAST*/n;
+ final int fi;
+ const A(num a) : this.fi = /*info:DOWN_CAST_IMPLICIT*/a;
+}
+class B extends A {
+ const B(Object a) : super(/*info:DOWN_CAST_IMPLICIT*/a);
+}
+void foo(Object o) {
+ var a = const A(/*info:DOWN_CAST_IMPLICIT, severe:CONST_WITH_NON_CONSTANT_ARGUMENT, severe:INVALID_CONSTANT*/o);
+}
+''');
+ }
- Object o;
- for (var i in /*info:DOWN_CAST_IMPLICIT*/o) {}
- }
- ''');
- });
-
- test('await for-in casts supertype sequence to stream', () {
+ void test_classOverrideOfGrandInterface_interfaceOfAbstractSuperclass() {
checkFile('''
- main() async {
- dynamic d;
- await for (var i in /*info:DYNAMIC_CAST*/d) {}
+class A {}
+class B {}
- Object o;
- await for (var i in /*info:DOWN_CAST_IMPLICIT*/o) {}
- }
- ''');
- });
+abstract class I1 {
+ m(A a);
+}
+abstract class Base implements I1 {}
- test('for-in casts iterable element to variable', () {
+class T1 extends Base {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+''');
+ }
+
+ void test_classOverrideOfGrandInterface_interfaceOfConcreteSuperclass() {
checkFile('''
- main() {
- // Don't choke if sequence is not iterable.
- for (var i in /*warning:FOR_IN_OF_INVALID_TYPE*/1234) {}
+class A {}
+class B {}
- // Dynamic cast.
- for (String /*info:DYNAMIC_CAST*/s in <dynamic>[]) {}
+abstract class I1 {
+ m(A a);
+}
- // Identity cast.
- for (String s in <String>[]) {}
+class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
+ implements I1 {}
- // Untyped.
- for (var s in <String>[]) {}
+class T1 extends Base {
+ // not reported technically because if the class is concrete,
+ // it should implement all its interfaces and hence it is
+ // sufficient to check overrides against it.
+ m(/*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+''');
+ }
- // Downcast.
- for (int /*info:DOWN_CAST_IMPLICIT*/i in <num>[]) {}
- }
- ''');
- });
-
- test('await for-in casts stream element to variable', () {
+ void test_classOverrideOfGrandInterface_interfaceOfInterfaceOfChild() {
checkFile('''
- import 'dart:async';
- main() async {
- // Don't choke if sequence is not stream.
- await for (var i in /*warning:FOR_IN_OF_INVALID_TYPE*/1234) {}
+class A {}
+class B {}
- // Dynamic cast.
- await for (String /*info:DYNAMIC_CAST*/s in new Stream<dynamic>()) {}
+abstract class I1 {
+ m(A a);
+}
+abstract class I2 implements I1 {}
- // Identity cast.
- await for (String s in new Stream<String>()) {}
+class T1 implements I2 {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+''');
+ }
- // Untyped.
- await for (var s in new Stream<String>()) {}
-
- // Downcast.
- await for (int /*info:DOWN_CAST_IMPLICIT*/i in new Stream<num>()) {}
- }
- ''');
- });
-
- test('dynamic invocation', () {
+ void test_classOverrideOfGrandInterface_mixinOfInterfaceOfChild() {
checkFile('''
- typedef dynamic A(dynamic x);
- class B {
- int call(int x) => x;
- double col(double x) => x;
- }
- void main() {
- {
- B f = new B();
- int x;
- double y;
- x = f(3);
- x = /*warning:INVALID_ASSIGNMENT*/f.col(3.0);
- y = /*warning:INVALID_ASSIGNMENT*/f(3);
- y = f.col(3.0);
- f(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3.0);
- f.col(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
- }
- {
- Function f = new B();
- int x;
- double y;
- x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
- x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE, info:INVALID_ASSIGNMENT*/f.col(3.0);
- y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
- y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f.col(3.0);
- /*info:DYNAMIC_INVOKE*/f(3.0);
- // Through type propagation, we know f is actually a B, hence the
- // hint.
- /*info:DYNAMIC_INVOKE*/f.col(/*info:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
- }
- {
- A f = new B();
- int x;
- double y;
- x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
- y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
- /*info:DYNAMIC_INVOKE*/f(3.0);
- }
- {
- dynamic g = new B();
- /*info:DYNAMIC_INVOKE*/g.call(/*info:ARGUMENT_TYPE_NOT_ASSIGNABLE*/32.0);
- /*info:DYNAMIC_INVOKE*/g.col(42.0);
- /*info:DYNAMIC_INVOKE*/g.foo(42.0);
- /*info:DYNAMIC_INVOKE*/g./*info:UNDEFINED_GETTER*/x;
- A f = new B();
- /*info:DYNAMIC_INVOKE*/f.col(42.0);
- /*info:DYNAMIC_INVOKE*/f.foo(42.0);
- /*info:DYNAMIC_INVOKE*/f./*warning:UNDEFINED_GETTER*/x;
- }
- }
- ''');
- });
+class A {}
+class B {}
- test('conversion and dynamic invoke', () {
+abstract class M1 {
+ m(A a);
+}
+abstract class I2 extends Object with M1 {}
+
+class T1 implements I2 {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+''');
+ }
+
+ void test_classOverrideOfGrandInterface_superclassOfInterfaceOfChild() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+abstract class I2 extends I1 {}
+
+class T1 implements I2 {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+''');
+ }
+
+ void test_compoundAssignments() {
+ checkFile('''
+class A {
+ A operator *(B b) => null;
+ A operator /(B b) => null;
+ A operator ~/(B b) => null;
+ A operator %(B b) => null;
+ A operator +(B b) => null;
+ A operator -(B b) => null;
+ A operator <<(B b) => null;
+ A operator >>(B b) => null;
+ A operator &(B b) => null;
+ A operator ^(B b) => null;
+ A operator |(B b) => null;
+ D operator [](B index) => null;
+ void operator []=(B index, D value) => null;
+}
+
+class B {
+ A operator -(B b) => null;
+}
+
+class D {
+ D operator +(D d) => null;
+}
+
+foo() => new A();
+
+test() {
+ int x = 0;
+ x += 5;
+ /*severe:STATIC_TYPE_ERROR*/x += 3.14;
+
+ double y = 0.0;
+ y += 5;
+ y += 3.14;
+
+ num z = 0;
+ z += 5;
+ z += 3.14;
+
+ x = /*info:DOWN_CAST_IMPLICIT*/x + z;
+ x += /*info:DOWN_CAST_IMPLICIT*/z;
+ y = y + z;
+ y += z;
+
+ dynamic w = 42;
+ x += /*info:DYNAMIC_CAST*/w;
+ y += /*info:DYNAMIC_CAST*/w;
+ z += /*info:DYNAMIC_CAST*/w;
+
+ A a = new A();
+ B b = new B();
+ var c = foo();
+ a = a * b;
+ a *= b;
+ a *= /*info:DYNAMIC_CAST*/c;
+ a /= b;
+ a ~/= b;
+ a %= b;
+ a += b;
+ a += /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
+ a -= b;
+ /*severe:STATIC_TYPE_ERROR*/b -= /*warning:INVALID_ASSIGNMENT*/b;
+ a <<= b;
+ a >>= b;
+ a &= b;
+ a ^= b;
+ a |= b;
+ /*info:DYNAMIC_INVOKE*/c += b;
+
+ var d = new D();
+ a[b] += d;
+ a[/*info:DYNAMIC_CAST*/c] += d;
+ a[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z] += d;
+ a[b] += /*info:DYNAMIC_CAST*/c;
+ a[b] += /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z;
+ /*info:DYNAMIC_INVOKE,info:DYNAMIC_INVOKE*/c[b] += d;
+}
+''');
+ }
+
+ void test_constructors() {
+ checkFile('''
+const num z = 25;
+Object obj = "world";
+
+class A {
+ int x;
+ String y;
+
+ A(this.x) : this.y = /*warning:FIELD_INITIALIZER_NOT_ASSIGNABLE*/42;
+
+ A.c1(p): this.x = /*info:DOWN_CAST_IMPLICIT*/z, this.y = /*info:DYNAMIC_CAST*/p;
+
+ A.c2(this.x, this.y);
+
+ A.c3(/*severe:INVALID_PARAMETER_DECLARATION*/num this.x, String this.y);
+}
+
+class B extends A {
+ B() : super(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
+
+ B.c2(int x, String y) : super.c2(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y,
+ /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/x);
+
+ B.c3(num x, Object y) : super.c3(x, /*info:DOWN_CAST_IMPLICIT*/y);
+}
+
+void main() {
+ A a = new A.c2(/*info:DOWN_CAST_IMPLICIT*/z, /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z);
+ var b = new B.c2(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*info:DOWN_CAST_IMPLICIT*/obj);
+}
+''');
+ }
+
+ void test_conversionAndDynamicInvoke() {
addFile(
'''
- dynamic toString = (int x) => x + 42;
- dynamic hashCode = "hello";
- ''',
+dynamic toString = (int x) => x + 42;
+dynamic hashCode = "hello";
+''',
name: '/helper.dart');
checkFile('''
- import 'helper.dart' as helper;
+import 'helper.dart' as helper;
- class A {
- String x = "hello world";
+class A {
+ String x = "hello world";
- void baz1(y) { x + /*info:DYNAMIC_CAST*/y; }
- static baz2(y) => /*info:DYNAMIC_INVOKE*/y + y;
- }
+ void baz1(y) { x + /*info:DYNAMIC_CAST*/y; }
+ static baz2(y) => /*info:DYNAMIC_INVOKE*/y + y;
+}
- void foo(String str) {
- print(str);
- }
+void foo(String str) {
+ print(str);
+}
- class B {
- String toString([int arg]) => arg.toString();
- }
+class B {
+ String toString([int arg]) => arg.toString();
+}
- void bar(a) {
- foo(/*info:DYNAMIC_CAST,info:DYNAMIC_INVOKE*/a.x);
- }
+void bar(a) {
+ foo(/*info:DYNAMIC_CAST,info:DYNAMIC_INVOKE*/a.x);
+}
- baz() => new B();
+baz() => new B();
- typedef DynFun(x);
- typedef StrFun(String x);
+typedef DynFun(x);
+typedef StrFun(String x);
- var bar1 = bar;
+var bar1 = bar;
- void main() {
- var a = new A();
- bar(a);
- (/*info:DYNAMIC_INVOKE*/bar1(a));
- var b = bar;
- (/*info:DYNAMIC_INVOKE*/b(a));
- var f1 = foo;
- f1("hello");
- dynamic f2 = foo;
- (/*info:DYNAMIC_INVOKE*/f2("hello"));
- DynFun f3 = foo;
- (/*info:DYNAMIC_INVOKE*/f3("hello"));
- (/*info:DYNAMIC_INVOKE*/f3(42));
- StrFun f4 = foo;
- f4("hello");
- a.baz1("hello");
- var b1 = a.baz1;
- (/*info:DYNAMIC_INVOKE*/b1("hello"));
- A.baz2("hello");
- var b2 = A.baz2;
- (/*info:DYNAMIC_INVOKE*/b2("hello"));
+void main() {
+ var a = new A();
+ bar(a);
+ (/*info:DYNAMIC_INVOKE*/bar1(a));
+ var b = bar;
+ (/*info:DYNAMIC_INVOKE*/b(a));
+ var f1 = foo;
+ f1("hello");
+ dynamic f2 = foo;
+ (/*info:DYNAMIC_INVOKE*/f2("hello"));
+ DynFun f3 = foo;
+ (/*info:DYNAMIC_INVOKE*/f3("hello"));
+ (/*info:DYNAMIC_INVOKE*/f3(42));
+ StrFun f4 = foo;
+ f4("hello");
+ a.baz1("hello");
+ var b1 = a.baz1;
+ (/*info:DYNAMIC_INVOKE*/b1("hello"));
+ A.baz2("hello");
+ var b2 = A.baz2;
+ (/*info:DYNAMIC_INVOKE*/b2("hello"));
- dynamic a1 = new B();
- (/*info:DYNAMIC_INVOKE*/a1./*info:UNDEFINED_GETTER*/x);
- a1.toString();
- (/*info:DYNAMIC_INVOKE*/a1.toString(42));
- var toStringClosure = a1.toString;
- (/*info:DYNAMIC_INVOKE*/a1.toStringClosure());
- (/*info:DYNAMIC_INVOKE*/a1.toStringClosure(42));
- (/*info:DYNAMIC_INVOKE*/a1.toStringClosure("hello"));
- a1.hashCode;
+ dynamic a1 = new B();
+ (/*info:DYNAMIC_INVOKE*/a1./*info:UNDEFINED_GETTER*/x);
+ a1.toString();
+ (/*info:DYNAMIC_INVOKE*/a1.toString(42));
+ var toStringClosure = a1.toString;
+ (/*info:DYNAMIC_INVOKE*/a1.toStringClosure());
+ (/*info:DYNAMIC_INVOKE*/a1.toStringClosure(42));
+ (/*info:DYNAMIC_INVOKE*/a1.toStringClosure("hello"));
+ a1.hashCode;
- dynamic toString = () => null;
- (/*info:DYNAMIC_INVOKE*/toString());
+ dynamic toString = () => null;
+ (/*info:DYNAMIC_INVOKE*/toString());
- (/*info:DYNAMIC_INVOKE*/helper.toString());
- var toStringClosure2 = helper.toString;
- (/*info:DYNAMIC_INVOKE*/toStringClosure2());
- int hashCode = /*info:DYNAMIC_CAST*/helper.hashCode;
+ (/*info:DYNAMIC_INVOKE*/helper.toString());
+ var toStringClosure2 = helper.toString;
+ (/*info:DYNAMIC_INVOKE*/toStringClosure2());
+ int hashCode = /*info:DYNAMIC_CAST*/helper.hashCode;
- baz().toString();
- baz().hashCode;
- }
- ''');
- });
+ baz().toString();
+ baz().hashCode;
+}
+''');
+ }
- test('Constructors', () {
+ void test_dynamicInvocation() {
checkFile('''
- const num z = 25;
- Object obj = "world";
+typedef dynamic A(dynamic x);
+class B {
+ int call(int x) => x;
+ double col(double x) => x;
+}
+void main() {
+ {
+ B f = new B();
+ int x;
+ double y;
+ x = f(3);
+ x = /*warning:INVALID_ASSIGNMENT*/f.col(3.0);
+ y = /*warning:INVALID_ASSIGNMENT*/f(3);
+ y = f.col(3.0);
+ f(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3.0);
+ f.col(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ }
+ {
+ Function f = new B();
+ int x;
+ double y;
+ x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
+ x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE, info:INVALID_ASSIGNMENT*/f.col(3.0);
+ y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
+ y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f.col(3.0);
+ /*info:DYNAMIC_INVOKE*/f(3.0);
+ // Through type propagation, we know f is actually a B, hence the
+ // hint.
+ /*info:DYNAMIC_INVOKE*/f.col(/*info:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+ }
+ {
+ A f = new B();
+ int x;
+ double y;
+ x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
+ y = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
+ /*info:DYNAMIC_INVOKE*/f(3.0);
+ }
+ {
+ dynamic g = new B();
+ /*info:DYNAMIC_INVOKE*/g.call(/*info:ARGUMENT_TYPE_NOT_ASSIGNABLE*/32.0);
+ /*info:DYNAMIC_INVOKE*/g.col(42.0);
+ /*info:DYNAMIC_INVOKE*/g.foo(42.0);
+ /*info:DYNAMIC_INVOKE*/g./*info:UNDEFINED_GETTER*/x;
+ A f = new B();
+ /*info:DYNAMIC_INVOKE*/f.col(42.0);
+ /*info:DYNAMIC_INVOKE*/f.foo(42.0);
+ /*info:DYNAMIC_INVOKE*/f./*warning:UNDEFINED_GETTER*/x;
+ }
+}
+''');
+ }
- class A {
- int x;
- String y;
+ void test_factoryConstructorDowncast() {
+ checkFile(r'''
+class Animal {
+ Animal();
+ factory Animal.cat() => new Cat();
+}
- A(this.x) : this.y = /*warning:FIELD_INITIALIZER_NOT_ASSIGNABLE*/42;
+class Cat extends Animal {}
- A.c1(p): this.x = /*info:DOWN_CAST_IMPLICIT*/z, this.y = /*info:DYNAMIC_CAST*/p;
+void main() {
+ Cat c = /*info:ASSIGNMENT_CAST*/new Animal.cat();
+ c = /*severe:STATIC_TYPE_ERROR*/new Animal();
+}''');
+ }
- A.c2(this.x, this.y);
-
- A.c3(/*severe:INVALID_PARAMETER_DECLARATION*/num this.x, String this.y);
- }
-
- class B extends A {
- B() : super(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello");
-
- B.c2(int x, String y) : super.c2(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y,
- /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/x);
-
- B.c3(num x, Object y) : super.c3(x, /*info:DOWN_CAST_IMPLICIT*/y);
- }
-
- void main() {
- A a = new A.c2(/*info:DOWN_CAST_IMPLICIT*/z, /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z);
- var b = new B.c2(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/"hello", /*info:DOWN_CAST_IMPLICIT*/obj);
- }
- ''');
- });
-
- test('Unbound variable', () {
+ void test_fieldFieldOverride() {
checkFile('''
- void main() {
- dynamic y = /*warning:UNDEFINED_IDENTIFIER should be error*/unboundVariable;
- }
- ''');
- });
+class A {}
+class B extends A {}
+class C extends B {}
- test('Unbound type name', () {
+class Base {
+ B f1;
+ B f2;
+ B f3;
+ B f4;
+}
+
+class Child extends Base {
+ /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
+ /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
+ /*severe:INVALID_FIELD_OVERRIDE*/var f3;
+ /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic f4;
+}
+
+class Child2 implements Base {
+ /*severe:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
+ /*severe:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
+ var f3;
+ /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic f4;
+}
+''');
+ }
+
+ void test_fieldGetterOverride() {
checkFile('''
- void main() {
- /*warning:UNDEFINED_CLASS should be error*/AToB y;
- }
- ''');
- });
+class A {}
+class B extends A {}
+class C extends B {}
- // Regression test for https://github.com/dart-lang/sdk/issues/25069
- test('Void subtyping', () {
+abstract class Base {
+ B f1;
+ B f2;
+ B f3;
+ B f4;
+}
+
+class Child extends Base {
+ /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
+ /*severe:INVALID_FIELD_OVERRIDE*/C get f2 => null;
+ /*severe:INVALID_FIELD_OVERRIDE*/get f3 => null;
+ /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
+}
+
+class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR*/Child2 implements Base {
+ /*severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
+ C get f2 => null;
+ get f3 => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
+}
+''');
+ }
+
+ void test_fieldOverride_fuzzyArrows() {
checkFile('''
- typedef int Foo();
- void foo() {}
- void main () {
- Foo x = /*warning:INVALID_ASSIGNMENT,info:USE_OF_VOID_RESULT*/foo();
- }
- ''');
- });
+typedef void ToVoid<T>(T x);
+class F {
+ final ToVoid<dynamic> f = null;
+ final ToVoid<int> g = null;
+}
- group('Ground type subtyping:', () {
- test('dynamic is top', () {
- checkFile('''
+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 A {}
- class B extends A {}
+class H implements F {
+ final ToVoid<int> f = null;
+ /*severe:INVALID_METHOD_OVERRIDE*/final ToVoid<dynamic> g = null;
+}
+ ''');
+ }
- void main() {
- dynamic y;
- Object o;
- int i = 0;
- double d = 0.0;
- num n;
- A a;
- B b;
- y = o;
- y = i;
- y = d;
- y = n;
- y = a;
- y = b;
- }
- ''');
- });
+ void test_fieldSetterOverride() {
+ checkFile('''
+class A {}
+class B extends A {}
+class C extends B {}
- test('dynamic downcasts', () {
- checkFile('''
+class Base {
+ B f1;
+ B f2;
+ B f3;
+ B f4;
+ B f5;
+}
- class A {}
- class B extends A {}
+class Child extends Base {
+ /*severe:INVALID_FIELD_OVERRIDE*/B get f1 => null;
+ /*severe:INVALID_FIELD_OVERRIDE*/B get f2 => null;
+ /*severe:INVALID_FIELD_OVERRIDE*/B get f3 => null;
+ /*severe:INVALID_FIELD_OVERRIDE*/B get f4 => null;
+ /*severe:INVALID_FIELD_OVERRIDE*/B get f5 => null;
- void main() {
- dynamic y;
- Object o;
- int i = 0;
- double d = 0.0;
- num n;
- A a;
- B b;
- o = y;
- i = /*info:DYNAMIC_CAST*/y;
- d = /*info:DYNAMIC_CAST*/y;
- n = /*info:DYNAMIC_CAST*/y;
- a = /*info:DYNAMIC_CAST*/y;
- b = /*info:DYNAMIC_CAST*/y;
- }
- ''');
- });
+ /*severe:INVALID_FIELD_OVERRIDE*/void set f1(A value) {}
+ /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
+ /*severe:INVALID_FIELD_OVERRIDE*/void set f3(value) {}
+ /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
+ /*severe:INVALID_FIELD_OVERRIDE*/set f5(B value) {}
+}
- test('assigning a class', () {
- checkFile('''
+class Child2 implements Base {
+ B get f1 => null;
+ B get f2 => null;
+ B get f3 => null;
+ B get f4 => null;
+ B get f5 => null;
- class A {}
- class B extends A {}
+ void set f1(A value) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
+ void set f3(value) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
+ set f5(B value) {}
+}
+''');
+ }
- void main() {
- dynamic y;
- Object o;
- int i = 0;
- double d = 0.0;
- num n;
- A a;
- B b;
- y = a;
- o = a;
- i = /*warning:INVALID_ASSIGNMENT*/a;
- d = /*warning:INVALID_ASSIGNMENT*/a;
- n = /*warning:INVALID_ASSIGNMENT*/a;
- a = a;
- b = /*info:DOWN_CAST_IMPLICIT*/a;
- }
- ''');
- });
+ void test_forInCastsIterateElementToVariable() {
+ checkFile('''
+main() {
+ // Don't choke if sequence is not iterable.
+ for (var i in /*warning:FOR_IN_OF_INVALID_TYPE*/1234) {}
- test('assigning a subclass', () {
- checkFile('''
+ // Dynamic cast.
+ for (String /*info:DYNAMIC_CAST*/s in <dynamic>[]) {}
- class A {}
- class B extends A {}
- class C extends A {}
+ // Identity cast.
+ for (String s in <String>[]) {}
- void main() {
- dynamic y;
- Object o;
- int i = 0;
- double d = 0.0;
- num n;
- A a;
- B b;
- C c;
- y = b;
- o = b;
- i = /*warning:INVALID_ASSIGNMENT*/b;
- d = /*warning:INVALID_ASSIGNMENT*/b;
- n = /*warning:INVALID_ASSIGNMENT*/b;
- a = b;
- b = b;
- c = /*warning:INVALID_ASSIGNMENT*/b;
- }
- ''');
- });
+ // Untyped.
+ for (var s in <String>[]) {}
- test('interfaces', () {
- checkFile('''
+ // Downcast.
+ for (int /*info:DOWN_CAST_IMPLICIT*/i in <num>[]) {}
+}
+''');
+ }
- class A {}
- class B extends A {}
- class C extends A {}
- class D extends B implements C {}
+ void test_forInCastsSupertypeSequenceToIterate() {
+ checkFile('''
+main() {
+ dynamic d;
+ for (var i in /*info:DYNAMIC_CAST*/d) {}
- void main() {
- A top;
- B left;
- C right;
- D bot;
- {
- top = top;
- top = left;
- top = right;
- top = bot;
- }
- {
- left = /*info:DOWN_CAST_IMPLICIT*/top;
- left = left;
- left = /*warning:INVALID_ASSIGNMENT*/right;
- left = bot;
- }
- {
- right = /*info:DOWN_CAST_IMPLICIT*/top;
- right = /*warning:INVALID_ASSIGNMENT*/left;
- right = right;
- right = bot;
- }
- {
- bot = /*info:DOWN_CAST_IMPLICIT*/top;
- bot = /*info:DOWN_CAST_IMPLICIT*/left;
- bot = /*info:DOWN_CAST_IMPLICIT*/right;
- bot = bot;
- }
- }
- ''');
- });
- });
+ Object o;
+ for (var i in /*info:DOWN_CAST_IMPLICIT*/o) {}
+}
+''');
+ }
- group('Function typing and subtyping:', () {
- test('int and object', () {
- checkFile('''
+ void test_forLoopVariable() {
+ checkFile('''
+foo() {
+ for (int i = 0; i < 10; i++) {
+ i = /*warning:INVALID_ASSIGNMENT*/"hi";
+ }
+}
+bar() {
+ for (var i = 0; i < 10; i++) {
+ int j = i + 1;
+ }
+}
+''');
+ }
- typedef Object Top(int x); // Top of the lattice
- typedef int Left(int x); // Left branch
- typedef int Left2(int x); // Left branch
- typedef Object Right(Object x); // Right branch
- typedef int Bot(Object x); // Bottom of the lattice
+ void test_functionModifiers_async() {
+ checkFile('''
+import 'dart:async';
+import 'dart:math' show Random;
- Object globalTop(int x) => x;
- int globalLeft(int x) => x;
- Object globalRight(Object x) => x;
- int bot_(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
- int globalBot(Object x) => x as int;
+dynamic x;
- void main() {
- // Note: use locals so we only know the type, not that it's a specific
- // function declaration. (we can issue better errors in that case.)
- var top = globalTop;
- var left = globalLeft;
- var right = globalRight;
- var bot = globalBot;
+foo1() async => x;
+Future foo2() async => x;
+Future<int> foo3() async => /*info:DYNAMIC_CAST*/x;
+Future<int> foo4() async => new Future<int>.value(/*info:DYNAMIC_CAST*/x);
+Future<int> foo5() async =>
+ /*warning:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
- { // Check typedef equality
- Left f = left;
- Left2 g = f;
- }
- {
- Top f;
- f = top;
- f = left;
- f = right;
- f = bot;
- }
- {
- Left f;
- f = /*warning:DOWN_CAST_COMPOSITE*/top;
- f = left;
- f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
- f = bot;
- }
- {
- Right f;
- f = /*warning:DOWN_CAST_COMPOSITE*/top;
- f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
- f = right;
- f = bot;
- }
- {
- Bot f;
- f = /*warning:DOWN_CAST_COMPOSITE*/top;
- f = /*warning:DOWN_CAST_COMPOSITE*/left;
- f = /*warning:DOWN_CAST_COMPOSITE*/right;
- f = bot;
- }
- }
- ''');
- });
+bar1() async { return x; }
+Future bar2() async { return x; }
+Future<int> bar3() async { return /*info:DYNAMIC_CAST*/x; }
+Future<int> bar4() async { return new Future<int>.value(/*info:DYNAMIC_CAST*/x); }
+Future<int> bar5() async {
+ return /*warning:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
+}
- test('classes', () {
- checkFile('''
+int y;
+Future<int> z;
- class A {}
- class B extends A {}
+baz() async {
+ int a = /*info:DYNAMIC_CAST*/await x;
+ int b = await y;
+ int c = await z;
+ String d = /*warning:INVALID_ASSIGNMENT*/await z;
+}
- typedef A Top(B x); // Top of the lattice
- typedef B Left(B x); // Left branch
- typedef B Left2(B x); // Left branch
- typedef A Right(A x); // Right branch
- typedef B Bot(A x); // Bottom of the lattice
+Future<bool> get issue_264 async {
+ await 42;
+ if (new Random().nextBool()) {
+ return true;
+ } else {
+ return new Future<bool>.value(false);
+ }
+}
+''');
+ }
- B left(B x) => x;
- B bot_(A x) => /*info:DOWN_CAST_IMPLICIT*/x;
- B bot(A x) => x as B;
- A top(B x) => x;
- A right(A x) => x;
+ void test_functionModifiers_asyncStar() {
+ checkFile('''
+import 'dart:async';
- void main() {
- { // Check typedef equality
- Left f = left;
- Left2 g = f;
- }
- {
- Top f;
- f = top;
- f = left;
- f = right;
- f = bot;
- }
- {
- Left f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
- f = bot;
- }
- {
- Right f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = right;
- f = bot;
- }
- {
- Bot f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
- f = bot;
- }
- }
- ''');
- });
+dynamic x;
- test('dynamic', () {
- checkFile('''
+bar1() async* { yield x; }
+Stream bar2() async* { yield x; }
+Stream<int> bar3() async* { yield /*info:DYNAMIC_CAST*/x; }
+Stream<int> bar4() async* { yield /*warning:YIELD_OF_INVALID_TYPE*/new Stream<int>(); }
- class A {}
+baz1() async* { yield* /*info:DYNAMIC_CAST*/x; }
+Stream baz2() async* { yield* /*info:DYNAMIC_CAST*/x; }
+Stream<int> baz3() async* { yield* /*warning:DOWN_CAST_COMPOSITE*/x; }
+Stream<int> baz4() async* { yield* new Stream<int>(); }
+Stream<int> baz5() async* { yield* /*info:INFERRED_TYPE_ALLOCATION*/new Stream(); }
+''');
+ }
- typedef dynamic Top(dynamic x); // Top of the lattice
- typedef dynamic Left(A x); // Left branch
- typedef A Right(dynamic x); // Right branch
- typedef A Bottom(A x); // Bottom of the lattice
+ void test_functionModifiers_syncStar() {
+ checkFile('''
+dynamic x;
- void main() {
- Top top;
- Left left;
- Right right;
- Bottom bot;
- {
- Top f;
- f = top;
- f = left;
- f = right;
- f = bot;
- }
- {
- Left f;
- f = /*warning:DOWN_CAST_COMPOSITE*/top;
- f = left;
- f = /*warning:DOWN_CAST_COMPOSITE*/right;
- f = bot;
- }
- {
- Right f;
- f = /*warning:DOWN_CAST_COMPOSITE*/top;
- f = /*warning:DOWN_CAST_COMPOSITE*/left;
- f = right;
- f = bot;
- }
- {
- Bottom f;
- f = /*warning:DOWN_CAST_COMPOSITE*/top;
- f = /*warning:DOWN_CAST_COMPOSITE*/left;
- f = /*warning:DOWN_CAST_COMPOSITE*/right;
- f = bot;
- }
- }
- ''');
- });
+bar1() sync* { yield x; }
+Iterable bar2() sync* { yield x; }
+Iterable<int> bar3() sync* { yield /*info:DYNAMIC_CAST*/x; }
+Iterable<int> bar4() sync* { yield /*warning:YIELD_OF_INVALID_TYPE*/bar3(); }
- test('dynamic functions - closures are not fuzzy', () {
- // Regression test for
- // https://github.com/dart-lang/sdk/issues/26118
- // https://github.com/dart-lang/sdk/issues/26156
- checkFile('''
- void takesF(void f(int x)) {}
+baz1() sync* { yield* /*info:DYNAMIC_CAST*/x; }
+Iterable baz2() sync* { yield* /*info:DYNAMIC_CAST*/x; }
+Iterable<int> baz3() sync* { yield* /*warning:DOWN_CAST_COMPOSITE*/x; }
+Iterable<int> baz4() sync* { yield* bar3(); }
+Iterable<int> baz5() sync* { yield* /*info:INFERRED_TYPE_ALLOCATION*/new List(); }
+''');
+ }
- typedef void TakesInt(int x);
+ void test_functionTypingAndSubtyping_classes() {
+ checkFile('''
+class A {}
+class B extends A {}
- void update(_) {}
- void updateOpt([_]) {}
- void updateOptNum([num x]) {}
+typedef A Top(B x); // Top of the lattice
+typedef B Left(B x); // Left branch
+typedef B Left2(B x); // Left branch
+typedef A Right(A x); // Right branch
+typedef B Bot(A x); // Bottom of the lattice
- class A {
- TakesInt f;
- A(TakesInt g) {
- f = update;
- f = updateOpt;
- f = updateOptNum;
- }
- TakesInt g(bool a, bool b) {
- if (a) {
- return update;
- } else if (b) {
- return updateOpt;
- } else {
- return updateOptNum;
- }
- }
- }
+B left(B x) => x;
+B bot_(A x) => /*info:DOWN_CAST_IMPLICIT*/x;
+B bot(A x) => x as B;
+A top(B x) => x;
+A right(A x) => x;
- void test0() {
- takesF(update);
- takesF(updateOpt);
- takesF(updateOptNum);
- TakesInt f;
- f = update;
- f = updateOpt;
- f = updateOptNum;
- new A(update);
- new A(updateOpt);
- new A(updateOptNum);
- }
+void main() {
+ { // Check typedef equality
+ Left f = left;
+ Left2 g = f;
+ }
+ {
+ Top f;
+ f = top;
+ f = left;
+ f = right;
+ f = bot;
+ }
+ {
+ Left f;
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = left;
+ f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = bot;
+ }
+ {
+ Right f;
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = right;
+ f = bot;
+ }
+ {
+ Bot f;
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = bot;
+ }
+}
+''');
+ }
- void test1() {
- void takesF(f(int x)) => null;
- takesF((dynamic y) => 3);
- }
+ void test_functionTypingAndSubtyping_dynamic() {
+ checkFile('''
+class A {}
- void test2() {
- int x;
- int f/*<T>*/(/*=T*/ t, callback(/*=T*/ x)) { return 3; }
- f(x, (y) => 3);
- }
- ''');
- });
+typedef dynamic Top(dynamic x); // Top of the lattice
+typedef dynamic Left(A x); // Left branch
+typedef A Right(dynamic x); // Right branch
+typedef A Bottom(A x); // Bottom of the lattice
- test('dynamic - known functions', () {
- // Our lattice should look like this:
- //
- //
- // Bot -> Top
- // / \
- // A -> Top Bot -> A
- // / \ /
- // Top -> Top A -> A
- // \ /
- // Top -> A
- //
- // Note that downcasts of known functions are promoted to
- // static type errors, since they cannot succeed.
- // This makes some of what look like downcasts turn into
- // type errors below.
- checkFile('''
- class A {}
+void main() {
+ Top top;
+ Left left;
+ Right right;
+ Bottom bot;
+ {
+ Top f;
+ f = top;
+ f = left;
+ f = right;
+ f = bot;
+ }
+ {
+ Left f;
+ f = /*warning:DOWN_CAST_COMPOSITE*/top;
+ f = left;
+ f = /*warning:DOWN_CAST_COMPOSITE*/right;
+ f = bot;
+ }
+ {
+ Right f;
+ f = /*warning:DOWN_CAST_COMPOSITE*/top;
+ f = /*warning:DOWN_CAST_COMPOSITE*/left;
+ f = right;
+ f = bot;
+ }
+ {
+ Bottom f;
+ f = /*warning:DOWN_CAST_COMPOSITE*/top;
+ f = /*warning:DOWN_CAST_COMPOSITE*/left;
+ f = /*warning:DOWN_CAST_COMPOSITE*/right;
+ f = bot;
+ }
+}
+''');
+ }
- typedef dynamic BotTop(dynamic x);
- typedef dynamic ATop(A x);
- typedef A BotA(dynamic x);
- typedef A AA(A x);
- typedef A TopA(Object x);
- typedef dynamic TopTop(Object x);
+ void test_functionTypingAndSubtyping_dynamic_knownFunctions() {
+ // Our lattice should look like this:
+ //
+ //
+ // Bot -> Top
+ // / \
+ // A -> Top Bot -> A
+ // / \ /
+ // Top -> Top A -> A
+ // \ /
+ // Top -> A
+ //
+ // Note that downcasts of known functions are promoted to
+ // static type errors, since they cannot succeed.
+ // This makes some of what look like downcasts turn into
+ // type errors below.
+ checkFile('''
+class A {}
- dynamic aTop(A x) => x;
- A aa(A x) => x;
- dynamic topTop(dynamic x) => x;
- A topA(dynamic x) => /*info:DYNAMIC_CAST*/x;
- void apply/*<T>*/(/*=T*/ f0, /*=T*/ f1, /*=T*/ f2,
- /*=T*/ f3, /*=T*/ f4, /*=T*/ f5) {}
- void main() {
- BotTop botTop;
- BotA botA;
- {
- BotTop f;
- f = topA;
- f = topTop;
- f = aa;
- f = aTop;
- f = botA;
- f = botTop;
- apply/*<BotTop>*/(
- topA,
- topTop,
- aa,
- aTop,
- botA,
- botTop
- );
- apply/*<BotTop>*/(
- (dynamic x) => new A(),
- (dynamic x) => (x as Object),
- (A x) => x,
- (A x) => null,
- botA,
- botTop
- );
- }
- {
- ATop f;
- f = topA;
- f = topTop;
- f = aa;
- f = aTop;
- f = /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA;
- f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
- apply/*<ATop>*/(
- topA,
- topTop,
- aa,
- aTop,
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
- /*warning:DOWN_CAST_COMPOSITE*/botTop
- );
- apply/*<ATop>*/(
- (dynamic x) => new A(),
- (dynamic x) => (x as Object),
- (A x) => x,
- (A x) => null,
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
- /*warning:DOWN_CAST_COMPOSITE*/botTop
- );
- }
- {
- BotA f;
- f = topA;
- f = /*severe:STATIC_TYPE_ERROR*/topTop;
- f = aa;
- f = /*severe:STATIC_TYPE_ERROR*/aTop;
- f = botA;
- f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
- apply/*<BotA>*/(
- topA,
- /*severe:STATIC_TYPE_ERROR*/topTop,
- aa,
- /*severe:STATIC_TYPE_ERROR*/aTop,
- botA,
- /*warning:DOWN_CAST_COMPOSITE*/botTop
- );
- apply/*<BotA>*/(
- (dynamic x) => new A(),
- /*severe:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object),
- (A x) => x,
- /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object),
- botA,
- /*warning:DOWN_CAST_COMPOSITE*/botTop
- );
- }
- {
- AA f;
- f = topA;
- f = /*severe:STATIC_TYPE_ERROR*/topTop;
- f = aa;
- f = /*severe:STATIC_TYPE_ERROR*/aTop; // known function
- f = /*warning:DOWN_CAST_COMPOSITE*/botA;
- f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
- apply/*<AA>*/(
- topA,
- /*severe:STATIC_TYPE_ERROR*/topTop,
- aa,
- /*severe:STATIC_TYPE_ERROR*/aTop, // known function
- /*warning:DOWN_CAST_COMPOSITE*/botA,
- /*warning:DOWN_CAST_COMPOSITE*/botTop
- );
- apply/*<AA>*/(
- (dynamic x) => new A(),
- /*severe:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object),
- (A x) => x,
- /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
- /*warning:DOWN_CAST_COMPOSITE*/botA,
- /*warning:DOWN_CAST_COMPOSITE*/botTop
- );
- }
- {
- TopTop f;
- f = topA;
- f = topTop;
- f = /*severe:STATIC_TYPE_ERROR*/aa;
- f = /*severe:STATIC_TYPE_ERROR*/aTop; // known function
- f = /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA;
- f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
- apply/*<TopTop>*/(
- topA,
- topTop,
- /*severe:STATIC_TYPE_ERROR*/aa,
- /*severe:STATIC_TYPE_ERROR*/aTop, // known function
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
- /*warning:DOWN_CAST_COMPOSITE*/botTop
- );
- apply/*<TopTop>*/(
- (dynamic x) => new A(),
- (dynamic x) => (x as Object),
- /*severe:STATIC_TYPE_ERROR*/(A x) => x,
- /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
- /*warning:DOWN_CAST_COMPOSITE*/botTop
- );
- }
- {
- TopA f;
- f = topA;
- f = /*severe:STATIC_TYPE_ERROR*/topTop; // known function
- f = /*severe:STATIC_TYPE_ERROR*/aa; // known function
- f = /*severe:STATIC_TYPE_ERROR*/aTop; // known function
- f = /*warning:DOWN_CAST_COMPOSITE*/botA;
- f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
- apply/*<TopA>*/(
- topA,
- /*severe:STATIC_TYPE_ERROR*/topTop, // known function
- /*severe:STATIC_TYPE_ERROR*/aa, // known function
- /*severe:STATIC_TYPE_ERROR*/aTop, // known function
- /*warning:DOWN_CAST_COMPOSITE*/botA,
- /*warning:DOWN_CAST_COMPOSITE*/botTop
- );
- apply/*<TopA>*/(
- (dynamic x) => new A(),
- /*severe:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object), // known function
- /*severe:STATIC_TYPE_ERROR*/(A x) => x, // known function
- /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
- /*warning:DOWN_CAST_COMPOSITE*/botA,
- /*warning:DOWN_CAST_COMPOSITE*/botTop
- );
- }
- }
- ''');
- });
-
- test('function literal variance', () {
- checkFile('''
-
- class A {}
- class B extends A {}
-
- typedef T Function2<S, T>(S z);
-
- A top(B x) => x;
- B left(B x) => x;
- A right(A x) => x;
- B bot(A x) => x as B;
-
- void main() {
- {
- Function2<B, A> f;
- f = top;
- f = left;
- f = right;
- f = bot;
- }
- {
- Function2<B, B> f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
- f = bot;
- }
- {
- Function2<A, A> f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = right;
- f = bot;
- }
- {
- Function2<A, B> f;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
- f = bot;
- }
- }
- ''');
- });
-
- test('function variable variance', () {
- checkFile('''
-
- class A {}
- class B extends A {}
-
- typedef T Function2<S, T>(S z);
-
- void main() {
- {
- Function2<B, A> top;
- Function2<B, B> left;
- Function2<A, A> right;
- Function2<A, B> bot;
-
- top = right;
- top = bot;
- top = top;
- top = left;
-
- left = /*warning:DOWN_CAST_COMPOSITE*/top;
- left = left;
- left = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
- left = bot;
-
- right = /*warning:DOWN_CAST_COMPOSITE*/top;
- right = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
- right = right;
- right = bot;
-
- bot = /*warning:DOWN_CAST_COMPOSITE*/top;
- bot = /*warning:DOWN_CAST_COMPOSITE*/left;
- bot = /*warning:DOWN_CAST_COMPOSITE*/right;
- bot = bot;
- }
- }
- ''');
- });
-
- test('static method variance', () {
- checkFile('''
-
- class A {}
- class B extends A {}
-
- class C {
- static A top(B x) => x;
- static B left(B x) => x;
- static A right(A x) => x;
- static B bot(A x) => x as B;
- }
-
- typedef T Function2<S, T>(S z);
-
- void main() {
- {
- Function2<B, A> f;
- f = C.top;
- f = C.left;
- f = C.right;
- f = C.bot;
- }
- {
- Function2<B, B> f;
- f = /*severe:STATIC_TYPE_ERROR*/C.top;
- f = C.left;
- f = /*severe:STATIC_TYPE_ERROR*/C.right;
- f = C.bot;
- }
- {
- Function2<A, A> f;
- f = /*severe:STATIC_TYPE_ERROR*/C.top;
- f = /*severe:STATIC_TYPE_ERROR*/C.left;
- f = C.right;
- f = C.bot;
- }
- {
- Function2<A, B> f;
- f = /*severe:STATIC_TYPE_ERROR*/C.top;
- f = /*severe:STATIC_TYPE_ERROR*/C.left;
- f = /*severe:STATIC_TYPE_ERROR*/C.right;
- f = C.bot;
- }
- }
- ''');
- });
-
- test('instance method variance', () {
- checkFile('''
-
- class A {}
- class B extends A {}
-
- class C {
- A top(B x) => x;
- B left(B x) => x;
- A right(A x) => x;
- B bot(A x) => x as B;
- }
-
- typedef T Function2<S, T>(S z);
-
- void main() {
- C c = new C();
- {
- Function2<B, A> f;
- f = c.top;
- f = c.left;
- f = c.right;
- f = c.bot;
- }
- {
- Function2<B, B> f;
- f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
- f = c.left;
- f = /*warning:DOWN_CAST_COMPOSITE*/c.right;
- f = c.bot;
- }
- {
- Function2<A, A> f;
- f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
- f = /*warning:DOWN_CAST_COMPOSITE*/c.left;
- f = c.right;
- f = c.bot;
- }
- {
- Function2<A, B> f;
- f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
- f = /*warning:DOWN_CAST_COMPOSITE*/c.left;
- f = /*warning:DOWN_CAST_COMPOSITE*/c.right;
- f = c.bot;
- }
- }
- ''');
- });
-
- test('higher order function literals 1', () {
- checkFile('''
-
- class A {}
- class B extends A {}
-
- typedef T Function2<S, T>(S z);
-
- typedef A BToA(B x); // Top of the base lattice
- typedef B AToB(A x); // Bot of the base lattice
-
- BToA top(AToB f) => f;
- AToB left(AToB f) => f;
- BToA right(BToA f) => f;
- AToB bot_(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
- AToB bot(BToA f) => f as AToB;
-
- void main() {
- {
- Function2<AToB, BToA> f; // Top
- f = top;
- f = left;
- f = right;
- f = bot;
- }
- {
- Function2<AToB, AToB> f; // Left
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
- f = bot;
- }
- {
- Function2<BToA, BToA> f; // Right
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = right;
- f = bot;
- }
- {
- Function2<BToA, AToB> f; // Bot
- f = bot;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- }
- }
- ''');
- });
-
- test('higher order function literals 2', () {
- checkFile('''
-
- class A {}
- class B extends A {}
-
- typedef T Function2<S, T>(S z);
-
- typedef A BToA(B x); // Top of the base lattice
- typedef B AToB(A x); // Bot of the base lattice
-
- Function2<B, A> top(AToB f) => f;
- Function2<A, B> left(AToB f) => f;
- Function2<B, A> right(BToA f) => f;
- Function2<A, B> bot_(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
- Function2<A, B> bot(BToA f) => f as Function2<A, B>;
-
- void main() {
- {
- Function2<AToB, BToA> f; // Top
- f = top;
- f = left;
- f = right;
- f = bot;
- }
- {
- Function2<AToB, AToB> f; // Left
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
- f = bot;
- }
- {
- Function2<BToA, BToA> f; // Right
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = right;
- f = bot;
- }
- {
- Function2<BToA, AToB> f; // Bot
- f = bot;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- }
- }
- ''');
- });
-
- test('higher order function literals 3', () {
- checkFile('''
-
- class A {}
- class B extends A {}
-
- typedef T Function2<S, T>(S z);
-
- typedef A BToA(B x); // Top of the base lattice
- typedef B AToB(A x); // Bot of the base lattice
-
- BToA top(Function2<A, B> f) => f;
- AToB left(Function2<A, B> f) => f;
- BToA right(Function2<B, A> f) => f;
- AToB bot_(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f;
- AToB bot(Function2<B, A> f) => f as AToB;
-
- void main() {
- {
- Function2<AToB, BToA> f; // Top
- f = top;
- f = left;
- f = right;
- f = bot;
- }
- {
- Function2<AToB, AToB> f; // Left
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = left;
- f = /*severe:STATIC_TYPE_ERROR*/right;
- f = bot;
- }
- {
- Function2<BToA, BToA> f; // Right
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = right;
- f = bot;
- }
- {
- Function2<BToA, AToB> f; // Bot
- f = bot;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- f = /*severe:STATIC_TYPE_ERROR*/top;
- f = /*severe:STATIC_TYPE_ERROR*/left;
- }
- }
- ''');
- });
-
- test('higher order function variables', () {
- checkFile('''
-
- class A {}
- class B extends A {}
-
- typedef T Function2<S, T>(S z);
+typedef dynamic BotTop(dynamic x);
+typedef dynamic ATop(A x);
+typedef A BotA(dynamic x);
+typedef A AA(A x);
+typedef A TopA(Object x);
+typedef dynamic TopTop(Object x);
- void main() {
- {
- Function2<Function2<A, B>, Function2<B, A>> top;
- Function2<Function2<B, A>, Function2<B, A>> right;
- Function2<Function2<A, B>, Function2<A, B>> left;
- Function2<Function2<B, A>, Function2<A, B>> bot;
+dynamic aTop(A x) => x;
+A aa(A x) => x;
+dynamic topTop(dynamic x) => x;
+A topA(dynamic x) => /*info:DYNAMIC_CAST*/x;
+void apply/*<T>*/(/*=T*/ f0, /*=T*/ f1, /*=T*/ f2,
+ /*=T*/ f3, /*=T*/ f4, /*=T*/ f5) {}
+void main() {
+ BotTop botTop;
+ BotA botA;
+ {
+ BotTop f;
+ f = topA;
+ f = topTop;
+ f = aa;
+ f = aTop;
+ f = botA;
+ f = botTop;
+ apply/*<BotTop>*/(
+ topA,
+ topTop,
+ aa,
+ aTop,
+ botA,
+ botTop
+ );
+ apply/*<BotTop>*/(
+ (dynamic x) => new A(),
+ (dynamic x) => (x as Object),
+ (A x) => x,
+ (A x) => null,
+ botA,
+ botTop
+ );
+ }
+ {
+ ATop f;
+ f = topA;
+ f = topTop;
+ f = aa;
+ f = aTop;
+ f = /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA;
+ f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
+ apply/*<ATop>*/(
+ topA,
+ topTop,
+ aa,
+ aTop,
+ /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
+ /*warning:DOWN_CAST_COMPOSITE*/botTop
+ );
+ apply/*<ATop>*/(
+ (dynamic x) => new A(),
+ (dynamic x) => (x as Object),
+ (A x) => x,
+ (A x) => null,
+ /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
+ /*warning:DOWN_CAST_COMPOSITE*/botTop
+ );
+ }
+ {
+ BotA f;
+ f = topA;
+ f = /*severe:STATIC_TYPE_ERROR*/topTop;
+ f = aa;
+ f = /*severe:STATIC_TYPE_ERROR*/aTop;
+ f = botA;
+ f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
+ apply/*<BotA>*/(
+ topA,
+ /*severe:STATIC_TYPE_ERROR*/topTop,
+ aa,
+ /*severe:STATIC_TYPE_ERROR*/aTop,
+ botA,
+ /*warning:DOWN_CAST_COMPOSITE*/botTop
+ );
+ apply/*<BotA>*/(
+ (dynamic x) => new A(),
+ /*severe:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object),
+ (A x) => x,
+ /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object),
+ botA,
+ /*warning:DOWN_CAST_COMPOSITE*/botTop
+ );
+ }
+ {
+ AA f;
+ f = topA;
+ f = /*severe:STATIC_TYPE_ERROR*/topTop;
+ f = aa;
+ f = /*severe:STATIC_TYPE_ERROR*/aTop; // known function
+ f = /*warning:DOWN_CAST_COMPOSITE*/botA;
+ f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
+ apply/*<AA>*/(
+ topA,
+ /*severe:STATIC_TYPE_ERROR*/topTop,
+ aa,
+ /*severe:STATIC_TYPE_ERROR*/aTop, // known function
+ /*warning:DOWN_CAST_COMPOSITE*/botA,
+ /*warning:DOWN_CAST_COMPOSITE*/botTop
+ );
+ apply/*<AA>*/(
+ (dynamic x) => new A(),
+ /*severe:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object),
+ (A x) => x,
+ /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
+ /*warning:DOWN_CAST_COMPOSITE*/botA,
+ /*warning:DOWN_CAST_COMPOSITE*/botTop
+ );
+ }
+ {
+ TopTop f;
+ f = topA;
+ f = topTop;
+ f = /*severe:STATIC_TYPE_ERROR*/aa;
+ f = /*severe:STATIC_TYPE_ERROR*/aTop; // known function
+ f = /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA;
+ f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
+ apply/*<TopTop>*/(
+ topA,
+ topTop,
+ /*severe:STATIC_TYPE_ERROR*/aa,
+ /*severe:STATIC_TYPE_ERROR*/aTop, // known function
+ /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
+ /*warning:DOWN_CAST_COMPOSITE*/botTop
+ );
+ apply/*<TopTop>*/(
+ (dynamic x) => new A(),
+ (dynamic x) => (x as Object),
+ /*severe:STATIC_TYPE_ERROR*/(A x) => x,
+ /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
+ /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/botA,
+ /*warning:DOWN_CAST_COMPOSITE*/botTop
+ );
+ }
+ {
+ TopA f;
+ f = topA;
+ f = /*severe:STATIC_TYPE_ERROR*/topTop; // known function
+ f = /*severe:STATIC_TYPE_ERROR*/aa; // known function
+ f = /*severe:STATIC_TYPE_ERROR*/aTop; // known function
+ f = /*warning:DOWN_CAST_COMPOSITE*/botA;
+ f = /*warning:DOWN_CAST_COMPOSITE*/botTop;
+ apply/*<TopA>*/(
+ topA,
+ /*severe:STATIC_TYPE_ERROR*/topTop, // known function
+ /*severe:STATIC_TYPE_ERROR*/aa, // known function
+ /*severe:STATIC_TYPE_ERROR*/aTop, // known function
+ /*warning:DOWN_CAST_COMPOSITE*/botA,
+ /*warning:DOWN_CAST_COMPOSITE*/botTop
+ );
+ apply/*<TopA>*/(
+ (dynamic x) => new A(),
+ /*severe:STATIC_TYPE_ERROR*/(dynamic x) => (x as Object), // known function
+ /*severe:STATIC_TYPE_ERROR*/(A x) => x, // known function
+ /*severe:STATIC_TYPE_ERROR*/(A x) => (x as Object), // known function
+ /*warning:DOWN_CAST_COMPOSITE*/botA,
+ /*warning:DOWN_CAST_COMPOSITE*/botTop
+ );
+ }
+}
+''');
+ }
- top = right;
- top = bot;
- top = top;
- top = left;
+ void test_functionTypingAndSubtyping_dynamicFunctions_clasuresAreNotFuzzy() {
+ // Regression test for
+ // https://github.com/dart-lang/sdk/issues/26118
+ // https://github.com/dart-lang/sdk/issues/26156
+ checkFile('''
+void takesF(void f(int x)) {}
- left = /*warning:DOWN_CAST_COMPOSITE*/top;
- left = left;
- left =
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/right;
- left = bot;
+typedef void TakesInt(int x);
- right = /*warning:DOWN_CAST_COMPOSITE*/top;
- right =
- /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/left;
- right = right;
- right = bot;
+void update(_) {}
+void updateOpt([_]) {}
+void updateOptNum([num x]) {}
- bot = /*warning:DOWN_CAST_COMPOSITE*/top;
- bot = /*warning:DOWN_CAST_COMPOSITE*/left;
- bot = /*warning:DOWN_CAST_COMPOSITE*/right;
- bot = bot;
- }
+class A {
+ TakesInt f;
+ A(TakesInt g) {
+ f = update;
+ f = updateOpt;
+ f = updateOptNum;
+ }
+ TakesInt g(bool a, bool b) {
+ if (a) {
+ return update;
+ } else if (b) {
+ return updateOpt;
+ } else {
+ return updateOptNum;
}
- ''');
- });
+ }
+}
- test('named and optional parameters', () {
- checkFile('''
+void test0() {
+ takesF(update);
+ takesF(updateOpt);
+ takesF(updateOptNum);
+ TakesInt f;
+ f = update;
+ f = updateOpt;
+ f = updateOptNum;
+ new A(update);
+ new A(updateOpt);
+ new A(updateOptNum);
+}
- class A {}
+void test1() {
+ void takesF(f(int x)) => null;
+ takesF((dynamic y) => 3);
+}
- typedef A FR(A x);
- typedef A FO([A x]);
- typedef A FN({A x});
- typedef A FRR(A x, A y);
- typedef A FRO(A x, [A y]);
- typedef A FRN(A x, {A n});
- typedef A FOO([A x, A y]);
- typedef A FNN({A x, A y});
- typedef A FNNN({A z, A y, A x});
+void test2() {
+ int x;
+ int f/*<T>*/(/*=T*/ t, callback(/*=T*/ x)) { return 3; }
+ f(x, (y) => 3);
+}
+''');
+ }
- void main() {
- FR r;
- FO o;
- FN n;
- FRR rr;
- FRO ro;
- FRN rn;
- FOO oo;
- FNN nn;
- FNNN nnn;
-
- r = r;
- r = o;
- r = /*warning:INVALID_ASSIGNMENT*/n;
- r = /*warning:INVALID_ASSIGNMENT*/rr;
- r = ro;
- r = rn;
- r = oo;
- r = /*warning:INVALID_ASSIGNMENT*/nn;
- r = /*warning:INVALID_ASSIGNMENT*/nnn;
-
- o = /*warning:DOWN_CAST_COMPOSITE*/r;
- o = o;
- o = /*warning:INVALID_ASSIGNMENT*/n;
- o = /*warning:INVALID_ASSIGNMENT*/rr;
- o = /*warning:INVALID_ASSIGNMENT*/ro;
- o = /*warning:INVALID_ASSIGNMENT*/rn;
- o = oo;
- o = /*warning:INVALID_ASSIGNMENT*/nn;
- o = /*warning:INVALID_ASSIGNMENT*/nnn;
-
- n = /*warning:INVALID_ASSIGNMENT*/r;
- n = /*warning:INVALID_ASSIGNMENT*/o;
- n = n;
- n = /*warning:INVALID_ASSIGNMENT*/rr;
- n = /*warning:INVALID_ASSIGNMENT*/ro;
- n = /*warning:INVALID_ASSIGNMENT*/rn;
- n = /*warning:INVALID_ASSIGNMENT*/oo;
- n = nn;
- n = nnn;
-
- rr = /*warning:INVALID_ASSIGNMENT*/r;
- rr = /*warning:INVALID_ASSIGNMENT*/o;
- rr = /*warning:INVALID_ASSIGNMENT*/n;
- rr = rr;
- rr = ro;
- rr = /*warning:INVALID_ASSIGNMENT*/rn;
- rr = oo;
- rr = /*warning:INVALID_ASSIGNMENT*/nn;
- rr = /*warning:INVALID_ASSIGNMENT*/nnn;
-
- ro = /*warning:DOWN_CAST_COMPOSITE*/r;
- ro = /*warning:INVALID_ASSIGNMENT*/o;
- ro = /*warning:INVALID_ASSIGNMENT*/n;
- ro = /*warning:DOWN_CAST_COMPOSITE*/rr;
- ro = ro;
- ro = /*warning:INVALID_ASSIGNMENT*/rn;
- ro = oo;
- ro = /*warning:INVALID_ASSIGNMENT*/nn;
- ro = /*warning:INVALID_ASSIGNMENT*/nnn;
-
- rn = /*warning:DOWN_CAST_COMPOSITE*/r;
- rn = /*warning:INVALID_ASSIGNMENT*/o;
- rn = /*warning:INVALID_ASSIGNMENT*/n;
- rn = /*warning:INVALID_ASSIGNMENT*/rr;
- rn = /*warning:INVALID_ASSIGNMENT*/ro;
- rn = rn;
- rn = /*warning:INVALID_ASSIGNMENT*/oo;
- rn = /*warning:INVALID_ASSIGNMENT*/nn;
- rn = /*warning:INVALID_ASSIGNMENT*/nnn;
-
- oo = /*warning:DOWN_CAST_COMPOSITE*/r;
- oo = /*warning:DOWN_CAST_COMPOSITE*/o;
- oo = /*warning:INVALID_ASSIGNMENT*/n;
- oo = /*warning:DOWN_CAST_COMPOSITE*/rr;
- oo = /*warning:DOWN_CAST_COMPOSITE*/ro;
- oo = /*warning:INVALID_ASSIGNMENT*/rn;
- oo = oo;
- oo = /*warning:INVALID_ASSIGNMENT*/nn;
- oo = /*warning:INVALID_ASSIGNMENT*/nnn;
-
- nn = /*warning:INVALID_ASSIGNMENT*/r;
- nn = /*warning:INVALID_ASSIGNMENT*/o;
- nn = /*warning:DOWN_CAST_COMPOSITE*/n;
- nn = /*warning:INVALID_ASSIGNMENT*/rr;
- nn = /*warning:INVALID_ASSIGNMENT*/ro;
- nn = /*warning:INVALID_ASSIGNMENT*/rn;
- nn = /*warning:INVALID_ASSIGNMENT*/oo;
- nn = nn;
- nn = nnn;
-
- nnn = /*warning:INVALID_ASSIGNMENT*/r;
- nnn = /*warning:INVALID_ASSIGNMENT*/o;
- nnn = /*warning:DOWN_CAST_COMPOSITE*/n;
- nnn = /*warning:INVALID_ASSIGNMENT*/rr;
- nnn = /*warning:INVALID_ASSIGNMENT*/ro;
- nnn = /*warning:INVALID_ASSIGNMENT*/rn;
- nnn = /*warning:INVALID_ASSIGNMENT*/oo;
- nnn = /*warning:DOWN_CAST_COMPOSITE*/nn;
- nnn = nnn;
- }
- ''');
- });
-
- test('Function subtyping: objects with call methods', () {
- checkFile('''
-
- typedef int I2I(int x);
- typedef num N2N(num x);
- class A {
- int call(int x) => x;
- }
- class B {
- num call(num x) => x;
- }
- int i2i(int x) => x;
- num n2n(num x) => x;
- void main() {
- {
- I2I f;
- f = new A();
- f = /*warning:INVALID_ASSIGNMENT*/new B();
- f = i2i;
- f = /*severe:STATIC_TYPE_ERROR*/n2n;
- f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
- f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
- }
- {
- N2N f;
- f = /*warning:INVALID_ASSIGNMENT*/new A();
- f = new B();
- f = /*severe:STATIC_TYPE_ERROR*/i2i;
- f = n2n;
- f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
- f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
- }
- {
- A f;
- f = new A();
- f = /*warning:INVALID_ASSIGNMENT*/new B();
- f = /*warning:INVALID_ASSIGNMENT*/i2i;
- f = /*warning:INVALID_ASSIGNMENT*/n2n;
- f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
- f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
- }
- {
- B f;
- f = /*warning:INVALID_ASSIGNMENT*/new A();
- f = new B();
- f = /*warning:INVALID_ASSIGNMENT*/i2i;
- f = /*warning:INVALID_ASSIGNMENT*/n2n;
- f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
- f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
- }
- {
- Function f;
- f = new A();
- f = new B();
- f = i2i;
- f = n2n;
- f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
- f = (n2n as Function);
- }
- }
- ''');
- });
-
- test('void', () {
- checkFile('''
-
- class A {
- void bar() => null;
- void foo() => bar(); // allowed
- }
- ''');
- });
-
- test('uninferred closure', () {
- checkFile('''
- typedef num Num2Num(num x);
- void main() {
- Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int x) { return x; };
- print(g(42));
- }
- ''');
- });
-
- test('subtype of universal type', () {
- checkFile('''
- void main() {
- nonGenericFn(x) => null;
- {
- /*=R*/ f/*<P, R>*/(/*=P*/ p) => null;
- /*=T*/ g/*<S, T>*/(/*=S*/ s) => null;
-
- var local = f;
- local = g; // valid
-
- // Non-generic function cannot subtype a generic one.
- local = /*warning:INVALID_ASSIGNMENT*/(x) => null;
- local = /*warning:INVALID_ASSIGNMENT*/nonGenericFn;
- }
- {
- Iterable/*<R>*/ f/*<P, R>*/(List/*<P>*/ p) => null;
- List/*<T>*/ g/*<S, T>*/(Iterable/*<S>*/ s) => null;
-
- var local = f;
- local = g; // valid
-
- var local2 = g;
- local = local2;
- local2 = /*severe:STATIC_TYPE_ERROR*/f;
- local2 = /*warning:DOWN_CAST_COMPOSITE*/local;
-
- // Non-generic function cannot subtype a generic one.
- local = /*warning:INVALID_ASSIGNMENT*/(x) => null;
- local = /*warning:INVALID_ASSIGNMENT*/nonGenericFn;
- }
- }
- ''');
- });
- });
-
- test('Relaxed casts', () {
+ void test_functionTypingAndSubtyping_functionLiteralVariance() {
checkFile('''
+class A {}
+class B extends A {}
- class A {}
+typedef T Function2<S, T>(S z);
- class L<T> {}
- class M<T> extends L<T> {}
- // L<dynamic|Object>
- // / \
- // M<dynamic|Object> L<A>
- // \ /
- // M<A>
- // In normal Dart, there are additional edges
- // from M<A> to M<dynamic>
- // from L<A> to M<dynamic>
- // from L<A> to L<dynamic>
- void main() {
- L lOfDs;
- L<Object> lOfOs;
- L<A> lOfAs;
+A top(B x) => x;
+B left(B x) => x;
+A right(A x) => x;
+B bot(A x) => x as B;
- M mOfDs;
- M<Object> mOfOs;
- M<A> mOfAs;
+void main() {
+ {
+ Function2<B, A> f;
+ f = top;
+ f = left;
+ f = right;
+ f = bot;
+ }
+ {
+ Function2<B, B> f;
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = left;
+ f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = bot;
+ }
+ {
+ Function2<A, A> f;
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = right;
+ f = bot;
+ }
+ {
+ Function2<A, B> f;
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = bot;
+ }
+}
+''');
+ }
- {
- lOfDs = mOfDs;
- lOfDs = mOfOs;
- lOfDs = mOfAs;
- lOfDs = lOfDs;
- lOfDs = lOfOs;
- lOfDs = lOfAs;
- lOfDs = new L(); // Reset type propagation.
- }
- {
- lOfOs = mOfDs;
- lOfOs = mOfOs;
- lOfOs = mOfAs;
- lOfOs = lOfDs;
- lOfOs = lOfOs;
- lOfOs = lOfAs;
- lOfOs = new L<Object>(); // Reset type propagation.
- }
- {
- lOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
- lOfAs = /*warning:INVALID_ASSIGNMENT*/mOfOs;
- lOfAs = mOfAs;
- lOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
- lOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
- lOfAs = lOfAs;
- lOfAs = new L<A>(); // Reset type propagation.
- }
- {
- mOfDs = mOfDs;
- mOfDs = mOfOs;
- mOfDs = mOfAs;
- mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
- mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
- mOfDs = /*warning:DOWN_CAST_COMPOSITE*/lOfAs;
- mOfDs = new M(); // Reset type propagation.
- }
- {
- mOfOs = mOfDs;
- mOfOs = mOfOs;
- mOfOs = mOfAs;
- mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
- mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
- mOfOs = /*warning:INVALID_ASSIGNMENT*/lOfAs;
- mOfOs = new M<Object>(); // Reset type propagation.
- }
- {
- mOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
- mOfAs = /*info:DOWN_CAST_IMPLICIT*/mOfOs;
- mOfAs = mOfAs;
- mOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
- mOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
- mOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfAs;
- }
- }
- ''');
- });
-
- test('Type checking literals', () {
+ void test_functionTypingAndSubtyping_functionVariableVariance() {
checkFile('''
- test() {
- num n = 3;
- int i = 3;
- String s = "hello";
- {
- List<int> l = <int>[i];
- l = <int>[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
- l = <int>[/*info:DOWN_CAST_IMPLICIT*/n];
- l = <int>[i, /*info:DOWN_CAST_IMPLICIT*/n, /*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
- }
- {
- List l = /*info:INFERRED_TYPE_LITERAL*/[i];
- l = /*info:INFERRED_TYPE_LITERAL*/[s];
- l = /*info:INFERRED_TYPE_LITERAL*/[n];
- l = /*info:INFERRED_TYPE_LITERAL*/[i, n, s];
- }
- {
- Map<String, int> m = <String, int>{s: i};
- m = <String, int>{s: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
- m = <String, int>{s: /*info:DOWN_CAST_IMPLICIT*/n};
- m = <String, int>{s: i,
- s: /*info:DOWN_CAST_IMPLICIT*/n,
- s: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
- }
- // TODO(leafp): We can't currently test for key errors since the
- // error marker binds to the entire entry.
- {
- Map m = /*info:INFERRED_TYPE_LITERAL*/{s: i};
- m = /*info:INFERRED_TYPE_LITERAL*/{s: s};
- m = /*info:INFERRED_TYPE_LITERAL*/{s: n};
- m = /*info:INFERRED_TYPE_LITERAL*/
- {s: i,
- s: n,
- s: s};
- m = /*info:INFERRED_TYPE_LITERAL*/
- {i: s,
- n: s,
- s: s};
- }
- }
- ''');
- });
+class A {}
+class B extends A {}
- test('casts in constant contexts', () {
+typedef T Function2<S, T>(S z);
+
+void main() {
+ {
+ Function2<B, A> top;
+ Function2<B, B> left;
+ Function2<A, A> right;
+ Function2<A, B> bot;
+
+ top = right;
+ top = bot;
+ top = top;
+ top = left;
+
+ left = /*warning:DOWN_CAST_COMPOSITE*/top;
+ left = left;
+ left = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
+ left = bot;
+
+ right = /*warning:DOWN_CAST_COMPOSITE*/top;
+ right = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
+ right = right;
+ right = bot;
+
+ bot = /*warning:DOWN_CAST_COMPOSITE*/top;
+ bot = /*warning:DOWN_CAST_COMPOSITE*/left;
+ bot = /*warning:DOWN_CAST_COMPOSITE*/right;
+ bot = bot;
+ }
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_higherOrderFunctionLiteral1() {
checkFile('''
- class A {
- static const num n = 3.0;
- // The severe error is from constant evaluation where we know the
- // concrete type.
- static const int /*severe:VARIABLE_TYPE_MISMATCH*/i = /*info:ASSIGNMENT_CAST*/n;
- final int fi;
- const A(num a) : this.fi = /*info:DOWN_CAST_IMPLICIT*/a;
- }
- class B extends A {
- const B(Object a) : super(/*info:DOWN_CAST_IMPLICIT*/a);
- }
- void foo(Object o) {
- var a = const A(/*info:DOWN_CAST_IMPLICIT, severe:CONST_WITH_NON_CONSTANT_ARGUMENT, severe:INVALID_CONSTANT*/o);
- }
- ''');
- });
+class A {}
+class B extends A {}
- test('casts in conditionals', () {
+typedef T Function2<S, T>(S z);
+
+typedef A BToA(B x); // Top of the base lattice
+typedef B AToB(A x); // Bot of the base lattice
+
+BToA top(AToB f) => f;
+AToB left(AToB f) => f;
+BToA right(BToA f) => f;
+AToB bot_(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
+AToB bot(BToA f) => f as AToB;
+
+void main() {
+ {
+ Function2<AToB, BToA> f; // Top
+ f = top;
+ f = left;
+ f = right;
+ f = bot;
+ }
+ {
+ Function2<AToB, AToB> f; // Left
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = left;
+ f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = bot;
+ }
+ {
+ Function2<BToA, BToA> f; // Right
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = right;
+ f = bot;
+ }
+ {
+ Function2<BToA, AToB> f; // Bot
+ f = bot;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ }
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_higherOrderFunctionLiteral2() {
checkFile('''
- main() {
- bool b = true;
- num x = b ? 1 : 2.3;
- int y = /*info:ASSIGNMENT_CAST*/b ? 1 : 2.3;
- String z = !b ? "hello" : null;
- z = b ? null : "hello";
- }
- ''');
- });
+class A {}
+class B extends A {}
- // This is a regression test for https://github.com/dart-lang/sdk/issues/25071
- test('unbound redirecting constructor', () {
+typedef T Function2<S, T>(S z);
+
+typedef A BToA(B x); // Top of the base lattice
+typedef B AToB(A x); // Bot of the base lattice
+
+Function2<B, A> top(AToB f) => f;
+Function2<A, B> left(AToB f) => f;
+Function2<B, A> right(BToA f) => f;
+Function2<A, B> bot_(BToA f) => /*warning:DOWN_CAST_COMPOSITE*/f;
+Function2<A, B> bot(BToA f) => f as Function2<A, B>;
+
+void main() {
+ {
+ Function2<AToB, BToA> f; // Top
+ f = top;
+ f = left;
+ f = right;
+ f = bot;
+ }
+ {
+ Function2<AToB, AToB> f; // Left
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = left;
+ f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = bot;
+ }
+ {
+ Function2<BToA, BToA> f; // Right
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = right;
+ f = bot;
+ }
+ {
+ Function2<BToA, AToB> f; // Bot
+ f = bot;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ }
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_higherOrderFunctionLiteral3() {
checkFile('''
- class Foo {
- Foo() : /*severe:REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR*/this.init();
- }
- ''');
- });
+class A {}
+class B extends A {}
- test('redirecting constructor', () {
+typedef T Function2<S, T>(S z);
+
+typedef A BToA(B x); // Top of the base lattice
+typedef B AToB(A x); // Bot of the base lattice
+
+BToA top(Function2<A, B> f) => f;
+AToB left(Function2<A, B> f) => f;
+BToA right(Function2<B, A> f) => f;
+AToB bot_(Function2<B, A> f) => /*warning:DOWN_CAST_COMPOSITE*/f;
+AToB bot(Function2<B, A> f) => f as AToB;
+
+void main() {
+ {
+ Function2<AToB, BToA> f; // Top
+ f = top;
+ f = left;
+ f = right;
+ f = bot;
+ }
+ {
+ Function2<AToB, AToB> f; // Left
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = left;
+ f = /*severe:STATIC_TYPE_ERROR*/right;
+ f = bot;
+ }
+ {
+ Function2<BToA, BToA> f; // Right
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = right;
+ f = bot;
+ }
+ {
+ Function2<BToA, AToB> f; // Bot
+ f = bot;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ f = /*severe:STATIC_TYPE_ERROR*/top;
+ f = /*severe:STATIC_TYPE_ERROR*/left;
+ }
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_higherOrderFunctionVariables() {
checkFile('''
- class A {
- A(A x) {}
- A.two() : this(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
- }
- ''');
- });
+class A {}
+class B extends A {}
- test('super constructor', () {
+typedef T Function2<S, T>(S z);
+
+void main() {
+ {
+ Function2<Function2<A, B>, Function2<B, A>> top;
+ Function2<Function2<B, A>, Function2<B, A>> right;
+ Function2<Function2<A, B>, Function2<A, B>> left;
+ Function2<Function2<B, A>, Function2<A, B>> bot;
+
+ top = right;
+ top = bot;
+ top = top;
+ top = left;
+
+ left = /*warning:DOWN_CAST_COMPOSITE*/top;
+ left = left;
+ left =
+ /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/right;
+ left = bot;
+
+ right = /*warning:DOWN_CAST_COMPOSITE*/top;
+ right =
+ /*warning:DOWN_CAST_COMPOSITE should be severe:STATIC_TYPE_ERROR*/left;
+ right = right;
+ right = bot;
+
+ bot = /*warning:DOWN_CAST_COMPOSITE*/top;
+ bot = /*warning:DOWN_CAST_COMPOSITE*/left;
+ bot = /*warning:DOWN_CAST_COMPOSITE*/right;
+ bot = bot;
+ }
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_instanceMethodVariance() {
checkFile('''
- class A { A(A x) {} }
- class B extends A {
- B() : super(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
- }
- ''');
- });
+class A {}
+class B extends A {}
- test('factory constructor downcast', () {
+class C {
+ A top(B x) => x;
+ B left(B x) => x;
+ A right(A x) => x;
+ B bot(A x) => x as B;
+}
+
+typedef T Function2<S, T>(S z);
+
+void main() {
+ C c = new C();
+ {
+ Function2<B, A> f;
+ f = c.top;
+ f = c.left;
+ f = c.right;
+ f = c.bot;
+ }
+ {
+ Function2<B, B> f;
+ f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
+ f = c.left;
+ f = /*warning:DOWN_CAST_COMPOSITE*/c.right;
+ f = c.bot;
+ }
+ {
+ Function2<A, A> f;
+ f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
+ f = /*warning:DOWN_CAST_COMPOSITE*/c.left;
+ f = c.right;
+ f = c.bot;
+ }
+ {
+ Function2<A, B> f;
+ f = /*warning:DOWN_CAST_COMPOSITE*/c.top;
+ f = /*warning:DOWN_CAST_COMPOSITE*/c.left;
+ f = /*warning:DOWN_CAST_COMPOSITE*/c.right;
+ f = c.bot;
+ }
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_intAndObject() {
+ checkFile('''
+typedef Object Top(int x); // Top of the lattice
+typedef int Left(int x); // Left branch
+typedef int Left2(int x); // Left branch
+typedef Object Right(Object x); // Right branch
+typedef int Bot(Object x); // Bottom of the lattice
+
+Object globalTop(int x) => x;
+int globalLeft(int x) => x;
+Object globalRight(Object x) => x;
+int bot_(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
+int globalBot(Object x) => x as int;
+
+void main() {
+ // Note: use locals so we only know the type, not that it's a specific
+ // function declaration. (we can issue better errors in that case.)
+ var top = globalTop;
+ var left = globalLeft;
+ var right = globalRight;
+ var bot = globalBot;
+
+ { // Check typedef equality
+ Left f = left;
+ Left2 g = f;
+ }
+ {
+ Top f;
+ f = top;
+ f = left;
+ f = right;
+ f = bot;
+ }
+ {
+ Left f;
+ f = /*warning:DOWN_CAST_COMPOSITE*/top;
+ f = left;
+ f = /*warning:DOWN_CAST_COMPOSITE*/right; // Should we reject this?
+ f = bot;
+ }
+ {
+ Right f;
+ f = /*warning:DOWN_CAST_COMPOSITE*/top;
+ f = /*warning:DOWN_CAST_COMPOSITE*/left; // Should we reject this?
+ f = right;
+ f = bot;
+ }
+ {
+ Bot f;
+ f = /*warning:DOWN_CAST_COMPOSITE*/top;
+ f = /*warning:DOWN_CAST_COMPOSITE*/left;
+ f = /*warning:DOWN_CAST_COMPOSITE*/right;
+ f = bot;
+ }
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_namedAndOptionalParameters() {
+ checkFile('''
+class A {}
+
+typedef A FR(A x);
+typedef A FO([A x]);
+typedef A FN({A x});
+typedef A FRR(A x, A y);
+typedef A FRO(A x, [A y]);
+typedef A FRN(A x, {A n});
+typedef A FOO([A x, A y]);
+typedef A FNN({A x, A y});
+typedef A FNNN({A z, A y, A x});
+
+void main() {
+ FR r;
+ FO o;
+ FN n;
+ FRR rr;
+ FRO ro;
+ FRN rn;
+ FOO oo;
+ FNN nn;
+ FNNN nnn;
+
+ r = r;
+ r = o;
+ r = /*warning:INVALID_ASSIGNMENT*/n;
+ r = /*warning:INVALID_ASSIGNMENT*/rr;
+ r = ro;
+ r = rn;
+ r = oo;
+ r = /*warning:INVALID_ASSIGNMENT*/nn;
+ r = /*warning:INVALID_ASSIGNMENT*/nnn;
+
+ o = /*warning:DOWN_CAST_COMPOSITE*/r;
+ o = o;
+ o = /*warning:INVALID_ASSIGNMENT*/n;
+ o = /*warning:INVALID_ASSIGNMENT*/rr;
+ o = /*warning:INVALID_ASSIGNMENT*/ro;
+ o = /*warning:INVALID_ASSIGNMENT*/rn;
+ o = oo;
+ o = /*warning:INVALID_ASSIGNMENT*/nn;
+ o = /*warning:INVALID_ASSIGNMENT*/nnn;
+
+ n = /*warning:INVALID_ASSIGNMENT*/r;
+ n = /*warning:INVALID_ASSIGNMENT*/o;
+ n = n;
+ n = /*warning:INVALID_ASSIGNMENT*/rr;
+ n = /*warning:INVALID_ASSIGNMENT*/ro;
+ n = /*warning:INVALID_ASSIGNMENT*/rn;
+ n = /*warning:INVALID_ASSIGNMENT*/oo;
+ n = nn;
+ n = nnn;
+
+ rr = /*warning:INVALID_ASSIGNMENT*/r;
+ rr = /*warning:INVALID_ASSIGNMENT*/o;
+ rr = /*warning:INVALID_ASSIGNMENT*/n;
+ rr = rr;
+ rr = ro;
+ rr = /*warning:INVALID_ASSIGNMENT*/rn;
+ rr = oo;
+ rr = /*warning:INVALID_ASSIGNMENT*/nn;
+ rr = /*warning:INVALID_ASSIGNMENT*/nnn;
+
+ ro = /*warning:DOWN_CAST_COMPOSITE*/r;
+ ro = /*warning:INVALID_ASSIGNMENT*/o;
+ ro = /*warning:INVALID_ASSIGNMENT*/n;
+ ro = /*warning:DOWN_CAST_COMPOSITE*/rr;
+ ro = ro;
+ ro = /*warning:INVALID_ASSIGNMENT*/rn;
+ ro = oo;
+ ro = /*warning:INVALID_ASSIGNMENT*/nn;
+ ro = /*warning:INVALID_ASSIGNMENT*/nnn;
+
+ rn = /*warning:DOWN_CAST_COMPOSITE*/r;
+ rn = /*warning:INVALID_ASSIGNMENT*/o;
+ rn = /*warning:INVALID_ASSIGNMENT*/n;
+ rn = /*warning:INVALID_ASSIGNMENT*/rr;
+ rn = /*warning:INVALID_ASSIGNMENT*/ro;
+ rn = rn;
+ rn = /*warning:INVALID_ASSIGNMENT*/oo;
+ rn = /*warning:INVALID_ASSIGNMENT*/nn;
+ rn = /*warning:INVALID_ASSIGNMENT*/nnn;
+
+ oo = /*warning:DOWN_CAST_COMPOSITE*/r;
+ oo = /*warning:DOWN_CAST_COMPOSITE*/o;
+ oo = /*warning:INVALID_ASSIGNMENT*/n;
+ oo = /*warning:DOWN_CAST_COMPOSITE*/rr;
+ oo = /*warning:DOWN_CAST_COMPOSITE*/ro;
+ oo = /*warning:INVALID_ASSIGNMENT*/rn;
+ oo = oo;
+ oo = /*warning:INVALID_ASSIGNMENT*/nn;
+ oo = /*warning:INVALID_ASSIGNMENT*/nnn;
+
+ nn = /*warning:INVALID_ASSIGNMENT*/r;
+ nn = /*warning:INVALID_ASSIGNMENT*/o;
+ nn = /*warning:DOWN_CAST_COMPOSITE*/n;
+ nn = /*warning:INVALID_ASSIGNMENT*/rr;
+ nn = /*warning:INVALID_ASSIGNMENT*/ro;
+ nn = /*warning:INVALID_ASSIGNMENT*/rn;
+ nn = /*warning:INVALID_ASSIGNMENT*/oo;
+ nn = nn;
+ nn = nnn;
+
+ nnn = /*warning:INVALID_ASSIGNMENT*/r;
+ nnn = /*warning:INVALID_ASSIGNMENT*/o;
+ nnn = /*warning:DOWN_CAST_COMPOSITE*/n;
+ nnn = /*warning:INVALID_ASSIGNMENT*/rr;
+ nnn = /*warning:INVALID_ASSIGNMENT*/ro;
+ nnn = /*warning:INVALID_ASSIGNMENT*/rn;
+ nnn = /*warning:INVALID_ASSIGNMENT*/oo;
+ nnn = /*warning:DOWN_CAST_COMPOSITE*/nn;
+ nnn = nnn;
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_objectsWithCallMethods() {
+ checkFile('''
+typedef int I2I(int x);
+typedef num N2N(num x);
+class A {
+ int call(int x) => x;
+}
+class B {
+ num call(num x) => x;
+}
+int i2i(int x) => x;
+num n2n(num x) => x;
+void main() {
+ {
+ I2I f;
+ f = new A();
+ f = /*warning:INVALID_ASSIGNMENT*/new B();
+ f = i2i;
+ f = /*severe:STATIC_TYPE_ERROR*/n2n;
+ f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
+ f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
+ }
+ {
+ N2N f;
+ f = /*warning:INVALID_ASSIGNMENT*/new A();
+ f = new B();
+ f = /*severe:STATIC_TYPE_ERROR*/i2i;
+ f = n2n;
+ f = /*warning:DOWN_CAST_COMPOSITE*/i2i as Object;
+ f = /*warning:DOWN_CAST_COMPOSITE*/n2n as Function;
+ }
+ {
+ A f;
+ f = new A();
+ f = /*warning:INVALID_ASSIGNMENT*/new B();
+ f = /*warning:INVALID_ASSIGNMENT*/i2i;
+ f = /*warning:INVALID_ASSIGNMENT*/n2n;
+ f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
+ f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
+ }
+ {
+ B f;
+ f = /*warning:INVALID_ASSIGNMENT*/new A();
+ f = new B();
+ f = /*warning:INVALID_ASSIGNMENT*/i2i;
+ f = /*warning:INVALID_ASSIGNMENT*/n2n;
+ f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
+ f = /*info:DOWN_CAST_IMPLICIT*/n2n as Function;
+ }
+ {
+ Function f;
+ f = new A();
+ f = new B();
+ f = i2i;
+ f = n2n;
+ f = /*info:DOWN_CAST_IMPLICIT*/i2i as Object;
+ f = (n2n as Function);
+ }
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_staticMethodVariance() {
+ checkFile('''
+class A {}
+class B extends A {}
+
+class C {
+ static A top(B x) => x;
+ static B left(B x) => x;
+ static A right(A x) => x;
+ static B bot(A x) => x as B;
+}
+
+typedef T Function2<S, T>(S z);
+
+void main() {
+ {
+ Function2<B, A> f;
+ f = C.top;
+ f = C.left;
+ f = C.right;
+ f = C.bot;
+ }
+ {
+ Function2<B, B> f;
+ f = /*severe:STATIC_TYPE_ERROR*/C.top;
+ f = C.left;
+ f = /*severe:STATIC_TYPE_ERROR*/C.right;
+ f = C.bot;
+ }
+ {
+ Function2<A, A> f;
+ f = /*severe:STATIC_TYPE_ERROR*/C.top;
+ f = /*severe:STATIC_TYPE_ERROR*/C.left;
+ f = C.right;
+ f = C.bot;
+ }
+ {
+ Function2<A, B> f;
+ f = /*severe:STATIC_TYPE_ERROR*/C.top;
+ f = /*severe:STATIC_TYPE_ERROR*/C.left;
+ f = /*severe:STATIC_TYPE_ERROR*/C.right;
+ f = C.bot;
+ }
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_subtypeOfUniversalType() {
+ checkFile('''
+void main() {
+ nonGenericFn(x) => null;
+ {
+ /*=R*/ f/*<P, R>*/(/*=P*/ p) => null;
+ /*=T*/ g/*<S, T>*/(/*=S*/ s) => null;
+
+ var local = f;
+ local = g; // valid
+
+ // Non-generic function cannot subtype a generic one.
+ local = /*warning:INVALID_ASSIGNMENT*/(x) => null;
+ local = /*warning:INVALID_ASSIGNMENT*/nonGenericFn;
+ }
+ {
+ Iterable/*<R>*/ f/*<P, R>*/(List/*<P>*/ p) => null;
+ List/*<T>*/ g/*<S, T>*/(Iterable/*<S>*/ s) => null;
+
+ var local = f;
+ local = g; // valid
+
+ var local2 = g;
+ local = local2;
+ local2 = /*severe:STATIC_TYPE_ERROR*/f;
+ local2 = /*warning:DOWN_CAST_COMPOSITE*/local;
+
+ // Non-generic function cannot subtype a generic one.
+ local = /*warning:INVALID_ASSIGNMENT*/(x) => null;
+ local = /*warning:INVALID_ASSIGNMENT*/nonGenericFn;
+ }
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_uninferredClosure() {
+ checkFile('''
+typedef num Num2Num(num x);
+void main() {
+ Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int x) { return x; };
+ print(g(42));
+}
+''');
+ }
+
+ void test_functionTypingAndSubtyping_void() {
+ checkFile('''
+class A {
+ void bar() => null;
+ void foo() => bar(); // allowed
+}
+''');
+ }
+
+ void test_genericClassMethodOverride() {
+ checkFile('''
+class A {}
+class B extends A {}
+
+class Base<T extends B> {
+ T foo() => null;
+}
+
+class Derived<S extends A> extends Base<B> {
+ /*severe:INVALID_METHOD_OVERRIDE*/S
+ /*warning:INVALID_METHOD_OVERRIDE_RETURN_TYPE*/foo() => null;
+}
+
+class Derived2<S extends B> extends Base<B> {
+ S foo() => null;
+}
+''');
+ }
+
+ void test_genericFunctionWrongNumberOfArguments() {
checkFile(r'''
- class Animal {
- Animal();
- factory Animal.cat() => new Cat();
- }
+/*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x;
+/*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x;
- class Cat extends Animal {}
+main() {
+ String x;
+ // resolving these shouldn't crash.
+ foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
+ x = foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/('1', '2', '3');
+ foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
+ x = foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/('1');
+ x = /*info:DYNAMIC_CAST*/foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
+ x = /*info:DYNAMIC_CAST*/foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
- void main() {
- Cat c = /*info:ASSIGNMENT_CAST*/new Animal.cat();
- c = /*severe:STATIC_TYPE_ERROR*/new Animal();
- }''');
- });
+ // named arguments
+ bar(y: 1, x: 2, /*warning:UNDEFINED_NAMED_PARAMETER*/z: 3);
+ x = bar(/*warning:UNDEFINED_NAMED_PARAMETER*/z: '1', x: '2', y: '3');
+ bar(y: 1);
+ x = bar(x: '1', /*warning:UNDEFINED_NAMED_PARAMETER*/z: 42);
+ x = /*info:DYNAMIC_CAST*/bar(y: 1, x: 2, /*warning:UNDEFINED_NAMED_PARAMETER*/z: 3);
+ x = /*info:DYNAMIC_CAST*/bar(x: 1);
+}
+''');
+ }
- test('field/field override', () {
+ void test_genericMethodOverride() {
checkFile('''
- class A {}
- class B extends A {}
- class C extends B {}
+class Future<T> {
+ /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
+}
- class Base {
- B f1;
- B f2;
- B f3;
- B f4;
- }
+class DerivedFuture<T> extends Future<T> {
+ /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
+}
- class Child extends Base {
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
- /*severe:INVALID_FIELD_OVERRIDE*/var f3;
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic f4;
- }
+class DerivedFuture2<A> extends Future<A> {
+ /*=B*/ then/*<B>*/(/*=B*/ onValue(A a)) => null;
+}
- class Child2 implements Base {
- /*severe:INVALID_METHOD_OVERRIDE*/A f1; // invalid for getter
- /*severe:INVALID_METHOD_OVERRIDE*/C f2; // invalid for setter
- var f3;
- /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic f4;
- }
- ''');
- });
+class DerivedFuture3<T> extends Future<T> {
+ /*=S*/ then/*<S>*/(Object onValue(T t)) => null;
+}
- test('private override', () {
- addFile(
- '''
- import 'main.dart' as main;
+class DerivedFuture4<A> extends Future<A> {
+ /*=B*/ then/*<B>*/(Object onValue(A a)) => null;
+}
+''');
+ }
- class Base {
- var f1;
- var _f2;
- var _f3;
- get _f4 => null;
-
- int _m1() => null;
- }
-
- class GrandChild extends main.Child {
- /*severe:INVALID_FIELD_OVERRIDE*/var _f2;
- /*severe:INVALID_FIELD_OVERRIDE*/var _f3;
- var _f4;
-
- /*severe:INVALID_METHOD_OVERRIDE*/String
- /*warning:INVALID_METHOD_OVERRIDE_RETURN_TYPE*/_m1() => null;
- }
- ''',
- name: '/helper.dart');
+ void test_getterGetterOverride() {
checkFile('''
- import 'helper.dart' as helper;
+class A {}
+class B extends A {}
+class C extends B {}
- class Child extends helper.Base {
- /*severe:INVALID_FIELD_OVERRIDE*/var f1;
- var _f2;
- var _f4;
+abstract class Base {
+ B get f1;
+ B get f2;
+ B get f3;
+ B get f4;
+}
- String _m1() => null;
- }
- ''');
- });
+class Child extends Base {
+ /*severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
+ C get f2 => null;
+ get f3 => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
+}
+''');
+ }
- test('getter/getter override', () {
+ void test_getterOverride_fuzzyArrows() {
checkFile('''
- class A {}
- class B extends A {}
- class C extends B {}
+typedef void ToVoid<T>(T x);
- abstract class Base {
- B get f1;
- B get f2;
- B get f3;
- B get f4;
- }
+class F {
+ ToVoid<dynamic> get f => null;
+ ToVoid<int> get g => null;
+}
- class Child extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
- C get f2 => null;
- get f3 => null;
- /*severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
- }
- ''');
- });
+class G extends F {
+ ToVoid<int> get f => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
+}
- test('field/getter override', () {
+class H implements F {
+ ToVoid<int> get f => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
+}
+''');
+ }
+
+ void test_ifForDoWhileStatementsUseBooleanConversion() {
checkFile('''
- class A {}
- class B extends A {}
- class C extends B {}
+main() {
+ dynamic dyn = 42;
+ Object obj = 42;
+ int i = 42;
+ bool b = false;
- abstract class Base {
- B f1;
- B f2;
- B f3;
- B f4;
- }
+ if (b) {}
+ if (/*info:DYNAMIC_CAST*/dyn) {}
+ if (/*info:DOWN_CAST_IMPLICIT*/obj) {}
+ if (/*warning:NON_BOOL_CONDITION*/i) {}
- class Child extends Base {
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/C get f2 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/get f3 => null;
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
- }
+ while (b) {}
+ while (/*info:DYNAMIC_CAST*/dyn) {}
+ while (/*info:DOWN_CAST_IMPLICIT*/obj) {}
+ while (/*warning:NON_BOOL_CONDITION*/i) {}
- class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR*/Child2 implements Base {
- /*severe:INVALID_METHOD_OVERRIDE*/A get f1 => null;
- C get f2 => null;
- get f3 => null;
- /*severe:INVALID_METHOD_OVERRIDE*/dynamic get f4 => null;
- }
- ''');
- });
+ do {} while (b);
+ do {} while (/*info:DYNAMIC_CAST*/dyn);
+ do {} while (/*info:DOWN_CAST_IMPLICIT*/obj);
+ do {} while (/*warning:NON_BOOL_CONDITION*/i);
- test('setter/setter override', () {
+ for (;b;) {}
+ for (;/*info:DYNAMIC_CAST*/dyn;) {}
+ for (;/*info:DOWN_CAST_IMPLICIT*/obj;) {}
+ for (;/*warning:NON_BOOL_CONDITION*/i;) {}
+}
+''');
+ }
+
+ void test_invalidOverrides_baseClassOverrideToChildInterface() {
checkFile('''
- class A {}
- class B extends A {}
- class C extends B {}
+class A {}
+class B {}
- abstract class Base {
- void set f1(B value);
- void set f2(B value);
- void set f3(B value);
- void set f4(B value);
- void set f5(B value);
- }
+abstract class I {
+ m(A a);
+}
- class Child extends Base {
- void set f1(A value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
- void set f3(value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
- set f5(B value) {}
- }
- ''');
- });
+class Base {
+ m(B a) {}
+}
- test('field/setter override', () {
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base implements I {}
+''');
+ }
+
+ void test_invalidOverrides_childOverride() {
checkFile('''
- class A {}
- class B extends A {}
- class C extends B {}
+class A {}
+class B {}
- class Base {
- B f1;
- B f2;
- B f3;
- B f4;
- B f5;
- }
+class Base {
+ A f;
+}
- class Child extends Base {
- /*severe:INVALID_FIELD_OVERRIDE*/B get f1 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/B get f2 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/B get f3 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/B get f4 => null;
- /*severe:INVALID_FIELD_OVERRIDE*/B get f5 => null;
+class T1 extends Base {
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B get
+ /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f => null;
+}
- /*severe:INVALID_FIELD_OVERRIDE*/void set f1(A value) {}
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
- /*severe:INVALID_FIELD_OVERRIDE*/void set f3(value) {}
- /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
- /*severe:INVALID_FIELD_OVERRIDE*/set f5(B value) {}
- }
+class T2 extends Base {
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/set f(
+ /*warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/B b) => null;
+}
- class Child2 implements Base {
- B get f1 => null;
- B get f2 => null;
- B get f3 => null;
- B get f4 => null;
- B get f5 => null;
+class T3 extends Base {
+ /*severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/final B
+ /*warning:FINAL_NOT_INITIALIZED, warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f;
+}
+class T4 extends Base {
+ // two: one for the getter one for the setter.
+ /*severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B
+ /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE, warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/f;
+}
- void set f1(A value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
- void set f3(value) {}
- /*severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
- set f5(B value) {}
- }
- ''');
- });
+class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T5 implements Base {
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_METHOD_OVERRIDE*/B get
+ /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f => null;
+}
- test('method override', () {
+class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T6 implements Base {
+ /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_METHOD_OVERRIDE*/set f(
+ /*warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/B b) => null;
+}
+
+class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T7 implements Base {
+ /*severe:INVALID_METHOD_OVERRIDE*/final B
+ /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f = null;
+}
+class T8 implements Base {
+ // two: one for the getter one for the setter.
+ /*severe:INVALID_METHOD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B
+ /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE, warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/f;
+}
+''');
+ }
+
+ void test_invalidOverrides_childOverride2() {
checkFile('''
- class A {}
- class B extends A {}
- class C extends B {}
+class A {}
+class B {}
- class Base {
- B m1(B a) => null;
- B m2(B a) => null;
- B m3(B a) => null;
- B m4(B a) => null;
- B m5(B a) => null;
- B m6(B a) => null;
- }
+class Base {
+ m(A a) {}
+}
- class Child extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/A m1(A value) => null;
- /*severe:INVALID_METHOD_OVERRIDE*/C m2(C value) => null;
- /*severe:INVALID_METHOD_OVERRIDE*/A m3(C value) => null;
- C m4(A value) => null;
- m5(value) => null;
- /*severe:INVALID_METHOD_OVERRIDE*/dynamic m6(dynamic value) => null;
- }
- ''');
- });
+class Test extends Base {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+''');
+ }
- test('method override, fuzzy arrows', () {
+ void test_invalidOverrides_classOverrideOfInterface() {
checkFile('''
- abstract class A {
- bool operator ==(Object object);
- }
+class A {}
+class B {}
- class B implements A {}
+abstract class I {
+ m(A a);
+}
+class T1 implements I {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B 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', () {
+ void test_invalidOverrides_doubleOverride() {
checkFile('''
- typedef void ToVoid<T>(T x);
- class F {
- ToVoid<dynamic> get f => null;
- ToVoid<int> get g => null;
- }
+class A {}
+class B {}
- class G extends F {
- ToVoid<int> get f => null;
- /*severe:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
- }
+class Grandparent {
+ m(A a) {}
+}
+class Parent extends Grandparent {
+ m(A a) {}
+}
- class H implements F {
- ToVoid<int> get f => null;
- /*severe:INVALID_METHOD_OVERRIDE*/ToVoid<dynamic> get g => null;
- }
- ''');
- });
+class Test extends Parent {
+ // Reported only once
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+''');
+ }
- test('setter override, fuzzy arrows', () {
+ void test_invalidOverrides_doubleOverride2() {
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 A {}
+class B {}
- 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 Grandparent {
+ m(A a) {}
+}
+class Parent extends Grandparent {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
- 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) {}
- }
- ''');
- });
+class Test extends Parent {
+ m(B a) {}
+}
+''');
+ }
- test('field override, fuzzy arrows', () {
+ void test_invalidOverrides_grandChildOverride() {
checkFile('''
- typedef void ToVoid<T>(T x);
- class F {
- final ToVoid<dynamic> f = null;
- final ToVoid<int> g = null;
- }
+class A {}
+class B {}
- 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 Grandparent {
+ m(A a) {}
+ int x;
+}
+class Parent extends Grandparent {
+}
- class H implements F {
- final ToVoid<int> f = null;
- /*severe:INVALID_METHOD_OVERRIDE*/final ToVoid<dynamic> g = null;
- }
- ''');
- });
+class Test extends Parent {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+ /*severe:INVALID_FIELD_OVERRIDE*/int x;
+}
+''');
+ }
- test('generic class method override', () {
+ void test_invalidOverrides_mixinOverrideOfInterface() {
checkFile('''
- class A {}
- class B extends A {}
+class A {}
+class B {}
- class Base<T extends B> {
- T foo() => null;
- }
+abstract class I {
+ m(A a);
+}
- class Derived<S extends A> extends Base<B> {
- /*severe:INVALID_METHOD_OVERRIDE*/S
- /*warning:INVALID_METHOD_OVERRIDE_RETURN_TYPE*/foo() => null;
- }
+class M {
+ m(B a) {}
+}
- class Derived2<S extends B> extends Base<B> {
- S foo() => null;
- }
- ''');
- });
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I {}
+''');
+ }
- test('generic method override', () {
+ void test_invalidOverrides_mixinOverrideToBase() {
checkFile('''
- class Future<T> {
- /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
- }
+class A {}
+class B {}
- class DerivedFuture<T> extends Future<T> {
- /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
- }
+class Base {
+ m(A a) {}
+ int x;
+}
- class DerivedFuture2<A> extends Future<A> {
- /*=B*/ then/*<B>*/(/*=B*/ onValue(A a)) => null;
- }
+class M1 {
+ m(B a) {}
+}
- class DerivedFuture3<T> extends Future<T> {
- /*=S*/ then/*<S>*/(Object onValue(T t)) => null;
- }
+class M2 {
+ int x;
+}
- class DerivedFuture4<A> extends Future<A> {
- /*=B*/ then/*<B>*/(Object onValue(A a)) => null;
- }
- ''');
- });
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with /*severe:INVALID_METHOD_OVERRIDE*/M1 {}
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2 extends Base
+ with /*severe:INVALID_METHOD_OVERRIDE*/M1, /*severe:INVALID_FIELD_OVERRIDE*/M2 {}
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T3 extends Base
+ with /*severe:INVALID_FIELD_OVERRIDE*/M2, /*severe:INVALID_METHOD_OVERRIDE*/M1 {}
+''');
+ }
- test('generic function wrong number of arguments', () {
- checkFile(r'''
- /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x;
- /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x;
-
- main() {
- String x;
- // resolving these shouldn't crash.
- foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
- x = foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/('1', '2', '3');
- foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
- x = foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/('1');
- x = /*info:DYNAMIC_CAST*/foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
- x = /*info:DYNAMIC_CAST*/foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
-
- // named arguments
- bar(y: 1, x: 2, /*warning:UNDEFINED_NAMED_PARAMETER*/z: 3);
- x = bar(/*warning:UNDEFINED_NAMED_PARAMETER*/z: '1', x: '2', y: '3');
- bar(y: 1);
- x = bar(x: '1', /*warning:UNDEFINED_NAMED_PARAMETER*/z: 42);
- x = /*info:DYNAMIC_CAST*/bar(y: 1, x: 2, /*warning:UNDEFINED_NAMED_PARAMETER*/z: 3);
- x = /*info:DYNAMIC_CAST*/bar(x: 1);
- }
- ''');
- });
-
- test('type promotion from dynamic', () {
- checkFile(r'''
- f() {
- dynamic x;
- if (x is int) {
- int y = x;
- String z = /*warning:INVALID_ASSIGNMENT*/x;
- }
- }
- g() {
- Object x;
- if (x is int) {
- int y = x;
- String z = /*warning:INVALID_ASSIGNMENT*/x;
- }
- }
- ''');
- });
-
- test('unary operators', () {
+ void test_invalidOverrides_mixinOverrideToMixin() {
checkFile('''
- class A {
- A operator ~() => null;
- A operator +(int x) => null;
- A operator -(int x) => null;
- A operator -() => null;
- }
+class A {}
+class B {}
- foo() => new A();
+class Base {
+}
- test() {
- A a = new A();
- var c = foo();
- dynamic d;
+class M1 {
+ m(B a) {}
+ int x;
+}
- ~a;
- (/*info:DYNAMIC_INVOKE*/~d);
+class M2 {
+ m(A a) {}
+ int x;
+}
- !/*warning:NON_BOOL_NEGATION_EXPRESSION*/a;
- !/*info:DYNAMIC_CAST*/d;
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with M1,
+ /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_FIELD_OVERRIDE*/M2 {}
+''');
+ }
- -a;
- (/*info:DYNAMIC_INVOKE*/-d);
-
- ++a;
- --a;
- (/*info:DYNAMIC_INVOKE*/++d);
- (/*info:DYNAMIC_INVOKE*/--d);
-
- a++;
- a--;
- (/*info:DYNAMIC_INVOKE*/d++);
- (/*info:DYNAMIC_INVOKE*/d--);
- }''');
- });
-
- test('binary and index operators', () {
- checkFile('''
- class A {
- A operator *(B b) => null;
- A operator /(B b) => null;
- A operator ~/(B b) => null;
- A operator %(B b) => null;
- A operator +(B b) => null;
- A operator -(B b) => null;
- A operator <<(B b) => null;
- A operator >>(B b) => null;
- A operator &(B b) => null;
- A operator ^(B b) => null;
- A operator |(B b) => null;
- A operator[](B b) => null;
- }
-
- class B {
- A operator -(B b) => null;
- }
-
- foo() => new A();
-
- test() {
- A a = new A();
- B b = new B();
- var c = foo();
- a = a * b;
- a = a * /*info:DYNAMIC_CAST*/c;
- a = a / b;
- a = a ~/ b;
- a = a % b;
- a = a + b;
- a = a + /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
- a = a - b;
- b = /*warning:INVALID_ASSIGNMENT*/b - b;
- a = a << b;
- a = a >> b;
- a = a & b;
- a = a ^ b;
- a = a | b;
- c = (/*info:DYNAMIC_INVOKE*/c + b);
-
- String x = 'hello';
- int y = 42;
- x = x + x;
- x = x + /*info:DYNAMIC_CAST*/c;
- x = x + /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y;
-
- bool p = true;
- p = p && p;
- p = p && /*info:DYNAMIC_CAST*/c;
- p = (/*info:DYNAMIC_CAST*/c) && p;
- p = (/*info:DYNAMIC_CAST*/c) && /*info:DYNAMIC_CAST*/c;
- p = /*warning:NON_BOOL_OPERAND*/y && p;
- p = c == y;
-
- a = a[b];
- a = a[/*info:DYNAMIC_CAST*/c];
- c = (/*info:DYNAMIC_INVOKE*/c[b]);
- a[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/y];
- }
- ''');
- });
-
- test('null coalescing operator', () {
- checkFile('''
- class A {}
- class C<T> {}
- main() {
- A a, b;
- a ??= new A();
- b = b ?? new A();
-
- // downwards inference
- C<int> c, d;
- c ??= /*info:INFERRED_TYPE_ALLOCATION*/new C();
- d = d ?? /*info:INFERRED_TYPE_ALLOCATION*/new C();
- }
- ''');
- });
-
- test('compound assignments', () {
- checkFile('''
- class A {
- A operator *(B b) => null;
- A operator /(B b) => null;
- A operator ~/(B b) => null;
- A operator %(B b) => null;
- A operator +(B b) => null;
- A operator -(B b) => null;
- A operator <<(B b) => null;
- A operator >>(B b) => null;
- A operator &(B b) => null;
- A operator ^(B b) => null;
- A operator |(B b) => null;
- D operator [](B index) => null;
- void operator []=(B index, D value) => null;
- }
-
- class B {
- A operator -(B b) => null;
- }
-
- class D {
- D operator +(D d) => null;
- }
-
- foo() => new A();
-
- test() {
- int x = 0;
- x += 5;
- /*severe:STATIC_TYPE_ERROR*/x += 3.14;
-
- double y = 0.0;
- y += 5;
- y += 3.14;
-
- num z = 0;
- z += 5;
- z += 3.14;
-
- x = /*info:DOWN_CAST_IMPLICIT*/x + z;
- x += /*info:DOWN_CAST_IMPLICIT*/z;
- y = y + z;
- y += z;
-
- dynamic w = 42;
- x += /*info:DYNAMIC_CAST*/w;
- y += /*info:DYNAMIC_CAST*/w;
- z += /*info:DYNAMIC_CAST*/w;
-
- A a = new A();
- B b = new B();
- var c = foo();
- a = a * b;
- a *= b;
- a *= /*info:DYNAMIC_CAST*/c;
- a /= b;
- a ~/= b;
- a %= b;
- a += b;
- a += /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
- a -= b;
- /*severe:STATIC_TYPE_ERROR*/b -= /*warning:INVALID_ASSIGNMENT*/b;
- a <<= b;
- a >>= b;
- a &= b;
- a ^= b;
- a |= b;
- /*info:DYNAMIC_INVOKE*/c += b;
-
- var d = new D();
- a[b] += d;
- a[/*info:DYNAMIC_CAST*/c] += d;
- a[/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z] += d;
- a[b] += /*info:DYNAMIC_CAST*/c;
- a[b] += /*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/z;
- /*info:DYNAMIC_INVOKE,info:DYNAMIC_INVOKE*/c[b] += d;
- }
- ''');
- });
-
- test('super call placement', () {
- checkFile('''
- class Base {
- var x;
- Base() : x = print('Base.1') { print('Base.2'); }
- }
-
- class Derived extends Base {
- var y, z;
- Derived()
- : y = print('Derived.1'),
- /*severe:INVALID_SUPER_INVOCATION*/super(),
- z = print('Derived.2') {
- print('Derived.3');
- }
- }
-
- class Valid extends Base {
- var y, z;
- Valid()
- : y = print('Valid.1'),
- z = print('Valid.2'),
- super() {
- print('Valid.3');
- }
- }
-
- class AlsoValid extends Base {
- AlsoValid() : super();
- }
-
- main() => new Derived();
- ''');
- });
-
- test('for loop variable', () {
- checkFile('''
- foo() {
- for (int i = 0; i < 10; i++) {
- i = /*warning:INVALID_ASSIGNMENT*/"hi";
- }
- }
- bar() {
- for (var i = 0; i < 10; i++) {
- int j = i + 1;
- }
- }
- ''');
- });
-
- test('loadLibrary', () {
- addFile('''library lib1;''', name: '/lib1.dart');
- checkFile(r'''
- import 'lib1.dart' deferred as lib1;
- import 'dart:async' show Future;
- main() {
- Future f = lib1.loadLibrary();
- }''');
- });
-
- group('invalid overrides', () {
- test('child override', () {
- checkFile('''
- class A {}
- class B {}
-
- class Base {
- A f;
- }
-
- class T1 extends Base {
- /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B get
- /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f => null;
- }
-
- class T2 extends Base {
- /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/set f(
- /*warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/B b) => null;
- }
-
- class T3 extends Base {
- /*severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/final B
- /*warning:FINAL_NOT_INITIALIZED, warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f;
- }
- class T4 extends Base {
- // two: one for the getter one for the setter.
- /*severe:INVALID_FIELD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B
- /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE, warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/f;
- }
-
- class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T5 implements Base {
- /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_METHOD_OVERRIDE*/B get
- /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f => null;
- }
-
- class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T6 implements Base {
- /*warning:MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, severe:INVALID_METHOD_OVERRIDE*/set f(
- /*warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/B b) => null;
- }
-
- class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/T7 implements Base {
- /*severe:INVALID_METHOD_OVERRIDE*/final B
- /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE*/f = null;
- }
- class T8 implements Base {
- // two: one for the getter one for the setter.
- /*severe:INVALID_METHOD_OVERRIDE, severe:INVALID_METHOD_OVERRIDE*/B
- /*warning:INVALID_GETTER_OVERRIDE_RETURN_TYPE, warning:INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE*/f;
- }
- ''');
- });
-
- test('child override 2', () {
- checkFile('''
- class A {}
- class B {}
-
- class Base {
- m(A a) {}
- }
-
- class Test extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
- ''');
- });
- test('grandchild override', () {
- checkFile('''
- class A {}
- class B {}
-
- class Grandparent {
- m(A a) {}
- int x;
- }
- class Parent extends Grandparent {
- }
-
- class Test extends Parent {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- /*severe:INVALID_FIELD_OVERRIDE*/int x;
- }
- ''');
- });
-
- test('double override', () {
- checkFile('''
- class A {}
- class B {}
-
- class Grandparent {
- m(A a) {}
- }
- class Parent extends Grandparent {
- m(A a) {}
- }
-
- class Test extends Parent {
- // Reported only once
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
- ''');
- });
-
- test('double override 2', () {
- checkFile('''
- class A {}
- class B {}
-
- class Grandparent {
- m(A a) {}
- }
- class Parent extends Grandparent {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
-
- class Test extends Parent {
- m(B a) {}
- }
- ''');
- });
-
- test('mixin override to base', () {
- checkFile('''
- class A {}
- class B {}
-
- class Base {
- m(A a) {}
- int x;
- }
-
- class M1 {
- m(B a) {}
- }
-
- class M2 {
- int x;
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
- with /*severe:INVALID_METHOD_OVERRIDE*/M1 {}
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2 extends Base
- with /*severe:INVALID_METHOD_OVERRIDE*/M1, /*severe:INVALID_FIELD_OVERRIDE*/M2 {}
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T3 extends Base
- with /*severe:INVALID_FIELD_OVERRIDE*/M2, /*severe:INVALID_METHOD_OVERRIDE*/M1 {}
- ''');
- });
-
- test('mixin override to mixin', () {
- checkFile('''
- class A {}
- class B {}
-
- class Base {
- }
-
- class M1 {
- m(B a) {}
- int x;
- }
-
- class M2 {
- m(A a) {}
- int x;
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
- with M1,
- /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_FIELD_OVERRIDE*/M2 {}
- ''');
- });
-
+ void test_invalidOverrides_noDuplicateMixinOverride() {
// This is a regression test for a bug in an earlier implementation were
// names were hiding errors if the first mixin override looked correct,
// but subsequent ones did not.
- test('no duplicate mixin override', () {
- checkFile('''
- class A {}
- class B {}
+ checkFile('''
+class A {}
+class B {}
- class Base {
- m(A a) {}
- }
+class Base {
+ m(A a) {}
+}
- class M1 {
- m(A a) {}
- }
+class M1 {
+ m(A a) {}
+}
- class M2 {
- m(B a) {}
- }
+class M2 {
+ m(B a) {}
+}
- class M3 {
- m(B a) {}
- }
+class M3 {
+ m(B a) {}
+}
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
- with M1, /*severe:INVALID_METHOD_OVERRIDE*/M2, M3 {}
- ''');
- });
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with M1, /*severe:INVALID_METHOD_OVERRIDE*/M2, M3 {}
+''');
+ }
- test('class override of interface', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I {
- m(A a);
- }
-
- class T1 implements I {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
- ''');
- });
-
- test('base class override to child interface', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I {
- m(A a);
- }
-
- class Base {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE*/extends Base implements I {}
- ''');
- });
-
- test('mixin override of interface', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I {
- m(A a);
- }
-
- class M {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I {}
- ''');
- });
-
+ void
+ test_invalidOverrides_noErrorsIfSubclassCorrectlyOverrideBaseAndInterface() {
// This is a case were it is incorrect to say that the base class
// incorrectly overrides the interface.
- test('no errors if subclass correctly overrides base and interface', () {
- checkFile('''
- class A {}
- class B {}
-
- class Base {
- m(A a) {}
- }
-
- class I1 {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE*/extends Base
- implements I1 {}
-
- class T2 extends Base implements I1 {
- m(a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T3
- extends Object with /*severe:INVALID_METHOD_OVERRIDE*/Base
- implements I1 {}
-
- class T4 extends Object with Base implements I1 {
- m(a) {}
- }
- ''');
- });
- });
-
- group('class override of grand interface', () {
- test('interface of interface of child', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
- abstract class I2 implements I1 {}
-
- class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
- ''');
- });
- test('superclass of interface of child', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
- abstract class I2 extends I1 {}
-
- class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
- ''');
- });
- test('mixin of interface of child', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class M1 {
- m(A a);
- }
- abstract class I2 extends Object with M1 {}
-
- class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
- ''');
- });
- test('interface of abstract superclass', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
- abstract class Base implements I1 {}
-
- class T1 extends Base {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
- ''');
- });
- test('interface of concrete superclass', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
-
- class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
- implements I1 {}
-
- class T1 extends Base {
- // not reported technically because if the class is concrete,
- // it should implement all its interfaces and hence it is
- // sufficient to check overrides against it.
- m(/*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
- ''');
- });
- });
-
- group('mixin override of grand interface', () {
- test('interface of interface of child', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
- abstract class I2 implements I1 {}
-
- class M {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I2 {}
- ''');
- });
- test('superclass of interface of child', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
- abstract class I2 extends I1 {}
-
- class M {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I2 {}
- ''');
- });
- test('mixin of interface of child', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class M1 {
- m(A a);
- }
- abstract class I2 extends Object with M1 {}
-
- class M {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I2 {}
- ''');
- });
- test('interface of abstract superclass', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
- abstract class Base implements I1 {}
-
- class M {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
- with /*severe:INVALID_METHOD_OVERRIDE*/M {}
- ''');
- });
- test('interface of concrete superclass', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
-
- class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
- implements I1 {}
-
- class M {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
- with M {}
- ''');
- });
- });
-
- group('superclass override of grand interface', () {
- test('interface of interface of child', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
- abstract class I2 implements I1 {}
-
- class Base {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE*/extends Base implements I2 {}
- ''');
- });
- test('superclass of interface of child', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
- abstract class I2 extends I1 {}
-
- class Base {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE*/extends Base
- implements I2 {}
- ''');
- });
- test('mixin of interface of child', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class M1 {
- m(A a);
- }
- abstract class I2 extends Object with M1 {}
-
- class Base {
- m(B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE*/extends Base
- implements I2 {}
- ''');
- });
- test('interface of abstract superclass', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
-
- abstract class Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
-
- class T1 extends Base {
- // we consider the base class incomplete because it is
- // abstract, so we report the error here too.
- // TODO(sigmund): consider tracking overrides in a fine-grain
- // manner, then this and the double-overrides would not be
- // reported.
- /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
- }
- ''');
- });
- test('interface of concrete superclass', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
-
- class Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
-
- class T1 extends Base {
- m(B a) {}
- }
- ''');
- });
- });
-
- group('no duplicate reports from overriding interfaces', () {
- test('type overrides same method in multiple interfaces', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
- abstract class I2 implements I1 {
- m(A a);
- }
-
- class Base {}
-
- class T1 implements I2 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
- ''');
- });
-
- test('type and base type override same method in interface', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
-
- class Base {
- m(B a) {}
- }
-
- // Note: no error reported in `extends Base` to avoid duplicating
- // the error in T1.
- class T1 extends Base implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
-
- // If there is no error in the class, we do report the error at
- // the base class:
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2
- /*severe:INVALID_METHOD_OVERRIDE*/extends Base
- implements I1 {}
- ''');
- });
-
- test('type and mixin override same method in interface', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
-
- class M {
- m(B a) {}
- }
-
- class T1 extends Object with M implements I1 {
- /*severe:INVALID_METHOD_OVERRIDE*/m(
- /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
- }
-
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2
- extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I1 {}
- ''');
- });
-
- test('two grand types override same method in interface', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
-
- class Grandparent {
- m(B a) {}
- }
-
- class Parent1 extends Grandparent {
- m(B a) {}
- }
- class Parent2 extends Grandparent {}
-
- // Note: otherwise both errors would be reported on this line
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE*/extends Parent1
- implements I1 {}
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2
- /*severe:INVALID_METHOD_OVERRIDE*/extends Parent2
- implements I1 {}
- ''');
- });
-
- test('two mixins override same method in interface', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
-
- class M1 {
- m(B a) {}
- }
-
- class M2 {
- m(B a) {}
- }
-
- // Here we want to report both, because the error location is
- // different.
- // TODO(sigmund): should we merge these as well?
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Object
- with /*severe:INVALID_METHOD_OVERRIDE*/M1,
- /*severe:INVALID_METHOD_OVERRIDE*/M2
- implements I1 {}
- ''');
- });
-
- test('base type and mixin override same method in interface', () {
- checkFile('''
- class A {}
- class B {}
-
- abstract class I1 {
- m(A a);
- }
-
- class Base {
- m(B a) {}
- }
-
- class M {
- m(B a) {}
- }
-
- // Here we want to report both, because the error location is
- // different.
- // TODO(sigmund): should we merge these as well?
- class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
- /*severe:INVALID_METHOD_OVERRIDE*/extends Base
- with /*severe:INVALID_METHOD_OVERRIDE*/M
- implements I1 {}
- ''');
- });
- });
-
- test('invalid runtime checks', () {
checkFile('''
- typedef int I2I(int x);
- typedef int D2I(x);
- typedef int II2I(int x, int y);
- typedef int DI2I(x, int y);
- typedef int ID2I(int x, y);
- typedef int DD2I(x, y);
+class A {}
+class B {}
- typedef I2D(int x);
- typedef D2D(x);
- typedef II2D(int x, int y);
- typedef DI2D(x, int y);
- typedef ID2D(int x, y);
- typedef DD2D(x, y);
+class Base {
+ m(A a) {}
+}
- int foo(int x) => x;
- int bar(int x, int y) => x + y;
+class I1 {
+ m(B a) {}
+}
- void main() {
- bool b;
- b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is I2I;
- b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is D2I;
- b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is I2D;
- b = foo is D2D;
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+ implements I1 {}
- b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is II2I;
- b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DI2I;
- b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is ID2I;
- b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is II2D;
- b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DD2I;
- b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DI2D;
- b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is ID2D;
- b = bar is DD2D;
+class T2 extends Base implements I1 {
+ m(a) {}
+}
- // For as, the validity of checks is deferred to runtime.
- Function f;
- f = foo as I2I;
- f = foo as D2I;
- f = foo as I2D;
- f = foo as D2D;
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T3
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/Base
+ implements I1 {}
- f = bar as II2I;
- f = bar as DI2I;
- f = bar as ID2I;
- f = bar as II2D;
- f = bar as DD2I;
- f = bar as DI2D;
- f = bar as ID2D;
- f = bar as DD2D;
- }
- ''');
- });
+class T4 extends Object with Base implements I1 {
+ m(a) {}
+}
+''');
+ }
- group('function modifiers', () {
- test('async', () {
- checkFile('''
- import 'dart:async';
- import 'dart:math' show Random;
+ void test_invalidRuntimeChecks() {
+ checkFile('''
+typedef int I2I(int x);
+typedef int D2I(x);
+typedef int II2I(int x, int y);
+typedef int DI2I(x, int y);
+typedef int ID2I(int x, y);
+typedef int DD2I(x, y);
- dynamic x;
+typedef I2D(int x);
+typedef D2D(x);
+typedef II2D(int x, int y);
+typedef DI2D(x, int y);
+typedef ID2D(int x, y);
+typedef DD2D(x, y);
- foo1() async => x;
- Future foo2() async => x;
- Future<int> foo3() async => /*info:DYNAMIC_CAST*/x;
- Future<int> foo4() async => new Future<int>.value(/*info:DYNAMIC_CAST*/x);
- Future<int> foo5() async =>
- /*warning:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
+int foo(int x) => x;
+int bar(int x, int y) => x + y;
- bar1() async { return x; }
- Future bar2() async { return x; }
- Future<int> bar3() async { return /*info:DYNAMIC_CAST*/x; }
- Future<int> bar4() async { return new Future<int>.value(/*info:DYNAMIC_CAST*/x); }
- Future<int> bar5() async {
- return /*warning:RETURN_OF_INVALID_TYPE*/new Future<String>.value(/*info:DYNAMIC_CAST*/x);
- }
+void main() {
+ bool b;
+ b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is I2I;
+ b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is D2I;
+ b = /*info:NON_GROUND_TYPE_CHECK_INFO*/foo is I2D;
+ b = foo is D2D;
- int y;
- Future<int> z;
+ b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is II2I;
+ b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DI2I;
+ b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is ID2I;
+ b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is II2D;
+ b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DD2I;
+ b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is DI2D;
+ b = /*info:NON_GROUND_TYPE_CHECK_INFO*/bar is ID2D;
+ b = bar is DD2D;
- baz() async {
- int a = /*info:DYNAMIC_CAST*/await x;
- int b = await y;
- int c = await z;
- String d = /*warning:INVALID_ASSIGNMENT*/await z;
- }
+ // For as, the validity of checks is deferred to runtime.
+ Function f;
+ f = foo as I2I;
+ f = foo as D2I;
+ f = foo as I2D;
+ f = foo as D2D;
- Future<bool> get issue_264 async {
- await 42;
- if (new Random().nextBool()) {
- return true;
- } else {
- return new Future<bool>.value(false);
- }
- }
- ''');
- });
+ f = bar as II2I;
+ f = bar as DI2I;
+ f = bar as ID2I;
+ f = bar as II2D;
+ f = bar as DD2I;
+ f = bar as DI2D;
+ f = bar as ID2D;
+ f = bar as DD2D;
+}
+''');
+ }
- test('async*', () {
- checkFile('''
- import 'dart:async';
+ void test_leastUpperBounds() {
+ checkFile('''
+typedef T Returns<T>();
- dynamic x;
+// regression test for https://github.com/dart-lang/sdk/issues/26094
+class A <S extends Returns<S>, T extends Returns<T>> {
+ int test(bool b) {
+ S s;
+ T t;
+ if (b) {
+ return /*warning:RETURN_OF_INVALID_TYPE*/b ? s : t;
+ } else {
+ return /*warning:RETURN_OF_INVALID_TYPE*/s ?? t;
+ }
+ }
+}
- bar1() async* { yield x; }
- Stream bar2() async* { yield x; }
- Stream<int> bar3() async* { yield /*info:DYNAMIC_CAST*/x; }
- Stream<int> bar4() async* { yield /*warning:YIELD_OF_INVALID_TYPE*/new Stream<int>(); }
+class B<S, T extends S> {
+ T t;
+ S s;
+ int test(bool b) {
+ return /*warning:RETURN_OF_INVALID_TYPE*/b ? t : s;
+ }
+}
- baz1() async* { yield* /*info:DYNAMIC_CAST*/x; }
- Stream baz2() async* { yield* /*info:DYNAMIC_CAST*/x; }
- Stream<int> baz3() async* { yield* /*warning:DOWN_CAST_COMPOSITE*/x; }
- Stream<int> baz4() async* { yield* new Stream<int>(); }
- Stream<int> baz5() async* { yield* /*info:INFERRED_TYPE_ALLOCATION*/new Stream(); }
- ''');
- });
+class C {
+ // Check that the least upper bound of two types with the same
+ // class but different type arguments produces the pointwise
+ // least upper bound of the type arguments
+ int test1(bool b) {
+ List<int> li;
+ List<double> ld;
+ return /*warning:RETURN_OF_INVALID_TYPE*/b ? li : ld;
+ }
+ // TODO(leafp): This case isn't handled yet. This test checks
+ // the case where two related classes are instantiated with related
+ // but different types.
+ Iterable<num> test2(bool b) {
+ List<int> li;
+ Iterable<double> id;
+ int x =
+ /*info:ASSIGNMENT_CAST should be warning:INVALID_ASSIGNMENT*/
+ b ? li : id;
+ return /*warning:DOWN_CAST_COMPOSITE should be pass*/b ? li : id;
+ }
+}
+''');
+ }
- test('sync*', () {
- checkFile('''
- dynamic x;
+ void test_loadLibrary() {
+ addFile('''library lib1;''', name: '/lib1.dart');
+ checkFile(r'''
+import 'lib1.dart' deferred as lib1;
+import 'dart:async' show Future;
+main() {
+ Future f = lib1.loadLibrary();
+}''');
+ }
- bar1() sync* { yield x; }
- Iterable bar2() sync* { yield x; }
- Iterable<int> bar3() sync* { yield /*info:DYNAMIC_CAST*/x; }
- Iterable<int> bar4() sync* { yield /*warning:YIELD_OF_INVALID_TYPE*/bar3(); }
+ void test_methodOverride() {
+ checkFile('''
+class A {}
+class B extends A {}
+class C extends B {}
- baz1() sync* { yield* /*info:DYNAMIC_CAST*/x; }
- Iterable baz2() sync* { yield* /*info:DYNAMIC_CAST*/x; }
- Iterable<int> baz3() sync* { yield* /*warning:DOWN_CAST_COMPOSITE*/x; }
- Iterable<int> baz4() sync* { yield* bar3(); }
- Iterable<int> baz5() sync* { yield* /*info:INFERRED_TYPE_ALLOCATION*/new List(); }
- ''');
- });
- });
+class Base {
+ B m1(B a) => null;
+ B m2(B a) => null;
+ B m3(B a) => null;
+ B m4(B a) => null;
+ B m5(B a) => null;
+ B m6(B a) => null;
+}
+
+class Child extends Base {
+ /*severe:INVALID_METHOD_OVERRIDE*/A m1(A value) => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/C m2(C value) => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/A m3(C value) => null;
+ C m4(A value) => null;
+ m5(value) => null;
+ /*severe:INVALID_METHOD_OVERRIDE*/dynamic m6(dynamic value) => null;
+}
+''');
+ }
+
+ void test_methodOverride_fuzzyArrows() {
+ 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) {}
+}
+''');
+ }
+
+ void test_mixinOverrideOfGrandInterface_interfaceOfAbstractSuperclass() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+abstract class Base implements I1 {}
+
+class M {
+ m(B a) {}
+}
+
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with /*severe:INVALID_METHOD_OVERRIDE*/M {}
+''');
+ }
+
+ void test_mixinOverrideOfGrandInterface_interfaceOfConcreteSuperclass() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+
+class /*warning:NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE*/Base
+ implements I1 {}
+
+class M {
+ m(B a) {}
+}
+
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Base
+ with M {}
+''');
+ }
+
+ void test_mixinOverrideOfGrandInterface_interfaceOfInterfaceOfChild() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+abstract class I2 implements I1 {}
+
+class M {
+ m(B a) {}
+}
+
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I2 {}
+''');
+ }
+
+ void test_mixinOverrideOfGrandInterface_mixinOfInterfaceOfChild() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class M1 {
+ m(A a);
+}
+abstract class I2 extends Object with M1 {}
+
+class M {
+ m(B a) {}
+}
+
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I2 {}
+''');
+ }
+
+ void test_mixinOverrideOfGrandInterface_superclassOfInterfaceOfChild() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+abstract class I2 extends I1 {}
+
+class M {
+ m(B a) {}
+}
+
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I2 {}
+''');
+ }
+
+ void
+ test_noDuplicateReportsFromOverridingInterfaces_baseTypeAndMixinOverrideSameMethodInInterface() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+
+class Base {
+ m(B a) {}
+}
+
+class M {
+ m(B a) {}
+}
+
+// Here we want to report both, because the error location is
+// different.
+// TODO(sigmund): should we merge these as well?
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+ with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I1 {}
+''');
+ }
+
+ void
+ test_noDuplicateReportsFromOverridingInterfaces_twoGrandTypesOverrideSameMethodInInterface() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+
+class Grandparent {
+ m(B a) {}
+}
+
+class Parent1 extends Grandparent {
+ m(B a) {}
+}
+class Parent2 extends Grandparent {}
+
+// Note: otherwise both errors would be reported on this line
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Parent1
+ implements I1 {}
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Parent2
+ implements I1 {}
+''');
+ }
+
+ void
+ test_noDuplicateReportsFromOverridingInterfaces_twoMixinsOverrideSameMethodInInterface() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+
+class M1 {
+ m(B a) {}
+}
+
+class M2 {
+ m(B a) {}
+}
+
+// Here we want to report both, because the error location is
+// different.
+// TODO(sigmund): should we merge these as well?
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1 extends Object
+ with /*severe:INVALID_METHOD_OVERRIDE*/M1,
+ /*severe:INVALID_METHOD_OVERRIDE*/M2
+ implements I1 {}
+''');
+ }
+
+ void
+ test_noDuplicateReportsFromOverridingInterfaces_typeAndBaseTypeOverrideSameMethodInInterface() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+
+class Base {
+ m(B a) {}
+}
+
+// Note: no error reported in `extends Base` to avoid duplicating
+// the error in T1.
+class T1 extends Base implements I1 {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+
+// If there is no error in the class, we do report the error at
+// the base class:
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+ implements I1 {}
+''');
+ }
+
+ void
+ test_noDuplicateReportsFromOverridingInterfaces_typeAndMixinOverrideSameMethodInInterface() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+
+class M {
+ m(B a) {}
+}
+
+class T1 extends Object with M implements I1 {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T2
+ extends Object with /*severe:INVALID_METHOD_OVERRIDE*/M
+ implements I1 {}
+''');
+ }
+
+ void
+ test_noDuplicateReportsFromOverridingInterfaces_typeOverridesSomeMethodInMultipleInterfaces() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+abstract class I2 implements I1 {
+ m(A a);
+}
+
+class Base {}
+
+class T1 implements I2 {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+''');
+ }
+
+ void test_nullCoalescingOperator() {
+ checkFile('''
+class A {}
+class C<T> {}
+main() {
+ A a, b;
+ a ??= new A();
+ b = b ?? new A();
+
+ // downwards inference
+ C<int> c, d;
+ c ??= /*info:INFERRED_TYPE_ALLOCATION*/new C();
+ d = d ?? /*info:INFERRED_TYPE_ALLOCATION*/new C();
+}
+''');
+ }
+
+ void test_privateOverride() {
+ addFile(
+ '''
+import 'main.dart' as main;
+
+class Base {
+ var f1;
+ var _f2;
+ var _f3;
+ get _f4 => null;
+
+ int _m1() => null;
+}
+
+class GrandChild extends main.Child {
+ /*severe:INVALID_FIELD_OVERRIDE*/var _f2;
+ /*severe:INVALID_FIELD_OVERRIDE*/var _f3;
+ var _f4;
+
+ /*severe:INVALID_METHOD_OVERRIDE*/String
+ /*warning:INVALID_METHOD_OVERRIDE_RETURN_TYPE*/_m1() => null;
+}
+''',
+ name: '/helper.dart');
+ checkFile('''
+import 'helper.dart' as helper;
+
+class Child extends helper.Base {
+ /*severe:INVALID_FIELD_OVERRIDE*/var f1;
+ var _f2;
+ var _f4;
+
+ String _m1() => null;
+}
+''');
+ }
+
+ void test_redirectingConstructor() {
+ checkFile('''
+class A {
+ A(A x) {}
+ A.two() : this(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+}
+''');
+ }
+
+ void test_relaxedCasts() {
+ checkFile('''
+class A {}
+
+class L<T> {}
+class M<T> extends L<T> {}
+// L<dynamic|Object>
+// / \
+// M<dynamic|Object> L<A>
+// \ /
+// M<A>
+// In normal Dart, there are additional edges
+// from M<A> to M<dynamic>
+// from L<A> to M<dynamic>
+// from L<A> to L<dynamic>
+void main() {
+ L lOfDs;
+ L<Object> lOfOs;
+ L<A> lOfAs;
+
+ M mOfDs;
+ M<Object> mOfOs;
+ M<A> mOfAs;
+
+ {
+ lOfDs = mOfDs;
+ lOfDs = mOfOs;
+ lOfDs = mOfAs;
+ lOfDs = lOfDs;
+ lOfDs = lOfOs;
+ lOfDs = lOfAs;
+ lOfDs = new L(); // Reset type propagation.
+ }
+ {
+ lOfOs = mOfDs;
+ lOfOs = mOfOs;
+ lOfOs = mOfAs;
+ lOfOs = lOfDs;
+ lOfOs = lOfOs;
+ lOfOs = lOfAs;
+ lOfOs = new L<Object>(); // Reset type propagation.
+ }
+ {
+ lOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
+ lOfAs = /*warning:INVALID_ASSIGNMENT*/mOfOs;
+ lOfAs = mOfAs;
+ lOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
+ lOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
+ lOfAs = lOfAs;
+ lOfAs = new L<A>(); // Reset type propagation.
+ }
+ {
+ mOfDs = mOfDs;
+ mOfDs = mOfOs;
+ mOfDs = mOfAs;
+ mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
+ mOfDs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
+ mOfDs = /*warning:DOWN_CAST_COMPOSITE*/lOfAs;
+ mOfDs = new M(); // Reset type propagation.
+ }
+ {
+ mOfOs = mOfDs;
+ mOfOs = mOfOs;
+ mOfOs = mOfAs;
+ mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfDs;
+ mOfOs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
+ mOfOs = /*warning:INVALID_ASSIGNMENT*/lOfAs;
+ mOfOs = new M<Object>(); // Reset type propagation.
+ }
+ {
+ mOfAs = /*warning:DOWN_CAST_COMPOSITE*/mOfDs;
+ mOfAs = /*info:DOWN_CAST_IMPLICIT*/mOfOs;
+ mOfAs = mOfAs;
+ mOfAs = /*warning:DOWN_CAST_COMPOSITE*/lOfDs;
+ mOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfOs;
+ mOfAs = /*info:DOWN_CAST_IMPLICIT*/lOfAs;
+ }
+}
+''');
+ }
+
+ void test_setterOverride_fuzzyArrows() {
+ 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) {}
+}
+ ''');
+ }
+
+ void test_setterReturnTypes() {
+ checkFile('''
+void voidFn() => null;
+class A {
+ set a(y) => 4;
+ set b(y) => voidFn();
+ void set c(y) => /*warning:RETURN_OF_INVALID_TYPE*/4;
+ void set d(y) => voidFn();
+ /*warning:NON_VOID_RETURN_FOR_SETTER*/int set e(y) => 4;
+ /*warning:NON_VOID_RETURN_FOR_SETTER*/int set f(y) =>
+ /*warning:RETURN_OF_INVALID_TYPE*/voidFn();
+ set g(y) {return /*warning:RETURN_OF_INVALID_TYPE*/4;}
+ void set h(y) {return /*warning:RETURN_OF_INVALID_TYPE*/4;}
+ /*warning:NON_VOID_RETURN_FOR_SETTER*/int set i(y) {return 4;}
+}
+''');
+ }
+
+ void test_setterSetterOverride() {
+ checkFile('''
+class A {}
+class B extends A {}
+class C extends B {}
+
+abstract class Base {
+ void set f1(B value);
+ void set f2(B value);
+ void set f3(B value);
+ void set f4(B value);
+ void set f5(B value);
+}
+
+class Child extends Base {
+ void set f1(A value) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/void set f2(C value) {}
+ void set f3(value) {}
+ /*severe:INVALID_METHOD_OVERRIDE*/void set f4(dynamic value) {}
+ set f5(B value) {}
+}
+''');
+ }
+
+ void test_superCallPlacement() {
+ checkFile('''
+class Base {
+ var x;
+ Base() : x = print('Base.1') { print('Base.2'); }
+}
+
+class Derived extends Base {
+ var y, z;
+ Derived()
+ : y = print('Derived.1'),
+ /*severe:INVALID_SUPER_INVOCATION*/super(),
+ z = print('Derived.2') {
+ print('Derived.3');
+ }
+}
+
+class Valid extends Base {
+ var y, z;
+ Valid()
+ : y = print('Valid.1'),
+ z = print('Valid.2'),
+ super() {
+ print('Valid.3');
+ }
+}
+
+class AlsoValid extends Base {
+ AlsoValid() : super();
+}
+
+main() => new Derived();
+''');
+ }
+
+ void test_superclassOverrideOfGrandInterface_interfaceOfAbstractSuperclass() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+
+abstract class Base implements I1 {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+
+class T1 extends Base {
+ // we consider the base class incomplete because it is
+ // abstract, so we report the error here too.
+ // TODO(sigmund): consider tracking overrides in a fine-grain
+ // manner, then this and the double-overrides would not be
+ // reported.
+ /*severe:INVALID_METHOD_OVERRIDE*/m(B a) {}
+}
+''');
+ }
+
+ void test_superclassOverrideOfGrandInterface_interfaceOfConcreteSuperclass() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+
+class Base implements I1 {
+ /*severe:INVALID_METHOD_OVERRIDE*/m(
+ /*warning:INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE*/B a) {}
+}
+
+class T1 extends Base {
+ m(B a) {}
+}
+''');
+ }
+
+ void test_superclassOverrideOfGrandInterface_interfaceOfInterfaceOfChild() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+abstract class I2 implements I1 {}
+
+class Base {
+ m(B a) {}
+}
+
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base implements I2 {}
+''');
+ }
+
+ void test_superclassOverrideOfGrandInterface_mixinOfInterfaceOfChild() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class M1 {
+ m(A a);
+}
+abstract class I2 extends Object with M1 {}
+
+class Base {
+ m(B a) {}
+}
+
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+ implements I2 {}
+''');
+ }
+
+ void test_superclassOverrideOfGrandInterface_superclassOfInterfaceOfChild() {
+ checkFile('''
+class A {}
+class B {}
+
+abstract class I1 {
+ m(A a);
+}
+abstract class I2 extends I1 {}
+
+class Base {
+ m(B a) {}
+}
+
+class /*warning:INCONSISTENT_METHOD_INHERITANCE*/T1
+ /*severe:INVALID_METHOD_OVERRIDE*/extends Base
+ implements I2 {}
+''');
+ }
+
+ void test_superConstructor() {
+ checkFile('''
+class A { A(A x) {} }
+class B extends A {
+ B() : super(/*warning:ARGUMENT_TYPE_NOT_ASSIGNABLE*/3);
+}
+''');
+ }
+
+ void test_ternaryOperator() {
+ checkFile('''
+abstract class Comparable<T> {
+ int compareTo(T other);
+ static int compare(Comparable a, Comparable b) => a.compareTo(b);
+}
+typedef int Comparator<T>(T a, T b);
+
+typedef bool _Predicate<T>(T value);
+
+class SplayTreeMap<K, V> {
+ Comparator<K> _comparator;
+ _Predicate _validKey;
+
+ // The warning on assigning to _comparator is legitimate. Since K has
+ // no bound, all we know is that it's object. _comparator's function
+ // type is effectively: (Object, Object) -> int
+ // We are assigning it a fn of type: (Comparable, Comparable) -> int
+ // There's no telling if that will work. For example, consider:
+ //
+ // new SplayTreeMap<Uri>();
+ //
+ // This would end up calling .compareTo() on a Uri, which doesn't
+ // define that since it doesn't implement Comparable.
+ SplayTreeMap([int compare(K key1, K key2),
+ bool isValidKey(potentialKey)])
+ : _comparator = /*warning:DOWN_CAST_COMPOSITE*/(compare == null) ? Comparable.compare : compare,
+ _validKey = (isValidKey != null) ? isValidKey : ((v) => true) {
+ _Predicate<Object> v = (isValidKey != null)
+ ? isValidKey : (/*info:INFERRED_TYPE_CLOSURE*/(_) => true);
+
+ v = (isValidKey != null)
+ ? v : (/*info:INFERRED_TYPE_CLOSURE*/(_) => true);
+ }
+}
+void main() {
+ Object obj = 42;
+ dynamic dyn = 42;
+ int i = 42;
+
+ // Check the boolean conversion of the condition.
+ print(/*warning:NON_BOOL_CONDITION*/i ? false : true);
+ print((/*info:DOWN_CAST_IMPLICIT*/obj) ? false : true);
+ print((/*info:DYNAMIC_CAST*/dyn) ? false : true);
+}
+''');
+ }
+
+ void test_typeCheckingLiterals() {
+ checkFile('''
+test() {
+ num n = 3;
+ int i = 3;
+ String s = "hello";
+ {
+ List<int> l = <int>[i];
+ l = <int>[/*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
+ l = <int>[/*info:DOWN_CAST_IMPLICIT*/n];
+ l = <int>[i, /*info:DOWN_CAST_IMPLICIT*/n, /*warning:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/s];
+ }
+ {
+ List l = /*info:INFERRED_TYPE_LITERAL*/[i];
+ l = /*info:INFERRED_TYPE_LITERAL*/[s];
+ l = /*info:INFERRED_TYPE_LITERAL*/[n];
+ l = /*info:INFERRED_TYPE_LITERAL*/[i, n, s];
+ }
+ {
+ Map<String, int> m = <String, int>{s: i};
+ m = <String, int>{s: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
+ m = <String, int>{s: /*info:DOWN_CAST_IMPLICIT*/n};
+ m = <String, int>{s: i,
+ s: /*info:DOWN_CAST_IMPLICIT*/n,
+ s: /*warning:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/s};
+ }
+ // TODO(leafp): We can't currently test for key errors since the
+ // error marker binds to the entire entry.
+ {
+ Map m = /*info:INFERRED_TYPE_LITERAL*/{s: i};
+ m = /*info:INFERRED_TYPE_LITERAL*/{s: s};
+ m = /*info:INFERRED_TYPE_LITERAL*/{s: n};
+ m = /*info:INFERRED_TYPE_LITERAL*/
+ {s: i,
+ s: n,
+ s: s};
+ m = /*info:INFERRED_TYPE_LITERAL*/
+ {i: s,
+ n: s,
+ s: s};
+ }
+}
+''');
+ }
+
+ void test_typePromotionFromDynamic() {
+ checkFile(r'''
+f() {
+ dynamic x;
+ if (x is int) {
+ int y = x;
+ String z = /*warning:INVALID_ASSIGNMENT*/x;
+ }
+}
+g() {
+ Object x;
+ if (x is int) {
+ int y = x;
+ String z = /*warning:INVALID_ASSIGNMENT*/x;
+ }
+}
+''');
+ }
+
+ void test_typeSubtyping_assigningClass() {
+ checkFile('''
+class A {}
+class B extends A {}
+
+void main() {
+ dynamic y;
+ Object o;
+ int i = 0;
+ double d = 0.0;
+ num n;
+ A a;
+ B b;
+ y = a;
+ o = a;
+ i = /*warning:INVALID_ASSIGNMENT*/a;
+ d = /*warning:INVALID_ASSIGNMENT*/a;
+ n = /*warning:INVALID_ASSIGNMENT*/a;
+ a = a;
+ b = /*info:DOWN_CAST_IMPLICIT*/a;
+}
+''');
+ }
+
+ void test_typeSubtyping_assigningSubclass() {
+ checkFile('''
+class A {}
+class B extends A {}
+class C extends A {}
+
+void main() {
+ dynamic y;
+ Object o;
+ int i = 0;
+ double d = 0.0;
+ num n;
+ A a;
+ B b;
+ C c;
+ y = b;
+ o = b;
+ i = /*warning:INVALID_ASSIGNMENT*/b;
+ d = /*warning:INVALID_ASSIGNMENT*/b;
+ n = /*warning:INVALID_ASSIGNMENT*/b;
+ a = b;
+ b = b;
+ c = /*warning:INVALID_ASSIGNMENT*/b;
+}
+''');
+ }
+
+ void test_typeSubtyping_dynamicDowncasts() {
+ checkFile('''
+class A {}
+class B extends A {}
+
+void main() {
+ dynamic y;
+ Object o;
+ int i = 0;
+ double d = 0.0;
+ num n;
+ A a;
+ B b;
+ o = y;
+ i = /*info:DYNAMIC_CAST*/y;
+ d = /*info:DYNAMIC_CAST*/y;
+ n = /*info:DYNAMIC_CAST*/y;
+ a = /*info:DYNAMIC_CAST*/y;
+ b = /*info:DYNAMIC_CAST*/y;
+}
+''');
+ }
+
+ void test_typeSubtyping_dynamicIsTop() {
+ checkFile('''
+class A {}
+class B extends A {}
+
+void main() {
+ dynamic y;
+ Object o;
+ int i = 0;
+ double d = 0.0;
+ num n;
+ A a;
+ B b;
+ y = o;
+ y = i;
+ y = d;
+ y = n;
+ y = a;
+ y = b;
+}
+''');
+ }
+
+ void test_typeSubtyping_interfaces() {
+ checkFile('''
+class A {}
+class B extends A {}
+class C extends A {}
+class D extends B implements C {}
+
+void main() {
+ A top;
+ B left;
+ C right;
+ D bot;
+ {
+ top = top;
+ top = left;
+ top = right;
+ top = bot;
+ }
+ {
+ left = /*info:DOWN_CAST_IMPLICIT*/top;
+ left = left;
+ left = /*warning:INVALID_ASSIGNMENT*/right;
+ left = bot;
+ }
+ {
+ right = /*info:DOWN_CAST_IMPLICIT*/top;
+ right = /*warning:INVALID_ASSIGNMENT*/left;
+ right = right;
+ right = bot;
+ }
+ {
+ bot = /*info:DOWN_CAST_IMPLICIT*/top;
+ bot = /*info:DOWN_CAST_IMPLICIT*/left;
+ bot = /*info:DOWN_CAST_IMPLICIT*/right;
+ bot = bot;
+ }
+}
+''');
+ }
+
+ void test_unaryOperators() {
+ checkFile('''
+class A {
+ A operator ~() => null;
+ A operator +(int x) => null;
+ A operator -(int x) => null;
+ A operator -() => null;
+}
+
+foo() => new A();
+
+test() {
+ A a = new A();
+ var c = foo();
+ dynamic d;
+
+ ~a;
+ (/*info:DYNAMIC_INVOKE*/~d);
+
+ !/*warning:NON_BOOL_NEGATION_EXPRESSION*/a;
+ !/*info:DYNAMIC_CAST*/d;
+
+ -a;
+ (/*info:DYNAMIC_INVOKE*/-d);
+
+ ++a;
+ --a;
+ (/*info:DYNAMIC_INVOKE*/++d);
+ (/*info:DYNAMIC_INVOKE*/--d);
+
+ a++;
+ a--;
+ (/*info:DYNAMIC_INVOKE*/d++);
+ (/*info:DYNAMIC_INVOKE*/d--);
+}''');
+ }
+
+ void test_unboundRedirectingConstructor() {
+ // This is a regression test for https://github.com/dart-lang/sdk/issues/25071
+ checkFile('''
+class Foo {
+ Foo() : /*severe:REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR*/this.init();
+}
+ ''');
+ }
+
+ void test_unboundTypeName() {
+ checkFile('''
+void main() {
+ /*warning:UNDEFINED_CLASS should be error*/AToB y;
+}
+''');
+ }
+
+ void test_unboundVariable() {
+ checkFile('''
+void main() {
+ dynamic y = /*warning:UNDEFINED_IDENTIFIER should be error*/unboundVariable;
+}
+''');
+ }
+
+ void test_voidSubtyping() {
+ // Regression test for https://github.com/dart-lang/sdk/issues/25069
+ checkFile('''
+typedef int Foo();
+void foo() {}
+void main () {
+ Foo x = /*warning:INVALID_ASSIGNMENT,info:USE_OF_VOID_RESULT*/foo();
+}
+''');
+ }
}
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 a686740..46e7434e 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -449,6 +449,29 @@
expect(f.type.toString(), '() → Iterable<num>');
}
+ void test_bottom() {
+ // When a type is inferred from the expression `null`, the inferred type is
+ // `dynamic`, but the inferred type of the initializer is `bottom`.
+ // TODO(paulberry): Is this intentional/desirable?
+ var mainUnit = checkFile('''
+var v = null;
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'dynamic');
+ expect(v.initializer.type.toString(), '() → <bottom>');
+ }
+
+ void test_bottom_inClosure() {
+ // When a closure's return type is inferred from the expression `null`, the
+ // inferred type is `dynamic`.
+ var mainUnit = checkFile('''
+var v = () => null;
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), '() → dynamic');
+ expect(v.initializer.type.toString(), '() → () → dynamic');
+ }
+
void test_canInferAlsoFromStaticAndInstanceFieldsFlagOn() {
addFile(
'''
@@ -479,6 +502,32 @@
''');
}
+ void test_circularReference_viaClosures() {
+ var mainUnit = checkFile('''
+var x = () => y;
+var y = () => x;
+''');
+ var x = mainUnit.topLevelVariables[0];
+ var y = mainUnit.topLevelVariables[1];
+ expect(x.name, 'x');
+ expect(y.name, 'y');
+ expect(x.type.toString(), 'dynamic');
+ expect(y.type.toString(), 'dynamic');
+ }
+
+ void test_circularReference_viaClosures_initializerTypes() {
+ var mainUnit = checkFile('''
+var x = () => y;
+var y = () => x;
+''');
+ var x = mainUnit.topLevelVariables[0];
+ var y = mainUnit.topLevelVariables[1];
+ expect(x.name, 'x');
+ expect(y.name, 'y');
+ expect(x.initializer.returnType.toString(), '() → dynamic');
+ expect(y.initializer.returnType.toString(), '() → dynamic');
+ }
+
void test_conflictsCanHappen() {
checkFile('''
class I1 {
@@ -1268,6 +1317,14 @@
expect(x.type.toString(), 'int');
}
+ void test_futureThen() {
+ checkFile('''
+import 'dart:async';
+Future f;
+Future<int> t1 = f.then((_) => new Future<int>.value(42));
+''');
+ }
+
void test_genericMethods_basicDownwardInference() {
checkFile(r'''
/*=T*/ f/*<S, T>*/(/*=S*/ s) => null;
@@ -2551,6 +2608,19 @@
expect(x.type.toString(), 'Map<String, () → int>');
}
+ void test_inferredType_opAssignToProperty() {
+ var mainUnit = checkFile('''
+class C {
+ num n;
+}
+C f() => null;
+var x = (f().n *= null);
+''');
+ var x = mainUnit.topLevelVariables[0];
+ expect(x.name, 'x');
+ expect(x.type.toString(), 'num');
+ }
+
void test_inferredType_opAssignToProperty_prefixedIdentifier() {
var mainUnit = checkFile('''
class C {
@@ -2578,19 +2648,6 @@
expect(x.type.toString(), 'num');
}
- void test_inferredType_opAssignToProperty() {
- var mainUnit = checkFile('''
-class C {
- num n;
-}
-C f() => null;
-var x = (f().n *= null);
-''');
- var x = mainUnit.topLevelVariables[0];
- expect(x.name, 'x');
- expect(x.type.toString(), 'num');
- }
-
void test_inferredType_opAssignToProperty_viaInterface() {
var mainUnit = checkFile('''
class I {
@@ -2605,6 +2662,42 @@
expect(x.type.toString(), 'num');
}
+ void test_inferredType_viaClosure_multipleLevelsOfNesting() {
+ var mainUnit = checkFile('''
+class C {
+ static final f = (bool b) => (int i) => /*info:INFERRED_TYPE_LITERAL*/{i: b};
+}
+''');
+ var f = mainUnit.getType('C').fields[0];
+ expect(f.type.toString(), '(bool) → (int) → Map<int, bool>');
+ }
+
+ void test_inferredType_viaClosure_typeDependsOnArgs() {
+ var mainUnit = checkFile('''
+class C {
+ static final f = (bool b) => b;
+}
+''');
+ var f = mainUnit.getType('C').fields[0];
+ expect(f.type.toString(), '(bool) → bool');
+ }
+
+ void test_inferredType_viaClosure_typeIndependentOfArgs_field() {
+ var mainUnit = checkFile('''
+class C {
+ static final f = (bool b) => 1;
+}
+''');
+ var f = mainUnit.getType('C').fields[0];
+ expect(f.type.toString(), '(bool) → int');
+ }
+
+ void test_inferredType_viaClosure_typeIndependentOfArgs_topLevel() {
+ var mainUnit = checkFile('final f = (bool b) => 1;');
+ var f = mainUnit.topLevelVariables[0];
+ expect(f.type.toString(), '(bool) → int');
+ }
+
void test_inferStaticsTransitively() {
addFile(
'''
@@ -3274,6 +3367,54 @@
expect(x.type.toString(), 'Map<dynamic, dynamic>');
}
+ void test_methodCall_withTypeArguments_instanceMethod() {
+ var mainUnit = checkFile('''
+class C {
+ D/*<T>*/ f/*<T>*/() => null;
+}
+class D<T> {}
+var f = new C().f/*<int>*/();
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'D<int>');
+ }
+
+ void test_methodCall_withTypeArguments_instanceMethod_identifierSequence() {
+ var mainUnit = checkFile('''
+class C {
+ D/*<T>*/ f/*<T>*/() => null;
+}
+class D<T> {}
+C c;
+var f = c.f/*<int>*/();
+''');
+ var v = mainUnit.topLevelVariables[1];
+ expect(v.name, 'f');
+ expect(v.type.toString(), 'D<int>');
+ }
+
+ void test_methodCall_withTypeArguments_staticMethod() {
+ var mainUnit = checkFile('''
+class C {
+ static D/*<T>*/ f/*<T>*/() => null;
+}
+class D<T> {}
+var f = C.f/*<int>*/();
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'D<int>');
+ }
+
+ void test_methodCall_withTypeArguments_topLevelFunction() {
+ var mainUnit = checkFile('''
+D/*<T>*/ f/*<T>*/() => null;
+class D<T> {}
+var g = f/*<int>*/();
+''');
+ var v = mainUnit.topLevelVariables[0];
+ expect(v.type.toString(), 'D<int>');
+ }
+
void test_noErrorWhenDeclaredTypeIsNumAndAssignedNull() {
checkFile('''
test1() {
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 6e5b83b..079bda1 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -66,8 +66,10 @@
AnalysisOptionsImpl options = context.analysisOptions as AnalysisOptionsImpl;
options.strongMode = true;
options.strongModeHints = true;
+ var mockSdk = new MockSdk();
+ mockSdk.context.analysisOptions.strongMode = true;
context.sourceFactory =
- new SourceFactory([new DartUriResolver(new MockSdk()), uriResolver]);
+ new SourceFactory([new DartUriResolver(mockSdk), uriResolver]);
// Run the checker on /main.dart.
Source mainSource = uriResolver.resolveAbsolute(new Uri.file('/main.dart'));
diff --git a/pkg/analyzer/tool/task_dependency_graph/tasks.dot b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
index 402efa5..e134a09 100644
--- a/pkg/analyzer/tool/task_dependency_graph/tasks.dot
+++ b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
@@ -99,6 +99,8 @@
GenerateLintsTask -> LINTS
HINTS -> LibraryUnitErrorsTask
HINTS [shape=box]
+ IGNORE_INFO -> DartErrorsTask
+ IGNORE_INFO [shape=box]
IMPORTED_LIBRARIES -> BuildDirectiveElementsTask
IMPORTED_LIBRARIES -> ReadyLibraryElement2Task
IMPORTED_LIBRARIES -> ReadyLibraryElement5Task
@@ -189,7 +191,6 @@
MODIFICATION_TIME -> VerifyUnitTask
MODIFICATION_TIME [shape=box]
PARSED_UNIT -> BuildCompilationUnitElementTask
- PARSED_UNIT -> DartErrorsTask
PARSED_UNIT [shape=box]
PARSE_ERRORS -> dartErrorsForSource
PARSE_ERRORS [shape=box]
@@ -322,6 +323,7 @@
SOURCE_KIND [shape=box]
STRONG_MODE_ERRORS -> LibraryUnitErrorsTask
STRONG_MODE_ERRORS [shape=box]
+ ScanDartTask -> IGNORE_INFO
ScanDartTask -> LINE_INFO
ScanDartTask -> SCAN_ERRORS
ScanDartTask -> TOKEN_STREAM
diff --git a/pkg/analyzer2dart/bin/analyzer2dart.dart b/pkg/analyzer2dart/bin/analyzer2dart.dart
deleted file mode 100644
index 9f372c1..0000000
--- a/pkg/analyzer2dart/bin/analyzer2dart.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/** The entry point for the command-line version analyzer2dart. */
-library analyzer2dart.cmdline;
-
-import 'dart:io';
-
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:compiler/src/source_file_provider.dart';
-
-import '../lib/src/closed_world.dart';
-import '../lib/src/driver.dart';
-import '../lib/src/converted_world.dart';
-import '../lib/src/dart_backend.dart';
-
-void main(List<String> args) {
- // TODO(paulberry): hacky
- String path = args[0];
-
- PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE;
- DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
- // TODO(johnniwinther): Support user specified output Uri.
- // TODO(johnniwinther): Integrate messaging.
- RandomAccessFileOutputProvider outputProvider =
- new RandomAccessFileOutputProvider(
- Uri.base.resolve('out.dart'),
- Uri.base.resolve('out.dart.map'),
- onInfo: (message) => print(message),
- onFailure: (message) {
- print(message);
- exit(1);
- });
-
- Driver analyzer2Dart = new Driver(provider, sdk, outputProvider);
-
- // Tell the analysis server about the root
- Source source = analyzer2Dart.setRoot(path);
-
- // Get the library element associated with the source.
- FunctionElement entryPointElement = analyzer2Dart.resolveEntryPoint(source);
-
- // TODO(brianwilkerson,paulberry,johnniwinther): Perform tree-growing by
- // visiting the ast and feeding the dependencies into a work queue (enqueuer).
- ClosedWorld world = analyzer2Dart.computeWorld(entryPointElement);
-
- // TODO(brianwilkerson,paulberry,johnniwinther): Convert the ast into cps by
- // visiting the ast and invoking the ir builder.
- // TODO(johnniwinther): Convert the analyzer element model into the dart2js
- // element model to fit the needs of the cps encoding above.
- ConvertedWorld convertedWorld = convertWorld(world);
-
- // TODO(johnniwinther): Feed the cps ir into the new dart2dart backend to
- // generate dart file(s).
- compileToDart(analyzer2Dart, convertedWorld);
-}
-
diff --git a/pkg/analyzer2dart/lib/src/closed_world.dart b/pkg/analyzer2dart/lib/src/closed_world.dart
deleted file mode 100644
index 8f91658..0000000
--- a/pkg/analyzer2dart/lib/src/closed_world.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer2dart.closedWorld;
-
-import 'dart:collection';
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-
-/**
- * Container for the elements and AST nodes which have been determined by
- * tree shaking to be reachable by the program being compiled.
- */
-class ClosedWorld {
- /// The core types of this world.
- final TypeProvider typeProvider;
-
- /// Returns the main function of this closed world compilation.
- final FunctionElement mainFunction;
-
- // TODO(paulberry): is it a problem to hold on to all the AST's for the
- // duration of tree shaking & CPS generation?
-
- /**
- * Methods, toplevel functions, etc. that are reachable.
- */
- Map<ExecutableElement, Declaration> executableElements =
- new HashMap<ExecutableElement, Declaration>();
-
- /**
- * Fields that are reachable.
- */
- Map<FieldElement, VariableDeclaration> fields =
- new HashMap<FieldElement, VariableDeclaration>();
-
- /**
- * Top-level variables that are reachable.
- */
- // TODO(johnniwinther): Is there value in splitting fields and top-level
- // variables?
- Map<TopLevelVariableElement, VariableDeclaration> variables =
- new HashMap<TopLevelVariableElement, VariableDeclaration>();
-
- /**
- * Classes that are instantiated from reachable code.
- *
- * TODO(paulberry): Also keep track of classes that are reachable but not
- * instantiated (because they are extended or mixed in)
- */
- Map<ClassElement, ClassDeclaration> instantiatedClasses =
- new HashMap<ClassElement, ClassDeclaration>();
-
- ClosedWorld(this.typeProvider, this.mainFunction);
-}
diff --git a/pkg/analyzer2dart/lib/src/converted_world.dart b/pkg/analyzer2dart/lib/src/converted_world.dart
deleted file mode 100644
index 600487a..0000000
--- a/pkg/analyzer2dart/lib/src/converted_world.dart
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer2dart.convertedWorld;
-
-import 'dart:collection';
-
-import 'package:analyzer/analyzer.dart';
-import 'package:compiler/src/dart_types.dart' as dart2js;
-import 'package:compiler/src/elements/elements.dart' as dart2js;
-import 'package:analyzer/src/generated/element.dart' as analyzer;
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
-
-import 'closed_world.dart';
-import 'element_converter.dart';
-import 'cps_generator.dart';
-import 'util.dart';
-
-/// A [ClosedWorld] converted to the dart2js element model.
-abstract class ConvertedWorld {
- Iterable<dart2js.LibraryElement> get libraries;
- Iterable<dart2js.AstElement> get resolvedElements;
- Iterable<dart2js.ClassElement> get instantiatedClasses;
- dart2js.FunctionElement get mainFunction;
- ir.Node getIr(dart2js.Element element);
- dart2js.DartTypes get dartTypes;
-}
-
-class _ConvertedWorldImpl implements ConvertedWorld {
- final dart2js.FunctionElement mainFunction;
- Map<dart2js.AstElement, ir.Node> executableElements =
- new HashMap<dart2js.AstElement, ir.Node>();
- final List<dart2js.ClassElement> instantiatedClasses =
- <dart2js.ClassElement>[];
-
- _ConvertedWorldImpl(this.mainFunction);
-
- // TODO(johnniwinther): Add all used libraries and all SDK libraries to the
- // set of libraries in the converted world.
- Iterable<dart2js.LibraryElement> get libraries => [mainFunction.library];
-
- Iterable<dart2js.AstElement> get resolvedElements => executableElements.keys;
-
- ir.Node getIr(dart2js.Element element) => executableElements[element];
-
- final dart2js.DartTypes dartTypes = new _DartTypes();
-}
-
-ConvertedWorld convertWorld(ClosedWorld closedWorld) {
- ElementConverter converter = new ElementConverter();
- _ConvertedWorldImpl convertedWorld = new _ConvertedWorldImpl(
- converter.convertElement(closedWorld.mainFunction));
-
- void convert(analyzer.Element analyzerElement, AstNode node) {
- // Skip conversion of SDK sources since we don't generate code for it
- // anyway.
- if (analyzerElement.source.isInSystemLibrary) return;
-
- dart2js.AstElement dart2jsElement =
- converter.convertElement(analyzerElement);
- CpsElementVisitor visitor = new CpsElementVisitor(converter, node);
- ir.Node cpsNode = analyzerElement.accept(visitor);
- convertedWorld.executableElements[dart2jsElement] = cpsNode;
- if (cpsNode == null && !analyzerElement.isSynthetic) {
- String message =
- 'No CPS node generated for $analyzerElement (${node.runtimeType}).';
- reportSourceMessage(analyzerElement.source, node, message);
- throw new UnimplementedError(message);
- }
- }
-
- void convertClass(analyzer.ClassElement analyzerElement, _) {
- // Skip conversion of SDK sources since we don't generate code for it
- // anyway.
- if (analyzerElement.source.isInSystemLibrary) return;
- convertedWorld.instantiatedClasses.add(
- converter.convertElement(analyzerElement));
- }
-
- closedWorld.executableElements.forEach(convert);
- closedWorld.variables.forEach(convert);
- closedWorld.fields.forEach(convert);
- closedWorld.instantiatedClasses.forEach(convertClass);
-
- return convertedWorld;
-}
-
-// TODO(johnniwinther): Implement [coreTypes] using [TypeProvider].
-class _DartTypes implements dart2js.DartTypes {
- @override
- get coreTypes => throw new UnsupportedError("coreTypes");
-
- @override
- bool isSubtype(dart2js.DartType t, dart2js.DartType s) {
- throw new UnsupportedError("isSubtype");
- }
-}
\ No newline at end of file
diff --git a/pkg/analyzer2dart/lib/src/cps_generator.dart b/pkg/analyzer2dart/lib/src/cps_generator.dart
deleted file mode 100644
index 1e5bb6d..0000000
--- a/pkg/analyzer2dart/lib/src/cps_generator.dart
+++ /dev/null
@@ -1,589 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer2dart.cps_generator;
-
-import 'package:analyzer/analyzer.dart';
-
-import 'package:compiler/src/dart_types.dart' as dart2js;
-import 'package:compiler/src/elements/elements.dart' as dart2js;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/element.dart' as analyzer;
-
-import 'package:compiler/src/constant_system_dart.dart'
- show DART_CONSTANT_SYSTEM;
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
-import 'package:compiler/src/cps_ir/cps_ir_builder.dart';
-import 'package:compiler/src/universe/universe.dart';
-
-import 'semantic_visitor.dart';
-import 'element_converter.dart';
-import 'util.dart';
-import 'identifier_semantics.dart';
-
-/// Visitor that converts the AST node of an analyzer element into a CPS ir
-/// node.
-class CpsElementVisitor extends analyzer.SimpleElementVisitor<ir.Node> {
- final ElementConverter converter;
- final AstNode node;
-
- CpsElementVisitor(this.converter, this.node);
-
- @override
- ir.FunctionDefinition visitFunctionElement(analyzer.FunctionElement element) {
- CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
- FunctionDeclaration functionDeclaration = node;
- return visitor.handleFunctionDeclaration(
- element, functionDeclaration.functionExpression.body);
- }
-
- @override
- ir.FunctionDefinition visitMethodElement(analyzer.MethodElement element) {
- CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
- MethodDeclaration methodDeclaration = node;
- return visitor.handleFunctionDeclaration(element, methodDeclaration.body);
- }
-
- @override
- ir.FieldDefinition visitTopLevelVariableElement(
- analyzer.TopLevelVariableElement element) {
- CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
- VariableDeclaration variableDeclaration = node;
- return visitor.handleFieldDeclaration(element, variableDeclaration);
- }
-
- @override
- ir.RootNode visitConstructorElement(analyzer.ConstructorElement element) {
- CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
- if (!element.isFactory) {
- ConstructorDeclaration constructorDeclaration = node;
- FunctionBody body;
- if (constructorDeclaration != null) {
- body = constructorDeclaration.body;
- } else {
- assert(element.isSynthetic);
- }
- return visitor.handleConstructorDeclaration(element, body);
- }
- // TODO(johnniwinther): Support factory constructors.
- return null;
- }
-}
-
-/// Visitor that converts analyzer AST nodes into CPS ir nodes.
-class CpsGeneratingVisitor extends SemanticVisitor<ir.Node>
- with IrBuilderMixin<AstNode> {
- /// Promote the type of [irBuilder] to [DartIrBuilder].
- /// The JS backend requires closure conversion which we do not support yet.
- DartIrBuilder get irBuilder => super.irBuilder;
- final analyzer.Element element;
- final ElementConverter converter;
-
- CpsGeneratingVisitor(this.converter, this.element);
-
- Source get currentSource => element.source;
-
- analyzer.LibraryElement get currentLibrary => element.library;
-
- ir.Node visit(AstNode node) => node.accept(this);
-
- ir.ConstructorDefinition handleConstructorDeclaration(
- analyzer.ConstructorElement constructor, FunctionBody body) {
- dart2js.ConstructorElement element = converter.convertElement(constructor);
- return withBuilder(
- new DartIrBuilder(DART_CONSTANT_SYSTEM,
- element,
- // TODO(johnniwinther): Support closure variables.
- new Set<dart2js.Local>()),
- () {
- irBuilder.buildFunctionHeader(
- constructor.parameters.map(converter.convertElement));
- // Visit the body directly to avoid processing the signature as
- // expressions.
- // Call to allow for `body == null` in case of synthesized constructors.
- build(body);
- return irBuilder.makeConstructorDefinition(const [], const []);
- });
- }
-
- ir.FieldDefinition handleFieldDeclaration(
- analyzer.PropertyInducingElement field, VariableDeclaration node) {
- dart2js.FieldElement element = converter.convertElement(field);
- return withBuilder(
- new DartIrBuilder(DART_CONSTANT_SYSTEM,
- element,
- // TODO(johnniwinther): Support closure variables.
- new Set<dart2js.Local>()),
- () {
- irBuilder.buildFieldInitializerHeader();
- ir.Primitive initializer = build(node.initializer);
- return irBuilder.makeFieldDefinition(initializer);
- });
- }
-
- ir.FunctionDefinition handleFunctionDeclaration(
- analyzer.ExecutableElement function, FunctionBody body) {
- dart2js.FunctionElement element = converter.convertElement(function);
- return withBuilder(
- new DartIrBuilder(DART_CONSTANT_SYSTEM,
- element,
- // TODO(johnniwinther): Support closure variables.
- new Set<dart2js.Local>()),
- () {
- irBuilder.buildFunctionHeader(
- function.parameters.map(converter.convertElement));
- // Visit the body directly to avoid processing the signature as
- // expressions.
- visit(body);
- return irBuilder.makeFunctionDefinition(const []);
- });
- }
-
- @override
- ir.Primitive visitFunctionExpression(FunctionExpression node) {
- return irBuilder.buildFunctionExpression(
- handleFunctionDeclaration(node.element, node.body));
- }
-
- @override
- ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) {
- return handleFunctionDeclaration(
- node.element, node.functionExpression.body);
- }
-
- @override
- visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
- FunctionDeclaration functionDeclaration = node.functionDeclaration;
- analyzer.FunctionElement function = functionDeclaration.element;
- dart2js.FunctionElement element = converter.convertElement(function);
- ir.FunctionDefinition definition = handleFunctionDeclaration(
- function, functionDeclaration.functionExpression.body);
- irBuilder.declareLocalFunction(element, definition);
- }
-
- List<ir.Primitive> visitArguments(ArgumentList argumentList) {
- List<ir.Primitive> arguments = <ir.Primitive>[];
- for (Expression argument in argumentList.arguments) {
- ir.Primitive value = build(argument);
- if (value == null) {
- giveUp(argument,
- 'Unsupported argument: $argument (${argument.runtimeType}).');
- }
- arguments.add(value);
- }
- return arguments;
- }
-
- @override
- ir.Node visitMethodInvocation(MethodInvocation node) {
- // Overridden to avoid eager visits of the receiver and arguments.
- return handleMethodInvocation(node);
- }
-
- @override
- ir.Primitive visitDynamicInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- // TODO(johnniwinther): Handle implicit `this`.
- ir.Primitive receiver = build(semantics.target);
- List<ir.Primitive> arguments = visitArguments(node.argumentList);
- return irBuilder.buildDynamicInvocation(
- receiver,
- createSelectorFromMethodInvocation(
- node.argumentList, node.methodName.name),
- arguments);
- }
-
- @override
- ir.Primitive visitStaticMethodInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- analyzer.Element staticElement = semantics.element;
- dart2js.Element element = converter.convertElement(staticElement);
- List<ir.Primitive> arguments = visitArguments(node.argumentList);
- return irBuilder.buildStaticFunctionInvocation(
- element,
- createCallStructureFromMethodInvocation(node.argumentList),
- arguments);
- }
-
- @override
- ir.Node visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
- return handleLocalAccess(node, semantics);
- }
-
- ir.Primitive handleLocalInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- analyzer.Element staticElement = semantics.element;
- dart2js.Element element = converter.convertElement(staticElement);
- List<ir.Definition> arguments = visitArguments(node.argumentList);
- CallStructure callStructure = createCallStructureFromMethodInvocation(
- node.argumentList);
- if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
- return irBuilder.buildLocalFunctionInvocation(
- element, callStructure, arguments);
- } else {
- return irBuilder.buildLocalVariableInvocation(
- element, callStructure, arguments);
- }
- }
-
- @override
- ir.Node visitLocalVariableInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return handleLocalInvocation(node, semantics);
- }
-
- @override
- ir.Primitive visitLocalFunctionInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return handleLocalInvocation(node, semantics);
- }
-
- @override
- ir.Primitive visitFunctionExpressionInvocation(
- FunctionExpressionInvocation node) {
- ir.Primitive target = build(node.function);
- List<ir.Definition> arguments = visitArguments(node.argumentList);
- return irBuilder.buildCallInvocation(
- target,
- createCallStructureFromMethodInvocation(node.argumentList),
- arguments);
- }
-
- @override
- ir.Primitive visitInstanceCreationExpression(
- InstanceCreationExpression node) {
- analyzer.Element staticElement = node.staticElement;
- if (staticElement != null) {
- dart2js.Element element = converter.convertElement(staticElement);
- dart2js.DartType type = converter.convertType(node.staticType);
- List<ir.Primitive> arguments = visitArguments(node.argumentList);
- return irBuilder.buildConstructorInvocation(
- element,
- createCallStructureFromMethodInvocation(node.argumentList),
- type,
- arguments);
- }
- return giveUp(node, "Unresolved constructor invocation.");
- }
-
- @override
- ir.Constant visitNullLiteral(NullLiteral node) {
- return irBuilder.buildNullConstant();
- }
-
- @override
- ir.Constant visitBooleanLiteral(BooleanLiteral node) {
- return irBuilder.buildBooleanConstant(node.value);
- }
-
- @override
- ir.Constant visitDoubleLiteral(DoubleLiteral node) {
- return irBuilder.buildDoubleConstant(node.value);
- }
-
- @override
- ir.Constant visitIntegerLiteral(IntegerLiteral node) {
- return irBuilder.buildIntegerConstant(node.value);
- }
-
- @override
- visitAdjacentStrings(AdjacentStrings node) {
- String value = node.stringValue;
- if (value != null) {
- return irBuilder.buildStringConstant(value);
- }
- giveUp(node, "Non constant adjacent strings.");
- }
-
- @override
- ir.Constant visitSimpleStringLiteral(SimpleStringLiteral node) {
- return irBuilder.buildStringConstant(node.value);
- }
-
- @override
- visitStringInterpolation(StringInterpolation node) {
- giveUp(node, "String interpolation.");
- }
-
- @override
- visitReturnStatement(ReturnStatement node) {
- irBuilder.buildReturn(build(node.expression));
- }
-
- @override
- ir.Node visitPropertyAccess(PropertyAccess node) {
- // Overridden to avoid eager visits of the receiver.
- return handlePropertyAccess(node);
- }
-
- @override
- ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
- return handleLocalAccess(node, semantics);
- }
-
- @override
- ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) {
- return handleLocalAccess(node, semantics);
- }
-
- @override
- visitVariableDeclaration(VariableDeclaration node) {
- // TODO(johnniwinther): Handle constant local variables.
- ir.Node initialValue = build(node.initializer);
- irBuilder.declareLocalVariable(
- converter.convertElement(node.element),
- initialValue: initialValue);
- }
-
- dart2js.Element getLocal(AstNode node, AccessSemantics semantics) {
- analyzer.Element element = semantics.element;
- dart2js.Element target = converter.convertElement(element);
- assert(invariant(node, target.isLocal, '$target expected to be local.'));
- return target;
- }
-
- ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) {
- dart2js.Element local = getLocal(node, semantics);
- if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
- return irBuilder.buildLocalFunctionGet(local);
- } else {
- return irBuilder.buildLocalVariableGet(local);
- }
- }
-
- ir.Primitive handleLocalAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- if (node.operator.lexeme != '=') {
- return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
- }
- return irBuilder.buildLocalVariableSet(
- getLocal(node, semantics),
- build(node.rightHandSide));
- }
-
- @override
- ir.Node visitAssignmentExpression(AssignmentExpression node) {
- // Avoid eager visiting of left and right hand side.
- return handleAssignmentExpression(node);
- }
-
- @override
- ir.Node visitLocalVariableAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return handleLocalAssignment(node, semantics);
- }
-
- @override
- ir.Node visitParameterAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return handleLocalAssignment(node, semantics);
- }
-
- @override
- ir.Node visitStaticFieldAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- if (node.operator.lexeme != '=') {
- return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
- }
- analyzer.Element element = semantics.element;
- dart2js.Element target = converter.convertElement(element);
- // TODO(johnniwinther): Selector information should be computed in the
- // [TreeShaker] and shared with the [CpsGeneratingVisitor].
- assert(invariant(node, target.isTopLevel || target.isStatic,
- '$target expected to be top-level or static.'));
- return irBuilder.buildStaticFieldSet(target, build(node.rightHandSide));
- }
-
- @override
- ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) {
- // TODO(johnniwinther): Handle implicit `this`.
- ir.Primitive receiver = build(semantics.target);
- return irBuilder.buildDynamicGet(receiver,
- new Selector.getter(semantics.identifier.name,
- converter.convertElement(element.library)));
- }
-
- @override
- ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
- analyzer.Element element = semantics.element;
- dart2js.Element target = converter.convertElement(element);
- // TODO(johnniwinther): Selector information should be computed in the
- // [TreeShaker] and shared with the [CpsGeneratingVisitor].
- assert(invariant(node, target.isTopLevel || target.isStatic,
- '$target expected to be top-level or static.'));
- return irBuilder.buildStaticFieldLazyGet(target, null);
- }
-
- ir.Primitive handleBinaryExpression(BinaryExpression node,
- String op) {
- ir.Primitive left = build(node.leftOperand);
- ir.Primitive right = build(node.rightOperand);
- Selector selector = new Selector.binaryOperator(op);
- return irBuilder.buildDynamicInvocation(
- left, selector, <ir.Primitive>[right]);
- }
-
- ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) {
- return irBuilder.buildLogicalOperator(
- build(node.leftOperand),
- subbuild(node.rightOperand),
- isLazyOr: isLazyOr);
- }
-
- @override
- ir.Node visitBinaryExpression(BinaryExpression node) {
- // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be
- // available through an enum.
- String op = node.operator.lexeme;
- switch (op) {
- case '||':
- case '&&':
- return handleLazyOperator(node, isLazyOr: op == '||');
- case '!=':
- return irBuilder.buildNegation(handleBinaryExpression(node, '=='));
- default:
- return handleBinaryExpression(node, op);
- }
- }
-
- @override
- ir.Node visitConditionalExpression(ConditionalExpression node) {
- return irBuilder.buildConditional(
- build(node.condition),
- subbuild(node.thenExpression),
- subbuild(node.elseExpression));
- }
-
- @override
- visitIfStatement(IfStatement node) {
- irBuilder.buildIf(
- build(node.condition),
- subbuild(node.thenStatement),
- subbuild(node.elseStatement));
- }
-
- @override
- visitBlock(Block node) {
- irBuilder.buildBlock(node.statements, build);
- }
-
- @override
- ir.Node visitListLiteral(ListLiteral node) {
- dart2js.InterfaceType type = converter.convertType(node.staticType);
- // TODO(johnniwinther): Use `build` instead of `(e) => build(e)` when issue
- // 18630 has been resolved.
- Iterable<ir.Primitive> values = node.elements.map((e) => build(e));
- return irBuilder.buildListLiteral(type, values);
- }
-
- @override
- ir.Node visitMapLiteral(MapLiteral node) {
- dart2js.InterfaceType type = converter.convertType(node.staticType);
- return irBuilder.buildMapLiteral(
- type,
- node.entries.map((e) => e.key),
- node.entries.map((e) => e.value),
- build);
- }
-
- @override
- visitForStatement(ForStatement node) {
- // TODO(johnniwinther): Support `for` as a jump target.
- List<dart2js.LocalElement> loopVariables = <dart2js.LocalElement>[];
- SubbuildFunction buildInitializer;
- if (node.variables != null) {
- buildInitializer = subbuild(node.variables);
- for (VariableDeclaration variable in node.variables.variables) {
- loopVariables.add(converter.convertElement(variable.element));
- }
- } else {
- buildInitializer = subbuild(node.initialization);
- }
- irBuilder.buildFor(buildInitializer: buildInitializer,
- buildCondition: subbuild(node.condition),
- buildBody: subbuild(node.body),
- buildUpdate: subbuildSequence(node.updaters),
- loopVariables: loopVariables);
- }
-
- @override
- visitWhileStatement(WhileStatement node) {
- // TODO(johnniwinther): Support `while` as a jump target.
- irBuilder.buildWhile(buildCondition: subbuild(node.condition),
- buildBody: subbuild(node.body));
- }
-
- @override
- visitDeclaredIdentifier(DeclaredIdentifier node) {
- giveUp(node, "Unexpected node: DeclaredIdentifier");
- }
-
- @override
- visitForEachStatement(ForEachStatement node) {
- SubbuildFunction buildVariableDeclaration;
- dart2js.Element variableElement;
- Selector variableSelector;
- if (node.identifier != null) {
- AccessSemantics accessSemantics =
- node.identifier.accept(ACCESS_SEMANTICS_VISITOR);
- if (accessSemantics.kind == AccessKind.DYNAMIC) {
- variableSelector = new Selector.setter(
- node.identifier.name, converter.convertElement(currentLibrary));
- } else if (accessSemantics.element != null) {
- variableElement = converter.convertElement(accessSemantics.element);
- variableSelector = new Selector.setter(
- variableElement.name,
- converter.convertElement(accessSemantics.element.library));
- } else {
- giveUp(node, 'For-in of unresolved variable: $accessSemantics');
- }
- } else {
- assert(invariant(
- node, node.loopVariable != null, "Loop variable expected"));
- variableElement = converter.convertElement(node.loopVariable.element);
- buildVariableDeclaration = (IrBuilder builder) {
- builder.declareLocalVariable(variableElement);
- };
- }
- // TODO(johnniwinther): Support `for-in` as a jump target.
- irBuilder.buildForIn(
- buildExpression: subbuild(node.iterable),
- buildVariableDeclaration: buildVariableDeclaration,
- variableElement: variableElement,
- variableSelector: variableSelector,
- buildBody: subbuild(node.body));
- }
- @override
- ir.Primitive visitIsExpression(IsExpression node) {
- return irBuilder.buildTypeOperator(
- visit(node.expression),
- converter.convertType(node.type.type),
- isTypeTest: true,
- isNotCheck: node.notOperator != null);
- }
-
- @override
- ir.Primitive visitAsExpression(AsExpression node) {
- return irBuilder.buildTypeOperator(
- visit(node.expression),
- converter.convertType(node.type.type),
- isTypeTest: false);
- }
-
- @override
- visitTryStatement(TryStatement node) {
- List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
- for (CatchClause catchClause in node.catchClauses) {
- catchClauseInfos.add(new CatchClauseInfo(
- exceptionVariable: converter.convertElement(
- catchClause.exceptionParameter.staticElement),
- buildCatchBlock: subbuild(catchClause.body)));
-
- }
- irBuilder.buildTry(
- tryStatementInfo: new TryStatementInfo(),
- buildTryBlock: subbuild(node.body),
- catchClauseInfos: catchClauseInfos);
- }
-}
diff --git a/pkg/analyzer2dart/lib/src/dart_backend.dart b/pkg/analyzer2dart/lib/src/dart_backend.dart
deleted file mode 100644
index 317fd2c..0000000
--- a/pkg/analyzer2dart/lib/src/dart_backend.dart
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer2dart.dart_backend;
-
-import 'package:compiler/src/constant_system_dart.dart';
-import 'package:compiler/src/constants/constant_system.dart';
-import 'package:compiler/src/dart_backend/dart_backend.dart';
-import 'package:compiler/src/dart2jslib.dart';
-import 'package:compiler/src/dart_types.dart';
-import 'package:compiler/src/elements/elements.dart';
-
-import 'driver.dart';
-import 'converted_world.dart';
-
-void compileToDart(Driver driver, ConvertedWorld convertedWorld) {
- DiagnosticListener listener = new Listener();
- DartOutputter outputter = new DartOutputter(listener, driver.outputProvider);
- ElementAstCreationContext context = new _ElementAstCreationContext(
- listener, convertedWorld.dartTypes);
- outputter.assembleProgram(
- libraries: convertedWorld.libraries,
- instantiatedClasses: convertedWorld.instantiatedClasses,
- resolvedElements: convertedWorld.resolvedElements,
- mainFunction: convertedWorld.mainFunction,
- computeElementAst: (Element element) {
- return DartBackend.createElementAst(
- context,
- element,
- convertedWorld.getIr(element));
- },
- shouldOutput: (Element element) => !element.isSynthesized,
- isSafeToRemoveTypeDeclarations: (_) => false);
-}
-
-class _ElementAstCreationContext implements ElementAstCreationContext {
- final Listener listener;
-
- @override
- final DartTypes dartTypes;
-
- _ElementAstCreationContext(this.listener, this.dartTypes);
-
- @override
- ConstantSystem get constantSystem => DART_CONSTANT_SYSTEM;
-
- @override
- InternalErrorFunction get internalError => listener.internalError;
-
- @override
- void traceCompilation(String name) {
- // Do nothing.
- }
-
- @override
- void traceGraph(String title, irObject) {
- // Do nothing.
- }
-}
-
-class Listener implements DiagnosticListener {
-
- @override
- void internalError(Spannable spannable, message) {
- throw new UnimplementedError(message);
- }
-
- @override
- void log(message) {
- // TODO: implement log
- }
-
- @override
- void reportError(Spannable node,
- MessageKind errorCode,
- [Map arguments = const {}]) {
- // TODO: implement reportError
- }
-
- @override
- void reportHint(Spannable node,
- MessageKind errorCode,
- [Map arguments = const {}]) {
- // TODO: implement reportHint
- }
-
- @override
- void reportInfo(Spannable node,
- MessageKind errorCode,
- [Map arguments = const {}]) {
- // TODO: implement reportInfo
- }
-
- @override
- void reportWarning(Spannable node,
- MessageKind errorCode,
- [Map arguments = const {}]) {
- // TODO: implement reportWarning
- }
-
- @override
- spanFromSpannable(Spannable node) {
- // TODO: implement spanFromSpannable
- }
-
- @override
- withCurrentElement(element, f()) {
- // TODO: implement withCurrentElement
- }
-}
diff --git a/pkg/analyzer2dart/lib/src/driver.dart b/pkg/analyzer2dart/lib/src/driver.dart
deleted file mode 100644
index 9707356..0000000
--- a/pkg/analyzer2dart/lib/src/driver.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer2dart.driver;
-
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-
-import 'package:compiler/compiler.dart';
-
-import 'closed_world.dart';
-import 'tree_shaker.dart';
-
-/**
- * Top level driver for Analyzer2Dart.
- */
-class Driver {
- final ResourceProvider resourceProvider;
- final AnalysisContext context;
- final CompilerOutputProvider outputProvider;
-
- Driver(this.resourceProvider, DartSdk sdk, this.outputProvider)
- : context = AnalysisEngine.instance.createAnalysisContext() {
- // Set up the source factory.
- // TODO(paulberry): do we want to use ExplicitPackageUriResolver?
- List<UriResolver> uriResolvers = [
- new FileUriResolver(),
- new DartUriResolver(sdk) /* ,
- new PackageUriResolver(packagesDirectories) */
- ];
- context.sourceFactory = new SourceFactory(uriResolvers);
- }
-
- /**
- * Compute the closed world that is reachable from an entry point.
- */
- ClosedWorld computeWorld(FunctionElement entryPointElement) {
- InternalAnalysisContext analysisContext = context;
- TreeShaker treeShaker =
- new TreeShaker(analysisContext.typeProvider, entryPointElement);
- return treeShaker.shake();
- }
-
- /**
- * Given a source, resolve it and return its entry point.
- */
- FunctionElement resolveEntryPoint(Source source) {
- // Get the library element associated with the source.
- LibraryElement libraryElement = context.computeLibraryElement(source);
-
- // Get the resolved AST for main
- FunctionElement entryPointElement = libraryElement.entryPoint;
- if (entryPointElement == null) {
- throw new Exception('No main()!');
- }
- return entryPointElement;
- }
-
- /**
- * Add the given file as the root of analysis, and return the corresponding
- * source.
- */
- Source setRoot(String path) {
- File file = resourceProvider.getResource(path);
- Source source = file.createSource();
- // add the Source
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source);
- context.applyChanges(changeSet);
- // return the Source
- return source;
- }
-}
diff --git a/pkg/analyzer2dart/lib/src/element_converter.dart b/pkg/analyzer2dart/lib/src/element_converter.dart
deleted file mode 100644
index 666124e..0000000
--- a/pkg/analyzer2dart/lib/src/element_converter.dart
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Convertion of elements between the analyzer element model and the dart2js
-/// element model.
-
-library analyzer2dart.element_converter;
-
-import 'package:compiler/src/elements/elements.dart' as dart2js;
-import 'package:compiler/src/util/util.dart' as util;
-import 'package:compiler/src/dart_types.dart' as dart2js;
-import 'package:analyzer/src/generated/element.dart' as analyzer;
-import 'package:analyzer/src/generated/utilities_dart.dart';
-
-part 'modely.dart';
-
-class ElementConverter {
- /// Map from analyzer elements to their equivalent dart2js elements.
- Map<analyzer.Element, dart2js.Element> conversionMap =
- <analyzer.Element, dart2js.Element>{};
-
- /// Map from dart2js elements to their equivalent analyzer elements.
- Map<dart2js.Element, analyzer.Element> inversionMap =
- <dart2js.Element, analyzer.Element>{};
-
- ElementConverterVisitor visitor;
-
- ElementConverter() {
- visitor = new ElementConverterVisitor(this);
- }
-
- dart2js.Element convertElement(analyzer.Element input) {
- return conversionMap.putIfAbsent(input, () {
- dart2js.Element output = convertElementInternal(input);
- inversionMap[output] = input;
- return output;
- });
- }
-
- dart2js.FunctionType convertFunctionType(analyzer.FunctionType input) {
- dart2js.DartType returnType = convertType(input.returnType);
- List<dart2js.DartType> requiredParameterTypes =
- input.normalParameterTypes.map(convertType).toList();
- List<dart2js.DartType> positionalParameterTypes =
- input.optionalParameterTypes.map(convertType).toList();
- List<String> namedParameters =
- input.namedParameterTypes.keys.toList()..sort();
- List<dart2js.DartType> namedParameterTypes =
- namedParameters.map((String name) {
- return convertType(input.namedParameterTypes[name]);
- }).toList();
- return new dart2js.FunctionType.synthesized(
- returnType,
- requiredParameterTypes,
- positionalParameterTypes,
- namedParameters,
- namedParameterTypes);
- }
-
- dart2js.DartType convertType(analyzer.DartType input) {
- if (input.isVoid) {
- return const dart2js.VoidType();
- } else if (input.isDynamic) {
- return const dart2js.DynamicType();
- } else if (input is analyzer.TypeParameterType) {
- return new dart2js.TypeVariableType(convertElement(input.element));
- } else if (input is analyzer.InterfaceType) {
- List<dart2js.DartType> typeArguments =
- input.typeArguments.map(convertType).toList();
- return new dart2js.InterfaceType(
- convertElement(input.element), typeArguments);
- } else if (input is analyzer.FunctionType) {
- if (input.element is analyzer.FunctionTypeAliasElement) {
- List<dart2js.DartType> typeArguments =
- input.typeArguments.map(convertType).toList();
- return new dart2js.ResolvedTypedefType(
- convertElement(input.element),
- typeArguments,
- convertFunctionType(input));
- } else {
- assert(input.typeArguments.isEmpty);
- return convertFunctionType(input);
- }
- }
- throw new UnsupportedError(
- "Conversion of $input (${input.runtimeType}) is not supported.");
- }
-
- analyzer.Element invertElement(dart2js.Element input) {
- return inversionMap[input];
- }
-
- dart2js.Element convertElementInternal(analyzer.Element input) {
- dart2js.Element output = input.accept(visitor);
- if (output != null) return output;
- throw new UnsupportedError(
- "Conversion of $input (${input.runtimeType}) is not supported.");
- }
-}
-
-/// Visitor that converts analyzer elements to dart2js elements.
-class ElementConverterVisitor
- extends analyzer.SimpleElementVisitor<dart2js.Element> {
- final ElementConverter converter;
-
- ElementConverterVisitor(this.converter);
-
- @override
- dart2js.LibraryElement visitLibraryElement(analyzer.LibraryElement input) {
- return new LibraryElementY(converter, input);
- }
-
- @override
- dart2js.FunctionElement visitFunctionElement(analyzer.FunctionElement input) {
- if (input.isStatic) {
- return new TopLevelFunctionElementY(converter, input);
- } else {
- return new LocalFunctionElementY(converter, input);
- }
- }
-
- @override
- dart2js.ParameterElement visitParameterElement(
- analyzer.ParameterElement input) {
- return new ParameterElementY(converter, input);
- }
-
- @override
- dart2js.ClassElement visitClassElement(analyzer.ClassElement input) {
- return new ClassElementY(converter, input);
- }
-
- @override
- dart2js.TypedefElement visitFunctionTypeAliasElement(
- analyzer.FunctionTypeAliasElement input) {
- return new TypedefElementY(converter, input);
- }
-
- @override
- dart2js.FieldElement visitTopLevelVariableElement(
- analyzer.TopLevelVariableElement input) {
- return new TopLevelVariableElementY(converter, input);
- }
-
- @override
- dart2js.Element visitPropertyAccessorElement(
- analyzer.PropertyAccessorElement input) {
- if (input.isSynthetic) {
- return input.variable.accept(this);
- }
- return null;
- }
-
- @override
- dart2js.Element visitLocalVariableElement(
- analyzer.LocalVariableElement input) {
- return new LocalVariableElementY(converter, input);
- }
-
- @override
- dart2js.ConstructorElement visitConstructorElement(
- analyzer.ConstructorElement input) {
- return new ConstructorElementY(converter, input);
- }
-
- @override
- dart2js.MethodElement visitMethodElement(analyzer.MethodElement input) {
- return new InstanceMethodElementY(converter, input);
- }
-}
diff --git a/pkg/analyzer2dart/lib/src/identifier_semantics.dart b/pkg/analyzer2dart/lib/src/identifier_semantics.dart
deleted file mode 100644
index a61cfa0..0000000
--- a/pkg/analyzer2dart/lib/src/identifier_semantics.dart
+++ /dev/null
@@ -1,516 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Code for classifying the semantics of identifiers appearing in a Dart file.
- */
-library analyzer2dart.identifierSemantics;
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/element.dart';
-
-// TODO(johnniwinther,paulberry): This should be a constant.
-final AccessSemanticsVisitor ACCESS_SEMANTICS_VISITOR =
- new AccessSemanticsVisitor();
-
-/**
- * Enum representing the different kinds of destinations which a property
- * access or method or function invocation might refer to.
- */
-class AccessKind {
- /**
- * The destination of the access is an instance method, property, or field
- * of a class, and thus must be determined dynamically.
- */
- static const AccessKind DYNAMIC = const AccessKind._('DYNAMIC');
-
- /**
- * The destination of the access is a function that is defined locally within
- * an enclosing function or method.
- */
- static const AccessKind LOCAL_FUNCTION = const AccessKind._('LOCAL_FUNCTION');
-
- /**
- * The destination of the access is a variable that is defined locally within
- * an enclosing function or method.
- */
- static const AccessKind LOCAL_VARIABLE = const AccessKind._('LOCAL_VARIABLE');
-
- /**
- * The destination of the access is a variable that is defined as a parameter
- * to an enclosing function or method.
- */
- static const AccessKind PARAMETER = const AccessKind._('PARAMETER');
-
- /**
- * The destination of the access is a field that is defined statically within
- * a class, or a top level variable within a library.
- */
- static const AccessKind STATIC_FIELD = const AccessKind._('STATIC_FIELD');
-
- /**
- * The destination of the access is a method that is defined statically
- * within a class, or at top level within a library.
- */
- static const AccessKind STATIC_METHOD = const AccessKind._('STATIC_METHOD');
-
- /**
- * The destination of the access is a property getter/setter that is defined
- * statically within a class, or at top level within a library.
- */
- static const AccessKind STATIC_PROPERTY =
- const AccessKind._('STATIC_PROPERTY');
-
- /**
- * The destination of the access is a toplevel class, function typedef, mixin
- * application, or the built-in type "dynamic".
- */
- static const AccessKind TOPLEVEL_TYPE = const AccessKind._('TOPLEVEL_TYPE');
-
- /**
- * The destination of the access is a type parameter of the enclosing class.
- */
- static const AccessKind TYPE_PARAMETER = const AccessKind._('TYPE_PARAMETER');
-
- final String name;
-
- const AccessKind._(this.name);
-
- String toString() => name;
-}
-
-/**
- * Data structure used to classify the semantics of a property access or method
- * or function invocation.
- */
-// TODO(paulberry,johnniwinther): Support index operations in AccessSemantics.
-class AccessSemantics {
- /**
- * The kind of access.
- */
- final AccessKind kind;
-
- /**
- * The identifier being used to access the property, method, or function.
- */
- final SimpleIdentifier identifier;
-
- /**
- * The element being accessed, if statically known. This will be null if
- * [kind] is DYNAMIC or if the element is undefined (e.g. an attempt to
- * access a non-existent static method in a class).
- */
- final Element element;
-
- /**
- * The class containing the element being accessed, if this is a static
- * reference to an element in a class. This will be null if [kind] is
- * DYNAMIC, LOCAL_FUNCTION, LOCAL_VARIABLE, PARAMETER, TOPLEVEL_CLASS, or
- * TYPE_PARAMETER, or if the element being accessed is defined at toplevel
- * within a library.
- *
- * Note: it is possible for [classElement] to be non-null and for [element]
- * to be null; for example this occurs if the element being accessed is a
- * non-existent static method or field inside an existing class.
- */
- final ClassElement classElement;
-
- // TODO(paulberry): would it also be useful to store the libraryElement?
-
- /**
- * When [kind] is DYNAMIC, the expression whose runtime type determines the
- * class in which [identifier] should be looked up. Null if the expression
- * is implicit "this".
- *
- * When [kind] is not DYNAMIC, this field is always null.
- */
- final Expression target;
-
- /**
- * True if this is an invocation of a method, or a call on a property.
- */
- final bool isInvoke;
-
- AccessSemantics.dynamic(this.identifier, this.target, {this.isInvoke: false})
- : kind = AccessKind.DYNAMIC,
- element = null,
- classElement = null;
-
- AccessSemantics.localFunction(this.identifier, this.element, {this.isInvoke:
- false})
- : kind = AccessKind.LOCAL_FUNCTION,
- classElement = null,
- target = null;
-
- AccessSemantics.localVariable(this.identifier, this.element, {this.isInvoke:
- false})
- : kind = AccessKind.LOCAL_VARIABLE,
- classElement = null,
- target = null;
-
- AccessSemantics.parameter(this.identifier, this.element, {this.isInvoke:
- false})
- : kind = AccessKind.PARAMETER,
- classElement = null,
- target = null;
-
- AccessSemantics.staticField(this.identifier, this.element, this.classElement,
- {this.isInvoke: false})
- : kind = AccessKind.STATIC_FIELD,
- target = null;
-
- AccessSemantics.staticMethod(this.identifier, this.element, this.classElement,
- {this.isInvoke: false})
- : kind = AccessKind.STATIC_METHOD,
- target = null;
-
- AccessSemantics.staticProperty(this.identifier, this.element,
- this.classElement, {this.isInvoke: false})
- : kind = AccessKind.STATIC_PROPERTY,
- target = null;
-
- AccessSemantics.toplevelType(this.identifier, this.element, {this.isInvoke:
- false})
- : kind = AccessKind.TOPLEVEL_TYPE,
- classElement = null,
- target = null;
-
- AccessSemantics.typeParameter(this.identifier, this.element, {this.isInvoke:
- false})
- : kind = AccessKind.TYPE_PARAMETER,
- classElement = null,
- target = null;
-
- /**
- * True if this is a read access to a property, or a method tear-off. Note
- * that both [isRead] and [isWrite] will be true in the case of a
- * read-modify-write operation (e.g. "+=").
- */
- bool get isRead => !isInvoke && identifier.inGetterContext();
-
- /**
- * True if this is a write access to a property, or an (erroneous) attempt to
- * write to a method. Note that both [isRead] and [isWrite] will be true in
- * the case of a read-modify-write operation (e.g. "+=").
- */
- bool get isWrite => identifier.inSetterContext();
-
- String toString() {
- StringBuffer sb = new StringBuffer();
- sb.write('AccessSemantics[');
- sb.write('kind=$kind,');
- if (isRead && isWrite) {
- assert(!isInvoke);
- sb.write('read/write,');
- } else if (isRead) {
- sb.write('read,');
- } else if (isWrite) {
- sb.write('write,');
- } else if (isInvoke) {
- sb.write('call,');
- }
- if (element != null) {
- sb.write('element=');
- if (classElement != null) {
- sb.write('${classElement.name}.');
- }
- sb.write('${element}');
- } else {
- if (target == null) {
- sb.write('target=this.$identifier');
- } else {
- sb.write('target=$target.$identifier');
- }
- }
- sb.write(']');
- return sb.toString();
- }
-}
-
-// TODO(johnniwinther,paulberry): This should extend a non-recursive visitor.
-class AccessSemanticsVisitor extends RecursiveAstVisitor<AccessSemantics> {
- /**
- * Return the semantics for [node].
- */
- @override
- AccessSemantics visitMethodInvocation(MethodInvocation node) {
- Expression target = node.realTarget;
- Element staticElement = node.methodName.staticElement;
- if (target == null) {
- if (staticElement is FunctionElement) {
- if (staticElement.enclosingElement is CompilationUnitElement) {
- return new AccessSemantics.staticMethod(
- node.methodName,
- staticElement,
- null,
- isInvoke: true);
- } else {
- return new AccessSemantics.localFunction(
- node.methodName,
- staticElement,
- isInvoke: true);
- }
- } else if (staticElement is MethodElement && staticElement.isStatic) {
- return new AccessSemantics.staticMethod(
- node.methodName,
- staticElement,
- staticElement.enclosingElement,
- isInvoke: true);
- } else if (staticElement is PropertyAccessorElement) {
- if (staticElement.isSynthetic) {
- if (staticElement.enclosingElement is CompilationUnitElement) {
- return new AccessSemantics.staticField(
- node.methodName,
- staticElement.variable,
- null,
- isInvoke: true);
- } else if (staticElement.isStatic) {
- return new AccessSemantics.staticField(
- node.methodName,
- staticElement.variable,
- staticElement.enclosingElement,
- isInvoke: true);
- }
- } else {
- if (staticElement.enclosingElement is CompilationUnitElement) {
- return new AccessSemantics.staticProperty(
- node.methodName,
- staticElement,
- null,
- isInvoke: true);
- } else if (staticElement.isStatic) {
- return new AccessSemantics.staticProperty(
- node.methodName,
- staticElement,
- staticElement.enclosingElement,
- isInvoke: true);
- }
- }
- } else if (staticElement is LocalVariableElement) {
- return new AccessSemantics.localVariable(
- node.methodName,
- staticElement,
- isInvoke: true);
- } else if (staticElement is ParameterElement) {
- return new AccessSemantics.parameter(
- node.methodName,
- staticElement,
- isInvoke: true);
- } else if (staticElement is TypeParameterElement) {
- return new AccessSemantics.typeParameter(
- node.methodName,
- staticElement,
- isInvoke: true);
- } else if (staticElement is ClassElement ||
- staticElement is FunctionTypeAliasElement ||
- staticElement is DynamicElementImpl) {
- return new AccessSemantics.toplevelType(
- node.methodName,
- staticElement,
- isInvoke: true);
- }
- } else if (target is Identifier) {
- Element targetStaticElement = target.staticElement;
- if (targetStaticElement is PrefixElement) {
- if (staticElement == null) {
- return new AccessSemantics.dynamic(
- node.methodName,
- null,
- isInvoke: true);
- } else if (staticElement is PropertyAccessorElement) {
- if (staticElement.isSynthetic) {
- return new AccessSemantics.staticField(
- node.methodName,
- staticElement.variable,
- null,
- isInvoke: true);
- } else {
- return new AccessSemantics.staticProperty(
- node.methodName,
- staticElement,
- null,
- isInvoke: true);
- }
- } else if (staticElement is TypeParameterElement) {
- return new AccessSemantics.typeParameter(
- node.methodName,
- staticElement,
- isInvoke: true);
- } else if (staticElement is ClassElement ||
- staticElement is FunctionTypeAliasElement) {
- return new AccessSemantics.toplevelType(
- node.methodName,
- staticElement,
- isInvoke: true);
- } else {
- return new AccessSemantics.staticMethod(
- node.methodName,
- staticElement,
- null,
- isInvoke: true);
- }
- } else if (targetStaticElement is ClassElement) {
- if (staticElement is PropertyAccessorElement) {
- if (staticElement.isSynthetic) {
- return new AccessSemantics.staticField(
- node.methodName,
- staticElement.variable,
- targetStaticElement,
- isInvoke: true);
- } else {
- return new AccessSemantics.staticProperty(
- node.methodName,
- staticElement,
- targetStaticElement,
- isInvoke: true);
- }
- } else {
- return new AccessSemantics.staticMethod(
- node.methodName,
- staticElement,
- targetStaticElement,
- isInvoke: true);
- }
- }
- }
- return new AccessSemantics.dynamic(node.methodName, target, isInvoke: true);
- }
-
- /**
- * Return the access semantics for [node].
- */
- @override
- AccessSemantics visitPrefixedIdentifier(PrefixedIdentifier node) {
- return _classifyPrefixed(node.prefix, node.identifier);
- }
-
- /**
- * Return the access semantics for [node].
- */
- @override
- AccessSemantics visitPropertyAccess(PropertyAccess node) {
- if (node.target is Identifier) {
- return _classifyPrefixed(node.target, node.propertyName);
- } else {
- return new AccessSemantics.dynamic(node.propertyName, node.realTarget);
- }
- }
-
- /**
- * Return the access semantics for [node].
- *
- * Note: if [node] is the right hand side of a [PropertyAccess] or
- * [PrefixedIdentifier], or the method name of a [MethodInvocation], the return
- * value is null, since the semantics are determined by the parent. In
- * practice these cases should never arise because the parent will visit the
- * parent node before visiting this one.
- */
- @override
- AccessSemantics visitSimpleIdentifier(SimpleIdentifier node) {
- AstNode parent = node.parent;
- if (node.inDeclarationContext()) {
- // This identifier is a declaration, not a use.
- return null;
- }
- if (parent is TypeName) {
- // TODO(paulberry): do we need to handle this case?
- return null;
- }
- if ((parent is PropertyAccess && parent.propertyName == node) ||
- (parent is PrefixedIdentifier && parent.identifier == node) ||
- (parent is MethodInvocation && parent.methodName == node)) {
- // The access semantics are determined by the parent.
- return null;
- }
- // TODO(paulberry): handle PrefixElement.
- Element staticElement = node.staticElement;
- if (staticElement is PropertyAccessorElement) {
- if (staticElement.isSynthetic) {
- if (staticElement.enclosingElement is CompilationUnitElement) {
- return new AccessSemantics.staticField(
- node,
- staticElement.variable,
- null);
- } else if (staticElement.isStatic) {
- return new AccessSemantics.staticField(
- node,
- staticElement.variable,
- staticElement.enclosingElement);
- }
- } else {
- if (staticElement.enclosingElement is CompilationUnitElement) {
- return new AccessSemantics.staticProperty(node, staticElement, null);
- } else if (staticElement.isStatic) {
- return new AccessSemantics.staticProperty(
- node,
- staticElement,
- staticElement.enclosingElement);
- }
- }
- } else if (staticElement is LocalVariableElement) {
- return new AccessSemantics.localVariable(node, staticElement);
- } else if (staticElement is ParameterElement) {
- return new AccessSemantics.parameter(node, staticElement);
- } else if (staticElement is FunctionElement) {
- if (staticElement.enclosingElement is CompilationUnitElement) {
- return new AccessSemantics.staticMethod(node, staticElement, null);
- } else {
- return new AccessSemantics.localFunction(node, staticElement);
- }
- } else if (staticElement is MethodElement && staticElement.isStatic) {
- return new AccessSemantics.staticMethod(
- node,
- staticElement,
- staticElement.enclosingElement);
- } else if (staticElement is TypeParameterElement) {
- return new AccessSemantics.typeParameter(node, staticElement);
- } else if (staticElement is ClassElement ||
- staticElement is FunctionTypeAliasElement ||
- staticElement is DynamicElementImpl) {
- return new AccessSemantics.toplevelType(node, staticElement);
- }
- return new AccessSemantics.dynamic(node, null);
- }
-
- /**
- * Helper function for classifying an expression of type
- * Identifier.SimpleIdentifier.
- */
- AccessSemantics _classifyPrefixed(Identifier lhs, SimpleIdentifier rhs) {
- Element lhsElement = lhs.staticElement;
- Element rhsElement = rhs.staticElement;
- if (lhsElement is PrefixElement) {
- if (rhsElement is PropertyAccessorElement) {
- if (rhsElement.isSynthetic) {
- return new AccessSemantics.staticField(
- rhs,
- rhsElement.variable,
- null);
- } else {
- return new AccessSemantics.staticProperty(rhs, rhsElement, null);
- }
- } else if (rhsElement is FunctionElement) {
- return new AccessSemantics.staticMethod(rhs, rhsElement, null);
- } else if (rhsElement is ClassElement ||
- rhsElement is FunctionTypeAliasElement) {
- return new AccessSemantics.toplevelType(rhs, rhsElement);
- } else {
- return new AccessSemantics.dynamic(rhs, null);
- }
- } else if (lhsElement is ClassElement) {
- if (rhsElement is PropertyAccessorElement && rhsElement.isSynthetic) {
- return new AccessSemantics.staticField(
- rhs,
- rhsElement.variable,
- lhsElement);
- } else if (rhsElement is MethodElement) {
- return new AccessSemantics.staticMethod(rhs, rhsElement, lhsElement);
- } else {
- return new AccessSemantics.staticProperty(rhs, rhsElement, lhsElement);
- }
- } else {
- return new AccessSemantics.dynamic(rhs, lhs);
- }
- }
-}
diff --git a/pkg/analyzer2dart/lib/src/modely.dart b/pkg/analyzer2dart/lib/src/modely.dart
deleted file mode 100644
index e865675..0000000
--- a/pkg/analyzer2dart/lib/src/modely.dart
+++ /dev/null
@@ -1,914 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of analyzer2dart.element_converter;
-
-
-/// Base [dart2js.Element] implementation for converted analyzer elements.
-class ElementY extends dart2js.Element {
- final ElementConverter converter;
- final analyzer.Element element;
-
- @override
- String get name => element.name;
-
- ElementY(this.converter, this.element);
-
- @override
- dart2js.LibraryElement get implementationLibrary => library;
-
- @override
- dart2js.Element get origin => this;
-
- @override
- dart2js.Element get patch => null;
-
- @override
- dart2js.Element get declaration => this;
-
- @override
- dart2js.Element get implementation => this;
-
- @override
- bool get isPatch => false;
-
- @override
- bool get isPatched => false;
-
- @override
- bool get isDeclaration => true;
-
- @override
- bool get isImplementation => false;
-
- @override
- dart2js.LibraryElement get library {
- return converter.convertElement(element.library);
- }
-
- @override
- bool get isLocal => false;
-
- @override
- bool get isSynthesized => false;
-
- unsupported(String method) {
- throw new UnsupportedError(
- "'$method' is unsupported on $this ($runtimeType)");
- }
-
-
- @override
- bool get isFinal => unsupported('isFinal');
-
- @override
- bool get isStatic => unsupported('isStatic');
-
- @override
- bool isForeign(_) => unsupported('isForeign');
-
- @override
- bool get impliesType => unsupported('impliesType');
-
- @override
- bool get isOperator => unsupported('impliesType');
-
- @override
- get position => unsupported('position');
-
- @override
- computeType(_) => unsupported('computeType');
-
- @override
- get enclosingElement => unsupported('enclosingElement');
-
- @override
- accept(_, __) => unsupported('accept');
-
- @override
- void addMetadata(_) => unsupported('addMetadata');
-
- @override
- get analyzableElement => unsupported('analyzableElement');
-
- @override
- asFunctionElement() => unsupported('asFunctionElement');
-
- @override
- buildScope() => unsupported('buildScope');
-
- @override
- get compilationUnit => unsupported('compilationUnit');
-
- @override
- get contextClass => unsupported('contextClass');
-
- @override
- void diagnose(context, listener) => unsupported('diagnose');
-
- @override
- get enclosingClass => unsupported('enclosingClass');
-
- @override
- get enclosingClassOrCompilationUnit {
- return unsupported('enclosingClassOrCompilationUnit');
- }
-
- @override
- String get fixedBackendName => unsupported('fixedBackendName');
-
- @override
- bool get hasFixedBackendName => unsupported('hasFixedBackendName');
-
- @override
- bool get isAbstract => unsupported('isAbstract');
-
- @override
- bool get isAssignable => unsupported('isAssignable');
-
- @override
- bool get isClassMember => unsupported('isClassMember');
-
- @override
- bool get isClosure => unsupported('isClosure');
-
- @override
- bool get isConst => unsupported('isConst');
-
- @override
- bool get isDeferredLoaderGetter => unsupported('isDeferredLoaderGetter');
-
- @override
- bool get isFactoryConstructor => unsupported('isFactoryConstructor');
-
- @override
- bool get isInjected => unsupported('isInjected');
-
- @override
- bool get isInstanceMember => unsupported('isInstanceMember');
-
- @override
- bool get isMixinApplication => unsupported('isMixinApplication');
-
- @override
- bool get isNative => unsupported('isNative');
-
- @override
- bool get isTopLevel => unsupported('isTopLevel');
-
- @override
- get kind => unsupported('kind');
-
- @override
- get metadata => unsupported('metadata');
-
- @override
- get outermostEnclosingMemberOrTopLevel {
- return unsupported('outermostEnclosingMemberOrTopLevel');
- }
-
- @override
- void setNative(String name) => unsupported('setNative');
-
- String toString() => '$kind($name)';
-}
-
-abstract class AnalyzableElementY
- implements ElementY, dart2js.AnalyzableElement {
- @override
- bool get hasTreeElements => unsupported('hasTreeElements');
-
- @override
- get treeElements => unsupported('treeElements');
-}
-
-abstract class AstElementY implements ElementY, dart2js.AstElement {
- @override
- bool get hasNode => unsupported('hasNode');
-
- @override
- get node => unsupported('node');
-
- @override
- bool get hasResolvedAst => unsupported('hasResolvedAst');
-
- @override
- get resolvedAst => unsupported('resolvedAst');
-}
-
-class LibraryElementY extends ElementY with AnalyzableElementY
- implements dart2js.LibraryElement {
- analyzer.LibraryElement get element => super.element;
-
- @override
- dart2js.ElementKind get kind => dart2js.ElementKind.LIBRARY;
-
- // TODO(johnniwinther): Ensure the correct semantics of this.
- @override
- bool get isInternalLibrary => isPlatformLibrary && element.isPrivate;
-
- // TODO(johnniwinther): Ensure the correct semantics of this.
- @override
- bool get isPlatformLibrary => element.isInSdk;
-
- @override
- bool get isDartCore => element.isDartCore;
-
- LibraryElementY(ElementConverter converter, analyzer.LibraryElement element)
- : super(converter, element);
-
- @override
- void addCompilationUnit(_) => unsupported('addCompilationUnit');
-
- @override
- void addImport(element, import, listener) => unsupported('addImport');
-
- @override
- void addMember(element, listener) => unsupported('addMember');
-
- @override
- void addTag(tag, listener) => unsupported('addTag');
-
- @override
- void addToScope(element, listener) => unsupported('addToScope');
-
- @override
- bool get canUseNative => unsupported('canUseNative');
-
- @override
- Uri get canonicalUri => unsupported('canonicalUri');
-
- @override
- int compareTo(other) => unsupported('compareTo');
-
- @override
- get compilationUnits => unsupported('compilationUnits');
-
- @override
- get entryCompilationUnit => unsupported('entryCompilationUnit');
-
- @override
- get exports => unsupported('exports');
-
- @override
- bool get exportsHandled => unsupported('exportsHandled');
-
- @override
- find(String elementName) => unsupported('find');
-
- @override
- findExported(String elementName) => unsupported('findExported');
-
- @override
- findLocal(String elementName) => unsupported('findLocal');
-
- @override
- void forEachExport(_) => unsupported('forEachExport');
-
- @override
- void forEachLocalMember(_) => unsupported('forEachLocalMember');
-
- @override
- getImportsFor(element) => unsupported('getImportsFor');
-
- @override
- getLibraryFromTag(tag) => unsupported('getLibraryFromTag');
-
- @override
- String getLibraryName() => unsupported('getLibraryName');
-
- @override
- String getLibraryOrScriptName() => unsupported('getLibraryOrScriptName');
-
- @override
- getNonPrivateElementsInScope() => unsupported('getNonPrivateElementsInScope');
-
- @override
- bool hasLibraryName() => unsupported('hasLibraryName');
-
- @override
- bool get isPackageLibrary => unsupported('isPackageLibrary');
-
- @override
- get libraryTag => unsupported('libraryTag');
-
- @override
- void set libraryTag(value) => unsupported('libraryTag');
-
- @override
- localLookup(elementName) => unsupported('localLookup');
-
- @override
- void recordResolvedTag(tag, library) => unsupported('recordResolvedTag');
-
- @override
- void setExports(exportedElements) => unsupported('setExports');
-
- @override
- get tags => unsupported('tags');
-}
-
-abstract class TopLevelElementMixin implements ElementY {
- @override
- bool get isClassMember => false;
-
- @override
- bool get isInstanceMember => false;
-
- @override
- bool get isTopLevel => true;
-
- // TODO(johnniwinther): Ensure the correct semantics of this.
- @override
- bool get isFactoryConstructor => false;
-
- @override
- bool get isStatic {
- // Semantic difference: Analyzer considers top-level and static class
- // members to be static, dart2js only considers static class members to be
- // static.
- return false;
- }
-
- // TODO(johnniwinther): Ensure the correct semantics of this.
- @override
- bool get isAbstract => false;
-
- @override
- dart2js.ClassElement get enclosingClass => null;
-}
-
-abstract class FunctionElementMixin
- implements ElementY, dart2js.FunctionElement {
- analyzer.ExecutableElement get element;
-
- // TODO(johnniwinther): Ensure the correct semantics of this.
- @override
- bool get isExternal => false;
-
- @override
- bool get isConst => false;
-
- @override
- get abstractField => unsupported('abstractField');
-
- @override
- computeSignature(_) => unsupported('computeSignature');
-
- @override
- get memberContext => unsupported('memberContext');
-
- @override
- get functionSignature => unsupported('functionSignature');
-
- @override
- bool get hasFunctionSignature => unsupported('hasFunctionSignature');
-
- @override
- get asyncMarker => unsupported('asyncMarker');
-
- @override
- List<dart2js.ParameterElement> get parameters {
- return element.parameters.map(converter.convertElement).toList();
- }
-
- @override
- dart2js.FunctionType get type => converter.convertType(element.type);
-}
-
-class TopLevelFunctionElementY extends ElementY
- with AnalyzableElementY,
- AstElementY,
- TopLevelElementMixin,
- FunctionElementMixin,
- MemberElementMixin
- implements dart2js.MethodElement {
- analyzer.FunctionElement get element => super.element;
-
- @override
- dart2js.ElementKind get kind => dart2js.ElementKind.FUNCTION;
-
- TopLevelFunctionElementY(ElementConverter converter,
- analyzer.FunctionElement element)
- : super(converter, element);
-
- @override
- get nestedClosures => unsupported('nestedClosures');
-}
-
-class LocalFunctionElementY extends ElementY
- with AnalyzableElementY,
- AstElementY,
- LocalElementMixin,
- FunctionElementMixin
- implements dart2js.LocalFunctionElement {
- analyzer.FunctionElement get element => super.element;
-
- @override
- dart2js.ElementKind get kind => dart2js.ElementKind.FUNCTION;
-
- @override
- bool get isAbstract => false;
-
- @override
- bool get isConst => false;
-
- LocalFunctionElementY(ElementConverter converter,
- analyzer.FunctionElement element)
- : super(converter, element);
-}
-
-class ParameterElementY extends ElementY
- with AnalyzableElementY, AstElementY, VariableElementMixin
- implements dart2js.ParameterElement {
-
- analyzer.ParameterElement get element => super.element;
-
- @override
- dart2js.ElementKind get kind => dart2js.ElementKind.PARAMETER;
-
- @override
- dart2js.DartType get type => converter.convertType(element.type);
-
- @override
- bool get isLocal => true;
-
- @override
- bool get isStatic => false;
-
- @override
- bool get isConst => false;
-
- @override
- bool get isNamed => element.parameterKind == ParameterKind.NAMED;
-
- @override
- bool get isOptional => element.parameterKind.isOptional;
-
- ParameterElementY(ElementConverter converter,
- analyzer.ParameterElement element)
- : super(converter, element) {
- assert(!element.isInitializingFormal);
- }
-
- @override
- get executableContext => unsupported('executableContext');
-
- @override
- get functionDeclaration => unsupported('functionDeclaration');
-
- @override
- get functionSignature => unsupported('functionSignature');
-}
-
-class TypeDeclarationElementY extends ElementY
- with AnalyzableElementY, AstElementY
- implements dart2js.TypeDeclarationElement {
-
- TypeDeclarationElementY(ElementConverter converter,
- analyzer.Element element)
- : super(converter, element);
-
- @override
- void ensureResolved(compiler) => unsupported('ensureResolved');
-
- @override
- bool get isResolved => unsupported('isResolved');
-
- @override
- get rawType => null;//unsupported('rawType');
-
- @override
- int get resolutionState => unsupported('resolutionState');
-
- @override
- get thisType => unsupported('thisType');
-
- @override
- get typeVariables => unsupported('typeVariables');
-}
-
-class ClassElementY extends TypeDeclarationElementY
- implements dart2js.ClassElement {
-
- analyzer.ClassElement get element => super.element;
-
- dart2js.ElementKind get kind => dart2js.ElementKind.CLASS;
-
- @override
- bool get isObject => element.type.isObject;
-
- // TODO(johnniwinther): Ensure the correct semantics.
- // TODO(paulberry,brianwilkerson): [ClassElement.isTypedef] should probably
- // be renamed to [ClassElement.isNamedMixinApplication].
- @override
- bool get isMixinApplication => element.isTypedef;
-
- @override
- bool get isUnnamedMixinApplication => false;
-
- @override
- bool get isEnumClass => element.isEnum;
-
- @override
- bool get isAbstract => element.isAbstract;
-
- // TODO(johnniwinther): Semantic difference: Dart2js points to unnamed
- // mixin applications, analyzer points to the type in the extends clause or
- // Object if omitted.
- @override
- dart2js.DartType get supertype {
- return element.supertype != null
- ? converter.convertType(element.supertype)
- : null;
- }
-
- @override
- util.Link<dart2js.DartType> get interfaces {
- // TODO(johnniwinther): Support interfaces.
- return const util.Link<dart2js.DartType>();
- }
-
- // TODO(johnniwinther): Support generic classes.
- @override
- List<dart2js.DartType> get typeVariables => const [];
-
- @override
- bool get isStatic => false;
-
- @override
- bool get isTopLevel => true;
-
- @override
- dart2js.ClassElement get enclosingClass => this;
-
- ClassElementY(ElementConverter converter, analyzer.ClassElement element)
- : super(converter, element);
-
- @override
- void addBackendMember(element) => unsupported('addBackendMember');
-
- @override
- void addMember(element, listener) => unsupported('addMember');
-
- @override
- void addToScope(element, listener) => unsupported('addToScope');
-
- @override
- get allSupertypes => unsupported('allSupertypes');
-
- @override
- get allSupertypesAndSelf => unsupported('allSupertypesAndSelf');
-
- @override
- asInstanceOf(cls) => unsupported('asInstanceOf');
-
- @override
- get callType => unsupported('callType');
-
- @override
- computeTypeParameters(compiler) => unsupported('computeTypeParameters');
-
- @override
- get constructors => unsupported('constructors');
-
- @override
- void forEachBackendMember(f) => unsupported('forEachBackendMember');
-
- @override
- void forEachClassMember(f) => unsupported('forEachClassMember');
-
- @override
- void forEachInstanceField(f, {includeSuperAndInjectedMembers: false}) {
- unsupported('forEachInstanceField');
- }
-
- @override
- void forEachInterfaceMember(f) => unsupported('forEachInterfaceMember');
-
- @override
- void forEachLocalMember(f) => unsupported('forEachLocalMember');
-
- @override
- void forEachMember(f,
- {includeBackendMembers: false,
- includeSuperAndInjectedMembers: false}) {
- unsupported('forEachMember');
- }
-
- @override
- void forEachStaticField(f) => unsupported('forEachStaticField');
-
- @override
- bool get hasBackendMembers => unsupported('hasBackendMembers');
-
- @override
- bool get hasConstructor => unsupported('hasConstructor');
-
- @override
- bool hasFieldShadowedBy(fieldMember) => unsupported('hasFieldShadowedBy');
-
- @override
- bool get hasIncompleteHierarchy => unsupported('hasIncompleteHierarchy');
-
- @override
- bool get hasLocalScopeMembers => unsupported('hasLocalScopeMembers');
-
- @override
- int get hierarchyDepth => unsupported('hierarchyDepth');
-
- @override
- int get id => unsupported('id');
-
- @override
- bool implementsFunction(compiler) => unsupported('implementsFunction');
-
- @override
- bool implementsInterface(intrface) => unsupported('implementsInterface');
-
- @override
- bool get isProxy => unsupported('isProxy');
-
- @override
- bool isSubclassOf(cls) => unsupported('isSubclassOf');
-
- @override
- localLookup(String elementName) => unsupported('localLookup');
-
- @override
- lookupBackendMember(String memberName) => unsupported('lookupBackendMember');
-
- @override
- lookupClassMember(name) => unsupported('lookupClassMember');
-
- @override
- lookupConstructor(selector, [noMatch]) => unsupported('lookupConstructor');
-
- @override
- lookupInterfaceMember(name) => unsupported('lookupInterfaceMember');
-
- @override
- lookupLocalMember(String memberName) => unsupported('lookupLocalMember');
-
- @override
- lookupMember(String memberName) => unsupported('lookupMember');
-
- @override
- lookupByName(dart2js.Name memberName) => unsupported('lookupByName');
-
- @override
- lookupSuperMember(String memberName) => unsupported('lookupSuperMember');
-
- @override
- lookupSuperMemberInLibrary(memberName, library) {
- unsupported('lookupSuperMemberInLibrary');
- }
-
- @override
- lookupSuperByName(dart2js.Name memberName) =>
- unsupported('lookupSuperByName');
-
- @override
- String get nativeTagInfo => unsupported('nativeTagInfo');
-
- @override
- void reverseBackendMembers() => unsupported('reverseBackendMembers');
-
- @override
- dart2js.ClassElement get superclass => unsupported('superclass');
-
- @override
- int get supertypeLoadState => unsupported('supertypeLoadState');
-
- @override
- dart2js.ConstructorElement lookupDefaultConstructor() => unsupported('lookupDefaultConstructor');
-}
-
-class TypedefElementY extends TypeDeclarationElementY
- implements dart2js.TypedefElement {
-
- analyzer.FunctionTypeAliasElement get element => super.element;
-
- dart2js.ElementKind get kind => dart2js.ElementKind.TYPEDEF;
-
- TypedefElementY(ElementConverter converter,
- analyzer.FunctionTypeAliasElement element)
- : super(converter, element);
-
- @override
- dart2js.DartType get alias => unsupported('alias');
-
- @override
- void checkCyclicReference(compiler) => unsupported('checkCyclicReference');
-
- @override
- get functionSignature => unsupported('functionSignature');
-}
-
-abstract class VariableElementMixin
- implements ElementY, dart2js.VariableElement {
- @override
- get initializer => unsupported('initializer');
-
- @override
- get memberContext => unsupported('memberContext');
-
- @override
- get constant => unsupported('constant');
-}
-
-class TopLevelVariableElementY extends ElementY
- with AnalyzableElementY,
- AstElementY,
- TopLevelElementMixin,
- VariableElementMixin,
- MemberElementMixin
- implements dart2js.FieldElement {
-
- analyzer.TopLevelVariableElement get element => super.element;
-
- dart2js.ElementKind get kind => dart2js.ElementKind.FIELD;
-
- @override
- dart2js.DartType get type => converter.convertType(element.type);
-
- @override
- bool get isFinal => element.isFinal;
-
- @override
- bool get isConst => element.isConst;
-
- TopLevelVariableElementY(ElementConverter converter,
- analyzer.TopLevelVariableElement element)
- : super(converter, element);
-
- @override
- get nestedClosures => unsupported('nestedClosures');
-}
-
-abstract class LocalElementMixin implements ElementY, dart2js.LocalElement {
-
- @override
- bool get isLocal => true;
-
- @override
- bool get isInstanceMember => false;
-
- @override
- bool get isStatic => false;
-
- @override
- bool get isTopLevel => false;
-
- @override
- get executableContext => unsupported('executableContext');
-
- // TODO(johnniwinther): Ensure the correct semantics of this.
- @override
- bool get isFactoryConstructor => false;
-}
-
-class LocalVariableElementY extends ElementY
- with AnalyzableElementY,
- AstElementY,
- LocalElementMixin,
- VariableElementMixin
- implements dart2js.LocalVariableElement {
-
- analyzer.LocalVariableElement get element => super.element;
-
- dart2js.ElementKind get kind => dart2js.ElementKind.VARIABLE;
-
- @override
- bool get isConst => element.isConst;
-
- LocalVariableElementY(ElementConverter converter,
- analyzer.LocalVariableElement element)
- : super(converter, element);
-
- @override
- dart2js.DartType get type => unsupported('type');
-}
-
-abstract class ClassMemberMixin implements ElementY {
- analyzer.ClassMemberElement get element;
-
- @override
- dart2js.ClassElement get contextClass => enclosingClass;
-
- @override
- dart2js.ClassElement get enclosingClass {
- return converter.convertElement(element.enclosingElement);
- }
-
- @override
- bool get isClassMember => true;
-
- @override
- bool get isTopLevel => false;
-}
-
-class ConstructorElementY extends ElementY
- with AnalyzableElementY,
- AstElementY,
- FunctionElementMixin,
- ClassMemberMixin,
- MemberElementMixin
- implements dart2js.ConstructorElement {
-
- analyzer.ConstructorElement get element => super.element;
-
- // TODO(johnniwinther): Support redirecting/factory constructors.
- @override
- dart2js.ElementKind get kind => dart2js.ElementKind.GENERATIVE_CONSTRUCTOR;
-
- // TODO(johnniwinther): Support factory constructors.
- @override
- bool get isFactoryConstructor => false;
-
- // TODO(johnniwinther): Support redirecting factory constructors.
- @override
- bool get isRedirectingFactory => false;
-
- // TODO(johnniwinther): Support redirecting generative constructors.
- @override
- bool get isRedirectingGenerative => false;
-
- @override
- bool get isStatic => false;
-
- @override
- bool get isSynthesized => element.isSynthetic;
-
- ConstructorElementY(ElementConverter converter,
- analyzer.ConstructorElement element)
- : super(converter, element);
-
- @override
- computeEffectiveTargetType(_) => unsupported('computeEffectiveTargetType');
-
- @override
- get definingConstructor => unsupported('definingConstructor');
-
- @override
- get effectiveTarget => unsupported('effectiveTarget');
-
- @override
- get immediateRedirectionTarget => unsupported('immediateRedirectionTarget');
-
- @override
- get nestedClosures => unsupported('nestedClosures');
-
- @override
- get constantConstructor => unsupported('constantConstructor');
-
- @override
- get isFromEnvironmentConstructor {
- unsupported('isFromEnvironmentConstructor');
- }
-
- @override
- bool get isCyclicRedirection => effectiveTarget.isRedirectingFactory;
-
- // TODO(johnniwinther): implement redirectionDeferredPrefix
- @override
- dart2js.PrefixElement get redirectionDeferredPrefix => null;
-}
-
-class InstanceMethodElementY extends ElementY
- with AnalyzableElementY,
- AstElementY,
- FunctionElementMixin,
- ClassMemberMixin,
- MemberElementMixin
- implements dart2js.MethodElement {
-
- analyzer.MethodElement get element => super.element;
-
- @override
- dart2js.ElementKind get kind => dart2js.ElementKind.FUNCTION;
-
- @override
- bool get isStatic => element.isStatic;
-
- @override
- bool get isAbstract => element.isAbstract;
-
- @override
- bool get isFactoryConstructor => false;
-
- @override
- bool get isInstanceMember => true;
-
- InstanceMethodElementY(ElementConverter converter,
- analyzer.MethodElement element)
- : super(converter, element);
-
- @override
- get nestedClosures => unsupported('nestedClosures');
-}
-
-abstract class MemberElementMixin implements dart2js.MemberElement {
- dart2js.Name get memberName => new dart2js.Name(name, library);
-}
diff --git a/pkg/analyzer2dart/lib/src/semantic_visitor.dart b/pkg/analyzer2dart/lib/src/semantic_visitor.dart
deleted file mode 100644
index b5edd6a..0000000
--- a/pkg/analyzer2dart/lib/src/semantic_visitor.dart
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer2dart.semantic_visitor;
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-import 'util.dart';
-import 'identifier_semantics.dart';
-
-/// An AST visitor which uses the [AccessSemantics] of invocations and accesses
-/// to fine-grain visitor methods.
-abstract class SemanticVisitor<R> extends RecursiveAstVisitor<R> {
-
- Source get currentSource;
-
- void reportMessage(AstNode node, String message) {
- reportSourceMessage(currentSource, node, message);
- }
-
- giveUp(AstNode node, String message) {
- reportMessage(node, message);
- throw new UnimplementedError(message);
- }
-
- bool invariant(AstNode node, condition, String message) {
- if (condition is Function) {
- condition = condition();
- }
- if (!condition) {
- reportMessage(node, message);
- return false;
- }
- return true;
- }
-
- R visitDynamicInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitDynamicInvocation of $semantics');
- }
-
- R visitLocalFunctionInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitLocalFunctionInvocation of $semantics');
- }
-
- R visitLocalVariableInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitLocalVariableInvocation of $semantics');
- }
-
- R visitParameterInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitParameterInvocation of $semantics');
- }
-
- R visitStaticFieldInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticFieldInvocation of $semantics');
- }
-
- R visitStaticMethodInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticMethodInvocation of $semantics');
- }
-
- R visitStaticPropertyInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticPropertyInvocation of $semantics');
- }
-
- @override
- R visitMethodInvocation(MethodInvocation node) {
- if (node.target != null) {
- node.target.accept(this);
- }
- node.argumentList.accept(this);
- return handleMethodInvocation(node);
- }
-
- R handleMethodInvocation(MethodInvocation node) {
- AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
- switch (semantics.kind) {
- case AccessKind.DYNAMIC:
- return visitDynamicInvocation(node, semantics);
- case AccessKind.LOCAL_FUNCTION:
- return visitLocalFunctionInvocation(node, semantics);
- case AccessKind.LOCAL_VARIABLE:
- return visitLocalVariableInvocation(node, semantics);
- case AccessKind.PARAMETER:
- return visitParameterInvocation(node, semantics);
- case AccessKind.STATIC_FIELD:
- return visitStaticFieldInvocation(node, semantics);
- case AccessKind.STATIC_METHOD:
- return visitStaticMethodInvocation(node, semantics);
- case AccessKind.STATIC_PROPERTY:
- return visitStaticPropertyInvocation(node, semantics);
- default:
- // Unexpected access kind.
- return giveUp(node,
- 'Unexpected ${semantics} in visitMethodInvocation.');
- }
- }
-
- @override
- R visitPropertyAccess(PropertyAccess node) {
- if (node.target != null) {
- node.target.accept(this);
- }
- return handlePropertyAccess(node);
- }
-
- R handlePropertyAccess(PropertyAccess node) {
- return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
- }
-
- @override
- R visitPrefixedIdentifier(PrefixedIdentifier node) {
- node.prefix.accept(this);
- return handlePrefixedIdentifier(node);
- }
-
- R handlePrefixedIdentifier(PrefixedIdentifier node) {
- return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
- }
-
- @override
- R visitSimpleIdentifier(SimpleIdentifier node) {
- AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
- if (semantics != null) {
- return _handlePropertyAccess(node, semantics);
- } else {
- return null;
- }
- }
-
- R visitDynamicAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitDynamicAccess of $semantics');
- }
-
- R visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitLocalFunctionAccess of $semantics');
- }
-
- R visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitLocalVariableAccess of $semantics');
- }
-
- R visitParameterAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitParameterAccess of $semantics');
- }
-
- R visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitStaticFieldAccess of $semantics');
- }
-
- R visitStaticMethodAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitStaticMethodAccess of $semantics');
- }
-
- R visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitStaticPropertyAccess of $semantics');
- }
-
- R visitToplevelClassAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitToplevelClassAccess of $semantics');
- }
-
- R visitTypeParameterAccess(AstNode node, AccessSemantics semantics) {
- return giveUp(node, 'visitTypeParameterAccess of $semantics');
- }
-
- R _handlePropertyAccess(AstNode node, AccessSemantics semantics) {
- switch (semantics.kind) {
- case AccessKind.DYNAMIC:
- return visitDynamicAccess(node, semantics);
- case AccessKind.LOCAL_FUNCTION:
- return visitLocalFunctionAccess(node, semantics);
- case AccessKind.LOCAL_VARIABLE:
- return visitLocalVariableAccess(node, semantics);
- case AccessKind.PARAMETER:
- return visitParameterAccess(node, semantics);
- case AccessKind.STATIC_FIELD:
- return visitStaticFieldAccess(node, semantics);
- case AccessKind.STATIC_METHOD:
- return visitStaticMethodAccess(node, semantics);
- case AccessKind.STATIC_PROPERTY:
- return visitStaticPropertyAccess(node, semantics);
- case AccessKind.TOPLEVEL_TYPE:
- return visitToplevelClassAccess(node, semantics);
- case AccessKind.TYPE_PARAMETER:
- return visitTypeParameterAccess(node, semantics);
- default:
- // Unexpected access kind.
- return giveUp(node,
- 'Unexpected ${semantics} in _handlePropertyAccess.');
- }
- }
-
- R visitDynamicPropertyAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitDynamicPropertyAssignment of $semantics');
- }
-
- R visitLocalFunctionAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitLocalFunctionAssignment of $semantics');
- }
-
- R visitLocalVariableAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitLocalVariableAssignment of $semantics');
- }
-
- R visitParameterAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitParameterAssignment of $semantics');
- }
-
- R visitStaticFieldAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticFieldAssignment of $semantics');
- }
-
- R visitStaticMethodAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticMethodAssignment of $semantics');
- }
-
- R visitStaticPropertyAssignment(AssignmentExpression node,
- AccessSemantics semantics) {
- return giveUp(node, 'visitStaticPropertyAssignment of $semantics');
- }
-
- @override
- R visitAssignmentExpression(AssignmentExpression node) {
- super.visitAssignmentExpression(node);
- return handleAssignmentExpression(node);
- }
-
- R handleAssignmentExpression(AssignmentExpression node) {
- AccessSemantics semantics =
- node.leftHandSide.accept(ACCESS_SEMANTICS_VISITOR);
- if (semantics == null) {
- return giveUp(node, 'handleAssignmentExpression with no AccessSemantics');
- } else {
- switch (semantics.kind) {
- case AccessKind.DYNAMIC:
- return visitDynamicPropertyAssignment(node, semantics);
- case AccessKind.LOCAL_FUNCTION:
- return visitLocalFunctionAssignment(node, semantics);
- case AccessKind.LOCAL_VARIABLE:
- return visitLocalVariableAssignment(node, semantics);
- case AccessKind.PARAMETER:
- return visitParameterAssignment(node, semantics);
- case AccessKind.STATIC_FIELD:
- return visitStaticFieldAssignment(node, semantics);
- case AccessKind.STATIC_METHOD:
- return visitStaticMethodAssignment(node, semantics);
- case AccessKind.STATIC_PROPERTY:
- return visitStaticPropertyAssignment(node, semantics);
- default:
- // Unexpected access kind.
- return giveUp(node,
- 'Unexpected ${semantics} in _handlePropertyAccess.');
- }
- }
- }
-}
diff --git a/pkg/analyzer2dart/lib/src/tree_shaker.dart b/pkg/analyzer2dart/lib/src/tree_shaker.dart
deleted file mode 100644
index 6b9eaa6..0000000
--- a/pkg/analyzer2dart/lib/src/tree_shaker.dart
+++ /dev/null
@@ -1,418 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer2dart.treeShaker;
-
-import 'dart:collection';
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:compiler/src/universe/universe.dart';
-
-import 'closed_world.dart';
-import 'util.dart';
-import 'semantic_visitor.dart';
-import 'identifier_semantics.dart';
-
-/**
- * The result of performing local reachability analysis on a method.
- */
-class MethodAnalysis {
- /**
- * The AST for the method.
- */
- final Declaration declaration;
-
- /**
- * The functions statically called by the method.
- */
- final List<ExecutableElement> calls = <ExecutableElement>[];
-
- /**
- * The fields and top-level variables statically accessed by the method.
- */
- // TODO(johnniwinther): Should we split this into reads and writes?
- final List<PropertyInducingElement> accesses = <PropertyInducingElement>[];
-
- /**
- * The selectors used by the method to perform dynamic invocation.
- */
- final List<Selector> invokes = <Selector>[];
-
- /**
- * The classes that are instantiated by the method.
- */
- // TODO(johnniwinther,paulberry): Register instantiated types.
- // TODO(johnniwinther,paulberry): Register checked types from is/as checks,
- // catch clauses and (checked) type annotations.
- final List<ClassElement> instantiates = <ClassElement>[];
-
- MethodAnalysis(this.declaration);
-}
-
-/**
- * The result of performing local reachability analysis on a class.
- *
- * TODO(paulberry): Do we need to do any other analysis of classes? (For
- * example, detect annotations that are relevant to mirrors, detect that a
- * class might be used for custom HTML elements, or collect inherited and
- * mixed-in classes).
- */
-class ClassAnalysis {
- /**
- * The AST for the class.
- */
- final ClassDeclaration declaration;
-
- ClassAnalysis(this.declaration);
-}
-
-/**
- * This class is responsible for performing local analysis of the source code
- * to provide the information needed to do tree shaking.
- */
-class LocalReachabilityComputer {
- /**
- * Perform local reachability analysis of [method].
- */
- MethodAnalysis analyzeMethod(ExecutableElement method) {
- Declaration declaration = method.node;
- MethodAnalysis analysis = new MethodAnalysis(declaration);
- if (declaration != null) {
- declaration.accept(new TreeShakingVisitor(analysis));
- } else if (method is ConstructorElement) {
- // This constructor has no associated declaration in the AST. Either it
- // is a default constructor for an ordinary class, or it's a synthetic
- // constructor associated with a mixin. For now we assume it's a default
- // constructor, in which case all we need to do is record the class as
- // being instantiated by this method. TODO(paulberry): handle the
- // mixin case.
- ClassElement instantiatedClass = method.enclosingElement;
- analysis.instantiates.add(instantiatedClass);
- if (instantiatedClass.supertype != null) {
- ClassElement superClass = instantiatedClass.supertype.element;
- ConstructorElement superConstructor = superClass.unnamedConstructor;
- if (superConstructor != null) {
- // TODO(johnniwinther): Register instantiated type and selector.
- analysis.calls.add(superConstructor);
- }
- }
- } else {
- // This is an executable element with no associated declaration in the
- // AST, and it's not a constructor. TODO(paulberry): can this ever
- // happen?
- throw new UnimplementedError();
- }
- return analysis;
- }
-
- /**
- * Perform local reachability analysis of [classElement].
- */
- ClassAnalysis analyzeClass(ClassElement classElement) {
- return new ClassAnalysis(classElement.node);
- }
-
- /**
- * Determine which members of [classElement] are matched by the given
- * [selector].
- *
- * [methods] is populated with all the class methods which are matched by the
- * selector, [accessors] with all the getters and setters which are matched
- * by the selector, and [fields] with all the fields which are matched by the
- * selector.
- */
- void getMatchingClassMembers(ClassElement classElement, Selector selector,
- List<MethodElement> methods, List<PropertyAccessorElement> accessors,
- List<PropertyInducingElement> fields) {
- // TODO(paulberry): should we walk through superclasses and mixins as well
- // here? Or would it be better to make [TreeShaker] responsible for those
- // relationships (since they are non-local)? Consider making use of
- // InheritanceManager to do this.
- for (MethodElement method in classElement.methods) {
- // TODO(paulberry): account for arity and named arguments when matching
- // the selector against the method.
- if (selector.name == method.name) {
- methods.add(method);
- }
- }
- if (selector.kind == SelectorKind.GETTER) {
- for (PropertyAccessorElement accessor in classElement.accessors) {
- if (accessor.isGetter && selector.name == accessor.name) {
- if (accessor.isSynthetic) {
- // This accessor is implied by the corresponding field declaration.
- fields.add(accessor.variable);
- } else {
- accessors.add(accessor);
- }
- }
- }
- } else if (selector.kind == SelectorKind.SETTER) {
- // accessor.name uses the convention that setter names end in '='.
- String selectorNameWithEquals = '${selector.name}=';
- for (PropertyAccessorElement accessor in classElement.accessors) {
- if (accessor.isSetter && selectorNameWithEquals == accessor.name) {
- if (accessor.isSynthetic) {
- // This accessor is implied by the corresponding field declaration.
- // TODO(paulberry): should we distinguish reads and writes?
- fields.add(accessor.variable);
- } else {
- accessors.add(accessor);
- }
- }
- }
- }
- }
-}
-
-/**
- * This class is responsible for driving the tree shaking process, and
- * and performing the global inferences necessary to determine which methods
- * in the source program are reachable. It makes use of
- * [LocalReachabilityComputer] to do local analysis of individual classes and
- * methods.
- */
-class TreeShaker {
- List<Element> _queue = <Element>[];
- Set<Element> _alreadyEnqueued = new HashSet<Element>();
- ClosedWorld _world;
- Set<Selector> _selectors = new HashSet<Selector>();
- final LocalReachabilityComputer _localComputer =
- new LocalReachabilityComputer();
-
- TreeShaker(TypeProvider typeProvider, FunctionElement mainFunction)
- : _world = new ClosedWorld(typeProvider, mainFunction);
-
- void _addElement(Element element) {
- if (_alreadyEnqueued.add(element)) {
- _queue.add(element);
- }
- }
-
- void _addSelector(Selector selector) {
- if (_selectors.add(selector)) {
- // New selector, so match it against all class methods.
- _world.instantiatedClasses.forEach((ClassElement element, AstNode node) {
- _matchClassToSelector(element, selector);
- });
- }
- }
-
- void _matchClassToSelector(ClassElement classElement, Selector selector) {
- List<MethodElement> methods = <MethodElement>[];
- List<PropertyAccessorElement> accessors = <PropertyAccessorElement>[];
- List<PropertyInducingElement> fields = <PropertyInducingElement>[];
- _localComputer.getMatchingClassMembers(
- classElement,
- selector,
- methods,
- accessors,
- fields);
- methods.forEach(_addElement);
- accessors.forEach(_addElement);
- fields.forEach(_addElement);
- }
-
- ClosedWorld shake() {
- _addElement(_world.mainFunction);
- while (_queue.isNotEmpty) {
- Element element = _queue.removeLast();
- if (element is ExecutableElement) {
- MethodAnalysis analysis = _localComputer.analyzeMethod(element);
- _world.executableElements[element] = analysis.declaration;
- analysis.calls.forEach(_addElement);
- analysis.invokes.forEach(_addSelector);
- analysis.instantiates.forEach(_addElement);
- analysis.accesses.forEach(_addElement);
- } else if (element is ClassElement) {
- ClassAnalysis analysis = _localComputer.analyzeClass(element);
- _world.instantiatedClasses[element] = analysis.declaration;
- for (Selector selector in _selectors) {
- _matchClassToSelector(element, selector);
- }
- } else if (element is FieldElement) {
- VariableDeclaration declaration = element.node;
- _world.fields[element] = declaration;
- } else if (element is TopLevelVariableElement) {
- VariableDeclaration declaration = element.node;
- _world.variables[element] = declaration;
- } else {
- throw new Exception(
- 'Unexpected element type while tree shaking: '
- '$element (${element.runtimeType})');
- }
- }
- return _world;
- }
-}
-
-class TreeShakingVisitor extends SemanticVisitor {
- final MethodAnalysis analysis;
-
- TreeShakingVisitor(this.analysis);
-
- Source get currentSource => analysis.declaration.element.source;
-
- @override
- void visitInstanceCreationExpression(InstanceCreationExpression node) {
- ConstructorElement staticElement = node.staticElement;
- if (staticElement != null) {
- analysis.calls.add(staticElement);
- } else {
- // TODO(paulberry): deal with this situation. This can happen, for
- // example, in the case "main() => new Unresolved();" (which is a
- // warning, not an error).
- }
- super.visitInstanceCreationExpression(node);
- }
-
- @override
- void visitDynamicInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- analysis.invokes.add(createSelectorFromMethodInvocation(
- node.argumentList, node.methodName.name));
- }
-
- @override
- void visitLocalFunctionInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- // Locals don't need to be tree shaken.
- }
-
- @override
- void visitLocalVariableInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- // Locals don't need to be tree shaken.
- }
-
- @override
- void visitParameterInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- // Locals don't need to be tree shaken.
- }
-
- @override
- void visitStaticFieldInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- // Invocation of a static field.
- analysis.accesses.add(semantics.element);
- analysis.invokes.add(createSelectorFromMethodInvocation(
- node.argumentList, 'call'));
- }
-
- @override
- void visitStaticMethodInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- analysis.calls.add(semantics.element);
- }
-
- @override
- void visitStaticPropertyInvocation(MethodInvocation node,
- AccessSemantics semantics) {
- // Invocation of a property. TODO(paulberry): handle this.
- super.visitStaticPropertyInvocation(node, semantics);
- }
-
- void handleDynamicAccess(AccessSemantics semantics) {
- if (semantics.isRead) {
- analysis.invokes.add(
- new Selector.getter(semantics.identifier.name, null));
- }
- if (semantics.isWrite) {
- // Selector.setter constructor uses the convention that setter names
- // don't end in '='.
- analysis.invokes.add(
- new Selector.setter(semantics.identifier.name, null));
- }
- }
-
- @override
- void visitDynamicAccess(AstNode node, AccessSemantics semantics) {
- handleDynamicAccess(semantics);
- }
-
- @override
- void visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
- // Locals don't need to be tree shaken.
- }
-
- @override
- void visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
- // Locals don't need to be tree shaken.
- }
-
- @override
- void visitParameterAccess(AstNode node, AccessSemantics semantics) {
- // Locals don't need to be tree shaken.
- }
-
- @override
- void visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
- analysis.accesses.add(semantics.element);
- }
-
- @override
- void visitStaticMethodAccess(AstNode node, AccessSemantics semantics) {
- // Method tear-off. TODO(paulberry): implement.
- super.visitStaticMethodAccess(node, semantics);
- }
-
- @override
- void visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) {
- // TODO(paulberry): implement.
- super.visitStaticPropertyAccess(node, semantics);
- }
-
- @override
- void visitConstructorDeclaration(ConstructorDeclaration node) {
- // TODO(paulberry): handle parameter list.
- node.initializers.accept(this);
- node.body.accept(this);
- if (node.factoryKeyword == null) {
- // This is a generative constructor. Figure out if it is redirecting.
- // If it isn't, then the constructor instantiates the class so we need to
- // add the class to analysis.instantiates. (If it is redirecting, then
- // we don't need to, because the redirected-to constructor will take care
- // of that).
- if (node.initializers.length != 1 || node.initializers[0] is! RedirectingConstructorInvocation) {
- ClassElement classElement = node.element.enclosingElement;
- analysis.instantiates.add(node.element.enclosingElement);
- if (!node.initializers.any((i) => i is SuperConstructorInvocation)) {
- if (classElement.supertype != null) {
- ClassElement superClass = classElement.supertype.element;
- ConstructorElement superConstructor = superClass.unnamedConstructor;
- if (superConstructor != null) {
- // TODO(johnniwinther): Register instantiated type and selector.
- analysis.calls.add(superConstructor);
- }
- }
- }
- }
- } else if (node.redirectedConstructor != null) {
- if (node.redirectedConstructor.staticElement == null) {
- // Factory constructor redirects to a non-existent constructor.
- // TODO(paulberry): handle this.
- throw new UnimplementedError();
- } else {
- analysis.calls.add(node.redirectedConstructor.staticElement);
- }
- }
- }
-
- @override
- void
- visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
- // Note: we don't have to worry about node.staticElement being
- // null, because that would have been detected by the analyzer and
- // reported as a compile time error.
- analysis.calls.add(node.staticElement);
- }
-
- @override
- void handleAssignmentExpression(AssignmentExpression node) {
- // Don't special-case assignment expressions.
- }
-}
diff --git a/pkg/analyzer2dart/lib/src/util.dart b/pkg/analyzer2dart/lib/src/util.dart
deleted file mode 100644
index fd1c20b..0000000
--- a/pkg/analyzer2dart/lib/src/util.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Utility function shared between different parts of analyzer2dart.
-
-library analyzer2dart.util;
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:compiler/src/elements/elements.dart' show PublicName;
-import 'package:compiler/src/universe/universe.dart';
-import 'package:compiler/src/io/source_file.dart';
-
-CallStructure createCallStructureFromMethodInvocation(ArgumentList node) {
- int arity = 0;
- List<String> namedArguments = <String>[];
- for (Expression argument in node.arguments) {
- if (argument is NamedExpression) {
- namedArguments.add(argument.name.label.name);
- } else {
- arity++;
- }
- }
- return new CallStructure(arity, namedArguments);
-}
-
-Selector createSelectorFromMethodInvocation(ArgumentList node,
- String name) {
- CallStructure callStructure = createCallStructureFromMethodInvocation(node);
- // TODO(johnniwinther): Support private names.
- return new Selector(SelectorKind.CALL, new PublicName(name), callStructure);
-}
-
-/// Prints [message] together with source code pointed to by [node] from
-/// [source].
-void reportSourceMessage(Source source, AstNode node, String message) {
- SourceFile sourceFile =
- new StringSourceFile.fromName(source.fullName, source.contents.data);
-
- print(sourceFile.getLocationMessage(message, node.offset, node.end));
-}
diff --git a/pkg/analyzer2dart/test/driver_test.dart b/pkg/analyzer2dart/test/driver_test.dart
deleted file mode 100644
index 5807714..0000000
--- a/pkg/analyzer2dart/test/driver_test.dart
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'mock_sdk.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:compiler/src/dart2jslib.dart' show NullSink;
-import 'package:unittest/unittest.dart';
-
-import '../lib/src/closed_world.dart';
-import '../lib/src/driver.dart';
-
-main() {
- MemoryResourceProvider provider;
- Driver driver;
- setUp(() {
- provider = new MemoryResourceProvider();
- DartSdk sdk = new MockSdk();
- driver = new Driver(provider, sdk, NullSink.outputProvider);
- });
-
- Source setFakeRoot(String contents) {
- String path = '/root.dart';
- provider.newFile(path, contents);
- return driver.setRoot(path);
- }
-
- test('resolveEntryPoint', () {
- String contents = 'main() {}';
- Source source = setFakeRoot(contents);
- FunctionElement element = driver.resolveEntryPoint(source);
- expect(element.name, equals('main'));
- });
-
- test('computeWorld', () {
- String contents = '''
-main() {
- foo();
-}
-
-foo() {
-}
-
-bar() {
-}
-''';
- Source source = setFakeRoot(contents);
- FunctionElement entryPoint = driver.resolveEntryPoint(source);
- ClosedWorld world = driver.computeWorld(entryPoint);
- expect(world.executableElements, hasLength(2));
- CompilationUnitElement compilationUnit =
- entryPoint.getAncestor((e) => e is CompilationUnitElement);
- Map<String, FunctionElement> functions = {};
- for (FunctionElement functionElement in compilationUnit.functions) {
- functions[functionElement.name] = functionElement;
- }
- FunctionElement mainElement = functions['main'];
- expect(world.executableElements.keys, contains(mainElement));
- FunctionDeclaration mainAst = world.executableElements[mainElement];
- expect(mainAst.element, equals(mainElement));
- FunctionElement fooElement = functions['foo'];
- expect(world.executableElements.keys, contains(fooElement));
- FunctionDeclaration fooAst = world.executableElements[fooElement];
- expect(fooAst.element, equals(fooElement));
- FunctionElement barElement = functions['bar'];
- expect(
- world.executableElements.keys,
- isNot(contains(functions[barElement])));
- });
-}
diff --git a/pkg/analyzer2dart/test/end2end_data.dart b/pkg/analyzer2dart/test/end2end_data.dart
deleted file mode 100644
index 20b680f..0000000
--- a/pkg/analyzer2dart/test/end2end_data.dart
+++ /dev/null
@@ -1,908 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Test data for the end2end test.
-library test.end2end.data;
-
-import 'test_helper.dart';
-
-class TestSpec extends TestSpecBase {
- final String output;
-
- const TestSpec(String input, [String output])
- : this.output = output != null ? output : input,
- super(input);
-}
-
-const List<Group> TEST_DATA = const <Group>[
- const Group('Empty main', const <TestSpec>[
- const TestSpec('''
-main() {}
-'''),
-
- const TestSpec('''
-main() {}
-foo() {}
-''', '''
-main() {}
-'''),
- ]),
- const Group('Simple call-chains', const <TestSpec>[
- const TestSpec('''
-foo() {}
-main() {
- foo();
-}
-'''),
-
- const TestSpec('''
-bar() {}
-foo() {
- bar();
-}
-main() {
- foo();
-}
-'''),
-
- const TestSpec('''
-bar() {
- main();
-}
-foo() {
- bar();
-}
-main() {
- foo();
-}
-'''),
-
- ]),
- const Group('Literals', const <TestSpec>[
- const TestSpec('''
-main() {
- return 0;
-}
-'''),
-
- const TestSpec('''
-main() {
- return 1.5;
-}
-'''),
-
- const TestSpec('''
-main() {
- return true;
-}
-'''),
-
- const TestSpec('''
-main() {
- return false;
-}
-'''),
-
- const TestSpec('''
-main() {
- return "a";
-}
-'''),
-
- const TestSpec('''
-main() {
- return "a" "b";
-}
-''', '''
-main() {
- return "ab";
-}
-'''),
- ]),
-
- const Group('Parameters', const <TestSpec>[
- const TestSpec('''
-main(args) {}
-'''),
-
- const TestSpec('''
-main(a, b) {}
-'''),
- ]),
-
- const Group('Typed parameters', const <TestSpec>[
- const TestSpec('''
-void main(args) {}
-'''),
-
- const TestSpec('''
-main(int a, String b) {}
-'''),
-
- const TestSpec('''
-main(Comparator a, List b) {}
-'''),
-
- const TestSpec('''
-main(Comparator<dynamic> a, List<dynamic> b) {}
-''','''
-main(Comparator a, List b) {}
-'''),
-
- const TestSpec('''
-main(Map a, Map<dynamic, List<int>> b) {}
-'''),
- ]),
-
- const Group('Pass arguments', const <TestSpec>[
- const TestSpec('''
-foo(a) {}
-main() {
- foo(null);
-}
-'''),
-
- const TestSpec('''
-bar(b, c) {}
-foo(a) {}
-main() {
- foo(null);
- bar(0, "");
-}
-'''),
-
- const TestSpec('''
-bar(b) {}
-foo(a) {
- bar(a);
-}
-main() {
- foo(null);
-}
-'''),
- ]),
-
- const Group('Top level field', const <TestSpec>[
- const TestSpec('''
-var field;
-main(args) {
- return field;
-}
-'''),
-
- // TODO(johnniwinther): Eliminate unneeded `null` initializers.
- const TestSpec('''
-var field = null;
-main(args) {
- return field;
-}
-'''),
-
- const TestSpec('''
-var field = 0;
-main(args) {
- return field;
-}
-'''),
-
- const TestSpec('''
-var field;
-main(args) {
- field = args.length;
- return field;
-}
-'''),
- ]),
-
- const Group('Local variables', const <TestSpec>[
- const TestSpec('''
-main() {
- var a;
- return a;
-}
-''','''
-main() {}
-'''),
-
- const TestSpec('''
-main() {
- var a = 0;
- return a;
-}
-''','''
-main() {
- return 0;
-}
-'''),
- ]),
-
- const Group('Local variable writes', const <TestSpec>[
- const TestSpec('''
-main() {
- var a;
- a = 10;
- return a;
-}
-''', '''
-main() {
- return 10;
-}
-'''),
-
- const TestSpec('''
-main() {
- var a = 0;
- a = 10;
- return a;
-}
-''', '''
-main() {
- return 10;
-}
-'''),
-
- const TestSpec('''
-main() {
- var a = 0;
- print(a);
- a = "";
- print(a);
- return a;
-}
-''', '''
-main() {
- var a;
- print(0);
- a = "";
- print(a);
- return a;
-}
-'''),
-
- const TestSpec('''
-main(a) {
- print(a);
- a = "";
- print(a);
- return a;
-}
-'''),
-
- const TestSpec('''
-main(a) {
- if (a) {
- a = "";
- }
- print(a);
- return a;
-}
-''', '''
-main(a) {
- print(a = a ? "" : a);
- return a;
-}
-'''),
- ]),
-
- const Group('Dynamic access', const <TestSpec>[
- const TestSpec('''
-main(a) {
- return a.foo;
-}
-'''),
-
- const TestSpec('''
-main() {
- var a = "";
- return a.foo;
-}
-''','''
-main() {
- return "".foo;
-}
-'''),
- ]),
-
- const Group('Dynamic invocation', const <TestSpec>[
- const TestSpec('''
-main(a) {
- return a.foo(0);
-}
-'''),
-
- const TestSpec('''
-main() {
- var a = "";
- return a.foo(0, 1);
-}
-''','''
-main() {
- return "".foo(0, 1);
-}
-'''),
- ]),
-
- const Group('Binary expressions', const <TestSpec>[
- const TestSpec('''
-main(a, b) {
- return a + b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a - b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a * b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a / b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a ~/ b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a % b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a < b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a <= b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a > b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a >= b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a << b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a >> b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a & b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a | b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a ^ b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a == b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a != b;
-}
-''','''
-main(a, b) {
- return !(a == b);
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a && b;
-}
-'''),
-
- const TestSpec('''
-main(a, b) {
- return a || b;
-}
-'''),
- ]),
-
- const Group('If statement', const <TestSpec>[
- const TestSpec('''
-main(a) {
- if (a) {
- print(0);
- }
-}
-'''),
-
- const TestSpec('''
-main(a) {
- if (a) {
- print(0);
- } else {
- print(1);
- }
-}
-''','''
-main(a) {
- a ? print(0) : print(1);
-}
-'''),
-
- const TestSpec('''
-main(a) {
- if (a) {
- print(0);
- } else {
- print(1);
- print(2);
- }
-}
-'''),
- ]),
-
- const Group('Conditional expression', const <TestSpec>[
- const TestSpec('''
-main(a) {
- return a ? print(0) : print(1);
-}
-'''),
- ]),
-
- // These test that unreachable statements are skipped within a block.
- const Group('Block statements', const <TestSpec>[
- const TestSpec('''
-main(a) {
- return 0;
- return 1;
-}
-''', '''
-main(a) {
- return 0;
-}
-'''),
-
- const TestSpec('''
-main(a) {
- if (a) {
- return 0;
- return 1;
- } else {
- return 2;
- return 3;
- }
-}
-''', '''
-main(a) {
- return a ? 0 : 2;
-}
-'''),
-
- const TestSpec('''
-main(a) {
- if (a) {
- print(0);
- return 0;
- return 1;
- } else {
- print(2);
- return 2;
- return 3;
- }
-}
-''', '''
-main(a) {
- if (a) {
- print(0);
- return 0;
- } else {
- print(2);
- return 2;
- }
-}
-'''),
- ]),
-
- const Group('List literal', const <TestSpec>[
- const TestSpec('''
-main() {
- return [];
-}
-'''),
-
- const TestSpec('''
-main() {
- return <int>[];
-}
-'''),
-
- const TestSpec('''
-main() {
- return <int>[0];
-}
-'''),
-
- const TestSpec('''
-main(a) {
- return <int>[0, 1, a];
-}
-'''),
-
- const TestSpec('''
-main(a) {
- return [0, [1], [a, <int>[3]]];
-}
-'''),
- ]),
-
- const Group('Constructor invocation', const <TestSpec>[
- const TestSpec('''
-main(a) {
- new Object();
-}
-'''),
-
-const TestSpec('''
-main(a) {
- new Deprecated("");
-}
-'''),
- ]),
-
- const Group('Map literal', const <TestSpec>[
- const TestSpec('''
-main() {
- return {};
-}
-'''),
-
- const TestSpec('''
-main() {
- return <int, String>{};
-}
-'''),
-
- const TestSpec('''
-main() {
- return <String, int>{"a": 0};
-}
-'''),
-
- const TestSpec('''
-main(a) {
- return <String, int>{"a": 0, "b": 1, "c": a};
-}
-'''),
-
- const TestSpec('''
-main(a) {
- return {0: "a", 1: {2: "b"}, a: {3: "c"}};
-}
-'''),
- ]),
- const Group('For loop', const <TestSpec>[
- const TestSpec('''
-main() {
- for (;;) {}
-}
-''', '''
-main() {
- while (true) {}
-}
-'''),
-
-const TestSpec('''
-main() {
- for (var i = 0; i < 10; i = i + 1) {
- print(i);
- }
-}
-''', '''
-main() {
- var i = 0;
- while (i < 10) {
- print(i);
- ++i;
- }
-}
-'''),
-
-const TestSpec('''
-main(i) {
- for (i = 0; i < 10; i = i + 1) {
- print(i);
- }
-}
-''', '''
-main(i) {
- i = 0;
- while (i < 10) {
- print(i);
- ++i;
- }
-}
-'''),
- ]),
-
- const Group('While loop', const <TestSpec>[
- const TestSpec('''
-main() {
- while (true) {}
-}
-'''),
-
-const TestSpec('''
-main() {
- var i = 0;
- while (i < 10) {
- print(i);
- i = i + 1;
- }
-}''', '''
-main() {
- var i = 0;
- while (i < 10) {
- print(i);
- ++i;
- }
-}'''),
- ]),
-
- const Group('Type operators', const <TestSpec>[
- const TestSpec('''
-main(a) {
- return a is String;
-}
-'''),
-
- const TestSpec('''
-main(a) {
- return a is List<String>;
-}
-'''),
-
- const TestSpec('''
-main(a) {
- return a is Comparator<String>;
-}
-'''),
-
- const TestSpec('''
-main(a) {
- return a is! String;
-}
-''', '''
-main(a) {
- return !(a is String);
-}
-'''),
-
-const TestSpec('''
-main(a) {
- return a as String;
-}
-'''),
- ]),
-
- const Group('For in loop', const <TestSpec>[
-// TODO(johnniwinther): Add tests for `i` as top-level, static and instance
-// fields.
- const TestSpec('''
-main(a) {
- for (var i in a) {
- print(i);
- }
-}
-''', '''
-main(a) {
- var v0 = a.iterator;
- while (v0.moveNext()) {
- print(v0.current);
- }
-}'''),
-
- const TestSpec('''
-main(a) {
- for (var i in a) {
- print(i);
- i = 0;
- print(i);
- }
-}
-''', '''
-main(a) {
- var v0 = a.iterator;
- while (v0.moveNext()) {
- print(v0.current);
- print(0);
- }
-}
-'''),
-
- const TestSpec('''
-main(a) {
- var i;
- for (i in a) {
- print(i);
- }
-}
-''', '''
-main(a) {
- var v0 = a.iterator;
- while (v0.moveNext()) {
- print(v0.current);
- }
-}
-'''),
- ]),
-
- const Group('Local functions', const <TestSpec>[
- const TestSpec('''
-main(a) {
- local() {}
- return local();
-}
-''', '''
-main(a) {
- return (() {})();
-}
-'''),
-
- const TestSpec('''
-main(a) {
- local() {}
- var l = local;
- return l();
-}
-''', '''
-main(a) {
- return (() {})();
-}
-'''),
-
- const TestSpec('''
-main(a) {
- return () {}();
-}
-''', '''
-main(a) {
- return (() {})();
-}
-'''),
-
- const TestSpec('''
-main(a) {
- var c = a ? () { return 0; } : () { return 1; };
- return c();
-}
-''', '''
-main(a) {
- return (a ? () {
- return 0;
- } : () {
- return 1;
- })();
-}
-'''),
- ]),
-
- const Group('Constructors', const <TestSpec>[
- const TestSpec('''
-class C {}
-main() {
- return new C();
-}
-'''),
-
- const TestSpec('''
-class C {
- C() {}
-}
-main() {
- return new C();
-}
-'''),
-
- const TestSpec('''
-class B {}
-class C extends B {
- C() {}
-}
-main() {
- return new C();
-}
-'''),
-
- const TestSpec('''
-class B {
- B() {}
-}
-class C extends B {}
-main() {
- return new C();
-}
-'''),
- ]),
-
- const Group('Instance method', const <TestSpec>[
- const TestSpec('''
-class C {
- C() {}
- foo() {}
-}
-main() {
- return new C().foo();
-}
-'''),
- ]),
-
- const Group('Try-catch', const <TestSpec>[
- const TestSpec('''
-main() {
- try {} catch (e) {}
-}
-''',
-// TODO(kmillikin): Remove the unused stack trace parameter.
-'''
-main() {
- try {} catch (e, v0) {}
-}
-'''),
-
- const TestSpec('''
-main() {
- try {
- return;
- } catch (e) {}
-}
-''',
-// TODO(kmillikin): Remove the unused stack trace parameter and unneeded return
-// statement(s).
-'''
-main() {
- try {
- return null;
- } catch (e, v0) {
- return null;
- }
-}
-'''),
- ]),
-];
diff --git a/pkg/analyzer2dart/test/end2end_test.dart b/pkg/analyzer2dart/test/end2end_test.dart
deleted file mode 100644
index 18fe84a..0000000
--- a/pkg/analyzer2dart/test/end2end_test.dart
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// End-to-end test of the analyzer2dart compiler.
-library test.end2end;
-
-import 'mock_sdk.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:unittest/unittest.dart';
-
-import '../lib/src/closed_world.dart';
-import '../lib/src/driver.dart';
-import '../lib/src/converted_world.dart';
-import '../lib/src/dart_backend.dart';
-
-import 'test_helper.dart' hide TestSpec;
-import 'output_helper.dart';
-import 'end2end_data.dart';
-
-main(List<String> args) {
- performTests(TEST_DATA, unittester, checkResult, args);
-}
-
-checkResult(TestSpec result) {
- String input = result.input;
- String expectedOutput = result.output.trim();
-
- CollectingOutputProvider outputProvider = new CollectingOutputProvider();
- MemoryResourceProvider provider = new MemoryResourceProvider();
- DartSdk sdk = new MockSdk();
- Driver driver = new Driver(provider, sdk, outputProvider);
- String rootFile = '/root.dart';
- provider.newFile(rootFile, input);
- Source rootSource = driver.setRoot(rootFile);
- FunctionElement entryPoint = driver.resolveEntryPoint(rootSource);
- ClosedWorld world = driver.computeWorld(entryPoint);
- ConvertedWorld convertedWorld = convertWorld(world);
- compileToDart(driver, convertedWorld);
- String output = outputProvider.output.text.trim();
- expect(output, equals(expectedOutput));
-}
diff --git a/pkg/analyzer2dart/test/identifier_semantics_test.dart b/pkg/analyzer2dart/test/identifier_semantics_test.dart
deleted file mode 100644
index 0801e7a..0000000
--- a/pkg/analyzer2dart/test/identifier_semantics_test.dart
+++ /dev/null
@@ -1,2536 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer2dart/src/identifier_semantics.dart';
-import 'package:unittest/unittest.dart';
-
-import 'mock_sdk.dart';
-
-main() {
- test('Call function defined at top level', () {
- Helper helper = new Helper('''
-g() {}
-
-f() {
- g();
-}
-''');
- helper.checkStaticMethod('g()', null, 'g', true, isInvoke: true);
- });
-
- test('Call function defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.g();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-g() {}
-''');
- helper.checkStaticMethod('l.g()', null, 'g', true, isInvoke: true);
- });
-
- test('Call method defined statically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- static g() {}
-
- f() {
- g();
- }
-}
-''');
- helper.checkStaticMethod('g()', 'A', 'g', true, isInvoke: true);
- });
-
- test('Call method defined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {
- static g() {}
-}
-f() {
- A.g();
-}
-''');
- helper.checkStaticMethod('A.g()', 'A', 'g', true, isInvoke: true);
- });
-
- test(
- 'Call method defined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.A.g();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {
- static g() {}
-}
-''');
- helper.checkStaticMethod('l.A.g()', 'A', 'g', true, isInvoke: true);
- });
-
- test('Call method defined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- g() {}
-
- f() {
- g();
- }
-}
-''');
- helper.checkDynamic('g()', null, 'g', isInvoke: true);
- });
-
- test(
- 'Call method defined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {
- g() {}
-}
-f(A a) {
- a.g();
-}
-''');
- helper.checkDynamic('a.g()', 'a', 'g', isInvoke: true);
- });
-
- test(
- 'Call method defined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {
- g() {}
-}
-A h() => null;
-f() {
- h().g();
-}
-''');
- helper.checkDynamic('h().g()', 'h()', 'g', isInvoke: true);
- });
-
- test(
- 'Call method defined dynamically in class from outside class via dynamic var',
- () {
- Helper helper = new Helper('''
-f(a) {
- a.g();
-}
-''');
- helper.checkDynamic('a.g()', 'a', 'g', isInvoke: true);
- });
-
- test(
- 'Call method defined dynamically in class from outside class via dynamic expression',
- () {
- Helper helper = new Helper('''
-h() => null;
-f() {
- h().g();
-}
-''');
- helper.checkDynamic('h().g()', 'h()', 'g', isInvoke: true);
- });
-
- test('Call method defined locally', () {
- Helper helper = new Helper('''
-f() {
- g() {}
- g();
-}
-''');
- helper.checkLocalFunction('g()', 'g', isInvoke: true);
- });
-
- test('Call method undefined at top level', () {
- Helper helper = new Helper('''
-f() {
- g();
-}
-''');
- // Undefined top level invocations are treated as dynamic.
- // TODO(paulberry): not sure if this is a good idea. In general, when such
- // a call appears inside an instance method, it is dynamic, because "this"
- // might be an instance of a derived class that implements g(). However,
- // in this case, we are not inside an instance method, so we know that the
- // target is undefined.
- helper.checkDynamic('g()', null, 'g', isInvoke: true);
- });
-
- test('Call method undefined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.g();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-''');
- // Undefined top level invocations are treated as dynamic.
- // TODO(paulberry): not sure if this is a good idea, for similar reasons to
- // the case above.
- helper.checkDynamic('l.g()', null, 'g', isInvoke: true);
- });
-
- test('Call method undefined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {}
-
-f() {
- A.g();
-}
-''');
- helper.checkStaticMethod('A.g()', 'A', 'g', false, isInvoke: true);
- });
-
- test(
- 'Call method undefined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.A.g();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {}
-''');
- helper.checkStaticMethod('l.A.g()', 'A', 'g', false, isInvoke: true);
- });
-
- test('Call method undefined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- f() {
- g();
- }
-}
-''');
- helper.checkDynamic('g()', null, 'g', isInvoke: true);
- });
-
- test(
- 'Call method undefined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {}
-
-f(A a) {
- a.g();
-}
-''');
- helper.checkDynamic('a.g()', 'a', 'g', isInvoke: true);
- });
-
- test(
- 'Call method undefined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {}
-
-A h() => null;
-
-f() {
- h().g();
-}
-''');
- helper.checkDynamic('h().g()', 'h()', 'g', isInvoke: true);
- });
-
- test('Call variable defined at top level', () {
- Helper helper = new Helper('''
-var x;
-
-f() {
- x();
-}
-''');
- helper.checkStaticField('x()', null, 'x', isInvoke: true);
- });
-
- test('Call variable defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.x();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-var x;
-''');
- helper.checkStaticField('l.x()', null, 'x', isInvoke: true);
- });
-
- test('Call field defined statically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- static var x;
-
- f() {
- return x();
- }
-}
-''');
- helper.checkStaticField('x()', 'A', 'x', isInvoke: true);
- });
-
- test('Call field defined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {
- static var x;
-}
-
-f() {
- return A.x();
-}
-''');
- helper.checkStaticField('A.x()', 'A', 'x', isInvoke: true);
- });
-
- test(
- 'Call field defined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.A.x();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {
- static var x;
-}
-''');
- helper.checkStaticField('l.A.x()', 'A', 'x', isInvoke: true);
- });
-
- test('Call field defined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- var x;
-
- f() {
- return x();
- }
-}
-''');
- helper.checkDynamic('x()', null, 'x', isInvoke: true);
- });
-
- test(
- 'Call field defined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {
- var x;
-}
-
-f(A a) {
- return a.x();
-}
-''');
- helper.checkDynamic('a.x()', 'a', 'x', isInvoke: true);
- });
-
- test(
- 'Call field defined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {
- var x;
-}
-
-A h() => null;
-
-f() {
- return h().x();
-}
-''');
- helper.checkDynamic('h().x()', 'h()', 'x', isInvoke: true);
- });
-
- test(
- 'Call field defined dynamically in class from outside class via dynamic var',
- () {
- Helper helper = new Helper('''
-f(a) {
- return a.x();
-}
-''');
- helper.checkDynamic('a.x()', 'a', 'x', isInvoke: true);
- });
-
- test(
- 'Call field defined dynamically in class from outside class via dynamic expression',
- () {
- Helper helper = new Helper('''
-h() => null;
-
-f() {
- return h().x();
-}
-''');
- helper.checkDynamic('h().x()', 'h()', 'x', isInvoke: true);
- });
-
- test('Call variable defined locally', () {
- Helper helper = new Helper('''
-f() {
- var x;
- return x();
-}
-''');
- helper.checkLocalVariable('x()', 'x', isInvoke: true);
- });
-
- test('Call variable defined in parameter', () {
- Helper helper = new Helper('''
-f(x) {
- return x();
-}
-''');
- helper.checkParameter('x()', 'x', isInvoke: true);
- });
-
- test('Call accessor defined at top level', () {
- Helper helper = new Helper('''
-get x => null;
-
-f() {
- return x();
-}
-''');
- helper.checkStaticProperty('x()', null, 'x', true, isInvoke: true);
- });
-
- test('Call accessor defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.x();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-get x => null;
-''');
- helper.checkStaticProperty('l.x()', null, 'x', true, isInvoke: true);
- });
-
- test('Call accessor defined statically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- static get x => null;
-
- f() {
- return x();
- }
-}
-''');
- helper.checkStaticProperty('x()', 'A', 'x', true, isInvoke: true);
- });
-
- test('Call accessor defined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {
- static get x => null;
-}
-
-f() {
- return A.x();
-}
-''');
- helper.checkStaticProperty('A.x()', 'A', 'x', true, isInvoke: true);
- });
-
- test(
- 'Call accessor defined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.A.x();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {
- static get x => null;
-}
-''');
- helper.checkStaticProperty('l.A.x()', 'A', 'x', true, isInvoke: true);
- });
-
- test('Call accessor defined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- get x => null;
-
- f() {
- return x();
- }
-}
-''');
- helper.checkDynamic('x()', null, 'x', isInvoke: true);
- });
-
- test(
- 'Call accessor defined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {
- get x => null;
-}
-
-f(A a) {
- return a.x();
-}
-''');
- helper.checkDynamic('a.x()', 'a', 'x', isInvoke: true);
- });
-
- test(
- 'Call accessor defined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {
- get x => null;
-}
-
-A h() => null;
-
-f() {
- return h().x();
-}
-''');
- helper.checkDynamic('h().x()', 'h()', 'x', isInvoke: true);
- });
-
- test(
- 'Call accessor defined dynamically in class from outside class via dynamic var',
- () {
- Helper helper = new Helper('''
-f(a) {
- return a.x();
-}
-''');
- helper.checkDynamic('a.x()', 'a', 'x', isInvoke: true);
- });
-
- test(
- 'Call accessor defined dynamically in class from outside class via dynamic expression',
- () {
- Helper helper = new Helper('''
-h() => null;
-
-f() {
- return h().x();
-}
-''');
- helper.checkDynamic('h().x()', 'h()', 'x', isInvoke: true);
- });
-
- test('Call class defined at top level', () {
- Helper helper = new Helper('''
-class A {}
-
-f() {
- A();
-}
-''');
- helper.checkTypeReference(
- 'A()',
- 'A',
- AccessKind.TOPLEVEL_TYPE,
- isInvoke: true);
- });
-
- test('Call class defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.A();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {}
-''');
- helper.checkTypeReference(
- 'l.A()',
- 'A',
- AccessKind.TOPLEVEL_TYPE,
- isInvoke: true);
- });
-
- test('Call dynamic type undefined at toplevel', () {
- Helper helper = new Helper('''
-f() {
- dynamic();
-}
-''');
- // Since it is legal to define a toplevel function or a class member called
- // dynamic, "dynamic()" must be treated as a dynamic access to a function
- // called "dynamic".
- helper.checkDynamic('dynamic()', null, 'dynamic', isInvoke: true);
- });
-
- test('Call function typedef defined at top level', () {
- Helper helper = new Helper('''
-typedef F();
-
-f() {
- F();
-}
-''');
- helper.checkTypeReference(
- 'F()',
- 'F',
- AccessKind.TOPLEVEL_TYPE,
- isInvoke: true);
- });
-
- test('Call function typedef defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.F();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-typedef F();
-''');
- helper.checkTypeReference(
- 'l.F()',
- 'F',
- AccessKind.TOPLEVEL_TYPE,
- isInvoke: true);
- });
-
- test('Call mixin application defined at top level', () {
- Helper helper = new Helper('''
-class A {}
-class B {}
-class C = A with B;
-
-f() {
- C();
-}
-''');
- helper.checkTypeReference(
- 'C()',
- 'C',
- AccessKind.TOPLEVEL_TYPE,
- isInvoke: true);
- });
-
- test('Call mixin application defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.C();
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {}
-class B {}
-class C = A with B;
-''');
- helper.checkTypeReference(
- 'l.C()',
- 'C',
- AccessKind.TOPLEVEL_TYPE,
- isInvoke: true);
- });
-
- test('Call type parameter of enclosing class', () {
- Helper helper = new Helper('''
-class A<T, U> {
- f() {
- U();
- }
-}
-''');
- helper.checkTypeReference(
- 'U()',
- 'U',
- AccessKind.TYPE_PARAMETER,
- isInvoke: true);
- });
-
- test('Get function defined at top level', () {
- Helper helper = new Helper('''
-g() {}
-
-f() {
- return g;
-}
-''');
- helper.checkStaticMethod('g', null, 'g', true, isRead: true);
- });
-
- test('Get function defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.g;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-g() {}
-''');
- helper.checkStaticMethod('l.g', null, 'g', true, isRead: true);
- });
-
- test('Get method defined statically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- static g() {}
-
- f() {
- return g;
- }
-}
-''');
- helper.checkStaticMethod('g', 'A', 'g', true, isRead: true);
- });
-
- test('Get method defined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {
- static g() {}
-}
-f() {
- return A.g;
-}
-''');
- helper.checkStaticMethod('A.g', 'A', 'g', true, isRead: true);
- });
-
- test(
- 'Get method defined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.A.g;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {
- static g() {}
-}
-''');
- helper.checkStaticMethod('l.A.g', 'A', 'g', true, isRead: true);
- });
-
- test('Get method defined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- g() {}
-
- f() {
- return g;
- }
-}
-''');
- helper.checkDynamic('g', null, 'g', isRead: true);
- });
-
- test(
- 'Get method defined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {
- g() {}
-}
-f(A a) {
- return a.g;
-}
-''');
- helper.checkDynamic('a.g', 'a', 'g', isRead: true);
- });
-
- test(
- 'Get method defined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {
- g() {}
-}
-A h() => null;
-f() {
- return h().g;
-}
-''');
- helper.checkDynamic('h().g', 'h()', 'g', isRead: true);
- });
-
- test('Get method defined locally', () {
- Helper helper = new Helper('''
-f() {
- g() {}
- return g;
-}
-''');
- helper.checkLocalFunction('g', 'g', isRead: true);
- });
-
- test('Get variable defined at top level', () {
- Helper helper = new Helper('''
-var x;
-
-f() {
- return x;
-}
-''');
- helper.checkStaticField('x', null, 'x', isRead: true);
- });
-
- test('Get variable defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.x;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-var x;
-''');
- helper.checkStaticField('l.x', null, 'x', isRead: true);
- });
-
- test('Get field defined statically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- static var x;
-
- f() {
- return x;
- }
-}
-''');
- helper.checkStaticField('x', 'A', 'x', isRead: true);
- });
-
- test('Get field defined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {
- static var x;
-}
-
-f() {
- return A.x;
-}
-''');
- helper.checkStaticField('A.x', 'A', 'x', isRead: true);
- });
-
- test(
- 'Get field defined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.A.x;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {
- static var x;
-}
-''');
- helper.checkStaticField('l.A.x', 'A', 'x', isRead: true);
- });
-
- test('Get field defined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- var x;
-
- f() {
- return x;
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isRead: true);
- });
-
- test(
- 'Get field defined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {
- var x;
-}
-
-f(A a) {
- return a.x;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isRead: true);
- });
-
- test(
- 'Get field defined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {
- var x;
-}
-
-A h() => null;
-
-f() {
- return h().x;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isRead: true);
- });
-
- test(
- 'Get field defined dynamically in class from outside class via dynamic var',
- () {
- Helper helper = new Helper('''
-f(a) {
- return a.x;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isRead: true);
- });
-
- test(
- 'Get field defined dynamically in class from outside class via dynamic expression',
- () {
- Helper helper = new Helper('''
-h() => null;
-
-f() {
- return h().x;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isRead: true);
- });
-
- test('Get variable defined locally', () {
- Helper helper = new Helper('''
-f() {
- var x;
- return x;
-}
-''');
- helper.checkLocalVariable('x', 'x', isRead: true);
- });
-
- test('Get variable defined in parameter', () {
- Helper helper = new Helper('''
-f(x) {
- return x;
-}
-''');
- helper.checkParameter('x', 'x', isRead: true);
- });
-
- test('Get accessor defined at top level', () {
- Helper helper = new Helper('''
-get x => null;
-
-f() {
- return x;
-}
-''');
- helper.checkStaticProperty('x', null, 'x', true, isRead: true);
- });
-
- test('Get accessor defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.x;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-get x => null;
-''');
- helper.checkStaticProperty('l.x', null, 'x', true, isRead: true);
- });
-
- test('Get accessor defined statically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- static get x => null;
-
- f() {
- return x;
- }
-}
-''');
- helper.checkStaticProperty('x', 'A', 'x', true, isRead: true);
- });
-
- test('Get accessor defined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {
- static get x => null;
-}
-
-f() {
- return A.x;
-}
-''');
- helper.checkStaticProperty('A.x', 'A', 'x', true, isRead: true);
- });
-
- test(
- 'Get accessor defined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.A.x;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {
- static get x => null;
-}
-''');
- helper.checkStaticProperty('l.A.x', 'A', 'x', true, isRead: true);
- });
-
- test('Get accessor defined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- get x => null;
-
- f() {
- return x;
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isRead: true);
- });
-
- test(
- 'Get accessor defined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {
- get x => null;
-}
-
-f(A a) {
- return a.x;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isRead: true);
- });
-
- test(
- 'Get accessor defined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {
- get x => null;
-}
-
-A h() => null;
-
-f() {
- return h().x;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isRead: true);
- });
-
- test(
- 'Get accessor defined dynamically in class from outside class via dynamic var',
- () {
- Helper helper = new Helper('''
-f(a) {
- return a.x;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isRead: true);
- });
-
- test(
- 'Get accessor defined dynamically in class from outside class via dynamic expression',
- () {
- Helper helper = new Helper('''
-h() => null;
-
-f() {
- return h().x;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isRead: true);
- });
-
- test('Get accessor undefined at top level', () {
- Helper helper = new Helper('''
-f() {
- return x;
-}
-''');
- // Undefined top level property accesses are treated as dynamic.
- // TODO(paulberry): not sure if this is a good idea. In general, when such
- // an access appears inside an instance method, it is dynamic, because
- // "this" might be an instance of a derived class that implements x.
- // However, in this case, we are not inside an instance method, so we know
- // that the target is undefined.
- helper.checkDynamic('x', null, 'x', isRead: true);
- });
-
- test('Get accessor undefined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.x;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-''');
- // Undefined top level property accesses are treated as dynamic.
- // TODO(paulberry): not sure if this is a good idea, for similar reasons to
- // the case above.
- helper.checkDynamic('l.x', null, 'x', isRead: true);
- });
-
- test('Get accessor undefined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {}
-
-f() {
- return A.x;
-}
-''');
- helper.checkStaticProperty('A.x', 'A', 'x', false, isRead: true);
- });
-
- test(
- 'Get accessor undefined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- return l.A.x;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {}
-''');
- helper.checkStaticProperty('l.A.x', 'A', 'x', false, isRead: true);
- });
-
- test('Get accessor undefined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- f() {
- return x;
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isRead: true);
- });
-
- test(
- 'Get accessor undefined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {}
-
-f(A a) {
- return a.x;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isRead: true);
- });
-
- test(
- 'Get accessor undefined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {}
-
-A h() => null;
-
-f() {
- return h().x;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isRead: true);
- });
-
- test('Get class defined at top level', () {
- Helper helper = new Helper('''
-class A {}
-var t = A;
-''');
- helper.checkTypeReference('A', 'A', AccessKind.TOPLEVEL_TYPE, isRead: true);
- });
-
- test('Get class defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-var t = l.A;
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {}
-''');
- helper.checkTypeReference(
- 'l.A',
- 'A',
- AccessKind.TOPLEVEL_TYPE,
- isRead: true);
- });
-
- test('Get dynamic type', () {
- Helper helper = new Helper('''
-var t = dynamic;
-''');
- helper.checkTypeReference(
- 'dynamic',
- 'dynamic',
- AccessKind.TOPLEVEL_TYPE,
- isRead: true);
- });
-
- test('Get function typedef defined at top level', () {
- Helper helper = new Helper('''
-typedef F();
-var t = F;
-''');
- helper.checkTypeReference('F', 'F', AccessKind.TOPLEVEL_TYPE, isRead: true);
- });
-
- test('Get function typedef defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-var t = l.F;
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-typedef F();
-''');
- helper.checkTypeReference(
- 'l.F',
- 'F',
- AccessKind.TOPLEVEL_TYPE,
- isRead: true);
- });
-
- test('Get mixin application defined at top level', () {
- Helper helper = new Helper('''
-class A {}
-class B {}
-class C = A with B;
-var t = C;
-''');
- helper.checkTypeReference('C', 'C', AccessKind.TOPLEVEL_TYPE, isRead: true);
- });
-
- test('Get mixin application defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-var t = l.C;
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {}
-class B {}
-class C = A with B;
-''');
- helper.checkTypeReference(
- 'l.C',
- 'C',
- AccessKind.TOPLEVEL_TYPE,
- isRead: true);
- });
-
- test('Get type parameter of enclosing class', () {
- Helper helper = new Helper('''
-class A<T, U> {
- f() {
- var t = U;
- }
-}
-''');
- helper.checkTypeReference(
- 'U',
- 'U',
- AccessKind.TYPE_PARAMETER,
- isRead: true);
- });
-
- test('Set variable defined at top level', () {
- Helper helper = new Helper('''
-var x;
-
-f() {
- x = 1;
-}
-''');
- helper.checkStaticField('x', null, 'x', isWrite: true);
- });
-
- test('Set variable defined at top level in foreach loop', () {
- Helper helper = new Helper('''
-var x;
-
-f() {
- for (x in []) {}
-}
-''');
- helper.checkStaticField('x', null, 'x', isWrite: true);
- });
-
- test('Set variable defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.x = 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-var x;
-''');
- helper.checkStaticField('l.x', null, 'x', isWrite: true);
- });
-
- test('Set field defined statically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- static var x;
-
- f() {
- x = 1;
- }
-}
-''');
- helper.checkStaticField('x', 'A', 'x', isWrite: true);
- });
-
- test(
- 'Set field defined statically in class from inside class in foreach' + ' loop',
- () {
- Helper helper = new Helper('''
-class A {
- static var x;
-
- f() {
- for (x in []) {}
- }
-}
-''');
- helper.checkStaticField('x', 'A', 'x', isWrite: true);
- });
-
- test('Set field defined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {
- static var x;
-}
-
-f() {
- A.x = 1;
-}
-''');
- helper.checkStaticField('A.x', 'A', 'x', isWrite: true);
- });
-
- test(
- 'Set field defined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.A.x = 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {
- static var x;
-}
-''');
- helper.checkStaticField('l.A.x', 'A', 'x', isWrite: true);
- });
-
- test('Set field defined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- var x;
-
- f() {
- x = 1;
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isWrite: true);
- });
-
- test(
- 'Set field defined dynamically in class from inside class in foreach' + ' loop',
- () {
- Helper helper = new Helper('''
-class A {
- var x;
-
- f() {
- for (x in []) {}
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isWrite: true);
- });
-
- test(
- 'Set field defined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {
- var x;
-}
-
-f(A a) {
- a.x = 1;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isWrite: true);
- });
-
- test(
- 'Set field defined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {
- var x;
-}
-
-A h() => null;
-
-f() {
- h().x = 1;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isWrite: true);
- });
-
- test('Set variable defined locally', () {
- Helper helper = new Helper('''
-f() {
- var x;
- x = 1;
-}
-''');
- helper.checkLocalVariable('x', 'x', isWrite: true);
- });
-
- test('Set variable defined locally in foreach loop', () {
- Helper helper = new Helper('''
-f() {
- var x;
- for (x in []) {}
-}
-''');
- helper.checkLocalVariable('x', 'x', isWrite: true);
- });
-
- test('Set variable defined in parameter', () {
- Helper helper = new Helper('''
-f(x) {
- x = 1;
-}
-''');
- helper.checkParameter('x', 'x', isWrite: true);
- });
-
- test('Set variable defined in parameter in foreach loop', () {
- Helper helper = new Helper('''
-f(x) {
- for (x in []) {}
-}
-''');
- helper.checkParameter('x', 'x', isWrite: true);
- });
-
- test('Set accessor defined at top level', () {
- Helper helper = new Helper('''
-set x(value) {};
-
-f() {
- x = 1;
-}
-''');
- helper.checkStaticProperty('x', null, 'x', true, isWrite: true);
- });
-
- test('Set accessor defined at top level in foreach loop', () {
- Helper helper = new Helper('''
-set x(value) {};
-
-f() {
- for (x in []) {}
-}
-''');
- helper.checkStaticProperty('x', null, 'x', true, isWrite: true);
- });
-
- test('Set accessor defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.x = 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-set x(value) {};
-''');
- helper.checkStaticProperty('l.x', null, 'x', true, isWrite: true);
- });
-
- test('Set accessor defined statically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- static set x(value) {}
-
- f() {
- x = 1;
- }
-}
-''');
- helper.checkStaticProperty('x', 'A', 'x', true, isWrite: true);
- });
-
- test(
- 'Set accessor defined statically in class from inside class in' +
- ' foreach loop',
- () {
- Helper helper = new Helper('''
-class A {
- static set x(value) {}
-
- f() {
- for (x in []) {}
- }
-}
-''');
- helper.checkStaticProperty('x', 'A', 'x', true, isWrite: true);
- });
-
- test('Set accessor defined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {
- static set x(value) {}
-}
-
-f() {
- A.x = 1;
-}
-''');
- helper.checkStaticProperty('A.x', 'A', 'x', true, isWrite: true);
- });
-
- test(
- 'Set accessor defined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.A.x = 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {
- static set x(value) {}
-}
-''');
- helper.checkStaticProperty('l.A.x', 'A', 'x', true, isWrite: true);
- });
-
- test('Set accessor defined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- set x(value) {}
-
- f() {
- x = 1;
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isWrite: true);
- });
-
- test(
- 'Set accessor defined dynamically in class from inside class in' +
- ' foreach loop',
- () {
- Helper helper = new Helper('''
-class A {
- set x(value) {}
-
- f() {
- for (x in []) {}
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isWrite: true);
- });
-
- test(
- 'Set accessor defined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {
- set x(value) {}
-}
-
-f(A a) {
- a.x = 1;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isWrite: true);
- });
-
- test(
- 'Set accessor defined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {
- set x(value) {}
-}
-
-A h() => null;
-
-f() {
- h().x = 1;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isWrite: true);
- });
-
- test(
- 'Set accessor defined dynamically in class from outside class via dynamic var',
- () {
- Helper helper = new Helper('''
-f(a) {
- a.x = 1;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isWrite: true);
- });
-
- test(
- 'Set accessor defined dynamically in class from outside class via dynamic expression',
- () {
- Helper helper = new Helper('''
-h() => null;
-
-f() {
- h().x = 1;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isWrite: true);
- });
-
- test('Set accessor undefined at top level', () {
- Helper helper = new Helper('''
-f() {
- x = 1;
-}
-''');
- helper.checkDynamic('x', null, 'x', isWrite: true);
- });
-
- test('Set accessor undefined at top level in foreach loop', () {
- Helper helper = new Helper('''
-f() {
- for (x in []) {}
-}
-''');
- helper.checkDynamic('x', null, 'x', isWrite: true);
- });
-
- test('Set accessor undefined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.x = 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-''');
- helper.checkDynamic('l.x', null, 'x', isWrite: true);
- });
-
- test('Set accessor undefined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {}
-
-f() {
- A.x = 1;
-}
-''');
- helper.checkStaticProperty('A.x', 'A', 'x', false, isWrite: true);
- });
-
- test(
- 'Set accessor undefined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.A.x = 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {}
-''');
- helper.checkStaticProperty('l.A.x', 'A', 'x', false, isWrite: true);
- });
-
- test('Set accessor undefined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- f() {
- x = 1;
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isWrite: true);
- });
-
- test(
- 'Set accessor undefined dynamically in class from inside class in' +
- ' foreach loop',
- () {
- Helper helper = new Helper('''
-class A {
- f() {
- for (x in []) {}
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isWrite: true);
- });
-
- test(
- 'Set accessor undefined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {}
-
-f(A a) {
- a.x = 1;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isWrite: true);
- });
-
- test(
- 'Set accessor undefined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {}
-
-A h() => null;
-
-f() {
- h().x = 1;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isWrite: true);
- });
-
- test('RMW variable defined at top level', () {
- Helper helper = new Helper('''
-var x;
-
-f() {
- x += 1;
-}
-''');
- helper.checkStaticField('x', null, 'x', isRead: true, isWrite: true);
- });
-
- test('RMW variable defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.x += 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-var x;
-''');
- helper.checkStaticField('l.x', null, 'x', isRead: true, isWrite: true);
- });
-
- test('RMW field defined statically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- static var x;
-
- f() {
- x += 1;
- }
-}
-''');
- helper.checkStaticField('x', 'A', 'x', isRead: true, isWrite: true);
- });
-
- test('RMW field defined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {
- static var x;
-}
-
-f() {
- A.x += 1;
-}
-''');
- helper.checkStaticField('A.x', 'A', 'x', isRead: true, isWrite: true);
- });
-
- test(
- 'RMW field defined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.A.x += 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {
- static var x;
-}
-''');
- helper.checkStaticField('l.A.x', 'A', 'x', isRead: true, isWrite: true);
- });
-
- test('RMW field defined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- var x;
-
- f() {
- x += 1;
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isRead: true, isWrite: true);
- });
-
- test(
- 'RMW field defined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {
- var x;
-}
-
-f(A a) {
- a.x += 1;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isRead: true, isWrite: true);
- });
-
- test(
- 'RMW field defined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {
- var x;
-}
-
-A h() => null;
-
-f() {
- h().x += 1;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isRead: true, isWrite: true);
- });
-
- test('RMW variable defined locally', () {
- Helper helper = new Helper('''
-f() {
- var x;
- x += 1;
-}
-''');
- helper.checkLocalVariable('x', 'x', isRead: true, isWrite: true);
- });
-
- test('RMW variable defined in parameter', () {
- Helper helper = new Helper('''
-f(x) {
- x += 1;
-}
-''');
- helper.checkParameter('x', 'x', isRead: true, isWrite: true);
- });
-
- test('RMW accessor defined at top level', () {
- Helper helper = new Helper('''
-set x(value) {};
-
-f() {
- x += 1;
-}
-''');
- helper.checkStaticProperty(
- 'x',
- null,
- 'x',
- true,
- isRead: true,
- isWrite: true);
- });
-
- test('RMW accessor defined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.x += 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-set x(value) {};
-''');
- helper.checkStaticProperty(
- 'l.x',
- null,
- 'x',
- true,
- isRead: true,
- isWrite: true);
- });
-
- test('RMW accessor defined statically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- static set x(value) {}
-
- f() {
- x += 1;
- }
-}
-''');
- helper.checkStaticProperty(
- 'x',
- 'A',
- 'x',
- true,
- isRead: true,
- isWrite: true);
- });
-
- test('RMW accessor defined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {
- static set x(value) {}
-}
-
-f() {
- A.x += 1;
-}
-''');
- helper.checkStaticProperty(
- 'A.x',
- 'A',
- 'x',
- true,
- isRead: true,
- isWrite: true);
- });
-
- test(
- 'RMW accessor defined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.A.x += 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {
- static set x(value) {}
-}
-''');
- helper.checkStaticProperty(
- 'l.A.x',
- 'A',
- 'x',
- true,
- isRead: true,
- isWrite: true);
- });
-
- test('RMW accessor defined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- set x(value) {}
-
- f() {
- x += 1;
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isRead: true, isWrite: true);
- });
-
- test(
- 'RMW accessor defined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {
- set x(value) {}
-}
-
-f(A a) {
- a.x += 1;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isRead: true, isWrite: true);
- });
-
- test(
- 'RMW accessor defined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {
- set x(value) {}
-}
-
-A h() => null;
-
-f() {
- h().x += 1;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isRead: true, isWrite: true);
- });
-
- test(
- 'RMW accessor defined dynamically in class from outside class via dynamic var',
- () {
- Helper helper = new Helper('''
-f(a) {
- a.x += 1;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isRead: true, isWrite: true);
- });
-
- test(
- 'RMW accessor defined dynamically in class from outside class via dynamic expression',
- () {
- Helper helper = new Helper('''
-h() => null;
-
-f() {
- h().x += 1;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isRead: true, isWrite: true);
- });
-
- test('RMW accessor undefined at top level', () {
- Helper helper = new Helper('''
-f() {
- x += 1;
-}
-''');
- helper.checkDynamic('x', null, 'x', isRead: true, isWrite: true);
- });
-
- test('RMW accessor undefined at top level via prefix', () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.x += 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-''');
- helper.checkDynamic('l.x', null, 'x', isRead: true, isWrite: true);
- });
-
- test('RMW accessor undefined statically in class from outside class', () {
- Helper helper = new Helper('''
-class A {}
-
-f() {
- A.x += 1;
-}
-''');
- helper.checkStaticProperty(
- 'A.x',
- 'A',
- 'x',
- false,
- isRead: true,
- isWrite: true);
- });
-
- test(
- 'RMW accessor undefined statically in class from outside class via prefix',
- () {
- Helper helper = new Helper('''
-import 'lib.dart' as l;
-
-f() {
- l.A.x += 1;
-}
-''');
- helper.addFile('/lib.dart', '''
-library lib;
-
-class A {}
-''');
- helper.checkStaticProperty(
- 'l.A.x',
- 'A',
- 'x',
- false,
- isRead: true,
- isWrite: true);
- });
-
- test('RMW accessor undefined dynamically in class from inside class', () {
- Helper helper = new Helper('''
-class A {
- f() {
- x += 1;
- }
-}
-''');
- helper.checkDynamic('x', null, 'x', isRead: true, isWrite: true);
- });
-
- test(
- 'RMW accessor undefined dynamically in class from outside class via typed var',
- () {
- Helper helper = new Helper('''
-class A {}
-
-f(A a) {
- a.x += 1;
-}
-''');
- helper.checkDynamic('a.x', 'a', 'x', isRead: true, isWrite: true);
- });
-
- test(
- 'RMW accessor undefined dynamically in class from outside class via typed expression',
- () {
- Helper helper = new Helper('''
-class A {}
-
-A h() => null;
-
-f() {
- h().x += 1;
-}
-''');
- helper.checkDynamic('h().x', 'h()', 'x', isRead: true, isWrite: true);
- });
-}
-
-typedef void AccessHandler(Expression node, AccessSemantics semantics);
-
-class Helper {
- final MemoryResourceProvider provider = new MemoryResourceProvider();
- Source rootSource;
- AnalysisContext context;
-
- Helper(String rootContents) {
- DartSdk sdk = new MockSdk();
- String rootFile = '/root.dart';
- File file = provider.newFile(rootFile, rootContents);
- rootSource = file.createSource();
- context = AnalysisEngine.instance.createAnalysisContext();
- // Set up the source factory.
- List<UriResolver> uriResolvers = [
- new ResourceUriResolver(provider),
- new DartUriResolver(sdk)];
- context.sourceFactory = new SourceFactory(uriResolvers);
- // add the Source
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(rootSource);
- context.applyChanges(changeSet);
- }
-
- LibraryElement get libraryElement {
- return context.computeLibraryElement(rootSource);
- }
-
- void addFile(String path, String contents) {
- provider.newFile(path, contents);
- }
-
- /**
- * Verify that the node represented by [expectedSource] is classified as
- * a dynamic method invocation.
- */
- void checkDynamic(String expectedSource, String expectedTarget,
- String expectedName, {bool isRead: false, bool isWrite: false, bool isInvoke:
- false}) {
- TestVisitor visitor = new TestVisitor();
- int count = 0;
- visitor.onAccess = (AstNode node, AccessSemantics semantics) {
- count++;
- expect(node.toSource(), equals(expectedSource));
- expect(semantics.kind, equals(AccessKind.DYNAMIC));
- if (expectedTarget == null) {
- expect(semantics.target, isNull);
- } else {
- expect(semantics.target.toSource(), equals(expectedTarget));
- }
- expect(semantics.identifier.name, equals(expectedName));
- expect(semantics.element, isNull);
- expect(semantics.classElement, isNull);
- expect(semantics.isRead, equals(isRead));
- expect(semantics.isWrite, equals(isWrite));
- expect(semantics.isInvoke, equals(isInvoke));
- };
- libraryElement.unit.accept(visitor);
- expect(count, equals(1));
- }
-
- /**
- * Verify that the node represented by [expectedSource] is classified as
- * a local function invocation.
- */
- void checkLocalFunction(String expectedSource, String expectedName,
- {bool isRead: false, bool isWrite: false, bool isInvoke: false}) {
- TestVisitor visitor = new TestVisitor();
- int count = 0;
- visitor.onAccess = (AstNode node, AccessSemantics semantics) {
- count++;
- expect(node.toSource(), equals(expectedSource));
- expect(semantics.kind, equals(AccessKind.LOCAL_FUNCTION));
- expect(semantics.identifier.name, equals(expectedName));
- expect(semantics.element.displayName, equals(expectedName));
- expect(semantics.classElement, isNull);
- expect(semantics.target, isNull);
- expect(semantics.isRead, equals(isRead));
- expect(semantics.isWrite, equals(isWrite));
- expect(semantics.isInvoke, equals(isInvoke));
- };
- libraryElement.unit.accept(visitor);
- expect(count, equals(1));
- }
-
- /**
- * Verify that the node represented by [expectedSource] is classified as
- * a local variable access.
- */
- void checkLocalVariable(String expectedSource, String expectedName,
- {bool isRead: false, bool isWrite: false, bool isInvoke: false}) {
- TestVisitor visitor = new TestVisitor();
- int count = 0;
- visitor.onAccess = (AstNode node, AccessSemantics semantics) {
- count++;
- expect(node.toSource(), equals(expectedSource));
- expect(semantics.kind, equals(AccessKind.LOCAL_VARIABLE));
- expect(semantics.element.name, equals(expectedName));
- expect(semantics.classElement, isNull);
- expect(semantics.target, isNull);
- expect(semantics.isRead, equals(isRead));
- expect(semantics.isWrite, equals(isWrite));
- expect(semantics.isInvoke, equals(isInvoke));
- };
- libraryElement.unit.accept(visitor);
- expect(count, equals(1));
- }
-
- /**
- * Verify that the node represented by [expectedSource] is classified as a
- * parameter access.
- */
- void checkParameter(String expectedSource, String expectedName, {bool isRead:
- false, bool isWrite: false, bool isInvoke: false}) {
- TestVisitor visitor = new TestVisitor();
- int count = 0;
- visitor.onAccess = (AstNode node, AccessSemantics semantics) {
- count++;
- expect(node.toSource(), equals(expectedSource));
- expect(semantics.kind, equals(AccessKind.PARAMETER));
- expect(semantics.element.name, equals(expectedName));
- expect(semantics.classElement, isNull);
- expect(semantics.target, isNull);
- expect(semantics.isRead, equals(isRead));
- expect(semantics.isWrite, equals(isWrite));
- expect(semantics.isInvoke, equals(isInvoke));
- };
- libraryElement.unit.accept(visitor);
- expect(count, equals(1));
- }
-
- /**
- * Verify that the node represented by [expectedSource] is classified as
- * a static field element reference.
- */
- void checkStaticField(String expectedSource, String expectedClass,
- String expectedName, {bool isRead: false, bool isWrite: false, bool isInvoke:
- false}) {
- TestVisitor visitor = new TestVisitor();
- int count = 0;
- visitor.onAccess = (Expression node, AccessSemantics semantics) {
- count++;
- expect(node.toSource(), equals(expectedSource));
- expect(semantics.kind, equals(AccessKind.STATIC_FIELD));
- expect(semantics.identifier.name, equals(expectedName));
- expect(semantics.element.displayName, equals(expectedName));
- if (expectedClass == null) {
- expect(semantics.classElement, isNull);
- } else {
- expect(semantics.classElement, isNotNull);
- expect(semantics.classElement.displayName, equals(expectedClass));
- }
- expect(semantics.target, isNull);
- expect(semantics.isRead, equals(isRead));
- expect(semantics.isWrite, equals(isWrite));
- expect(semantics.isInvoke, equals(isInvoke));
- };
- libraryElement.unit.accept(visitor);
- expect(count, equals(1));
- }
-
- /**
- * Verify that the node represented by [expectedSource] is classified as
- * a static method.
- */
- void checkStaticMethod(String expectedSource, String expectedClass,
- String expectedName, bool defined, {bool isRead: false, bool isWrite: false,
- bool isInvoke: false}) {
- TestVisitor visitor = new TestVisitor();
- int count = 0;
- visitor.onAccess = (AstNode node, AccessSemantics semantics) {
- count++;
- expect(node.toSource(), equals(expectedSource));
- expect(semantics.kind, equals(AccessKind.STATIC_METHOD));
- expect(semantics.identifier.name, equals(expectedName));
- if (expectedClass == null) {
- expect(semantics.classElement, isNull);
- if (defined) {
- expect(semantics.element, new isInstanceOf<FunctionElement>());
- }
- } else {
- expect(semantics.classElement, isNotNull);
- expect(semantics.classElement.displayName, equals(expectedClass));
- if (defined) {
- expect(semantics.element, new isInstanceOf<MethodElement>());
- }
- }
- if (defined) {
- expect(semantics.element.displayName, equals(expectedName));
- } else {
- expect(semantics.element, isNull);
- }
- expect(semantics.target, isNull);
- expect(semantics.isRead, equals(isRead));
- expect(semantics.isWrite, equals(isWrite));
- expect(semantics.isInvoke, equals(isInvoke));
- };
- libraryElement.unit.accept(visitor);
- expect(count, equals(1));
- }
-
- /**
- * Verify that the node represented by [expectedSource] is classified as
- * a static property access.
- */
- void checkStaticProperty(String expectedSource, String expectedClass,
- String expectedName, bool defined, {bool isRead: false, bool isWrite: false,
- bool isInvoke: false}) {
- TestVisitor visitor = new TestVisitor();
- int count = 0;
- visitor.onAccess = (Expression node, AccessSemantics semantics) {
- count++;
- expect(node.toSource(), equals(expectedSource));
- expect(semantics.kind, equals(AccessKind.STATIC_PROPERTY));
- expect(semantics.identifier.name, equals(expectedName));
- if (expectedClass == null) {
- expect(semantics.classElement, isNull);
- } else {
- expect(semantics.classElement, isNotNull);
- expect(semantics.classElement.displayName, equals(expectedClass));
- }
- if (defined) {
- expect(semantics.element.displayName, equals(expectedName));
- } else {
- expect(semantics.element, isNull);
- }
- expect(semantics.target, isNull);
- expect(semantics.isRead, equals(isRead));
- expect(semantics.isWrite, equals(isWrite));
- expect(semantics.isInvoke, equals(isInvoke));
- };
- libraryElement.unit.accept(visitor);
- expect(count, equals(1));
- }
-
- /**
- * Verify that the node represented by [expectedSource] is classified as a
- * reference to a toplevel class or a type parameter.
- */
- void checkTypeReference(String expectedSource, String expectedName,
- AccessKind expectedKind, {bool isRead: false, bool isInvoke: false}) {
- TestVisitor visitor = new TestVisitor();
- int count = 0;
- visitor.onAccess = (AstNode node, AccessSemantics semantics) {
- count++;
- expect(node.toSource(), equals(expectedSource));
- expect(semantics.kind, equals(expectedKind));
- expect(semantics.element.name, equals(expectedName));
- expect(semantics.classElement, isNull);
- expect(semantics.target, isNull);
- expect(semantics.isRead, equals(isRead));
- expect(semantics.isWrite, isFalse);
- expect(semantics.isInvoke, equals(isInvoke));
- };
- libraryElement.unit.accept(visitor);
- expect(count, equals(1));
- }
-}
-
-/**
- * Visitor class used to run the tests.
- */
-class TestVisitor extends RecursiveAstVisitor {
- AccessHandler onAccess;
-
- @override
- visitMethodInvocation(MethodInvocation node) {
- onAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
- }
-
- @override
- visitPrefixedIdentifier(PrefixedIdentifier node) {
- onAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
- }
-
- @override
- visitPropertyAccess(PropertyAccess node) {
- onAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
- }
-
- @override
- visitSimpleIdentifier(SimpleIdentifier node) {
- AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
- if (semantics != null) {
- onAccess(node, semantics);
- }
- }
-}
diff --git a/pkg/analyzer2dart/test/mock_sdk.dart b/pkg/analyzer2dart/test/mock_sdk.dart
deleted file mode 100644
index 8cebd44..0000000
--- a/pkg/analyzer2dart/test/mock_sdk.dart
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library testing.mock_sdk;
-
-import 'package:analyzer/file_system/file_system.dart' as resource;
-import 'package:analyzer/file_system/memory_file_system.dart' as resource;
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-
-class MockSdk implements DartSdk {
- static const _MockSdkLibrary LIB_CORE =
- const _MockSdkLibrary('core', '/lib/core/core.dart', '''
-library dart.core;
-
-class Object {
- bool operator ==(other) => identical(this, other);
-}
-
-class Function {}
-class StackTrace {}
-class Symbol {}
-class Type {}
-
-abstract class Comparable<T> {
- int compareTo(T other);
-}
-
-class String implements Comparable<String> {
- bool get isEmpty => false;
- bool get isNotEmpty => false;
- int get length => 0;
-}
-
-class bool extends Object {}
-abstract class num implements Comparable<num> {
- bool operator <(num other);
- num operator +(num other);
- num operator -(num other);
- num operator *(num other);
- num operator /(num other);
- int toInt();
-}
-abstract class int extends num {
- bool get isEven => false;
- int operator -();
-}
-class double extends num {}
-class DateTime extends Object {}
-class Null extends Object {}
-
-class Deprecated extends Object {
- final String expires;
- const Deprecated(this.expires);
-}
-const Object deprecated = const Deprecated("next release");
-
-abstract class Iterable<E> {}
-
-abstract class List<E> extends Object implements Iterable {
- void add(E value);
- E operator [](int index);
- void operator []=(int index, E value);
-}
-class Map<K, V> extends Object {}
-
-external bool identical(Object a, Object b);
-
-void print(Object object) {}
-
-typedef int Comparator<T>(T a, T b);
-''');
-
- static const _MockSdkLibrary LIB_ASYNC =
- const _MockSdkLibrary('async', '/lib/async/async.dart', '''
-library dart.async;
-class Future<T> {
- static Future wait(List<Future> futures) => null;
-}
-
-class Stream<T> {}
-''');
-
- static const _MockSdkLibrary LIB_MATH =
- const _MockSdkLibrary('math', '/lib/math/math.dart', '''
-library dart.math;
-const double E = 2.718281828459045;
-const double PI = 3.1415926535897932;
-num min(num a, num b) => 0;
-num max(num a, num b) => 0;
-class Random {}
-''');
-
- static const _MockSdkLibrary LIB_HTML =
- const _MockSdkLibrary('html', '/lib/html/dartium/html_dartium.dart', '''
-library dart.html;
-class HtmlElement {}
-''');
-
- static const List<SdkLibrary> LIBRARIES = const [
- LIB_CORE,
- LIB_ASYNC,
- LIB_MATH,
- LIB_HTML,];
-
- final resource.MemoryResourceProvider provider =
- new resource.MemoryResourceProvider();
-
- /**
- * The [AnalysisContext] which is used for all of the sources.
- */
- InternalAnalysisContext _analysisContext;
-
- MockSdk() {
- LIBRARIES.forEach((_MockSdkLibrary library) {
- provider.newFile(library.path, library.content);
- });
- }
-
- @override
- AnalysisContext get context {
- if (_analysisContext == null) {
- _analysisContext = new SdkAnalysisContext();
- SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
- _analysisContext.sourceFactory = factory;
- ChangeSet changeSet = new ChangeSet();
- for (String uri in uris) {
- Source source = factory.forUri(uri);
- changeSet.addedSource(source);
- }
- _analysisContext.applyChanges(changeSet);
- }
- return _analysisContext;
- }
-
- @override
- List<SdkLibrary> get sdkLibraries => LIBRARIES;
-
- @override
- String get sdkVersion => throw unimplemented;
-
- UnimplementedError get unimplemented => new UnimplementedError();
-
- @override
- List<String> get uris {
- List<String> uris = <String>[];
- for (SdkLibrary library in LIBRARIES) {
- uris.add('dart:' + library.shortName);
- }
- return uris;
- }
-
- @override
- Source fromFileUri(Uri uri) {
- String filePath = uri.path;
- String libPath = '/lib';
- if (!filePath.startsWith("$libPath/")) {
- return null;
- }
- for (SdkLibrary library in LIBRARIES) {
- String libraryPath = library.path;
- if (filePath.replaceAll('\\', '/') == libraryPath) {
- String path = library.shortName;
- try {
- resource.File file = provider.getResource(uri.path);
- Uri dartUri = new Uri(scheme: 'dart', path: library.shortName);
- return file.createSource(dartUri);
- } catch (exception) {
- return null;
- }
- }
- if (filePath.startsWith("$libraryPath/")) {
- String pathInLibrary = filePath.substring(libraryPath.length + 1);
- String path = '${library.shortName}/${pathInLibrary}';
- try {
- resource.File file = provider.getResource(uri.path);
- Uri dartUri = new Uri(scheme: 'dart', path: path);
- return file.createSource(dartUri);
- } catch (exception) {
- return null;
- }
- }
- }
- return null;
- }
-
- @override
- SdkLibrary getSdkLibrary(String dartUri) {
- // getSdkLibrary() is only used to determine whether a library is internal
- // to the SDK. The mock SDK doesn't have any internals, so it's safe to
- // return null.
- return null;
- }
-
- @override
- Source mapDartUri(String dartUri) {
- const Map<String, String> uriToPath = const {
- "dart:core": "/lib/core/core.dart",
- "dart:html": "/lib/html/dartium/html_dartium.dart",
- "dart:async": "/lib/async/async.dart",
- "dart:math": "/lib/math/math.dart"
- };
-
- String path = uriToPath[dartUri];
- if (path != null) {
- resource.File file = provider.getResource(path);
- Uri uri = new Uri(scheme: 'dart', path: dartUri.substring(5));
- return file.createSource(uri);
- }
-
- // If we reach here then we tried to use a dartUri that's not in the
- // table above.
- throw unimplemented;
- }
-}
-
-
-class _MockSdkLibrary implements SdkLibrary {
- final String shortName;
- final String path;
- final String content;
-
- const _MockSdkLibrary(this.shortName, this.path, this.content);
-
- @override
- String get category => throw unimplemented;
-
- @override
- bool get isDart2JsLibrary => throw unimplemented;
-
- @override
- bool get isDocumented => throw unimplemented;
-
- @override
- bool get isImplementation => throw unimplemented;
-
- @override
- bool get isInternal => throw unimplemented;
-
- @override
- bool get isShared => throw unimplemented;
-
- @override
- bool get isVmLibrary => throw unimplemented;
-
- UnimplementedError get unimplemented => new UnimplementedError();
-}
diff --git a/pkg/analyzer2dart/test/output_helper.dart b/pkg/analyzer2dart/test/output_helper.dart
deleted file mode 100644
index 5a3f6b4..0000000
--- a/pkg/analyzer2dart/test/output_helper.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Helper classes for testing compiler output.
-library test.output_helper;
-
-import 'dart:async';
-
-
-class CollectingOutputProvider {
- StringBufferSink output;
-
- EventSink<String> call(String name, String extension) {
- return output = new StringBufferSink();
- }
-}
-
-class StringBufferSink implements EventSink<String> {
- StringBuffer sb = new StringBuffer();
-
- void add(String text) {
- sb.write(text);
- }
-
- void addError(errorEvent, [StackTrace stackTrace]) {}
-
- void close() {}
-
- String get text => sb.toString();
-}
-
diff --git a/pkg/analyzer2dart/test/sexpr_data.dart b/pkg/analyzer2dart/test/sexpr_data.dart
deleted file mode 100644
index e7d00ae..0000000
--- a/pkg/analyzer2dart/test/sexpr_data.dart
+++ /dev/null
@@ -1,1549 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Test data for sexpr_test.
-library test.sexpr.data;
-
-import 'test_helper.dart';
-
-class TestSpec extends TestSpecBase {
- // A [String] or a [Map<String, String>].
- final output;
-
- /// True if the test should be skipped when testing analyzer2dart.
- final bool skipInAnalyzerFrontend;
-
- const TestSpec(String input, this.output,
- {this.skipInAnalyzerFrontend: false}) : super(input);
-}
-
-const List<Group> TEST_DATA = const [
- const Group('Empty main', const [
- const TestSpec('''
-main() {}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-foo() {}
-main() {
- foo();
-}
-''', '''
-(FunctionDefinition main () () return
- (LetCont ((k0 (v0)
- (LetPrim (v1 (Constant (Null)))
- (InvokeContinuation return (v1)))))
- (InvokeStatic foo () k0)))
-''')
- ]),
-
- const Group('Literals', const [
- const TestSpec('''
-main() {
- return 0;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-main() {
- return 1.5;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Double 1.5)))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-main() {
- return true;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Bool true)))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-main() {
- return false;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Bool false)))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-main() {
- return "a";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (String "a")))
- (InvokeContinuation return (v0))))
-'''),
- ]),
-
- const Group('Parameters', const [
- const TestSpec('''
-main(args) {}
-''', '''
-(FunctionDefinition main () (args) return
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-main(a, b) {}
-''', '''
-(FunctionDefinition main () (a b) return
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-'''),
- ]),
-
- const Group('Pass arguments', const [
- const TestSpec('''
-foo(a) {}
-main() {
- foo(null);
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Null)))
- (LetCont ((k0 (v1)
- (LetPrim (v2 (Constant (Null)))
- (InvokeContinuation return (v2)))))
- (InvokeStatic foo (v0) k0))))
-'''),
-
- const TestSpec('''
-bar(b, c) {}
-foo(a) {}
-main() {
- foo(null);
- bar(0, "");
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Null)))
- (LetCont ((k0 (v1)
- (LetPrim (v2 (Constant (Int 0)))
- (LetPrim (v3 (Constant (String "")))
- (LetCont ((k1 (v4)
- (LetPrim (v5 (Constant (Null)))
- (InvokeContinuation return (v5)))))
- (InvokeStatic bar (v2 v3) k1))))))
- (InvokeStatic foo (v0) k0))))
-'''),
-
- const TestSpec('''
-foo(a) {}
-main() {
- return foo(null);
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Null)))
- (LetCont ((k0 (v1)
- (InvokeContinuation return (v1))))
- (InvokeStatic foo (v0) k0))))
-'''),
- ]),
-
- const Group('Local variables', const [
- const TestSpec('''
-main() {
- var a;
- return a;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-main() {
- var a = 0;
- return a;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-main(a) {
- return a;
-}
-''', '''
-(FunctionDefinition main () (a) return
- (InvokeContinuation return (a)))
-'''),
- ]),
-
- const Group('Local variable writes', const <TestSpec>[
- const TestSpec('''
-main() {
- var a;
- a = 10;
- return a;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Null)))
- (LetPrim (v1 (Constant (Int 10)))
- (InvokeContinuation return (v1)))))
-'''),
-
- const TestSpec('''
-main() {
- var a = 0;
- a = 10;
- return a;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (Int 10)))
- (InvokeContinuation return (v1)))))
-'''),
-
- const TestSpec('''
-main() {
- var a = 0;
- print(a);
- a = "";
- print(a);
- return a;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetCont ((k0 (v1)
- (LetPrim (v2 (Constant (String "")))
- (LetCont ((k1 (v3)
- (InvokeContinuation return (v2))))
- (InvokeStatic print (v2) k1)))))
- (InvokeStatic print (v0) k0))))
-'''),
-
- const TestSpec('''
-main(a) {
- print(a);
- a = "";
- print(a);
- return a;
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k1 (v2)
- (InvokeContinuation return (v1))))
- (InvokeStatic print (v1) k1)))))
- (InvokeStatic print (a) k0)))
-'''),
-
- const TestSpec('''
-main(a) {
- if (a) {
- a = "";
- }
- print(a);
- return a;
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (LetCont ((k1 (v1)
- (InvokeContinuation return (v0))))
- (InvokeStatic print (v0) k1))))
- (LetCont ((k2 ()
- (LetPrim (v2 (Constant (String "")))
- (InvokeContinuation k0 (v2))))
- (k3 ()
- (InvokeContinuation k0 (a))))
- (Branch (IsTrue a) k2 k3))))
-'''),
- ]),
-
- const Group('Dynamic access', const [
- const TestSpec('''
-main(a) {
- return a.foo;
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (InvokeMethod a foo () k0)))
-'''),
-
- const TestSpec('''
-main() {
- var a = "";
- return a.foo;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (String "")))
- (LetCont ((k0 (v1)
- (InvokeContinuation return (v1))))
- (InvokeMethod v0 foo () k0))))
-'''),
- ]),
-
- const Group('Dynamic invocation', const [
- const TestSpec('''
-main(a) {
- return a.foo(0);
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (Constant (Int 0)))
- (LetCont ((k0 (v1)
- (InvokeContinuation return (v1))))
- (InvokeMethod a foo (v0) k0))))
-'''),
-
- const TestSpec('''
-main() {
- var a = "";
- return a.foo(0, 1);
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (String "")))
- (LetPrim (v1 (Constant (Int 0)))
- (LetPrim (v2 (Constant (Int 1)))
- (LetCont ((k0 (v3)
- (InvokeContinuation return (v3))))
- (InvokeMethod v0 foo (v1 v2) k0))))))
-'''),
- ]),
-
- const Group('Binary expressions', const [
- const TestSpec('''
-main() {
- return 0 + "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 + (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 - "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 - (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 * "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 * (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 / "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 / (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 ~/ "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 ~/ (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 < "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 < (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 <= "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 <= (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 > "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 > (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 >= "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 >= (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 << "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 << (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 >> "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 >> (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 & "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 & (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 | "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 | (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 ^ "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 ^ (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 == "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 == (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 != "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (LetCont ((k1 (v3)
- (InvokeContinuation return (v3))))
- (LetCont ((k2 ()
- (LetPrim (v4 (Constant (Bool false)))
- (InvokeContinuation k1 (v4))))
- (k3 ()
- (LetPrim (v5 (Constant (Bool true)))
- (InvokeContinuation k1 (v5)))))
- (Branch (IsTrue v2) k2 k3)))))
- (InvokeMethod v0 == (v1) k0)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 && "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetCont ((k0 (v1)
- (InvokeContinuation return (v1))))
- (LetCont ((k1 ()
- (LetPrim (v2 (Constant (String "")))
- (LetCont ((k2 ()
- (LetPrim (v3 (Constant (Bool true)))
- (InvokeContinuation k0 (v3))))
- (k3 ()
- (LetPrim (v4 (Constant (Bool false)))
- (InvokeContinuation k0 (v4)))))
- (Branch (IsTrue v2) k2 k3))))
- (k4 ()
- (LetPrim (v5 (Constant (Bool false)))
- (InvokeContinuation k0 (v5)))))
- (Branch (IsTrue v0) k1 k4)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 || "";
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetCont ((k0 (v1)
- (InvokeContinuation return (v1))))
- (LetCont ((k1 ()
- (LetPrim (v2 (Constant (Bool true)))
- (InvokeContinuation k0 (v2))))
- (k2 ()
- (LetPrim (v3 (Constant (String "")))
- (LetCont ((k3 ()
- (LetPrim (v4 (Constant (Bool true)))
- (InvokeContinuation k0 (v4))))
- (k4 ()
- (LetPrim (v5 (Constant (Bool false)))
- (InvokeContinuation k0 (v5)))))
- (Branch (IsTrue v3) k3 k4)))))
- (Branch (IsTrue v0) k1 k2)))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 + "" * 2;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetPrim (v2 (Constant (Int 2)))
- (LetCont ((k0 (v3)
- (LetCont ((k1 (v4)
- (InvokeContinuation return (v4))))
- (InvokeMethod v0 + (v3) k1))))
- (InvokeMethod v1 * (v2) k0))))))
-'''),
-
- const TestSpec('''
-main() {
- return 0 * "" + 2;
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "")))
- (LetCont ((k0 (v2)
- (LetPrim (v3 (Constant (Int 2)))
- (LetCont ((k1 (v4)
- (InvokeContinuation return (v4))))
- (InvokeMethod v2 + (v3) k1)))))
- (InvokeMethod v0 * (v1) k0)))))
-'''),
- ]),
-
- const Group('If statement', const [
- const TestSpec('''
-main(a) {
- if (a) {
- print(0);
- }
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 ()
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0)))))
- (LetCont ((k1 ()
- (LetPrim (v1 (Constant (Int 0)))
- (LetCont ((k2 (v2)
- (InvokeContinuation k0 ())))
- (InvokeStatic print (v1) k2))))
- (k3 ()
- (InvokeContinuation k0 ())))
- (Branch (IsTrue a) k1 k3))))
-'''),
-
- const TestSpec('''
-main(a) {
- if (a) {
- print(0);
- } else {
- print(1);
- }
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 ()
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0)))))
- (LetCont ((k1 ()
- (LetPrim (v1 (Constant (Int 0)))
- (LetCont ((k2 (v2)
- (InvokeContinuation k0 ())))
- (InvokeStatic print (v1) k2))))
- (k3 ()
- (LetPrim (v3 (Constant (Int 1)))
- (LetCont ((k4 (v4)
- (InvokeContinuation k0 ())))
- (InvokeStatic print (v3) k4)))))
- (Branch (IsTrue a) k1 k3))))
-'''),
-
- const TestSpec('''
-main(a) {
- if (a) {
- print(0);
- } else {
- print(1);
- print(2);
- }
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 ()
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0)))))
- (LetCont ((k1 ()
- (LetPrim (v1 (Constant (Int 0)))
- (LetCont ((k2 (v2)
- (InvokeContinuation k0 ())))
- (InvokeStatic print (v1) k2))))
- (k3 ()
- (LetPrim (v3 (Constant (Int 1)))
- (LetCont ((k4 (v4)
- (LetPrim (v5 (Constant (Int 2)))
- (LetCont ((k5 (v6)
- (InvokeContinuation k0 ())))
- (InvokeStatic print (v5) k5)))))
- (InvokeStatic print (v3) k4)))))
- (Branch (IsTrue a) k1 k3))))
-'''),
- ]),
-
- const Group('Conditional expression', const [
- const TestSpec('''
-main(a) {
- return a ? print(0) : print(1);
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (LetCont ((k1 ()
- (LetPrim (v1 (Constant (Int 0)))
- (LetCont ((k2 (v2)
- (InvokeContinuation k0 (v2))))
- (InvokeStatic print (v1) k2))))
- (k3 ()
- (LetPrim (v3 (Constant (Int 1)))
- (LetCont ((k4 (v4)
- (InvokeContinuation k0 (v4))))
- (InvokeStatic print (v3) k4)))))
- (Branch (IsTrue a) k1 k3))))
-'''),
- ]),
-
-
- // These test that unreachable statements are skipped within a block.
- const Group('Block statements', const <TestSpec>[
- const TestSpec('''
-main(a) {
- return 0;
- return 1;
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (Constant (Int 0)))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-main(a) {
- if (a) {
- return 0;
- return 1;
- } else {
- return 2;
- return 3;
- }
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 ()
- (LetPrim (v0 (Constant (Int 0)))
- (InvokeContinuation return (v0))))
- (k1 ()
- (LetPrim (v1 (Constant (Int 2)))
- (InvokeContinuation return (v1)))))
- (Branch (IsTrue a) k0 k1)))
-'''),
-
- const TestSpec('''
-main(a) {
- if (a) {
- print(0);
- return 0;
- return 1;
- } else {
- print(2);
- return 2;
- return 3;
- }
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 ()
- (LetPrim (v0 (Constant (Int 0)))
- (LetCont ((k1 (v1)
- (LetPrim (v2 (Constant (Int 0)))
- (InvokeContinuation return (v2)))))
- (InvokeStatic print (v0) k1))))
- (k2 ()
- (LetPrim (v3 (Constant (Int 2)))
- (LetCont ((k3 (v4)
- (LetPrim (v5 (Constant (Int 2)))
- (InvokeContinuation return (v5)))))
- (InvokeStatic print (v3) k3)))))
- (Branch (IsTrue a) k0 k2)))
-'''),
- ]),
-
- const Group('Constructor invocation', const <TestSpec>[
- const TestSpec('''
-main(a) {
- new Object();
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (LetPrim (v1 (Constant (Null)))
- (InvokeContinuation return (v1)))))
- (InvokeConstructor Object () k0)))
-'''),
-
- const TestSpec('''
-main(a) {
- new Deprecated("");
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (Constant (String "")))
- (LetCont ((k0 (v1)
- (LetPrim (v2 (Constant (Null)))
- (InvokeContinuation return (v2)))))
- (InvokeConstructor Deprecated (v0) k0))))
-'''),
- ]),
-
- const Group('List literal', const <TestSpec>[
- const TestSpec('''
-main() {
- return [];
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (LiteralList ()))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-main() {
- return [0];
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (LiteralList (v0)))
- (InvokeContinuation return (v1)))))
-'''),
-
- const TestSpec('''
-main(a) {
- return [0, 1, a];
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (Int 1)))
- (LetPrim (v2 (LiteralList (v0 v1 a)))
- (InvokeContinuation return (v2))))))
-'''),
-
- const TestSpec('''
-main(a) {
- return [0, [1], [a, [3]]];
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (Int 1)))
- (LetPrim (v2 (LiteralList (v1)))
- (LetPrim (v3 (Constant (Int 3)))
- (LetPrim (v4 (LiteralList (v3)))
- (LetPrim (v5 (LiteralList (a v4)))
- (LetPrim (v6 (LiteralList (v0 v2 v5)))
- (InvokeContinuation return (v6))))))))))
-'''),
- ]),
-
- const Group('Map literal', const <TestSpec>[
- const TestSpec('''
-main() {
- return {};
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (LiteralMap () ()))
- (InvokeContinuation return (v0))))
-'''),
-
- const TestSpec('''
-main() {
- return {"a": 0};
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (String "a")))
- (LetPrim (v1 (Constant (Int 0)))
- (LetPrim (v2 (LiteralMap (v0) (v1)))
- (InvokeContinuation return (v2))))))
-'''),
-
- const TestSpec('''
-main(a) {
- return {"a": 0, "b": 1, "c": a};
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (Constant (String "a")))
- (LetPrim (v1 (Constant (Int 0)))
- (LetPrim (v2 (Constant (String "b")))
- (LetPrim (v3 (Constant (Int 1)))
- (LetPrim (v4 (Constant (String "c")))
- (LetPrim (v5 (LiteralMap (v0 v2 v4) (v1 v3 a)))
- (InvokeContinuation return (v5)))))))))
-'''),
-
- const TestSpec('''
-main(a) {
- return {0: "a", 1: {2: "b"}, a: {3: "c"}};
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (Constant (Int 0)))
- (LetPrim (v1 (Constant (String "a")))
- (LetPrim (v2 (Constant (Int 1)))
- (LetPrim (v3 (Constant (Int 2)))
- (LetPrim (v4 (Constant (String "b")))
- (LetPrim (v5 (LiteralMap (v3) (v4)))
- (LetPrim (v6 (Constant (Int 3)))
- (LetPrim (v7 (Constant (String "c")))
- (LetPrim (v8 (LiteralMap (v6) (v7)))
- (LetPrim (v9 (LiteralMap (v0 v2 a) (v1 v5 v8)))
- (InvokeContinuation return (v9)))))))))))))
-'''),
- ]),
-
- const Group('For loop', const <TestSpec>[
- const TestSpec('''
-main() {
- for (;;) {}
-}
-''', '''
-(FunctionDefinition main () () return
- (LetCont ((rec k0 ()
- (LetPrim (v0 (Constant (Bool true)))
- (LetCont ((k1 ()
- (LetPrim (v1 (Constant (Null)))
- (InvokeContinuation return (v1))))
- (k2 ()
- (InvokeContinuation rec k0 ())))
- (Branch (IsTrue v0) k2 k1)))))
- (InvokeContinuation k0 ())))
-'''),
-
-const TestSpec('''
-main() {
- for (var i = 0; i < 10; i = i + 1) {
- print(i);
- }
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetCont ((rec k0 (v1)
- (LetPrim (v2 (Constant (Int 10)))
- (LetCont ((k1 (v3)
- (LetCont ((k2 ()
- (LetPrim (v4 (Constant (Null)))
- (InvokeContinuation return (v4))))
- (k3 ()
- (LetCont ((k4 (v5)
- (LetPrim (v6 (Constant (Int 1)))
- (LetCont ((k5 (v7)
- (InvokeContinuation rec k0 (v7))))
- (InvokeMethod v1 + (v6) k5)))))
- (InvokeStatic print (v1) k4))))
- (Branch (IsTrue v3) k3 k2))))
- (InvokeMethod v1 < (v2) k1)))))
- (InvokeContinuation k0 (v0)))))
-'''),
-
-const TestSpec('''
-main(i) {
- for (i = 0; i < 10; i = i + 1) {
- print(i);
- }
-}
-''', '''
-(FunctionDefinition main () (i) return
- (LetPrim (v0 (Constant (Int 0)))
- (LetCont ((rec k0 (v1)
- (LetPrim (v2 (Constant (Int 10)))
- (LetCont ((k1 (v3)
- (LetCont ((k2 ()
- (LetPrim (v4 (Constant (Null)))
- (InvokeContinuation return (v4))))
- (k3 ()
- (LetCont ((k4 (v5)
- (LetPrim (v6 (Constant (Int 1)))
- (LetCont ((k5 (v7)
- (InvokeContinuation rec k0 (v7))))
- (InvokeMethod v1 + (v6) k5)))))
- (InvokeStatic print (v1) k4))))
- (Branch (IsTrue v3) k3 k2))))
- (InvokeMethod v1 < (v2) k1)))))
- (InvokeContinuation k0 (v0)))))
-'''),
- ]),
-
- const Group('While loop', const <TestSpec>[
- const TestSpec('''
-main() {
- while (true) {}
-}
-''', '''
-(FunctionDefinition main () () return
- (LetCont ((rec k0 ()
- (LetPrim (v0 (Constant (Bool true)))
- (LetCont ((k1 ()
- (LetPrim (v1 (Constant (Null)))
- (InvokeContinuation return (v1))))
- (k2 ()
- (InvokeContinuation rec k0 ())))
- (Branch (IsTrue v0) k2 k1)))))
- (InvokeContinuation k0 ())))
-'''),
-
-const TestSpec('''
-main() {
- var i = 0;
- while (i < 10) {
- print(i);
- i = i + 1;
- }
-}
-''', '''
-(FunctionDefinition main () () return
- (LetPrim (v0 (Constant (Int 0)))
- (LetCont ((rec k0 (v1)
- (LetPrim (v2 (Constant (Int 10)))
- (LetCont ((k1 (v3)
- (LetCont ((k2 ()
- (LetPrim (v4 (Constant (Null)))
- (InvokeContinuation return (v4))))
- (k3 ()
- (LetCont ((k4 (v5)
- (LetPrim (v6 (Constant (Int 1)))
- (LetCont ((k5 (v7)
- (InvokeContinuation rec k0 (v7))))
- (InvokeMethod v1 + (v6) k5)))))
- (InvokeStatic print (v1) k4))))
- (Branch (IsTrue v3) k3 k2))))
- (InvokeMethod v1 < (v2) k1)))))
- (InvokeContinuation k0 (v0)))))
-'''),
- ]),
-
- const Group('Type operators', const <TestSpec>[
- const TestSpec('''
-main(a) {
- return a is String;
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (TypeOperator is a String () k0)))
-'''),
-
- const TestSpec('''
-main(a) {
- return a is List<String>;
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (TypeOperator is a List<String> () k0)))
-'''),
-
- const TestSpec('''
-main(a) {
- return a is Comparator<String>;
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (TypeOperator is a Comparator<String> () k0)))
-'''),
-
- const TestSpec('''
-main(a) {
- return a is! String;
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (LetCont ((k1 (v1)
- (InvokeContinuation return (v1))))
- (LetCont ((k2 ()
- (LetPrim (v2 (Constant (Bool false)))
- (InvokeContinuation k1 (v2))))
- (k3 ()
- (LetPrim (v3 (Constant (Bool true)))
- (InvokeContinuation k1 (v3)))))
- (Branch (IsTrue v0) k2 k3)))))
- (TypeOperator is a String () k0)))
-'''),
-
-const TestSpec('''
-main(a) {
- return a as String;
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (TypeOperator as a String () k0)))
-'''),
- ]),
-
- const Group('For in loop', const <TestSpec>[
-// TODO(johnniwinther): Add tests for `i` as top-level, static and instance
-// fields.
- const TestSpec('''
-main(a) {
- for (var i in a) {
- print(i);
- }
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (LetCont ((rec k1 (v1)
- (LetCont ((k2 (v2)
- (LetCont ((k3 ()
- (LetPrim (v3 (Constant (Null)))
- (InvokeContinuation return (v3))))
- (k4 ()
- (LetPrim (v4 (Constant (Null)))
- (LetCont ((k5 (v5)
- (LetCont ((k6 (v6)
- (InvokeContinuation rec k1 (v1))))
- (InvokeStatic print (v5) k6))))
- (InvokeMethod v0 current () k5)))))
- (Branch (IsTrue v2) k4 k3))))
- (InvokeMethod v0 moveNext () k2))))
- (InvokeContinuation k1 (a)))))
- (InvokeMethod a iterator () k0)))
-'''),
-
- const TestSpec('''
-main(a) {
- for (var i in a) {
- print(i);
- i = 0;
- print(i);
- }
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (LetCont ((rec k1 (v1)
- (LetCont ((k2 (v2)
- (LetCont ((k3 ()
- (LetPrim (v3 (Constant (Null)))
- (InvokeContinuation return (v3))))
- (k4 ()
- (LetPrim (v4 (Constant (Null)))
- (LetCont ((k5 (v5)
- (LetCont ((k6 (v6)
- (LetPrim (v7 (Constant (Int 0)))
- (LetCont ((k7 (v8)
- (InvokeContinuation rec k1 (v1))))
- (InvokeStatic print (v7) k7)))))
- (InvokeStatic print (v5) k6))))
- (InvokeMethod v0 current () k5)))))
- (Branch (IsTrue v2) k4 k3))))
- (InvokeMethod v0 moveNext () k2))))
- (InvokeContinuation k1 (a)))))
- (InvokeMethod a iterator () k0)))
-'''),
-
- const TestSpec('''
-main(a) {
- var i;
- for (i in a) {
- print(i);
- }
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (Constant (Null)))
- (LetCont ((k0 (v1)
- (LetCont ((rec k1 (v2 v3)
- (LetCont ((k2 (v4)
- (LetCont ((k3 ()
- (LetPrim (v5 (Constant (Null)))
- (InvokeContinuation return (v5))))
- (k4 ()
- (LetCont ((k5 (v6)
- (LetCont ((k6 (v7)
- (InvokeContinuation rec k1 (v2 v6))))
- (InvokeStatic print (v6) k6))))
- (InvokeMethod v1 current () k5))))
- (Branch (IsTrue v4) k4 k3))))
- (InvokeMethod v1 moveNext () k2))))
- (InvokeContinuation k1 (a v0)))))
- (InvokeMethod a iterator () k0))))
-'''),
- ]),
-
- const Group('Local functions', const <TestSpec>[
- const TestSpec('''
-main(a) {
- local() {}
- return local();
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (CreateFunction
- (FunctionDefinition local () () return
- (LetPrim (v1 (Constant (Null)))
- (InvokeContinuation return (v1))))))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 call () k0))))
-'''),
-
- const TestSpec('''
-main(a) {
- local() {}
- var l = local;
- return l();
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (CreateFunction
- (FunctionDefinition local () () return
- (LetPrim (v1 (Constant (Null)))
- (InvokeContinuation return (v1))))))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 call () k0))))
-'''),
-
- const TestSpec('''
-main(a) {
- return () {}();
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetPrim (v0 (CreateFunction
- (FunctionDefinition () () return
- (LetPrim (v1 (Constant (Null)))
- (InvokeContinuation return (v1))))))
- (LetCont ((k0 (v2)
- (InvokeContinuation return (v2))))
- (InvokeMethod v0 call () k0))))
-'''),
-
- const TestSpec('''
-main(a) {
- var c = a ? () { return 0; } : () { return 1; }
- return c();
-}
-''', '''
-(FunctionDefinition main () (a) return
- (LetCont ((k0 (v0)
- (LetCont ((k1 (v1)
- (InvokeContinuation return (v1))))
- (InvokeMethod v0 call () k1))))
- (LetCont ((k2 ()
- (LetPrim (v2 (CreateFunction
- (FunctionDefinition () () return
- (LetPrim (v3 (Constant (Int 0)))
- (InvokeContinuation return (v3))))))
- (InvokeContinuation k0 (v2))))
- (k3 ()
- (LetPrim (v4 (CreateFunction
- (FunctionDefinition () () return
- (LetPrim (v5 (Constant (Int 1)))
- (InvokeContinuation return (v5))))))
- (InvokeContinuation k0 (v4)))))
- (Branch (IsTrue a) k2 k3))))
-'''),
- ]),
-
- const Group('Top level field', const <TestSpec>[
- const TestSpec('''
-var field;
-main(args) {
- return field;
-}
-''', const {
- 'main': '''
-(FunctionDefinition main () (args) return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (GetLazyStatic field k0)))
-''',
- 'field': '''
-(FieldDefinition field)
-'''}),
-
- const TestSpec('''
-var field = null;
-main(args) {
- return field;
-}
-''', const {
- 'main': '''
-(FunctionDefinition main () (args) return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (GetLazyStatic field k0)))
-''',
- 'field': '''
-(FieldDefinition field () return
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-'''}),
-
- const TestSpec('''
-var field = 0;
-main(args) {
- return field;
-}
-''', const {
- 'main': '''
-(FunctionDefinition main () (args) return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (GetLazyStatic field k0)))
-''',
- 'field': '''
-(FieldDefinition field () return
- (LetPrim (v0 (Constant (Int 0)))
- (InvokeContinuation return (v0))))
-'''}),
-
- const TestSpec('''
-var field;
-main(args) {
- field = args.length;
- return field;
-}
-''', '''
-(FunctionDefinition main () (args) return
- (LetCont ((k0 (v0)
- (SetStatic field v0
- (LetCont ((k1 (v1)
- (InvokeContinuation return (v1))))
- (GetLazyStatic field k1)))))
- (InvokeMethod args length () k0)))
-'''),
- ]),
-
- const Group('Closure variables', const <TestSpec>[
- const TestSpec('''
-main(x,foo) {
- print(x);
- getFoo() => foo;
- print(getFoo());
-}
-''', '''
-(FunctionDefinition main () (x foo) return
- (LetCont ((k0 (v0)
- (LetPrim (v1 (CreateFunction
- (FunctionDefinition getFoo () () return
- (LetPrim (v2 (GetMutableVariable foo))
- (InvokeContinuation return (v2))))))
- (LetCont ((k1 (v3)
- (LetCont ((k2 (v4)
- (LetPrim (v5 (Constant (Null)))
- (InvokeContinuation return (v5)))))
- (InvokeStatic print (v3) k2))))
- (InvokeMethod v1 call () k1)))))
- (InvokeStatic print (x) k0)))
-''', skipInAnalyzerFrontend: true)
- ]),
-
- const Group('Constructors', const <TestSpec>[
- const TestSpec('''
-class C {}
-main() {
- return new C();
-}
-''',
- const {
-'main': '''
-(FunctionDefinition main () () return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (InvokeConstructor C () k0)))
-''',
-'C.': '''
-(ConstructorDefinition (this) () return (
- )
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-'''}),
-
- const TestSpec('''
-class C {
- C() {}
-}
-main() {
- return new C();
-}
-''',
- const {
-'main': '''
-(FunctionDefinition main () () return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (InvokeConstructor C () k0)))
-''',
-'C.': '''
-(ConstructorDefinition (this) () return (
- )
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-'''}),
-
- const TestSpec('''
-class B {}
-class C extends B {
- C() {}
-}
-main() {
- return new C();
-}
-''',
- const {
-'main': '''
-(FunctionDefinition main () () return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (InvokeConstructor C () k0)))
-''',
-'B.': '''
-(ConstructorDefinition (this) () return (
- )
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-''',
-'C.': '''
-(ConstructorDefinition (this) () return (
- )
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-'''}),
-
- const TestSpec('''
-class B {
- B() {}
-}
-class C extends B {}
-main() {
- return new C();
-}
-''',
- const {
-'main': '''
-(FunctionDefinition main () () return
- (LetCont ((k0 (v0)
- (InvokeContinuation return (v0))))
- (InvokeConstructor C () k0)))
-''',
-'B.': '''
-(ConstructorDefinition (this) () return (
- )
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-''',
-'C.': '''
-(ConstructorDefinition (this) () return (
- )
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-'''}),
- ]),
-
- const Group('Instance method', const <TestSpec>[
- const TestSpec('''
-class C {
- C() {}
- foo() {}
-}
-main() {
- return new C().foo();
-}
-''',
- const {
-'main': '''
-(FunctionDefinition main () () return
- (LetCont ((k0 (v0)
- (LetCont ((k1 (v1)
- (InvokeContinuation return (v1))))
- (InvokeMethod v0 foo () k1))))
- (InvokeConstructor C () k0)))
-''',
-'C.foo': '''
-(FunctionDefinition foo (this) () return
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0))))
-'''}),
- ]),
-
-
- const Group('Try-catch', const <TestSpec>[
- const TestSpec('''
-main() {
- try {} catch (e) {}
-}
-''',
-'''
-(FunctionDefinition main () () return
- (LetCont ((k0 ()
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0)))))
- (LetHandler ((v1 v2)
- (InvokeContinuation k0 ()))
- (InvokeContinuation k0 ()))))
-'''),
-
- const TestSpec('''
-main() {
- try {
- return;
- } catch (e) {}
-}
-''',
-'''
-(FunctionDefinition main () () return
- (LetCont ((k0 ()
- (LetPrim (v0 (Constant (Null)))
- (InvokeContinuation return (v0)))))
- (LetHandler ((v1 v2)
- (InvokeContinuation k0 ()))
- (LetPrim (v3 (Constant (Null)))
- (InvokeContinuation return (v3))))))
-'''),
- ]),
-];
diff --git a/pkg/analyzer2dart/test/sexpr_test.dart b/pkg/analyzer2dart/test/sexpr_test.dart
deleted file mode 100644
index 2c8da58..0000000
--- a/pkg/analyzer2dart/test/sexpr_test.dart
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Unittest test of the CPS ir generated by the analyzer2dart compiler.
-
-import 'mock_sdk.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:compiler/src/cps_ir/cps_ir_nodes.dart';
-import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart';
-import 'package:compiler/src/elements/elements.dart' as dart2js;
-import 'package:unittest/unittest.dart';
-
-import '../lib/src/closed_world.dart';
-import '../lib/src/driver.dart';
-import '../lib/src/converted_world.dart';
-import 'output_helper.dart';
-import 'test_helper.dart';
-import 'sexpr_data.dart';
-
-main(List<String> args) {
- performTests(TEST_DATA, unittester, checkResult, args);
-}
-
-checkResult(TestSpec result) {
- if (result.skipInAnalyzerFrontend) return;
- String input = result.input.trim();
- CollectingOutputProvider outputProvider = new CollectingOutputProvider();
- MemoryResourceProvider provider = new MemoryResourceProvider();
- DartSdk sdk = new MockSdk();
- Driver driver = new Driver(provider, sdk, outputProvider);
- String rootFile = '/root.dart';
- provider.newFile(rootFile, input);
- Source rootSource = driver.setRoot(rootFile);
- FunctionElement entryPoint = driver.resolveEntryPoint(rootSource);
- ClosedWorld world = driver.computeWorld(entryPoint);
- ConvertedWorld convertedWorld = convertWorld(world);
-
- void checkOutput(String elementName,
- dart2js.Element element,
- String expectedOutput) {
- RootNode ir = convertedWorld.getIr(element);
- if (expectedOutput == null) {
- expect(ir, isNull,
- reason: "\nInput:\n${result.input}\n"
- "No CPS IR expected for $element");
- } else {
- expect(ir, isNotNull,
- reason: "\nInput:\n${result.input}\n"
- "No CPS IR for $element");
- expectedOutput = expectedOutput.trim();
- String output = ir.accept(new SExpressionStringifier());
- expect(output, equals(expectedOutput),
- reason: "\nInput:\n${result.input}\n"
- "Expected for '$elementName':\n$expectedOutput\n"
- "Actual for '$elementName':\n$output\n");
- }
- }
-
- if (result.output is String) {
- checkOutput('main', convertedWorld.mainFunction, result.output);
- } else {
- assert(result.output is Map<String, String>);
- dart2js.LibraryElement mainLibrary = convertedWorld.mainFunction.library;
- result.output.forEach((String elementName, String output) {
- bool found = false;
- List<String> names = <String>[];
- convertedWorld.resolvedElements.forEach((dart2js.Element element) {
- if (element.library == mainLibrary) {
- String name = element.name;
- if (element.enclosingClass != null) {
- name = '${element.enclosingClass.name}.$name';
- }
- if (name == elementName) {
- checkOutput(elementName, element, output);
- found = true;
- }
- names.add(name);
- }
- });
- expect(found, isTrue, reason: "'$elementName' not found in $names.");
- });
- }
-}
-
diff --git a/pkg/analyzer2dart/test/test_helper.dart b/pkg/analyzer2dart/test/test_helper.dart
deleted file mode 100644
index 86a52b0..0000000
--- a/pkg/analyzer2dart/test/test_helper.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Helpers for defining input/output based unittests through (constant) data.
-
-import 'package:unittest/unittest.dart';
-
-/// A unittest group with a name and a list of input/output results.
-class Group {
- final String name;
- final List<TestSpecBase> results;
-
- const Group(this.name, this.results);
-}
-
-/// A [input] for which a certain processing result is expected.
-class TestSpecBase {
- final String input;
-
- const TestSpecBase(this.input);
-}
-
-typedef TestGroup(Group group, RunTest check);
-typedef RunTest(TestSpecBase result);
-
-/// Test [data] using [testGroup] and [check].
-void performTests(List<Group> data,
- TestGroup testGroup,
- RunTest runTest,
- List<String> groupsToRun) {
- for (Group group in data) {
- if (groupsToRun.isNotEmpty &&
- !groupsToRun.contains(group.name)) {
- // Skip this group.
- continue;
- }
- testGroup(group, runTest);
- }
-}
-
-/// Test group using unittest.
-unittester(Group group, RunTest runTest) {
- test(group.name, () {
- for (TestSpecBase result in group.results) {
- runTest(result);
- }
- });
-}
\ No newline at end of file
diff --git a/pkg/analyzer2dart/test/tree_shaker_test.dart b/pkg/analyzer2dart/test/tree_shaker_test.dart
deleted file mode 100644
index cedb449..0000000
--- a/pkg/analyzer2dart/test/tree_shaker_test.dart
+++ /dev/null
@@ -1,546 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'mock_sdk.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:compiler/src/dart2jslib.dart' show NullSink;
-import 'package:unittest/unittest.dart';
-
-import '../lib/src/closed_world.dart';
-import '../lib/src/driver.dart';
-
-main() {
- test('Toplevel function', () {
- var helper = new TreeShakerTestHelper('''
-main() {
- foo();
-}
-foo() {
-}
-''');
- helper.assertHasFunction('main');
- helper.assertHasFunction('foo');
- });
-
- test('Toplevel field read', () {
- var helper = new TreeShakerTestHelper('''
-main() {
- return foo;
-}
-var foo;
-var bar;
-''');
- helper.assertHasFunction('main');
- helper.assertHasVariable('foo');
- helper.assertNoVariable('bar');
- });
-
- test('Toplevel field write', () {
- var helper = new TreeShakerTestHelper('''
-main() {
- foo = 1;
-}
-var foo;
-var bar;
-''');
- helper.assertHasFunction('main');
- helper.assertHasVariable('foo');
- helper.assertNoVariable('bar');
- });
-
- test('Toplevel field invocation', () {
- var helper = new TreeShakerTestHelper('''
-main() {
- return foo();
-}
-var foo;
-var bar;
-''');
- helper.assertHasFunction('main');
- helper.assertHasVariable('foo');
- helper.assertNoVariable('bar');
- });
-
- test('Member field invocation', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- void call() {}
- void baz() {}
-}
-main() {
- new A();
- foo();
-}
-var foo;
-var bar;
-''');
- helper.assertHasFunction('main');
- helper.assertHasVariable('foo');
- helper.assertNoVariable('bar');
- helper.assertHasInstantiatedClass('A');
- helper.assertHasMethod('A.call');
- helper.assertNoMethod('A.baz');
- });
-
- test('Class instantiation', () {
- var helper = new TreeShakerTestHelper('''
-main() {
- var x = new A();
-}
-class A {}
-class B {}
-''');
- helper.assertHasInstantiatedClass('A');
- helper.assertNoInstantiatedClass('B');
- });
-
- test('Super class instantiation', () {
- var helper = new TreeShakerTestHelper('''
-main() {
- var x = new B();
-}
-class A {}
-class B extends A {}
-''');
- helper.assertHasInstantiatedClass('A');
- helper.assertHasInstantiatedClass('B');
- });
-
- test('Method invocation', () {
- var helper = new TreeShakerTestHelper('''
-main() {
- var x = new A().foo();
-}
-class A {
- foo() {}
- bar() {}
-}
-class B {
- foo() {}
- bar() {}
-}
-''');
- helper.assertHasMethod('A.foo');
- helper.assertNoMethod('A.bar');
- helper.assertNoMethod('B.foo');
- helper.assertNoMethod('B.bar');
- });
-
- test('Method invocation on dynamic', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- m1() {}
- m2() {}
-}
-foo(dynamic x) {
- x.m1();
-}
-main() {
- foo(new A());
-}
-''');
- helper.assertHasMethod('A.m1');
- helper.assertNoMethod('A.m2');
- });
-
- test('Method invocation on dynamic via cascade', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- m1() {}
- m2() {}
-}
-foo(dynamic x) {
- x..m1()..m2();
-}
-main() {
- foo(new A());
-}
-''');
- helper.assertHasMethod('A.m1');
- helper.assertHasMethod('A.m2');
- });
-
- test('Getter usage', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- get g1 => null;
- get g2 => null;
- set g1(x) {}
- set g2(x) {}
-}
-class B {
- get g1 => null;
- get g2 => null;
- set g1(x) {}
- set g2(x) {}
-}
-main() {
- new A().g1;
-}
-''');
- helper.assertHasGetter('A.g1');
- helper.assertNoGetter('A.g2');
- helper.assertNoGetter('B.g1');
- helper.assertNoGetter('B.g2');
- helper.assertNoSetter('A.g1');
- helper.assertNoSetter('A.g2');
- helper.assertNoSetter('B.g1');
- helper.assertNoSetter('B.g2');
- });
-
- test('Setter usage', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- get g1 => null;
- get g2 => null;
- set g1(x) {}
- set g2(x) {}
-}
-class B {
- get g1 => null;
- get g2 => null;
- set g1(x) {}
- set g2(x) {}
-}
-main() {
- new A().g1 = 1;
-}
-''');
- helper.assertHasSetter('A.g1');
- helper.assertNoSetter('A.g2');
- helper.assertNoSetter('B.g1');
- helper.assertNoSetter('B.g2');
- helper.assertNoGetter('A.g1');
- helper.assertNoGetter('A.g2');
- helper.assertNoGetter('B.g1');
- helper.assertNoGetter('B.g2');
- });
-
- test('Field read', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- var f1;
- var f2;
-}
-class B {
- var f1;
- var f2;
-}
-main() {
- new A().f1;
-}
-''');
- helper.assertHasField('A.f1');
- helper.assertNoField('A.f2');
- helper.assertNoField('B.f1');
- helper.assertNoField('B.f2');
- });
-
- test('Field write', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- var f1;
- var f2;
-}
-class B {
- var f1;
- var f2;
-}
-main() {
- new A().f1 = 1;
-}
-''');
- helper.assertHasField('A.f1');
- helper.assertNoField('A.f2');
- helper.assertNoField('B.f1');
- helper.assertNoField('B.f2');
- });
-
- test('Ordinary constructor with initializer list', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- A() : x = f();
- var x;
- foo() {}
-}
-f() {}
-main() {
- new A().foo();
-}
-''');
- helper.assertHasMethod('A.foo');
- helper.assertHasFunction('f');
- });
-
- test('Redirecting constructor', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- A.a1() : this.a2();
- A.a2();
- foo() {}
-}
-main() {
- new A.a1().foo();
-}
-''');
- helper.assertHasMethod('A.foo');
- });
-
- test('Factory constructor', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- factory A() {
- return new B();
- }
- foo() {}
-}
-class B {
- B();
- foo() {}
-}
-main() {
- new A().foo();
-}
-''');
- helper.assertHasMethod('B.foo');
- helper.assertNoMethod('A.foo');
- });
-
- test('Redirecting factory constructor', () {
- var helper = new TreeShakerTestHelper('''
-class A {
- factory A() = B;
- foo() {}
-}
-class B {
- B();
- foo() {}
-}
-main() {
- new A().foo();
-}
-''');
- helper.assertHasMethod('B.foo');
- helper.assertNoMethod('A.foo');
- });
-}
-
-class TreeShakerTestHelper {
- /**
- * The name of the root file.
- */
- String rootFile = '/root.dart';
-
- /**
- * ClosedWorld that resulted from tree shaking.
- */
- ClosedWorld world;
-
- /**
- * Functions contained in [world], indexed by name.
- */
- Map<String, FunctionDeclaration> functions = <String, FunctionDeclaration>{};
-
- /**
- * Methods contained in [world], indexed by className.methodName.
- */
- Map<String, MethodDeclaration> methods = <String, MethodDeclaration>{};
-
- /**
- * Getters contained in [world], indexed by className.propertyName.
- */
- Map<String, MethodDeclaration> getters = <String, MethodDeclaration>{};
-
- /**
- * Setters contained in [world], indexed by className.propertyName.
- */
- Map<String, MethodDeclaration> setters = <String, MethodDeclaration>{};
-
- /**
- * Fields contained in [world], indexed by className.fieldName.
- */
- Map<String, VariableDeclaration> fields = <String, VariableDeclaration>{};
-
- /**
- * Top level variables contained in [world], indexed by name.
- */
- Map<String, VariableDeclaration> variables = <String, VariableDeclaration>{};
-
- /**
- * Classes instantiated in [world], indexed by name.
- */
- Map<String, ClassDeclaration> instantiatedClasses = <String,
- ClassDeclaration>{};
-
- /**
- * Create a TreeShakerTestHelper based on the given file contents.
- */
- TreeShakerTestHelper(String contents) {
- MemoryResourceProvider provider = new MemoryResourceProvider();
- DartSdk sdk = new MockSdk();
- Driver driver = new Driver(provider, sdk, NullSink.outputProvider);
- provider.newFile(rootFile, contents);
- Source rootSource = driver.setRoot(rootFile);
- FunctionElement entryPoint = driver.resolveEntryPoint(rootSource);
- world = driver.computeWorld(entryPoint);
- world.executableElements.forEach(
- (ExecutableElement element, Declaration node) {
- if (element is FunctionElement) {
- FunctionDeclaration declaration = node as FunctionDeclaration;
- expect(declaration, isNotNull);
- expect(declaration.element, equals(element));
- functions[element.name] = declaration;
- } else if (element is MethodElement) {
- MethodDeclaration declaration = node as MethodDeclaration;
- expect(declaration, isNotNull);
- expect(declaration.element, equals(element));
- methods['${element.enclosingElement.name}.${element.name}'] =
- declaration;
- } else if (element is PropertyAccessorElement) {
- MethodDeclaration declaration = node as MethodDeclaration;
- expect(declaration, isNotNull);
- expect(declaration.element, equals(element));
- if (declaration.isGetter) {
- getters['${element.enclosingElement.name}.${element.name}'] =
- declaration;
- } else if (declaration.isSetter) {
- setters['${element.enclosingElement.name}.${element.displayName}'] =
- declaration;
- } else {
- fail('Unexpected property accessor (neither getter nor setter)');
- }
- }
- });
- world.instantiatedClasses.forEach(
- (ClassElement element, ClassDeclaration declaration) {
- expect(declaration, isNotNull);
- expect(declaration.element, equals(element));
- instantiatedClasses[element.name] = declaration;
- });
- world.fields.forEach(
- (FieldElement element, VariableDeclaration declaration) {
- expect(declaration, isNotNull);
- expect(declaration.element, equals(element));
- fields['${element.enclosingElement.name}.${element.name}'] = declaration;
- });
- world.variables.forEach(
- (TopLevelVariableElement element, VariableDeclaration declaration) {
- expect(declaration, isNotNull);
- expect(declaration.element, equals(element));
- variables['${element.name}'] = declaration;
- });
- }
-
- /**
- * Asserts that [world] contains a field with the given qualified name.
- */
- void assertHasField(String qualifiedName) {
- expect(fields, contains(qualifiedName));
- }
-
- /**
- * Asserts that [world] contains a top level variable with the given name.
- */
- void assertHasVariable(String name) {
- expect(variables, contains(name));
- }
-
- /**
- * Asserts that [world] contains a top-level function with the given name.
- */
- void assertHasFunction(String name) {
- expect(functions, contains(name));
- }
-
- /**
- * Asserts that [world] contains a getter with the given qualified name.
- */
- void assertHasGetter(String qualifiedName) {
- expect(getters, contains(qualifiedName));
- }
-
- /**
- * Asserts that [world] contains a setter with the given qualified name.
- */
- void assertHasSetter(String qualifiedName) {
- expect(setters, contains(qualifiedName));
- }
-
- /**
- * Asserts that [world] instantiates a class with the given name.
- */
- void assertHasInstantiatedClass(String name) {
- expect(instantiatedClasses, contains(name));
- }
-
- /**
- * Asserts that [world] contains a method with the given qualified name.
- *
- * [qualifiedName] - the qualified name in form 'className.methodName'.
- */
- void assertHasMethod(String qualifiedName) {
- expect(methods, contains(qualifiedName));
- }
-
- /**
- * Asserts that [world] doesn't contain a field with the given qualified
- * name.
- */
- void assertNoField(String qualifiedName) {
- expect(fields, isNot(contains(qualifiedName)));
- }
-
- /**
- * Asserts that [world] doesn't contain a top level variable with the given
- * name.
- */
- void assertNoVariable(String name) {
- expect(variables, isNot(contains(name)));
- }
-
- /**
- * Asserts that [world] doesn't contain a top-level function with the given
- * name.
- */
- void assertNoFunction(String name) {
- expect(functions, isNot(contains(name)));
- }
-
- /**
- * Asserts that [world] doesn't contain a getter with the given qualified
- * name.
- */
- void assertNoGetter(String qualifiedName) {
- expect(getters, isNot(contains(qualifiedName)));
- }
-
- /**
- * Asserts that [world] doesn't contain a setter with the given qualified
- * name.
- */
- void assertNoSetter(String qualifiedName) {
- expect(setters, isNot(contains(qualifiedName)));
- }
-
- /**
- * Asserts that [world] doesn't instantiate a class with the given name.
- */
- void assertNoInstantiatedClass(String name) {
- expect(instantiatedClasses, isNot(contains(name)));
- }
-
- /**
- * Asserts that [world] doesn't contain a method with the given qualified
- * name.
- *
- * [qualifiedName] - the qualified name in form 'className.methodName'.
- */
- void assertNoMethod(String qualifiedName) {
- expect(methods, isNot(contains(qualifiedName)));
- }
-}
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 6c4fbcd..12b39df 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -18,6 +18,7 @@
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer_cli/src/driver.dart';
import 'package:analyzer_cli/src/error_formatter.dart';
+import 'package:analyzer_cli/src/incremental_analyzer.dart';
import 'package:analyzer_cli/src/options.dart';
import 'package:path/path.dart' as pathos;
@@ -38,6 +39,8 @@
final AnalysisContext context;
+ final IncrementalAnalysisSession incrementalSession;
+
/// Accumulated analysis statistics.
final AnalysisStats stats;
@@ -60,8 +63,8 @@
/// specified the "--package-warnings" option.
String _selfPackageName;
- AnalyzerImpl(this.context, this.librarySource, this.options, this.stats,
- this.startTime);
+ AnalyzerImpl(this.context, this.incrementalSession, this.librarySource,
+ this.options, this.stats, this.startTime);
/// Returns the maximal [ErrorSeverity] of the recorded errors.
ErrorSeverity get maxErrorSeverity {
@@ -135,6 +138,7 @@
var units = new Set<CompilationUnitElement>();
var libraries = new Set<LibraryElement>();
addLibrarySources(library, libraries, units);
+ incrementalSession?.setAnalyzedSources(sources);
}
/// Setup local fields such as the analysis context for analysis.
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 4d80c61..b776d51 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -37,6 +37,7 @@
import 'package:analyzer_cli/src/analyzer_impl.dart';
import 'package:analyzer_cli/src/build_mode.dart';
import 'package:analyzer_cli/src/error_formatter.dart';
+import 'package:analyzer_cli/src/incremental_analyzer.dart';
import 'package:analyzer_cli/src/options.dart';
import 'package:analyzer_cli/src/perf_report.dart';
import 'package:analyzer_cli/starter.dart';
@@ -86,6 +87,8 @@
/// creation.
CommandLineOptions _previousOptions;
+ IncrementalAnalysisSession incrementalSession;
+
@override
EmbeddedResolverProvider embeddedUriResolverProvider;
@@ -217,6 +220,8 @@
libUris.add(source.uri);
}
+ incrementalSession?.finish();
+
// Check that each part has a corresponding source in the input list.
for (Source part in parts) {
bool found = false;
@@ -297,6 +302,9 @@
if (options.enableSuperMixins != _previousOptions.enableSuperMixins) {
return false;
}
+ if (options.incrementalCachePath != _previousOptions.incrementalCachePath) {
+ return false;
+ }
return true;
}
@@ -510,6 +518,8 @@
_chooseUriResolutionPolicy(options, embedderMap, packageInfo);
_context.sourceFactory = sourceFactory;
+
+ incrementalSession = configureIncrementalAnalysis(options, context);
}
/// Return discovered packagespec, or `null` if none is found.
@@ -618,7 +628,7 @@
ErrorSeverity _runAnalyzer(Source source, CommandLineOptions options) {
int startTime = currentTimeMillis();
AnalyzerImpl analyzer =
- new AnalyzerImpl(_context, source, options, stats, startTime);
+ new AnalyzerImpl(_context, incrementalSession, source, options, stats, startTime);
var errorSeverity = analyzer.analyzeSync();
if (errorSeverity == ErrorSeverity.ERROR) {
exitCode = errorSeverity.ordinal;
diff --git a/pkg/analyzer_cli/lib/src/incremental_analyzer.dart b/pkg/analyzer_cli/lib/src/incremental_analyzer.dart
new file mode 100644
index 0000000..f9d8d4c
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/incremental_analyzer.dart
@@ -0,0 +1,223 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.src.incremental_analyzer;
+
+import 'dart:io' as io;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/incremental_cache.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/general.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:analyzer_cli/src/options.dart';
+
+/**
+ * If the given [options] enables incremental analysis and [context] and Dart
+ * SDK implementations support incremental analysis, configure it for the
+ * given [context] and return the handle to work with it.
+ */
+IncrementalAnalysisSession configureIncrementalAnalysis(
+ CommandLineOptions options, AnalysisContext context) {
+ String cachePath = options.incrementalCachePath;
+ DartSdk sdk = context.sourceFactory.dartSdk;
+ // If supported implementations, configure for incremental analysis.
+ if (cachePath != null &&
+ context is InternalAnalysisContext &&
+ sdk is DirectoryBasedDartSdk) {
+ context.typeProvider = sdk.context.typeProvider;
+ // Set the result provide from the cache.
+ CacheStorage storage = new FolderCacheStorage(
+ PhysicalResourceProvider.INSTANCE.getFolder(cachePath),
+ '${io.pid}.temp');
+ List<int> configSalt = <int>[
+ context.analysisOptions.encodeCrossContextOptions()
+ ];
+ IncrementalCache cache = new IncrementalCache(storage, context, configSalt);
+ context.resultProvider = new _CacheBasedResultProvider(context, cache);
+ // Listen for new libraries to put into the cache.
+ _IncrementalAnalysisSession session =
+ new _IncrementalAnalysisSession(options, context, cache);
+ context
+ .onResultChanged(LIBRARY_ELEMENT1)
+ .listen((ResultChangedEvent event) {
+ if (event.wasComputed) {
+ session.newLibrarySources.add(event.target.source);
+ }
+ });
+ return session;
+ }
+ // Incremental analysis cannot be used.
+ return null;
+}
+
+/**
+ * Interface that is exposed to the clients of incremental analysis.
+ */
+abstract class IncrementalAnalysisSession {
+ /**
+ * Finish tasks required after incremental analysis - save results into the
+ * cache, evict old results, etc.
+ */
+ void finish();
+
+ /**
+ * Sets the set of [Source]s analyzed in the context, both explicit and
+ * implicit, for which errors might be requested. This set is used to compute
+ * containing libraries for every source in the context.
+ */
+ void setAnalyzedSources(Iterable<Source> sources);
+}
+
+/**
+ * The [ResultProvider] that provides results from [IncrementalCache].
+ */
+class _CacheBasedResultProvider extends ResynthesizerResultProvider {
+ final IncrementalCache cache;
+
+ final Set<Source> sourcesWithSummaries = new Set<Source>();
+ final Set<Source> sourcesWithoutSummaries = new Set<Source>();
+ final Set<String> addedLibraryBundleIds = new Set<String>();
+
+ _CacheBasedResultProvider(InternalAnalysisContext context, this.cache)
+ : super(context, new SummaryDataStore(<String>[])) {
+ AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
+ createResynthesizer(sdkContext, sdkContext.typeProvider);
+ }
+
+ @override
+ bool compute(CacheEntry entry, ResultDescriptor result) {
+ AnalysisTarget target = entry.target;
+ // Source based results.
+ if (target is Source) {
+ if (result == SOURCE_KIND) {
+ SourceKind kind = cache.getSourceKind(target);
+ if (kind != null) {
+ entry.setValue(result, kind, TargetedResult.EMPTY_LIST);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ if (result == INCLUDED_PARTS) {
+ List<Source> parts = cache.getLibraryParts(target);
+ if (parts != null) {
+ entry.setValue(result, parts, TargetedResult.EMPTY_LIST);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ if (result == DART_ERRORS) {
+ List<Source> librarySources = context.getLibrariesContaining(target);
+ List<List<AnalysisError>> errorList = <List<AnalysisError>>[];
+ for (Source librarySource in librarySources) {
+ List<AnalysisError> errors =
+ cache.getSourceErrorsInLibrary(librarySource, target);
+ if (errors == null) {
+ return false;
+ }
+ errorList.add(errors);
+ }
+ List<AnalysisError> mergedErrors = AnalysisError.mergeLists(errorList);
+ // Filter the errors.
+ IgnoreInfo ignoreInfo = context.getResult(target, IGNORE_INFO);
+ LineInfo lineInfo = context.getResult(target, LINE_INFO);
+ List<AnalysisError> filteredErrors =
+ DartErrorsTask.filterIgnored(mergedErrors, ignoreInfo, lineInfo);
+ // Set the result.
+ entry.setValue(result, filteredErrors, TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ }
+ return super.compute(entry, result);
+ }
+
+ @override
+ bool hasResultsForSource(Source source) {
+ // Check cache states.
+ if (sourcesWithSummaries.contains(source)) {
+ return true;
+ }
+ if (sourcesWithoutSummaries.contains(source)) {
+ return false;
+ }
+ // Try to load bundles.
+ List<LibraryBundleWithId> bundles = cache.getLibraryClosureBundles(source);
+ if (bundles == null) {
+ sourcesWithoutSummaries.add(source);
+ return false;
+ }
+ // Fill the resynthesizer.
+ sourcesWithSummaries.add(source);
+ for (LibraryBundleWithId bundleWithId in bundles) {
+ if (addedLibraryBundleIds.add(bundleWithId.id)) {
+ addBundle(null, bundleWithId.bundle);
+ }
+ }
+ return true;
+ }
+}
+
+class _IncrementalAnalysisSession implements IncrementalAnalysisSession {
+ final CommandLineOptions commandLineOptions;
+ final AnalysisContext context;
+ final IncrementalCache cache;
+
+ final Set<Source> newLibrarySources = new Set<Source>();
+
+ _IncrementalAnalysisSession(
+ this.commandLineOptions, this.context, this.cache);
+
+ @override
+ void finish() {
+ // Finish computing new libraries and put them into the cache.
+ for (Source librarySource in newLibrarySources) {
+ if (!commandLineOptions.machineFormat) {
+ print('Compute library element for $librarySource');
+ }
+ _putLibrary(librarySource);
+ }
+ }
+
+ @override
+ void setAnalyzedSources(Iterable<Source> sources) {
+ for (Source source in sources) {
+ SourceKind kind = context.computeKindOf(source);
+ if (kind == SourceKind.LIBRARY) {
+ context.computeResult(source, LINE_INFO);
+ context.computeResult(source, IGNORE_INFO);
+ context.computeResult(source, INCLUDED_PARTS);
+ }
+ }
+ }
+
+ void _putLibrary(Source librarySource) {
+ LibraryElement libraryElement =
+ context.computeResult(librarySource, LIBRARY_ELEMENT);
+ try {
+ cache.putLibrary(libraryElement);
+ } catch (e) {
+ return;
+ }
+ // Write errors for the library units.
+ for (CompilationUnitElement unit in libraryElement.units) {
+ Source unitSource = unit.source;
+ List<AnalysisError> errors = context.computeResult(
+ new LibrarySpecificUnit(librarySource, unitSource),
+ LIBRARY_UNIT_ERRORS);
+ cache.putSourceErrorsInLibrary(librarySource, unitSource, errors);
+ }
+ }
+}
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 5a2e939..4cd4c6c 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -112,6 +112,9 @@
/// Whether to use machine format for error display
final bool machineFormat;
+ /// The path to the root folder of the incremental cache.
+ final String incrementalCachePath;
+
/// The path to the package root
final String packageRootPath;
@@ -176,6 +179,7 @@
lints = args['lints'],
log = args['log'],
machineFormat = args['machine'] || args['format'] == 'machine',
+ incrementalCachePath = args['incremental-cache-path'],
packageConfigPath = args['packages'],
packageRootPath = args['package-root'],
perfReport = args['x-perf-report'],
@@ -351,6 +355,13 @@
allowMultiple: true,
splitCommas: false)
//
+ // Incremental analysis.
+ //
+ ..addOption('incremental-cache-path',
+ help: 'The path to the folder with information to support '
+ 'incremental analysis, e.g. summary files, errors, etc.',
+ hide: true)
+ //
// Build mode.
//
..addFlag('persistent_worker',
diff --git a/pkg/compiler/bin/resolver.dart b/pkg/compiler/bin/resolver.dart
new file mode 100644
index 0000000..aa70e4d
--- /dev/null
+++ b/pkg/compiler/bin/resolver.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:compiler/src/apiimpl.dart';
+import 'package:compiler/src/dart2js.dart';
+import 'package:compiler/src/filenames.dart';
+import 'package:compiler/src/null_compiler_output.dart';
+import 'package:compiler/src/source_file_provider.dart';
+import 'package:compiler/src/options.dart';
+import 'package:compiler/src/serialization/json_serializer.dart';
+import 'package:package_config/discovery.dart';
+
+main(var argv) async {
+ var parser = new ArgParser();
+ parser.addOption('deps', abbr: 'd', allowMultiple: true);
+ parser.addOption('out', abbr: 'o');
+ parser.addOption('library-root', abbr: 'l');
+ var args = parser.parse(argv);
+
+ var resolutionInputs = args['deps']
+ .map((uri) => currentDirectory.resolve(nativeToUriPath(uri)))
+ .toList();
+ var root = args['library-root'];
+ var libraryRoot = root == null
+ ? Platform.script.resolve('../../../sdk/')
+ : currentDirectory.resolve(nativeToUriPath(root));
+ var options = new CompilerOptions(
+ libraryRoot: libraryRoot,
+ resolveOnly: true,
+ resolutionInputs: resolutionInputs,
+ packagesDiscoveryProvider: findPackages);
+ var inputProvider = new CompilerSourceFileProvider();
+ var outputProvider = const NullCompilerOutput();
+ var diagnostics = new FormattingDiagnosticHandler(inputProvider);
+
+ var compiler =
+ new CompilerImpl(inputProvider, outputProvider, diagnostics, options);
+
+ var inputs = args.rest
+ .map((uri) => currentDirectory.resolve(nativeToUriPath(uri)))
+ .toList();
+
+ await compiler.setupSdk();
+ await compiler.setupPackages(inputs.first);
+
+ for (var library in inputs) {
+ await compiler.libraryLoader.loadLibrary(library);
+ }
+
+ for (var library in inputs) {
+ compiler.fullyEnqueueLibrary(compiler.libraryLoader.lookupLibrary(library),
+ compiler.enqueuer.resolution);
+ }
+
+ compiler.processQueue(compiler.enqueuer.resolution, null);
+
+ var librariesToSerialize =
+ inputs.map((lib) => compiler.libraryLoader.lookupLibrary(lib)).toList();
+
+ var serializer =
+ compiler.serialization.createSerializer(librariesToSerialize);
+ var text = serializer.toText(const JsonSerializationEncoder());
+
+ var outFile = args['out'] ?? 'out.data';
+
+ await new File(outFile).writeAsString(text);
+}
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 013e997..bf08051 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -65,6 +65,7 @@
// account).
static const String genericMethodSyntax = '--generic-method-syntax';
static const String resolveOnly = '--resolve-only';
+ static const String initializingFormalAccess = '--initializing-formal-access';
}
class Option {
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index 9860b08..8a26860 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -251,4 +251,6 @@
registry = new CodegenRegistry(compiler, element);
return compiler.codegen(this, world);
}
+
+ String toString() => 'CodegenWorkItem(${resolvedAst.element})';
}
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 7380911..97b5b2d 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -257,6 +257,9 @@
/// Computes the [WorldImpact] for [element].
WorldImpact computeWorldImpact(Element element);
+ WorldImpact transformResolutionImpact(
+ Element element, ResolutionImpact resolutionImpact);
+
/// Removes the [WorldImpact] for [element] from the resolution cache. Later
/// calls to [getWorldImpact] or [computeWorldImpact] returns an empty impact.
void uncacheWorldImpact(Element element);
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 9bab3a5..bbabcf9 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -104,6 +104,9 @@
/// Returns the compile-time constant value of [metadata].
ConstantValue getConstantValueForMetadata(MetadataAnnotation metadata);
+
+ /// Register that [element] needs lazy initialization.
+ void registerLazyStatic(FieldElement element);
}
/// Interface for the task that compiles the constant environments for the
@@ -142,6 +145,8 @@
*
* Invariant: The keys in this map are declarations.
*/
+ // TODO(johnniwinther): Make this purely internal when no longer used by
+ // poi/forget_element_test.
final Map<VariableElement, ConstantExpression> initialVariableValues =
new Map<VariableElement, ConstantExpression>();
@@ -922,10 +927,7 @@
assert(normalizedArguments != null);
concreteArguments = normalizedArguments;
}
-
- if (constructor == compiler.intEnvironment ||
- constructor == compiler.boolEnvironment ||
- constructor == compiler.stringEnvironment) {
+ if (constructor.isFromEnvironmentConstructor) {
return createFromEnvironmentConstant(node, constructedType, constructor,
callStructure, normalizedArguments, concreteArguments);
} else {
@@ -969,7 +971,7 @@
return null;
}
- if (constructor == compiler.intEnvironment &&
+ if (constructor.isIntFromEnvironmentConstructor &&
!(defaultValue.isNull || defaultValue.isInt)) {
DartType type = defaultValue.getType(coreTypes);
reporter.reportErrorMessage(
@@ -979,7 +981,7 @@
return null;
}
- if (constructor == compiler.boolEnvironment &&
+ if (constructor.isBoolFromEnvironmentConstructor &&
!(defaultValue.isNull || defaultValue.isBool)) {
DartType type = defaultValue.getType(coreTypes);
reporter.reportErrorMessage(
@@ -989,7 +991,7 @@
return null;
}
- if (constructor == compiler.stringEnvironment &&
+ if (constructor.isStringFromEnvironmentConstructor &&
!(defaultValue.isNull || defaultValue.isString)) {
DartType type = defaultValue.getType(coreTypes);
reporter.reportErrorMessage(
@@ -1009,13 +1011,13 @@
if (concreteArguments.length > 1) {
defaultValue = concreteArguments[1].expression;
}
- if (constructor == compiler.intEnvironment) {
+ if (constructor.isIntFromEnvironmentConstructor) {
expression =
new IntFromEnvironmentConstantExpression(name, defaultValue);
- } else if (constructor == compiler.boolEnvironment) {
+ } else if (constructor.isBoolFromEnvironmentConstructor) {
expression =
new BoolFromEnvironmentConstantExpression(name, defaultValue);
- } else if (constructor == compiler.stringEnvironment) {
+ } else if (constructor.isStringFromEnvironmentConstructor) {
expression =
new StringFromEnvironmentConstantExpression(name, defaultValue);
}
@@ -1025,11 +1027,11 @@
if (value == null) {
return createEvaluatedConstant(defaultValue);
- } else if (constructor == compiler.intEnvironment) {
+ } else if (constructor.isIntFromEnvironmentConstructor) {
int number = int.parse(value, onError: (_) => null);
return createEvaluatedConstant(
(number == null) ? defaultValue : constantSystem.createInt(number));
- } else if (constructor == compiler.boolEnvironment) {
+ } else if (constructor.isBoolFromEnvironmentConstructor) {
if (value == 'true') {
return createEvaluatedConstant(constantSystem.createBool(true));
} else if (value == 'false') {
@@ -1038,7 +1040,7 @@
return createEvaluatedConstant(defaultValue);
}
} else {
- assert(constructor == compiler.stringEnvironment);
+ assert(constructor.isStringFromEnvironmentConstructor);
return createEvaluatedConstant(
constantSystem.createString(new DartString.literal(value)));
}
@@ -1182,6 +1184,9 @@
if (parameter.isInitializingFormal) {
InitializingFormalElement initializingFormal = parameter;
updateFieldValue(node, initializingFormal.fieldElement, argument);
+ if (compiler.options.enableInitializingFormalAccess) {
+ definitions[parameter] = argument;
+ }
} else {
potentiallyCheckType(parameter, argument);
definitions[parameter] = argument;
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 7f7a37f..234c7e1 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -209,15 +209,6 @@
Element loadLibraryFunction;
Element functionApplyMethod;
- /// The [int.fromEnvironment] constructor.
- ConstructorElement intEnvironment;
-
- /// The [bool.fromEnvironment] constructor.
- ConstructorElement boolEnvironment;
-
- /// The [String.fromEnvironment] constructor.
- ConstructorElement stringEnvironment;
-
// TODO(zarah): Remove this map and incorporate compile-time errors
// in the model.
/// Tracks elements with compile-time errors.
@@ -623,12 +614,6 @@
mirrorSystemGetNameFunction = cls.lookupLocalMember('getName');
} else if (mirrorsUsedClass == cls) {
mirrorsUsedConstructor = cls.constructors.head;
- } else if (coreClasses.intClass == cls) {
- intEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment);
- } else if (coreClasses.stringClass == cls) {
- stringEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment);
- } else if (coreClasses.boolClass == cls) {
- boolEnvironment = cls.lookupConstructor(Identifiers.fromEnvironment);
}
}
@@ -2022,13 +2007,20 @@
// Only analyze nodes with a corresponding [TreeElements].
compiler.checker.check(element);
}
- WorldImpact worldImpact = compiler.backend.impactTransformer
- .transformResolutionImpact(resolutionImpact);
- return worldImpact;
+ return transformResolutionImpact(element, resolutionImpact);
});
}
@override
+ WorldImpact transformResolutionImpact(
+ Element element, ResolutionImpact resolutionImpact) {
+ WorldImpact worldImpact = compiler.backend.impactTransformer
+ .transformResolutionImpact(resolutionImpact);
+ _worldImpactCache[element] = worldImpact;
+ return worldImpact;
+ }
+
+ @override
void uncacheWorldImpact(Element element) {
assert(invariant(element, element.isDeclaration,
message: "Element $element must be the declaration."));
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 3b4317f..2deb866 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -549,7 +549,7 @@
@override
void _createStructuredText(StringBuffer sb) {
- sb.write('Constructored(type=$type,constructor=$target,'
+ sb.write('Constructed(type=$type,constructor=$target,'
'callStructure=$callStructure,arguments=[');
String delimiter = '';
for (ConstantExpression value in arguments) {
@@ -561,6 +561,8 @@
}
Map<FieldElement, ConstantExpression> computeInstanceFields() {
+ assert(invariant(target, target.constantConstructor != null,
+ message: "No constant constructor computed for $target."));
return target.constantConstructor
.computeInstanceFields(arguments, callStructure);
}
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 64bb70a..7d19ec0 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -338,6 +338,7 @@
new OptionHandler(Flags.allowMockCompilation, passThrough),
new OptionHandler(Flags.fastStartup, passThrough),
new OptionHandler(Flags.genericMethodSyntax, passThrough),
+ new OptionHandler(Flags.initializingFormalAccess, passThrough),
new OptionHandler('${Flags.minify}|-m', implyCompilation),
new OptionHandler(Flags.preserveUris, passThrough),
new OptionHandler('--force-strip=.*', setStrip),
diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart
index 9a1162e..371eed6 100644
--- a/pkg/compiler/lib/src/dart_backend/backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend.dart
@@ -540,4 +540,9 @@
constantCompiler.constantValueMap
.addAll(task.constantCompiler.constantValueMap);
}
+
+ @override
+ void registerLazyStatic(FieldElement element) {
+ // Do nothing.
+ }
}
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 18e85ad..0f4f8d7 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -349,6 +349,13 @@
// See dartbug.com/26406 for context.
treeElements
.forEachConstantNode((Node node, ConstantExpression expression) {
+ if (compiler.serialization.isDeserialized(analyzableElement)) {
+ if (!expression.isImplicit && !expression.isPotential) {
+ // Enforce evaluation of [expression].
+ backend.constants.getConstantValue(expression);
+ }
+ }
+
// Explicitly depend on the backend constants.
if (backend.constants.hasConstantValue(expression)) {
ConstantValue value =
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index ad689fd..8ddc535 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -665,6 +665,7 @@
MessageKind.DUPLICATE_DEFINITION: const MessageTemplate(
MessageKind.DUPLICATE_DEFINITION,
"Duplicate definition of '#{name}'.",
+ options: const ["--initializing-formal-access"],
howToFix: "Try to rename or remove this definition.",
examples: const [
"""
@@ -676,7 +677,16 @@
main() {
new C();
}
+""",
+ """
+class C {
+ int x;
+ C(this.x, int x);
+}
+main() {
+ new C(4, 2);
+}
"""
]),
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
index 6c9a013..0020393 100644
--- a/pkg/compiler/lib/src/elements/common.dart
+++ b/pkg/compiler/lib/src/elements/common.dart
@@ -6,7 +6,7 @@
library elements.common;
-import '../common/names.dart' show Names, Uris;
+import '../common/names.dart' show Identifiers, Names, Uris;
import '../core_types.dart' show CoreClasses;
import '../dart_types.dart' show DartType, InterfaceType, FunctionType;
import '../util/util.dart' show Link;
@@ -594,3 +594,48 @@
});
}
}
+
+abstract class AbstractFieldElementCommon implements AbstractFieldElement {
+ @override
+ bool get isInstanceMember {
+ return isClassMember && !isStatic;
+ }
+
+ @override
+ bool get isAbstract {
+ return getter != null && getter.isAbstract ||
+ setter != null && setter.isAbstract;
+ }
+}
+
+abstract class ConstructorElementCommon implements ConstructorElement {
+ @override
+ bool get isFromEnvironmentConstructor {
+ return name == Identifiers.fromEnvironment &&
+ library.isDartCore &&
+ (enclosingClass.name == 'bool' ||
+ enclosingClass.name == 'int' ||
+ enclosingClass.name == 'String');
+ }
+
+ @override
+ bool get isIntFromEnvironmentConstructor {
+ return name == Identifiers.fromEnvironment &&
+ library.isDartCore &&
+ enclosingClass.name == 'int';
+ }
+
+ @override
+ bool get isBoolFromEnvironmentConstructor {
+ return name == Identifiers.fromEnvironment &&
+ library.isDartCore &&
+ enclosingClass.name == 'bool';
+ }
+
+ @override
+ bool get isStringFromEnvironmentConstructor {
+ return name == Identifiers.fromEnvironment &&
+ library.isDartCore &&
+ enclosingClass.name == 'String';
+ }
+}
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index dc708d0..e5338de 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -1067,7 +1067,7 @@
///
/// Normal parameter that introduce a local variable are modeled by
/// [LocalParameterElement] whereas initializing formals, that is parameter of
-/// the form `this.x`, are modeled by [InitializingFormalParameter].
+/// the form `this.x`, are modeled by [InitializingFormalElement].
abstract class ParameterElement extends Element
implements VariableElement, FormalElement, LocalElement {
/// Use [functionDeclaration] instead.
@@ -1092,7 +1092,7 @@
/// A formal parameter in a constructor that directly initializes a field.
///
/// For example: `A(this.field)`.
-abstract class InitializingFormalElement extends ParameterElement {
+abstract class InitializingFormalElement extends LocalParameterElement {
/// The field initialized by this initializing formal.
FieldElement get fieldElement;
@@ -1324,6 +1324,15 @@
/// `int.fromEnvironment`, or `String.fromEnvironment`.
bool get isFromEnvironmentConstructor;
+ /// `true` if this constructor is `int.fromEnvironment`.
+ bool get isIntFromEnvironmentConstructor;
+
+ /// `true` if this constructor is `bool.fromEnvironment`.
+ bool get isBoolFromEnvironmentConstructor;
+
+ /// `true` if this constructor is `String.fromEnvironment`.
+ bool get isStringFromEnvironmentConstructor;
+
/// Use [enclosingClass] instead.
@deprecated
get enclosingElement;
@@ -1490,6 +1499,8 @@
Element lookupSuperMemberInLibrary(String memberName, LibraryElement library);
+ // TODO(johnniwinther): Clean up semantics. Can the default constructor take
+ // optional arguments? Must it be resolved?
ConstructorElement lookupDefaultConstructor();
ConstructorElement lookupConstructor(String name);
@@ -1526,6 +1537,10 @@
abstract class MixinApplicationElement extends ClassElement {
ClassElement get mixin;
InterfaceType get mixinType;
+
+ /// If this is an unnamed mixin application [subclass] is the subclass for
+ /// which this mixin application is created.
+ ClassElement get subclass;
}
/// Enum declaration.
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 2381d64..e1fd271 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -206,7 +206,9 @@
}
}
-class ErroneousElementX extends ElementX implements ErroneousElement {
+class ErroneousElementX extends ElementX
+ with ConstructorElementCommon
+ implements ErroneousElement {
final MessageKind messageKind;
final Map messageArguments;
@@ -284,9 +286,6 @@
}
@override
- bool get isFromEnvironmentConstructor => false;
-
- @override
List<DartType> get typeVariables => unsupported();
}
@@ -1820,7 +1819,11 @@
MemberElement get memberContext => enclosingElement;
- bool get isLocal => false;
+ @override
+ bool get isFinal => true;
+
+ @override
+ bool get isLocal => true;
}
class ErroneousInitializingFormalElementX extends ParameterElementX
@@ -1845,7 +1848,9 @@
DynamicType get type => const DynamicType();
}
-class AbstractFieldElementX extends ElementX implements AbstractFieldElement {
+class AbstractFieldElementX extends ElementX
+ with AbstractFieldElementCommon
+ implements AbstractFieldElement {
GetterElementX getter;
SetterElementX setter;
@@ -1888,18 +1893,9 @@
}
}
- bool get isInstanceMember {
- return isClassMember && !isStatic;
- }
-
accept(ElementVisitor visitor, arg) {
return visitor.visitAbstractFieldElement(this, arg);
}
-
- bool get isAbstract {
- return getter != null && getter.isAbstract ||
- setter != null && setter.isAbstract;
- }
}
// TODO(johnniwinther): [FunctionSignature] should be merged with
@@ -2170,21 +2166,13 @@
}
}
- bool get isFromEnvironmentConstructor {
- return name == 'fromEnvironment' &&
- library.isDartCore &&
- (enclosingClass.name == 'bool' ||
- 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
- with ConstantConstructorMixin
+ with ConstantConstructorMixin, ConstructorElementCommon
implements ConstructorElement {
bool isRedirectingGenerative = false;
@@ -2995,7 +2983,6 @@
ClassElement get mixin => mixinType != null ? mixinType.element : null;
bool get isMixinApplication => true;
- bool get isUnnamedMixinApplication => node is! NamedMixinApplication;
bool get hasConstructor => !constructors.isEmpty;
bool get hasLocalScopeMembers => !constructors.isEmpty;
@@ -3053,14 +3040,20 @@
Modifiers get modifiers => node.modifiers;
DeclarationSite get declarationSite => this;
+
+ ClassElement get subclass => null;
}
class UnnamedMixinApplicationElementX extends MixinApplicationElementX {
final Node node;
+ final ClassElement subclass;
UnnamedMixinApplicationElementX(
- String name, CompilationUnitElement enclosing, int id, this.node)
- : super(name, enclosing, id);
+ String name, ClassElement subclass, int id, this.node)
+ : this.subclass = subclass,
+ super(name, subclass.compilationUnit, id);
+
+ bool get isUnnamedMixinApplication => true;
bool get isAbstract => true;
}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 2bc3670..ea9e893 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -494,15 +494,18 @@
}
Compiler compiler = inferrer.compiler;
- if (element.declaration == compiler.intEnvironment) {
- giveUp(inferrer);
- return compiler.typesTask.intType.nullable();
- } else if (element.declaration == compiler.boolEnvironment) {
- giveUp(inferrer);
- return compiler.typesTask.boolType.nullable();
- } else if (element.declaration == compiler.stringEnvironment) {
- giveUp(inferrer);
- return compiler.typesTask.stringType.nullable();
+ if (element.isConstructor) {
+ ConstructorElement constructor = element;
+ if (constructor.isIntFromEnvironmentConstructor) {
+ giveUp(inferrer);
+ return compiler.typesTask.intType.nullable();
+ } else if (constructor.isBoolFromEnvironmentConstructor) {
+ giveUp(inferrer);
+ return compiler.typesTask.boolType.nullable();
+ } else if (constructor.isStringFromEnvironmentConstructor) {
+ giveUp(inferrer);
+ return compiler.typesTask.stringType.nullable();
+ }
}
return null;
}
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 da3efb5..6077e6d 100644
--- a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
@@ -132,28 +132,18 @@
element, definitions,
isConst: isConst, checkType: checkType);
if (!isConst && value == null) {
- lazyStatics.add(element);
+ registerLazyStatic(element);
}
return value;
}
- void addCompileTimeConstantForEmission(ConstantValue constant) {
- compiledConstants.add(constant);
+ @override
+ void registerLazyStatic(FieldElement element) {
+ lazyStatics.add(element);
}
- /**
- * Returns an [Iterable] of static non final fields that need to be
- * initialized. The fields list must be evaluated in order since they might
- * depend on each other.
- */
- Iterable<VariableElement> getStaticNonFinalFieldsForEmission() {
- return initialVariableValues.keys.where((element) {
- return element.kind == ElementKind.FIELD &&
- !element.isInstanceMember &&
- !element.modifiers.isFinal &&
- // The const fields are all either emitted elsewhere or inlined.
- !element.modifiers.isConst;
- });
+ void addCompileTimeConstantForEmission(ConstantValue constant) {
+ compiledConstants.add(constant);
}
List<VariableElement> getLazilyInitializedFieldsForEmission() {
@@ -189,15 +179,6 @@
return result;
}
- ConstantValue getInitialValueFor(VariableElement element) {
- ConstantExpression initialValue =
- initialVariableValues[element.declaration];
- if (initialValue == null) {
- reporter.internalError(element, "No initial value for given element.");
- }
- return getConstantValue(initialValue);
- }
-
ConstantExpression compileNode(Node node, TreeElements elements,
{bool enforceConst: true}) {
return compileNodeWithDefinitions(node, elements, isConst: enforceConst);
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 f3d2b4c..410d1c8 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -349,11 +349,12 @@
@override
ConstantValue createSymbol(Compiler compiler, String text) {
// TODO(johnniwinther): Create a backend agnostic value.
- InterfaceType type = compiler.coreTypes.symbolType;
+ JavaScriptBackend backend = compiler.backend;
+ ClassElement symbolClass = backend.helpers.symbolImplementationClass;
+ InterfaceType type = symbolClass.rawType;
ConstantValue argument = createString(new DartString.literal(text));
Map<FieldElement, ConstantValue> fields = <FieldElement, ConstantValue>{};
- JavaScriptBackend backend = compiler.backend;
- backend.helpers.symbolImplementationClass.forEachInstanceField(
+ symbolClass.forEachInstanceField(
(ClassElement enclosingClass, FieldElement field) {
fields[field] = argument;
});
diff --git a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
index b3b4354..faf8539 100644
--- a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
+++ b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
@@ -9,7 +9,7 @@
*/
class TypeVariableHandler {
final Compiler _compiler;
- FunctionElement _typeVariableConstructor;
+ ConstructorElement _typeVariableConstructor;
/**
* Set to 'true' on first encounter of a class with type variables.
@@ -77,43 +77,23 @@
for (TypeVariableType currentTypeVariable in cls.typeVariables) {
TypeVariableElement typeVariableElement = currentTypeVariable.element;
- AstConstant name = new AstConstant(
- typeVariableElement,
- typeVariableElement.node,
- new StringConstantExpression(currentTypeVariable.name),
- _backend.constantSystem
- .createString(new DartString.literal(currentTypeVariable.name)));
jsAst.Expression boundIndex =
_metadataCollector.reifyType(typeVariableElement.bound);
ConstantValue boundValue = new SyntheticConstantValue(
SyntheticConstantKind.TYPEVARIABLE_REFERENCE, boundIndex);
ConstantExpression boundExpression =
new SyntheticConstantExpression(boundValue);
- AstConstant bound = new AstConstant(typeVariableElement,
- typeVariableElement.node, boundExpression, boundValue);
- AstConstant type = new AstConstant(
- typeVariableElement,
- typeVariableElement.node,
- new TypeConstantExpression(cls.rawType),
- _backend.constantSystem.createType(_backend.compiler, cls.rawType));
- List<AstConstant> arguments = [type, name, bound];
+ ConstantExpression constant = new ConstructedConstantExpression(
+ _typeVariableConstructor.enclosingClass.thisType,
+ _typeVariableConstructor,
+ const CallStructure.unnamed(3), [
+ new TypeConstantExpression(cls.rawType),
+ new StringConstantExpression(currentTypeVariable.name),
+ new SyntheticConstantExpression(boundValue)
+ ]);
- // TODO(johnniwinther): Support a less front-end specific creation of
- // constructed constants.
- AstConstant constant =
- CompileTimeConstantEvaluator.makeConstructedConstant(
- _compiler,
- _backend.constants,
- typeVariableElement,
- typeVariableElement.node,
- typeVariableType,
- _typeVariableConstructor,
- typeVariableType,
- _typeVariableConstructor,
- const CallStructure.unnamed(3),
- arguments,
- arguments);
- ConstantValue value = constant.value;
+ _backend.constants.evaluate(constant);
+ ConstantValue value = _backend.constants.getConstantValue(constant);
_backend.registerCompileTimeConstant(value, _compiler.globalDependencies);
_backend.addCompileTimeConstantForEmission(value);
_backend.constants.addCompileTimeConstantForEmission(value);
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index 0e02c6c..5bd1cb1 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -614,9 +614,9 @@
// If the outputUnit does not contain any static non-final fields, then
// [fields] is `null`.
if (fields != null) {
- for (Element element in fields) {
+ for (FieldElement element in fields) {
reporter.withCurrentElement(element, () {
- ConstantValue constant = handler.getInitialValueFor(element);
+ ConstantValue constant = handler.getConstantValue(element.constant);
parts.add(buildInitialization(element, constantReference(constant)));
});
}
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index 6c76418..a32f462 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -282,18 +282,21 @@
list.add(element);
}
- Iterable<VariableElement> staticNonFinalFields = handler
- .getStaticNonFinalFieldsForEmission()
- .where(compiler.codegenWorld.allReferencedStaticFields.contains);
+ Iterable<Element> fields = compiler.codegenWorld.allReferencedStaticFields
+ .where((FieldElement field) {
+ if (!field.isConst) {
+ return field.isField &&
+ !field.isInstanceMember &&
+ !field.isFinal &&
+ field.constant != null;
+ } else {
+ // We also need to emit static const fields if they are available for
+ // reflection.
+ return backend.isAccessibleByReflection(field);
+ }
+ });
- Elements.sortedByPosition(staticNonFinalFields).forEach(addToOutputUnit);
-
- // We also need to emit static const fields if they are available for
- // reflection.
- compiler.codegenWorld.allReferencedStaticFields
- .where((FieldElement field) => field.isConst)
- .where(backend.isAccessibleByReflection)
- .forEach(addToOutputUnit);
+ Elements.sortedByPosition(fields).forEach(addToOutputUnit);
}
void computeNeededLibraries() {
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index b779ef7..1f81f6d 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -260,9 +260,9 @@
return staticNonFinalFields.map(_buildStaticField).toList(growable: false);
}
- StaticField _buildStaticField(Element element) {
+ StaticField _buildStaticField(FieldElement element) {
JavaScriptConstantCompiler handler = backend.constants;
- ConstantValue initialValue = handler.getInitialValueFor(element);
+ ConstantValue initialValue = handler.getConstantValue(element.constant);
// TODO(zarah): The holder should not be registered during building of
// a static field.
_registry.registerHolder(namer.globalObjectForConstant(initialValue),
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 3a2e2a3..9da31d6 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -131,7 +131,7 @@
* point to the 'packages' folder.
*
*/
-abstract class LibraryLoaderTask implements CompilerTask {
+abstract class LibraryLoaderTask implements LibraryProvider, CompilerTask {
factory LibraryLoaderTask(
ResolvedUriTranslator uriTranslator,
ScriptLoader scriptLoader,
@@ -145,9 +145,6 @@
/// Returns all libraries that have been loaded.
Iterable<LibraryElement> get libraries;
- /// Looks up the library with the [canonicalUri].
- LibraryElement lookupLibrary(Uri canonicalUri);
-
/// Loads the library specified by the [resolvedUri] and returns its
/// [LibraryElement].
///
@@ -176,6 +173,14 @@
Future<Null> resetLibraries(ReuseLibrariesFunction reuseLibraries);
}
+/// Interface for an entity that provide libraries. For instance from normal
+/// library loading or from deserialization.
+// TODO(johnniwinther): Use this to integrate deserialized libraries better.
+abstract class LibraryProvider {
+ /// Looks up the library with the [canonicalUri].
+ LibraryElement lookupLibrary(Uri canonicalUri);
+}
+
/// Handle for creating synthesized/patch libraries during library loading.
abstract class LibraryLoader {
/// This method must be called when a new synthesized/patch library has been
@@ -299,9 +304,15 @@
final DiagnosticReporter reporter;
- _LibraryLoaderTask(this.uriTranslator, this.scriptLoader,
- this.scanner, this.deserializer, this.listener, this.environment,
- this.reporter, Measurer measurer)
+ _LibraryLoaderTask(
+ this.uriTranslator,
+ this.scriptLoader,
+ this.scanner,
+ this.deserializer,
+ this.listener,
+ this.environment,
+ this.reporter,
+ Measurer measurer)
: super(measurer);
String get name => 'LibraryLoader';
@@ -1384,8 +1395,6 @@
suffixChainMap[library] = const <Link<Uri>>[];
List<Link<Uri>> suffixes = [];
if (targetUri != canonicalUri) {
- LibraryDependencyNode node = nodeMap[library];
-
/// Process the import (or export) of [importedLibrary].
void processLibrary(LibraryElement importedLibrary) {
bool suffixesArePrecomputed =
@@ -1416,12 +1425,12 @@
}
}
- for (ImportLink import in node.imports.reverse()) {
+ for (ImportElement import in library.imports) {
processLibrary(import.importedLibrary);
if (aborted) return;
}
- for (LibraryElement exportedLibrary in node.exports.reverse()) {
- processLibrary(exportedLibrary);
+ for (ExportElement export in library.exports) {
+ processLibrary(export.exportedLibrary);
if (aborted) return;
}
} else {
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index e15f185..f38ccc4 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -520,12 +520,23 @@
.isSubtype(type, backend.listImplementation.rawType)) {
backend.registerInstantiatedType(type, world, registry);
}
+ // TODO(johnniwinther): Improve spec string precision to handle type
+ // arguments and implements relations that preserve generics. Currently
+ // we cannot distinguish between `List`, `List<dynamic>`, and
+ // `List<int>` and take all to mean `List<E>`; in effect not including
+ // any native subclasses of generic classes.
+ // TODO(johnniwinther,sra): Find and replace uses of `List` with the
+ // actual implementation classes such as `JSArray` et al.
+ enqueueUnusedClassesMatching((ClassElement nativeClass) {
+ InterfaceType nativeType = nativeClass.thisType;
+ InterfaceType specType = type.element.thisType;
+ return compiler.types.isSubtype(nativeType, specType);
+ }, cause, 'subtypeof($type)');
+ } else if (type.isDynamic) {
+ enqueueUnusedClassesMatching((_) => true, cause, 'subtypeof($type)');
+ } else {
+ assert(type is VoidType);
}
- assert(type is DartType);
- enqueueUnusedClassesMatching(
- (nativeClass) => compiler.types.isSubtype(nativeClass.thisType, type),
- cause,
- 'subtypeof($type)');
}
// Give an info so that library developers can compile with -v to find why
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index e839a17..2d235c1 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -149,6 +149,10 @@
/// methods where type arguments are passed.
final bool enableGenericMethodSyntax;
+ /// Support access to initializing formal constructor arguments, e.g., the
+ /// use of `x` to initialize `y` in `C(this.x) : y = x`.
+ final bool enableInitializingFormalAccess;
+
/// Whether the user specified a flag to allow the use of dart:mirrors. This
/// silences a warning produced by the compiler.
final bool enableExperimentalMirrors;
@@ -292,6 +296,8 @@
enableAssertMessage: _hasOption(options, Flags.enableAssertMessage),
enableGenericMethodSyntax:
_hasOption(options, Flags.genericMethodSyntax),
+ enableInitializingFormalAccess:
+ _hasOption(options, Flags.initializingFormalAccess),
enableExperimentalMirrors:
_hasOption(options, Flags.enableExperimentalMirrors),
enableMinification: _hasOption(options, Flags.minify),
@@ -361,6 +367,7 @@
bool emitJavaScript: true,
bool enableAssertMessage: false,
bool enableGenericMethodSyntax: false,
+ bool enableInitializingFormalAccess: false,
bool enableExperimentalMirrors: false,
bool enableMinification: false,
bool enableNativeLiveTypeAnalysis: true,
@@ -434,6 +441,7 @@
emitJavaScript: emitJavaScript,
enableAssertMessage: enableAssertMessage,
enableGenericMethodSyntax: enableGenericMethodSyntax,
+ enableInitializingFormalAccess: enableInitializingFormalAccess,
enableExperimentalMirrors: enableExperimentalMirrors,
enableMinification: enableMinification,
enableNativeLiveTypeAnalysis: enableNativeLiveTypeAnalysis,
@@ -487,6 +495,7 @@
this.emitJavaScript: true,
this.enableAssertMessage: false,
this.enableGenericMethodSyntax: false,
+ this.enableInitializingFormalAccess: false,
this.enableExperimentalMirrors: false,
this.enableMinification: false,
this.enableNativeLiveTypeAnalysis: false,
diff --git a/pkg/compiler/lib/src/parser/partial_parser.dart b/pkg/compiler/lib/src/parser/partial_parser.dart
index 67f320d..514a058 100644
--- a/pkg/compiler/lib/src/parser/partial_parser.dart
+++ b/pkg/compiler/lib/src/parser/partial_parser.dart
@@ -49,7 +49,8 @@
}
if (identical(value, '=') ||
identical(value, '?') ||
- identical(value, ':')) {
+ identical(value, ':') ||
+ identical(value, '??')) {
var nextValue = token.next.stringValue;
if (identical(nextValue, 'const')) {
token = token.next;
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
index e136a14..87c00a8 100644
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -303,11 +303,8 @@
String superName = supertype.name;
String mixinName = mixinType.name;
MixinApplicationElementX mixinApplication =
- new UnnamedMixinApplicationElementX(
- "${superName}+${mixinName}",
- element.compilationUnit,
- compiler.idGenerator.getNextFreeId(),
- node);
+ new UnnamedMixinApplicationElementX("${superName}+${mixinName}",
+ element, compiler.idGenerator.getNextFreeId(), node);
// Create synthetic type variables for the mixin application.
List<DartType> typeVariables = <DartType>[];
int index = 0;
diff --git a/pkg/compiler/lib/src/resolution/class_members.dart b/pkg/compiler/lib/src/resolution/class_members.dart
index 6cbbf70..7c28777 100644
--- a/pkg/compiler/lib/src/resolution/class_members.dart
+++ b/pkg/compiler/lib/src/resolution/class_members.dart
@@ -824,8 +824,30 @@
/// includes `call`.
Iterable<String> computedMemberNames;
+ bool _interfaceMembersAreClassMembers;
+
+ /// Compute value of the [_interfaceMembersAreClassMembers] for this class
+ /// and its superclasses.
+ void _computeInterfaceMembersAreClassMembers(Resolution resolution) {
+ if (_interfaceMembersAreClassMembers == null) {
+ ensureResolved(resolution);
+ ClassMemberMixin superclass = this.superclass;
+ if (superclass != null) {
+ superclass._computeInterfaceMembersAreClassMembers(resolution);
+ }
+ if ((superclass != null &&
+ (!superclass.interfaceMembersAreClassMembers ||
+ superclass.isMixinApplication)) ||
+ !interfaces.isEmpty) {
+ _interfaceMembersAreClassMembers = false;
+ } else {
+ _interfaceMembersAreClassMembers = true;
+ }
+ }
+ }
+
/// If `true` interface members are the non-static class member.
- bool interfaceMembersAreClassMembers = true;
+ bool get interfaceMembersAreClassMembers => _interfaceMembersAreClassMembers;
Map<Name, Member> classMembers;
Map<Name, MemberSignature> interfaceMembers;
@@ -834,18 +856,8 @@
/// this class.
MembersCreator _prepareCreator(Resolution resolution) {
if (classMembers == null) {
- ensureResolved(resolution);
+ _computeInterfaceMembersAreClassMembers(resolution);
classMembers = new Map<Name, Member>();
-
- if (interfaceMembersAreClassMembers) {
- ClassMemberMixin superclass = this.superclass;
- if ((superclass != null &&
- (!superclass.interfaceMembersAreClassMembers ||
- superclass.isMixinApplication)) ||
- !interfaces.isEmpty) {
- interfaceMembersAreClassMembers = false;
- }
- }
if (!interfaceMembersAreClassMembers) {
interfaceMembers = new Map<Name, MemberSignature>();
}
@@ -864,6 +876,9 @@
/// and private names.
void computeClassMember(
Resolution resolution, String name, Setlet<Name> names) {
+ // TODO(johnniwinther): Should we assert that the class has been resolved
+ // instead?
+ ensureResolved(resolution);
if (isMemberComputed(name)) return;
if (Name.isPrivateName(name)) {
names
@@ -887,6 +902,9 @@
}
void computeAllClassMembers(Resolution resolution) {
+ // TODO(johnniwinther): Should we assert that the class has been resolved
+ // instead?
+ ensureResolved(resolution);
if (areAllMembersComputed()) return;
MembersCreator creator = _prepareCreator(resolution);
creator.computeAllMembers();
diff --git a/pkg/compiler/lib/src/resolution/member_impl.dart b/pkg/compiler/lib/src/resolution/member_impl.dart
index 7597d36..8c4eb1c 100644
--- a/pkg/compiler/lib/src/resolution/member_impl.dart
+++ b/pkg/compiler/lib/src/resolution/member_impl.dart
@@ -138,13 +138,17 @@
}
DeclaredMember inheritFrom(InterfaceType newInstance) {
- assert(() {
+ assert(invariant(declaration.element, () {
// Assert that if [instance] contains type variables, then these are
// defined in the declaration of [newInstance] and will therefore be
// substituted into the context of [newInstance] in the created member.
ClassElement contextClass = Types.getClassContext(instance);
return contextClass == null || contextClass == newInstance.element;
- });
+ }, message: () {
+ return "Context mismatch: Context class "
+ "${Types.getClassContext(instance)} from $instance does match "
+ "the new instance $newInstance.";
+ }));
return _newInheritedMember(newInstance);
}
@@ -169,7 +173,7 @@
String toString() {
StringBuffer sb = new StringBuffer();
- printOn(sb, instance);
+ printOn(sb, type);
return sb.toString();
}
}
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index b69287a..3658a7d 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -17,10 +17,10 @@
import '../elements/elements.dart';
import '../elements/modelx.dart'
show
- BaseFunctionElementX,
ConstructorElementX,
ErroneousElementX,
FunctionElementX,
+ InitializingFormalElementX,
JumpTargetX,
LocalFunctionElementX,
LocalParameterElementX,
@@ -444,6 +444,11 @@
// fields they reference are visible, but must be resolved independently.
if (element.isInitializingFormal) {
registry.useElement(parameterNode, element);
+ if (compiler.options.enableInitializingFormalAccess) {
+ InitializingFormalElementX initializingFormalElementX = element;
+ defineLocalVariable(parameterNode, initializingFormalElementX);
+ addToScope(initializingFormalElementX);
+ }
} else {
LocalParameterElementX parameterElement = element;
defineLocalVariable(parameterNode, parameterElement);
@@ -886,6 +891,8 @@
} else {
return new StaticAccess.parameter(target);
}
+ } else if (target.isInitializingFormal) {
+ return new StaticAccess.finalParameter(target);
} else if (target.isVariable) {
if (target.isFinal || target.isConst) {
return new StaticAccess.finalLocalVariable(target);
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 4ea5aff..9317d30 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -359,8 +359,21 @@
// TODO(johnniwinther): Share the resolved type between all variables
// declared in the same declaration.
if (tree.type != null) {
- element.variables.type = visitor.resolveTypeAnnotation(tree.type);
- } else {
+ DartType type = visitor.resolveTypeAnnotation(tree.type);
+ assert(invariant(
+ element,
+ element.variables.type == null ||
+ // Crude check but we have no equivalence relation that
+ // equates malformed types, like matching creations of type
+ // `Foo<Unresolved>`.
+ element.variables.type.toString() == type.toString(),
+ message: "Unexpected type computed for $element. "
+ "Was ${element.variables.type}, computed $type."));
+ element.variables.type = type;
+ } else if (element.variables.type == null) {
+ // Only assign the dynamic type if the element has no known type. This
+ // happens for enum fields where the type is known but is not in the
+ // synthesized AST.
element.variables.type = const DynamicType();
}
diff --git a/pkg/compiler/lib/src/serialization/element_serialization.dart b/pkg/compiler/lib/src/serialization/element_serialization.dart
index ab10cc8..b115ae0 100644
--- a/pkg/compiler/lib/src/serialization/element_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/element_serialization.dart
@@ -478,6 +478,7 @@
}
SerializerUtil.serializeParentRelation(element, encoder);
encoder.setBool(Key.IS_EXTERNAL, element.isExternal);
+ encoder.setBool(Key.IS_ABSTRACT, element.isAbstract);
if (element.isLocal) {
LocalFunctionElement localFunction = element;
encoder.setElement(
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index ab8f78e..563783f 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -383,9 +383,31 @@
@override
bool visitClassElement(ClassElement element1, ClassElement element2) {
- return strategy.test(
- element1, element2, 'name', element1.name, element2.name) &&
- visit(element1.library, element2.library);
+ if (!strategy.test(
+ element1,
+ element2,
+ 'isUnnamedMixinApplication',
+ element1.isUnnamedMixinApplication,
+ element2.isUnnamedMixinApplication)) {
+ return false;
+ }
+ if (element1.isUnnamedMixinApplication) {
+ MixinApplicationElement mixin1 = element1;
+ MixinApplicationElement mixin2 = element2;
+ return strategy.testElements(
+ mixin1, mixin2, 'subclass', mixin1.subclass, mixin2.subclass) &&
+ // Using the [mixinType] is more precise but requires the test to
+ // handle self references: The identity of a type variable is based on
+ // its type declaration and if [mixin1] is generic the [mixinType]
+ // will contain the type variables declared by [mixin1], i.e.
+ // `abstract class Mixin<T> implements MixinType<T> {}`
+ strategy.testElements(
+ mixin1, mixin2, 'mixin', mixin1.mixin, mixin2.mixin);
+ } else {
+ return strategy.test(
+ element1, element2, 'name', element1.name, element2.name) &&
+ visit(element1.library, element2.library);
+ }
}
bool checkMembers(Element element1, Element element2) {
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index 36ec45c..a03ef2f 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -301,7 +301,9 @@
}
}
-class AbstractFieldElementZ extends ElementZ implements AbstractFieldElement {
+class AbstractFieldElementZ extends ElementZ
+ with AbstractFieldElementCommon
+ implements AbstractFieldElement {
final String name;
final GetterElementZ getter;
final SetterElementZ setter;
@@ -346,6 +348,18 @@
@override
ClassElement get enclosingClass => _canonicalElement.enclosingClass;
+
+ @override
+ bool get isClassMember => _canonicalElement.isClassMember;
+
+ @override
+ bool get isInstanceMember => _canonicalElement.isInstanceMember;
+
+ @override
+ bool get isStatic => _canonicalElement.isStatic;
+
+ @override
+ bool get isTopLevel => _canonicalElement.isTopLevel;
}
class LibraryElementZ extends DeserializedElementZ
@@ -468,7 +482,9 @@
@override
Iterable<ImportElement> getImportsFor(Element element) {
- return _unsupported('getImportsFor');
+ // TODO(johnniwinther): Serialize this to support deferred access to
+ // serialized entities.
+ return <ImportElement>[];
}
String toString() {
@@ -568,6 +584,9 @@
SourceSpan get sourcePosition => new SourceSpan(script.resourceUri, 0, 0);
@override
+ bool get isTopLevel => false;
+
+ @override
accept(ElementVisitor visitor, arg) {
return visitor.visitCompilationUnitElement(this, arg);
}
@@ -669,6 +688,9 @@
@override
bool get isInstanceMember => true;
+
+ @override
+ bool get isClassMember => true;
}
abstract class StaticMemberMixin implements DeserializedElementZ {
@@ -677,6 +699,9 @@
@override
bool get isStatic => true;
+
+ @override
+ bool get isClassMember => true;
}
abstract class TypedElementMixin implements DeserializedElementZ, TypedElement {
@@ -810,7 +835,8 @@
@override
ConstructorElement lookupDefaultConstructor() {
ConstructorElement constructor = lookupConstructor("");
- if (constructor != null && constructor.parameters.isEmpty) {
+ if (constructor != null &&
+ constructor.functionSignature.requiredParameterCount == 0) {
return constructor;
}
return null;
@@ -823,8 +849,10 @@
void ensureResolved(Resolution resolution) {
if (!_isResolved) {
_isResolved = true;
- class_members.MembersCreator
- .computeClassMembersByName(resolution, this, Identifiers.call);
+ // TODO(johnniwinther): Avoid eager computation of all members. `call` is
+ // always needed, but the remaining should be computed on-demand or on
+ // type instantiation.
+ class_members.MembersCreator.computeAllClassMembers(resolution, this);
resolution.registerClass(this);
}
}
@@ -946,6 +974,9 @@
@override
InterfaceType get mixinType => _mixinType ??= _decoder.getType(Key.MIXIN);
+
+ @override
+ ClassElement get subclass => null;
}
class UnnamedMixinApplicationElementZ extends ElementZ
@@ -959,26 +990,30 @@
MixinApplicationElementCommon,
MixinApplicationElementMixin {
final String name;
- final ClassElement _subclass;
- final InterfaceType supertype;
- final Link<DartType> interfaces;
+ final ClassElement subclass;
+ final InterfaceType _supertypeBase;
+ final InterfaceType _mixinBase;
+ InterfaceType _supertype;
+ Link<DartType> _interfaces;
OrderedTypeSet _allSupertypesAndSelf;
Link<ConstructorElement> _constructors;
UnnamedMixinApplicationElementZ(
- ClassElement subclass, InterfaceType supertype, InterfaceType mixin)
- : this._subclass = subclass,
- this.supertype = supertype,
- this.interfaces = const Link<DartType>().prepend(mixin),
+ this.subclass, InterfaceType supertype, InterfaceType mixin)
+ : this._supertypeBase = supertype,
+ this._mixinBase = mixin,
this.name = "${supertype.name}+${mixin.name}";
@override
- CompilationUnitElement get compilationUnit => _subclass.compilationUnit;
+ CompilationUnitElement get compilationUnit => subclass.compilationUnit;
@override
bool get isTopLevel => true;
@override
+ bool get isAbstract => true;
+
+ @override
bool get isUnnamedMixinApplication => true;
Link<ConstructorElement> get constructors {
@@ -1005,7 +1040,7 @@
// Create synthetic type variables for the mixin application.
List<DartType> typeVariables = <DartType>[];
int index = 0;
- for (TypeVariableType type in _subclass.typeVariables) {
+ for (TypeVariableType type in subclass.typeVariables) {
SyntheticTypeVariableElementZ typeVariableElement =
new SyntheticTypeVariableElementZ(this, index, type.name);
TypeVariableType typeVariable = new TypeVariableType(typeVariableElement);
@@ -1013,17 +1048,56 @@
index++;
}
// Setup bounds on the synthetic type variables.
- for (TypeVariableType type in _subclass.typeVariables) {
+ for (TypeVariableType type in subclass.typeVariables) {
TypeVariableType typeVariable = typeVariables[type.element.index];
SyntheticTypeVariableElementZ typeVariableElement = typeVariable.element;
typeVariableElement._type = typeVariable;
typeVariableElement._bound =
- type.element.bound.subst(typeVariables, _subclass.typeVariables);
+ type.element.bound.subst(typeVariables, subclass.typeVariables);
}
return typeVariables;
}
@override
+ InterfaceType get supertype {
+ if (_supertype == null) {
+ // Substitute the type variables in [_supertypeBase] provided by
+ // [_subclass] with the type variables in this unnamed mixin application.
+ //
+ // For instance
+ // class S<S.T> {}
+ // class M<M.T> {}
+ // class C<C.T> extends S<C.T> with M<C.T> {}
+ // the unnamed mixin application should be
+ // abstract class S+M<S+M.T> extends S<S+M.T> implements M<S+M.T> {}
+ // but the supertype is provided as S<C.T> and we need to substitute S+M.T
+ // for C.T.
+ _supertype = _supertypeBase.subst(typeVariables, subclass.typeVariables);
+ }
+ return _supertype;
+ }
+
+ @override
+ Link<DartType> get interfaces {
+ if (_interfaces == null) {
+ // Substitute the type variables in [_mixinBase] provided by
+ // [_subclass] with the type variables in this unnamed mixin application.
+ //
+ // For instance
+ // class S<S.T> {}
+ // class M<M.T> {}
+ // class C<C.T> extends S<C.T> with M<C.T> {}
+ // the unnamed mixin application should be
+ // abstract class S+M<S+M.T> extends S<S+M.T> implements M<S+M.T> {}
+ // but the mixin is provided as M<C.T> and we need to substitute S+M.T
+ // for C.T.
+ _interfaces = const Link<DartType>()
+ .prepend(_mixinBase.subst(typeVariables, subclass.typeVariables));
+ }
+ return _interfaces;
+ }
+
+ @override
accept(ElementVisitor visitor, arg) {
return visitor.visitMixinApplicationElement(this, arg);
}
@@ -1038,7 +1112,7 @@
}
@override
- Element get enclosingElement => _subclass.enclosingElement;
+ Element get enclosingElement => subclass.enclosingElement;
@override
bool get isObject => false;
@@ -1053,10 +1127,10 @@
InterfaceType get mixinType => interfaces.head;
@override
- int get sourceOffset => _subclass.sourceOffset;
+ int get sourceOffset => subclass.sourceOffset;
@override
- SourceSpan get sourcePosition => _subclass.sourcePosition;
+ SourceSpan get sourcePosition => subclass.sourcePosition;
}
class EnumClassElementZ extends ClassElementZ implements EnumClassElement {
@@ -1084,7 +1158,8 @@
FunctionTypedElementMixin,
ParametersMixin,
TypedElementMixin,
- MemberElementMixin
+ MemberElementMixin,
+ ConstructorElementCommon
implements
ConstructorElement,
// TODO(johnniwinther): Sort out whether a constructor is a method.
@@ -1104,14 +1179,6 @@
@override
bool get isExternal => _decoder.getBool(Key.IS_EXTERNAL);
- bool get isFromEnvironmentConstructor {
- return name == 'fromEnvironment' &&
- library.isDartCore &&
- (enclosingClass.name == 'bool' ||
- enclosingClass.name == 'int' ||
- enclosingClass.name == 'String');
- }
-
ConstantConstructor get constantConstructor {
if (isConst && _constantConstructor == null) {
ObjectDecoder data =
@@ -1263,8 +1330,13 @@
}
class ForwardingConstructorElementZ extends ElementZ
- with AnalyzableElementMixin, AstElementMixinZ
- implements ConstructorElement {
+ with
+ AnalyzableElementMixin,
+ AstElementMixinZ
+ implements
+ ConstructorElement,
+ // TODO(johnniwinther): Sort out whether a constructor is a method.
+ MethodElement {
final MixinApplicationElement enclosingClass;
final ConstructorElement definingConstructor;
@@ -1293,6 +1365,9 @@
bool get isConst => false;
@override
+ bool get isClassMember => true;
+
+ @override
ConstantConstructor get constantConstructor => null;
@override
@@ -1332,6 +1407,15 @@
bool get isFromEnvironmentConstructor => false;
@override
+ bool get isIntFromEnvironmentConstructor => false;
+
+ @override
+ bool get isBoolFromEnvironmentConstructor => false;
+
+ @override
+ bool get isStringFromEnvironmentConstructor => false;
+
+ @override
bool get isRedirectingFactory => false;
@override
@@ -1493,6 +1577,9 @@
}
@override
+ bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
+
+ @override
bool get isOperator => _decoder.getBool(Key.IS_OPERATOR);
}
@@ -1594,6 +1681,9 @@
}
@override
+ bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
+
+ @override
AsyncMarker get asyncMarker => AsyncMarker.SYNC;
}
@@ -1634,6 +1724,9 @@
}
@override
+ bool get isAbstract => _decoder.getBool(Key.IS_ABSTRACT);
+
+ @override
AsyncMarker get asyncMarker => AsyncMarker.SYNC;
}
@@ -1960,7 +2053,7 @@
ElementKind get kind => ElementKind.PARAMETER;
}
-class InitializingFormalElementZ extends ParameterElementZ
+class InitializingFormalElementZ extends LocalParameterElementZ
implements InitializingFormalElement {
FieldElement _fieldElement;
@@ -1981,6 +2074,9 @@
@override
ElementKind get kind => ElementKind.INITIALIZING_FORMAL;
+
+ @override
+ bool get isLocal => true;
}
class LocalVariableElementZ extends DeserializedElementZ
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index 74dd4a0..1b97c3d 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -5,9 +5,11 @@
library dart2js.serialization;
import '../common.dart';
+import '../common/resolution.dart';
import '../constants/expressions.dart';
import '../dart_types.dart';
import '../elements/elements.dart';
+import '../library_loader.dart' show LibraryProvider;
import '../util/enumset.dart';
import 'constant_serialization.dart';
@@ -921,13 +923,17 @@
/// Context for parallel deserialization.
class DeserializationContext {
final DiagnosticReporter reporter;
+ final Resolution resolution;
+ final LibraryProvider libraryProvider;
Map<Uri, LibraryElement> _uriMap = <Uri, LibraryElement>{};
List<Deserializer> deserializers = <Deserializer>[];
List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
- DeserializationContext(this.reporter);
+ DeserializationContext(this.reporter, this.resolution, this.libraryProvider);
LibraryElement lookupLibrary(Uri uri) {
+ // TODO(johnniwinther): Move this to the library loader by making a
+ // [Deserializer] a [LibraryProvider].
return _uriMap.putIfAbsent(uri, () {
Uri foundUri;
LibraryElement foundLibrary;
@@ -949,6 +955,11 @@
return foundLibrary;
});
}
+
+ LibraryElement findLibrary(Uri uri) {
+ LibraryElement library = lookupLibrary(uri);
+ return library ?? libraryProvider.lookupLibrary(uri);
+ }
}
/// Deserializer for a closed collection of libraries.
@@ -1024,7 +1035,7 @@
decoder.getEnum(Key.KIND, SerializedElementKind.values);
if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY) {
Uri uri = decoder.getUri(Key.URI);
- element = context.lookupLibrary(uri);
+ element = context.findLibrary(uri);
if (element == null) {
throw new StateError("Missing library for $uri.");
}
@@ -1047,6 +1058,7 @@
}
} else if (elementKind == SerializedElementKind.EXTERNAL_CLASS_MEMBER) {
ClassElement cls = decoder.getElement(Key.CLASS);
+ cls.ensureResolved(context.resolution);
String name = decoder.getString(Key.NAME);
bool isGetter = decoder.getBool(Key.GETTER, isOptional: true);
element = cls.lookupLocalMember(name);
@@ -1063,6 +1075,7 @@
}
} else if (elementKind == SerializedElementKind.EXTERNAL_CONSTRUCTOR) {
ClassElement cls = decoder.getElement(Key.CLASS);
+ cls.ensureResolved(context.resolution);
String name = decoder.getString(Key.NAME);
element = cls.lookupConstructor(name);
if (element == null) {
diff --git a/pkg/compiler/lib/src/serialization/system.dart b/pkg/compiler/lib/src/serialization/system.dart
index 8b54e98d..22ac66b 100644
--- a/pkg/compiler/lib/src/serialization/system.dart
+++ b/pkg/compiler/lib/src/serialization/system.dart
@@ -28,16 +28,15 @@
class DeserializerSystemImpl extends DeserializerSystem {
final Compiler _compiler;
+ final Resolution resolution;
final DeserializationContext deserializationContext;
final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
final ResolutionImpactDeserializer _resolutionImpactDeserializer;
final ResolvedAstDeserializerPlugin _resolvedAstDeserializer;
- final ImpactTransformer _impactTransformer;
- factory DeserializerSystemImpl(
- Compiler compiler, ImpactTransformer impactTransformer) {
- DeserializationContext context =
- new DeserializationContext(compiler.reporter);
+ factory DeserializerSystemImpl(Compiler compiler) {
+ DeserializationContext context = new DeserializationContext(
+ compiler.reporter, compiler.resolution, compiler.libraryLoader);
DeserializerPlugin backendDeserializer =
compiler.backend.serialization.deserializer;
context.plugins.add(backendDeserializer);
@@ -48,14 +47,14 @@
new ResolvedAstDeserializerPlugin(
compiler.parsingContext, backendDeserializer);
context.plugins.add(resolvedAstDeserializer);
- return new DeserializerSystemImpl._(compiler, context, impactTransformer,
+ return new DeserializerSystemImpl._(compiler, compiler.resolution, context,
resolutionImpactDeserializer, resolvedAstDeserializer);
}
DeserializerSystemImpl._(
this._compiler,
+ this.resolution,
this.deserializationContext,
- this._impactTransformer,
this._resolutionImpactDeserializer,
this._resolvedAstDeserializer);
@@ -96,7 +95,7 @@
element.enclosingClass.isUnnamedMixinApplication) {
return true;
}
- return _resolutionImpactDeserializer.impactMap.containsKey(element);
+ return _resolutionImpactDeserializer.hasResolutionImpact(element);
}
@override
@@ -111,14 +110,15 @@
"${element} not found in ${superclass}."));
// TODO(johnniwinther): Compute callStructure. Currently not used.
CallStructure callStructure;
- return _resolutionImpactDeserializer.impactMap.putIfAbsent(element, () {
+ return _resolutionImpactDeserializer.registerResolutionImpact(element,
+ () {
return new DeserializedResolutionImpact(staticUses: <StaticUse>[
new StaticUse.superConstructorInvoke(
superclassConstructor, callStructure)
]);
});
}
- return _resolutionImpactDeserializer.impactMap[element];
+ return _resolutionImpactDeserializer.getResolutionImpact(element);
}
@override
@@ -129,7 +129,18 @@
if (element is ExecutableElement) {
getResolvedAst(element);
}
- return _impactTransformer.transformResolutionImpact(resolutionImpact);
+ if (element.isField && !element.isConst) {
+ FieldElement field = element;
+ if (field.isTopLevel || field.isStatic) {
+ if (field.constant == null) {
+ // TODO(johnniwinther): Find a cleaner way to do this. Maybe
+ // `Feature.LAZY_FIELD` of the resolution impact should be used
+ // instead.
+ _compiler.backend.constants.registerLazyStatic(element);
+ }
+ }
+ }
+ return resolution.transformResolutionImpact(element, resolutionImpact);
}
@override
@@ -158,7 +169,8 @@
}
class ResolutionImpactDeserializer extends DeserializerPlugin {
- Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{};
+ Map<Element, ObjectDecoder> _decoderMap = <Element, ObjectDecoder>{};
+ Map<Element, ResolutionImpact> _impactMap = <Element, ResolutionImpact>{};
final DeserializerPlugin nativeDataDeserializer;
ResolutionImpactDeserializer(this.nativeDataDeserializer);
@@ -167,10 +179,30 @@
void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG);
if (decoder != null) {
- impactMap[element] = ImpactDeserializer.deserializeImpact(
- element, decoder, nativeDataDeserializer);
+ _decoderMap[element] = decoder;
}
}
+
+ bool hasResolutionImpact(Element element) {
+ return _impactMap.containsKey(element) || _decoderMap.containsKey(element);
+ }
+
+ ResolutionImpact registerResolutionImpact(
+ Element element, ResolutionImpact ifAbsent()) {
+ return _impactMap.putIfAbsent(element, ifAbsent);
+ }
+
+ ResolutionImpact getResolutionImpact(Element element) {
+ return registerResolutionImpact(element, () {
+ ObjectDecoder decoder = _decoderMap[element];
+ if (decoder != null) {
+ _decoderMap.remove(element);
+ return ImpactDeserializer.deserializeImpact(
+ element, decoder, nativeDataDeserializer);
+ }
+ return null;
+ });
+ }
}
const String RESOLVED_AST_TAG = 'resolvedAst';
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 80d98d6..f57ade6 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -117,8 +117,7 @@
void deserializeFromText(Uri sourceUri, String serializedData) {
measure(() {
if (deserializer == null) {
- deserializer = new DeserializerSystemImpl(
- compiler, compiler.backend.impactTransformer);
+ deserializer = new DeserializerSystemImpl(compiler);
}
DeserializerSystemImpl deserializerImpl = deserializer;
DeserializationContext context = deserializerImpl.deserializationContext;
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index 750357e..2a8ab08 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -40,7 +40,7 @@
TypeDeclarationElement,
TypedElement,
VariableElement;
-import 'resolution/class_members.dart' show MembersCreator;
+import 'resolution/class_members.dart' show MembersCreator, ErroneousMember;
import 'resolution/tree_elements.dart' show TreeElements;
import 'tree/tree.dart';
import 'util/util.dart' show Link, LinkBuilder;
@@ -733,7 +733,11 @@
Name name, DartType unaliasedBound, InterfaceType interface) {
MemberSignature member = lookupMemberSignature(memberName, interface);
if (member != null) {
- return new MemberAccess(member);
+ if (member is ErroneousMember) {
+ return const DynamicAccess();
+ } else {
+ return new MemberAccess(member);
+ }
}
if (name == const PublicName('call')) {
if (unaliasedBound.isFunctionType) {
@@ -1057,7 +1061,10 @@
} else if (element.isFunction) {
// foo() where foo is a method in the same class.
return createResolvedAccess(node, name, element);
- } else if (element.isVariable || element.isParameter || element.isField) {
+ } else if (element.isVariable ||
+ element.isParameter ||
+ element.isField ||
+ element.isInitializingFormal) {
// foo() where foo is a field in the same class.
return createResolvedAccess(node, name, element);
} else if (element.isGetter || element.isSetter) {
diff --git a/pkg/meta/CHANGELOG.md b/pkg/meta/CHANGELOG.md
index 474ddfe..6d83624 100644
--- a/pkg/meta/CHANGELOG.md
+++ b/pkg/meta/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.12.2
+* Updated `@protected` to include implemented interfaces (linter#252).
+
## 0.12.1
* Fixed markdown in dartdocs.
diff --git a/pkg/meta/lib/meta.dart b/pkg/meta/lib/meta.dart
index ff0f9b0..17f7f1f 100644
--- a/pkg/meta/lib/meta.dart
+++ b/pkg/meta/lib/meta.dart
@@ -69,8 +69,9 @@
/// field) `m` in a class `C`. If the annotation is on a field it applies to the
/// getter, and setter if appropriate, that are induced by the field. Indicates
/// that `m` should only be invoked from instance methods of `C` or classes that
-/// extend or mix in `C`, either directly or indirectly. Additionally indicates
-/// that `m` should only be invoked on `this`, whether explicitly or implicitly.
+/// extend, implement or mix in `C`, either directly or indirectly. Additionally
+/// indicates that `m` should only be invoked on `this`, whether explicitly or
+/// implicitly.
///
/// Tools, such as the analyzer, can provide feedback if
///
diff --git a/pkg/meta/pubspec.yaml b/pkg/meta/pubspec.yaml
index 82a1677..7daaa74 100644
--- a/pkg/meta/pubspec.yaml
+++ b/pkg/meta/pubspec.yaml
@@ -1,5 +1,5 @@
name: meta
-version: 0.12.1
+version: 0.12.2
author: Dart Team <misc@dartlang.org>
homepage: http://www.dartlang.org
description: >
diff --git a/pkg/pkgbuild.status b/pkg/pkgbuild.status
index 1366f47..fa11a2d 100644
--- a/pkg/pkgbuild.status
+++ b/pkg/pkgbuild.status
@@ -3,9 +3,9 @@
# BSD-style license that can be found in the LICENSE file.
samples/searchable_list: Pass, Slow
+third_party/pkg/scheduled_test: Fail # Issue 26585
[ $use_repository_packages ]
-pkg/analyzer: PubGetError
samples/third_party/angular_todo: Fail # angular needs to be updated
[ $use_public_packages ]
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 6b16d99..7045187 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -1,5 +1,5 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
+// for details. All rights solveserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library builtin;
@@ -10,6 +10,10 @@
import 'dart:isolate';
import 'dart:typed_data';
+// Embedder sets this to true if the --trace-loading flag was passed on the
+// command line.
+bool _traceLoading = false;
+
// Before handling an embedder entrypoint we finalize the setup of the
// dart:_builtin library.
@@ -52,40 +56,40 @@
_getUriBaseClosure() => _uriBase;
-
// Asynchronous loading of resources.
-// The embedder forwards most loading requests to this library.
-
-// See Dart_LibraryTag in dart_api.h
-const _Dart_kScriptTag = null;
-const _Dart_kImportTag = 0;
-const _Dart_kSourceTag = 1;
-const _Dart_kCanonicalizeUrl = 2;
-const _Dart_kResourceLoad = 3;
-
-// Embedder sets this to true if the --trace-loading flag was passed on the
-// command line.
-bool _traceLoading = false;
-
-// This is currently a build time flag only. We measure the time from the first
-// load request (opening the receive port) to completing the last load
-// request (closing the receive port). Future, deferred load operations will
-// add to this time.
-bool _timeLoading = false;
-Stopwatch _stopwatch;
+// The embedder forwards loading requests to the service isolate.
// A port for communicating with the service isolate for I/O.
SendPort _loadPort;
-// The receive port for a load request. Multiple sources can be fetched in
-// a single load request.
-RawReceivePort _dataPort;
-// A request id valid only for the current load cycle (while the number of
-// outstanding load requests is greater than 0). Can be reset when loading is
-// completed.
-int _reqId = 0;
-// An unordered hash map mapping from request id to a particular load request.
-// Once there are no outstanding load requests the current load has finished.
-HashMap _reqMap = new HashMap();
+
+// The isolateId used to communicate with the service isolate for I/O.
+int _isolateId;
+
+// Requests made to the service isolate over the load port.
+
+// Extra requests. Keep these in sync between loader.dart and builtin.dart.
+const _Dart_kInitLoader = 4; // Initialize the loader.
+const _Dart_kResourceLoad = 5; // Resource class support.
+const _Dart_kGetPackageRootUri = 6; // Uri of the packages/ directory.
+const _Dart_kGetPackageConfigUri = 7; // Uri of the .packages file.
+const _Dart_kResolvePackageUri = 8; // Resolve a package: uri.
+
+// Make a request to the loader. Future will complete with result which is
+// either a Uri or a List<int>.
+Future _makeLoaderRequest(int tag, String uri) {
+ assert(_isolateId != null);
+ assert(_loadPort != null);
+ Completer completer = new Completer();
+ RawReceivePort port = new RawReceivePort();
+ port.handler = (msg) {
+ // Close the port.
+ port.close();
+ completer.complete(msg);
+ };
+ _loadPort.send([_traceLoading, _isolateId, tag, port.sendPort, uri]);
+ return completer.future;
+}
+
// The current working directory when the embedder was launched.
Uri _workingDirectory;
@@ -93,29 +97,8 @@
// package imports can be resolved relative to it. The root script is the basis
// for the root library in the VM.
Uri _rootScript;
-
-// Packages are either resolved looking up in a map or resolved from within a
-// package root.
-bool get _packagesReady =>
- (_packageRoot != null) || (_packageMap != null) || (_packageError != null);
-// Error string set if there was an error resolving package configuration.
-// For example not finding a .packages file or packages/ directory, malformed
-// .packages file or any other related error.
-String _packageError = null;
-// The directory to look in to resolve "package:" scheme URIs. By detault it is
-// the 'packages' directory right next to the script.
-Uri _packageRoot = null; // Used to be _rootScript.resolve('packages/');
-// The map describing how certain package names are mapped to Uris.
-Uri _packageConfig = null;
-Map<String, Uri> _packageMap = null;
-
-// A list of pending packags which have been requested while resolving the
-// location of the package root or the contents of the package map.
-List<_LoadRequest> _pendingPackageLoads = [];
-
-// If we have outstanding loads or pending package loads waiting for resolution,
-// then we do have pending loads.
-bool _pendingLoads() => !_reqMap.isEmpty || !_pendingPackageLoads.isEmpty;
+// The package root set on the command line.
+Uri _packageRoot;
// Special handling for Windows paths so that they are compatible with URI
// handling.
@@ -128,47 +111,6 @@
_print("* $_logId $msg");
}
-// A class wrapping the load error message in an Error object.
-class _LoadError extends Error {
- final _LoadRequest request;
- final String message;
- _LoadError(this.request, this.message);
-
- String toString() {
- var context = request._context;
- if (context == null || context is! String) {
- return 'Could not load "${request._uri}": $message';
- } else {
- return 'Could not import "${request._uri}" from "$context": $message';
- }
- }
-}
-
-// Class collecting all of the information about a particular load request.
-class _LoadRequest {
- final int _id = _reqId++;
- final int _tag;
- final String _uri;
- final Uri _resourceUri;
- final _context;
-
- _LoadRequest(this._tag, this._uri, this._resourceUri, this._context) {
- assert(_reqMap[_id] == null);
- _reqMap[_id] = this;
- }
-
- toString() => "LoadRequest($_id, $_tag, $_uri, $_resourceUri, $_context)";
-}
-
-
-// Native calls provided by the embedder.
-void _signalDoneLoading() native "Builtin_DoneLoading";
-void _loadScriptCallback(int tag, String uri, String libraryUri, Uint8List data)
- native "Builtin_LoadSource";
-void _asyncLoadErrorCallback(uri, libraryUri, error)
- native "Builtin_AsyncLoadError";
-
-
_sanitizeWindowsPath(path) {
// For Windows we need to massage the paths a bit according to
// http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
@@ -193,7 +135,6 @@
return fixedPath;
}
-
_trimWindowsPath(path) {
// Convert /X:/ to X:/.
if (_isWindows == false) {
@@ -211,7 +152,6 @@
return path;
}
-
// Ensure we have a trailing slash character.
_enforceTrailingSlash(uri) {
if (!uri.endsWith('/')) {
@@ -220,7 +160,6 @@
return uri;
}
-
// Embedder Entrypoint:
// The embedder calls this method with the current working directory.
void _setWorkingDirectory(cwd) {
@@ -236,7 +175,6 @@
}
}
-
// Embedder Entrypoint:
// The embedder calls this method with a custom package root.
_setPackageRoot(String packageRoot) {
@@ -246,15 +184,15 @@
if (_traceLoading) {
_log('Setting package root: $packageRoot');
}
- packageRoot = _enforceTrailingSlash(packageRoot);
if (packageRoot.startsWith('file:') ||
packageRoot.startsWith('http:') ||
packageRoot.startsWith('https:')) {
+ packageRoot = _enforceTrailingSlash(packageRoot);
_packageRoot = _workingDirectory.resolve(packageRoot);
} else {
packageRoot = _sanitizeWindowsPath(packageRoot);
packageRoot = _trimWindowsPath(packageRoot);
- _packageRoot = _workingDirectory.resolveUri(new Uri.file(packageRoot));
+ _packageRoot = _workingDirectory.resolveUri(new Uri.directory(packageRoot));
}
// Now that we have determined the packageRoot value being used, set it
// up for use in Platform.packageRoot. This is only set when the embedder
@@ -266,265 +204,8 @@
}
}
-
-// Given a uri with a 'package' scheme, return a Uri that is prefixed with
-// the package root.
-Uri _resolvePackageUri(Uri uri) {
- assert(uri.scheme == "package");
- assert(_packagesReady);
-
- if (!uri.host.isEmpty) {
- var path = '${uri.host}${uri.path}';
- var right = 'package:$path';
- var wrong = 'package://$path';
-
- throw "URIs using the 'package:' scheme should look like "
- "'$right', not '$wrong'.";
- }
-
- if (_traceLoading) {
- _log('Resolving package with uri path: ${uri.path}');
- }
- var resolvedUri;
- if (_packageError != null) {
- if (_traceLoading) {
- _log("Resolving package with pending resolution error: $_packageError");
- }
- throw _packageError;
- } else if (_packageRoot != null) {
- resolvedUri = _packageRoot.resolve(uri.path);
- } else {
- var packageName = uri.pathSegments[0];
- var mapping = _packageMap[packageName];
- if (_traceLoading) {
- _log("Mapped '$packageName' package to '$mapping'");
- }
- if (mapping == null) {
- throw "No mapping for '$packageName' package when resolving '$uri'.";
- }
- var path;
- if (uri.path.length > packageName.length) {
- path = uri.path.substring(packageName.length + 1);
- } else {
- // Handle naked package resolution to the default package name:
- // package:foo is equivalent to package:foo/foo.dart
- assert(uri.path.length == packageName.length);
- path = "$packageName.dart";
- }
- if (_traceLoading) {
- _log("Path to be resolved in package: $path");
- }
- resolvedUri = mapping.resolve(path);
- }
- if (_traceLoading) {
- _log("Resolved '$uri' to '$resolvedUri'.");
- }
- return resolvedUri;
-}
-
-
-// Resolves the script uri in the current working directory iff the given uri
-// did not specify a scheme (e.g. a path to a script file on the command line).
-Uri _resolveScriptUri(String scriptName) {
- if (_traceLoading) {
- _log("Resolving script: $scriptName");
- }
- if (_workingDirectory == null) {
- throw 'No current working directory set.';
- }
- scriptName = _sanitizeWindowsPath(scriptName);
-
- var scriptUri = Uri.parse(scriptName);
- if (scriptUri.scheme == '') {
- // Script does not have a scheme, assume that it is a path,
- // resolve it against the working directory.
- scriptUri = _workingDirectory.resolveUri(scriptUri);
- }
-
- // Remember the root script URI so that we can resolve packages based on
- // this location.
- _rootScript = scriptUri;
-
- if (_traceLoading) {
- _log('Resolved entry point to: $_rootScript');
- }
- return scriptUri;
-}
-
-
-void _finishLoadRequest(_LoadRequest req) {
- if (req != null) {
- // Now that we are done with loading remove the request from the map.
- var tmp = _reqMap.remove(req._id);
- assert(tmp == req);
- if (_traceLoading) {
- _log("Loading of ${req._uri} finished: "
- "${_reqMap.length} requests remaining, "
- "${_pendingPackageLoads.length} packages pending.");
- }
- }
-
- if (!_pendingLoads() && (_dataPort != null)) {
- _stopwatch.stop();
- // Close the _dataPort now that there are no more requests outstanding.
- if (_traceLoading || _timeLoading) {
- _log("Closing loading port: ${_stopwatch.elapsedMilliseconds} ms");
- }
- _dataPort.close();
- _dataPort = null;
- _reqId = 0;
- _signalDoneLoading();
- }
-}
-
-
-void _handleLoaderReply(msg) {
- int id = msg[0];
- var dataOrError = msg[1];
- assert((id >= 0) && (id < _reqId));
- var req = _reqMap[id];
- try {
- if (dataOrError is Uint8List) {
- // Successfully loaded the data.
- if (req._tag == _Dart_kResourceLoad) {
- Completer c = req._context;
- c.complete(dataOrError);
- } else {
- // TODO: Currently a compilation error while loading the script is
- // fatal for the isolate. _loadScriptCallback() does not return and
- // the number of requests remains out of sync.
- _loadScriptCallback(req._tag, req._uri, req._context, dataOrError);
- }
- _finishLoadRequest(req);
- } else {
- assert(dataOrError is String);
- var error = new _LoadError(req, dataOrError.toString());
- _asyncLoadError(req, error, null);
- }
- } catch(e, s) {
- // Wrap inside a _LoadError unless we are already propagating a
- // previous _LoadError.
- var error = (e is _LoadError) ? e : new _LoadError(req, e.toString());
- assert(req != null);
- _asyncLoadError(req, error, s);
- }
-}
-
-
-void _startLoadRequest(int tag, String uri, Uri resourceUri, context) {
- if (_dataPort == null) {
- if (_traceLoading) {
- _log("Initializing load port.");
- }
- // Allocate the Stopwatch if necessary.
- if (_stopwatch == null) {
- _stopwatch = new Stopwatch();
- }
- assert(_dataPort == null);
- _dataPort = new RawReceivePort(_handleLoaderReply);
- _stopwatch.start();
- }
- // Register the load request and send it to the VM service isolate.
- var req = new _LoadRequest(tag, uri, resourceUri, context);
-
- assert(_dataPort != null);
- var msg = new List(4);
- msg[0] = _dataPort.sendPort;
- msg[1] = _traceLoading;
- msg[2] = req._id;
- msg[3] = resourceUri.toString();
- _loadPort.send(msg);
-
- if (_traceLoading) {
- _log("Loading of $resourceUri for $uri started with id: ${req._id}. "
- "${_reqMap.length} requests remaining, "
- "${_pendingPackageLoads.length} packages pending.");
- }
-}
-
-
-RawReceivePort _packagesPort;
-
-void _handlePackagesReply(msg) {
- // Make sure to close the _packagePort before any other action.
- _packagesPort.close();
- _packagesPort = null;
-
- if (_traceLoading) {
- _log("Got packages reply: $msg");
- }
- if (msg is String) {
- if (_traceLoading) {
- _log("Got failure response on package port: '$msg'");
- }
- // Remember the error message.
- _packageError = msg;
- } else if (msg is List) {
- if (msg.length == 1) {
- if (_traceLoading) {
- _log("Received package root: '${msg[0]}'");
- }
- _packageRoot = Uri.parse(msg[0]);
- } else {
- // First entry contains the location of the loaded .packages file.
- assert((msg.length % 2) == 0);
- assert(msg.length >= 2);
- assert(msg[1] == null);
- _packageConfig = Uri.parse(msg[0]);
- _packageMap = new Map<String, Uri>();
- for (var i = 2; i < msg.length; i+=2) {
- // TODO(iposva): Complain about duplicate entries.
- _packageMap[msg[i]] = Uri.parse(msg[i+1]);
- }
- if (_traceLoading) {
- _log("Setup package map: $_packageMap");
- }
- }
- } else {
- _packageError = "Bad type of packages reply: ${msg.runtimeType}";
- if (_traceLoading) {
- _log(_packageError);
- }
- }
-
- // Resolve all pending package loads now that we know how to resolve them.
- while (_pendingPackageLoads.length > 0) {
- // Order does not matter as we queue all of the requests up right now.
- var req = _pendingPackageLoads.removeLast();
- // Call the registered closure, to handle the delayed action.
- req();
- }
- // Reset the pending package loads to empty. So that we eventually can
- // finish loading.
- _pendingPackageLoads = [];
- // Make sure that the receive port is closed if no other loads are pending.
- _finishLoadRequest(null);
-}
-
-
-void _requestPackagesMap() {
- assert(_packagesPort == null);
- assert(_rootScript != null);
- // Create a port to receive the packages map on.
- _packagesPort = new RawReceivePort(_handlePackagesReply);
- var sp = _packagesPort.sendPort;
-
- var msg = new List(4);
- msg[0] = sp;
- msg[1] = _traceLoading;
- msg[2] = -1;
- msg[3] = _rootScript.toString();
- _loadPort.send(msg);
-
- if (_traceLoading) {
- _log("Requested packages map for '$_rootScript'.");
- }
-}
-
-
// Embedder Entrypoint:
-// Request the load of a particular packages map.
-void _loadPackagesMap(String packagesParam) {
+void _setPackagesMap(String packagesParam) {
if (!_setupCompleted) {
_setupHooks();
}
@@ -550,147 +231,36 @@
if (_traceLoading) {
_log('Resolved packages map to: $packagesUri');
}
+}
- // Request the loading and parsing of the packages map at the specified URI.
- // Create a port to receive the packages map on.
- assert(_packagesPort == null);
- _packagesPort = new RawReceivePort(_handlePackagesReply);
- var sp = _packagesPort.sendPort;
+// Resolves the script uri in the current working directory iff the given uri
+// did not specify a scheme (e.g. a path to a script file on the command line).
+String _resolveScriptUri(String scriptName) {
+ if (_traceLoading) {
+ _log("Resolving script: $scriptName");
+ }
+ if (_workingDirectory == null) {
+ throw 'No current working directory set.';
+ }
+ scriptName = _sanitizeWindowsPath(scriptName);
- var msg = new List(4);
- msg[0] = sp;
- msg[1] = _traceLoading;
- msg[2] = -2;
- msg[3] = packagesUriStr;
- _loadPort.send(msg);
+ var scriptUri = Uri.parse(scriptName);
+ if (scriptUri.scheme == '') {
+ // Script does not have a scheme, assume that it is a path,
+ // resolve it against the working directory.
+ scriptUri = _workingDirectory.resolveUri(scriptUri);
+ }
- // Signal that the resolution of the packages map has started. But in this
- // case it is not tied to a particular request.
- _pendingPackageLoads.add(() {
- // Nothing to be done beyond registering that there is pending package
- // resolution requested by having an empty entry.
- if (_traceLoading) {
- _log("Skipping dummy deferred request.");
- }
- });
+ // Remember the root script URI so that we can resolve packages based on
+ // this location.
+ _rootScript = scriptUri;
if (_traceLoading) {
- _log("Requested packages map at '$packagesUri'.");
+ _log('Resolved entry point to: $_rootScript');
}
+ return scriptUri.toString();
}
-
-void _asyncLoadError(_LoadRequest req, _LoadError error, StackTrace stack) {
- if (_traceLoading) {
- _log("_asyncLoadError(${req._uri}), error: $error\nstack: $stack");
- }
- if (req._tag == _Dart_kResourceLoad) {
- Completer c = req._context;
- c.completeError(error, stack);
- } else {
- String libraryUri = req._context;
- if (req._tag == _Dart_kImportTag) {
- // When importing a library, the libraryUri is the imported
- // uri.
- libraryUri = req._uri;
- }
- _asyncLoadErrorCallback(req._uri, libraryUri, error);
- }
- _finishLoadRequest(req);
-}
-
-
-_loadDataFromLoadPort(int tag, String uri, Uri resourceUri, context) {
- try {
- _startLoadRequest(tag, uri, resourceUri, context);
- } catch (e, s) {
- if (_traceLoading) {
- _log("Exception when communicating with service isolate: $e");
- }
- // Register a dummy load request so we can fail to load it.
- var req = new _LoadRequest(tag, uri, resourceUri, context);
-
- // Wrap inside a _LoadError unless we are already propagating a previously
- // seen _LoadError.
- var error = (e is _LoadError) ? e : new _LoadError(req, e.toString());
- _asyncLoadError(req, error, s);
- }
-}
-
-
-// Loading a package URI needs to first map the package name to a loadable
-// URI.
-_loadPackage(int tag, String uri, Uri resourceUri, context) {
- if (_packagesReady) {
- var resolvedUri;
- try {
- resolvedUri = _resolvePackageUri(resourceUri);
- } catch (e, s) {
- if (_traceLoading) {
- _log("Exception ($e) when resolving package URI: $resourceUri");
- }
- // Register a dummy load request so we can fail to load it.
- var req = new _LoadRequest(tag, uri, resourceUri, context);
-
- // Wrap inside a _LoadError unless we are already propagating a previously
- // seen _LoadError.
- var error = (e is _LoadError) ? e : new _LoadError(req, e.toString());
- _asyncLoadError(req, error, s);
- }
- _loadData(tag, uri, resolvedUri, context);
- } else {
- if (_pendingPackageLoads.isEmpty) {
- // Package resolution has not been setup yet, and this is the first
- // request for package resolution & loading.
- _requestPackagesMap();
- }
- // Register the action of loading this package once the package resolution
- // is ready.
- _pendingPackageLoads.add(() {
- if (_traceLoading) {
- _log("Handling deferred package request: "
- "$tag, $uri, $resourceUri, $context");
- }
- _loadPackage(tag, uri, resourceUri, context);
- });
- if (_traceLoading) {
- _log("Pending package load of '$uri': "
- "${_pendingPackageLoads.length} pending");
- }
- }
-}
-
-
-// Load the data associated with the resourceUri.
-_loadData(int tag, String uri, Uri resourceUri, context) {
- if (resourceUri.scheme == 'package') {
- // package based uris need to be resolved to the correct loadable location.
- // The logic of which is handled seperately, and then _loadData is called
- // recursively.
- _loadPackage(tag, uri, resourceUri, context);
- } else {
- _loadDataFromLoadPort(tag, uri, resourceUri, context);
- }
-}
-
-
-// Embedder Entrypoint:
-// Asynchronously loads script data through a http[s] or file uri.
-_loadDataAsync(int tag, String uri, String libraryUri) {
- if (!_setupCompleted) {
- _setupHooks();
- }
- var resourceUri;
- if (tag == _Dart_kScriptTag) {
- resourceUri = _resolveScriptUri(uri);
- uri = resourceUri.toString();
- } else {
- resourceUri = Uri.parse(uri);
- }
- _loadData(tag, uri, resourceUri, libraryUri);
-}
-
-
// Embedder Entrypoint:
// Function called by standalone embedder to resolve uris when the VM requests
// Dart_kCanonicalizeUrl from the tag handler.
@@ -698,109 +268,20 @@
if (!_setupCompleted) {
_setupHooks();
}
+
if (_traceLoading) {
_log('Resolving: $userString from $base');
}
+
var baseUri = Uri.parse(base);
var result = baseUri.resolve(userString).toString();
if (_traceLoading) {
_log('Resolved $userString in $base to $result');
}
+
return result;
}
-
-// Handling of access to the package root or package map from user code.
-_triggerPackageResolution(action) {
- if (_packagesReady) {
- // Packages are ready. Execute the action now.
- action();
- } else {
- if (_pendingPackageLoads.isEmpty) {
- // Package resolution has not been setup yet, and this is the first
- // request for package resolution & loading.
- _requestPackagesMap();
- }
- // Register the action for when the package resolution is ready.
- _pendingPackageLoads.add(action);
- }
-}
-
-
-Future<Uri> _getPackageRootFuture() {
- if (_traceLoading) {
- _log("Request for package root from user code.");
- }
- var completer = new Completer<Uri>();
- _triggerPackageResolution(() {
- completer.complete(_packageRoot);
- });
- return completer.future;
-}
-
-
-Future<Uri> _getPackageConfigFuture() {
- if (_traceLoading) {
- _log("Request for package config from user code.");
- }
- var completer = new Completer<Uri>();
- _triggerPackageResolution(() {
- completer.complete(_packageConfig);
- });
- return completer.future;
-}
-
-
-Future<Uri> _resolvePackageUriFuture(Uri packageUri) async {
- if (_traceLoading) {
- _log("Request for package Uri resolution from user code: $packageUri");
- }
- if (packageUri.scheme != "package") {
- if (_traceLoading) {
- _log("Non-package Uri, returning unmodified: $packageUri");
- }
- // Return the incoming parameter if not passed a package: URI.
- return packageUri;
- }
-
- if (!_packagesReady) {
- if (_traceLoading) {
- _log("Trigger loading by requesting the package config.");
- }
- // Make sure to trigger package resolution.
- var dummy = await _getPackageConfigFuture();
- }
- assert(_packagesReady);
-
- var result;
- try {
- result = _resolvePackageUri(packageUri);
- } catch (e, s) {
- // Any error during resolution will resolve this package as not mapped,
- // which is indicated by a null return.
- if (_traceLoading) {
- _log("Exception ($e) when resolving package URI: $packageUri");
- }
- result = null;
- }
- if (_traceLoading) {
- _log("Resolved '$packageUri' to '$result'");
- }
- return result;
-}
-
-
-// Handling of Resource class by dispatching to the load port.
-Future<List<int>> _resourceReadAsBytes(Uri uri) {
- var completer = new Completer<List<int>>();
- // Request the load of the resource associating the completer as the context
- // for the load.
- _loadData(_Dart_kResourceLoad, uri.toString(), uri, completer);
- // Return the future that will be triggered once the resource has been loaded.
- return completer.future;
-}
-
-
// Embedder Entrypoint (gen_snapshot):
// Resolve relative paths relative to working directory.
String _resolveInWorkingDirectory(String fileName) {
@@ -824,6 +305,11 @@
return uri.toString();
}
+// Only used by vm/cc unit tests.
+Uri _resolvePackageUri(Uri uri) {
+ assert(_packageRoot != null);
+ return _packageRoot.resolve(uri.path);
+}
// Returns either a file path or a URI starting with http[s]:, as a String.
String _filePathFromUri(String userUri) {
@@ -853,7 +339,6 @@
}
}
-
// Embedder Entrypoint.
_libraryFilePath(String libraryUri) {
if (!_setupCompleted) {
@@ -869,7 +354,6 @@
return _filePathFromUri(path);
}
-
// Register callbacks and hooks with the rest of the core libraries.
_setupHooks() {
_setupCompleted = true;
@@ -879,3 +363,54 @@
VMLibraryHooks.packageConfigUriFuture = _getPackageConfigFuture;
VMLibraryHooks.resolvePackageUriFuture = _resolvePackageUriFuture;
}
+
+// Handling of Resource class by dispatching to the load port.
+Future<List<int>> _resourceReadAsBytes(Uri uri) async {
+ List response = await _makeLoaderRequest(_Dart_kResourceLoad, uri.toString());
+ if (response[3] is String) {
+ // Throw the error.
+ throw response[3];
+ } else {
+ return response[3];
+ }
+}
+
+Future<Uri> _getPackageRootFuture() {
+ if (_traceLoading) {
+ _log("Request for package root from user code.");
+ }
+ return _makeLoaderRequest(_Dart_kGetPackageRootUri, null);
+}
+
+Future<Uri> _getPackageConfigFuture() {
+ if (_traceLoading) {
+ _log("Request for package config from user code.");
+ }
+ assert(_loadPort != null);
+ return _makeLoaderRequest(_Dart_kGetPackageConfigUri, null);
+}
+
+Future<Uri> _resolvePackageUriFuture(Uri packageUri) async {
+ if (_traceLoading) {
+ _log("Request for package Uri resolution from user code: $packageUri");
+ }
+ if (packageUri.scheme != "package") {
+ if (_traceLoading) {
+ _log("Non-package Uri, returning unmodified: $packageUri");
+ }
+ // Return the incoming parameter if not passed a package: URI.
+ return packageUri;
+ }
+ var result = await _makeLoaderRequest(_Dart_kResolvePackageUri,
+ packageUri.toString());
+ if (result is! Uri) {
+ if (_traceLoading) {
+ _log("Exception when resolving package URI: $packageUri");
+ }
+ result = null;
+ }
+ if (_traceLoading) {
+ _log("Resolved '$packageUri' to '$result'");
+ }
+ return result;
+}
diff --git a/runtime/bin/builtin.h b/runtime/bin/builtin.h
index a4893d9..5029cf1 100644
--- a/runtime/bin/builtin.h
+++ b/runtime/bin/builtin.h
@@ -51,6 +51,11 @@
static Dart_Handle SetLoadPort(Dart_Port port);
+ static Dart_Port LoadPort() {
+ ASSERT(load_port_ != ILLEGAL_PORT);
+ return load_port_;
+ }
+
private:
// Map specified URI to an actual file name from 'source_paths' and read
// the file.
diff --git a/runtime/bin/builtin_common.cc b/runtime/bin/builtin_common.cc
index 678e48b..79713e1 100644
--- a/runtime/bin/builtin_common.cc
+++ b/runtime/bin/builtin_common.cc
@@ -23,13 +23,18 @@
namespace bin {
Dart_Handle Builtin::SetLoadPort(Dart_Port port) {
+ Dart_Handle builtin_lib =
+ Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
+ RETURN_IF_ERROR(builtin_lib);
+ // Set the _isolateId field.
+ Dart_Handle result = Dart_SetField(builtin_lib,
+ DartUtils::NewString("_isolateId"),
+ Dart_NewInteger(Dart_GetMainPortId()));
+ RETURN_IF_ERROR(result);
load_port_ = port;
ASSERT(load_port_ != ILLEGAL_PORT);
Dart_Handle field_name = DartUtils::NewString("_loadPort");
RETURN_IF_ERROR(field_name);
- Dart_Handle builtin_lib =
- Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
- RETURN_IF_ERROR(builtin_lib);
Dart_Handle send_port = Dart_GetField(builtin_lib, field_name);
RETURN_IF_ERROR(send_port);
if (!Dart_IsNull(send_port)) {
@@ -38,7 +43,7 @@
}
send_port = Dart_NewSendPort(load_port_);
RETURN_IF_ERROR(send_port);
- Dart_Handle result = Dart_SetField(builtin_lib, field_name, send_port);
+ result = Dart_SetField(builtin_lib, field_name, send_port);
RETURN_IF_ERROR(result);
return Dart_True();
}
diff --git a/runtime/bin/builtin_impl_sources.gypi b/runtime/bin/builtin_impl_sources.gypi
index eb90ddf..f775ffc 100644
--- a/runtime/bin/builtin_impl_sources.gypi
+++ b/runtime/bin/builtin_impl_sources.gypi
@@ -47,6 +47,8 @@
'io_buffer.cc',
'io_buffer.h',
'isolate_data.h',
+ 'loader.cc',
+ 'loader.h',
'lockers.h',
'thread.h',
'thread_android.cc',
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index b7f418b..c0d6072 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -379,6 +379,17 @@
}
+Dart_Handle DartUtils::ResolveScript(Dart_Handle url) {
+ const int kNumArgs = 1;
+ Dart_Handle dart_args[kNumArgs];
+ dart_args[0] = url;
+ return Dart_Invoke(DartUtils::BuiltinLib(),
+ NewString("_resolveScriptUri"),
+ kNumArgs,
+ dart_args);
+}
+
+
static Dart_Handle LoadDataAsync_Invoke(Dart_Handle tag,
Dart_Handle url,
Dart_Handle library_url) {
@@ -397,6 +408,9 @@
Dart_Handle DartUtils::LibraryTagHandler(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url) {
+ if (tag == Dart_kCanonicalizeUrl) {
+ return Dart_DefaultCanonicalizeUrl(library, url);
+ }
if (!Dart_IsLibrary(library)) {
return Dart_NewApiError("not a library");
}
@@ -420,10 +434,7 @@
// Handle canonicalization, 'import' and 'part' of 'dart:' libraries.
if (is_dart_scheme_url || is_dart_library) {
- if (tag == Dart_kCanonicalizeUrl) {
- // These will be handled internally.
- return url;
- } else if (tag == Dart_kImportTag) {
+ if (tag == Dart_kImportTag) {
Builtin::BuiltinLibraryId id = Builtin::FindId(url_string);
if (id == Builtin::kInvalidLibrary) {
return NewError("The built-in library '%s' is not available"
@@ -452,11 +463,6 @@
UNREACHABLE();
}
- if (tag == Dart_kCanonicalizeUrl) {
- // Resolve the url within the context of the library's URL.
- return ResolveUri(library_url, url);
- }
-
if (DartUtils::IsDartExtensionSchemeURL(url_string)) {
// Load a native code shared library to use in a native extension
if (tag != Dart_kImportTag) {
@@ -747,7 +753,7 @@
Dart_Handle dart_args[kNumArgs];
dart_args[0] = result;
result = Dart_Invoke(DartUtils::BuiltinLib(),
- NewString("_loadPackagesMap"),
+ NewString("_setPackagesMap"),
kNumArgs,
dart_args);
RETURN_IF_ERROR(result);
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index b416a93..9c3bc72 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -200,6 +200,7 @@
static Dart_Handle ResolveUriInWorkingDirectory(Dart_Handle script_uri);
static Dart_Handle FilePathFromUri(Dart_Handle script_uri);
static Dart_Handle ResolveUri(Dart_Handle library_url, Dart_Handle url);
+ static Dart_Handle ResolveScript(Dart_Handle url);
// Sniffs the specified text_buffer to see if it contains the magic number
// representing a script snapshot. If the text_buffer is a script snapshot
@@ -231,9 +232,10 @@
static const uint8_t magic_number[];
+ static Dart_Handle LibraryFilePath(Dart_Handle library_uri);
+
private:
static Dart_Handle SetWorkingDirectory();
- static Dart_Handle LibraryFilePath(Dart_Handle library_uri);
static Dart_Handle PrepareBuiltinLibrary(Dart_Handle builtin_lib,
Dart_Handle internal_lib,
bool is_service_isolate,
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 3e18248..5d70175 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -63,7 +63,17 @@
static const char* assembly_filename = NULL;
static const char* instructions_blob_filename = NULL;
static const char* rodata_blob_filename = NULL;
-static const char* package_root = NULL;
+
+
+// Value of the --package-root flag.
+// (This pointer points into an argv buffer and does not need to be
+// free'd.)
+static const char* commandline_package_root = NULL;
+
+// Value of the --packages flag.
+// (This pointer points into an argv buffer and does not need to be
+// free'd.)
+static const char* commandline_packages_file = NULL;
// Global state which contains a pointer to the script name for which
@@ -249,7 +259,17 @@
name = ProcessOption(option, "--package-root=");
}
if (name != NULL) {
- package_root = name;
+ commandline_package_root = name;
+ return true;
+ }
+ return false;
+}
+
+
+static bool ProcessPackagesOption(const char* option) {
+ const char* name = ProcessOption(option, "--packages=");
+ if (name != NULL) {
+ commandline_packages_file = name;
return true;
}
return false;
@@ -296,6 +316,7 @@
ProcessEmbedderEntryPointsManifestOption(argv[i]) ||
ProcessURLmappingOption(argv[i]) ||
ProcessPackageRootOption(argv[i]) ||
+ ProcessPackagesOption(argv[i]) ||
ProcessEnvironmentOption(argv[i])) {
i += 1;
continue;
@@ -312,6 +333,14 @@
*script_name = NULL;
}
+ // Verify consistency of arguments.
+ if ((commandline_package_root != NULL) &&
+ (commandline_packages_file != NULL)) {
+ Log::PrintErr("Specifying both a packages directory and a packages "
+ "file is invalid.\n");
+ return -1;
+ }
+
if (vm_isolate_snapshot_filename == NULL) {
Log::PrintErr("No vm isolate snapshot output file specified.\n\n");
return -1;
@@ -452,7 +481,7 @@
// Run DartUtils::ResolveUri in context of uri resolver isolate.
Dart_Handle result = DartUtils::ResolveUri(
- DartUtils::NewString(library_uri), DartUtils::NewString(uri));
+ DartUtils::NewString(library_uri), DartUtils::NewString(uri));
if (Dart_IsError(result)) {
failed = true;
result_string = strdup(Dart_GetError(result));
@@ -468,6 +497,7 @@
}
+
static Builtin::BuiltinLibraryId BuiltinId(const char* url) {
if (DartUtils::IsDartBuiltinLibURL(url)) {
return Builtin::kBuiltinLibrary;
@@ -645,6 +675,8 @@
" --package_root=<path> Where to find packages, that is, \n"
" package:... imports. \n"
" \n"
+" --packages=<packages_file> Where to find a package spec file \n"
+" \n"
" --url_mapping=<mapping> Uses the URL mapping(s) specified on \n"
" the command line to load the \n"
" libraries. \n"
@@ -1285,7 +1317,8 @@
CHECK_RESULT(result);
// Setup package root if specified.
- result = DartUtils::SetupPackageRoot(package_root, NULL);
+ result = DartUtils::SetupPackageRoot(commandline_package_root,
+ commandline_packages_file);
CHECK_RESULT(result);
Dart_ExitScope();
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index 6532fbc..a5e8bfb 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -14,6 +14,7 @@
// Forward declaration.
class EventHandler;
+class Loader;
// Data associated with every isolate in the standalone VM
// embedding. This is used to free external resources for each isolate
@@ -27,7 +28,8 @@
package_root(NULL),
packages_file(NULL),
udp_receive_buffer(NULL),
- builtin_lib_(NULL) {
+ builtin_lib_(NULL),
+ loader_(NULL) {
if (package_root != NULL) {
ASSERT(packages_file == NULL);
this->package_root = strdup(package_root);
@@ -67,8 +69,20 @@
char* packages_file;
uint8_t* udp_receive_buffer;
+ // While loading a loader is associated with the isolate.
+ bool HasLoader() const { return loader_ != NULL; }
+ Loader* loader() const {
+ ASSERT(loader_ != NULL);
+ return loader_;
+ }
+ void set_loader(Loader* loader) {
+ ASSERT((loader_ == NULL) || (loader == NULL));
+ loader_ = loader;
+ }
+
private:
Dart_Handle builtin_lib_;
+ Loader* loader_;
DISALLOW_COPY_AND_ASSIGN(IsolateData);
};
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
new file mode 100644
index 0000000..f43cf30
--- /dev/null
+++ b/runtime/bin/loader.cc
@@ -0,0 +1,585 @@
+// 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 "bin/loader.h"
+
+#include "bin/builtin.h"
+#include "bin/dartutils.h"
+#include "bin/extensions.h"
+#include "bin/lockers.h"
+#include "bin/utils.h"
+
+namespace dart {
+namespace bin {
+
+// Development flag.
+static bool trace_loader = false;
+
+Loader::Loader(IsolateData* isolate_data)
+ : port_(ILLEGAL_PORT),
+ isolate_data_(isolate_data),
+ error_(Dart_Null()),
+ monitor_(NULL),
+ pending_operations_(0),
+ results_(NULL),
+ results_length_(0),
+ results_capacity_(0) {
+ monitor_ = new Monitor();
+ ASSERT(isolate_data_ != NULL);
+ port_ = Dart_NewNativePort("Loader",
+ Loader::NativeMessageHandler,
+ false);
+ isolate_data_->set_loader(this);
+ AddLoader(port_, isolate_data_);
+}
+
+
+Loader::~Loader() {
+ ASSERT(port_ != ILLEGAL_PORT);
+ // Enter the monitor while we close the Dart port. After the Dart port is
+ // closed, no more results can be queued.
+ monitor_->Enter();
+ Dart_CloseNativePort(port_);
+ monitor_->Exit();
+ RemoveLoader(port_);
+ port_ = ILLEGAL_PORT;
+ isolate_data_->set_loader(NULL);
+ isolate_data_ = NULL;
+ delete monitor_;
+ monitor_ = NULL;
+ for (intptr_t i = 0; i < results_length_; i++) {
+ results_[i].Cleanup();
+ }
+ free(results_);
+ results_ = NULL;
+}
+
+
+// Copy the contents of |message| into an |IOResult|.
+void Loader::IOResult::Setup(Dart_CObject* message) {
+ ASSERT(message->type == Dart_CObject_kArray);
+ ASSERT(message->value.as_array.length == 4);
+ Dart_CObject* tag_message = message->value.as_array.values[0];
+ ASSERT(tag_message != NULL);
+ Dart_CObject* uri_message = message->value.as_array.values[1];
+ ASSERT(uri_message != NULL);
+ Dart_CObject* library_uri_message = message->value.as_array.values[2];
+ ASSERT(library_uri_message != NULL);
+ Dart_CObject* payload_message = message->value.as_array.values[3];
+ ASSERT(payload_message != NULL);
+
+ // Grab the tag.
+ ASSERT(tag_message->type == Dart_CObject_kInt32);
+ tag = tag_message->value.as_int32;
+
+ // Grab the uri id.
+ ASSERT(uri_message->type == Dart_CObject_kString);
+ uri = strdup(uri_message->value.as_string);
+
+ // Grab the library uri if one is present.
+ if (library_uri_message->type != Dart_CObject_kNull) {
+ ASSERT(library_uri_message->type == Dart_CObject_kString);
+ library_uri = strdup(library_uri_message->value.as_string);
+ } else {
+ library_uri = NULL;
+ }
+
+ // Grab the payload.
+ if (payload_message->type == Dart_CObject_kString) {
+ // Payload is an error message.
+ payload_length = strlen(payload_message->value.as_string);
+ payload =
+ reinterpret_cast<uint8_t*>(strdup(payload_message->value.as_string));
+ } else {
+ // Payload is the contents of a file.
+ ASSERT(payload_message->type == Dart_CObject_kTypedData);
+ ASSERT(payload_message->value.as_typed_data.type == Dart_TypedData_kUint8);
+ payload_length = payload_message->value.as_typed_data.length;
+ payload = reinterpret_cast<uint8_t*>(malloc(payload_length));
+ memmove(payload,
+ payload_message->value.as_typed_data.values,
+ payload_length);
+ }
+}
+
+
+void Loader::IOResult::Cleanup() {
+ free(uri);
+ free(library_uri);
+ free(payload);
+}
+
+
+// Send the Loader Initialization message to the service isolate. This
+// message is sent the first time a loader is constructed for an isolate and
+// seeds the service isolate with some initial state about this isolate.
+void Loader::Init(const char* package_root,
+ const char* packages_file,
+ const char* working_directory,
+ const char* root_script_uri) {
+ // This port delivers loading messages to the service isolate.
+ Dart_Port loader_port = Builtin::LoadPort();
+ ASSERT(loader_port != ILLEGAL_PORT);
+
+ // Keep in sync with loader.dart.
+ const intptr_t _Dart_kInitLoader = 4;
+
+ Dart_Handle request = Dart_NewList(8);
+ Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False());
+ Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId()));
+ Dart_ListSetAt(request, 2, Dart_NewInteger(_Dart_kInitLoader));
+ Dart_ListSetAt(request, 3, Dart_NewSendPort(port_));
+ Dart_ListSetAt(request, 4,
+ (package_root == NULL) ? Dart_Null() :
+ Dart_NewStringFromCString(package_root));
+ Dart_ListSetAt(request, 5,
+ (packages_file == NULL) ? Dart_Null() :
+ Dart_NewStringFromCString(packages_file));
+ Dart_ListSetAt(request, 6,
+ Dart_NewStringFromCString(working_directory));
+ Dart_ListSetAt(request, 7,
+ (root_script_uri == NULL) ? Dart_Null() :
+ Dart_NewStringFromCString(root_script_uri));
+
+ bool success = Dart_Post(loader_port, request);
+ ASSERT(success);
+}
+
+
+// Forward a request from the tag handler to the service isolate.
+void Loader::SendRequest(Dart_LibraryTag tag,
+ Dart_Handle url,
+ Dart_Handle library_url) {
+ // This port delivers loading messages to the service isolate.
+ Dart_Port loader_port = Builtin::LoadPort();
+ ASSERT(loader_port != ILLEGAL_PORT);
+
+ Dart_Handle request = Dart_NewList(6);
+ Dart_ListSetAt(request, 0, trace_loader ? Dart_True() : Dart_False());
+ Dart_ListSetAt(request, 1, Dart_NewInteger(Dart_GetMainPortId()));
+ Dart_ListSetAt(request, 2, Dart_NewInteger(tag));
+ Dart_ListSetAt(request, 3, Dart_NewSendPort(port_));
+
+ Dart_ListSetAt(request, 4, url);
+ Dart_ListSetAt(request, 5, library_url);
+
+ if (Dart_Post(loader_port, request)) {
+ MonitorLocker ml(monitor_);
+ pending_operations_++;
+ }
+}
+
+
+void Loader::QueueMessage(Dart_CObject* message) {
+ MonitorLocker ml(monitor_);
+ if (results_length_ == results_capacity_) {
+ // Grow to an initial capacity or double in size.
+ results_capacity_ = (results_capacity_ == 0) ? 4 : results_capacity_ * 2;
+ results_ =
+ reinterpret_cast<IOResult*>(
+ realloc(results_,
+ sizeof(IOResult) * results_capacity_));
+ ASSERT(results_ != NULL);
+ }
+ ASSERT(results_ != NULL);
+ ASSERT(results_length_ < results_capacity_);
+ results_[results_length_].Setup(message);
+ results_length_++;
+ ml.Notify();
+}
+
+
+void Loader::BlockUntilComplete() {
+ MonitorLocker ml(monitor_);
+
+ while (true) {
+ // If |ProcessQueueLocked| returns false, we've hit an error and should
+ // stop loading.
+ if (!ProcessQueueLocked()) {
+ break;
+ }
+
+ // When |pending_operations_| hits 0, we are done loading.
+ if (pending_operations_ == 0) {
+ break;
+ }
+
+ // Wait to be notified about new I/O results.
+ ml.Wait();
+ }
+}
+
+
+bool Loader::ProcessResultLocked(Loader::IOResult* result) {
+ // A negative result tag indicates a loading error occurred in the service
+ // isolate. The payload is a C string of the error message.
+ if (result->tag < 0) {
+ error_ =
+ Dart_NewUnhandledExceptionError(
+ Dart_NewStringFromUTF8(result->payload,
+ result->payload_length));
+
+ return false;
+ }
+
+ // We have to copy everything we care about out of |result| because after
+ // dropping the lock below |result| may no longer valid.
+ Dart_Handle uri =
+ Dart_NewStringFromCString(reinterpret_cast<char*>(result->uri));
+ Dart_Handle library_uri = Dart_Null();
+ if (result->library_uri != NULL) {
+ library_uri =
+ Dart_NewStringFromCString(reinterpret_cast<char*>(result->library_uri));
+ }
+ // Check for payload and load accordingly.
+ bool is_snapshot = false;
+ const uint8_t* payload = result->payload;
+ intptr_t payload_length = result->payload_length;
+ payload =
+ DartUtils::SniffForMagicNumber(payload,
+ &payload_length,
+ &is_snapshot);
+ Dart_Handle source = Dart_Null();
+ if (!is_snapshot) {
+ source = Dart_NewStringFromUTF8(result->payload,
+ result->payload_length);
+ if (Dart_IsError(source)) {
+ error_ = DartUtils::NewError("%s is not a valid UTF-8 script",
+ reinterpret_cast<char*>(result->uri));
+ return false;
+ }
+ }
+ intptr_t tag = result->tag;
+
+ // No touching.
+ result = NULL;
+
+ // We must drop the lock here because the tag handler may be recursively
+ // invoked and it will attempt to acquire the lock to queue more work.
+ monitor_->Exit();
+
+ Dart_Handle dart_result = Dart_Null();
+
+ switch (tag) {
+ case Dart_kImportTag:
+ dart_result = Dart_LoadLibrary(uri, source, 0, 0);
+ break;
+ case Dart_kSourceTag: {
+ ASSERT(library_uri != Dart_Null());
+ Dart_Handle library = Dart_LookupLibrary(library_uri);
+ ASSERT(!Dart_IsError(library));
+ dart_result = Dart_LoadSource(library, uri, source, 0, 0);
+ }
+ break;
+ case Dart_kScriptTag:
+ if (is_snapshot) {
+ dart_result = Dart_LoadScriptFromSnapshot(payload, payload_length);
+ } else {
+ dart_result = Dart_LoadScript(uri, source, 0, 0);
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ // Re-acquire the lock before exiting the function (it was held before entry),
+ monitor_->Enter();
+ if (Dart_IsError(dart_result)) {
+ // Remember the error if we encountered one.
+ error_ = dart_result;
+ return false;
+ }
+
+ return true;
+}
+
+
+bool Loader::ProcessQueueLocked() {
+ bool hit_error = false;
+ for (intptr_t i = 0; i < results_length(); i++) {
+ if (!hit_error) {
+ hit_error = !ProcessResultLocked(&results_[i]);
+ }
+ pending_operations_--;
+ ASSERT(hit_error || (pending_operations_ >= 0));
+ results_[i].Cleanup();
+ }
+ results_length_ = 0;
+ return !hit_error;
+}
+
+
+static bool IsWindowsHost() {
+#if defined(TARGET_OS_WINDOWS)
+ return true;
+#else // defined(TARGET_OS_WINDOWS)
+ return false;
+#endif // defined(TARGET_OS_WINDOWS)
+}
+
+
+void Loader::InitForSnapshot(const char* snapshot_uri) {
+ IsolateData* isolate_data =
+ reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData());
+ ASSERT(isolate_data != NULL);
+ ASSERT(!isolate_data->HasLoader());
+ // Setup a loader. The constructor does a bunch of leg work.
+ Loader* loader = new Loader(isolate_data);
+ // Send the init message.
+ loader->Init(isolate_data->package_root,
+ isolate_data->packages_file,
+ DartUtils::original_working_directory,
+ snapshot_uri);
+ // Destroy the loader. The destructor does a bunch of leg work.
+ delete loader;
+}
+
+
+Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
+ Dart_Handle library,
+ Dart_Handle url) {
+ if (tag == Dart_kCanonicalizeUrl) {
+ return Dart_DefaultCanonicalizeUrl(library, url);
+ }
+ const char* url_string = NULL;
+ Dart_Handle result = Dart_StringToCString(url, &url_string);
+ if (Dart_IsError(result)) {
+ return result;
+ }
+
+ // Special case for handling dart: imports and parts.
+ if (tag != Dart_kScriptTag) {
+ // Grab the library's url.
+ Dart_Handle library_url = Dart_LibraryUrl(library);
+ const char* library_url_string = NULL;
+ result = Dart_StringToCString(library_url, &library_url_string);
+ if (Dart_IsError(result)) {
+ return result;
+ }
+
+ bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_string);
+ bool is_dart_library = DartUtils::IsDartSchemeURL(library_url_string);
+
+ if (is_dart_scheme_url || is_dart_library) {
+ return DartColonLibraryTagHandler(tag,
+ library,
+ url,
+ library_url_string,
+ url_string);
+ }
+ }
+
+ if (DartUtils::IsDartExtensionSchemeURL(url_string)) {
+ // Load a native code shared library to use in a native extension
+ if (tag != Dart_kImportTag) {
+ return DartUtils::NewError("Dart extensions must use import: '%s'",
+ url_string);
+ }
+ Dart_Handle library_url = Dart_LibraryUrl(library);
+ Dart_Handle library_file_path = DartUtils::LibraryFilePath(library_url);
+ const char* lib_path_str = NULL;
+ Dart_StringToCString(library_file_path, &lib_path_str);
+ const char* extension_path = DartUtils::RemoveScheme(url_string);
+ if (strchr(extension_path, '/') != NULL ||
+ (IsWindowsHost() && strchr(extension_path, '\\') != NULL)) {
+ return DartUtils::NewError(
+ "Relative paths for dart extensions are not supported: '%s'",
+ extension_path);
+ }
+ return Extensions::LoadExtension(lib_path_str,
+ extension_path,
+ library);
+ }
+
+ IsolateData* isolate_data =
+ reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData());
+ ASSERT(isolate_data != NULL);
+
+ // Grab this isolate's loader.
+ Loader* loader = NULL;
+
+ // The outer invocation of the tag handler for this isolate. We make the outer
+ // invocation block and allow any nested invocations to operate in parallel.
+ bool blocking_call = !isolate_data->HasLoader();
+
+ if (!isolate_data->HasLoader()) {
+ // The isolate doesn't have a loader -- this is the outer invocation which
+ // will block.
+
+ // Setup the loader. The constructor does a bunch of leg work.
+ loader = new Loader(isolate_data);
+ loader->Init(isolate_data->package_root,
+ isolate_data->packages_file,
+ DartUtils::original_working_directory,
+ (tag == Dart_kScriptTag) ? url_string : NULL);
+ } else {
+ ASSERT(tag != Dart_kScriptTag);
+ // The isolate has a loader -- this is an inner invocation that will queue
+ // work with the service isolate.
+ // Use the existing loader.
+ loader = isolate_data->loader();
+ }
+ ASSERT(loader != NULL);
+ ASSERT(isolate_data->HasLoader());
+
+ loader->SendRequest(tag,
+ url,
+ (library != Dart_Null()) ?
+ Dart_LibraryUrl(library) : Dart_Null());
+
+ if (blocking_call) {
+ // The outer invocation of the tag handler will block here until all nested
+ // invocations complete.
+ loader->BlockUntilComplete();
+
+ // Remember the error (if any).
+ Dart_Handle error = loader->error();
+ // Destroy the loader. The destructor does a bunch of leg work.
+ delete loader;
+
+ // An error occurred during loading.
+ if (Dart_IsError(error)) {
+ return error;
+ }
+
+ // Finalize loading. This will complete any futures for completed deferred
+ // loads.
+ error = Dart_FinalizeLoading(true);
+ if (Dart_IsError(error)) {
+ return error;
+ }
+ }
+ return Dart_Null();
+}
+
+
+Dart_Handle Loader::DartColonLibraryTagHandler(Dart_LibraryTag tag,
+ Dart_Handle library,
+ Dart_Handle url,
+ const char* library_url_string,
+ const char* url_string) {
+ // Handle canonicalization, 'import' and 'part' of 'dart:' libraries.
+ if (tag == Dart_kCanonicalizeUrl) {
+ // These will be handled internally.
+ return url;
+ } else if (tag == Dart_kImportTag) {
+ Builtin::BuiltinLibraryId id = Builtin::FindId(url_string);
+ if (id == Builtin::kInvalidLibrary) {
+ return DartUtils::NewError("The built-in library '%s' is not available"
+ " on the stand-alone VM.\n", url_string);
+ }
+ return Builtin::LoadLibrary(url, id);
+ } else {
+ ASSERT(tag == Dart_kSourceTag);
+ Builtin::BuiltinLibraryId id = Builtin::FindId(library_url_string);
+ if (id == Builtin::kInvalidLibrary) {
+ return DartUtils::NewError("The built-in library '%s' is not available"
+ " on the stand-alone VM. Trying to load"
+ " '%s'.\n", library_url_string, url_string);
+ }
+ // Prepend the library URI to form a unique script URI for the part.
+ intptr_t len = snprintf(NULL, 0, "%s/%s", library_url_string, url_string);
+ char* part_uri = reinterpret_cast<char*>(malloc(len + 1));
+ snprintf(part_uri, len + 1, "%s/%s", library_url_string, url_string);
+ Dart_Handle part_uri_obj = DartUtils::NewString(part_uri);
+ free(part_uri);
+ return Dart_LoadSource(library,
+ part_uri_obj,
+ Builtin::PartSource(id, url_string), 0, 0);
+ }
+ // All cases should have been handled above.
+ UNREACHABLE();
+}
+
+
+Mutex Loader::loader_infos_lock_;
+Loader::LoaderInfo* Loader::loader_infos_ = NULL;
+intptr_t Loader::loader_infos_length_ = 0;
+intptr_t Loader::loader_infos_capacity_ = 0;
+
+
+// Add a mapping from |port| to |isolate_data| (really the loader). When a
+// native message arrives, we use this map to report the I/O result to the
+// correct loader.
+// This happens whenever an isolate begins loading.
+void Loader::AddLoader(Dart_Port port, IsolateData* isolate_data) {
+ MutexLocker ml(&loader_infos_lock_);
+ ASSERT(LoaderForLocked(port) == NULL);
+ if (loader_infos_length_ == loader_infos_capacity_) {
+ // Grow to an initial capacity or double in size.
+ loader_infos_capacity_ =
+ (loader_infos_capacity_ == 0) ? 4 : loader_infos_capacity_ * 2;
+ loader_infos_ =
+ reinterpret_cast<Loader::LoaderInfo*>(
+ realloc(loader_infos_,
+ sizeof(Loader::LoaderInfo) * loader_infos_capacity_));
+ ASSERT(loader_infos_ != NULL);
+ // Initialize new entries.
+ for (intptr_t i = loader_infos_length_; i < loader_infos_capacity_; i++) {
+ loader_infos_[i].port = ILLEGAL_PORT;
+ loader_infos_[i].isolate_data = NULL;
+ }
+ }
+ ASSERT(loader_infos_length_ < loader_infos_capacity_);
+ loader_infos_[loader_infos_length_].port = port;
+ loader_infos_[loader_infos_length_].isolate_data = isolate_data;
+ loader_infos_length_++;
+ ASSERT(LoaderForLocked(port) != NULL);
+}
+
+
+// Remove |port| from the map.
+// This happens once an isolate has finished loading.
+void Loader::RemoveLoader(Dart_Port port) {
+ MutexLocker ml(&loader_infos_lock_);
+ const intptr_t index = LoaderIndexFor(port);
+ ASSERT(index >= 0);
+ const intptr_t last = loader_infos_length_ - 1;
+ ASSERT(last >= 0);
+ if (index != last) {
+ // Swap with the tail.
+ loader_infos_[index] = loader_infos_[last];
+ }
+ loader_infos_length_--;
+}
+
+
+intptr_t Loader::LoaderIndexFor(Dart_Port port) {
+ for (intptr_t i = 0; i < loader_infos_length_; i++) {
+ if (loader_infos_[i].port == port) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+Loader* Loader::LoaderForLocked(Dart_Port port) {
+ intptr_t index = LoaderIndexFor(port);
+ if (index < 0) {
+ return NULL;
+ }
+ return loader_infos_[index].isolate_data->loader();
+}
+
+
+Loader* Loader::LoaderFor(Dart_Port port) {
+ MutexLocker ml(&loader_infos_lock_);
+ return LoaderForLocked(port);
+}
+
+
+void Loader::NativeMessageHandler(Dart_Port dest_port_id,
+ Dart_CObject* message) {
+ MutexLocker ml(&loader_infos_lock_);
+ Loader* loader = LoaderForLocked(dest_port_id);
+ if (loader == NULL) {
+ return;
+ }
+ loader->QueueMessage(message);
+}
+
+} // namespace bin
+} // namespace dart
diff --git a/runtime/bin/loader.h b/runtime/bin/loader.h
new file mode 100644
index 0000000..bab237b
--- /dev/null
+++ b/runtime/bin/loader.h
@@ -0,0 +1,131 @@
+// 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.
+
+#ifndef BIN_LOADER_H_
+#define BIN_LOADER_H_
+
+#include "bin/isolate_data.h"
+#include "include/dart_api.h"
+#include "include/dart_native_api.h"
+#include "platform/assert.h"
+#include "platform/globals.h"
+#include "bin/thread.h"
+
+namespace dart {
+namespace bin {
+
+class Loader {
+ public:
+ explicit Loader(IsolateData* isolate_data);
+ ~Loader();
+
+ static void InitForSnapshot(const char* snapshot_uri);
+
+ // A static tag handler that hides all usage of a loader for an isolate.
+ static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
+ Dart_Handle library,
+ Dart_Handle url);
+
+ Dart_Handle error() const {
+ return error_;
+ }
+
+ private:
+ // The port assigned to our native message handler.
+ Dart_Port port_;
+ // Each Loader is associated with an Isolate via its IsolateData.
+ IsolateData* isolate_data_;
+ // Remember the first error that occurs during loading.
+ Dart_Handle error_;
+
+ // This monitor is used to protect the pending operations count and the
+ // I/O result queue.
+ Monitor* monitor_;
+
+ // The number of operations dispatched to the service isolate for loading.
+ // Must be accessed with monitor_ held.
+ intptr_t pending_operations_;
+
+ // The result of an I/O request to the service isolate. Payload is either
+ // a UInt8Array or a C string containing an error message.
+ struct IOResult {
+ uint8_t* payload;
+ intptr_t payload_length;
+ char* library_uri;
+ char* uri;
+ int8_t tag;
+
+ void Setup(Dart_CObject* message);
+ void Cleanup();
+ };
+ // An array of I/O results queued from the service isolate.
+ IOResult* results_;
+ intptr_t results_length_;
+ intptr_t results_capacity_;
+
+ intptr_t results_length() {
+ return *static_cast<volatile intptr_t*>(&results_length_);
+ }
+
+ // Send the loader init request to the service isolate.
+ void Init(const char* package_root,
+ const char* packages_file,
+ const char* working_directory,
+ const char* root_script_uri);
+
+ // Send a request from the tag handler to the service isolate.
+ void SendRequest(Dart_LibraryTag tag,
+ Dart_Handle url,
+ Dart_Handle library_url);
+
+ /// Queue |message| and notify the loader that a message is available.
+ void QueueMessage(Dart_CObject* message);
+
+ /// Blocks the caller until the loader is finished.
+ void BlockUntilComplete();
+
+ /// Returns false if |result| is an error and the loader should quit.
+ bool ProcessResultLocked(IOResult* result);
+
+ /// Returns false if an error occurred and the loader should quit.
+ bool ProcessQueueLocked();
+
+ // Special inner tag handler for dart: uris.
+ static Dart_Handle DartColonLibraryTagHandler(Dart_LibraryTag tag,
+ Dart_Handle library,
+ Dart_Handle url,
+ const char* library_url_string,
+ const char* url_string);
+
+ // We use one native message handler callback for N loaders. The native
+ // message handler callback provides us with the Dart_Port which we use as a
+ // key into our map of active loaders from |port| to |isolate_data|.
+
+ // Static information to map Dart_Port back to the isolate in question.
+ struct LoaderInfo {
+ Dart_Port port;
+ IsolateData* isolate_data;
+ };
+
+ // The map of active loaders.
+ static Mutex loader_infos_lock_;
+ static LoaderInfo* loader_infos_;
+ static intptr_t loader_infos_length_;
+ static intptr_t loader_infos_capacity_;
+
+ static void AddLoader(Dart_Port port, IsolateData* data);
+ static void RemoveLoader(Dart_Port port);
+ static intptr_t LoaderIndexFor(Dart_Port port);
+ static Loader* LoaderFor(Dart_Port port);
+ static Loader* LoaderForLocked(Dart_Port port);
+
+ // This is the global callback for the native message handlers.
+ static void NativeMessageHandler(Dart_Port dest_port_id,
+ Dart_CObject* message);
+};
+
+} // namespace bin
+} // namespace dart
+
+#endif // BIN_LOADER_H_
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 8823eda..6c8ca4b 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -17,6 +17,7 @@
#include "bin/extensions.h"
#include "bin/file.h"
#include "bin/isolate_data.h"
+#include "bin/loader.h"
#include "bin/log.h"
#include "bin/platform.h"
#include "bin/process.h"
@@ -690,7 +691,7 @@
int* exit_code) {
ASSERT(script_uri != NULL);
- const bool needs_load_port = !run_app_snapshot;
+ const bool needs_load_port = true;
#if defined(PRODUCT)
const bool run_service_isolate = needs_load_port;
#else
@@ -726,7 +727,7 @@
}
// Set up the library tag handler for this isolate.
- Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
+ Dart_Handle result = Dart_SetLibraryTagHandler(Loader::LibraryTagHandler);
CHECK_RESULT(result);
if (Dart_IsServiceIsolate(isolate)) {
@@ -770,13 +771,15 @@
if (run_app_snapshot) {
result = DartUtils::SetupIOLibrary(script_uri);
CHECK_RESULT(result);
+ Loader::InitForSnapshot(script_uri);
} else {
// Load the specified application script into the newly created isolate.
- result = DartUtils::LoadScript(script_uri);
- CHECK_RESULT(result);
-
- // Run event-loop and wait for script loading to complete.
- result = Dart_RunLoop();
+ Dart_Handle uri =
+ DartUtils::ResolveScript(Dart_NewStringFromCString(script_uri));
+ CHECK_RESULT(uri);
+ result = Loader::LibraryTagHandler(Dart_kScriptTag,
+ Dart_Null(),
+ uri);
CHECK_RESULT(result);
Dart_TimelineEvent("LoadScript",
@@ -932,9 +935,11 @@
}
-static const char* ServiceRequestError(Dart_Handle error) {
+static const char* InternalJsonRpcError(Dart_Handle error) {
TextBuffer buffer(128);
- buffer.Printf("{\"type\":\"Error\",\"text\":\"Internal error %s\"}",
+ buffer.Printf("{\"code\":-32603,"
+ "\"message\":\"Internal error\","
+ "\"details\": \"%s\"}",
Dart_GetError(error));
return buffer.Steal();
}
@@ -947,28 +952,32 @@
};
-static const char* ServiceGetIOHandler(
+static bool ServiceGetIOHandler(
const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
- void* user_data) {
+ void* user_data,
+ const char** response) {
DartScope scope;
// TODO(ajohnsen): Store the library/function in isolate data or user_data.
Dart_Handle dart_io_str = Dart_NewStringFromCString("dart:io");
if (Dart_IsError(dart_io_str)) {
- return ServiceRequestError(dart_io_str);
+ *response = InternalJsonRpcError(dart_io_str);
+ return false;
}
Dart_Handle io_lib = Dart_LookupLibrary(dart_io_str);
if (Dart_IsError(io_lib)) {
- return ServiceRequestError(io_lib);
+ *response = InternalJsonRpcError(io_lib);
+ return false;
}
Dart_Handle handler_function_name =
Dart_NewStringFromCString("_serviceObjectHandler");
if (Dart_IsError(handler_function_name)) {
- return ServiceRequestError(handler_function_name);
+ *response = InternalJsonRpcError(handler_function_name);
+ return false;
}
// TODO(johnmccutchan): paths is no longer used. Update the io
@@ -983,15 +992,18 @@
Dart_Handle args[] = {paths, keys, values};
Dart_Handle result = Dart_Invoke(io_lib, handler_function_name, 3, args);
if (Dart_IsError(result)) {
- return ServiceRequestError(result);
+ *response = InternalJsonRpcError(result);
+ return false;
}
const char *json;
result = Dart_StringToCString(result, &json);
if (Dart_IsError(result)) {
- return ServiceRequestError(result);
+ *response = InternalJsonRpcError(result);
+ return false;
}
- return strdup(json);
+ *response = strdup(json);
+ return true;
}
@@ -1359,7 +1371,6 @@
reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
result = Dart_LibraryImportLibrary(
isolate_data->builtin_lib(), root_lib, Dart_Null());
-#if !defined(PRODUCT)
if (is_noopt ||
(gen_snapshot_kind == kAppAfterRun) ||
(gen_snapshot_kind == kAppAOT) ||
@@ -1374,7 +1385,6 @@
exit(kErrorExitCode);
}
}
-#endif // PRODUCT
if (compile_all) {
result = Dart_CompileAll();
@@ -1386,11 +1396,11 @@
{ "dart:_builtin", "::", "_getMainClosure" },
{ "dart:_builtin", "::", "_getPrintClosure" },
{ "dart:_builtin", "::", "_getUriBaseClosure" },
+ { "dart:_builtin", "::", "_resolveInWorkingDirectory" },
{ "dart:_builtin", "::", "_resolveUri" },
{ "dart:_builtin", "::", "_setWorkingDirectory" },
{ "dart:_builtin", "::", "_setPackageRoot" },
- { "dart:_builtin", "::", "_loadPackagesMap" },
- { "dart:_builtin", "::", "_loadDataAsync" },
+ { "dart:_builtin", "::", "_libraryFilePath" },
{ "dart:io", "::", "_makeUint8ListView" },
{ "dart:io", "::", "_makeDatagram" },
{ "dart:io", "::", "_setupHooks" },
@@ -1410,9 +1420,7 @@
{ "dart:io", "_ProcessStartStatus", "set:_errorMessage" },
{ "dart:io", "_SecureFilterImpl", "get:ENCRYPTED_SIZE" },
{ "dart:io", "_SecureFilterImpl", "get:SIZE" },
-#if !defined(PRODUCT)
{ "dart:vmservice_io", "::", "main" },
-#endif // !PRODUCT
{ NULL, NULL, NULL } // Must be terminated with NULL entries.
};
diff --git a/runtime/bin/vmservice/loader.dart b/runtime/bin/vmservice/loader.dart
index 7bec4a1..42bc6f9 100644
--- a/runtime/bin/vmservice/loader.dart
+++ b/runtime/bin/vmservice/loader.dart
@@ -4,6 +4,303 @@
part of vmservice_io;
+_sanitizeWindowsPath(path) {
+ // For Windows we need to massage the paths a bit according to
+ // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
+ //
+ // Convert
+ // C:\one\two\three
+ // to
+ // /C:/one/two/three
+
+ if (_isWindows == false) {
+ // Do nothing when not running Windows.
+ return path;
+ }
+
+ var fixedPath = "${path.replaceAll('\\', '/')}";
+
+ if ((path.length > 2) && (path[1] == ':')) {
+ // Path begins with a drive letter.
+ return '/$fixedPath';
+ }
+
+ return fixedPath;
+}
+
+_trimWindowsPath(path) {
+ // Convert /X:/ to X:/.
+ if (_isWindows == false) {
+ // Do nothing when not running Windows.
+ return path;
+ }
+ if (!path.startsWith('/') || (path.length < 3)) {
+ return path;
+ }
+ // Match '/?:'.
+ if ((path[0] == '/') && (path[2] == ':')) {
+ // Remove leading '/'.
+ return path.substring(1);
+ }
+ return path;
+}
+
+// Ensure we have a trailing slash character.
+_enforceTrailingSlash(uri) {
+ if (!uri.endsWith('/')) {
+ return '$uri/';
+ }
+ return uri;
+}
+
+// State associated with the isolate that is used for loading.
+class IsolateLoaderState extends IsolateEmbedderData {
+ IsolateLoaderState(this.isolateId);
+
+ final int isolateId;
+
+ SendPort sp;
+
+ void init(String packageRootFlag,
+ String packagesConfigFlag,
+ String workingDirectory,
+ String rootScript) {
+ // _workingDirectory must be set first.
+ _workingDirectory = new Uri.directory(workingDirectory);
+ if (rootScript != null) {
+ _rootScript = Uri.parse(rootScript);
+ }
+ // If the --package-root flag was passed.
+ if (packageRootFlag != null) {
+ _setPackageRoot(packageRootFlag);
+ }
+ // If the --packages flag was passed.
+ if (packagesConfigFlag != null) {
+ _setPackagesConfig(packagesConfigFlag);
+ }
+ }
+
+ void cleanup() {
+ if (_packagesPort != null) {
+ _packagesPort.close();
+ _packagesPort = null;
+ }
+ }
+
+ // The working directory when the embedder started.
+ Uri _workingDirectory;
+
+ // The root script's uri.
+ Uri _rootScript;
+
+ bool _traceLoading = false;
+
+ // Packages are either resolved looking up in a map or resolved from within a
+ // package root.
+ bool get _packagesReady => (_packageRoot != null) ||
+ (_packageMap != null) ||
+ (_packageError != null);
+
+ // Error string set if there was an error resolving package configuration.
+ // For example not finding a .packages file or packages/ directory, malformed
+ // .packages file or any other related error.
+ String _packageError = null;
+
+ // The directory to look in to resolve "package:" scheme URIs. By default it
+ // is the 'packages' directory right next to the script.
+ Uri _packageRoot = null;
+
+ // The map describing how certain package names are mapped to Uris.
+ Uri _packageConfig = null;
+ Map<String, Uri> _packageMap = null;
+
+ _setPackageRoot(String packageRoot) {
+ packageRoot = _enforceTrailingSlash(packageRoot);
+ if (packageRoot.startsWith('file:') ||
+ packageRoot.startsWith('http:') ||
+ packageRoot.startsWith('https:')) {
+ _packageRoot = _workingDirectory.resolve(packageRoot);
+ } else {
+ packageRoot = _sanitizeWindowsPath(packageRoot);
+ packageRoot = _trimWindowsPath(packageRoot);
+ _packageRoot = _workingDirectory.resolveUri(new Uri.file(packageRoot));
+ }
+ }
+
+ _setPackagesConfig(String packagesParam) {
+ var packagesName = _sanitizeWindowsPath(packagesParam);
+ var packagesUri = Uri.parse(packagesName);
+ if (packagesUri.scheme == '') {
+ // Script does not have a scheme, assume that it is a path,
+ // resolve it against the working directory.
+ packagesUri = _workingDirectory.resolveUri(packagesUri);
+ }
+ _requestPackagesMap(packagesUri);
+ _pendingPackageLoads.add(() {
+ // Dummy action.
+ });
+ }
+
+ // Handling of access to the package root or package map from user code.
+ _triggerPackageResolution(action) {
+ if (_packagesReady) {
+ // Packages are ready. Execute the action now.
+ action();
+ } else {
+ if (_pendingPackageLoads.isEmpty) {
+ // Package resolution has not been setup yet, and this is the first
+ // request for package resolution & loading.
+ _requestPackagesMap();
+ }
+ // Register the action for when the package resolution is ready.
+ _pendingPackageLoads.add(action);
+ }
+ }
+
+ // A list of callbacks which should be invoked after the package map has been
+ // loaded.
+ List<Function> _pendingPackageLoads = [];
+
+ // Given a uri with a 'package' scheme, return a Uri that is prefixed with
+ // the package root.
+ Uri _resolvePackageUri(Uri uri) {
+ assert(uri.scheme == "package");
+ assert(_packagesReady);
+
+ if (!uri.host.isEmpty) {
+ var path = '${uri.host}${uri.path}';
+ var right = 'package:$path';
+ var wrong = 'package://$path';
+
+ throw "URIs using the 'package:' scheme should look like "
+ "'$right', not '$wrong'.";
+ }
+
+ if (_traceLoading) {
+ _log('Resolving package with uri path: ${uri.path}');
+ }
+ var resolvedUri;
+ if (_packageError != null) {
+ if (_traceLoading) {
+ _log("Resolving package with pending resolution error: $_packageError");
+ }
+ throw _packageError;
+ } else if (_packageRoot != null) {
+ resolvedUri = _packageRoot.resolve(uri.path);
+ } else {
+ var packageName = uri.pathSegments[0];
+ var mapping = _packageMap[packageName];
+ if (_traceLoading) {
+ _log("Mapped '$packageName' package to '$mapping'");
+ }
+ if (mapping == null) {
+ throw "No mapping for '$packageName' package when resolving '$uri'.";
+ }
+ var path;
+ if (uri.path.length > packageName.length) {
+ path = uri.path.substring(packageName.length + 1);
+ } else {
+ // Handle naked package resolution to the default package name:
+ // package:foo is equivalent to package:foo/foo.dart
+ assert(uri.path.length == packageName.length);
+ path = "$packageName.dart";
+ }
+ if (_traceLoading) {
+ _log("Path to be resolved in package: $path");
+ }
+ resolvedUri = mapping.resolve(path);
+ }
+ if (_traceLoading) {
+ _log("Resolved '$uri' to '$resolvedUri'.");
+ }
+ return resolvedUri;
+ }
+
+ RawReceivePort _packagesPort;
+
+ void _requestPackagesMap([Uri packageConfig]) {
+ assert(_packagesPort == null);
+ assert(_rootScript != null);
+ // Create a port to receive the packages map on.
+ _packagesPort = new RawReceivePort(_handlePackagesReply);
+ var sp = _packagesPort.sendPort;
+
+ if (packageConfig != null) {
+ // Explicitly specified .packages path.
+ _handlePackagesRequest(sp,
+ _traceLoading,
+ -2,
+ packageConfig);
+ } else {
+ // Search for .packages or packages/ starting at the root script.
+ _handlePackagesRequest(sp,
+ _traceLoading,
+ -1,
+ _rootScript);
+ }
+
+ if (_traceLoading) {
+ _log("Requested packages map for '$_rootScript'.");
+ }
+ }
+
+ void _handlePackagesReply(msg) {
+ assert(_packagesPort != null);
+ // Make sure to close the _packagePort before any other action.
+ _packagesPort.close();
+ _packagesPort = null;
+
+ if (_traceLoading) {
+ _log("Got packages reply: $msg");
+ }
+ if (msg is String) {
+ if (_traceLoading) {
+ _log("Got failure response on package port: '$msg'");
+ }
+ // Remember the error message.
+ _packageError = msg;
+ } else if (msg is List) {
+ if (msg.length == 1) {
+ if (_traceLoading) {
+ _log("Received package root: '${msg[0]}'");
+ }
+ _packageRoot = Uri.parse(msg[0]);
+ } else {
+ // First entry contains the location of the loaded .packages file.
+ assert((msg.length % 2) == 0);
+ assert(msg.length >= 2);
+ assert(msg[1] == null);
+ _packageConfig = Uri.parse(msg[0]);
+ _packageMap = new Map<String, Uri>();
+ for (var i = 2; i < msg.length; i+=2) {
+ // TODO(iposva): Complain about duplicate entries.
+ _packageMap[msg[i]] = Uri.parse(msg[i+1]);
+ }
+ if (_traceLoading) {
+ _log("Setup package map: $_packageMap");
+ }
+ }
+ } else {
+ _packageError = "Bad type of packages reply: ${msg.runtimeType}";
+ if (_traceLoading) {
+ _log(_packageError);
+ }
+ }
+
+ // Resolve all pending package loads now that we know how to resolve them.
+ while (_pendingPackageLoads.length > 0) {
+ // Order does not matter as we queue all of the requests up right now.
+ var req = _pendingPackageLoads.removeLast();
+ // Call the registered closure, to handle the delayed action.
+ req();
+ }
+ // Reset the pending package loads to empty. So that we eventually can
+ // finish loading.
+ _pendingPackageLoads = [];
+ }
+
+}
+
_log(msg) {
print("% $msg");
}
@@ -11,19 +308,38 @@
var _httpClient;
// Send a response to the requesting isolate.
-void _sendResourceResponse(SendPort sp, int id, dynamic data) {
+void _sendResourceResponse(SendPort sp,
+ int tag,
+ Uri uri,
+ String libraryUrl,
+ dynamic data) {
assert((data is List<int>) || (data is String));
- var msg = new List(2);
- msg[0] = id;
- msg[1] = data;
+ var msg = new List(4);
+ if (data is String) {
+ // We encountered an error, flip the sign of the tag to indicate that.
+ tag = -tag;
+ if (libraryUrl == null) {
+ data = 'Could not load "$uri": $data';
+ } else {
+ data = 'Could not import "$uri" from "$libraryUrl": $data';
+ }
+ }
+ msg[0] = tag;
+ msg[1] = uri.toString();
+ msg[2] = libraryUrl;
+ msg[3] = data;
sp.send(msg);
}
-void _loadHttp(SendPort sp, int id, Uri uri) {
+void _loadHttp(SendPort sp,
+ int tag,
+ Uri uri,
+ Uri resolvedUri,
+ String libraryUrl) {
if (_httpClient == null) {
_httpClient = new HttpClient()..maxConnectionsPerHost = 6;
}
- _httpClient.getUrl(uri)
+ _httpClient.getUrl(resolvedUri)
.then((HttpClientRequest request) => request.close())
.then((HttpClientResponse response) {
var builder = new BytesBuilder(copy: false);
@@ -31,37 +347,46 @@
builder.add,
onDone: () {
if (response.statusCode != 200) {
- var msg = "Failure getting $uri:\n"
+ var msg = "Failure getting $resolvedUri:\n"
" ${response.statusCode} ${response.reasonPhrase}";
- _sendResourceResponse(sp, id, msg);
+ _sendResourceResponse(sp, tag, uri, libraryUrl, msg);
} else {
- _sendResourceResponse(sp, id, builder.takeBytes());
+ _sendResourceResponse(sp, tag, uri, libraryUrl,
+ builder.takeBytes());
}
},
onError: (e) {
- _sendResourceResponse(sp, id, e.toString());
+ _sendResourceResponse(sp, tag, uri, libraryUrl, e.toString());
});
})
.catchError((e) {
- _sendResourceResponse(sp, id, e.toString());
+ _sendResourceResponse(sp, tag, uri, libraryUrl, e.toString());
});
// It's just here to push an event on the event loop so that we invoke the
// scheduled microtasks.
Timer.run(() {});
}
-void _loadFile(SendPort sp, int id, Uri uri) {
- var path = uri.toFilePath();
+void _loadFile(SendPort sp,
+ int tag,
+ Uri uri,
+ Uri resolvedUri,
+ String libraryUrl) {
+ var path = resolvedUri.toFilePath();
var sourceFile = new File(path);
sourceFile.readAsBytes().then((data) {
- _sendResourceResponse(sp, id, data);
+ _sendResourceResponse(sp, tag, uri, libraryUrl, data);
},
onError: (e) {
- _sendResourceResponse(sp, id, e.toString());
+ _sendResourceResponse(sp, tag, uri, libraryUrl, e.toString());
});
}
-void _loadDataUri(SendPort sp, int id, Uri uri) {
+void _loadDataUri(SendPort sp,
+ int tag,
+ Uri uri,
+ Uri resolvedUri,
+ String libraryUrl) {
try {
var mime = uri.data.mimeType;
if ((mime != "application/dart") &&
@@ -74,25 +399,102 @@
// The C++ portion of the embedder assumes UTF-8.
throw "Only utf-8 or US-ASCII encodings are supported: $charset given.";
}
- _sendResourceResponse(sp, id, uri.data.contentAsBytes());
+ _sendResourceResponse(sp, tag, uri, libraryUrl, uri.data.contentAsBytes());
} catch (e) {
- _sendResourceResponse(sp, id, "Invalid data uri ($uri):\n $e");
+ _sendResourceResponse(sp, tag, uri, libraryUrl,
+ "Invalid data uri ($uri):\n $e");
}
}
-_handleResourceRequest(SendPort sp, bool traceLoading, int id, Uri resource) {
- if (resource.scheme == 'file') {
- _loadFile(sp, id, resource);
- } else if ((resource.scheme == 'http') || (resource.scheme == 'https')) {
- _loadHttp(sp, id, resource);
- } else if ((resource.scheme == 'data')) {
- _loadDataUri(sp, id, resource);
+// Loading a package URI needs to first map the package name to a loadable
+// URI.
+_loadPackage(IsolateLoaderState loaderState,
+ SendPort sp,
+ bool traceLoading,
+ int tag,
+ Uri uri,
+ Uri resolvedUri,
+ String libraryUrl) {
+ if (loaderState._packagesReady) {
+ var resolvedUri;
+ try {
+ resolvedUri = loaderState._resolvePackageUri(uri);
+ } catch (e, s) {
+ if (traceLoading) {
+ _log("Exception ($e) when resolving package URI: $uri");
+ }
+ // Report error.
+ _sendResourceResponse(sp,
+ tag,
+ uri,
+ libraryUrl,
+ e.toString());
+ return;
+ }
+ // Recursively call with the new resolved uri.
+ _handleResourceRequest(loaderState,
+ sp,
+ traceLoading,
+ tag,
+ uri,
+ resolvedUri,
+ libraryUrl);
} else {
- _sendResourceResponse(sp, id,
- 'Unknown scheme (${resource.scheme}) for $resource');
+ if (loaderState._pendingPackageLoads.isEmpty) {
+ // Package resolution has not been setup yet, and this is the first
+ // request for package resolution & loading.
+ loaderState._requestPackagesMap();
+ }
+ // Register the action of loading this package once the package resolution
+ // is ready.
+ loaderState._pendingPackageLoads.add(() {
+ _handleResourceRequest(loaderState,
+ sp,
+ traceLoading,
+ tag,
+ uri,
+ uri,
+ libraryUrl);
+ });
+ if (traceLoading) {
+ _log("Pending package load of '$uri': "
+ "${loaderState._pendingPackageLoads.length} pending");
+ }
}
}
+// TODO(johnmccutchan): This and most other top level functions in this file
+// should be turned into methods on the IsolateLoaderState class.
+_handleResourceRequest(IsolateLoaderState loaderState,
+ SendPort sp,
+ bool traceLoading,
+ int tag,
+ Uri uri,
+ Uri resolvedUri,
+ String libraryUrl) {
+ if (resolvedUri.scheme == 'file') {
+ _loadFile(sp, tag, uri, resolvedUri, libraryUrl);
+ } else if ((resolvedUri.scheme == 'http') ||
+ (resolvedUri.scheme == 'https')) {
+ _loadHttp(sp, tag, uri, resolvedUri, libraryUrl);
+ } else if ((resolvedUri.scheme == 'data')) {
+ _loadDataUri(sp, tag, uri, resolvedUri, libraryUrl);
+ } else if ((resolvedUri.scheme == 'package')) {
+ _loadPackage(loaderState,
+ sp,
+ traceLoading,
+ tag,
+ uri,
+ resolvedUri,
+ libraryUrl);
+ } else {
+ _sendResourceResponse(sp, tag,
+ uri,
+ libraryUrl,
+ 'Unknown scheme (${resolvedUri.scheme}) for '
+ '$resolvedUri');
+ }
+}
// Handling of packages requests. Finding and parsing of .packages file or
// packages/ directories.
@@ -329,7 +731,6 @@
}
}
-
Future<bool> _loadHttpPackagesFile(SendPort sp,
bool traceLoading,
Uri resource) async {
@@ -386,13 +787,16 @@
}
}
-
+// This code used to exist in a second isolate and so it uses a SendPort to
+// report it's return value. This could be refactored so that it returns it's
+// value and the caller could wait on the future rather than a message on
+// SendPort.
_handlePackagesRequest(SendPort sp,
bool traceLoading,
- int id,
+ int tag,
Uri resource) async {
try {
- if (id == -1) {
+ if (tag == -1) {
if (resource.scheme == 'file') {
_findPackagesFile(sp, traceLoading, resource);
} else if ((resource.scheme == 'http') || (resource.scheme == 'https')) {
@@ -409,7 +813,7 @@
sp.send("Unsupported scheme used to locate .packages file: "
"'$resource'.");
}
- } else if (id == -2) {
+ } else if (tag == -2) {
if (traceLoading) {
_log("Handling load of packages map: '$resource'.");
}
@@ -432,7 +836,7 @@
"'$resource'.");
}
} else {
- sp.send("Unknown packages request id: $id for '$resource'.");
+ sp.send("Unknown packages request tag: $tag for '$resource'.");
}
} catch (e, s) {
if (traceLoading) {
@@ -442,21 +846,143 @@
}
}
+// Shutdown all active loaders by sending an error message.
+void shutdownLoaders() {
+ String message = 'Service shutdown';
+ if (_httpClient != null) {
+ _httpClient.close(force: true);
+ _httpClient = null;
+ }
+ isolateEmbedderData.values.toList().forEach((IsolateLoaderState ils) {
+ ils.cleanup();
+ assert(ils.sp != null);
+ _sendResourceResponse(ils.sp, 1, null, null, message);
+ });
+}
+
+// See Dart_LibraryTag in dart_api.h
+const _Dart_kCanonicalizeUrl = 0; // Canonicalize the URL.
+const _Dart_kScriptTag = 1; // Load the root script.
+const _Dart_kSourceTag = 2; // Load a part source.
+const _Dart_kImportTag = 3; // Import a library.
+
+// Extra requests. Keep these in sync between loader.dart and builtin.dart.
+const _Dart_kInitLoader = 4; // Initialize the loader.
+const _Dart_kResourceLoad = 5; // Resource class support.
+const _Dart_kGetPackageRootUri = 6; // Uri of the packages/ directory.
+const _Dart_kGetPackageConfigUri = 7; // Uri of the .packages file.
+const _Dart_kResolvePackageUri = 8; // Resolve a package: uri.
// External entry point for loader requests.
_processLoadRequest(request) {
- SendPort sp = request[0];
- assert(sp != null);
- bool traceLoading = request[1];
- assert(traceLoading != null);
- int id = request[2];
- assert(id != null);
- String resource = request[3];
- assert(resource != null);
- var uri = Uri.parse(resource);
- if (id >= 0) {
- _handleResourceRequest(sp, traceLoading, id, uri);
- } else {
- _handlePackagesRequest(sp, traceLoading, id, uri);
+ assert(request is List);
+ assert(request.length > 4);
+
+ // Should we trace loading?
+ bool traceLoading = request[0];
+
+ // This is the sending isolate's Dart_GetMainPortId().
+ int isolateId = request[1];
+
+ // The tag describing the operation.
+ int tag = request[2];
+
+ // The send port to send the response on.
+ SendPort sp = request[3];
+
+ // Grab the loader state for the requesting isolate.
+ IsolateLoaderState loaderState = isolateEmbedderData[isolateId];
+
+ // We are either about to initialize the loader, or, we already have.
+ assert((tag == _Dart_kInitLoader) || (loaderState != null));
+
+ // Handle the request specified in the tag.
+ switch (tag) {
+ case _Dart_kScriptTag: {
+ Uri uri = Uri.parse(request[4]);
+ // Remember the root script.
+ loaderState._rootScript = uri;
+ _handleResourceRequest(loaderState,
+ sp,
+ traceLoading,
+ tag,
+ uri,
+ uri,
+ null);
+ }
+ break;
+ case _Dart_kSourceTag:
+ case _Dart_kImportTag: {
+ // The url of the file being loaded.
+ var uri = Uri.parse(request[4]);
+ // The library that is importing/parting the file.
+ String libraryUrl = request[5];
+ _handleResourceRequest(loaderState,
+ sp,
+ traceLoading,
+ tag,
+ uri,
+ uri,
+ libraryUrl);
+ }
+ break;
+ case _Dart_kInitLoader: {
+ String packageRoot = request[4];
+ String packagesFile = request[5];
+ String workingDirectory = request[6];
+ String rootScript = request[7];
+ if (loaderState == null) {
+ loaderState = new IsolateLoaderState(isolateId);
+ isolateEmbedderData[isolateId] = loaderState;
+ loaderState.init(packageRoot,
+ packagesFile,
+ workingDirectory,
+ rootScript);
+ }
+ loaderState.sp = sp;
+ assert(isolateEmbedderData[isolateId] == loaderState);
+ }
+ break;
+ case _Dart_kResourceLoad: {
+ Uri uri = Uri.parse(request[4]);
+ _handleResourceRequest(loaderState,
+ sp,
+ traceLoading,
+ tag,
+ uri,
+ uri,
+ null);
+ }
+ break;
+ case _Dart_kGetPackageRootUri:
+ loaderState._triggerPackageResolution(() {
+ // Respond with the package root (if any) after package resolution.
+ sp.send(loaderState._packageRoot);
+ });
+ break;
+ case _Dart_kGetPackageConfigUri:
+ loaderState._triggerPackageResolution(() {
+ // Respond with the packages config (if any) after package resolution.
+ sp.send(loaderState._packageConfig);
+ });
+ break;
+ case _Dart_kResolvePackageUri:
+ Uri uri = Uri.parse(request[4]);
+ loaderState._triggerPackageResolution(() {
+ // Respond with the resolved package uri after package resolution.
+ Uri resolvedUri;
+ try {
+ resolvedUri = loaderState._resolvePackageUri(uri);
+ } catch (e, s) {
+ if (traceLoading) {
+ _log("Exception ($e) when resolving package URI: $uri");
+ }
+ resolvedUri = null;
+ }
+ sp.send(resolvedUri);
+ });
+ break;
+ default:
+ _log('Unknown loader request tag=$tag from $isolateId');
}
}
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index ba82441..bfa99a6 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -39,6 +39,7 @@
}
Future cleanupCallback() async {
+ shutdownLoaders();
// Cancel the sigquit subscription.
if (_signalSubscription != null) {
await _signalSubscription.cancel();
@@ -51,6 +52,10 @@
print("Error in vm-service shutdown: $e\n$st\n");
}
}
+ if (_registerSignalHandlerTimer != null) {
+ _registerSignalHandlerTimer.cancel();
+ _registerSignalHandlerTimer = null;
+ }
// Call out to embedder's shutdown callback.
_shutdown();
}
@@ -73,7 +78,10 @@
}
}
+Timer _registerSignalHandlerTimer;
+
_registerSignalHandler() {
+ _registerSignalHandlerTimer = null;
if (_signalWatch == null) {
// Cannot register for signals.
return;
@@ -88,6 +96,9 @@
main() {
// Set embedder hooks.
VMServiceEmbedderHooks.cleanup = cleanupCallback;
+ // Always instantiate the vmservice object so that the exit message
+ // can be delivered and waiting loaders can be cancelled.
+ var service = new VMService();
if (_autoStart) {
_lazyServerBoot();
server.startup();
@@ -95,12 +106,10 @@
// scheduled microtasks.
Timer.run(() {});
}
- // TODO(johnmccutchan): Fixup service isolate shutdown in the general case.
- // See ServiceIsolate::KillServiceIsolate and ServiceIsolate::Shutdown.
scriptLoadPort.handler = _processLoadRequest;
// Register signal handler after a small delay to avoid stalling main
// isolate startup.
- new Timer(shortDelay, _registerSignalHandler);
+ _registerSignalHandlerTimer = new Timer(shortDelay, _registerSignalHandler);
return scriptLoadPort;
}
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index d019d4f..e27d70e 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -2656,10 +2656,10 @@
/* TODO(turnidge): Finish documenting this section. */
typedef enum {
- Dart_kImportTag = 0,
- Dart_kSourceTag,
- Dart_kCanonicalizeUrl,
+ Dart_kCanonicalizeUrl = 0,
Dart_kScriptTag,
+ Dart_kSourceTag,
+ Dart_kImportTag,
} Dart_LibraryTag;
/* TODO(turnidge): Document. */
@@ -2684,15 +2684,35 @@
Dart_LibraryTagHandler handler);
/**
+ * Canonicalizes a url with respect to some library.
+ *
+ * The url is resolved with respect to the library's url and some url
+ * normalizations are performed.
+ *
+ * This canonicalization function should be sufficient for most
+ * embedders to implement the Dart_kCanonicalizeUrl tag.
+ *
+ * \param library The library relative to which the url is being
+ * resolved.
+ * \param url The url being resolved and canonicalized. This
+ * parameter is a string handle.
+ *
+ * \return If no error occurs, a String object is returned. Otherwise
+ * an error handle is returned.
+ */
+DART_EXPORT Dart_Handle Dart_DefaultCanonicalizeUrl(Dart_Handle library,
+ Dart_Handle url);
+
+/**
* Loads the root script for the current isolate. The script can be
* embedded in another file, for example in an html file.
*
* TODO(turnidge): Document.
*
- * \line_offset is the number of text lines before the
+ * \param line_offset is the number of text lines before the
* first line of the Dart script in the containing file.
*
- * \col_offset is the number of characters before the first character
+ * \param col_offset is the number of characters before the first character
* in the first line of the Dart script.
*/
DART_EXPORT Dart_Handle Dart_LoadScript(Dart_Handle url,
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index da43d94..961c444 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -752,22 +752,44 @@
* a service request it can't handle and the service request command name
* matches one of the embedder registered handlers.
*
+ * The return value of the callback indicates whether the response
+ * should be used as a regular result or an error result.
+ * Specifically, if the callback returns true, a regular JSON-RPC
+ * response is built in the following way:
+ *
+ * {
+ * "jsonrpc": "2.0",
+ * "result": <json_object>,
+ * "id": <some sequence id>,
+ * }
+ *
+ * If the callback returns false, a JSON-RPC error is built like this:
+ *
+ * {
+ * "jsonrpc": "2.0",
+ * "error": <json_object>,
+ * "id": <some sequence id>,
+ * }
+ *
* \param method The rpc method name.
* \param param_keys Service requests can have key-value pair parameters. The
* keys and values are flattened and stored in arrays.
* \param param_values The values associated with the keys.
* \param num_params The length of the param_keys and param_values arrays.
* \param user_data The user_data pointer registered with this handler.
+ * \param result A C string containing a valid JSON object. The returned
+ * pointer will be freed by the VM by calling free.
*
- * \return Returns a C string containing a valid JSON object. The returned
- * pointer will be freed by the VM by calling free.
+ * \return True if the result is a regular JSON-RPC response, false if the
+ * result is a JSON-RPC error.
*/
-typedef const char* (*Dart_ServiceRequestCallback)(
+typedef bool (*Dart_ServiceRequestCallback)(
const char* method,
const char** param_keys,
const char** param_values,
intptr_t num_params,
- void* user_data);
+ void* user_data,
+ const char** json_object);
/**
diff --git a/runtime/lib/lib_prefix.dart b/runtime/lib/lib_prefix.dart
index 4f509da..9d5af28 100644
--- a/runtime/lib/lib_prefix.dart
+++ b/runtime/lib/lib_prefix.dart
@@ -46,19 +46,27 @@
// second element is the Completer for the load request.
var _outstandingLoadRequests = new List<List>();
-// Called from the VM when all outstanding load requests have
-// finished.
+// Called from the VM when an outstanding load request has finished.
_completeDeferredLoads() {
+ // Determine which outstanding load requests have completed and complete
+ // their completer (with an error or true). For outstanding load requests
+ // which have not completed, remember them for next time in
+ // stillOutstandingLoadRequests.
+ var stillOutstandingLoadRequests = new List<List>();
for (int i = 0; i < _outstandingLoadRequests.length; i++) {
var prefix = _outstandingLoadRequests[i][0];
- var completer = _outstandingLoadRequests[i][1];
- var error = prefix._loadError();
- if (error != null) {
- completer.completeError(error);
+ if (prefix._load()) {
+ var completer = _outstandingLoadRequests[i][1];
+ var error = prefix._loadError();
+ if (error != null) {
+ completer.completeError(error);
+ } else {
+ prefix._invalidateDependentCode();
+ completer.complete(true);
+ }
} else {
- prefix._invalidateDependentCode();
- completer.complete(true);
+ stillOutstandingLoadRequests.add(_outstandingLoadRequests[i]);
}
}
- _outstandingLoadRequests.clear();
+ _outstandingLoadRequests = stillOutstandingLoadRequests;
}
diff --git a/runtime/lib/symbol_patch.dart b/runtime/lib/symbol_patch.dart
index fdb6527..1a1b2bc 100644
--- a/runtime/lib/symbol_patch.dart
+++ b/runtime/lib/symbol_patch.dart
@@ -51,4 +51,9 @@
}
return result.toString();
}
+
+ /* patch */ int get hashCode {
+ const arbitraryPrime = 664597;
+ return 0x1fffffff & (arbitraryPrime * _name.hashCode);
+ }
}
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index ad0d89a..f37cacb 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -2886,12 +2886,10 @@
Int32x4 withFlagY(bool y) native "Int32x4_setFlagY";
Int32x4 withFlagZ(bool z) native "Int32x4_setFlagZ";
Int32x4 withFlagW(bool w) native "Int32x4_setFlagW";
- Float32x4 select(Float32x4 trueValue,
- Float32x4 falseValue) {
+ Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) {
return _select(trueValue, falseValue);
}
- Float32x4 _select(Float32x4 trueValue,
- Float32x4 falseValue)
+ Float32x4 _select(Float32x4 trueValue, Float32x4 falseValue)
native "Int32x4_select";
/// Mask passed to [shuffle] or [shuffleMix].
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 502f510..9c4fc7f 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -9,6 +9,7 @@
#include "vm/flags.h"
#include "vm/growable_array.h"
#include "vm/message.h"
+#include "vm/message_handler.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/port.h"
@@ -139,6 +140,9 @@
DEFINE_NATIVE_ENTRY(VMService_OnExit, 0) {
if (FLAG_trace_service) {
OS::Print("vm-service: processed exit message.\n");
+ MessageHandler* message_handler = isolate->message_handler();
+ OS::Print("vm-service: live ports = %" Pd "\n",
+ message_handler->live_ports());
}
return Object::null();
}
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index 4863c2c..9ee5cf2 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -43,6 +43,7 @@
export 'package:observatory/src/elements/object_common.dart';
export 'package:observatory/src/elements/object_view.dart';
export 'package:observatory/src/elements/objectpool_view.dart';
+export 'package:observatory/src/elements/objectstore_view.dart';
export 'package:observatory/src/elements/observatory_application.dart';
export 'package:observatory/src/elements/observatory_element.dart';
export 'package:observatory/src/elements/persistent_handles.dart';
diff --git a/runtime/observatory/lib/elements.html b/runtime/observatory/lib/elements.html
index 4e84fec..52b59b4 100644
--- a/runtime/observatory/lib/elements.html
+++ b/runtime/observatory/lib/elements.html
@@ -36,6 +36,7 @@
<link rel="import" href="src/elements/object_common.html">
<link rel="import" href="src/elements/object_view.html">
<link rel="import" href="src/elements/objectpool_view.html">
+<link rel="import" href="src/elements/objectstore_view.html">
<link rel="import" href="src/elements/observatory_application.html">
<link rel="import" href="src/elements/observatory_element.html">
<link rel="import" href="src/elements/persistent_handles.html">
diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart
index 0ffe385..7a034da 100644
--- a/runtime/observatory/lib/src/app/application.dart
+++ b/runtime/observatory/lib/src/app/application.dart
@@ -136,6 +136,7 @@
_pageRegistry.add(new InspectPage(this));
_pageRegistry.add(new ClassTreePage(this));
_pageRegistry.add(new DebuggerPage(this));
+ _pageRegistry.add(new ObjectStorePage(this));
_pageRegistry.add(new CpuProfilerPage(this));
_pageRegistry.add(new TableCpuProfilerPage(this));
_pageRegistry.add(new AllocationProfilerPage(this));
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index b2216e4..7f51a8e 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -199,6 +199,24 @@
}
}
+
+class ObjectStorePage extends SimplePage {
+ ObjectStorePage(app) : super('object-store', 'objectstore-view', app);
+
+ void _visit(Uri uri) {
+ super._visit(uri);
+ getIsolate(uri).then((isolate) {
+ isolate.getObjectStore().then((objectStore) {
+ if (element != null) {
+ /// Update the page.
+ ObjectStoreViewElement page = element;
+ page.objectStore = objectStore;
+ }
+ });
+ });
+ }
+}
+
class CpuProfilerPage extends SimplePage {
CpuProfilerPage(app) : super('profiler', 'cpu-profile', app);
diff --git a/runtime/observatory/lib/src/elements/isolate_view.html b/runtime/observatory/lib/src/elements/isolate_view.html
index 69c30ed..e7777a7 100644
--- a/runtime/observatory/lib/src/elements/isolate_view.html
+++ b/runtime/observatory/lib/src/elements/isolate_view.html
@@ -94,6 +94,12 @@
<div class="memberName">service protocol extensions</div>
<div class="memberValue">{{ isolate.extensionRPCs }}</div>
</div>
+ <div class="memberItem">
+ <div class="memberName">object store</div>
+ <div class="memberValue">
+ <a on-click="{{ goto }}" _href="{{ gotoLink('/object-store', isolate) }}">object store</a>
+ </div>
+ </div>
<div class="memberItem">
<div class="memberName">
diff --git a/runtime/observatory/lib/src/elements/objectstore_view.dart b/runtime/observatory/lib/src/elements/objectstore_view.dart
new file mode 100644
index 0000000..c5ff3bc
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/objectstore_view.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library objectstore_view_element;
+
+import 'dart:async';
+import 'observatory_element.dart';
+import 'package:observatory/service.dart';
+import 'package:polymer/polymer.dart';
+
+
+@CustomTag('objectstore-view')
+class ObjectStoreViewElement extends ObservatoryElement {
+ @published ObjectStore objectStore;
+
+ ObjectStoreViewElement.created() : super.created();
+
+ Future refresh() {
+ return objectStore.isolate.getObjectStore().then((newObjectStore) {
+ objectStore = newObjectStore;
+ });
+ }
+}
diff --git a/runtime/observatory/lib/src/elements/objectstore_view.html b/runtime/observatory/lib/src/elements/objectstore_view.html
new file mode 100644
index 0000000..a8d4d02
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/objectstore_view.html
@@ -0,0 +1,46 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="class_ref.html">
+<link rel="import" href="curly_block.html">
+<link rel="import" href="eval_box.html">
+<link rel="import" href="field_ref.html">
+<link rel="import" href="function_ref.html">
+<link rel="import" href="instance_ref.html">
+<link rel="import" href="observatory_element.html">
+<link rel="import" href="library_ref.html">
+<link rel="import" href="nav_bar.html">
+<link rel="import" href="script_ref.html">
+<link rel="import" href="view_footer.html">
+
+<polymer-element name="objectstore-view" extends="observatory-element">
+ <template>
+ <link rel="stylesheet" href="css/shared.css">
+
+ <nav-bar>
+ <top-nav-menu></top-nav-menu>
+ <vm-nav-menu vm="{{ objectStore.isolate.vm }}"></vm-nav-menu>
+ <isolate-nav-menu isolate="{{ objectStore.isolate }}" last="{{ true }}"></isolate-nav-menu>
+ <nav-refresh callback="{{ refresh }}"></nav-refresh>
+ </nav-bar>
+
+ <div class="content-centered-big">
+ <h1>
+ object store ({{ objectStore.fields.length }})
+ </h1>
+
+ <hr>
+
+ <div class="memberList">
+ <template repeat="{{ field in objectStore.fields }}">
+ <div class="memberItem">
+ <div class="memberName">{{ field.name }}</div>
+ <div class="memberValue"><any-service-ref ref="{{ field.value }}"></any-service-ref></div>
+ </div>
+ </template>
+ </div>
+ </div>
+
+ <view-footer></view-footer>
+ </template>
+</polymer-element>
+
+<script type="application/dart" src="library_view.dart"></script>
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index b0be812..bcaf2f8 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1636,6 +1636,14 @@
return invokeRpc('getStack', {});
}
+ Future<ObjectStore> getObjectStore() {
+ return invokeRpc('_getObjectStore', {}).then((map) {
+ ObjectStore objectStore = new ObjectStore._empty(this);
+ objectStore._update(map, false);
+ return objectStore;
+ });
+ }
+
Future<ServiceObject> _eval(ServiceObject target,
String expression) {
Map params = {
@@ -1744,6 +1752,36 @@
String toString() => "Isolate($name)";
}
+
+class NamedField {
+ final String name;
+ final ServiceObject value;
+ NamedField(this.name, this.value);
+}
+
+
+class ObjectStore extends ServiceObject {
+ @observable List<NamedField> fields = new List<NamedField>();
+
+ ObjectStore._empty(ServiceObjectOwner owner) : super._empty(owner);
+
+ void _update(ObservableMap map, bool mapIsRef) {
+ // Extract full properties.
+ _upgradeCollection(map, isolate);
+
+ if (mapIsRef) {
+ return;
+ }
+
+ fields.clear();
+ map['fields'].forEach((key, value) {
+ fields.add(new NamedField(key, value));
+ });
+ _loaded = true;
+ }
+}
+
+
/// A [ServiceObject] which implements [ObservableMap].
class ServiceMap extends ServiceObject implements ObservableMap {
final ObservableMap _map = new ObservableMap();
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index 9c9baec..c2084e1 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -105,6 +105,8 @@
'lib/src/elements/library_ref.html',
'lib/src/elements/library_view.dart',
'lib/src/elements/library_view.html',
+ 'lib/src/elements/objectstore_view.dart',
+ 'lib/src/elements/objectstore_view.html',
'lib/src/elements/logging.dart',
'lib/src/elements/logging.html',
'lib/src/elements/megamorphiccache_view.dart',
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index e34859d..5debbc1 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -85,10 +85,6 @@
[ $builder_tag == asan ]
cc/CodeImmutability: Fail,OK # Address Sanitizer turns a crash into a failure.
-[ $arch == ia32 && $builder_tag == asan ]
-cc/Dart2JSCompileAll: Crash # Issue 26487 - stack overflow
-cc/Dart2JSCompilerStats: Crash # Issue 26487 - stack overflow
-
[ $noopt ]
dart/byte_array_test: Crash # Incompatible flag --disable_alloc_stubs_after_gc
diff --git a/runtime/tools/create_snapshot_bin.py b/runtime/tools/create_snapshot_bin.py
index 78213cf..65e56de 100755
--- a/runtime/tools/create_snapshot_bin.py
+++ b/runtime/tools/create_snapshot_bin.py
@@ -45,6 +45,9 @@
result.add_option("--package_root",
action="store", type="string",
help="path used to resolve package: imports.")
+ result.add_option("--packages",
+ action="store", type="string",
+ help="package config file used to reasolve package: imports.")
result.add_option("--url_mapping",
default=[],
action="append",
@@ -112,6 +115,10 @@
if options.package_root:
script_args.append(''.join([ "--package_root=", options.package_root]))
+ # Pass along the packages if there is one.
+ if options.packages:
+ script_args.append(''.join([ "--packages=", options.packages]))
+
# First setup the vm isolate and regular isolate snapshot output filename.
script_args.append(''.join([ "--vm_isolate_snapshot=",
options.vm_output_bin ]))
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index 8b66e49..2507451 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -108,8 +108,6 @@
VisitInstanceCall(call);
}
}
- } else if (instr->IsPolymorphicInstanceCall()) {
- SpecializePolymorphicInstanceCall(instr->AsPolymorphicInstanceCall());
}
}
current_iterator_ = NULL;
@@ -268,37 +266,6 @@
}
-void AotOptimizer::SpecializePolymorphicInstanceCall(
- PolymorphicInstanceCallInstr* call) {
- if (!FLAG_polymorphic_with_deopt) {
- // Specialization adds receiver checks which can lead to deoptimization.
- return;
- }
- if (!call->with_checks()) {
- return; // Already specialized.
- }
-
- const intptr_t receiver_cid =
- call->PushArgumentAt(0)->value()->Type()->ToCid();
- if (receiver_cid == kDynamicCid) {
- return; // No information about receiver was infered.
- }
-
- const ICData& ic_data = TrySpecializeICData(call->ic_data(), receiver_cid);
- if (ic_data.raw() == call->ic_data().raw()) {
- // No specialization.
- return;
- }
-
- PolymorphicInstanceCallInstr* specialized =
- new(Z) PolymorphicInstanceCallInstr(call->instance_call(),
- ic_data,
- /* with_checks = */ false,
- /* complete = */ false);
- call->ReplaceWith(specialized, current_iterator());
-}
-
-
static BinarySmiOpInstr* AsSmiShiftLeftInstruction(Definition* d) {
BinarySmiOpInstr* instr = d->AsBinarySmiOp();
if ((instr != NULL) && (instr->op_kind() == Token::kSHL)) {
@@ -2148,6 +2115,11 @@
// TODO(srdjan): Use ICData to check if always true or false.
void AotOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
ASSERT(Token::IsTypeTestOperator(call->token_kind()));
+ // Guard against repeated speculative inlining.
+ if (!use_speculative_inlining_ ||
+ IsBlackListedForInlining(call->deopt_id())) {
+ return;
+ }
Definition* left = call->ArgumentAt(0);
Definition* type_args = NULL;
AbstractType& type = AbstractType::ZoneHandle(Z);
@@ -2256,6 +2228,11 @@
// TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids).
void AotOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) {
ASSERT(Token::IsTypeCastOperator(call->token_kind()));
+ // Guard against repeated speculative inlining.
+ if (!use_speculative_inlining_ ||
+ IsBlackListedForInlining(call->deopt_id())) {
+ return;
+ }
Definition* left = call->ArgumentAt(0);
Definition* type_args = call->ArgumentAt(1);
const AbstractType& type =
diff --git a/runtime/vm/aot_optimizer.h b/runtime/vm/aot_optimizer.h
index 97c996a..d608442 100644
--- a/runtime/vm/aot_optimizer.h
+++ b/runtime/vm/aot_optimizer.h
@@ -62,8 +62,6 @@
bool TryCreateICData(InstanceCallInstr* call);
const ICData& TrySpecializeICData(const ICData& ic_data, intptr_t cid);
- void SpecializePolymorphicInstanceCall(PolymorphicInstanceCallInstr* call);
-
bool TryReplaceWithIndexedOp(InstanceCallInstr* call);
bool TryReplaceWithBinaryOp(InstanceCallInstr* call, Token::Kind op_kind);
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index eeb831d..9832dae 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -1126,7 +1126,33 @@
}
+void Assembler::SetupDartSP() {
+ mov(SP, CSP);
+}
+
+
+void Assembler::RestoreCSP() {
+ mov(CSP, SP);
+}
+
+
void Assembler::EnterFrame(intptr_t frame_size) {
+ // The ARM64 ABI requires at all times
+ // - stack limit < CSP <= stack base
+ // - CSP mod 16 = 0
+ // - we do not access stack memory below CSP
+ // Pratically, this means we need to keep the C stack pointer ahead of the
+ // Dart stack pointer and 16-byte aligned for signal handlers. If we knew the
+ // real stack limit, we could just set CSP to a value near it during
+ // SetupDartSP, but we do not know the real stack limit for the initial
+ // thread or threads created by the embedder.
+ // TODO(26472): It would be safer to use CSP as the Dart stack pointer, but
+ // this requires adjustments to stack handling to maintain the 16-byte
+ // alignment.
+ const intptr_t kMaxDartFrameSize = 4096;
+ sub(TMP, SP, Operand(kMaxDartFrameSize));
+ andi(CSP, TMP, Immediate(~15));
+
PushPair(LR, FP);
mov(FP, SP);
diff --git a/runtime/vm/assembler_arm64.h b/runtime/vm/assembler_arm64.h
index 735e07e..8080ab8 100644
--- a/runtime/vm/assembler_arm64.h
+++ b/runtime/vm/assembler_arm64.h
@@ -1349,18 +1349,12 @@
Register scratch2,
Label* miss);
+ void SetupDartSP();
+ void RestoreCSP();
+
void EnterFrame(intptr_t frame_size);
void LeaveFrame();
- // When entering Dart code from C++, we copy the system stack pointer (CSP)
- // to the Dart stack pointer (SP), and reserve a little space for the stack
- // to grow.
- void SetupDartSP(intptr_t reserved_space) {
- ASSERT(Utils::IsAligned(reserved_space, 16));
- mov(SP, CSP);
- sub(CSP, CSP, Operand(reserved_space));
- }
-
void CheckCodePointer();
void RestoreCodePointer();
diff --git a/runtime/vm/assembler_arm64_test.cc b/runtime/vm/assembler_arm64_test.cc
index ba0d646..7c7a620 100644
--- a/runtime/vm/assembler_arm64_test.cc
+++ b/runtime/vm/assembler_arm64_test.cc
@@ -390,12 +390,12 @@
// Loads and Stores.
ASSEMBLER_TEST_GENERATE(SimpleLoadStore, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ movz(R0, Immediate(43), 0);
__ movz(R1, Immediate(42), 0);
__ str(R1, Address(SP, -1*kWordSize, Address::PreIndex));
__ ldr(R0, Address(SP, 1*kWordSize, Address::PostIndex));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -407,13 +407,13 @@
ASSEMBLER_TEST_GENERATE(SimpleLoadStoreHeapTag, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ movz(R0, Immediate(43), 0);
__ movz(R1, Immediate(42), 0);
__ add(R2, SP, Operand(1));
__ str(R1, Address(R2, -1));
__ ldr(R0, Address(R2, -1));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -425,7 +425,7 @@
ASSEMBLER_TEST_GENERATE(LoadStoreLargeIndex, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ movz(R0, Immediate(43), 0);
__ movz(R1, Immediate(42), 0);
// Largest negative offset that can fit in the signed 9-bit immediate field.
@@ -434,7 +434,7 @@
__ ldr(R0, Address(SP, 31*kWordSize, Address::PostIndex));
// Correction.
__ add(SP, SP, Operand(kWordSize)); // Restore SP.
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -446,14 +446,14 @@
ASSEMBLER_TEST_GENERATE(LoadStoreLargeOffset, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ movz(R0, Immediate(43), 0);
__ movz(R1, Immediate(42), 0);
__ sub(SP, SP, Operand(512*kWordSize));
__ str(R1, Address(SP, 512*kWordSize, Address::Offset));
__ add(SP, SP, Operand(512*kWordSize));
__ ldr(R0, Address(SP));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -465,7 +465,7 @@
ASSEMBLER_TEST_GENERATE(LoadStoreExtReg, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ movz(R0, Immediate(43), 0);
__ movz(R1, Immediate(42), 0);
__ movz(R2, Immediate(0xfff8), 0);
@@ -476,7 +476,7 @@
__ sub(SP, SP, Operand(kWordSize));
__ ldr(R0, Address(SP));
__ add(SP, SP, Operand(kWordSize));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -488,7 +488,7 @@
ASSEMBLER_TEST_GENERATE(LoadStoreScaledReg, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ movz(R0, Immediate(43), 0);
__ movz(R1, Immediate(42), 0);
__ movz(R2, Immediate(10), 0);
@@ -497,7 +497,7 @@
__ str(R1, Address(SP, R2, UXTX, Address::Scaled));
__ ldr(R0, Address(SP, R2, UXTX, Address::Scaled));
__ add(SP, SP, Operand(10*kWordSize));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -509,12 +509,12 @@
ASSEMBLER_TEST_GENERATE(LoadSigned32Bit, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadImmediate(R1, 0xffffffff);
__ str(R1, Address(SP, -4, Address::PreIndex, kWord), kWord);
__ ldr(R0, Address(SP), kWord);
__ ldr(R1, Address(SP, 4, Address::PostIndex, kWord), kWord);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -526,13 +526,13 @@
ASSEMBLER_TEST_GENERATE(SimpleLoadStorePair, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadImmediate(R2, 43);
__ LoadImmediate(R3, 42);
__ stp(R2, R3, Address(SP, -2*kWordSize, Address::PairPreIndex));
__ ldp(R0, R1, Address(SP, 2*kWordSize, Address::PairPostIndex));
__ sub(R0, R0, Operand(R1));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -544,7 +544,7 @@
ASSEMBLER_TEST_GENERATE(LoadStorePairOffset, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadImmediate(R2, 43);
__ LoadImmediate(R3, 42);
__ sub(SP, SP, Operand(4 * kWordSize));
@@ -552,7 +552,7 @@
__ ldp(R0, R1, Address::Pair(SP, 2 * kWordSize));
__ add(SP, SP, Operand(4 * kWordSize));
__ sub(R0, R0, Operand(R1));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -564,7 +564,7 @@
ASSEMBLER_TEST_GENERATE(Semaphore, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ movz(R0, Immediate(40), 0);
__ movz(R1, Immediate(42), 0);
__ Push(R0);
@@ -575,7 +575,7 @@
__ cmp(TMP, Operand(0));
__ b(&retry, NE); // NE if context switch occurred between ldrex and strex.
__ Pop(R0); // 42
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -588,7 +588,7 @@
ASSEMBLER_TEST_GENERATE(FailedSemaphore, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ movz(R0, Immediate(40), 0);
__ movz(R1, Immediate(42), 0);
__ Push(R0);
@@ -597,7 +597,7 @@
__ stxr(TMP, R1, SP); // IP == 1, failure
__ Pop(R0); // 40
__ add(R0, R0, Operand(TMP));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -723,6 +723,24 @@
}
+ASSEMBLER_TEST_GENERATE(AndImmCsp, assembler) {
+ // Note we must maintain the ARM64 ABI invariants on CSP here.
+ __ mov(TMP, CSP);
+ __ sub(TMP2, CSP, Operand(31));
+ __ andi(CSP, TMP2, Immediate(~15));
+ __ mov(R0, CSP);
+ __ sub(R0, TMP, Operand(R0));
+ __ mov(CSP, TMP);
+ __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(AndImmCsp, test) {
+ typedef int64_t (*Int64Return)() DART_UNUSED;
+ EXPECT_EQ(32, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+
ASSEMBLER_TEST_GENERATE(AndOneImm, assembler) {
__ movz(R1, Immediate(43), 0);
__ andi(R0, R1, Immediate(1));
@@ -1689,11 +1707,11 @@
// Loading immediate values with the object pool.
ASSEMBLER_TEST_GENERATE(LoadImmediatePPSmall, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
EnterTestFrame(assembler);
__ LoadImmediate(R0, 42);
LeaveTestFrame(assembler);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -1704,11 +1722,11 @@
ASSEMBLER_TEST_GENERATE(LoadImmediatePPMed, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
EnterTestFrame(assembler);
__ LoadImmediate(R0, 0xf1234123);
LeaveTestFrame(assembler);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -1719,11 +1737,11 @@
ASSEMBLER_TEST_GENERATE(LoadImmediatePPMed2, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
EnterTestFrame(assembler);
__ LoadImmediate(R0, 0x4321f1234124);
LeaveTestFrame(assembler);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -1734,11 +1752,11 @@
ASSEMBLER_TEST_GENERATE(LoadImmediatePPLarge, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
EnterTestFrame(assembler);
__ LoadImmediate(R0, 0x9287436598237465);
LeaveTestFrame(assembler);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -1751,11 +1769,11 @@
// LoadObject null.
ASSEMBLER_TEST_GENERATE(LoadObjectNull, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
EnterTestFrame(assembler);
__ LoadObject(R0, Object::null_object());
LeaveTestFrame(assembler);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -1766,11 +1784,11 @@
ASSEMBLER_TEST_GENERATE(LoadObjectTrue, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
EnterTestFrame(assembler);
__ LoadObject(R0, Bool::True());
LeaveTestFrame(assembler);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -1781,11 +1799,11 @@
ASSEMBLER_TEST_GENERATE(LoadObjectFalse, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
EnterTestFrame(assembler);
__ LoadObject(R0, Bool::False());
LeaveTestFrame(assembler);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -1940,11 +1958,11 @@
ASSEMBLER_TEST_GENERATE(FldrdFstrdPrePostIndex, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V1, 42.0);
__ fstrd(V1, Address(SP, -1*kWordSize, Address::PreIndex));
__ fldrd(V0, Address(SP, 1*kWordSize, Address::PostIndex));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -1956,13 +1974,13 @@
ASSEMBLER_TEST_GENERATE(FldrsFstrsPrePostIndex, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V1, 42.0);
__ fcvtsd(V2, V1);
__ fstrs(V2, Address(SP, -1*kWordSize, Address::PreIndex));
__ fldrs(V3, Address(SP, 1*kWordSize, Address::PostIndex));
__ fcvtds(V0, V3);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -1974,7 +1992,7 @@
ASSEMBLER_TEST_GENERATE(FldrqFstrqPrePostIndex, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V1, 21.0);
__ LoadDImmediate(V2, 21.0);
__ LoadImmediate(R1, 42);
@@ -1987,7 +2005,7 @@
__ PopDouble(V0);
__ PopDouble(V1);
__ faddd(V0, V0, V1);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -2160,7 +2178,7 @@
ASSEMBLER_TEST_GENERATE(FldrdFstrdHeapTag, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V0, 43.0);
__ LoadDImmediate(V1, 42.0);
__ AddImmediate(SP, SP, -1 * kWordSize);
@@ -2168,7 +2186,7 @@
__ fstrd(V1, Address(R2, -1));
__ fldrd(V0, Address(R2, -1));
__ AddImmediate(SP, SP, 1 * kWordSize);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -2180,7 +2198,7 @@
ASSEMBLER_TEST_GENERATE(FldrdFstrdLargeIndex, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V0, 43.0);
__ LoadDImmediate(V1, 42.0);
// Largest negative offset that can fit in the signed 9-bit immediate field.
@@ -2189,7 +2207,7 @@
__ fldrd(V0, Address(SP, 31*kWordSize, Address::PostIndex));
// Correction.
__ add(SP, SP, Operand(kWordSize)); // Restore SP.
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -2201,14 +2219,14 @@
ASSEMBLER_TEST_GENERATE(FldrdFstrdLargeOffset, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V0, 43.0);
__ LoadDImmediate(V1, 42.0);
__ sub(SP, SP, Operand(512*kWordSize));
__ fstrd(V1, Address(SP, 512*kWordSize, Address::Offset));
__ add(SP, SP, Operand(512*kWordSize));
__ fldrd(V0, Address(SP));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -2220,7 +2238,7 @@
ASSEMBLER_TEST_GENERATE(FldrdFstrdExtReg, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V0, 43.0);
__ LoadDImmediate(V1, 42.0);
__ movz(R2, Immediate(0xfff8), 0);
@@ -2231,7 +2249,7 @@
__ sub(SP, SP, Operand(kWordSize));
__ fldrd(V0, Address(SP));
__ add(SP, SP, Operand(kWordSize));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -2243,7 +2261,7 @@
ASSEMBLER_TEST_GENERATE(FldrdFstrdScaledReg, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V0, 43.0);
__ LoadDImmediate(V1, 42.0);
__ movz(R2, Immediate(10), 0);
@@ -2252,7 +2270,7 @@
__ fstrd(V1, Address(SP, R2, UXTX, Address::Scaled));
__ fldrd(V0, Address(SP, R2, UXTX, Address::Scaled));
__ add(SP, SP, Operand(10*kWordSize));
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -2707,7 +2725,7 @@
ASSEMBLER_TEST_GENERATE(Vdupd, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V0, 21.0);
__ vdupd(V1, V0, 0);
@@ -2719,7 +2737,7 @@
__ fldrd(V3, Address(SP, 1 * dword_bytes, Address::PostIndex));
__ faddd(V0, V2, V3);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -2731,7 +2749,7 @@
ASSEMBLER_TEST_GENERATE(Vdups, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V0, 21.0);
__ fcvtsd(V0, V0);
__ vdups(V1, V0, 0);
@@ -2753,7 +2771,7 @@
__ faddd(V0, V1, V1);
__ faddd(V0, V0, V2);
__ faddd(V0, V0, V3);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -2765,7 +2783,7 @@
ASSEMBLER_TEST_GENERATE(Vinsd, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V5, 42.0);
__ vinsd(V1, 1, V5, 0); // V1[1] <- V0[0].
@@ -2777,7 +2795,7 @@
__ fldrd(V3, Address(SP, 1 * dword_bytes, Address::PostIndex));
__ fmovdd(V0, V3);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -2789,7 +2807,7 @@
ASSEMBLER_TEST_GENERATE(Vinss, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ LoadDImmediate(V0, 21.0);
__ fcvtsd(V0, V0);
__ vinss(V1, 3, V0, 0);
@@ -2812,7 +2830,7 @@
__ faddd(V0, V0, V1);
__ faddd(V0, V0, V2);
__ faddd(V0, V0, V3);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
@@ -3601,7 +3619,7 @@
// R1: growable array.
// R2: current thread.
ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
__ Push(CODE_REG);
__ Push(THR);
__ Push(LR);
@@ -3612,13 +3630,13 @@
__ Pop(LR);
__ Pop(THR);
__ Pop(CODE_REG);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
- __ SetupDartSP(kTestStackSpace);
+ __ SetupDartSP();
EnterTestFrame(assembler);
Label miss, done;
__ ComputeRange(R0, R2, R3, &miss);
@@ -3629,7 +3647,7 @@
__ Bind(&done);
LeaveTestFrame(assembler);
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
diff --git a/runtime/vm/assembler_dbc_test.cc b/runtime/vm/assembler_dbc_test.cc
index 11e579e..3d5b751 100644
--- a/runtime/vm/assembler_dbc_test.cc
+++ b/runtime/vm/assembler_dbc_test.cc
@@ -32,6 +32,81 @@
#define __ assembler->
+static RawClass* CreateDummyClass(const String& class_name,
+ const Script& script) {
+ const Class& cls = Class::Handle(Class::New(
+ Library::Handle(), class_name, script, TokenPosition::kNoSource));
+ cls.set_is_synthesized_class(); // Dummy class for testing.
+ return cls.raw();
+}
+
+
+static RawLibrary* CreateDummyLibrary(const String& library_name) {
+ return Library::New(library_name);
+}
+
+
+static RawFunction* CreateFunction(const char* name) {
+ Thread* thread = Thread::Current();
+ const String& class_name = String::Handle(Symbols::New(thread, "ownerClass"));
+ const String& lib_name = String::Handle(Symbols::New(thread, "ownerLibrary"));
+ const Script& script = Script::Handle();
+ const Class& owner_class =
+ Class::Handle(CreateDummyClass(class_name, script));
+ const Library& owner_library =
+ Library::Handle(CreateDummyLibrary(lib_name));
+ owner_class.set_library(owner_library);
+ const String& function_name = String::ZoneHandle(Symbols::New(thread, name));
+ return Function::New(function_name, RawFunction::kRegularFunction,
+ true, false, false, false, false, owner_class,
+ TokenPosition::kMinSource);
+}
+
+
+static void GenerateDummyCode(Assembler* assembler, const Object& result) {
+ __ PushConstant(result);
+ __ ReturnTOS();
+}
+
+
+static void MakeDummyInstanceCall(Assembler* assembler, const Object& result) {
+ // Make a dummy function.
+ Assembler _assembler_;
+ GenerateDummyCode(&_assembler_, result);
+ const char* dummy_function_name = "dummy_instance_function";
+ const Function& dummy_instance_function =
+ Function::Handle(CreateFunction(dummy_function_name));
+ Code& code =
+ Code::Handle(Code::FinalizeCode(dummy_instance_function, &_assembler_));
+ dummy_instance_function.AttachCode(code);
+
+ // Make a dummy ICData.
+ const Array& dummy_arguments_descriptor =
+ Array::Handle(ArgumentsDescriptor::New(2));
+ const ICData& ic_data = ICData::Handle(ICData::New(
+ dummy_instance_function,
+ String::Handle(dummy_instance_function.name()),
+ dummy_arguments_descriptor,
+ Thread::kNoDeoptId,
+ 2));
+
+ // Wire up the Function in the ICData.
+ GrowableArray<intptr_t> cids(2);
+ cids.Add(kSmiCid);
+ cids.Add(kSmiCid);
+ ic_data.AddCheck(cids, dummy_instance_function);
+
+ // For the non-Smi tests.
+ cids[0] = kBigintCid;
+ ic_data.AddCheck(cids, dummy_instance_function);
+ ICData* call_ic_data = &ICData::ZoneHandle(ic_data.Original());
+
+ // Generate the instance call.
+ const intptr_t call_ic_data_kidx = __ AddConstant(*call_ic_data);
+ __ InstanceCall2(2, call_ic_data_kidx);
+}
+
+
ASSEMBLER_TEST_GENERATE(Simple, assembler) {
__ PushConstant(Smi::Handle(Smi::New(42)));
__ ReturnTOS();
@@ -66,7 +141,8 @@
__ PushConstant(Smi::Handle(Smi::New(-42)));
__ PushConstant(Smi::Handle(Smi::New(84)));
__ AddTOS();
- __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(0)));
__ ReturnTOS();
}
@@ -80,7 +156,8 @@
__ PushConstant(Smi::Handle(Smi::New(Smi::kMaxValue)));
__ PushConstant(Smi::Handle(Smi::New(1)));
__ AddTOS();
- __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(42)));
__ ReturnTOS();
}
@@ -96,7 +173,8 @@
__ 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.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(42)));
__ ReturnTOS();
}
@@ -110,7 +188,8 @@
__ PushConstant(Smi::Handle(Smi::New(30)));
__ PushConstant(Smi::Handle(Smi::New(-12)));
__ SubTOS();
- __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(0)));
__ ReturnTOS();
}
@@ -124,7 +203,8 @@
__ PushConstant(Smi::Handle(Smi::New(Smi::kMinValue)));
__ PushConstant(Smi::Handle(Smi::New(1)));
__ SubTOS();
- __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(42)));
__ ReturnTOS();
}
@@ -140,7 +220,8 @@
__ 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.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(42)));
__ ReturnTOS();
}
@@ -154,7 +235,8 @@
__ PushConstant(Smi::Handle(Smi::New(-6)));
__ PushConstant(Smi::Handle(Smi::New(-7)));
__ MulTOS();
- __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(0)));
__ ReturnTOS();
}
@@ -168,7 +250,8 @@
__ PushConstant(Smi::Handle(Smi::New(Smi::kMaxValue)));
__ PushConstant(Smi::Handle(Smi::New(-8)));
__ MulTOS();
- __ PushConstant(Smi::Handle(Smi::New(42))); // Shouldn't be skipped.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(42)));
__ ReturnTOS();
}
@@ -184,7 +267,8 @@
__ 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.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(42)));
__ ReturnTOS();
}
@@ -198,7 +282,8 @@
__ PushConstant(Smi::Handle(Smi::New(0x22)));
__ PushConstant(Smi::Handle(Smi::New(0x08)));
__ BitOrTOS();
- __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(0)));
__ ReturnTOS();
}
@@ -214,7 +299,8 @@
__ 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.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(42)));
__ ReturnTOS();
}
@@ -228,7 +314,8 @@
__ PushConstant(Smi::Handle(Smi::New(0x2a)));
__ PushConstant(Smi::Handle(Smi::New(0xaa)));
__ BitAndTOS();
- __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(0)));
__ ReturnTOS();
}
@@ -244,7 +331,8 @@
__ 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.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(42)));
__ ReturnTOS();
}
@@ -258,7 +346,8 @@
__ PushConstant(Smi::Handle(Smi::New(42)));
__ PushConstant(Smi::Handle(Smi::New(42)));
__ EqualTOS();
- __ PushConstant(Bool::False()); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Bool::False());
__ ReturnTOS();
}
@@ -272,7 +361,8 @@
__ PushConstant(Smi::Handle(Smi::New(42)));
__ PushConstant(Smi::Handle(Smi::New(-42)));
__ EqualTOS();
- __ PushConstant(Bool::True()); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Bool::True());
__ ReturnTOS();
}
@@ -288,7 +378,8 @@
__ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
__ PushConstant(Smi::Handle(Smi::New(-42)));
__ EqualTOS();
- __ PushConstant(Bool::True()); // Shouldn't be skipped.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Bool::True());
__ ReturnTOS();
}
@@ -302,7 +393,8 @@
__ PushConstant(Smi::Handle(Smi::New(-42)));
__ PushConstant(Smi::Handle(Smi::New(42)));
__ LessThanTOS();
- __ PushConstant(Bool::False()); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Bool::False());
__ ReturnTOS();
}
@@ -316,7 +408,8 @@
__ PushConstant(Smi::Handle(Smi::New(42)));
__ PushConstant(Smi::Handle(Smi::New(-42)));
__ LessThanTOS();
- __ PushConstant(Bool::False()); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Bool::False());
__ ReturnTOS();
}
@@ -332,7 +425,8 @@
__ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
__ PushConstant(Smi::Handle(Smi::New(-42)));
__ LessThanTOS();
- __ PushConstant(Bool::True()); // Shouldn't be skipped.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Bool::True());
__ ReturnTOS();
}
@@ -346,7 +440,8 @@
__ PushConstant(Smi::Handle(Smi::New(42)));
__ PushConstant(Smi::Handle(Smi::New(-42)));
__ GreaterThanTOS();
- __ PushConstant(Bool::False()); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Bool::False());
__ ReturnTOS();
}
@@ -360,7 +455,8 @@
__ PushConstant(Smi::Handle(Smi::New(-42)));
__ PushConstant(Smi::Handle(Smi::New(42)));
__ GreaterThanTOS();
- __ PushConstant(Bool::False()); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Bool::False());
__ ReturnTOS();
}
@@ -376,7 +472,8 @@
__ PushConstant(Integer::Handle(Integer::New(numstr, Heap::kOld)));
__ PushConstant(Smi::Handle(Smi::New(-42)));
__ GreaterThanTOS();
- __ PushConstant(Bool::True()); // Shouldn't be skipped.
+ // Shouldn't be skipped.
+ MakeDummyInstanceCall(assembler, Bool::True());
__ ReturnTOS();
}
@@ -777,7 +874,7 @@
__ PushConstant(Smi::Handle(Smi::New(41)));
__ DropR(11);
__ AddTOS();
- __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(0)));
__ ReturnTOS();
}
@@ -840,11 +937,13 @@
// Push FP[rX] to the stack.
ASSEMBLER_TEST_GENERATE(StoreLocalPush, assembler) {
__ Frame(1);
+ __ PushConstant(Smi::Handle(Smi::New(37)));
__ PushConstant(Smi::Handle(Smi::New(21)));
__ StoreLocal(0);
__ Push(0);
__ AddTOS();
- __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(0)));
__ ReturnTOS();
}
@@ -861,7 +960,8 @@
__ Push(0);
__ Push(0);
__ AddTOS();
- __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(0)));
__ ReturnTOS();
}
@@ -877,7 +977,8 @@
__ Push(0);
__ Push(0);
__ AddTOS();
- __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(0)));
__ ReturnTOS();
}
@@ -900,7 +1001,8 @@
__ Push(0);
__ Push(1);
__ AddTOS();
- __ PushConstant(Smi::Handle(Smi::New(0))); // Should be skipped.
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(0)));
__ ReturnTOS();
}
@@ -951,14 +1053,16 @@
__ PushConstant(Smi::Handle(Smi::New(1)));
__ Push(1);
__ AddTOS();
- __ Jump(&error);
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(-1)));
__ PopLocal(1);
// Subtract 1 from FP[0].
__ Push(0);
__ PushConstant(Smi::Handle(Smi::New(1)));
__ SubTOS();
- __ Jump(&error);
+ // Should be skipped.
+ MakeDummyInstanceCall(assembler, Smi::Handle(Smi::New(-1)));
// Jump to loop_entry if FP[0] != 0.
__ StoreLocal(0);
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 790e94c..48b4a22 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -540,15 +540,16 @@
ClosureNode(TokenPosition token_pos,
const Function& function,
AstNode* receiver, // Non-null for implicit instance closures.
- LocalScope* scope) // Null for implicit closures.
+ LocalScope* scope) // Null for implicit closures or functions
+ // that already have a ContextScope because
+ // they were compiled before.
: AstNode(token_pos),
function_(function),
receiver_(receiver),
scope_(scope),
is_deferred_reference_(false) {
ASSERT(function_.IsZoneHandle());
- ASSERT((function_.IsNonImplicitClosureFunction() &&
- (receiver_ == NULL) && (scope_ != NULL)) ||
+ ASSERT((function_.IsNonImplicitClosureFunction() && (receiver_ == NULL)) ||
(function_.IsImplicitInstanceClosureFunction() &&
(receiver_ != NULL) && (scope_ == NULL)) ||
(function_.IsImplicitStaticClosureFunction() &&
diff --git a/runtime/vm/become.cc b/runtime/vm/become.cc
index 0f4586f..2a8e491 100644
--- a/runtime/vm/become.cc
+++ b/runtime/vm/become.cc
@@ -8,7 +8,6 @@
#include "platform/utils.h"
#include "vm/dart_api_state.h"
-#include "vm/freelist.h"
#include "vm/isolate_reload.h"
#include "vm/object.h"
#include "vm/raw_object.h"
@@ -20,32 +19,55 @@
DECLARE_FLAG(bool, trace_reload);
+
+ForwardingCorpse* ForwardingCorpse::AsForwarder(uword addr, intptr_t size) {
+ ASSERT(size >= kObjectAlignment);
+ ASSERT(Utils::IsAligned(size, kObjectAlignment));
+
+ ForwardingCorpse* result = reinterpret_cast<ForwardingCorpse*>(addr);
+
+ uword tags = 0;
+ tags = RawObject::SizeTag::update(size, tags);
+ tags = RawObject::ClassIdTag::update(kForwardingCorpse, tags);
+
+ result->tags_ = tags;
+ if (size > RawObject::SizeTag::kMaxSizeTag) {
+ *result->SizeAddress() = size;
+ }
+ result->set_target(Object::null());
+ return result;
+}
+
+
+void ForwardingCorpse::InitOnce() {
+ ASSERT(sizeof(ForwardingCorpse) == kObjectAlignment);
+ ASSERT(OFFSET_OF(ForwardingCorpse, tags_) == Object::tags_offset());
+}
+
+
// Free list elements are used as a marker for forwarding objects. This is
// safe because we cannot reach free list elements from live objects. Ideally
// forwarding objects would have their own class id. See TODO below.
static bool IsForwardingObject(RawObject* object) {
- return object->IsHeapObject() && object->IsFreeListElement();
+ return object->IsHeapObject() && object->IsForwardingCorpse();
}
static RawObject* GetForwardedObject(RawObject* object) {
ASSERT(IsForwardingObject(object));
uword addr = reinterpret_cast<uword>(object) - kHeapObjectTag;
- FreeListElement* forwarder = reinterpret_cast<FreeListElement*>(addr);
- RawObject* new_target = reinterpret_cast<RawObject*>(forwarder->next());
- return new_target;
+ ForwardingCorpse* forwarder = reinterpret_cast<ForwardingCorpse*>(addr);
+ return forwarder->target();
}
static void ForwardObjectTo(RawObject* before_obj, RawObject* after_obj) {
const intptr_t size_before = before_obj->Size();
- // TODO(rmacnak): We should use different cids for forwarding corpses and
- // free list elements.
uword corpse_addr = reinterpret_cast<uword>(before_obj) - kHeapObjectTag;
- FreeListElement* forwarder = FreeListElement::AsElement(corpse_addr,
- size_before);
- forwarder->set_next(reinterpret_cast<FreeListElement*>(after_obj));
+ ForwardingCorpse* forwarder = ForwardingCorpse::AsForwarder(corpse_addr,
+ size_before);
+ forwarder->set_target(after_obj);
if (!IsForwardingObject(before_obj)) {
FATAL("become: ForwardObjectTo failure.");
}
@@ -130,22 +152,22 @@
#if defined(DEBUG)
-class NoFreeListTargetsVisitor : public ObjectPointerVisitor {
+class NoForwardingCorpseTargetsVisitor : public ObjectPointerVisitor {
public:
- explicit NoFreeListTargetsVisitor(Isolate* isolate)
+ explicit NoForwardingCorpseTargetsVisitor(Isolate* isolate)
: ObjectPointerVisitor(isolate) { }
virtual void VisitPointers(RawObject** first, RawObject** last) {
for (RawObject** p = first; p <= last; p++) {
RawObject* target = *p;
if (target->IsHeapObject()) {
- ASSERT(!target->IsFreeListElement());
+ ASSERT(!target->IsForwardingCorpse());
}
}
}
private:
- DISALLOW_COPY_AND_ASSIGN(NoFreeListTargetsVisitor);
+ DISALLOW_COPY_AND_ASSIGN(NoForwardingCorpseTargetsVisitor);
};
#endif
@@ -166,7 +188,7 @@
#if defined(DEBUG)
{
// There should be no pointers to free list elements / forwarding corpses.
- NoFreeListTargetsVisitor visitor(isolate);
+ NoForwardingCorpseTargetsVisitor visitor(isolate);
isolate->VisitObjectPointers(&visitor, true);
heap->VisitObjectPointers(&visitor);
}
@@ -190,7 +212,10 @@
if (before_obj->IsVMHeapObject()) {
FATAL("become: Cannot forward VM heap objects");
}
- if (after_obj->IsFreeListElement()) {
+ if (before_obj->IsForwardingCorpse()) {
+ FATAL("become: Cannot forward to multiple targets");
+ }
+ if (after_obj->IsForwardingCorpse()) {
// The Smalltalk become does allow this, and for very special cases
// it is important (shape changes to Class or Mixin), but as these
// cases do not arise in Dart, better to prohibit it.
@@ -228,7 +253,7 @@
{
// There should be no pointers to forwarding corpses.
- NoFreeListTargetsVisitor visitor(isolate);
+ NoForwardingCorpseTargetsVisitor visitor(isolate);
isolate->VisitObjectPointers(&visitor, true);
heap->VisitObjectPointers(&visitor);
}
diff --git a/runtime/vm/become.h b/runtime/vm/become.h
index 9773553..b78524d 100644
--- a/runtime/vm/become.h
+++ b/runtime/vm/become.h
@@ -6,11 +6,71 @@
#define VM_BECOME_H_
#include "vm/allocation.h"
+#include "vm/raw_object.h"
namespace dart {
class Array;
+// Objects that are a source in a become are tranformed into forwarding
+// corpses pointing to the corresponding target. Forwarding corpses have the
+// same heap sizes as the source object to ensure the heap remains walkable.
+// If the heap sizes is small enough to be encoded in the size field of the
+// header, a forwarding corpse consists only of a header and the target pointer.
+// If the heap size is too big to be encoded in the header's size field, the
+// word after the target pointer contains the size. This is the same
+// representation as a FreeListElement.
+class ForwardingCorpse {
+ public:
+ RawObject* target() const {
+ return target_;
+ }
+ void set_target(RawObject* target) {
+ target_ = target;
+ }
+
+ intptr_t Size() {
+ intptr_t size = RawObject::SizeTag::decode(tags_);
+ if (size != 0) return size;
+ return *SizeAddress();
+ }
+
+ static ForwardingCorpse* AsForwarder(uword addr, intptr_t size);
+
+ static void InitOnce();
+
+ // Used to allocate class for forwarding corpses in Object::InitOnce.
+ class FakeInstance {
+ public:
+ FakeInstance() { }
+ static cpp_vtable vtable() { return 0; }
+ static intptr_t InstanceSize() { return 0; }
+ static intptr_t NextFieldOffset() { return -kWordSize; }
+ static const ClassId kClassId = kForwardingCorpse;
+ static bool IsInstance() { return true; }
+
+ private:
+ DISALLOW_ALLOCATION();
+ DISALLOW_COPY_AND_ASSIGN(FakeInstance);
+ };
+
+ private:
+ // This layout mirrors the layout of RawObject.
+ uword tags_;
+ RawObject* target_;
+
+ // Returns the address of the embedded size.
+ intptr_t* SizeAddress() const {
+ uword addr = reinterpret_cast<uword>(&target_) + kWordSize;
+ return reinterpret_cast<intptr_t*>(addr);
+ }
+
+ // ForwardingCorpses cannot be allocated. Instead references to them are
+ // created using the AsForwarder factory method.
+ DISALLOW_ALLOCATION();
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ForwardingCorpse);
+};
+
// TODO(johnmccutchan): Refactor this class so that it is not all static and
// provides utility methods for building the mapping of before and after.
class Become : public AllStatic {
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 8cb9fa1..9432a1b 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -35,6 +35,7 @@
table_[i] = vm_class_table->At(i);
}
table_[kFreeListElement] = vm_class_table->At(kFreeListElement);
+ table_[kForwardingCorpse] = vm_class_table->At(kForwardingCorpse);
table_[kDynamicCid] = vm_class_table->At(kDynamicCid);
table_[kVoidCid] = vm_class_table->At(kVoidCid);
class_heap_stats_table_ = reinterpret_cast<ClassHeapStats*>(
@@ -218,9 +219,6 @@
if (!HasValidClassAt(i)) {
continue;
}
- if (i == kFreeListElement) {
- continue;
- }
cls = At(i);
if (cls.raw() != reinterpret_cast<RawClass*>(0)) {
name = cls.Name();
@@ -395,7 +393,10 @@
ClassHeapStats* ClassTable::StatsWithUpdatedSize(intptr_t cid) {
- if (!HasValidClassAt(cid) || (cid == kFreeListElement) || (cid == kSmiCid)) {
+ if (!HasValidClassAt(cid) ||
+ (cid == kFreeListElement) ||
+ (cid == kForwardingCorpse) ||
+ (cid == kSmiCid)) {
return NULL;
}
Class& cls = Class::Handle(At(cid));
diff --git a/runtime/vm/compiler_stats.cc b/runtime/vm/compiler_stats.cc
index d15df53..e8d39b3 100644
--- a/runtime/vm/compiler_stats.cc
+++ b/runtime/vm/compiler_stats.cc
@@ -26,8 +26,8 @@
}
void VisitObject(RawObject* raw_obj) {
- if (raw_obj->IsFreeListElement()) {
- return;
+ if (raw_obj->IsPseudoObject()) {
+ return; // Cannot be wrapped in handles.
}
obj_ = raw_obj;
if (obj_.GetClassId() == TokenStream::kClassId) {
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 870bb34..e855b0f 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -996,7 +996,15 @@
return R31IsSP;
}
}
- // TODO(zra): Handle for logical immediate operations.
+ if (IsLogicalImmOp()) {
+ const int op = Bits(29, 2);
+ const bool set_flags = op == 3;
+ if (set_flags) {
+ return R31IsZR;
+ } else {
+ return R31IsSP;
+ }
+ }
return R31IsZR;
}
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index 657ffb0..4449cb1 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -404,7 +404,7 @@
V(StoreLocal, X, xeg, ___, ___) \
V(PopLocal, X, xeg, ___, ___) \
V(StaticCall, A_D, num, num, ___) \
- V(InstanceCall1, A_D, num, num, ___) \
+ V(InstanceCall1, A_D, num, num, ___) \
V(InstanceCall2, A_D, num, num, ___) \
V(InstanceCall1Opt, A_D, num, num, ___) \
V(InstanceCall2Opt, A_D, num, num, ___) \
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index f4821e4..fe8154b 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -4,6 +4,7 @@
#include "vm/dart.h"
+#include "vm/become.h"
#include "vm/code_observers.h"
#include "vm/cpu.h"
#include "vm/dart_api_state.h"
@@ -146,6 +147,7 @@
Isolate::InitOnce();
PortMap::InitOnce();
FreeListElement::InitOnce();
+ ForwardingCorpse::InitOnce();
Api::InitOnce();
NOT_IN_PRODUCT(CodeObservers::InitOnce());
if (FLAG_profiler) {
@@ -653,7 +655,6 @@
Isolate* isolate = Isolate::Current();
void* callback_data = isolate->init_callback_data();
Dart_IsolateShutdownCallback callback = Isolate::ShutdownCallback();
- ServiceIsolate::SendIsolateShutdownMessage();
if (callback != NULL) {
(callback)(callback_data);
}
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 95ae648..254d829 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -42,6 +42,7 @@
#include "vm/timeline.h"
#include "vm/timer.h"
#include "vm/unicode.h"
+#include "vm/uri.h"
#include "vm/verifier.h"
#include "vm/version.h"
@@ -480,6 +481,9 @@
CHECK_API_SCOPE(T);
HANDLESCOPE(T);
CHECK_CALLBACK_STATE(T);
+ // Ensure we transition safepoint state to VM if we are not already in
+ // that state.
+ TransitionToVM transition(T);
va_list args;
va_start(args, format);
@@ -847,23 +851,20 @@
DART_EXPORT Dart_Handle Dart_PropagateError(Dart_Handle handle) {
Thread* thread = Thread::Current();
- {
- const Object& obj = Object::Handle(thread->zone(),
- Api::UnwrapHandle(handle));
- if (!obj.IsError()) {
- return Api::NewError(
- "%s expects argument 'handle' to be an error handle. "
- "Did you forget to check Dart_IsError first?",
- CURRENT_FUNC);
- }
+ TransitionNativeToVM transition(thread);
+ const Object& obj = Object::Handle(thread->zone(),
+ Api::UnwrapHandle(handle));
+ if (!obj.IsError()) {
+ return Api::NewError(
+ "%s expects argument 'handle' to be an error handle. "
+ "Did you forget to check Dart_IsError first?",
+ CURRENT_FUNC);
}
if (thread->top_exit_frame_info() == 0) {
// There are no dart frames on the stack so it would be illegal to
// propagate an error here.
return Api::NewError("No Dart frames on stack, cannot propagate error.");
}
-
- TransitionNativeToVM transition(thread);
// Unwind all the API scopes till the exit frame before propagating.
const Error* error;
{
@@ -975,6 +976,7 @@
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
ApiState* state = isolate->api_state();
ASSERT(state != NULL);
PersistentHandle* ref = PersistentHandle::Cast(object);
@@ -987,6 +989,7 @@
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
ApiState* state = isolate->api_state();
ASSERT(state != NULL);
FinalizablePersistentHandle* weak_ref =
@@ -1061,6 +1064,7 @@
DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object) {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
ApiState* state = isolate->api_state();
ASSERT(state != NULL);
PersistentHandle* ref = PersistentHandle::Cast(object);
@@ -1076,6 +1080,7 @@
Dart_WeakPersistentHandle object) {
Isolate* isolate = reinterpret_cast<Isolate*>(current_isolate);
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
ASSERT(isolate == Isolate::Current());
ApiState* state = isolate->api_state();
ASSERT(state != NULL);
@@ -1091,8 +1096,10 @@
DART_EXPORT Dart_Handle Dart_SetGcCallbacks(
Dart_GcPrologueCallback prologue_callback,
Dart_GcEpilogueCallback epilogue_callback) {
- Isolate* isolate = Isolate::Current();
+ Thread* thread = Thread::Current();
+ Isolate* isolate = thread->isolate();
CHECK_ISOLATE(isolate);
+ DARTSCOPE(thread);
if (prologue_callback != NULL) {
if (isolate->gc_prologue_callback() != NULL) {
return Api::NewError(
@@ -1290,13 +1297,14 @@
StackZone zone(T);
HandleScope handle_scope(T);
Dart::RunShutdownCallback();
+ // The Thread structure is disassociated from the isolate, we do the
+ // safepoint transition explicity here instead of using the TransitionXXX
+ // scope objects as the original transition happened outside this scope in
+ // Dart_EnterIsolate/Dart_CreateIsolate.
+ T->ExitSafepoint();
+ T->set_execution_state(Thread::kThreadInVM);
+ ServiceIsolate::SendIsolateShutdownMessage();
}
- // The Thread structure is disassociated from the isolate, we do the
- // safepoint transition explicity here instead of using the TransitionXXX
- // scope objects as the original transition happened outside this scope in
- // Dart_EnterIsolate/Dart_CreateIsolate.
- T->ExitSafepoint();
- T->set_execution_state(Thread::kThreadInVM);
Dart::ShutdownIsolate();
}
@@ -1309,6 +1317,7 @@
DART_EXPORT void* Dart_CurrentIsolateData() {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
return isolate->init_callback_data();
}
@@ -1318,6 +1327,7 @@
FATAL1("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
}
// TODO(16615): Validate isolate parameter.
+ NoSafepointScope no_safepoint_scope;
Isolate* iso = reinterpret_cast<Isolate*>(isolate);
return iso->init_callback_data();
}
@@ -1371,6 +1381,7 @@
DART_EXPORT bool Dart_ShouldPauseOnStart() {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
return isolate->message_handler()->should_pause_on_start();
}
@@ -1378,6 +1389,7 @@
DART_EXPORT void Dart_SetShouldPauseOnStart(bool should_pause) {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
if (isolate->is_runnable()) {
FATAL1("%s expects the current isolate to not be runnable yet.",
CURRENT_FUNC);
@@ -1389,6 +1401,7 @@
DART_EXPORT bool Dart_IsPausedOnStart() {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
return isolate->message_handler()->is_paused_on_start();
}
@@ -1396,6 +1409,7 @@
DART_EXPORT void Dart_SetPausedOnStart(bool paused) {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
if (isolate->message_handler()->is_paused_on_start() != paused) {
isolate->message_handler()->PausedOnStart(paused);
}
@@ -1405,6 +1419,7 @@
DART_EXPORT bool Dart_ShouldPauseOnExit() {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
return isolate->message_handler()->should_pause_on_exit();
}
@@ -1412,6 +1427,7 @@
DART_EXPORT void Dart_SetShouldPauseOnExit(bool should_pause) {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
return isolate->message_handler()->set_should_pause_on_exit(should_pause);
}
@@ -1419,6 +1435,7 @@
DART_EXPORT bool Dart_IsPausedOnExit() {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
return isolate->message_handler()->is_paused_on_exit();
}
@@ -1426,6 +1443,7 @@
DART_EXPORT void Dart_SetPausedOnExit(bool paused) {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
if (isolate->message_handler()->is_paused_on_exit() != paused) {
isolate->message_handler()->PausedOnExit(paused);
}
@@ -1557,6 +1575,7 @@
FATAL1("%s expects argument 'isolate' to be non-null.", CURRENT_FUNC);
}
// TODO(16615): Validate isolate parameter.
+ TransitionNativeToVM transition(Thread::Current());
Isolate* iso = reinterpret_cast<Isolate*>(isolate);
iso->SendInternalLibMessage(Isolate::kInterruptMsg, iso->pause_capability());
}
@@ -1584,6 +1603,7 @@
Dart_MessageNotifyCallback message_notify_callback) {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
isolate->set_message_notify_callback(message_notify_callback);
}
@@ -1591,6 +1611,7 @@
DART_EXPORT Dart_MessageNotifyCallback Dart_GetMessageNotifyCallback() {
Isolate* isolate = Isolate::Current();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
return isolate->message_notify_callback();
}
@@ -1700,6 +1721,7 @@
DART_EXPORT bool Dart_HasServiceMessages() {
Isolate* isolate = Isolate::Current();
ASSERT(isolate);
+ NoSafepointScope no_safepoint_scope;
return isolate->message_handler()->HasOOBMessages();
}
@@ -1707,6 +1729,7 @@
DART_EXPORT bool Dart_HasLivePorts() {
Isolate* isolate = Isolate::Current();
ASSERT(isolate);
+ NoSafepointScope no_safepoint_scope;
return isolate->message_handler()->HasLivePorts();
}
@@ -1784,6 +1807,7 @@
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
CHECK_ISOLATE(isolate);
+ NoSafepointScope no_safepoint_scope;
ApiLocalScope* new_scope = thread->api_reusable_scope();
if (new_scope == NULL) {
new_scope = new ApiLocalScope(thread->api_top_scope(),
@@ -1802,6 +1826,7 @@
DART_EXPORT void Dart_ExitScope() {
Thread* T = Thread::Current();
CHECK_API_SCOPE(T);
+ NoSafepointScope no_safepoint_scope;
ApiLocalScope* scope = T->api_top_scope();
ApiLocalScope* reusable_scope = T->api_reusable_scope();
T->set_api_top_scope(scope->previous()); // Reset top scope to previous.
@@ -4577,20 +4602,16 @@
if (Api::IsError(exception)) {
::Dart_PropagateError(exception);
}
-
- {
- const Instance& excp = Api::UnwrapInstanceHandle(zone, exception);
- if (excp.IsNull()) {
- RETURN_TYPE_ERROR(zone, exception, Instance);
- }
+ TransitionNativeToVM transition(thread);
+ const Instance& excp = Api::UnwrapInstanceHandle(zone, exception);
+ if (excp.IsNull()) {
+ RETURN_TYPE_ERROR(zone, exception, Instance);
}
if (thread->top_exit_frame_info() == 0) {
// There are no dart frames on the stack so it would be illegal to
// throw an exception here.
return Api::NewError("No Dart frames on stack, cannot throw exception");
}
-
- TransitionNativeToVM transition(thread);
// Unwind all the API scopes till the exit frame before throwing an
// exception.
const Instance* saved_exception;
@@ -4613,6 +4634,7 @@
Isolate* isolate = thread->isolate();
CHECK_ISOLATE(isolate);
CHECK_CALLBACK_STATE(thread);
+ TransitionNativeToVM transition(thread);
{
const Instance& excp = Api::UnwrapInstanceHandle(zone, exception);
if (excp.IsNull()) {
@@ -4628,8 +4650,6 @@
// throw an exception here.
return Api::NewError("No Dart frames on stack, cannot throw exception");
}
-
- TransitionNativeToVM transition(thread);
// Unwind all the API scopes till the exit frame before throwing an
// exception.
const Instance* saved_exception;
@@ -5124,6 +5144,7 @@
} else {
// Slow path for Mints and Bigints.
ASSERT_CALLBACK_STATE(arguments->thread());
+ TransitionNativeToVM transition(arguments->thread());
Api::SetIntegerReturnValue(arguments, retval);
}
}
@@ -5133,6 +5154,7 @@
double retval) {
NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
ASSERT_CALLBACK_STATE(arguments->thread());
+ TransitionNativeToVM transition(arguments->thread());
Api::SetDoubleReturnValue(arguments, retval);
}
@@ -5148,6 +5170,31 @@
}
+DART_EXPORT Dart_Handle Dart_DefaultCanonicalizeUrl(Dart_Handle library,
+ Dart_Handle url) {
+ API_TIMELINE_DURATION;
+ DARTSCOPE(Thread::Current());
+ CHECK_CALLBACK_STATE(T);
+
+ const Library& lib = Api::UnwrapLibraryHandle(Z, library);
+ if (lib.IsNull()) {
+ RETURN_TYPE_ERROR(Z, library, Library);
+ }
+ const String& uri = Api::UnwrapStringHandle(Z, url);
+ if (uri.IsNull()) {
+ RETURN_TYPE_ERROR(Z, url, String);
+ }
+
+ const String& lib_uri = String::Handle(Z, lib.url());
+ const char* resolved_uri;
+ if (!ResolveUri(uri.ToCString(), lib_uri.ToCString(), &resolved_uri)) {
+ return Api::NewError("%s: Unable to canonicalize uri '%s'.",
+ CURRENT_FUNC, uri.ToCString());
+ }
+ return Api::NewHandle(T, String::New(resolved_uri));
+}
+
+
// NOTE: Need to pass 'result' as a parameter here in order to avoid
// warning: variable 'result' might be clobbered by 'longjmp' or 'vfork'
// which shows up because of the use of setjmp.
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 7b5f135..5818624 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -37,7 +37,7 @@
#define FLAG_LIST(P, R, D, C) \
P(always_megamorphic_calls, bool, false, \
"Instance call always as megamorphic.") \
-P(background_compilation, bool, false, \
+P(background_compilation, bool, USING_MULTICORE, \
"Run optimizing compilation in background") \
R(background_compilation_stop_alot, false, bool, false, \
"Stress test system: stop background compiler often.") \
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index d4fd498..4778d7a 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -156,8 +156,9 @@
// TODO(vegorov) remove this once we have ported all necessary
// instructions to DBC.
if (!current->HasLocs()) {
- graph_entry_->parsed_function().Bailout("SSALivenessAnalysis",
- current->ToCString());
+ const char* msg = "SSALivenessAnalysis::ComputeInitialSets";
+ NOT_IN_PRODUCT(msg = current->ToCString());
+ graph_entry_->parsed_function().Bailout("SSALivenessAnalysis", msg);
}
#endif
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index bd07667..d1e0b85 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -2411,6 +2411,7 @@
// compiler. If it was not, set it here.
if (function.context_scope() == ContextScope::null()) {
ASSERT(!is_implicit);
+ ASSERT(node->scope() != NULL);
const ContextScope& context_scope = ContextScope::ZoneHandle(
Z, node->scope()->PreserveOuterScope(owner()->context_level()));
ASSERT(!function.HasCode());
@@ -2611,40 +2612,27 @@
}
-static intptr_t GetResultCidOfNativeFactory(const Function& function) {
+static bool IsNativeListFactory(const Function& function) {
switch (function.recognized_kind()) {
case MethodRecognizer::kTypedData_Int8Array_factory:
- return kTypedDataInt8ArrayCid;
case MethodRecognizer::kTypedData_Uint8Array_factory:
- return kTypedDataUint8ArrayCid;
case MethodRecognizer::kTypedData_Uint8ClampedArray_factory:
- return kTypedDataUint8ClampedArrayCid;
case MethodRecognizer::kTypedData_Int16Array_factory:
- return kTypedDataInt16ArrayCid;
case MethodRecognizer::kTypedData_Uint16Array_factory:
- return kTypedDataUint16ArrayCid;
case MethodRecognizer::kTypedData_Int32Array_factory:
- return kTypedDataInt32ArrayCid;
case MethodRecognizer::kTypedData_Uint32Array_factory:
- return kTypedDataUint32ArrayCid;
case MethodRecognizer::kTypedData_Int64Array_factory:
- return kTypedDataInt64ArrayCid;
case MethodRecognizer::kTypedData_Uint64Array_factory:
- return kTypedDataUint64ArrayCid;
case MethodRecognizer::kTypedData_Float32Array_factory:
- return kTypedDataFloat32ArrayCid;
case MethodRecognizer::kTypedData_Float64Array_factory:
- return kTypedDataFloat64ArrayCid;
case MethodRecognizer::kTypedData_Float32x4Array_factory:
- return kTypedDataFloat32x4ArrayCid;
case MethodRecognizer::kTypedData_Int32x4Array_factory:
- return kTypedDataInt32x4ArrayCid;
case MethodRecognizer::kTypedData_Float64x2Array_factory:
- return kTypedDataFloat64x2ArrayCid;
+ return true;
default:
break;
}
- return kDynamicCid;
+ return false;
}
@@ -2660,12 +2648,11 @@
node->arguments()->names(),
arguments,
owner()->ic_data_array());
- if (node->function().is_native()) {
- const intptr_t result_cid = GetResultCidOfNativeFactory(node->function());
- if (result_cid != kDynamicCid) {
- call->set_result_cid(result_cid);
- call->set_is_native_list_factory(true);
- }
+ if (node->function().is_native() && IsNativeListFactory(node->function())) {
+ call->set_is_native_list_factory(true);
+ }
+ if (node->function().recognized_kind() != MethodRecognizer::kUnknown) {
+ call->set_result_cid(MethodRecognizer::ResultCid(node->function()));
}
ReturnDefinition(call);
}
@@ -2819,6 +2806,9 @@
// (0) type-arguments, (1) length.
ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) ||
arguments->length() == 2);
+ } else if (node->constructor().recognized_kind() !=
+ MethodRecognizer::kUnknown) {
+ call->set_result_cid(MethodRecognizer::ResultCid(node->constructor()));
}
ReturnDefinition(call);
return;
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index d0ffe77..2ee8ed1 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -888,6 +888,15 @@
}
+CompileType PolymorphicInstanceCallInstr::ComputeType() const {
+ if (!HasSingleRecognizedTarget()) return CompileType::Dynamic();
+ const Function& target = Function::Handle(ic_data().GetTargetAt(0));
+ return (target.recognized_kind() != MethodRecognizer::kUnknown)
+ ? CompileType::FromCid(MethodRecognizer::ResultCid(target))
+ : CompileType::Dynamic();
+}
+
+
CompileType StaticCallInstr::ComputeType() const {
if (result_cid_ != kDynamicCid) {
return CompileType::FromCid(result_cid_);
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 4704219..1763877 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -3038,6 +3038,34 @@
default: return NULL;
}
}
+#else
+static void TryFastPathSmiOp(
+ FlowGraphCompiler* compiler, ICData* call_ic_data, const String& name) {
+ if (!FLAG_two_args_smi_icd) {
+ return;
+ }
+ if (name.raw() == Symbols::Plus().raw()) {
+ __ AddTOS();
+ } else if (name.raw() == Symbols::Minus().raw()) {
+ __ SubTOS();
+ } else if (name.raw() == Symbols::EqualOperator().raw()) {
+ __ EqualTOS();
+ } else if (name.raw() == Symbols::LAngleBracket().raw()) {
+ __ LessThanTOS();
+ } else if (name.raw() == Symbols::RAngleBracket().raw()) {
+ __ GreaterThanTOS();
+ } else if (name.raw() == Symbols::BitAnd().raw()) {
+ __ BitAndTOS();
+ } else if (name.raw() == Symbols::BitOr().raw()) {
+ __ BitOrTOS();
+ } else if (name.raw() == Symbols::Star().raw()) {
+ __ MulTOS();
+ } else {
+ return;
+ }
+ bool is_smi_two_args_op = call_ic_data->AddSmiSmiCheckForFastSmiStubs();
+ ASSERT(is_smi_two_args_op);
+}
#endif
@@ -3110,28 +3138,14 @@
}
}
#else
- call_ic_data = &ICData::ZoneHandle(call_ic_data->Original());
+ ICData* ic_data = &ICData::ZoneHandle(call_ic_data->Original());
// Emit smi fast path instruction. If fast-path succeeds it skips the next
// instruction otherwise it falls through.
- if (function_name().raw() == Symbols::Plus().raw()) {
- __ AddTOS();
- } else if (function_name().raw() == Symbols::EqualOperator().raw()) {
- __ EqualTOS();
- } else if (function_name().raw() == Symbols::LAngleBracket().raw()) {
- __ LessThanTOS();
- } else if (function_name().raw() == Symbols::RAngleBracket().raw()) {
- __ GreaterThanTOS();
- } else if (function_name().raw() == Symbols::BitAnd().raw()) {
- __ BitAndTOS();
- } else if (function_name().raw() == Symbols::BitOr().raw()) {
- __ BitOrTOS();
- } else if (function_name().raw() == Symbols::Star().raw()) {
- __ MulTOS();
- }
+ TryFastPathSmiOp(compiler, ic_data, function_name());
const intptr_t call_ic_data_kidx = __ AddConstant(*call_ic_data);
- switch (call_ic_data->NumArgsTested()) {
+ switch (ic_data->NumArgsTested()) {
case 1:
if (compiler->is_optimizing()) {
__ InstanceCall1Opt(ArgumentCount(), call_ic_data_kidx);
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index be04e5e..27fe9a1 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -2912,6 +2912,8 @@
return instance_call_->token_pos();
}
+ virtual CompileType ComputeType() const;
+
virtual intptr_t ArgumentCount() const {
return instance_call()->ArgumentCount();
}
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 9d167dc..a2fa2cb 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -2649,7 +2649,9 @@
compiler->AddSlowPathCode(slow_path);
__ ldr(TMP, Address(THR, Thread::stack_limit_offset()));
- __ CompareRegisters(SP, TMP);
+ // Compare to CSP not SP because CSP is closer to the stack limit. See
+ // Assembler::EnterFrame.
+ __ CompareRegisters(CSP, TMP);
__ b(slow_path->entry_label(), LS);
if (compiler->CanOSRFunction() && in_loop()) {
const Register temp = locs()->temp(0).reg();
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
index 16a2baf..4af998e 100644
--- a/runtime/vm/intermediate_language_dbc.cc
+++ b/runtime/vm/intermediate_language_dbc.cc
@@ -212,7 +212,11 @@
void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+#if defined(PRODUCT)
+ compiler->Bailout("PolymorphicInstanceCallInstr::EmitNativeCode");
+#else // defined(PRODUCT)
compiler->Bailout(ToCString());
+#endif // defined(PRODUCT)
}
@@ -505,7 +509,11 @@
EMIT_NATIVE_CODE(StoreIndexed, 3) {
if (compiler->is_optimizing()) {
if (class_id() != kArrayCid) {
+#if defined(PRODUCT)
+ compiler->Bailout("StoreIndexed");
+#else // defined(PRODUCT)
compiler->Bailout(ToCString());
+#endif // defined(PRODUCT)
}
__ StoreIndexed(locs()->in(kArrayPos).reg(),
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index bdd7c5c..03ffd48 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -68,7 +68,7 @@
String& str = String::Handle(zone);
Error& error = Error::Handle(zone);
-#define SETUP_FUNCTION(class_name, function_name, destination, fp) \
+#define SETUP_FUNCTION(class_name, function_name, destination, type, fp) \
if (strcmp(#class_name, "::") == 0) { \
str = String::New(#function_name); \
func = lib.LookupFunctionAllowPrivate(str); \
@@ -179,7 +179,7 @@
FlowGraph* graph = new FlowGraph(parsed_function, graph_entry, block_id);
const Function& function = parsed_function.function();
switch (function.recognized_kind()) {
-#define EMIT_CASE(class_name, function_name, enum_name, fp) \
+#define EMIT_CASE(class_name, function_name, enum_name, type, fp) \
case MethodRecognizer::k##enum_name: \
if (!Build_##enum_name(graph)) return false; \
break;
@@ -227,7 +227,7 @@
return;
}
-#define EMIT_CASE(class_name, function_name, enum_name, fp) \
+#define EMIT_CASE(class_name, function_name, enum_name, type, fp) \
case MethodRecognizer::k##enum_name: \
compiler->assembler()->Comment("Intrinsic"); \
enum_name(compiler->assembler()); \
diff --git a/runtime/vm/intrinsifier.h b/runtime/vm/intrinsifier.h
index 54eec6e..100dee4 100644
--- a/runtime/vm/intrinsifier.h
+++ b/runtime/vm/intrinsifier.h
@@ -38,7 +38,7 @@
private:
static bool CanIntrinsify(const Function& function);
-#define DECLARE_FUNCTION(test_class_name, test_function_name, enum_name, fp) \
+#define DECLARE_FUNCTION(class_name, function_name, enum_name, type, fp) \
static void enum_name(Assembler* assembler);
ALL_INTRINSICS_LIST(DECLARE_FUNCTION)
@@ -50,7 +50,7 @@
#undef DECLARE_FUNCTION
#if !defined(TARGET_ARCH_DBC)
-#define DECLARE_FUNCTION(test_class_name, test_function_name, enum_name, fp) \
+#define DECLARE_FUNCTION(class_name, function_name, enum_name, type, fp) \
static bool Build_##enum_name(FlowGraph* flow_graph);
GRAPH_INTRINSICS_LIST(DECLARE_FUNCTION)
diff --git a/runtime/vm/intrinsifier_dbc.cc b/runtime/vm/intrinsifier_dbc.cc
index 21a3ae0..3d0b5d1 100644
--- a/runtime/vm/intrinsifier_dbc.cc
+++ b/runtime/vm/intrinsifier_dbc.cc
@@ -23,7 +23,7 @@
intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
-#define DEFINE_FUNCTION(test_class_name, test_function_name, enum_name, fp) \
+#define DEFINE_FUNCTION(class_name, test_function_name, enum_name, type, fp) \
void Intrinsifier::enum_name(Assembler* assembler) { \
if (Simulator::IsSupportedIntrinsic(Simulator::k##enum_name##Intrinsic)) { \
assembler->Intrinsic(Simulator::k##enum_name##Intrinsic); \
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 0291517..5913789 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -408,7 +408,7 @@
class_table->HasValidClassAt(i)) {
// Copy the class into the saved class table and add it to the set.
local_saved_class_table[i] = class_table->At(i);
- if (i != kFreeListElement) {
+ if (i != kFreeListElement && i != kForwardingCorpse) {
cls = class_table->At(i);
bool already_present = old_classes_set.Insert(cls);
ASSERT(!already_present);
@@ -971,8 +971,8 @@
}
virtual void VisitObject(RawObject* obj) {
- // Free-list elements cannot even be wrapped in handles.
- if (obj->IsFreeListElement()) {
+ if (obj->IsPseudoObject()) {
+ // Cannot even be wrapped in handles.
return;
}
handle_ = obj;
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index b6d1382..9b45046 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -648,7 +648,7 @@
TEST_CASE(IsolateReload_LiveStack) {
const char* kScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"helper() => 7;\n"
"alpha() { var x = helper(); reloadTest(); return x + helper(); }\n"
"foo() => alpha();\n"
@@ -661,7 +661,7 @@
EXPECT_VALID(lib);
const char* kReloadScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"helper() => 100;\n"
"alpha() => 5 + helper();\n"
"foo() => alpha();\n"
@@ -694,41 +694,41 @@
EXPECT_ERROR(SimpleInvokeError(lib, "main"), "importedFunc");
- // Fail to find 'importable_test_lib' in the isolate.
- result = Dart_LookupLibrary(NewString("importable_test_lib"));
+ // Fail to find 'test:importable_lib' in the isolate.
+ result = Dart_LookupLibrary(NewString("test:importable_lib"));
EXPECT(Dart_IsError(result));
const char* kReloadScript =
- "import 'importable_test_lib';\n"
+ "import 'test:importable_lib';\n"
"main() {\n"
" return importedFunc();\n"
"}\n";
- // Reload and add 'importable_test_lib' to isolate.
+ // Reload and add 'test:importable_lib' to isolate.
lib = TestCase::ReloadTestScript(kReloadScript);
EXPECT_VALID(lib);
EXPECT_STREQ("a", SimpleInvokeStr(lib, "main"));
- // Find 'importable_test_lib' in the isolate.
- result = Dart_LookupLibrary(NewString("importable_test_lib"));
+ // Find 'test:importable_lib' in the isolate.
+ result = Dart_LookupLibrary(NewString("test:importable_lib"));
EXPECT(Dart_IsLibrary(result));
// Reload and remove 'dart:math' from isolate.
lib = TestCase::ReloadTestScript(kScript);
EXPECT_VALID(lib);
- // Fail to find 'importable_test_lib' in the isolate.
- result = Dart_LookupLibrary(NewString("importable_test_lib"));
+ // Fail to find 'test:importable_lib' in the isolate.
+ result = Dart_LookupLibrary(NewString("test:importable_lib"));
EXPECT(Dart_IsError(result));
}
TEST_CASE(IsolateReload_LibraryHide) {
- // Import 'importable_test_lib' with importedFunc hidden. Will result in an
+ // Import 'test:importable_lib' with importedFunc hidden. Will result in an
// error.
const char* kScript =
- "import 'importable_test_lib' hide importedFunc;\n"
+ "import 'test:importable_lib' hide importedFunc;\n"
"main() {\n"
" return importedFunc();\n"
"}\n";
@@ -740,9 +740,9 @@
EXPECT_ERROR(SimpleInvokeError(lib, "main"), "importedFunc");
- // Import 'importable_test_lib'.
+ // Import 'test:importable_lib'.
const char* kReloadScript =
- "import 'importable_test_lib';\n"
+ "import 'test:importable_lib';\n"
"main() {\n"
" return importedFunc();\n"
"}\n";
@@ -755,10 +755,10 @@
TEST_CASE(IsolateReload_LibraryShow) {
- // Import 'importable_test_lib' with importedIntFunc visible. Will result in
+ // Import 'test:importable_lib' with importedIntFunc visible. Will result in
// an error when 'main' is invoked.
const char* kScript =
- "import 'importable_test_lib' show importedIntFunc;\n"
+ "import 'test:importable_lib' show importedIntFunc;\n"
"main() {\n"
" return importedFunc();\n"
"}\n"
@@ -775,10 +775,10 @@
// Results in an error.
EXPECT_ERROR(SimpleInvokeError(lib, "main"), "importedFunc");
- // Import 'importable_test_lib' with importedFunc visible. Will result in
+ // Import 'test:importable_lib' with importedFunc visible. Will result in
// an error when 'mainInt' is invoked.
const char* kReloadScript =
- "import 'importable_test_lib' show importedFunc;\n"
+ "import 'test:importable_lib' show importedFunc;\n"
"main() {\n"
" return importedFunc();\n"
"}\n"
@@ -800,8 +800,8 @@
// that is compatible with the fast path smi stubs.
TEST_CASE(IsolateReload_SmiFastPathStubs) {
const char* kScript =
- "import 'isolate_reload_test_helper';\n"
- "import 'importable_test_lib' show importedIntFunc;\n"
+ "import 'test:isolate_reload_helper';\n"
+ "import 'test:importable_lib' show importedIntFunc;\n"
"main() {\n"
" var x = importedIntFunc();\n"
" var y = importedIntFunc();\n"
@@ -824,7 +824,7 @@
// mixins when we reload.
TEST_CASE(IsolateReload_ImportedMixinFunction) {
const char* kScript =
- "import 'importable_test_lib' show ImportedMixin;\n"
+ "import 'test:importable_lib' show ImportedMixin;\n"
"class A extends Object with ImportedMixin {\n"
"}"
"var func = new A().mixinFunc;\n"
@@ -838,7 +838,7 @@
EXPECT_STREQ("mixin", SimpleInvokeStr(lib, "main"));
const char* kReloadScript =
- "import 'importable_test_lib' show ImportedMixin;\n"
+ "import 'test:importable_lib' show ImportedMixin;\n"
"class A extends Object with ImportedMixin {\n"
"}"
"var func;\n"
@@ -877,7 +877,7 @@
TEST_CASE(IsolateReload_PendingUnqualifiedCall_StaticToInstance) {
const char* kScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"class C {\n"
" static foo() => 'static';\n"
" test() {\n"
@@ -893,7 +893,7 @@
EXPECT_VALID(lib);
const char* kReloadScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"class C {\n"
" foo() => 'instance';\n"
" test() {\n"
@@ -918,7 +918,7 @@
TEST_CASE(IsolateReload_PendingUnqualifiedCall_InstanceToStatic) {
const char* kScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"class C {\n"
" foo() => 'instance';\n"
" test() {\n"
@@ -934,7 +934,7 @@
EXPECT_VALID(lib);
const char* kReloadScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"class C {\n"
" static foo() => 'static';\n"
" test() {\n"
@@ -959,7 +959,7 @@
TEST_CASE(IsolateReload_PendingConstructorCall_AbstractToConcrete) {
const char* kScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"abstract class Foo {}\n"
"class C {\n"
" test() {\n"
@@ -980,7 +980,7 @@
EXPECT_VALID(lib);
const char* kReloadScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"class Foo {}\n"
"class C {\n"
" test() {\n"
@@ -1010,7 +1010,7 @@
TEST_CASE(IsolateReload_PendingConstructorCall_ConcreteToAbstract) {
const char* kScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"class Foo {}\n"
"class C {\n"
" test() {\n"
@@ -1031,7 +1031,7 @@
EXPECT_VALID(lib);
const char* kReloadScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"abstract class Foo {}\n"
"class C {\n"
" test() {\n"
@@ -1061,7 +1061,7 @@
TEST_CASE(IsolateReload_PendingStaticCall_DefinedToNSM) {
const char* kScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"class C {\n"
" static foo() => 'static'\n"
" test() {\n"
@@ -1081,7 +1081,7 @@
EXPECT_VALID(lib);
const char* kReloadScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"class C {\n"
" test() {\n"
" reloadTest();\n"
@@ -1109,7 +1109,7 @@
TEST_CASE(IsolateReload_PendingStaticCall_NSMToDefined) {
const char* kScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"class C {\n"
" test() {\n"
" reloadTest();\n"
@@ -1128,7 +1128,7 @@
EXPECT_VALID(lib);
const char* kReloadScript =
- "import 'isolate_reload_test_helper';\n"
+ "import 'test:isolate_reload_helper';\n"
"class C {\n"
" static foo() => 'static'\n"
" test() {\n"
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
index 2efe245..b8ac4b6 100644
--- a/runtime/vm/lockers.cc
+++ b/runtime/vm/lockers.cc
@@ -12,11 +12,11 @@
static void updateThreadState(Thread* thread) {
// First try a fast update of the thread state to indicate it is not at a
// safepoint anymore.
- uword old_state = Thread::SetAtSafepoint(true, 0);
+ uint32_t old_state = Thread::SetAtSafepoint(true, 0);
uword addr =
reinterpret_cast<uword>(thread) + Thread::safepoint_state_offset();
- if (AtomicOperations::CompareAndSwapWord(
- reinterpret_cast<uword*>(addr), old_state, 0) != old_state) {
+ if (AtomicOperations::CompareAndSwapUint32(
+ reinterpret_cast<uint32_t*>(addr), old_state, 0) != old_state) {
// Fast update failed which means we could potentially be in the middle
// of a safepoint operation and need to block for it.
SafepointHandler* handler = thread->isolate()->safepoint_handler();
@@ -34,11 +34,11 @@
Monitor::WaitResult result = monitor_->Wait(millis);
// First try a fast update of the thread state to indicate it is not at a
// safepoint anymore.
- uword old_state = Thread::SetAtSafepoint(true, 0);
+ uint32_t old_state = Thread::SetAtSafepoint(true, 0);
uword addr =
reinterpret_cast<uword>(thread) + Thread::safepoint_state_offset();
- if (AtomicOperations::CompareAndSwapWord(
- reinterpret_cast<uword*>(addr), old_state, 0) != old_state) {
+ if (AtomicOperations::CompareAndSwapUint32(
+ reinterpret_cast<uint32_t*>(addr), old_state, 0) != old_state) {
// Fast update failed which means we could potentially be in the middle
// of a safepoint operation and need to block for it.
monitor_->Exit();
@@ -98,11 +98,11 @@
Monitor::WaitResult result = monitor_->Wait(millis);
// First try a fast update of the thread state to indicate it is not at a
// safepoint anymore.
- uword old_state = Thread::SetAtSafepoint(true, 0);
+ uint32_t old_state = Thread::SetAtSafepoint(true, 0);
uword addr =
reinterpret_cast<uword>(thread) + Thread::safepoint_state_offset();
- if (AtomicOperations::CompareAndSwapWord(
- reinterpret_cast<uword*>(addr), old_state, 0) != old_state) {
+ if (AtomicOperations::CompareAndSwapUint32(
+ reinterpret_cast<uint32_t*>(addr), old_state, 0) != old_state) {
// Fast update failed which means we could potentially be in the middle
// of a safepoint operation and need to block for it.
monitor_->Exit();
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index 8784651..5e5f685 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -457,6 +457,11 @@
}
+void MessageHandler::DebugDump() {
+ PortMap::DebugDumpForMessageHandler(this);
+}
+
+
void MessageHandler::PausedOnStartLocked(MonitorLocker* ml, bool paused) {
if (paused) {
ASSERT(!is_paused_on_start_);
diff --git a/runtime/vm/message_handler.h b/runtime/vm/message_handler.h
index 1d039c5..c52431d 100644
--- a/runtime/vm/message_handler.h
+++ b/runtime/vm/message_handler.h
@@ -81,6 +81,8 @@
return live_ports_;
}
+ void DebugDump();
+
bool paused() const { return paused_ > 0; }
void increment_paused() { paused_++; }
diff --git a/runtime/vm/method_recognizer.cc b/runtime/vm/method_recognizer.cc
index 45a6f59..03014ac 100644
--- a/runtime/vm/method_recognizer.cc
+++ b/runtime/vm/method_recognizer.cc
@@ -25,7 +25,19 @@
}
-#define KIND_TO_STRING(class_name, function_name, enum_name, fp) \
+intptr_t MethodRecognizer::ResultCid(const Function& function) {
+ switch (function.recognized_kind()) {
+#define DEFINE_CASE(cname, fname, ename, result_type, fingerprint) \
+ case k##ename: return k##result_type##Cid;
+ RECOGNIZED_LIST(DEFINE_CASE)
+#undef DEFINE_CASE
+ default:
+ return kDynamicCid;
+ }
+}
+
+
+#define KIND_TO_STRING(class_name, function_name, enum_name, type, fp) \
#enum_name,
static const char* recognized_list_method_name[] = {
"Unknown",
@@ -51,7 +63,7 @@
libs.Add(&Library::ZoneHandle(Library::DeveloperLibrary()));
Function& func = Function::Handle();
-#define SET_RECOGNIZED_KIND(class_name, function_name, enum_name, fp) \
+#define SET_RECOGNIZED_KIND(class_name, function_name, enum_name, type, fp) \
func = Library::GetFunction(libs, #class_name, #function_name); \
if (func.IsNull()) { \
OS::PrintErr("Missing %s::%s\n", #class_name, #function_name); \
@@ -74,7 +86,7 @@
#define SET_IS_ALWAYS_INLINE(class_name, function_name, dest, fp) \
SET_FUNCTION_BIT(class_name, function_name, dest, fp, set_always_inline, true)
-#define SET_IS_NEVER_INLINE(class_name, function_name, dest, fp) \
+#define SET_IS_NEVER_INLINE(class_name, function_name, dest, fp) \
SET_FUNCTION_BIT(class_name, function_name, dest, fp, set_is_inlinable, false)
#define SET_IS_POLYMORPHIC_TARGET(class_name, function_name, dest, fp) \
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h
index 6d7e1e8..33b7f42 100644
--- a/runtime/vm/method_recognizer.h
+++ b/runtime/vm/method_recognizer.h
@@ -9,293 +9,319 @@
namespace dart {
-// (class-name, function-name, recognized enum, fingerprint).
+// (class-name, function-name, recognized enum, result type, fingerprint).
// When adding a new function add a 0 as fingerprint, build and run to get the
// correct fingerprint from the mismatch error.
#define OTHER_RECOGNIZED_LIST(V) \
- V(::, identical, ObjectIdentical, 317103244) \
- V(ClassID, getID, ClassIDgetID, 1385157717) \
- V(Object, Object., ObjectConstructor, 1746278398) \
- V(_List, ., ObjectArrayAllocate, 1661438741) \
- V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 1508321565) \
- V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 953411007) \
- V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 433971756) \
- V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1329446488) \
- V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 137212209) \
- V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 499907480) \
- V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 1639388276) \
- V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 1672834581) \
- V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 966634744) \
- V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1197581758) \
- V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 810805548) \
- V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 1317196265) \
- V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 1328908284) \
- V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1827614958) \
- V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 1694054572) \
- V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 915652649) \
- V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1958474336) \
- V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 1970687707) \
- V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1853026980) \
- V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1197862362) \
- V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 2093630771) \
- V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 1982971324) \
- V(_StringBase, _interpolate, StringBaseInterpolate, 1872292681) \
- V(_IntegerImplementation, toDouble, IntegerToDouble, 792762465) \
- V(_Double, _add, DoubleAdd, 2213216) \
- V(_Double, _sub, DoubleSub, 1100692582) \
- V(_Double, _mul, DoubleMul, 436784097) \
- V(_Double, _div, DoubleDiv, 953317135) \
- V(::, min, MathMin, 1115051548) \
- V(::, max, MathMax, 1410473322) \
- V(::, _doublePow, MathDoublePow, 1770960781) \
- V(Float32x4, Float32x4., Float32x4Constructor, 93751705) \
- V(Float32x4, Float32x4.zero, Float32x4Zero, 1193954374) \
- V(Float32x4, Float32x4.splat, Float32x4Splat, 12296613) \
- V(Float32x4, Float32x4.fromInt32x4Bits, Float32x4FromInt32x4Bits, 1188039061)\
- V(Float32x4, Float32x4.fromFloat64x2, Float32x4FromFloat64x2, 1750763218) \
- V(Float32x4, shuffle, Float32x4Shuffle, 2015957023) \
- V(Float32x4, shuffleMix, Float32x4ShuffleMix, 1099087979) \
- V(Float32x4, get:signMask, Float32x4GetSignMask, 487049875) \
- V(Float32x4, _cmpequal, Float32x4Equal, 127403211) \
- V(Float32x4, _cmpgt, Float32x4GreaterThan, 2118391173) \
- V(Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, 557807661) \
- V(Float32x4, _cmplt, Float32x4LessThan, 1061691185) \
- V(Float32x4, _cmplte, Float32x4LessThanOrEqual, 102608993) \
- V(Float32x4, _cmpnequal, Float32x4NotEqual, 1873649982) \
- V(Float32x4, _min, Float32x4Min, 1158016632) \
- V(Float32x4, _max, Float32x4Max, 118915526) \
- V(Float32x4, _scale, Float32x4Scale, 415757469) \
- V(Float32x4, _sqrt, Float32x4Sqrt, 1934518992) \
- V(Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, 1586141174) \
- V(Float32x4, _reciprocal, Float32x4Reciprocal, 1651466502) \
- V(Float32x4, _negate, Float32x4Negate, 2142478676) \
- V(Float32x4, _abs, Float32x4Absolute, 337704007) \
- V(Float32x4, _clamp, Float32x4Clamp, 1107305005) \
- V(Float32x4, withX, Float32x4WithX, 1311992575) \
- V(Float32x4, withY, Float32x4WithY, 175290640) \
- V(Float32x4, withZ, Float32x4WithZ, 837367384) \
- V(Float32x4, withW, Float32x4WithW, 1625145605) \
- V(Float64x2, Float64x2., Float64x2Constructor, 423355933) \
- V(Float64x2, Float64x2.zero, Float64x2Zero, 2066666975) \
- V(Float64x2, Float64x2.splat, Float64x2Splat, 716962994) \
- V(Float64x2, Float64x2.fromFloat32x4, Float64x2FromFloat32x4, 792974246) \
- V(Float64x2, get:x, Float64x2GetX, 1488958362) \
- V(Float64x2, get:y, Float64x2GetY, 1022688506) \
- V(Float64x2, _negate, Float64x2Negate, 1693416311) \
- V(Float64x2, abs, Float64x2Abs, 52403783) \
- V(Float64x2, sqrt, Float64x2Sqrt, 2012680669) \
- V(Float64x2, get:signMask, Float64x2GetSignMask, 668856717) \
- V(Float64x2, scale, Float64x2Scale, 646122081) \
- V(Float64x2, withX, Float64x2WithX, 489409269) \
- V(Float64x2, withY, Float64x2WithY, 943642284) \
- V(Float64x2, min, Float64x2Min, 685235702) \
- V(Float64x2, max, Float64x2Max, 198659675) \
- V(Int32x4, Int32x4., Int32x4Constructor, 649173415) \
- V(Int32x4, Int32x4.bool, Int32x4BoolConstructor, 458597857) \
- V(Int32x4, Int32x4.fromFloat32x4Bits, Int32x4FromFloat32x4Bits, 2122470988) \
- V(Int32x4, get:flagX, Int32x4GetFlagX, 1446544324) \
- V(Int32x4, get:flagY, Int32x4GetFlagY, 1148149370) \
- V(Int32x4, get:flagZ, Int32x4GetFlagZ, 550901369) \
- V(Int32x4, get:flagW, Int32x4GetFlagW, 1346664620) \
- V(Int32x4, get:signMask, Int32x4GetSignMask, 740215269) \
- V(Int32x4, shuffle, Int32x4Shuffle, 549194518) \
- V(Int32x4, shuffleMix, Int32x4ShuffleMix, 1550866145) \
- V(Int32x4, select, Int32x4Select, 1368318775) \
- V(Int32x4, withFlagX, Int32x4WithFlagX, 250974159) \
- V(Int32x4, withFlagY, Int32x4WithFlagY, 1686481348) \
- V(Int32x4, withFlagZ, Int32x4WithFlagZ, 645582330) \
- V(Int32x4, withFlagW, Int32x4WithFlagW, 878364277) \
- V(Float32List, [], Float32ArrayGetIndexed, 1451643535) \
- V(Float32List, []=, Float32ArraySetIndexed, 453873887) \
- V(Int8List, [], Int8ArrayGetIndexed, 110819507) \
- V(Int8List, []=, Int8ArraySetIndexed, 865684695) \
- V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 41288685) \
- V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 687206488) \
+ V(::, identical, ObjectIdentical, Bool, 0x12e69c8c) \
+ V(ClassID, getID, ClassIDgetID, Smi, 0x528fd455) \
+ V(Object, Object., ObjectConstructor, Dynamic, 0x681617fe) \
+ V(_List, ., ObjectArrayAllocate, Array, 0x63078b15) \
+ V(_TypedList, _getInt8, ByteArrayBaseGetInt8, Smi, 0x59e7291d) \
+ V(_TypedList, _getUint8, ByteArrayBaseGetUint8, Smi, 0x38d3e5bf) \
+ V(_TypedList, _getInt16, ByteArrayBaseGetInt16, Smi, 0x19dde22c) \
+ V(_TypedList, _getUint16, ByteArrayBaseGetUint16, Smi, 0x4f3dbe58) \
+ V(_TypedList, _getInt32, ByteArrayBaseGetInt32, Dynamic, 0x082db131) \
+ V(_TypedList, _getUint32, ByteArrayBaseGetUint32, Dynamic, 0x1dcbfb98) \
+ V(_TypedList, _getInt64, ByteArrayBaseGetInt64, Dynamic, 0x61b71474) \
+ V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, Double, 0x63b56e15) \
+ V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, Double, 0x399dacf8) \
+ V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, Float32x4, \
+ 0x4761a5be) \
+ V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, Int32x4, 0x3053e92c) \
+ V(_TypedList, _setInt8, ByteArrayBaseSetInt8, Dynamic, 0x4e82d1e9) \
+ V(_TypedList, _setUint8, ByteArrayBaseSetUint8, Dynamic, 0x4f3587fc) \
+ V(_TypedList, _setInt16, ByteArrayBaseSetInt16, Dynamic, 0x6cef30ee) \
+ V(_TypedList, _setUint16, ByteArrayBaseSetUint16, Dynamic, 0x64f938ac) \
+ V(_TypedList, _setInt32, ByteArrayBaseSetInt32, Dynamic, 0x3693c029) \
+ V(_TypedList, _setUint32, ByteArrayBaseSetUint32, Dynamic, 0x74bbf260) \
+ V(_TypedList, _setInt64, ByteArrayBaseSetInt64, Dynamic, 0x75764edb) \
+ V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, Dynamic, 0x6e72f2a4) \
+ V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, Dynamic, 0x4765edda) \
+ V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, Dynamic, 0x7cca4533) \
+ V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, Dynamic, 0x7631bdbc) \
+ V(_StringBase, _interpolate, StringBaseInterpolate, Dynamic, 0x6f98eb49) \
+ V(_IntegerImplementation, toDouble, IntegerToDouble, Double, 0x2f409861) \
+ V(_Double, _add, DoubleAdd, Double, 0x0021c560) \
+ V(_Double, _sub, DoubleSub, Double, 0x419b3c66) \
+ V(_Double, _mul, DoubleMul, Double, 0x1a08cbe1) \
+ V(_Double, _div, DoubleDiv, Double, 0x38d2770f) \
+ V(::, min, MathMin, Dynamic, 0x4276561c) \
+ V(::, max, MathMax, Dynamic, 0x54121d6a) \
+ V(::, _doublePow, MathDoublePow, Double, 0x698eb78d) \
+ V(Float32x4, Float32x4., Float32x4Constructor, Float32x4, 0x05968999) \
+ V(Float32x4, Float32x4.zero, Float32x4Zero, Float32x4, 0x472a4c46) \
+ V(Float32x4, Float32x4.splat, Float32x4Splat, Float32x4, 0x00bba1a5) \
+ V(Float32x4, Float32x4.fromInt32x4Bits, Float32x4FromInt32x4Bits, Float32x4, \
+ 0x46d00995) \
+ V(Float32x4, Float32x4.fromFloat64x2, Float32x4FromFloat64x2, Float32x4, \
+ 0x685a86d2) \
+ V(Float32x4, shuffle, Float32x4Shuffle, Float32x4, 0x7829101f) \
+ V(Float32x4, shuffleMix, Float32x4ShuffleMix, Float32x4, 0x4182c06b) \
+ V(Float32x4, get:signMask, Float32x4GetSignMask, Dynamic, 0x1d07ca93) \
+ V(Float32x4, _cmpequal, Float32x4Equal, Int32x4, 0x079804cb) \
+ V(Float32x4, _cmpgt, Float32x4GreaterThan, Int32x4, 0x7e441585) \
+ V(Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, Int32x4, 0x213f782d) \
+ V(Float32x4, _cmplt, Float32x4LessThan, Int32x4, 0x3f481f31) \
+ V(Float32x4, _cmplte, Float32x4LessThanOrEqual, Int32x4, 0x061db061) \
+ V(Float32x4, _cmpnequal, Float32x4NotEqual, Int32x4, 0x6fada13e) \
+ V(Float32x4, _min, Float32x4Min, Float32x4, 0x4505ee78) \
+ V(Float32x4, _max, Float32x4Max, Float32x4, 0x071681c6) \
+ V(Float32x4, _scale, Float32x4Scale, Float32x4, 0x18c7f49d) \
+ V(Float32x4, _sqrt, Float32x4Sqrt, Float32x4, 0x734e6ad0) \
+ V(Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, Float32x4, \
+ 0x5e8a97f6) \
+ V(Float32x4, _reciprocal, Float32x4Reciprocal, Float32x4, 0x626f6106) \
+ V(Float32x4, _negate, Float32x4Negate, Float32x4, 0x7fb3a154) \
+ V(Float32x4, _abs, Float32x4Absolute, Float32x4, 0x1420f447) \
+ V(Float32x4, _clamp, Float32x4Clamp, Float32x4, 0x4200222d) \
+ V(Float32x4, withX, Float32x4WithX, Float32x4, 0x4e336aff) \
+ V(Float32x4, withY, Float32x4WithY, Float32x4, 0x0a72b910) \
+ V(Float32x4, withZ, Float32x4WithZ, Float32x4, 0x31e93658) \
+ V(Float32x4, withW, Float32x4WithW, Float32x4, 0x60ddc105) \
+ V(Float64x2, Float64x2., Float64x2Constructor, Float64x2, 0x193be61d) \
+ V(Float64x2, Float64x2.zero, Float64x2Zero, Float64x2, 0x7b2ed5df) \
+ V(Float64x2, Float64x2.splat, Float64x2Splat, Float64x2, 0x2abbfcb2) \
+ V(Float64x2, Float64x2.fromFloat32x4, Float64x2FromFloat32x4, Float64x2, \
+ 0x2f43d3a6) \
+ V(Float64x2, get:x, Float64x2GetX, Double, 0x58bfb39a) \
+ V(Float64x2, get:y, Float64x2GetY, Double, 0x3cf4fcfa) \
+ V(Float64x2, _negate, Float64x2Negate, Float64x2, 0x64ef7b77) \
+ V(Float64x2, abs, Float64x2Abs, Float64x2, 0x031f9e47) \
+ V(Float64x2, sqrt, Float64x2Sqrt, Float64x2, 0x77f711dd) \
+ V(Float64x2, get:signMask, Float64x2GetSignMask, Dynamic, 0x27ddf18d) \
+ V(Float64x2, scale, Float64x2Scale, Float64x2, 0x26830a61) \
+ V(Float64x2, withX, Float64x2WithX, Float64x2, 0x1d2bcaf5) \
+ V(Float64x2, withY, Float64x2WithY, Float64x2, 0x383ed6ac) \
+ V(Float64x2, min, Float64x2Min, Float64x2, 0x28d7ddf6) \
+ V(Float64x2, max, Float64x2Max, Float64x2, 0x0bd74e5b) \
+ V(Int32x4, Int32x4., Int32x4Constructor, Int32x4, 0x26b199a7) \
+ V(Int32x4, Int32x4.bool, Int32x4BoolConstructor, Int32x4, 0x1b55a5e1) \
+ V(Int32x4, Int32x4.fromFloat32x4Bits, Int32x4FromFloat32x4Bits, Int32x4, \
+ 0x7e82564c) \
+ V(Int32x4, get:flagX, Int32x4GetFlagX, Bool, 0x563883c4) \
+ V(Int32x4, get:flagY, Int32x4GetFlagY, Bool, 0x446f5e7a) \
+ V(Int32x4, get:flagZ, Int32x4GetFlagZ, Bool, 0x20d61679) \
+ V(Int32x4, get:flagW, Int32x4GetFlagW, Bool, 0x504478ac) \
+ V(Int32x4, get:signMask, Int32x4GetSignMask, Dynamic, 0x2c1ec9e5) \
+ V(Int32x4, shuffle, Int32x4Shuffle, Int32x4, 0x20bc0b16) \
+ V(Int32x4, shuffleMix, Int32x4ShuffleMix, Int32x4, 0x5c7056e1) \
+ V(Int32x4, select, Int32x4Select, Float32x4, 0x518ee337) \
+ V(Int32x4, withFlagX, Int32x4WithFlagX, Int32x4, 0x0ef58fcf) \
+ V(Int32x4, withFlagY, Int32x4WithFlagY, Int32x4, 0x6485a9c4) \
+ V(Int32x4, withFlagZ, Int32x4WithFlagZ, Int32x4, 0x267acdfa) \
+ V(Int32x4, withFlagW, Int32x4WithFlagW, Int32x4, 0x345ac675) \
+ V(Float32List, [], Float32ArrayGetIndexed, Double, 0x5686528f) \
+ V(Float32List, []=, Float32ArraySetIndexed, Dynamic, 0x1b0d90df) \
+ V(Int8List, [], Int8ArrayGetIndexed, Smi, 0x069af8b3) \
+ V(Int8List, []=, Int8ArraySetIndexed, Dynamic, 0x33994cd7) \
+ V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, Smi, 0x027603ed) \
+ V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, Dynamic, 0x28f5f058) \
V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed, \
- 41288685) \
+ Smi, 0x027603ed) \
V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed, \
- 687206488) \
- V(Int16List, [], Int16ArrayGetIndexed, 389863073) \
- V(Int16List, []=, Int16ArraySetIndexed, 855133756) \
- V(Uint16List, [], Uint16ArrayGetIndexed, 1053739567) \
- V(Uint16List, []=, Uint16ArraySetIndexed, 1547307961) \
- V(Int32List, [], Int32ArrayGetIndexed, 640610057) \
- V(Int32List, []=, Int32ArraySetIndexed, 453358705) \
- V(Int64List, [], Int64ArrayGetIndexed, 202150810) \
- V(Int64List, []=, Int64ArraySetIndexed, 924110852) \
- V(Float32x4List, [], Float32x4ArrayGetIndexed, 29819259) \
- V(Float32x4List, []=, Float32x4ArraySetIndexed, 1458062250) \
- V(Int32x4List, [], Int32x4ArrayGetIndexed, 137707405) \
- V(Int32x4List, []=, Int32x4ArraySetIndexed, 496650149) \
- V(Float64x2List, [], Float64x2ArrayGetIndexed, 1721439384) \
- V(Float64x2List, []=, Float64x2ArraySetIndexed, 1994027006) \
- V(_Bigint, get:_neg, Bigint_getNeg, 2079423063) \
- V(_Bigint, get:_used, Bigint_getUsed, 1426329619) \
- V(_Bigint, get:_digits, Bigint_getDigits, 1185333683) \
- V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 2104211307) \
- V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 1273697266) \
- V(_HashVMBase, get:_data, LinkedHashMap_getData, 1274399923) \
- V(_HashVMBase, set:_data, LinkedHashMap_setData, 1611093357) \
- V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 367462469) \
- V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 1049390812) \
- V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 902147072) \
- V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 1236137630) \
- V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 812542585) \
- V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 1072259010) \
+ Dynamic, 0x28f5f058) \
+ V(Int16List, [], Int16ArrayGetIndexed, Smi, 0x173cd6a1) \
+ V(Int16List, []=, Int16ArraySetIndexed, Dynamic, 0x32f84e3c) \
+ V(Uint16List, [], Uint16ArrayGetIndexed, Smi, 0x3ececa2f) \
+ V(Uint16List, []=, Uint16ArraySetIndexed, Dynamic, 0x5c3a0bb9) \
+ V(Int32List, [], Int32ArrayGetIndexed, Dynamic, 0x262eef09) \
+ V(Int32List, []=, Int32ArraySetIndexed, Dynamic, 0x1b05b471) \
+ V(Int64List, [], Int64ArrayGetIndexed, Dynamic, 0x0c0c939a) \
+ V(Int64List, []=, Int64ArraySetIndexed, Dynamic, 0x3714d004) \
+ V(Float32x4List, [], Float32x4ArrayGetIndexed, Float32x4, 0x01c7017b) \
+ V(Float32x4List, []=, Float32x4ArraySetIndexed, Dynamic, 0x56e843aa) \
+ V(Int32x4List, [], Int32x4ArrayGetIndexed, Int32x4, 0x08353f8d) \
+ V(Int32x4List, []=, Int32x4ArraySetIndexed, Dynamic, 0x1d9a47a5) \
+ V(Float64x2List, [], Float64x2ArrayGetIndexed, Float64x2, 0x669b1498) \
+ V(Float64x2List, []=, Float64x2ArraySetIndexed, Dynamic, 0x76da6ffe) \
+ V(_Bigint, get:_neg, Bigint_getNeg, Bool, 0x7bf17a57) \
+ V(_Bigint, get:_used, Bigint_getUsed, Smi, 0x55041013) \
+ V(_Bigint, get:_digits, Bigint_getDigits, TypedDataUint32Array, 0x46a6c1b3) \
+ V(_HashVMBase, get:_index, LinkedHashMap_getIndex, Dynamic, 0x7d6bb76b) \
+ V(_HashVMBase, set:_index, LinkedHashMap_setIndex, Dynamic, 0x4beb13f2) \
+ V(_HashVMBase, get:_data, LinkedHashMap_getData, Array, 0x4bf5ccb3) \
+ V(_HashVMBase, set:_data, LinkedHashMap_setData, Dynamic, 0x6007556d) \
+ V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, Smi, 0x15e70845) \
+ V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, Dynamic, 0x3e8c6edc)\
+ V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, Smi, 0x35c5ac00) \
+ V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, Dynamic, 0x49adf69e)\
+ V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, Smi, \
+ 0x306e6a79) \
+ V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, Dynamic, \
+ 0x3fe95fc2) \
// List of intrinsics:
// (class-name, function-name, intrinsification method, fingerprint).
#define CORE_LIB_INTRINSIC_LIST(V) \
- V(_Smi, ~, Smi_bitNegate, 1673522705) \
- V(_Smi, get:bitLength, Smi_bitLength, 632480332) \
- V(_Bigint, _lsh, Bigint_lsh, 1557746963) \
- V(_Bigint, _rsh, Bigint_rsh, 761843937) \
- V(_Bigint, _absAdd, Bigint_absAdd, 1227835493) \
- V(_Bigint, _absSub, Bigint_absSub, 390740532) \
- V(_Bigint, _mulAdd, Bigint_mulAdd, 617534446) \
- V(_Bigint, _sqrAdd, Bigint_sqrAdd, 1623635507) \
- V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 797340802) \
- V(_Montgomery, _mulMod, Montgomery_mulMod, 1947987219) \
- V(_Double, >, Double_greaterThan, 1453001345) \
- V(_Double, >=, Double_greaterEqualThan, 1815180096) \
- V(_Double, <, Double_lessThan, 652059836) \
- V(_Double, <=, Double_lessEqualThan, 512138528) \
- V(_Double, ==, Double_equal, 1468668497) \
- V(_Double, +, Double_add, 1269587413) \
- V(_Double, -, Double_sub, 1644506555) \
- V(_Double, *, Double_mul, 600860888) \
- V(_Double, /, Double_div, 1220198876) \
- V(_Double, get:isNaN, Double_getIsNaN, 184085483) \
- V(_Double, get:isNegative, Double_getIsNegative, 978911030) \
- V(_Double, _mulFromInteger, Double_mulFromInteger, 856594998) \
- V(_Double, .fromInteger, DoubleFromInteger, 2129942595) \
- V(_List, []=, ObjectArraySetIndexed, 886228780) \
- V(_GrowableList, .withData, GrowableArray_Allocate, 631736030) \
- V(_GrowableList, add, GrowableArray_add, 219371757) \
- V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 1614206970) \
- V(Object, ==, ObjectEquals, 291909336) \
- V(Object, get:runtimeType, ObjectRuntimeType, 15188587) \
- V(_StringBase, get:hashCode, String_getHashCode, 2026040200) \
- V(_StringBase, get:isEmpty, StringBaseIsEmpty, 1958879178) \
- V(_StringBase, _substringMatches, StringBaseSubstringMatches, 797253099) \
- V(_StringBase, [], StringBaseCharAt, 754527301) \
- V(_OneByteString, get:hashCode, OneByteString_getHashCode, 2026040200) \
+ V(_Smi, ~, Smi_bitNegate, Smi, 0x63bfee11) \
+ V(_Smi, get:bitLength, Smi_bitLength, Smi, 0x25b2e24c) \
+ V(_Bigint, _lsh, Bigint_lsh, Dynamic, 0x5cd95513) \
+ V(_Bigint, _rsh, Bigint_rsh, Dynamic, 0x2d68d0e1) \
+ V(_Bigint, _absAdd, Bigint_absAdd, Dynamic, 0x492f4865) \
+ V(_Bigint, _absSub, Bigint_absSub, Dynamic, 0x174a3a34) \
+ V(_Bigint, _mulAdd, Bigint_mulAdd, Dynamic, 0x24ced3ee) \
+ V(_Bigint, _sqrAdd, Bigint_sqrAdd, Dynamic, 0x60c6b633) \
+ V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, Dynamic, 0x2f867482) \
+ V(_Montgomery, _mulMod, Montgomery_mulMod, Dynamic, 0x741bed13) \
+ V(_Double, >, Double_greaterThan, Bool, 0x569b0a81) \
+ V(_Double, >=, Double_greaterEqualThan, Bool, 0x6c317340) \
+ V(_Double, <, Double_lessThan, Bool, 0x26dda4bc) \
+ V(_Double, <=, Double_lessEqualThan, Bool, 0x1e869d20) \
+ V(_Double, ==, Double_equal, Bool, 0x578a1a51) \
+ V(_Double, +, Double_add, Double, 0x4bac5dd5) \
+ V(_Double, -, Double_sub, Double, 0x62052dbb) \
+ V(_Double, *, Double_mul, Double, 0x23d068d8) \
+ V(_Double, /, Double_div, Double, 0x48bac1dc) \
+ V(_Double, get:isNaN, Double_getIsNaN, Bool, 0x0af8ebeb) \
+ V(_Double, get:isNegative, Double_getIsNegative, Bool, 0x3a58ff36) \
+ V(_Double, _mulFromInteger, Double_mulFromInteger, Double, 0x330e9a36) \
+ V(_Double, .fromInteger, DoubleFromInteger, Double, 0x7ef45843) \
+ V(_List, []=, ObjectArraySetIndexed, Dynamic, 0x34d2c72c) \
+ V(_GrowableList, .withData, GrowableArray_Allocate, GrowableObjectArray, \
+ 0x25a786de) \
+ V(_GrowableList, add, GrowableArray_add, Dynamic, 0x0d1358ed) \
+ V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, Dynamic, 0x6036d7fa) \
+ V(Object, ==, ObjectEquals, Bool, 0x11662ed8) \
+ V(Object, get:runtimeType, ObjectRuntimeType, Type, 0x00e7c26b) \
+ V(_StringBase, get:hashCode, String_getHashCode, Smi, 0x78c2eb88) \
+ V(_StringBase, get:isEmpty, StringBaseIsEmpty, Bool, 0x74c21fca) \
+ V(_StringBase, _substringMatches, StringBaseSubstringMatches, Bool, \
+ 0x2f851deb) \
+ V(_StringBase, [], StringBaseCharAt, Dynamic, 0x2cf92c45) \
+ V(_OneByteString, get:hashCode, OneByteString_getHashCode, Smi, 0x78c2eb88) \
V(_OneByteString, _substringUncheckedNative, \
- OneByteString_substringUnchecked, 1670133538) \
- V(_OneByteString, _setAt, OneByteStringSetAt, 1160066031) \
- V(_OneByteString, _allocate, OneByteString_allocate, 1028631946) \
- V(_OneByteString, ==, OneByteString_equality, 1062844160) \
- V(_TwoByteString, ==, TwoByteString_equality, 1062844160) \
+ OneByteString_substringUnchecked, OneByteString, 0x638c3722) \
+ V(_OneByteString, _setAt, OneByteStringSetAt, Dynamic, 0x452533ef) \
+ V(_OneByteString, _allocate, OneByteString_allocate, OneByteString, \
+ 0x3d4fad8a) \
+ V(_OneByteString, ==, OneByteString_equality, Bool, 0x3f59b700) \
+ V(_TwoByteString, ==, TwoByteString_equality, Bool, 0x3f59b700) \
#define CORE_INTEGER_LIB_INTRINSIC_LIST(V) \
V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger, \
- 2042488139) \
- V(_IntegerImplementation, +, Integer_add, 239272130) \
- V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, 957923759)\
- V(_IntegerImplementation, -, Integer_sub, 216175811) \
+ Dynamic, 0x79bde54b) \
+ V(_IntegerImplementation, +, Integer_add, Dynamic, 0x0e4300c2) \
+ V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, Dynamic, \
+ 0x3918c1af) \
+ V(_IntegerImplementation, -, Integer_sub, Dynamic, 0x0ce294c3) \
V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger, \
- 2032062140) \
- V(_IntegerImplementation, *, Integer_mul, 1301152164) \
+ Dynamic, 0x791ecebc) \
+ V(_IntegerImplementation, *, Integer_mul, Dynamic, 0x4d8e01a4) \
V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger, \
- 779285842) \
- V(_IntegerImplementation, ~/, Integer_truncDivide, 1018128256) \
- V(_IntegerImplementation, unary-, Integer_negate, 1507648892) \
+ Dynamic, 0x2e72f552) \
+ V(_IntegerImplementation, ~/, Integer_truncDivide, Dynamic, 0x3caf6780) \
+ V(_IntegerImplementation, unary-, Integer_negate, Dynamic, 0x59dce57c) \
V(_IntegerImplementation, _bitAndFromInteger, Integer_bitAndFromInteger, \
- 503046514) \
- V(_IntegerImplementation, &, Integer_bitAnd, 1500136766) \
+ Dynamic, 0x1dfbe172) \
+ V(_IntegerImplementation, &, Integer_bitAnd, Dynamic, 0x596a453e) \
V(_IntegerImplementation, _bitOrFromInteger, Integer_bitOrFromInteger, \
- 1031383580) \
- V(_IntegerImplementation, |, Integer_bitOr, 119412028) \
+ Dynamic, 0x3d79aa1c) \
+ V(_IntegerImplementation, |, Integer_bitOr, Dynamic, 0x071e153c) \
V(_IntegerImplementation, _bitXorFromInteger, Integer_bitXorFromInteger, \
- 1339506501) \
- V(_IntegerImplementation, ^, Integer_bitXor, 210430781) \
+ Dynamic, 0x4fd73f45) \
+ V(_IntegerImplementation, ^, Integer_bitXor, Dynamic, 0x0c8aeb3d) \
V(_IntegerImplementation, _greaterThanFromInteger, \
- Integer_greaterThanFromInt, 780147656) \
- V(_IntegerImplementation, >, Integer_greaterThan, 673741711) \
- V(_IntegerImplementation, ==, Integer_equal, 272474439) \
- V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger, \
- 2004079901) \
- V(_IntegerImplementation, <, Integer_lessThan, 652059836) \
- V(_IntegerImplementation, <=, Integer_lessEqualThan, 512138528) \
- V(_IntegerImplementation, >=, Integer_greaterEqualThan, 1815180096) \
- V(_IntegerImplementation, <<, Integer_shl, 1127538624) \
- V(_IntegerImplementation, >>, Integer_sar, 1243972513) \
- V(_Double, toInt, DoubleToInteger, 653210699)
+ Integer_greaterThanFromInt, Bool, 0x2e801bc8) \
+ V(_IntegerImplementation, >, Integer_greaterThan, Bool, 0x28287b8f) \
+ V(_IntegerImplementation, ==, Integer_equal, Bool, 0x103da147) \
+ V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger, Bool, \
+ 0x7773d51d) \
+ V(_IntegerImplementation, <, Integer_lessThan, Bool, 0x26dda4bc) \
+ V(_IntegerImplementation, <=, Integer_lessEqualThan, Bool, 0x1e869d20) \
+ V(_IntegerImplementation, >=, Integer_greaterEqualThan, Bool, 0x6c317340) \
+ V(_IntegerImplementation, <<, Integer_shl, Dynamic, 0x4334dfc0) \
+ V(_IntegerImplementation, >>, Integer_sar, Dynamic, 0x4a2583a1) \
+ V(_Double, toInt, DoubleToInteger, Dynamic, 0x26ef344b)
#define MATH_LIB_INTRINSIC_LIST(V) \
- V(::, sqrt, MathSqrt, 417912310) \
- V(_Random, _nextState, Random_nextState, 508231939) \
+ V(::, sqrt, MathSqrt, Double, 0x18e8d5f6) \
+ V(_Random, _nextState, Random_nextState, Dynamic, 0x1e4b0103) \
#define GRAPH_MATH_LIB_INTRINSIC_LIST(V) \
- V(::, sin, MathSin, 65032) \
- V(::, cos, MathCos, 2006233918) \
- V(::, tan, MathTan, 1276867325) \
- V(::, asin, MathAsin, 1678592173) \
- V(::, acos, MathAcos, 1121218433) \
- V(::, atan, MathAtan, 1109653625) \
- V(::, atan2, MathAtan2, 894696289) \
+ V(::, sin, MathSin, Double, 0x0000fe08) \
+ V(::, cos, MathCos, Double, 0x7794b33e) \
+ V(::, tan, MathTan, Double, 0x4c1b72fd) \
+ V(::, asin, MathAsin, Double, 0x640d48ad) \
+ V(::, acos, MathAcos, Double, 0x42d46f81) \
+ V(::, atan, MathAtan, Double, 0x4223f879) \
+ V(::, atan2, MathAtan2, Double, 0x3553fb61) \
#define TYPED_DATA_LIB_INTRINSIC_LIST(V) \
- V(Int8List, ., TypedData_Int8Array_factory, 779569635) \
- V(Uint8List, ., TypedData_Uint8Array_factory, 1790399545) \
- V(Uint8ClampedList, ., TypedData_Uint8ClampedArray_factory, 405875159) \
- V(Int16List, ., TypedData_Int16Array_factory, 347431914) \
- V(Uint16List, ., TypedData_Uint16Array_factory, 121990116) \
- V(Int32List, ., TypedData_Int32Array_factory, 1540657744) \
- V(Uint32List, ., TypedData_Uint32Array_factory, 1012511652) \
- V(Int64List, ., TypedData_Int64Array_factory, 1473796807) \
- V(Uint64List, ., TypedData_Uint64Array_factory, 738799620) \
- V(Float32List, ., TypedData_Float32Array_factory, 1938690635) \
- V(Float64List, ., TypedData_Float64Array_factory, 1344005361) \
- V(Float32x4List, ., TypedData_Float32x4Array_factory, 2055067416) \
- V(Int32x4List, ., TypedData_Int32x4Array_factory, 504220232) \
- V(Float64x2List, ., TypedData_Float64x2Array_factory, 416019673) \
+ V(Int8List, ., TypedData_Int8Array_factory, TypedDataInt8Array, 0x2e7749e3) \
+ V(Uint8List, ., TypedData_Uint8Array_factory, TypedDataUint8Array, \
+ 0x6ab75439) \
+ V(Uint8ClampedList, ., TypedData_Uint8ClampedArray_factory, \
+ TypedDataUint8ClampedArray, 0x183129d7) \
+ V(Int16List, ., TypedData_Int16Array_factory, TypedDataInt16Array, \
+ 0x14b563ea) \
+ V(Uint16List, ., TypedData_Uint16Array_factory, TypedDataUint16Array, \
+ 0x07456be4) \
+ V(Int32List, ., TypedData_Int32Array_factory, TypedDataInt32Array, \
+ 0x5bd49250) \
+ V(Uint32List, ., TypedData_Uint32Array_factory, \
+ TypedDataUint32Array, 0x3c59b3a4) \
+ V(Int64List, ., TypedData_Int64Array_factory, \
+ TypedDataInt64Array, 0x57d85ac7) \
+ V(Uint64List, ., TypedData_Uint64Array_factory, \
+ TypedDataUint64Array, 0x2c093004) \
+ V(Float32List, ., TypedData_Float32Array_factory, \
+ TypedDataFloat32Array, 0x738e124b) \
+ V(Float64List, ., TypedData_Float64Array_factory, \
+ TypedDataFloat64Array, 0x501be4f1) \
+ V(Float32x4List, ., TypedData_Float32x4Array_factory, \
+ TypedDataFloat32x4Array, 0x7a7dd718) \
+ V(Int32x4List, ., TypedData_Int32x4Array_factory, \
+ TypedDataInt32x4Array, 0x1e0dca48) \
+ V(Float64x2List, ., TypedData_Float64x2Array_factory, \
+ TypedDataFloat64x2Array, 0x18cbf4d9) \
#define GRAPH_TYPED_DATA_INTRINSICS_LIST(V) \
- V(Uint8List, [], Uint8ArrayGetIndexed, 41288685) \
- V(Uint8List, []=, Uint8ArraySetIndexed, 101536342) \
- V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 41288685) \
- V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 101536342) \
- V(Uint32List, [], Uint32ArrayGetIndexed, 1614870523) \
- V(Uint32List, []=, Uint32ArraySetIndexed, 978194713) \
- V(Float64List, []=, Float64ArraySetIndexed, 328934501) \
- V(Float64List, [], Float64ArrayGetIndexed, 2049378701) \
- V(_TypedList, get:length, TypedDataLength, 546364442) \
- V(Float32x4, get:x, Float32x4ShuffleX, 1674625343) \
- V(Float32x4, get:y, Float32x4ShuffleY, 540293915) \
- V(Float32x4, get:z, Float32x4ShuffleZ, 320347578) \
- V(Float32x4, get:w, Float32x4ShuffleW, 1770606624) \
- V(Float32x4, _mul, Float32x4Mul, 42807622) \
- V(Float32x4, _sub, Float32x4Sub, 103774455) \
- V(Float32x4, _add, Float32x4Add, 1352634374) \
+ V(Uint8List, [], Uint8ArrayGetIndexed, Smi, 0x027603ed) \
+ V(Uint8List, []=, Uint8ArraySetIndexed, Dynamic, 0x060d5256) \
+ V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, Smi, 0x027603ed) \
+ V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, Dynamic, \
+ 0x060d5256) \
+ V(Uint32List, [], Uint32ArrayGetIndexed, Dynamic, 0x6040f7fb) \
+ V(Uint32List, []=, Uint32ArraySetIndexed, Dynamic, 0x3a4e1119) \
+ V(Float64List, [], Float64ArrayGetIndexed, Double, 0x7a27098d) \
+ V(Float64List, []=, Float64ArraySetIndexed, Dynamic, 0x139b2465) \
+ V(_TypedList, get:length, TypedDataLength, Smi, 0x2090dc1a) \
+ V(Float32x4, get:x, Float32x4ShuffleX, Double, 0x63d0c13f) \
+ V(Float32x4, get:y, Float32x4ShuffleY, Double, 0x20343b1b) \
+ V(Float32x4, get:z, Float32x4ShuffleZ, Double, 0x13181dba) \
+ V(Float32x4, get:w, Float32x4ShuffleW, Double, 0x69895020) \
+ V(Float32x4, _mul, Float32x4Mul, Float32x4, 0x028d3146) \
+ V(Float32x4, _sub, Float32x4Sub, Float32x4, 0x062f78f7) \
+ V(Float32x4, _add, Float32x4Add, Float32x4, 0x509f9006) \
#define GRAPH_CORE_INTRINSICS_LIST(V) \
- V(_List, get:length, ObjectArrayLength, 630471378) \
- V(_List, [], ObjectArrayGetIndexed, 360400496) \
- V(_ImmutableList, get:length, ImmutableArrayLength, 630471378) \
- V(_ImmutableList, [], ImmutableArrayGetIndexed, 360400496) \
- V(_GrowableList, get:length, GrowableArrayLength, 417111542) \
- V(_GrowableList, get:_capacity, GrowableArrayCapacity, 41110914) \
- V(_GrowableList, _setData, GrowableArraySetData, 210059283) \
- V(_GrowableList, _setLength, GrowableArraySetLength, 335652822) \
- V(_GrowableList, [], GrowableArrayGetIndexed, 1957529650) \
- V(_GrowableList, []=, GrowableArraySetIndexed, 225246870) \
- V(_StringBase, get:length, StringBaseLength, 707533587) \
- V(_OneByteString, codeUnitAt, OneByteStringCodeUnitAt, 1436590579) \
- V(_TwoByteString, codeUnitAt, TwoByteStringCodeUnitAt, 1436590579) \
+ V(_List, get:length, ObjectArrayLength, Smi, 0x25943ad2) \
+ V(_List, [], ObjectArrayGetIndexed, Dynamic, 0x157b4670) \
+ V(_ImmutableList, get:length, ImmutableArrayLength, Smi, 0x25943ad2) \
+ V(_ImmutableList, [], ImmutableArrayGetIndexed, Dynamic, 0x157b4670) \
+ V(_GrowableList, get:length, GrowableArrayLength, Smi, 0x18dc9df6) \
+ V(_GrowableList, get:_capacity, GrowableArrayCapacity, Smi, 0x02734d82) \
+ V(_GrowableList, _setData, GrowableArraySetData, Dynamic, 0x0c854013) \
+ V(_GrowableList, _setLength, GrowableArraySetLength, Dynamic, 0x1401a7d6) \
+ V(_GrowableList, [], GrowableArrayGetIndexed, Dynamic, 0x74ad8832) \
+ V(_GrowableList, []=, GrowableArraySetIndexed, Dynamic, 0x0d6cfe96) \
+ V(_StringBase, get:length, StringBaseLength, Smi, 0x2a2c1b13) \
+ V(_OneByteString, codeUnitAt, OneByteStringCodeUnitAt, Smi, 0x55a0a1f3) \
+ V(_TwoByteString, codeUnitAt, TwoByteStringCodeUnitAt, Smi, 0x55a0a1f3) \
V(_ExternalOneByteString, codeUnitAt, ExternalOneByteStringCodeUnitAt, \
- 1436590579) \
+ Smi, 0x55a0a1f3) \
V(_ExternalTwoByteString, codeUnitAt, ExternalTwoByteStringCodeUnitAt, \
- 1436590579) \
- V(_Double, unary-, DoubleFlipSignBit, 1783281169) \
- V(_Double, truncateToDouble, DoubleTruncate, 791143891) \
- V(_Double, roundToDouble, DoubleRound, 797558034) \
- V(_Double, floorToDouble, DoubleFloor, 1789426271) \
- V(_Double, ceilToDouble, DoubleCeil, 453271198) \
- V(_Double, _modulo, DoubleMod, 776062204)
+ Smi, 0x55a0a1f3) \
+ V(_Double, unary-, DoubleFlipSignBit, Double, 0x6a4ab611) \
+ V(_Double, truncateToDouble, DoubleTruncate, Double, 0x2f27e5d3) \
+ V(_Double, roundToDouble, DoubleRound, Double, 0x2f89c512) \
+ V(_Double, floorToDouble, DoubleFloor, Double, 0x6aa87a5f) \
+ V(_Double, ceilToDouble, DoubleCeil, Double, 0x1b045e9e) \
+ V(_Double, _modulo, DoubleMod, Double, 0x2e41c4fc)
#define GRAPH_INTRINSICS_LIST(V) \
@@ -304,10 +330,11 @@
GRAPH_MATH_LIB_INTRINSIC_LIST(V) \
#define DEVELOPER_LIB_INTRINSIC_LIST(V) \
- V(_UserTag, makeCurrent, UserTag_makeCurrent, 187721469) \
- V(::, _getDefaultTag, UserTag_defaultTag, 350077879) \
- V(::, _getCurrentTag, Profiler_getCurrentTag, 1215225901) \
- V(::, _isDartStreamEnabled, Timeline_isDartStreamEnabled, 1072246292) \
+ V(_UserTag, makeCurrent, UserTag_makeCurrent, Dynamic, 0x0b3066fd) \
+ V(::, _getDefaultTag, UserTag_defaultTag, Dynamic, 0x14ddc3b7) \
+ V(::, _getCurrentTag, Profiler_getCurrentTag, Dynamic, 0x486ee02d) \
+ V(::, _isDartStreamEnabled, Timeline_isDartStreamEnabled, Dynamic, \
+ 0x3fe92e14) \
#define ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V) \
CORE_LIB_INTRINSIC_LIST(V) \
@@ -326,158 +353,158 @@
// A list of core function that should always be inlined.
#define INLINE_WHITE_LIST(V) \
- V(Object, ==, ObjectEquals, 291909336) \
- V(_List, get:length, ObjectArrayLength, 630471378) \
- V(_ImmutableList, get:length, ImmutableArrayLength, 630471378) \
- V(_TypedList, get:length, TypedDataLength, 546364442) \
- V(_GrowableList, get:length, GrowableArrayLength, 417111542) \
- V(_GrowableList, add, GrowableListAdd, 219371757) \
- V(_GrowableList, removeLast, GrowableListRemoveLast, 324891524) \
- V(_StringBase, get:length, StringBaseLength, 707533587) \
- V(ListIterator, moveNext, ListIteratorMoveNext, 1065954929) \
- V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 1451346178) \
- V(_GrowableList, get:iterator, GrowableArrayIterator, 1840323187) \
- V(_GrowableList, forEach, GrowableArrayForEach, 620771070) \
- V(_List, ., ObjectArrayAllocate, 1661438741) \
- V(_List, [], ObjectArrayGetIndexed, 360400496) \
- V(_List, []=, ObjectArraySetIndexed, 886228780) \
- V(ListMixin, get:isEmpty, ListMixinIsEmpty, 2021497798) \
- V(_List, get:iterator, ObjectArrayIterator, 295498778) \
- V(_List, forEach, ObjectArrayForEach, 180150673) \
- V(_List, _slice, ObjectArraySlice, 840558357) \
- V(_ImmutableList, get:iterator, ImmutableArrayIterator, 295498778) \
- V(_ImmutableList, forEach, ImmutableArrayForEach, 180150673) \
- V(_ImmutableList, [], ImmutableArrayGetIndexed, 360400496) \
- V(_GrowableList, [], GrowableArrayGetIndexed, 1957529650) \
- V(_GrowableList, []=, GrowableArraySetIndexed, 225246870) \
- V(Float32List, [], Float32ArrayGetIndexed, 1451643535) \
- V(Float32List, []=, Float32ArraySetIndexed, 453873887) \
- V(Float64List, [], Float64ArrayGetIndexed, 2049378701) \
- V(Float64List, []=, Float64ArraySetIndexed, 328934501) \
- V(Int8List, [], Int8ArrayGetIndexed, 110819507) \
- V(Int8List, []=, Int8ArraySetIndexed, 865684695) \
- V(Uint8List, [], Uint8ArrayGetIndexed, 41288685) \
- V(Uint8List, []=, Uint8ArraySetIndexed, 101536342) \
- V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 41288685) \
- V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 687206488) \
- V(Uint16List, [], Uint16ArrayGetIndexed, 1053739567) \
- V(Uint16List, []=, Uint16ArraySetIndexed, 1547307961) \
- V(Int16List, [], Int16ArrayGetIndexed, 389863073) \
- V(Int16List, []=, Int16ArraySetIndexed, 855133756) \
- V(Int32List, [], Int32ArrayGetIndexed, 640610057) \
- V(Int32List, []=, Int32ArraySetIndexed, 453358705) \
- V(Int64List, [], Int64ArrayGetIndexed, 202150810) \
- V(Int64List, []=, Int64ArraySetIndexed, 924110852) \
- V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 1338422227) \
- V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 540212720) \
- V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 302213458) \
- V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 1837635160) \
- V(_ByteDataView, setInt8, ByteDataViewSetInt8, 660389322) \
- V(_ByteDataView, setUint8, ByteDataViewSetUint8, 1651986039) \
- V(_ByteDataView, setInt16, ByteDataViewSetInt16, 2051262146) \
- V(_ByteDataView, setUint16, ByteDataViewSetUint16, 1692244111) \
- V(_ByteDataView, setInt32, ByteDataViewSetInt32, 862135882) \
- V(_ByteDataView, setUint32, ByteDataViewSetUint32, 361732249) \
- V(_ByteDataView, setInt64, ByteDataViewSetInt64, 1208972197) \
- V(_ByteDataView, setUint64, ByteDataViewSetUint64, 1545853836) \
- V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 1333183642) \
- V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 1579015503) \
- V(_ByteDataView, getInt8, ByteDataViewGetInt8, 29018237) \
- V(_ByteDataView, getUint8, ByteDataViewGetUint8, 312322868) \
- V(_ByteDataView, getInt16, ByteDataViewGetInt16, 1613243255) \
- V(_ByteDataView, getUint16, ByteDataViewGetUint16, 284020105) \
- V(_ByteDataView, getInt32, ByteDataViewGetInt32, 2036535169) \
- V(_ByteDataView, getUint32, ByteDataViewGetUint32, 571293096) \
- V(_ByteDataView, getInt64, ByteDataViewGetInt64, 1971181000) \
- V(_ByteDataView, getUint64, ByteDataViewGetUint64, 799775022) \
- V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 947822534) \
- V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 1402356525) \
- V(::, asin, MathASin, 1678592173) \
- V(::, acos, MathACos, 1121218433) \
- V(::, atan, MathATan, 1109653625) \
- V(::, atan2, MathATan2, 894696289) \
- V(::, cos, MathCos, 2006233918) \
- V(::, exp, MathExp, 1500946333) \
- V(::, log, MathLog, 739403086) \
- V(::, max, MathMax, 1410473322) \
- V(::, min, MathMin, 1115051548) \
- V(::, pow, MathPow, 2058759335) \
- V(::, sin, MathSin, 65032) \
- V(::, sqrt, MathSqrt, 417912310) \
- V(::, tan, MathTan, 1276867325) \
- V(Lists, copy, ListsCopy, 564237562) \
- V(_Bigint, get:_neg, Bigint_getNeg, 2079423063) \
- V(_Bigint, get:_used, Bigint_getUsed, 1426329619) \
- V(_Bigint, get:_digits, Bigint_getDigits, 1185333683) \
- V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 2104211307) \
- V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 1273697266) \
- V(_HashVMBase, get:_data, LinkedHashMap_getData, 1274399923) \
- V(_HashVMBase, set:_data, LinkedHashMap_setData, 1611093357) \
- V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 367462469) \
- V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 1049390812) \
- V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 902147072) \
- V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 1236137630) \
- V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 812542585) \
- V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 1072259010) \
+ V(Object, ==, ObjectEquals, 0x11662ed8) \
+ V(_List, get:length, ObjectArrayLength, 0x25943ad2) \
+ V(_ImmutableList, get:length, ImmutableArrayLength, 0x25943ad2) \
+ V(_TypedList, get:length, TypedDataLength, 0x2090dc1a) \
+ V(_GrowableList, get:length, GrowableArrayLength, 0x18dc9df6) \
+ V(_GrowableList, add, GrowableListAdd, 0x0d1358ed) \
+ V(_GrowableList, removeLast, GrowableListRemoveLast, 0x135d7384) \
+ V(_StringBase, get:length, StringBaseLength, 0x2a2c1b13) \
+ V(ListIterator, moveNext, ListIteratorMoveNext, 0x3f892e71) \
+ V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 0x5681c902) \
+ V(_GrowableList, get:iterator, GrowableArrayIterator, 0x6db11a73) \
+ V(_GrowableList, forEach, GrowableArrayForEach, 0x250036fe) \
+ V(_List, ., ObjectArrayAllocate, 0x63078b15) \
+ V(_List, [], ObjectArrayGetIndexed, 0x157b4670) \
+ V(_List, []=, ObjectArraySetIndexed, 0x34d2c72c) \
+ V(ListMixin, get:isEmpty, ListMixinIsEmpty, 0x787d9bc6) \
+ V(_List, get:iterator, ObjectArrayIterator, 0x119cf41a) \
+ V(_List, forEach, ObjectArrayForEach, 0x0abce191) \
+ V(_List, _slice, ObjectArraySlice, 0x3219e715) \
+ V(_ImmutableList, get:iterator, ImmutableArrayIterator, 0x119cf41a) \
+ V(_ImmutableList, forEach, ImmutableArrayForEach, 0x0abce191) \
+ V(_ImmutableList, [], ImmutableArrayGetIndexed, 0x157b4670) \
+ V(_GrowableList, [], GrowableArrayGetIndexed, 0x74ad8832) \
+ V(_GrowableList, []=, GrowableArraySetIndexed, 0x0d6cfe96) \
+ V(Float32List, [], Float32ArrayGetIndexed, 0x5686528f) \
+ V(Float32List, []=, Float32ArraySetIndexed, 0x1b0d90df) \
+ V(Float64List, [], Float64ArrayGetIndexed, 0x7a27098d) \
+ V(Float64List, []=, Float64ArraySetIndexed, 0x139b2465) \
+ V(Int8List, [], Int8ArrayGetIndexed, 0x069af8b3) \
+ V(Int8List, []=, Int8ArraySetIndexed, 0x33994cd7) \
+ V(Uint8List, [], Uint8ArrayGetIndexed, 0x027603ed) \
+ V(Uint8List, []=, Uint8ArraySetIndexed, 0x060d5256) \
+ V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 0x027603ed) \
+ V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 0x28f5f058) \
+ V(Uint16List, [], Uint16ArrayGetIndexed, 0x3ececa2f) \
+ V(Uint16List, []=, Uint16ArraySetIndexed, 0x5c3a0bb9) \
+ V(Int16List, [], Int16ArrayGetIndexed, 0x173cd6a1) \
+ V(Int16List, []=, Int16ArraySetIndexed, 0x32f84e3c) \
+ V(Int32List, [], Int32ArrayGetIndexed, 0x262eef09) \
+ V(Int32List, []=, Int32ArraySetIndexed, 0x1b05b471) \
+ V(Int64List, [], Int64ArrayGetIndexed, 0x0c0c939a) \
+ V(Int64List, []=, Int64ArraySetIndexed, 0x3714d004) \
+ V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 0x4fc6b3d3) \
+ V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 0x2032fdf0) \
+ V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 0x12036952) \
+ V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 0x6d881658) \
+ V(_ByteDataView, setInt8, ByteDataViewSetInt8, 0x275cbdca) \
+ V(_ByteDataView, setUint8, ByteDataViewSetUint8, 0x62774e77) \
+ V(_ByteDataView, setInt16, ByteDataViewSetInt16, 0x7a43c6c2) \
+ V(_ByteDataView, setUint16, ByteDataViewSetUint16, 0x64dd988f) \
+ V(_ByteDataView, setInt32, ByteDataViewSetInt32, 0x3363264a) \
+ V(_ByteDataView, setUint32, ByteDataViewSetUint32, 0x158f9899) \
+ V(_ByteDataView, setInt64, ByteDataViewSetInt64, 0x480f73a5) \
+ V(_ByteDataView, setUint64, ByteDataViewSetUint64, 0x5c23db8c) \
+ V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 0x4f76c49a) \
+ V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 0x5e1ddd4f) \
+ V(_ByteDataView, getInt8, ByteDataViewGetInt8, 0x01bac87d) \
+ V(_ByteDataView, getUint8, ByteDataViewGetUint8, 0x129dab34) \
+ V(_ByteDataView, getInt16, ByteDataViewGetInt16, 0x60282377) \
+ V(_ByteDataView, getUint16, ByteDataViewGetUint16, 0x10edcd89) \
+ V(_ByteDataView, getInt32, ByteDataViewGetInt32, 0x79630f81) \
+ V(_ByteDataView, getUint32, ByteDataViewGetUint32, 0x220d3da8) \
+ V(_ByteDataView, getInt64, ByteDataViewGetInt64, 0x757dd5c8) \
+ V(_ByteDataView, getUint64, ByteDataViewGetUint64, 0x2fab992e) \
+ V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 0x387e9fc6) \
+ V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 0x5396432d) \
+ V(::, asin, MathAsin, 0x640d48ad) \
+ V(::, acos, MathAcos, 0x42d46f81) \
+ V(::, atan, MathAtan, 0x4223f879) \
+ V(::, atan2, MathAtan2, 0x3553fb61) \
+ V(::, cos, MathCos, 0x7794b33e) \
+ V(::, exp, MathExp, 0x59769f9d) \
+ V(::, log, MathLog, 0x2c12654e) \
+ V(::, max, MathMax, 0x54121d6a) \
+ V(::, min, MathMin, 0x4276561c) \
+ V(::, pow, MathPow, 0x7ab62ca7) \
+ V(::, sin, MathSin, 0x0000fe08) \
+ V(::, sqrt, MathSqrt, 0x18e8d5f6) \
+ V(::, tan, MathTan, 0x4c1b72fd) \
+ V(Lists, copy, ListsCopy, 0x21a194fa) \
+ V(_Bigint, get:_neg, Bigint_getNeg, 0x7bf17a57) \
+ V(_Bigint, get:_used, Bigint_getUsed, 0x55041013) \
+ V(_Bigint, get:_digits, Bigint_getDigits, 0x46a6c1b3) \
+ V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0x7d6bb76b) \
+ V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0x4beb13f2) \
+ V(_HashVMBase, get:_data, LinkedHashMap_getData, 0x4bf5ccb3) \
+ V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x6007556d) \
+ V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0x15e70845) \
+ V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0x3e8c6edc) \
+ V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0x35c5ac00) \
+ V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0x49adf69e) \
+ V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0x306e6a79) \
+ V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0x3fe95fc2) \
// A list of core function that should never be inlined.
#define INLINE_BLACK_LIST(V) \
- V(_Bigint, _lsh, Bigint_lsh, 1557746963) \
- V(_Bigint, _rsh, Bigint_rsh, 761843937) \
- V(_Bigint, _absAdd, Bigint_absAdd, 1227835493) \
- V(_Bigint, _absSub, Bigint_absSub, 390740532) \
- V(_Bigint, _mulAdd, Bigint_mulAdd, 617534446) \
- V(_Bigint, _sqrAdd, Bigint_sqrAdd, 1623635507) \
- V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 797340802) \
- V(_Montgomery, _mulMod, Montgomery_mulMod, 1947987219) \
- V(_Double, >, Double_greaterThan, 1453001345) \
- V(_Double, >=, Double_greaterEqualThan, 1815180096) \
- V(_Double, <, Double_lessThan, 652059836) \
- V(_Double, <=, Double_lessEqualThan, 512138528) \
- V(_Double, ==, Double_equal, 1468668497) \
- V(_Double, +, Double_add, 1269587413) \
- V(_Double, -, Double_sub, 1644506555) \
- V(_Double, *, Double_mul, 600860888) \
- V(_Double, /, Double_div, 1220198876) \
- V(_IntegerImplementation, +, Integer_add, 239272130) \
- V(_IntegerImplementation, -, Integer_sub, 216175811) \
- V(_IntegerImplementation, *, Integer_mul, 1301152164) \
- V(_IntegerImplementation, ~/, Integer_truncDivide, 1018128256) \
- V(_IntegerImplementation, unary-, Integer_negate, 1507648892) \
- V(_IntegerImplementation, &, Integer_bitAnd, 1500136766) \
- V(_IntegerImplementation, |, Integer_bitOr, 119412028) \
- V(_IntegerImplementation, ^, Integer_bitXor, 210430781) \
- V(_IntegerImplementation, >, Integer_greaterThan, 673741711) \
- V(_IntegerImplementation, ==, Integer_equal, 272474439) \
- V(_IntegerImplementation, <, Integer_lessThan, 652059836) \
- V(_IntegerImplementation, <=, Integer_lessEqualThan, 512138528) \
- V(_IntegerImplementation, >=, Integer_greaterEqualThan, 1815180096) \
- V(_IntegerImplementation, <<, Integer_shl, 1127538624) \
- V(_IntegerImplementation, >>, Integer_sar, 1243972513) \
+ V(_Bigint, _lsh, Bigint_lsh, 0x5cd95513) \
+ V(_Bigint, _rsh, Bigint_rsh, 0x2d68d0e1) \
+ V(_Bigint, _absAdd, Bigint_absAdd, 0x492f4865) \
+ V(_Bigint, _absSub, Bigint_absSub, 0x174a3a34) \
+ V(_Bigint, _mulAdd, Bigint_mulAdd, 0x24ced3ee) \
+ V(_Bigint, _sqrAdd, Bigint_sqrAdd, 0x60c6b633) \
+ V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 0x2f867482) \
+ V(_Montgomery, _mulMod, Montgomery_mulMod, 0x741bed13) \
+ V(_Double, >, Double_greaterThan, 0x569b0a81) \
+ V(_Double, >=, Double_greaterEqualThan, 0x6c317340) \
+ V(_Double, <, Double_lessThan, 0x26dda4bc) \
+ V(_Double, <=, Double_lessEqualThan, 0x1e869d20) \
+ V(_Double, ==, Double_equal, 0x578a1a51) \
+ V(_Double, +, Double_add, 0x4bac5dd5) \
+ V(_Double, -, Double_sub, 0x62052dbb) \
+ V(_Double, *, Double_mul, 0x23d068d8) \
+ V(_Double, /, Double_div, 0x48bac1dc) \
+ V(_IntegerImplementation, +, Integer_add, 0x0e4300c2) \
+ V(_IntegerImplementation, -, Integer_sub, 0x0ce294c3) \
+ V(_IntegerImplementation, *, Integer_mul, 0x4d8e01a4) \
+ V(_IntegerImplementation, ~/, Integer_truncDivide, 0x3caf6780) \
+ V(_IntegerImplementation, unary-, Integer_negate, 0x59dce57c) \
+ V(_IntegerImplementation, &, Integer_bitAnd, 0x596a453e) \
+ V(_IntegerImplementation, |, Integer_bitOr, 0x071e153c) \
+ V(_IntegerImplementation, ^, Integer_bitXor, 0x0c8aeb3d) \
+ V(_IntegerImplementation, >, Integer_greaterThan, 0x28287b8f) \
+ V(_IntegerImplementation, ==, Integer_equal, 0x103da147) \
+ V(_IntegerImplementation, <, Integer_lessThan, 0x26dda4bc) \
+ V(_IntegerImplementation, <=, Integer_lessEqualThan, 0x1e869d20) \
+ V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0x6c317340) \
+ V(_IntegerImplementation, <<, Integer_shl, 0x4334dfc0) \
+ V(_IntegerImplementation, >>, Integer_sar, 0x4a2583a1) \
// A list of core functions that internally dispatch based on received id.
#define POLYMORPHIC_TARGET_LIST(V) \
- V(_StringBase, [], StringBaseCharAt, 754527301) \
- V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 1508321565) \
- V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 953411007) \
- V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 433971756) \
- V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1329446488) \
- V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 137212209) \
- V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 499907480) \
- V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 1672834581) \
- V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 966634744) \
- V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1197581758) \
- V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 810805548) \
- V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 1317196265) \
- V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 1328908284) \
- V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1827614958) \
- V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 1694054572) \
- V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 915652649) \
- V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1958474336) \
- V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1853026980) \
- V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1197862362) \
- V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 2093630771) \
- V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 1982971324) \
+ V(_StringBase, [], StringBaseCharAt, 0x2cf92c45) \
+ V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x59e7291d) \
+ V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x38d3e5bf) \
+ V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x19dde22c) \
+ V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x4f3dbe58) \
+ V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x082db131) \
+ V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x1dcbfb98) \
+ V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0x63b56e15) \
+ V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x399dacf8) \
+ V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x4761a5be) \
+ V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x3053e92c) \
+ V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x4e82d1e9) \
+ V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 0x4f3587fc) \
+ V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x6cef30ee) \
+ V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 0x64f938ac) \
+ V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x3693c029) \
+ V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x74bbf260) \
+ V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x6e72f2a4) \
+ V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x4765edda) \
+ V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x7cca4533) \
+ V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x7631bdbc) \
// Forward declarations.
class Function;
@@ -489,7 +516,8 @@
public:
enum Kind {
kUnknown,
-#define DEFINE_ENUM_LIST(class_name, function_name, enum_name, fp) k##enum_name,
+#define DEFINE_ENUM_LIST(class_name, function_name, enum_name, type, fp) \
+ k##enum_name,
RECOGNIZED_LIST(DEFINE_ENUM_LIST)
#undef DEFINE_ENUM_LIST
kNumRecognizedMethods
@@ -498,6 +526,7 @@
static Kind RecognizeKind(const Function& function);
static bool AlwaysInline(const Function& function);
static bool PolymorphicTarget(const Function& function);
+ static intptr_t ResultCid(const Function& function);
static const char* KindToCString(Kind kind);
#if defined(DART_NO_SNAPSHOT)
static void InitializeState();
@@ -517,21 +546,21 @@
// List of recognized list factories:
// (factory-name-symbol, result-cid, fingerprint).
#define RECOGNIZED_LIST_FACTORY_LIST(V) \
- V(_ListFactory, kArrayCid, 1661438741) \
- V(_GrowableListWithData, kGrowableObjectArrayCid, 631736030) \
- V(_GrowableListFactory, kGrowableObjectArrayCid, 1330464656) \
- V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 779569635) \
- V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1790399545) \
- V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 405875159) \
- V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 347431914) \
- V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 121990116) \
- V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 1540657744) \
- V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 1012511652) \
- V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 1473796807) \
- V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 738799620) \
- V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 1344005361) \
- V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 1938690635) \
- V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 2055067416) \
+ V(_ListFactory, kArrayCid, 0x63078b15) \
+ V(_GrowableListWithData, kGrowableObjectArrayCid, 0x25a786de) \
+ V(_GrowableListFactory, kGrowableObjectArrayCid, 0x4f4d4790) \
+ V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 0x2e7749e3) \
+ V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 0x6ab75439) \
+ V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 0x183129d7) \
+ V(_Int16ArrayFactory, kTypedDataInt16ArrayCid, 0x14b563ea) \
+ V(_Uint16ArrayFactory, kTypedDataUint16ArrayCid, 0x07456be4) \
+ V(_Int32ArrayFactory, kTypedDataInt32ArrayCid, 0x5bd49250) \
+ V(_Uint32ArrayFactory, kTypedDataUint32ArrayCid, 0x3c59b3a4) \
+ V(_Int64ArrayFactory, kTypedDataInt64ArrayCid, 0x57d85ac7) \
+ V(_Uint64ArrayFactory, kTypedDataUint64ArrayCid, 0x2c093004) \
+ V(_Float64ArrayFactory, kTypedDataFloat64ArrayCid, 0x501be4f1) \
+ V(_Float32ArrayFactory, kTypedDataFloat32ArrayCid, 0x738e124b) \
+ V(_Float32x4ArrayFactory, kTypedDataFloat32x4ArrayCid, 0x7a7dd718) \
// Class that recognizes factories and returns corresponding result cid.
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 0d5ca5f..13b84c6 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -7,6 +7,7 @@
#include "include/dart_api.h"
#include "platform/assert.h"
#include "vm/assembler.h"
+#include "vm/become.h"
#include "vm/cpu.h"
#include "vm/bit_vector.h"
#include "vm/bootstrap.h"
@@ -562,6 +563,13 @@
cls.set_is_finalized();
cls.set_is_type_finalized();
+ // Allocate and initialize the forwarding corpse class.
+ cls = Class::New<ForwardingCorpse::FakeInstance>(kForwardingCorpse);
+ cls.set_num_type_arguments(0);
+ cls.set_num_own_type_arguments(0);
+ cls.set_is_finalized();
+ cls.set_is_type_finalized();
+
// Allocate and initialize the sentinel values of Null class.
{
*sentinel_ ^=
@@ -929,6 +937,8 @@
void VisitObject(RawObject* obj) {
// Free list elements should never be marked.
ASSERT(!obj->IsMarked());
+ // No forwarding corpses in the VM isolate.
+ ASSERT(!obj->IsForwardingCorpse());
if (!obj->IsFreeListElement()) {
ASSERT(obj->IsVMHeapObject());
obj->SetMarkBitUnsynchronized();
@@ -1000,6 +1010,13 @@
cls = isolate->object_store()->one_byte_string_class();
cls.set_name(Symbols::OneByteString());
+ // Set up names for the pseudo-classes for free list elements and forwarding
+ // corpses. Mainly this makes VM debugging easier.
+ cls = isolate->class_table()->At(kFreeListElement);
+ cls.set_name(Symbols::FreeListElement());
+ cls = isolate->class_table()->At(kForwardingCorpse);
+ cls.set_name(Symbols::ForwardingCorpse());
+
{
ASSERT(isolate == Dart::vm_isolate());
WritableVMIsolateScope scope(Thread::Current());
@@ -1080,6 +1097,7 @@
}
}
ASSERT(builtin_vtables_[kFreeListElement] == 0);
+ ASSERT(builtin_vtables_[kForwardingCorpse] == 0);
#endif
}
@@ -1916,8 +1934,6 @@
RawString* Class::Name() const {
- // TODO(turnidge): This assert fails for the fake kFreeListElement class.
- // Fix this.
ASSERT(raw_ptr()->name_ != String::null());
return raw_ptr()->name_;
}
@@ -7123,11 +7139,10 @@
// This output can be copied into a file, then used with sed
// to replace the old values.
// sed -i .bak -f /tmp/newkeys runtime/vm/method_recognizer.h
- THR_Print("s/V(%s, %d)/V(%s, %d)/\n",
- prefix, fp, prefix, SourceFingerprint());
+ THR_Print("s/0x%08x/0x%08x/\n", fp, SourceFingerprint());
} else {
THR_Print("FP mismatch while recognizing method %s:"
- " expecting %d found %d\n",
+ " expecting 0x%08x found 0x%08x\n",
ToFullyQualifiedCString(),
fp,
SourceFingerprint());
@@ -11315,33 +11330,39 @@
OS::Print("Function not found %s.%s\n", #class_name, #function_name); \
} else { \
CHECK_FINGERPRINT3(func, class_name, function_name, dest, fp); \
- } \
+ }
+
+#define CHECK_FINGERPRINTS2(class_name, function_name, dest, type, fp) \
+ CHECK_FINGERPRINTS(class_name, function_name, dest, fp)
all_libs.Add(&Library::ZoneHandle(Library::CoreLibrary()));
- CORE_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
- CORE_INTEGER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
+ CORE_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
+ CORE_INTEGER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
all_libs.Add(&Library::ZoneHandle(Library::CollectionLibrary()));
- OTHER_RECOGNIZED_LIST(CHECK_FINGERPRINTS);
+ OTHER_RECOGNIZED_LIST(CHECK_FINGERPRINTS2);
INLINE_WHITE_LIST(CHECK_FINGERPRINTS);
INLINE_BLACK_LIST(CHECK_FINGERPRINTS);
POLYMORPHIC_TARGET_LIST(CHECK_FINGERPRINTS);
all_libs.Clear();
all_libs.Add(&Library::ZoneHandle(Library::DeveloperLibrary()));
- DEVELOPER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
+ DEVELOPER_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
all_libs.Clear();
all_libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
- MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
+ MATH_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
all_libs.Clear();
all_libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
- TYPED_DATA_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS);
+ TYPED_DATA_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS2);
#undef CHECK_FINGERPRINTS
+#undef CHECK_FINGERPRINTS2
+
+
Class& cls = Class::Handle();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 30cc72d..984a718 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -8521,6 +8521,7 @@
intptr_t cid = value->GetClassId();
// Free-list elements cannot be wrapped in a handle.
ASSERT(cid != kFreeListElement);
+ ASSERT(cid != kForwardingCorpse);
if (cid >= kNumPredefinedCids) {
cid = kInstanceCid;
}
diff --git a/runtime/vm/object_arm64_test.cc b/runtime/vm/object_arm64_test.cc
index 4349bb9..a883609 100644
--- a/runtime/vm/object_arm64_test.cc
+++ b/runtime/vm/object_arm64_test.cc
@@ -17,7 +17,7 @@
// Generate a simple dart code sequence.
// This is used to test Code and Instruction object creation.
void GenerateIncrement(Assembler* assembler) {
- __ mov(SP, CSP);
+ __ EnterFrame(1 * kWordSize);
__ movz(R0, Immediate(0), 0);
__ Push(R0);
__ add(R0, R0, Operand(1));
@@ -26,6 +26,7 @@
__ add(R1, R1, Operand(1));
__ Pop(R0);
__ mov(R0, R1);
+ __ LeaveFrame();
__ ret();
}
diff --git a/runtime/vm/object_dbc_test.cc b/runtime/vm/object_dbc_test.cc
index 464350d..ecb1fa0 100644
--- a/runtime/vm/object_dbc_test.cc
+++ b/runtime/vm/object_dbc_test.cc
@@ -16,14 +16,12 @@
// Generate a simple dart code sequence.
// This is used to test Code and Instruction object creation.
+// For other architectures, this sequence does do an increment, hence the name.
+// On DBC, we don't do an increment because generating an instance call here
+// would be too complex.
void GenerateIncrement(Assembler* assembler) {
__ Frame(1);
- __ LoadConstant(0, Smi::Handle(Smi::New(0)));
- __ PushConstant(Smi::Handle(Smi::New(1)));
- __ Push(0);
- __ AddTOS();
- __ Trap();
- __ PopLocal(0);
+ __ LoadConstant(0, Smi::Handle(Smi::New(1)));
__ Return(0);
}
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 9affdcb..e1ca9dd 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -120,6 +120,24 @@
}
+void ObjectStore::PrintToJSONObject(JSONObject* jsobj) {
+ if (!FLAG_support_service) {
+ return;
+ }
+ jsobj->AddProperty("type", "_ObjectStore");
+
+ {
+ JSONObject fields(jsobj, "fields");
+ Object& value = Object::Handle();
+#define PRINT_OBJECT_STORE_FIELD(type, name) \
+ value = name; \
+ fields.AddProperty(#name, value);
+OBJECT_STORE_FIELD_LIST(PRINT_OBJECT_STORE_FIELD);
+#undef PRINT_OBJECT_STORE_FIELD
+ }
+}
+
+
RawError* ObjectStore::PreallocateObjects() {
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 56ee2b0..a58bc6c 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -498,92 +498,100 @@
static void Init(Isolate* isolate);
+ void PrintToJSONObject(JSONObject* jsobj);
+
private:
ObjectStore();
+#define OBJECT_STORE_FIELD_LIST(V) \
+ V(RawClass*, object_class_) \
+ V(RawType*, object_type_) \
+ V(RawClass*, null_class_) \
+ V(RawType*, null_type_) \
+ V(RawType*, function_type_) \
+ V(RawClass*, closure_class_) \
+ V(RawType*, number_type_) \
+ V(RawType*, int_type_) \
+ V(RawClass*, integer_implementation_class_) \
+ V(RawClass*, smi_class_) \
+ V(RawType*, smi_type_) \
+ V(RawClass*, mint_class_) \
+ V(RawType*, mint_type_) \
+ V(RawClass*, bigint_class_) \
+ V(RawClass*, double_class_) \
+ V(RawType*, double_type_) \
+ V(RawType*, float32x4_type_) \
+ V(RawType*, int32x4_type_) \
+ V(RawType*, float64x2_type_) \
+ V(RawType*, string_type_) \
+ V(RawClass*, future_class_) \
+ V(RawClass*, completer_class_) \
+ V(RawClass*, stream_iterator_class_) \
+ V(RawClass*, symbol_class_) \
+ V(RawClass*, one_byte_string_class_) \
+ V(RawClass*, two_byte_string_class_) \
+ V(RawClass*, external_one_byte_string_class_) \
+ V(RawClass*, external_two_byte_string_class_) \
+ V(RawType*, bool_type_) \
+ V(RawClass*, bool_class_) \
+ V(RawClass*, array_class_) \
+ V(RawType*, array_type_) \
+ V(RawClass*, immutable_array_class_) \
+ V(RawClass*, growable_object_array_class_) \
+ V(RawClass*, linked_hash_map_class_) \
+ V(RawClass*, float32x4_class_) \
+ V(RawClass*, int32x4_class_) \
+ V(RawClass*, float64x2_class_) \
+ V(RawClass*, error_class_) \
+ V(RawClass*, weak_property_class_) \
+ V(RawArray*, symbol_table_) \
+ V(RawArray*, canonical_types_) \
+ V(RawArray*, canonical_type_arguments_) \
+ V(RawLibrary*, async_library_) \
+ V(RawLibrary*, builtin_library_) \
+ V(RawLibrary*, core_library_) \
+ V(RawLibrary*, collection_library_) \
+ V(RawLibrary*, convert_library_) \
+ V(RawLibrary*, developer_library_) \
+ V(RawLibrary*, internal_library_) \
+ V(RawLibrary*, isolate_library_) \
+ V(RawLibrary*, math_library_) \
+ V(RawLibrary*, mirrors_library_) \
+ V(RawLibrary*, native_wrappers_library_) \
+ V(RawLibrary*, profiler_library_) \
+ V(RawLibrary*, root_library_) \
+ V(RawLibrary*, typed_data_library_) \
+ V(RawLibrary*, vmservice_library_) \
+ V(RawGrowableObjectArray*, libraries_) \
+ V(RawArray*, libraries_map_) \
+ V(RawGrowableObjectArray*, closure_functions_) \
+ V(RawGrowableObjectArray*, pending_classes_) \
+ V(RawGrowableObjectArray*, pending_deferred_loads_) \
+ V(RawGrowableObjectArray*, resume_capabilities_) \
+ V(RawGrowableObjectArray*, exit_listeners_) \
+ V(RawGrowableObjectArray*, error_listeners_) \
+ V(RawContext*, empty_context_) \
+ V(RawInstance*, stack_overflow_) \
+ V(RawInstance*, out_of_memory_) \
+ V(RawUnhandledException*, preallocated_unhandled_exception_) \
+ V(RawStacktrace*, preallocated_stack_trace_) \
+ V(RawFunction*, lookup_port_handler_) \
+ V(RawTypedData*, empty_uint32_array_) \
+ V(RawFunction*, handle_message_function_) \
+ V(RawArray*, library_load_error_table_) \
+ V(RawArray*, compile_time_constants_) \
+ V(RawArray*, unique_dynamic_targets_) \
+ V(RawGrowableObjectArray*, token_objects_) \
+ V(RawArray*, token_objects_map_) \
+ V(RawGrowableObjectArray*, megamorphic_cache_table_) \
+ V(RawCode*, megamorphic_miss_code_) \
+ V(RawFunction*, megamorphic_miss_function_) \
+
RawObject** from() { return reinterpret_cast<RawObject**>(&object_class_); }
- RawClass* object_class_;
- RawType* object_type_;
- RawClass* null_class_;
- RawType* null_type_;
- RawType* function_type_;
- RawClass* closure_class_;
- RawType* number_type_;
- RawType* int_type_;
- RawClass* integer_implementation_class_;
- RawClass* smi_class_;
- RawType* smi_type_;
- RawClass* mint_class_;
- RawType* mint_type_;
- RawClass* bigint_class_;
- RawClass* double_class_;
- RawType* double_type_;
- RawType* float32x4_type_;
- RawType* int32x4_type_;
- RawType* float64x2_type_;
- RawType* string_type_;
- RawClass* future_class_;
- RawClass* completer_class_;
- RawClass* stream_iterator_class_;
- RawClass* symbol_class_;
- RawClass* one_byte_string_class_;
- RawClass* two_byte_string_class_;
- RawClass* external_one_byte_string_class_;
- RawClass* external_two_byte_string_class_;
- RawType* bool_type_;
- RawClass* bool_class_;
- RawClass* array_class_;
- RawType* array_type_;
- RawClass* immutable_array_class_;
- RawClass* growable_object_array_class_;
- RawClass* linked_hash_map_class_;
- RawClass* float32x4_class_;
- RawClass* int32x4_class_;
- RawClass* float64x2_class_;
- RawClass* error_class_;
- RawClass* weak_property_class_;
- RawArray* symbol_table_;
- RawArray* canonical_types_;
- RawArray* canonical_type_arguments_;
- RawLibrary* async_library_;
- RawLibrary* builtin_library_;
- RawLibrary* core_library_;
- RawLibrary* collection_library_;
- RawLibrary* convert_library_;
- RawLibrary* developer_library_;
- RawLibrary* internal_library_;
- RawLibrary* isolate_library_;
- RawLibrary* math_library_;
- RawLibrary* mirrors_library_;
- RawLibrary* native_wrappers_library_;
- RawLibrary* profiler_library_;
- RawLibrary* root_library_;
- RawLibrary* typed_data_library_;
- RawLibrary* vmservice_library_;
- RawGrowableObjectArray* libraries_;
- RawArray* libraries_map_;
- RawGrowableObjectArray* closure_functions_;
- RawGrowableObjectArray* pending_classes_;
- RawGrowableObjectArray* pending_deferred_loads_;
- RawGrowableObjectArray* resume_capabilities_;
- RawGrowableObjectArray* exit_listeners_;
- RawGrowableObjectArray* error_listeners_;
- RawContext* empty_context_;
- RawInstance* stack_overflow_;
- RawInstance* out_of_memory_;
- RawUnhandledException* preallocated_unhandled_exception_;
- RawStacktrace* preallocated_stack_trace_;
- RawFunction* lookup_port_handler_;
- RawTypedData* empty_uint32_array_;
- RawFunction* handle_message_function_;
- RawArray* library_load_error_table_;
- RawArray* compile_time_constants_;
- RawArray* unique_dynamic_targets_;
- RawGrowableObjectArray* token_objects_;
- RawArray* token_objects_map_;
- RawGrowableObjectArray* megamorphic_cache_table_;
- RawCode* megamorphic_miss_code_;
- RawFunction* megamorphic_miss_function_;
+#define DECLARE_OBJECT_STORE_FIELD(type, name) \
+ type name;
+OBJECT_STORE_FIELD_LIST(DECLARE_OBJECT_STORE_FIELD)
+#undef DECLARE_OBJECT_STORE_FIELD
RawObject** to() {
return reinterpret_cast<RawObject**>(&megamorphic_miss_function_);
}
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 9ad5f70..7d70f20 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -4125,9 +4125,8 @@
: objects_(objects) { }
virtual ~ObjectAccumulator() { }
virtual void VisitObject(RawObject* obj) {
- // Free-list elements cannot even be wrapped in handles.
- if (obj->IsFreeListElement()) {
- return;
+ if (obj->IsPseudoObject()) {
+ return; // Cannot be wrapped in handles.
}
Object& handle = Object::Handle(obj);
// Skip some common simple objects to run in reasonable time.
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index a07921f..f2a6422 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -365,6 +365,7 @@
void exit_finally() { inside_finally_ = false; }
void AddNodeForFinallyInlining(AstNode* node);
+ void RemoveJumpToLabel(SourceLabel *label);
AstNode* GetNodeToInlineFinally(int index) {
if (0 <= index && index < inlined_finally_nodes_.length()) {
return inlined_finally_nodes_[index];
@@ -390,6 +391,25 @@
}
+void Parser::TryStack::RemoveJumpToLabel(SourceLabel *label) {
+ int i = 0;
+ while (i < inlined_finally_nodes_.length()) {
+ if (inlined_finally_nodes_[i]->IsJumpNode()) {
+ JumpNode* jump = inlined_finally_nodes_[i]->AsJumpNode();
+ if (jump->label() == label) {
+ // Shift remaining entries left and delete last entry.
+ for (int j = i + 1; j < inlined_finally_nodes_.length(); j++) {
+ inlined_finally_nodes_[j - 1] = inlined_finally_nodes_[j];
+ }
+ inlined_finally_nodes_.RemoveLast();
+ continue;
+ }
+ }
+ i++;
+ }
+}
+
+
// For parsing a compilation unit.
Parser::Parser(const Script& script,
const Library& library,
@@ -508,6 +528,14 @@
}
+int Parser::FunctionLevel() const {
+ if (current_block_ != NULL) {
+ return current_block_->scope->function_level();
+ }
+ return 0;
+}
+
+
const Class& Parser::current_class() const {
return current_class_;
}
@@ -2369,7 +2397,7 @@
// If we create an implicit instance closure from inside a closure of a
// parameterized class, make sure that the receiver is captured as
// instantiator.
- if (current_block_->scope->function_level() > 0) {
+ if (FunctionLevel() > 0) {
const Type& signature_type = Type::Handle(Z,
implicit_closure_function.SignatureType());
const Class& scope_class = Class::Handle(Z, signature_type.type_class());
@@ -3358,7 +3386,7 @@
AddFormalParamsToScope(¶ms, current_block_->scope);
if (I->type_checks() &&
- (current_block_->scope->function_level() > 0)) {
+ (FunctionLevel() > 0)) {
// We are parsing, but not compiling, a local function.
// The instantiator may be required at run time for generic type checks.
if (IsInstantiatorRequired()) {
@@ -7406,7 +7434,7 @@
void Parser::CaptureInstantiator() {
- ASSERT(current_block_->scope->function_level() > 0);
+ ASSERT(FunctionLevel() > 0);
const String* variable_name = current_function().IsInFactoryScope() ?
&Symbols::TypeArgumentsParameter() : &Symbols::This();
current_block_->scope->CaptureVariable(
@@ -7643,6 +7671,7 @@
// Note that we cannot share the same closure function between the closurized
// and non-closurized versions of the same parent function.
Function& function = Function::ZoneHandle(Z);
+ bool found_func = true;
// TODO(hausner): There could be two different closures at the given
// function_pos, one enclosed in a closurized function and one enclosed in the
// non-closurized version of this same function.
@@ -7651,6 +7680,7 @@
// The function will be registered in the lookup table by the
// EffectGraphVisitor::VisitClosureNode when the newly allocated closure
// function has been properly setup.
+ found_func = false;
function = Function::NewClosureFunction(*function_name,
innermost_function(),
function_pos);
@@ -7700,15 +7730,40 @@
}
}
- // Parse the local function.
- SequenceNode* statements = Parser::ParseFunc(function, !is_literal);
- INC_STAT(thread(), num_functions_parsed, 1);
+ Type& signature_type = Type::ZoneHandle(Z);
+ SequenceNode* statements = NULL;
+ if (!found_func) {
+ // Parse the local function. As a side effect of the parsing, the
+ // variables of this function's scope that are referenced by the local
+ // function (and its inner nested functions) will be marked as captured.
- // Now that the local function has formal parameters, lookup the signature
- Type& signature_type = Type::ZoneHandle(Z, function.SignatureType());
- signature_type ^= ClassFinalizer::FinalizeType(
- current_class(), signature_type, ClassFinalizer::kCanonicalize);
- function.SetSignatureType(signature_type);
+ statements = Parser::ParseFunc(function, !is_literal);
+ INC_STAT(thread(), num_functions_parsed, 1);
+
+ // Now that the local function has formal parameters, lookup the signature
+ signature_type = function.SignatureType();
+ signature_type ^= ClassFinalizer::FinalizeType(
+ current_class(), signature_type, ClassFinalizer::kCanonicalize);
+ function.SetSignatureType(signature_type);
+ } else {
+ // The local function was parsed before. The captured variables are
+ // saved in the function's context scope. Iterate over the context scope
+ // and mark its variables as captured.
+ const ContextScope& context_scope =
+ ContextScope::Handle(Z, function.context_scope());
+ ASSERT(!context_scope.IsNull());
+ String& var_name = String::Handle(Z);
+ for (int i = 0; i < context_scope.num_variables(); i++) {
+ var_name = context_scope.NameAt(i);
+ // We need to look up the name in a way that returns even hidden
+ // variables, e.g. 'this' in an initializer list.
+ LocalVariable* v = current_block_->scope->LookupVariable(var_name, true);
+ ASSERT(v != NULL);
+ current_block_->scope->CaptureVariable(v);
+ }
+ SkipFunctionLiteral();
+ signature_type = function.SignatureType();
+ }
// Local functions are registered in the enclosing class, but
// ignored during class finalization. The enclosing class has
@@ -7717,7 +7772,7 @@
ASSERT(signature_type.IsFinalized());
// Make sure that the instantiator is captured.
- if ((current_block_->scope->function_level() > 0) &&
+ if ((FunctionLevel() > 0) &&
Class::Handle(signature_type.type_class()).IsGeneric()) {
CaptureInstantiator();
}
@@ -7763,8 +7818,9 @@
// variables are not relevant for the compilation of the enclosing function.
// This pruning is done by omitting to hook the local scope in its parent
// scope in the constructor of LocalScope.
- AstNode* closure = new(Z) ClosureNode(
- function_pos, function, NULL, statements->scope());
+ AstNode* closure =
+ new(Z) ClosureNode(function_pos, function, NULL,
+ statements != NULL ? statements->scope() : NULL);
if (function_variable == NULL) {
ASSERT(is_literal);
@@ -8405,6 +8461,7 @@
// We have seen a 'continue' with this label name. Resolve
// the forward reference.
case_label->ResolveForwardReference();
+ RemoveNodesForFinallyInlining(case_label);
} else {
ReportError(label_pos, "label '%s' already exists in scope",
label_name->ToCString());
@@ -8548,7 +8605,7 @@
if (try_stack_ != NULL) {
LocalScope* scope = try_stack_->try_block()->scope;
uint16_t try_index = try_stack_->try_index();
- const int current_function_level = current_block_->scope->function_level();
+ const int current_function_level = FunctionLevel();
if (scope->function_level() == current_function_level) {
// The block declaring :saved_try_ctx_var variable is the parent of the
// pushed try block.
@@ -9299,7 +9356,7 @@
return;
}
ASSERT(node->IsReturnNode() || node->IsJumpNode());
- const intptr_t func_level = current_block_->scope->function_level();
+ const intptr_t func_level = FunctionLevel();
TryStack* iterator = try_stack_;
while ((iterator != NULL) &&
(iterator->try_block()->scope->function_level() == func_level)) {
@@ -9313,7 +9370,12 @@
// so we do not need to inline the finally code. Otherwise we need
// to inline the finally code of this try block and then move on to the
// next outer try block.
- if (label->owner()->IsNestedWithin(try_scope)) {
+ // For unresolved forward jumps to switch cases, we don't yet know
+ // to which scope the label will be resolved. Tentatively add the
+ // jump to all nested try statements and remove the outermost ones
+ // when we know the exact jump target. (See
+ // RemoveNodesForFinallyInlining below.)
+ if (!label->IsUnresolved() && label->owner()->IsNestedWithin(try_scope)) {
break;
}
}
@@ -9323,13 +9385,26 @@
}
+void Parser::RemoveNodesForFinallyInlining(SourceLabel* label) {
+ TryStack* iterator = try_stack_;
+ const intptr_t func_level = FunctionLevel();
+ while ((iterator != NULL) &&
+ (iterator->try_block()->scope->function_level() == func_level)) {
+ iterator->RemoveJumpToLabel(label);
+ iterator = iterator->outer_try();
+ }
+}
+
+
// Add the inlined finally clause to the specified node.
void Parser::AddFinallyClauseToNode(bool is_async,
AstNode* node,
InlinedFinallyNode* finally_clause) {
ReturnNode* return_node = node->AsReturnNode();
if (return_node != NULL) {
- parsed_function()->EnsureFinallyReturnTemp(is_async);
+ if (FunctionLevel() == 0) {
+ parsed_function()->EnsureFinallyReturnTemp(is_async);
+ }
return_node->AddInlinedFinallyNode(finally_clause);
return;
}
@@ -9444,7 +9519,7 @@
// Has a type specification that is not malformed or malbounded. Now
// form an 'if type check' to guard the catch handler code.
if (!exception_param.type->IsInstantiated() &&
- (current_block_->scope->function_level() > 0)) {
+ (FunctionLevel() > 0)) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
@@ -9859,7 +9934,7 @@
if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) {
ReportError(jump_pos, "'break' to case clause label is illegal");
}
- if (target->FunctionLevel() != current_block_->scope->function_level()) {
+ if (target->FunctionLevel() != FunctionLevel()) {
ReportError(jump_pos, "'%s' target must be in same function context",
Token::Str(jump_kind));
}
@@ -10058,17 +10133,16 @@
if (CurrentToken() != Token::kSEMICOLON) {
const TokenPosition expr_pos = TokenPos();
if (current_function().IsGenerativeConstructor() &&
- (current_block_->scope->function_level() == 0)) {
+ (FunctionLevel() == 0)) {
ReportError(expr_pos,
"return of a value is not allowed in constructors");
} else if (current_function().IsGeneratorClosure() &&
- (current_block_->scope->function_level() == 0)) {
+ (FunctionLevel() == 0)) {
ReportError(expr_pos, "generator functions may not return a value");
}
AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
if (I->type_checks() &&
- current_function().IsAsyncClosure() &&
- (current_block_->scope->function_level() == 0)) {
+ current_function().IsAsyncClosure() && (FunctionLevel() == 0)) {
// In checked mode, when the declared result type is Future<T>, verify
// that the returned expression is of type T or Future<T> as follows:
// return temp = expr, temp is Future ? temp as Future<T> : temp as T;
@@ -10119,7 +10193,7 @@
statement = new(Z) ReturnNode(statement_pos, expr);
} else {
if (current_function().IsSyncGenClosure() &&
- (current_block_->scope->function_level() == 0)) {
+ (FunctionLevel() == 0)) {
// In a synchronous generator, return without an expression
// returns false, signaling that the iterator terminates and
// did not yield a value.
@@ -10529,8 +10603,7 @@
const TokenPosition type_pos = TokenPos();
const AbstractType& type = AbstractType::ZoneHandle(Z,
ParseType(ClassFinalizer::kCanonicalize));
- if (!type.IsInstantiated() &&
- (current_block_->scope->function_level() > 0)) {
+ if (!type.IsInstantiated() && (FunctionLevel() > 0)) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
@@ -11451,7 +11524,7 @@
"from static function",
name.ToCString());
}
- if (current_block_->scope->function_level() > 0) {
+ if (FunctionLevel() > 0) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
@@ -11547,7 +11620,7 @@
"from static function",
name.ToCString());
}
- if (current_block_->scope->function_level() > 0) {
+ if (FunctionLevel() > 0) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
@@ -11665,7 +11738,7 @@
"from static function",
name.ToCString());
}
- if (current_block_->scope->function_level() > 0) {
+ if (FunctionLevel() > 0) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
@@ -12498,7 +12571,7 @@
TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z,
current_class().LookupTypeParameter(ident));
if (!type_parameter.IsNull()) {
- if (current_block_->scope->function_level() > 0) {
+ if (FunctionLevel() > 0) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
@@ -12839,7 +12912,7 @@
ASSERT(!factory_method.IsNull());
if (!list_type_arguments.IsNull() &&
!list_type_arguments.IsInstantiated() &&
- (current_block_->scope->function_level() > 0)) {
+ (FunctionLevel() > 0)) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
@@ -13101,7 +13174,7 @@
ASSERT(!factory_method.IsNull());
if (!map_type_arguments.IsNull() &&
!map_type_arguments.IsInstantiated() &&
- (current_block_->scope->function_level() > 0)) {
+ (FunctionLevel() > 0)) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
@@ -13685,7 +13758,7 @@
CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments);
if (!type_arguments.IsNull() &&
!type_arguments.IsInstantiated() &&
- (current_block_->scope->function_level() > 0)) {
+ (FunctionLevel() > 0)) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
@@ -14352,6 +14425,7 @@
void Parser::SkipPostfixExpr() {
SkipPrimary();
if (CurrentToken() == Token::kHASH) {
+ ConsumeToken();
if (IsIdentifier()) {
ConsumeToken();
SkipIf(Token::kASSIGN);
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 84301f2..3bcb688 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -338,6 +338,10 @@
// current_function(), but is greater than zero while parsing the body of
// local functions nested in current_function().
+ // FunctionLevel is 0 when parsing code of current_function(), and denotes
+ // the relative nesting level when parsing a nested function.
+ int FunctionLevel() const;
+
// The class being parsed.
const Class& current_class() const;
void set_current_class(const Class& value);
@@ -739,6 +743,7 @@
// Add specified node to try block list so that it can be patched with
// inlined finally code if needed.
void AddNodeForFinallyInlining(AstNode* node);
+ void RemoveNodesForFinallyInlining(SourceLabel* label);
// Add the inlined finally clause to the specified node.
void AddFinallyClauseToNode(bool is_async,
AstNode* node,
diff --git a/runtime/vm/port.cc b/runtime/vm/port.cc
index 3df0a63..8ef15c5 100644
--- a/runtime/vm/port.cc
+++ b/runtime/vm/port.cc
@@ -326,4 +326,20 @@
}
}
+
+void PortMap::DebugDumpForMessageHandler(MessageHandler* handler) {
+ SafepointMutexLocker ml(mutex_);
+ Object& msg_handler = Object::Handle();
+ for (intptr_t i = 0; i < capacity_; i++) {
+ if (map_[i].handler == handler) {
+ if (map_[i].state == kLivePort) {
+ OS::Print("Live Port = %" Pd64 "\n", map_[i].port);
+ msg_handler = DartLibraryCalls::LookupHandler(map_[i].port);
+ OS::Print("Handler = %s\n", msg_handler.ToCString());
+ }
+ }
+ }
+}
+
+
} // namespace dart
diff --git a/runtime/vm/port.h b/runtime/vm/port.h
index 9ec7e7b..6e41e3a 100644
--- a/runtime/vm/port.h
+++ b/runtime/vm/port.h
@@ -59,6 +59,8 @@
static void PrintPortsForMessageHandler(MessageHandler* handler,
JSONStream* stream);
+ static void DebugDumpForMessageHandler(MessageHandler* handler);
+
private:
friend class dart::PortMapTestPeer;
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 52c6e88..fd26900 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -366,7 +366,8 @@
}
if ((cid == kDynamicCid) ||
(cid == kVoidCid) ||
- (cid == kFreeListElement)) {
+ (cid == kFreeListElement) ||
+ (cid == kForwardingCorpse)) {
continue;
}
cls = isolate()->class_table()->At(cid);
@@ -407,11 +408,12 @@
{ "dart:typed_data", "ByteData", "ByteData." },
{ "dart:typed_data", "ByteData", "ByteData._view" },
{ "dart:typed_data", "ByteBuffer", "ByteBuffer._New" },
-#if !defined(PRODUCT)
{ "dart:_vmservice", "::", "_registerIsolate" },
{ "dart:_vmservice", "::", "boot" },
+#if !defined(PRODUCT)
{ "dart:developer", "Metrics", "_printMetrics" },
{ "dart:developer", "::", "_runExtension" },
+ { "dart:isolate", "::", "_runPendingImmediateCallback" },
#endif // !PRODUCT
// Fields
{ "dart:core", "Error", "_stackTrace" },
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 195149f..cc0f89d 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -1255,7 +1255,9 @@
void Build() {
ScopeTimer sw("ProfileBuilder::Build", FLAG_trace_profiler);
- FilterSamples();
+ if (!FilterSamples()) {
+ return;
+ }
Setup();
BuildCodeTable();
@@ -1297,15 +1299,16 @@
RegisterProfileCodeTag(VMTag::kInlineEndCodeTagId);
}
- void FilterSamples() {
+ bool FilterSamples() {
ScopeTimer sw("ProfileBuilder::FilterSamples", FLAG_trace_profiler);
SampleBuffer* sample_buffer = Profiler::sample_buffer();
if (sample_buffer == NULL) {
- return;
+ return false;
}
samples_ = sample_buffer->BuildProcessedSampleBuffer(filter_);
profile_->samples_ = samples_;
profile_->sample_count_ = samples_->length();
+ return true;
}
void UpdateMinMaxTimes(int64_t timestamp) {
@@ -2518,7 +2521,7 @@
ProfileFunction* Profile::FindFunction(const Function& function) {
- return functions_->Lookup(function);
+ return (functions_ != NULL) ? functions_->Lookup(function) : NULL;
}
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index cc880e9..8f92e9d 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -4,6 +4,7 @@
#include "vm/raw_object.h"
+#include "vm/become.h"
#include "vm/class_table.h"
#include "vm/dart.h"
#include "vm/freelist.h"
@@ -177,6 +178,12 @@
instance_size = element->Size();
break;
}
+ case kForwardingCorpse: {
+ uword addr = RawObject::ToAddr(this);
+ ForwardingCorpse* element = reinterpret_cast<ForwardingCorpse*>(addr);
+ instance_size = element->Size();
+ break;
+ }
default: {
// Get the (constant) instance size out of the class object.
// TODO(koda): Add Size(ClassTable*) interface to allow caching in loops.
@@ -288,6 +295,12 @@
size = element->Size();
break;
}
+ case kForwardingCorpse: {
+ uword addr = RawObject::ToAddr(this);
+ ForwardingCorpse* forwarder = reinterpret_cast<ForwardingCorpse*>(addr);
+ size = forwarder->Size();
+ break;
+ }
case kNullCid:
size = Size();
break;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 74cf176..518b027 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -181,9 +181,12 @@
kDynamicCid,
kVoidCid,
- // The following entry does not describe a real class, but instead it is an
- // id which is used to identify free list elements in the heap.
+ // The following entries describes classes for pseudo-objects in the heap
+ // that should never be reachable from live objects. Free list elements
+ // maintain the free list for old space, and forwarding corpses are used to
+ // implement one-way become.
kFreeListElement,
+ kForwardingCorpse,
kNumPredefinedCids,
};
@@ -442,6 +445,12 @@
bool IsFreeListElement() const {
return ((GetClassId() == kFreeListElement));
}
+ bool IsForwardingCorpse() const {
+ return ((GetClassId() == kForwardingCorpse));
+ }
+ bool IsPseudoObject() const {
+ return IsFreeListElement() || IsForwardingCorpse();
+ }
intptr_t Size() const {
uword tags = ptr()->tags_;
diff --git a/runtime/vm/safepoint.h b/runtime/vm/safepoint.h
index 9477425..58afb49 100644
--- a/runtime/vm/safepoint.h
+++ b/runtime/vm/safepoint.h
@@ -313,10 +313,45 @@
}
private:
- int16_t execution_state_;
+ uint32_t execution_state_;
DISALLOW_COPY_AND_ASSIGN(TransitionToGenerated);
};
+
+// TransitionToVM is used to transition the safepoint state of a
+// thread from "running native code" to "running vm code"
+// and ensures that the state is reverted back to "running native code"
+// when exiting the scope/frame.
+// This transition helper is mainly used in the error path of the
+// Dart API implementations where we sometimes do not have an explicit
+// transition set up.
+class TransitionToVM : public TransitionSafepointState {
+ public:
+ explicit TransitionToVM(Thread* T) : TransitionSafepointState(T),
+ execution_state_(T->execution_state()) {
+ ASSERT(T == Thread::Current());
+ ASSERT((execution_state_ == Thread::kThreadInVM) ||
+ (execution_state_ == Thread::kThreadInNative));
+ if (execution_state_ == Thread::kThreadInNative) {
+ T->ExitSafepoint();
+ T->set_execution_state(Thread::kThreadInVM);
+ }
+ ASSERT(T->execution_state() == Thread::kThreadInVM);
+ }
+
+ ~TransitionToVM() {
+ ASSERT(thread()->execution_state() == Thread::kThreadInVM);
+ if (execution_state_ == Thread::kThreadInNative) {
+ thread()->set_execution_state(Thread::kThreadInNative);
+ thread()->EnterSafepoint();
+ }
+ }
+
+ private:
+ uint32_t execution_state_;
+ DISALLOW_COPY_AND_ASSIGN(TransitionToVM);
+};
+
} // namespace dart
#endif // VM_SAFEPOINT_H_
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 03f0912..306a78a 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -464,11 +464,9 @@
total_count += count;
while (!pending->IsEmpty()) {
RawObject* raw_object = pending->Pop();
- if (raw_object->IsFreeListElement()) {
- // TODO(rmacnak): Forwarding corpse from become. Probably we should also
- // visit the store buffer blocks during become, and mark any forwardees
- // as remembered if their forwarders are remembered to satisfy the
- // following assert.
+ if (raw_object->IsForwardingCorpse()) {
+ // A source object in a become was a remembered object, but we do
+ // not visit the store buffer during become to remove it.
continue;
}
ASSERT(raw_object->IsRemembered());
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 6060e7a..be2cdda 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -98,6 +98,14 @@
}
+void LocalScope::MoveLabel(SourceLabel* label) {
+ ASSERT(LocalLookupLabel(label->name()) == NULL);
+ ASSERT(label->kind() == SourceLabel::kForward);
+ labels_.Add(label);
+ label->set_owner(this);
+}
+
+
NameReference* LocalScope::FindReference(const String& name) const {
ASSERT(name.IsSymbol());
intptr_t num_references = referenced_.length();
@@ -489,7 +497,7 @@
if (outer_switch == NULL) {
return label;
} else {
- outer_switch->AddLabel(label);
+ outer_switch->MoveLabel(label);
}
}
}
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index aaf120d..c2fbfe0 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -182,7 +182,6 @@
const String& name() const { return name_; }
LocalScope* owner() const { return owner_; }
void set_owner(LocalScope* owner) {
- ASSERT(owner_ == NULL);
owner_ = owner;
}
@@ -191,6 +190,7 @@
// Returns the function level of the scope in which the label is defined.
int FunctionLevel() const;
+ bool IsUnresolved() { return kind_ == kForward; }
void ResolveForwardReference() { kind_ = kCase; }
private:
@@ -255,6 +255,9 @@
// is already present.
bool AddLabel(SourceLabel* label);
+ // Move an unresolved label of a switch case label to an outer switch.
+ void MoveLabel(SourceLabel* label);
+
// Lookup a variable in this scope only.
LocalVariable* LocalLookupVariable(const String& name) const;
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index fc78a48..80607bb 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -859,7 +859,6 @@
if (handler != NULL) {
EmbedderHandleMessage(handler, &js);
- js.PostReply();
return;
}
@@ -1126,16 +1125,16 @@
ASSERT(handler != NULL);
Dart_ServiceRequestCallback callback = handler->callback();
ASSERT(callback != NULL);
- const char* r = NULL;
- const char* method = js->method();
- const char** keys = js->param_keys();
- const char** values = js->param_values();
- r = callback(method, keys, values, js->num_params(), handler->user_data());
- ASSERT(r != NULL);
- // TODO(johnmccutchan): Allow for NULL returns?
- TextBuffer* buffer = js->buffer();
- buffer->AddString(r);
- free(const_cast<char*>(r));
+ const char* response = NULL;
+ bool success = callback(js->method(), js->param_keys(), js->param_values(),
+ js->num_params(), handler->user_data(), &response);
+ ASSERT(response != NULL);
+ if (!success) {
+ js->SetupError();
+ }
+ js->buffer()->AddString(response);
+ js->PostReply();
+ free(const_cast<char*>(response));
}
@@ -2217,7 +2216,7 @@
virtual Direction VisitObject(ObjectGraph::StackIterator* it) {
RawObject* raw_obj = it->Get();
- if (raw_obj->IsFreeListElement()) {
+ if (raw_obj->IsPseudoObject()) {
return kProceed;
}
Thread* thread = Thread::Current();
@@ -3341,8 +3340,7 @@
virtual uword filter_addr() const { return addr_; }
virtual bool FindObject(RawObject* obj) const {
- // Free list elements are not real objects, so skip them.
- if (obj->IsFreeListElement()) {
+ if (obj->IsPseudoObject()) {
return false;
}
uword obj_begin = RawObject::ToAddr(obj);
@@ -3597,6 +3595,19 @@
}
+static const MethodParameter* get_object_store_params[] = {
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
+};
+
+
+static bool GetObjectStore(Thread* thread, JSONStream* js) {
+ JSONObject jsobj(js);
+ thread->isolate()->object_store()->PrintToJSONObject(&jsobj);
+ return true;
+}
+
+
static const MethodParameter* get_class_list_params[] = {
RUNNABLE_ISOLATE_PARAMETER,
NULL,
@@ -3973,6 +3984,8 @@
get_isolate_metric_list_params },
{ "getObject", GetObject,
get_object_params },
+ { "_getObjectStore", GetObjectStore,
+ get_object_store_params },
{ "_getObjectByAddress", GetObjectByAddress,
get_object_by_address_params },
{ "_getPersistentHandles", GetPersistentHandles,
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index e65c539..d4d02d7 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -363,6 +363,9 @@
protected:
static void ShutdownIsolate(uword parameter) {
+ if (FLAG_trace_service) {
+ OS::Print("vm-service: ShutdownIsolate\n");
+ }
Isolate* I = reinterpret_cast<Isolate*>(parameter);
ASSERT(ServiceIsolate::IsServiceIsolate(I));
ServiceIsolate::SetServiceIsolate(NULL);
@@ -382,6 +385,10 @@
if (!error.IsNull() && !error.IsUnwindError()) {
OS::PrintErr("vm-service: Error: %s\n", error.ToErrorCString());
}
+ error = I->sticky_error();
+ if (!error.IsNull() && !error.IsUnwindError()) {
+ OS::PrintErr("vm-service: Error: %s\n", error.ToErrorCString());
+ }
Dart::RunShutdownCallback();
}
// Shut the isolate down.
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index 5071bce..c272b4c 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -571,23 +571,27 @@
}
-static const char* alpha_callback(
+static bool alpha_callback(
const char* name,
const char** option_keys,
const char** option_values,
intptr_t num_options,
- void* user_data) {
- return strdup("alpha");
+ void* user_data,
+ const char** result) {
+ *result = strdup("alpha");
+ return true;
}
-static const char* beta_callback(
+static bool beta_callback(
const char* name,
const char** option_keys,
const char** option_values,
intptr_t num_options,
- void* user_data) {
- return strdup("beta");
+ void* user_data,
+ const char** result) {
+ *result = strdup("beta");
+ return false;
}
@@ -626,7 +630,7 @@
service_msg = Eval(lib, "[0, port, 1, 'beta', [], []]");
Service::HandleRootMessage(service_msg);
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
- EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"result\":beta,\"id\":1}",
+ EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"error\":beta,\"id\":1}",
handler.msg());
}
@@ -666,7 +670,7 @@
service_msg = Eval(lib, "[0, port, '0', 'beta', [], []]");
Service::HandleIsolateMessage(isolate, service_msg);
EXPECT_EQ(MessageHandler::kOK, handler.HandleNextMessage());
- EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"result\":beta,\"id\":\"0\"}",
+ EXPECT_STREQ("{\"jsonrpc\":\"2.0\", \"error\":beta,\"id\":\"0\"}",
handler.msg());
}
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 36f5f9c..b3cac8b 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -1218,7 +1218,7 @@
void Simulator::ClearExclusive() {
MutexLocker ml(exclusive_access_lock_);
// Remove the reservation for this thread.
- SetExclusiveAccess(NULL);
+ SetExclusiveAccess(0);
}
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index ffe4e92..baafca84 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -754,6 +754,20 @@
#define DECLARE_A_X int32_t rD; USE(rD)
#define DECODE_A_X rD = (static_cast<int32_t>(op) >> Bytecode::kDShift);
+
+#define SMI_FASTPATH_ICDATA_INC \
+ do { \
+ ASSERT(Bytecode::IsCallOpcode(*pc)); \
+ const uint16_t kidx = Bytecode::DecodeD(*pc); \
+ const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx)); \
+ RawObject** data = icdata->ptr()->ic_data_->ptr()->data(); \
+ const intptr_t count_offset = ICData::CountIndexFor(2); \
+ const intptr_t raw_smi_old = \
+ reinterpret_cast<intptr_t>(data[count_offset]); \
+ const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1); \
+ *reinterpret_cast<intptr_t*>(&data[count_offset]) = raw_smi_new; \
+ } while (0); \
+
// Declare bytecode handler for a smi operation (e.g. AddTOS) with the
// given result type and the given behavior specified as a function
// that takes left and right operands and result slot and returns
@@ -764,6 +778,7 @@
const intptr_t rhs = reinterpret_cast<intptr_t>(SP[-0]); \
ResultT* slot = reinterpret_cast<ResultT*>(SP - 1); \
if (LIKELY(AreBothSmis(lhs, rhs) && !Func(lhs, rhs, slot))) { \
+ SMI_FASTPATH_ICDATA_INC; \
/* Fast path succeeded. Skip the generic call that follows. */ \
pc++; \
/* We dropped 2 arguments and push result */ \
diff --git a/runtime/vm/simulator_dbc.h b/runtime/vm/simulator_dbc.h
index 9865ca9..7172bbe 100644
--- a/runtime/vm/simulator_dbc.h
+++ b/runtime/vm/simulator_dbc.h
@@ -76,7 +76,7 @@
}
enum IntrinsicId {
-#define V(test_class_name, test_function_name, enum_name, fp) \
+#define V(test_class_name, test_function_name, enum_name, type, fp) \
k##enum_name##Intrinsic,
ALL_INTRINSICS_LIST(V)
GRAPH_INTRINSICS_LIST(V)
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index d23c755..d980ca1 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -1156,7 +1156,7 @@
void Simulator::ClearExclusive() {
MutexLocker ml(exclusive_access_lock_);
// Remove the reservation for this thread.
- SetExclusiveAccess(NULL);
+ SetExclusiveAccess(0);
}
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index ee8858d6..7fa1573 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -30,6 +30,22 @@
}
+SourceReport::~SourceReport() {
+ ClearScriptTable();
+}
+
+
+void SourceReport::ClearScriptTable() {
+ for (intptr_t i = 0; i < script_table_entries_.length(); i++) {
+ delete script_table_entries_[i];
+ script_table_entries_[i] = NULL;
+ }
+ script_table_entries_.Clear();
+ script_table_.Clear();
+ next_script_index_ = 0;
+}
+
+
void SourceReport::Init(Thread* thread,
const Script* script,
TokenPosition start_pos,
@@ -38,9 +54,7 @@
script_ = script;
start_pos_ = start_pos;
end_pos_ = end_pos;
- script_table_entries_.Clear();
- script_table_.Clear();
- next_script_index_ = 0;
+ ClearScriptTable();
if (IsReportRequested(kProfile)) {
// Build the profile.
SampleFilter samplesForIsolate(thread_->isolate(),
@@ -103,17 +117,36 @@
if (pair != NULL) {
return pair->index;
}
-
- ScriptTableEntry tmp;
- tmp.key = &url;
- tmp.index = next_script_index_++;
- tmp.script = &script;
+ ScriptTableEntry* tmp = new ScriptTableEntry();
+ tmp->key = &url;
+ tmp->index = next_script_index_++;
+ tmp->script = &Script::Handle(zone(), script.raw());
script_table_entries_.Add(tmp);
- script_table_.Insert(&(script_table_entries_.Last()));
- return tmp.index;
+ script_table_.Insert(tmp);
+ ASSERT(script_table_entries_.length() == next_script_index_);
+#if defined(DEBUG)
+ VerifyScriptTable();
+#endif
+ return tmp->index;
}
+#if defined(DEBUG)
+void SourceReport::VerifyScriptTable() {
+ for (intptr_t i = 0; i < script_table_entries_.length(); i++) {
+ const String* url = script_table_entries_[i]->key;
+ const Script* script = script_table_entries_[i]->script;
+ intptr_t index = script_table_entries_[i]->index;
+ ASSERT(i == index);
+ const String& url2 = String::Handle(zone(), script->url());
+ ASSERT(url2.Equals(*url));
+ ScriptTableEntry* pair = script_table_.Lookup(&url2);
+ ASSERT(i == pair->index);
+ }
+}
+#endif
+
+
bool SourceReport::ScriptIsLoadedByLibrary(const Script& script,
const Library& lib) {
const Array& scripts = Array::Handle(zone(), lib.LoadedScripts());
@@ -337,8 +370,8 @@
void SourceReport::PrintScriptTable(JSONArray* scripts) {
- for (int i = 0; i < script_table_entries_.length(); i++) {
- const Script* script = script_table_entries_[i].script;
+ for (intptr_t i = 0; i < script_table_entries_.length(); i++) {
+ const Script* script = script_table_entries_[i]->script;
scripts->AddValue(*script);
}
}
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index cd2ad3a..dec18cfa 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -40,6 +40,7 @@
// (e.g. kCallSites | kCoverage).
explicit SourceReport(intptr_t report_set,
CompileMode compile = kNoCompile);
+ ~SourceReport();
// Generate a source report for (some subrange of) a script.
//
@@ -50,6 +51,7 @@
TokenPosition end_pos = TokenPosition::kNoSource);
private:
+ void ClearScriptTable();
void Init(Thread* thread, const Script* script,
TokenPosition start_pos, TokenPosition end_pos);
@@ -69,6 +71,9 @@
void PrintPossibleBreakpointsData(JSONObject* jsobj,
const Function& func, const Code& code);
void PrintProfileData(JSONObject* jsobj, ProfileFunction* profile_function);
+#if defined(DEBUG)
+ void VerifyScriptTable();
+#endif
void PrintScriptTable(JSONArray* jsarr);
void VisitFunction(JSONArray* jsarr, const Function& func);
@@ -114,7 +119,7 @@
TokenPosition start_pos_;
TokenPosition end_pos_;
Profile profile_;
- GrowableArray<ScriptTableEntry> script_table_entries_;
+ GrowableArray<ScriptTableEntry*> script_table_entries_;
DirectChainedHashMap<ScriptTableTrait> script_table_;
intptr_t next_script_index_;
};
diff --git a/runtime/vm/source_report_test.cc b/runtime/vm/source_report_test.cc
index ad00dec..2d3f5bc 100644
--- a/runtime/vm/source_report_test.cc
+++ b/runtime/vm/source_report_test.cc
@@ -425,6 +425,49 @@
}
+TEST_CASE(SourceReport_Coverage_AllFunctions_ForceCompile) {
+ const char* kScript =
+ "helper0() {}\n"
+ "helper1() {}\n"
+ "main() {\n"
+ " if (true) {\n"
+ " helper0();\n"
+ " } else {\n"
+ " helper1();\n"
+ " }\n"
+ "}";
+
+ Library& lib = Library::Handle();
+ lib ^= ExecuteScript(kScript);
+ ASSERT(!lib.IsNull());
+
+ SourceReport report(SourceReport::kCoverage, SourceReport::kForceCompile);
+ JSONStream js;
+
+ // We generate a report with all functions in the VM.
+ Script& null_script = Script::Handle();
+ {
+ TransitionNativeToVM transition(Thread::Current());
+ report.PrintJSON(&js, null_script);
+ }
+ const char* result = js.ToCString();
+
+ // Sanity check the header.
+ EXPECT_SUBSTRING("{\"type\":\"SourceReport\",\"ranges\":[", result);
+
+ // Make sure that the main function was found.
+ EXPECT_SUBSTRING(
+ "\"startPos\":12,\"endPos\":39,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[23],\"misses\":[32]}",
+ result);
+
+ // More than one script is referenced in the report.
+ EXPECT_SUBSTRING("\"scriptIndex\":0", result);
+ EXPECT_SUBSTRING("\"scriptIndex\":1", result);
+ EXPECT_SUBSTRING("\"scriptIndex\":2", result);
+}
+
+
TEST_CASE(SourceReport_CallSites_SimpleCall) {
char buffer[1024];
const char* kScript =
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 15b7e0f..97a20c8 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -780,8 +780,8 @@
__ Comment("InvokeDartCodeStub");
// Copy the C stack pointer (R31) into the stack pointer we'll actually use
- // to access the stack, and put the C stack pointer at the stack limit.
- __ SetupDartSP(OSThread::GetSpecifiedStackSize());
+ // to access the stack.
+ __ SetupDartSP();
__ EnterFrame(0);
// Push code object to PC marker slot.
@@ -896,7 +896,7 @@
// Restore the frame pointer and C stack pointer and return.
__ LeaveFrame();
- __ mov(CSP, SP);
+ __ RestoreCSP();
__ ret();
}
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 7057da2..8b85956 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -274,6 +274,8 @@
V(ByteBufferDot_New, "ByteBuffer._New") \
V(_WeakProperty, "_WeakProperty") \
V(_MirrorReference, "_MirrorReference") \
+ V(FreeListElement, "FreeListElement") \
+ V(ForwardingCorpse, "ForwardingCorpse") \
V(InvocationMirror, "_InvocationMirror") \
V(AllocateInvocationMirror, "_allocateInvocationMirror") \
V(toString, "toString") \
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index c6b6bdb..2059b7107 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -75,7 +75,7 @@
static bool IsImportableTestLib(const char* url_name) {
- const char* kImportTestLibUri = "importable_test_lib";
+ const char* kImportTestLibUri = "test:importable_lib";
static const intptr_t kImportTestLibUriLen = strlen(kImportTestLibUri);
return (strncmp(url_name, kImportTestLibUri, kImportTestLibUriLen) == 0);
}
@@ -92,8 +92,9 @@
}
+#ifndef PRODUCT
static bool IsIsolateReloadTestLib(const char* url_name) {
- const char* kIsolateReloadTestLibUri = "isolate_reload_test_helper";
+ const char* kIsolateReloadTestLibUri = "test:isolate_reload_helper";
static const intptr_t kIsolateReloadTestLibUriLen =
strlen(kIsolateReloadTestLibUri);
return (strncmp(url_name,
@@ -102,7 +103,6 @@
}
-#ifndef PRODUCT
static Dart_Handle IsolateReloadTestLibSource() {
// Special library with one function.
return DartUtils::NewString("void reloadTest() native 'Reload_Test';\n");
@@ -139,6 +139,9 @@
static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
Dart_Handle library,
Dart_Handle url) {
+ if (tag == Dart_kCanonicalizeUrl) {
+ return Dart_DefaultCanonicalizeUrl(library, url);
+ }
if (tag == Dart_kScriptTag) {
// Reload request.
ASSERT(script_reload_key != kUnsetThreadLocalKey);
@@ -146,7 +149,7 @@
reinterpret_cast<const char*>(
OSThread::GetThreadLocal(script_reload_key));
ASSERT(script_source != NULL);
- OSThread::SetThreadLocal(script_reload_key, NULL);
+ OSThread::SetThreadLocal(script_reload_key, 0);
return Dart_LoadScript(url,
NewString(script_source),
0,
@@ -172,23 +175,6 @@
bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_chars);
bool is_io_library = DartUtils::IsDartIOLibURL(library_url_string);
- if (tag == Dart_kCanonicalizeUrl) {
- // Already canonicalized.
- if (IsImportableTestLib(url_chars) || IsIsolateReloadTestLib(url_chars)) {
- return url;
- }
- // If this is a Dart Scheme URL then it is not modified as it will be
- // handled by the VM internally.
- if (is_dart_scheme_url || is_io_library) {
- return url;
- }
-
- Dart_Handle library_url = Dart_LibraryUrl(library);
- if (Dart_IsError(library_url)) {
- return library_url;
- }
- return DartUtils::ResolveUri(library_url, url);
- }
if (is_dart_scheme_url) {
ASSERT(tag == Dart_kImportTag);
// Handle imports of other built-in libraries present in the SDK.
diff --git a/runtime/vm/uri.cc b/runtime/vm/uri.cc
new file mode 100644
index 0000000..7d9ef76
--- /dev/null
+++ b/runtime/vm/uri.cc
@@ -0,0 +1,541 @@
+// 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/uri.h"
+
+#include "vm/zone.h"
+
+namespace dart {
+
+static bool IsUnreservedChar(intptr_t value) {
+ return ((value >= 'a' && value <= 'z') ||
+ (value >= 'A' && value <= 'Z') ||
+ (value >= '0' && value <= '9') ||
+ value == '-' ||
+ value == '.' ||
+ value == '_' ||
+ value == '~');
+}
+
+
+static bool IsDelimiter(intptr_t value) {
+ switch (value) {
+ case ':': case '/': case '?': case '#':
+ case '[': case ']': case '@': case '!':
+ case '$': case '&': case '\'': case '(':
+ case ')': case '*': case '+': case ',':
+ case ';': case '=':
+ return true;
+ default:
+ return false;
+ }
+}
+
+
+static bool IsHexDigit(char value) {
+ return ((value >= '0' && value <= '9') ||
+ (value >= 'A' && value <= 'F') ||
+ (value >= 'a' && value <= 'f'));
+}
+
+
+static int HexValue(char digit) {
+ if ((digit >= '0' && digit <= '9')) {
+ return digit - '0';
+ }
+ if ((digit >= 'A' && digit <= 'F')) {
+ return digit - 'A' + 10;
+ }
+ if ((digit >= 'a' && digit <= 'f')) {
+ return digit - 'a' + 10;
+ }
+ UNREACHABLE();
+ return 0;
+}
+
+
+static int GetEscapedValue(const char* str, intptr_t pos, intptr_t len) {
+ if (pos + 2 >= len) {
+ // Not enough room for a valid escape sequence.
+ return -1;
+ }
+ if (str[pos] != '%') {
+ // Escape sequences start with '%'.
+ return -1;
+ }
+
+ char digit1 = str[pos + 1];
+ char digit2 = str[pos + 2];
+ if (!IsHexDigit(digit1) || !IsHexDigit(digit2)) {
+ // Invalid escape sequence. Ignore it.
+ return -1;
+ }
+ return HexValue(digit1) * 16 + HexValue(digit2);
+}
+
+
+static char* NormalizeEscapes(const char* str, intptr_t len) {
+ // Allocate the buffer.
+ Zone* zone = Thread::Current()->zone();
+ // We multiply len by three because a percent-escape sequence is
+ // three characters long (e.g. ' ' -> '%20). +1 for '\0'. We could
+ // take two passes through the string and avoid the excess
+ // allocation, but it's zone-memory so it doesn't seem necessary.
+ char* buffer = zone->Alloc<char>(len * 3 + 1);
+
+ // Copy the string, normalizing as we go.
+ intptr_t buffer_pos = 0;
+ intptr_t pos = 0;
+ while (pos < len) {
+ int escaped_value = GetEscapedValue(str, pos, len);
+ if (escaped_value >= 0) {
+ // If one of the special "unreserved" characters has been
+ // escaped, revert the escaping. Otherwise preserve the
+ // escaping.
+ if (IsUnreservedChar(escaped_value)) {
+ buffer[buffer_pos] = escaped_value;
+ buffer_pos++;
+ } else {
+ OS::SNPrint(buffer + buffer_pos, 4, "%%%02X", escaped_value);
+ buffer_pos += 3;
+ }
+ pos += 3;
+ } else {
+ char c = str[pos];
+ // If a delimiter or unreserved character is currently not
+ // escaped, preserve that. If there is a busted %-sequence in
+ // the input, preserve that too.
+ if (c == '%' || IsDelimiter(c) || IsUnreservedChar(c)) {
+ buffer[buffer_pos] = c;
+ buffer_pos++;
+ } else {
+ // Escape funky characters.
+ OS::SNPrint(buffer + buffer_pos, 4, "%%%02X", c);
+ buffer_pos += 3;
+ }
+ pos++;
+ }
+ }
+ buffer[buffer_pos] = '\0';
+ return buffer;
+}
+
+
+// Lower-case a string in place.
+static void StringLower(char* str) {
+ const intptr_t len = strlen(str);
+ intptr_t i = 0;
+ while (i < len) {
+ int escaped_value = GetEscapedValue(str, i, len);
+ if (escaped_value >= 0) {
+ // Don't lowercase escape sequences.
+ i += 3;
+ } else {
+ // I don't use tolower() because I don't want the locale
+ // transforming any non-acii characters.
+ char c = str[i];
+ if (c >= 'A' && c <= 'Z') {
+ str[i] = c + ('a' - 'A');
+ }
+ i++;
+ }
+ }
+}
+
+
+static void ClearParsedUri(ParsedUri* parsed_uri) {
+ parsed_uri->scheme = NULL;
+ parsed_uri->userinfo = NULL;
+ parsed_uri->host = NULL;
+ parsed_uri->port = NULL;
+ parsed_uri->path = NULL;
+ parsed_uri->query = NULL;
+ parsed_uri->fragment = NULL;
+}
+
+
+static intptr_t ParseAuthority(const char* authority, ParsedUri* parsed_uri) {
+ Zone* zone = Thread::Current()->zone();
+ const char* current = authority;
+ intptr_t len = 0;
+
+ size_t userinfo_len = strcspn(current, "@/");
+ if (current[userinfo_len] == '@') {
+ // The '@' character follows the optional userinfo string.
+ parsed_uri->userinfo = NormalizeEscapes(current, userinfo_len);
+ current += userinfo_len + 1;
+ len += userinfo_len + 1;
+ } else {
+ parsed_uri->userinfo = NULL;
+ }
+
+ size_t host_len = strcspn(current, ":/");
+ char* host = NormalizeEscapes(current, host_len);
+ StringLower(host);
+ parsed_uri->host = host;
+ len += host_len;
+
+ if (current[host_len] == ':') {
+ // The ':' character precedes the optional port string.
+ const char* port_start = current + host_len + 1; // +1 for ':'
+ size_t port_len = strcspn(port_start, "/");
+ parsed_uri->port = zone->MakeCopyOfStringN(port_start, port_len);
+ len += 1 + port_len; // +1 for ':'
+ } else {
+ parsed_uri->port = NULL;
+ }
+ return len;
+}
+
+
+// Performs a simple parse of a uri into its components.
+// See RFC 3986 Section 3: Syntax.
+bool ParseUri(const char* uri, ParsedUri* parsed_uri) {
+ Zone* zone = Thread::Current()->zone();
+
+ // The first ':' separates the scheme from the rest of the uri. If
+ // a ':' occurs after the first '/' it doesn't count.
+ size_t scheme_len = strcspn(uri, ":/");
+ const char* rest = uri;
+ if (uri[scheme_len] == ':') {
+ char* scheme = zone->MakeCopyOfStringN(uri, scheme_len);
+ StringLower(scheme);
+ parsed_uri->scheme = scheme;
+ rest = uri + scheme_len + 1;
+ } else {
+ parsed_uri->scheme = NULL;
+ }
+
+ // The first '#' separates the optional fragment
+ const char* hash_pos = rest + strcspn(rest, "#");
+ if (*hash_pos == '#') {
+ // There is a fragment part.
+ const char* fragment_start = hash_pos + 1;
+ parsed_uri->fragment =
+ NormalizeEscapes(fragment_start, strlen(fragment_start));
+ } else {
+ parsed_uri->fragment = NULL;
+ }
+
+ // The first '?' or '#' separates the hierarchical part from the
+ // optional query.
+ const char* question_pos = rest + strcspn(rest, "?#");
+ if (*question_pos == '?') {
+ // There is a query part.
+ const char* query_start = question_pos + 1;
+ parsed_uri->query =
+ NormalizeEscapes(query_start, (hash_pos - query_start));
+ } else {
+ parsed_uri->query = NULL;
+ }
+
+ const char* path_start = rest;
+ if (rest[0] == '/' && rest[1] == '/') {
+ // There is an authority part.
+ const char* authority_start = rest + 2; // 2 for '//'.
+
+ intptr_t authority_len =
+ ParseAuthority(authority_start, parsed_uri);
+ if (authority_len < 0) {
+ ClearParsedUri(parsed_uri);
+ return false;
+ }
+ path_start = authority_start + authority_len;
+ } else {
+ parsed_uri->userinfo = NULL;
+ parsed_uri->host = NULL;
+ parsed_uri->port = NULL;
+ }
+
+ // The path is the substring between the authority and the query.
+ parsed_uri->path = NormalizeEscapes(path_start, (question_pos - path_start));
+ return true;
+}
+
+
+static char* RemoveLastSegment(char* current, char* base) {
+ if (current == base) {
+ return current;
+ }
+ ASSERT(current > base);
+ for (current--; current > base; current--) {
+ if (*current == '/') {
+ // We have found the beginning of the last segment.
+ return current;
+ }
+ }
+ ASSERT(current == base);
+ return current;
+}
+
+
+static intptr_t SegmentLength(const char* input) {
+ const char* cp = input;
+
+ // Include initial slash in the segment, if any.
+ if (*cp == '/') {
+ cp++;
+ }
+
+ // Don't include trailing slash in the segment.
+ cp += strcspn(cp, "/");
+ return cp - input;
+}
+
+
+// See RFC 3986 Section 5.2.4: Remove Dot Segments.
+static const char* RemoveDotSegments(const char* path) {
+ const char* input = path;
+
+ // The output path will always be less than or equal to the size of
+ // the input path.
+ Zone* zone = Thread::Current()->zone();
+ char* buffer = zone->Alloc<char>(strlen(path) + 1); // +1 for '\0'
+ char* output = buffer;
+
+ while (*input != '\0') {
+ if (strncmp("../", input, 3) == 0) {
+ // Discard initial "../" from the input. It's junk.
+ input += 3;
+
+ } else if (strncmp("./", input, 3) == 0) {
+ // Discard initial "./" from the input. It's junk.
+ input += 2;
+
+ } else if (strncmp("/./", input, 3) == 0) {
+ // Advance past the "/." part of the input.
+ input += 2;
+
+ } else if (strcmp("/.", input) == 0) {
+ // Pretend the input just contains a "/".
+ input = "/";
+
+ } else if (strncmp("/../", input, 4) == 0) {
+ // Advance past the "/.." part of the input and remove one
+ // segment from the output.
+ input += 3;
+ output = RemoveLastSegment(output, buffer);
+
+ } else if (strcmp("/..", input) == 0) {
+ // Pretend the input contains a "/" and remove one segment from
+ // the output.
+ input = "/";
+ output = RemoveLastSegment(output, buffer);
+
+ } else if (strcmp("..", input) == 0) {
+ // The input has been reduced to nothing useful.
+ input += 2;
+
+ } else if (strcmp(".", input) == 0) {
+ // The input has been reduced to nothing useful.
+ input += 1;
+
+ } else {
+ intptr_t segment_len = SegmentLength(input);
+ if (input[0] != '/' && output != buffer) {
+ *output = '/';
+ output++;
+ }
+ strncpy(output, input, segment_len);
+ output += segment_len;
+ input += segment_len;
+ }
+ }
+ *output = '\0';
+ return buffer;
+}
+
+
+// See RFC 3986 Section 5.2.3: Merge Paths.
+static const char* MergePaths(const char* base_path, const char* ref_path) {
+ Zone* zone = Thread::Current()->zone();
+ if (base_path[0] == '\0') {
+ // If the base_path is empty, we prepend '/'.
+ return zone->PrintToString("/%s", ref_path);
+ }
+
+ // We need to find the last '/' in base_path.
+ const char* last_slash = strrchr(base_path, '/');
+ if (last_slash == NULL) {
+ // There is no slash in the base_path. Return the ref_path unchanged.
+ return ref_path;
+ }
+
+ // We found a '/' in the base_path. Cut off everything after it and
+ // add the ref_path.
+ intptr_t truncated_base_len = last_slash - base_path;
+ intptr_t ref_path_len = strlen(ref_path);
+ intptr_t len = truncated_base_len + ref_path_len + 1; // +1 for '/'
+ char* buffer = zone->Alloc<char>(len + 1); // +1 for '\0'
+
+ // Copy truncated base.
+ strncpy(buffer, base_path, truncated_base_len);
+
+ // Add a slash.
+ buffer[truncated_base_len] = '/';
+
+ // Copy the ref_path.
+ strncpy((buffer + truncated_base_len + 1), ref_path, ref_path_len);
+
+ // Add the trailing '\0'.
+ buffer[len] = '\0';
+
+ return buffer;
+}
+
+
+static char* BuildUri(const ParsedUri& uri) {
+ Zone* zone = Thread::Current()->zone();
+ ASSERT(uri.path != NULL);
+
+ const char* fragment = uri.fragment == NULL ? "" : uri.fragment;
+ const char* fragment_separator = uri.fragment == NULL ? "" : "#";
+ const char* query = uri.query == NULL ? "" : uri.query;
+ const char* query_separator = uri.query == NULL ? "" : "?";
+
+ // If there is no scheme for this uri, just build a relative uri of
+ // the form: "path[?query][#fragment]". This occurs when we resolve
+ // relative urls inside a "dart:" library.
+ if (uri.scheme == NULL) {
+ ASSERT(uri.userinfo == NULL && uri.host == NULL && uri.port == NULL);
+ return zone->PrintToString("%s%s%s%s%s",
+ uri.path, query_separator, query,
+ fragment_separator, fragment);
+ }
+
+ // Uri with no authority: "scheme:path[?query][#fragment]"
+ if (uri.host == NULL) {
+ ASSERT(uri.userinfo == NULL && uri.port == NULL);
+ return zone->PrintToString("%s:%s%s%s%s%s",
+ uri.scheme, uri.path, query_separator, query,
+ fragment_separator, fragment);
+ }
+
+ const char* user = uri.userinfo == NULL ? "" : uri.userinfo;
+ const char* user_separator = uri.userinfo == NULL ? "" : "@";
+ const char* port = uri.port == NULL ? "" : uri.port;
+ const char* port_separator = uri.port == NULL ? "" : ":";
+
+ // If the path doesn't start with a '/', add one. We need it to
+ // separate the path from the authority.
+ const char* path_separator = ((uri.path[0] == '\0' || uri.path[0] == '/')
+ ? "" : "/");
+
+ // Uri with authority:
+ // "scheme://[userinfo@]host[:port][/]path[?query][#fragment]"
+ return zone->PrintToString(
+ "%s://%s%s%s%s%s%s%s%s%s%s%s", // There is *nothing* wrong with this.
+ uri.scheme, user, user_separator, uri.host, port_separator, port,
+ path_separator, uri.path, query_separator, query,
+ fragment_separator, fragment);
+}
+
+
+// See RFC 3986 Section 5: Reference Resolution
+bool ResolveUri(const char* ref_uri,
+ const char* base_uri,
+ const char** target_uri) {
+ // Parse the reference uri.
+ ParsedUri ref;
+ if (!ParseUri(ref_uri, &ref)) {
+ *target_uri = NULL;
+ return false;
+ }
+
+ ParsedUri target;
+ if (ref.scheme != NULL) {
+ if (strcmp(ref.scheme, "dart") == 0) {
+ Zone* zone = Thread::Current()->zone();
+ *target_uri = zone->MakeCopyOfString(ref_uri);
+ return true;
+ }
+
+ // When the ref_uri specifies a scheme, the base_uri is ignored.
+ target.scheme = ref.scheme;
+ target.userinfo = ref.userinfo;
+ target.host = ref.host;
+ target.port = ref.port;
+ target.path = RemoveDotSegments(ref.path);
+ target.query = ref.query;
+ target.fragment = ref.fragment;
+ *target_uri = BuildUri(target);
+ return true;
+ }
+
+ // Parse the base uri.
+ ParsedUri base;
+ if (!ParseUri(base_uri, &base)) {
+ *target_uri = NULL;
+ return false;
+ }
+
+ if ((base.scheme != NULL) && strcmp(base.scheme, "dart") == 0) {
+ Zone* zone = Thread::Current()->zone();
+ *target_uri = zone->MakeCopyOfString(ref_uri);
+ return true;
+ }
+
+ if (ref.host != NULL) {
+ // When the ref_uri specifies an authority, we only use the base scheme.
+ target.scheme = base.scheme;
+ target.userinfo = ref.userinfo;
+ target.host = ref.host;
+ target.port = ref.port;
+ target.path = RemoveDotSegments(ref.path);
+ target.query = ref.query;
+ target.fragment = ref.fragment;
+ *target_uri = BuildUri(target);
+ return true;
+ }
+
+ if (ref.path[0] == '\0') {
+ // Empty path. Use most parts of base_uri.
+ target.scheme = base.scheme;
+ target.userinfo = base.userinfo;
+ target.host = base.host;
+ target.port = base.port;
+ target.path = base.path;
+ target.query = ((ref.query == NULL) ? base.query : ref.query);
+ target.fragment = ref.fragment;
+ *target_uri = BuildUri(target);
+ return true;
+
+ } else if (ref.path[0] == '/') {
+ // Absolute path. ref_path wins.
+ target.scheme = base.scheme;
+ target.userinfo = base.userinfo;
+ target.host = base.host;
+ target.port = base.port;
+ target.path = RemoveDotSegments(ref.path);
+ target.query = ref.query;
+ target.fragment = ref.fragment;
+ *target_uri = BuildUri(target);
+ return true;
+
+ } else {
+ // Relative path. We need to merge the base path and the ref path.
+
+ if (base.scheme == NULL && base.host == NULL && base.path[0] != '/') {
+ // The dart:core Uri class handles resolving a relative uri
+ // against a second relative uri specially, in a way not
+ // described in the RFC. We do not need to support this for
+ // library resolution. If we need to implement this later, we
+ // can.
+ *target_uri = NULL;
+ return false;
+ }
+
+ target.scheme = base.scheme;
+ target.userinfo = base.userinfo;
+ target.host = base.host;
+ target.port = base.port;
+ target.path = RemoveDotSegments(MergePaths(base.path, ref.path));
+ target.query = ref.query;
+ target.fragment = ref.fragment;
+ *target_uri = BuildUri(target);
+ return true;
+ }
+}
+
+} // namespace dart
diff --git a/runtime/vm/uri.h b/runtime/vm/uri.h
new file mode 100644
index 0000000..453b371
--- /dev/null
+++ b/runtime/vm/uri.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef VM_URI_H_
+#define VM_URI_H_
+
+#include "platform/utils.h"
+#include "vm/globals.h"
+
+namespace dart {
+
+struct ParsedUri {
+ const char* scheme;
+ const char* userinfo;
+ const char* host;
+ const char* port;
+ const char* path;
+ const char* query;
+ const char* fragment;
+};
+
+// Parses a uri into its parts. Returns false if the parse fails.
+bool ParseUri(const char* uri, ParsedUri* parsed_uri);
+
+// Resolves some reference uri with respect to a base uri.
+bool ResolveUri(const char* ref_uri,
+ const char* base_uri,
+ const char** target_uri);
+
+} // namespace dart
+
+#endif // VM_URI_H_
diff --git a/runtime/vm/uri_test.cc b/runtime/vm/uri_test.cc
new file mode 100644
index 0000000..34631a5
--- /dev/null
+++ b/runtime/vm/uri_test.cc
@@ -0,0 +1,666 @@
+// 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/uri.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+TEST_CASE(ParseUri_WithScheme_NoQueryNoUser) {
+ ParsedUri uri;
+ EXPECT(ParseUri("foo://example.com:8042/over/there", &uri));
+ EXPECT_STREQ("foo", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT_STREQ("example.com", uri.host);
+ EXPECT_STREQ("8042", uri.port);
+ EXPECT_STREQ("/over/there", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_WithScheme_WithQuery) {
+ ParsedUri uri;
+ EXPECT(ParseUri("foo://example.com:8042/over/there?name=ferret", &uri));
+ EXPECT_STREQ("foo", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT_STREQ("example.com", uri.host);
+ EXPECT_STREQ("8042", uri.port);
+ EXPECT_STREQ("/over/there", uri.path);
+ EXPECT_STREQ("name=ferret", uri.query);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_WithScheme_WithFragment) {
+ ParsedUri uri;
+ EXPECT(ParseUri("foo://example.com:8042/over/there#fragment", &uri));
+ EXPECT_STREQ("foo", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT_STREQ("example.com", uri.host);
+ EXPECT_STREQ("8042", uri.port);
+ EXPECT_STREQ("/over/there", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT_STREQ("fragment", uri.fragment);
+}
+
+
+TEST_CASE(ParseUri_WithScheme_WithQueryWithFragment) {
+ ParsedUri uri;
+ EXPECT(ParseUri("foo://example.com:8042/over/there?name=ferret#fragment",
+ &uri));
+ EXPECT_STREQ("foo", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT_STREQ("example.com", uri.host);
+ EXPECT_STREQ("8042", uri.port);
+ EXPECT_STREQ("/over/there", uri.path);
+ EXPECT_STREQ("name=ferret", uri.query);
+ EXPECT_STREQ("fragment", uri.fragment);
+}
+
+
+TEST_CASE(ParseUri_WithScheme_WithUser) {
+ ParsedUri uri;
+ EXPECT(ParseUri("foo://user@example.com:8042/over/there", &uri));
+ EXPECT_STREQ("foo", uri.scheme);
+ EXPECT_STREQ("user", uri.userinfo);
+ EXPECT_STREQ("example.com", uri.host);
+ EXPECT_STREQ("8042", uri.port);
+ EXPECT_STREQ("/over/there", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_WithScheme_ShortPath) {
+ ParsedUri uri;
+ EXPECT(ParseUri("foo://example.com:8042/", &uri));
+ EXPECT_STREQ("foo", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT_STREQ("example.com", uri.host);
+ EXPECT_STREQ("8042", uri.port);
+ EXPECT_STREQ("/", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_WithScheme_EmptyPath) {
+ ParsedUri uri;
+ EXPECT(ParseUri("foo://example.com:8042", &uri));
+ EXPECT_STREQ("foo", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT_STREQ("example.com", uri.host);
+ EXPECT_STREQ("8042", uri.port);
+ EXPECT_STREQ("", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_WithScheme_Rootless1) {
+ ParsedUri uri;
+ EXPECT(ParseUri("foo:here", &uri));
+ EXPECT_STREQ("foo", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("here", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_WithScheme_Rootless2) {
+ ParsedUri uri;
+ EXPECT(ParseUri("foo:or/here", &uri));
+ EXPECT_STREQ("foo", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("or/here", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_NoScheme_AbsPath_WithAuthority) {
+ ParsedUri uri;
+ EXPECT(ParseUri("//example.com:8042/over/there", &uri));
+ EXPECT(uri.scheme == NULL);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT_STREQ("example.com", uri.host);
+ EXPECT_STREQ("8042", uri.port);
+ EXPECT_STREQ("/over/there", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_NoScheme_AbsPath_NoAuthority) {
+ ParsedUri uri;
+ EXPECT(ParseUri("/over/there", &uri));
+ EXPECT(uri.scheme == NULL);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("/over/there", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+// Colons are permitted in path segments, in many cases.
+TEST_CASE(ParseUri_NoScheme_AbsPath_StrayColon) {
+ ParsedUri uri;
+ EXPECT(ParseUri("/ov:er/there", &uri));
+ EXPECT(uri.scheme == NULL);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("/ov:er/there", uri.path);
+ EXPECT(uri.query == NULL);
+}
+
+
+TEST_CASE(ParseUri_NoScheme_Rootless1) {
+ ParsedUri uri;
+ EXPECT(ParseUri("here", &uri));
+ EXPECT(uri.scheme == NULL);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("here", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_NoScheme_Rootless2) {
+ ParsedUri uri;
+ EXPECT(ParseUri("or/here", &uri));
+ EXPECT(uri.scheme == NULL);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("or/here", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_NoScheme_Empty) {
+ ParsedUri uri;
+ EXPECT(ParseUri("", &uri));
+ EXPECT(uri.scheme == NULL);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_NoScheme_QueryOnly) {
+ ParsedUri uri;
+ EXPECT(ParseUri("?name=ferret", &uri));
+ EXPECT(uri.scheme == NULL);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("", uri.path);
+ EXPECT_STREQ("name=ferret", uri.query);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_NoScheme_FragmentOnly) {
+ ParsedUri uri;
+ EXPECT(ParseUri("#fragment", &uri));
+ EXPECT(uri.scheme == NULL);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT_STREQ("fragment", uri.fragment);
+}
+
+
+TEST_CASE(ParseUri_LowerCaseScheme) {
+ ParsedUri uri;
+ EXPECT(ParseUri("ScHeMe:path", &uri));
+ EXPECT_STREQ("scheme", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("path", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_NormalizeEscapes_PathQueryFragment) {
+ ParsedUri uri;
+ EXPECT(ParseUri(
+ "scheme:/This%09Is A P%61th?This%09Is A Qu%65ry#A Fr%61gment", &uri));
+ EXPECT_STREQ("scheme", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("/This%09Is%20A%20Path", uri.path);
+ EXPECT_STREQ("This%09Is%20A%20Query", uri.query);
+ EXPECT_STREQ("A%20Fragment", uri.fragment);
+}
+
+
+TEST_CASE(ParseUri_NormalizeEscapes_UppercaseEscapesPreferred) {
+ ParsedUri uri;
+ EXPECT(ParseUri(
+ "scheme:/%1b%1B", &uri));
+ EXPECT_STREQ("scheme", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("/%1B%1B", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_NormalizeEscapes_Authority) {
+ ParsedUri uri;
+ EXPECT(ParseUri(
+ "scheme://UsEr N%61%4de@h%4FsT.c%6fm:80/", &uri));
+ EXPECT_STREQ("scheme", uri.scheme);
+ EXPECT_STREQ("UsEr%20NaMe", uri.userinfo); // Normalized, case preserved.
+ EXPECT_STREQ("host.com", uri.host); // Normalized, lower-cased.
+ EXPECT_STREQ("80", uri.port);
+ EXPECT_STREQ("/", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_NormalizeEscapes_UppercaseEscapeInHost) {
+ ParsedUri uri;
+ EXPECT(ParseUri("scheme://tEst%1b/", &uri));
+ EXPECT_STREQ("scheme", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT_STREQ("test%1B", uri.host); // Notice that %1B is upper-cased.
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("/", uri.path);
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ParseUri_BrokenEscapeSequence) {
+ ParsedUri uri;
+ EXPECT(ParseUri(
+ "scheme:/%1g", &uri));
+ EXPECT_STREQ("scheme", uri.scheme);
+ EXPECT(uri.userinfo == NULL);
+ EXPECT(uri.host == NULL);
+ EXPECT(uri.port == NULL);
+ EXPECT_STREQ("/%1g", uri.path); // Broken sequence is unchanged.
+ EXPECT(uri.query == NULL);
+ EXPECT(uri.fragment == NULL);
+}
+
+
+TEST_CASE(ResolveUri_WithScheme_NoAuthorityNoQuery) {
+ const char* target_uri;
+ EXPECT(ResolveUri("rscheme:/ref/path",
+ "bscheme://buser@bhost:11/base/path?baseQuery",
+ &target_uri));
+ EXPECT_STREQ("rscheme:/ref/path", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_WithScheme_WithAuthorityWithQuery) {
+ const char* target_uri;
+ EXPECT(ResolveUri("rscheme://ruser@rhost:22/ref/path?refQuery",
+ "bscheme://buser@bhost:11/base/path?baseQuery",
+ &target_uri));
+ EXPECT_STREQ("rscheme://ruser@rhost:22/ref/path?refQuery", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NoScheme_WithAuthority) {
+ const char* target_uri;
+ EXPECT(ResolveUri("//ruser@rhost:22/ref/path",
+ "bscheme://buser@bhost:11/base/path?baseQuery",
+ &target_uri));
+ EXPECT_STREQ("bscheme://ruser@rhost:22/ref/path", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NoSchemeNoAuthority_AbsolutePath) {
+ const char* target_uri;
+ EXPECT(ResolveUri("/ref/path",
+ "bscheme://buser@bhost:11/base/path?baseQuery",
+ &target_uri));
+ EXPECT_STREQ("bscheme://buser@bhost:11/ref/path", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NoSchemeNoAuthority_RelativePath) {
+ const char* target_uri;
+ EXPECT(ResolveUri("ref/path",
+ "bscheme://buser@bhost:11/base/path?baseQuery",
+ &target_uri));
+ EXPECT_STREQ("bscheme://buser@bhost:11/base/ref/path", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NoSchemeNoAuthority_RelativePathEmptyBasePath) {
+ const char* target_uri;
+ EXPECT(ResolveUri("ref/path",
+ "bscheme://buser@bhost:11",
+ &target_uri));
+ EXPECT_STREQ("bscheme://buser@bhost:11/ref/path", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NoSchemeNoAuthority_RelativePathWeirdBasePath) {
+ const char* target_uri;
+ EXPECT(ResolveUri("ref/path",
+ "bscheme:base",
+ &target_uri));
+ EXPECT_STREQ("bscheme:ref/path", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NoSchemeNoAuthority_EmptyPath) {
+ const char* target_uri;
+ EXPECT(ResolveUri("",
+ "bscheme://buser@bhost:11/base/path?baseQuery#bfragment",
+ &target_uri));
+ // Note that we drop the base fragment from the resolved uri.
+ EXPECT_STREQ("bscheme://buser@bhost:11/base/path?baseQuery", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NoSchemeNoAuthority_EmptyPathWithQuery) {
+ const char* target_uri;
+ EXPECT(ResolveUri("?refQuery",
+ "bscheme://buser@bhost:11/base/path?baseQuery#bfragment",
+ &target_uri));
+ EXPECT_STREQ("bscheme://buser@bhost:11/base/path?refQuery", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NoSchemeNoAuthority_EmptyPathWithFragment) {
+ const char* target_uri;
+ EXPECT(ResolveUri("#rfragment",
+ "bscheme://buser@bhost:11/base/path?baseQuery#bfragment",
+ &target_uri));
+ EXPECT_STREQ("bscheme://buser@bhost:11/base/path?baseQuery#rfragment",
+ target_uri);
+}
+
+
+TEST_CASE(ResolveUri_RemoveDots_RemoveOneDotSegment) {
+ const char* target_uri;
+ EXPECT(ResolveUri("./refpath",
+ "scheme://auth/a/b/c/d",
+ &target_uri));
+ EXPECT_STREQ("scheme://auth/a/b/c/refpath", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_RemoveDots_RemoveTwoDotSegments) {
+ const char* target_uri;
+ EXPECT(ResolveUri("././refpath",
+ "scheme://auth/a/b/c/d",
+ &target_uri));
+ EXPECT_STREQ("scheme://auth/a/b/c/refpath", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_RemoveDots_RemoveOneDotDotSegment) {
+ const char* target_uri;
+ EXPECT(ResolveUri("../refpath",
+ "scheme://auth/a/b/c/d",
+ &target_uri));
+ EXPECT_STREQ("scheme://auth/a/b/refpath", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_RemoveDots_RemoveTwoDotDotSegments) {
+ const char* target_uri;
+ EXPECT(ResolveUri("../../refpath",
+ "scheme://auth/a/b/c/d",
+ &target_uri));
+ EXPECT_STREQ("scheme://auth/a/refpath", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_RemoveDots_RemoveTooManyDotDotSegments) {
+ const char* target_uri;
+ EXPECT(ResolveUri("../../../../../../../../../refpath",
+ "scheme://auth/a/b/c/d",
+ &target_uri));
+ EXPECT_STREQ("scheme://auth/refpath", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_RemoveDots_RemoveDotSegmentsNothingLeft1) {
+ const char* target_uri;
+ EXPECT(ResolveUri("../../../../..",
+ "scheme://auth/a/b/c/d",
+ &target_uri));
+ EXPECT_STREQ("scheme://auth/", target_uri);
+}
+
+
+
+TEST_CASE(ResolveUri_RemoveDots_RemoveDotSegmentsNothingLeft2) {
+ const char* target_uri;
+ EXPECT(ResolveUri(".",
+ "scheme://auth/",
+ &target_uri));
+ EXPECT_STREQ("scheme://auth/", target_uri);
+}
+
+
+
+TEST_CASE(ResolveUri_RemoveDots_RemoveDotSegmentsInitialPrefix) {
+ const char* target_uri;
+ EXPECT(ResolveUri("../../../../refpath",
+ "scheme://auth",
+ &target_uri));
+ EXPECT_STREQ("scheme://auth/refpath", target_uri);
+}
+
+
+
+TEST_CASE(ResolveUri_RemoveDots_RemoveDotSegmentsMixed) {
+ const char* target_uri;
+ EXPECT(ResolveUri("../../1/./2/../3/4/../5/././6/../7",
+ "scheme://auth/a/b/c/d/e",
+ &target_uri));
+ EXPECT_STREQ("scheme://auth/a/b/1/3/5/7", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NormalizeEscapes_PathQueryFragment) {
+ const char* target_uri;
+ EXPECT(ResolveUri("#A Fr%61gment",
+ "scheme:/This%09Is A P%61th?This%09Is A Qu%65ry",
+ &target_uri));
+ EXPECT_STREQ(
+ "scheme:/This%09Is%20A%20Path?This%09Is%20A%20Query#A%20Fragment",
+ target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NormalizeEscapes_UppercaseHexPreferred) {
+ const char* target_uri;
+ EXPECT(ResolveUri("",
+ "scheme:/%1b%1B",
+ &target_uri));
+ EXPECT_STREQ("scheme:/%1B%1B",
+ target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NormalizeEscapes_Authority) {
+ const char* target_uri;
+ EXPECT(ResolveUri("",
+ "scheme://UsEr N%61%4de@h%4FsT.c%6fm:80/",
+ &target_uri));
+ // userinfo is normalized and case is preserved. host is normalized
+ // and lower-cased.
+ EXPECT_STREQ("scheme://UsEr%20NaMe@host.com:80/", target_uri);
+}
+
+
+TEST_CASE(ResolveUri_NormalizeEscapes_BrokenEscapeSequence) {
+ const char* target_uri;
+ EXPECT(ResolveUri("",
+ "scheme:/%1g",
+ &target_uri));
+ // We don't change broken escape sequences.
+ EXPECT_STREQ("scheme:/%1g",
+ target_uri);
+}
+
+
+TEST_CASE(ResolveUri_DataUri) {
+ const char* data_uri =
+ "data:application/dart;charset=utf-8,%20%20%20%20%20%20%20%20import%20%22dart:isolate%22;%0A%0A%20%20%20%20%20%20%20%20import%20%22package:stream_channel/stream_channel.dart%22;%0A%0A%20%20%20%20%20%20%20%20import%20%22package:test/src/runner/plugin/remote_platform_helpers.dart%22;%0A%20%20%20%20%20%20%20%20import%20%22package:test/src/runner/vm/catch_isolate_errors.dart%22;%0A%0A%20%20%20%20%20%20%20%20import%20%22file:///home/sra/xxxx/dev_compiler/test/all_tests.dart%22%20as%20test;%0A%0A%20%20%20%20%20%20%20%20void%20main(_,%20SendPort%20message)%20%7B%0A%20%20%20%20%20%20%20%20%20%20var%20channel%20=%20serializeSuite(()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20catchIsolateErrors();%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20test.main;%0A%20%20%20%20%20%20%20%20%20%20%7D);%0A%20%20%20%20%20%20%20%20%20%20new%20IsolateChannel.connectSend(message).pipe(channel);%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20"; // NOLINT
+
+ const char* target_uri;
+ EXPECT(ResolveUri(data_uri,
+ "bscheme://buser@bhost:11/base/path?baseQuery#bfragment",
+ &target_uri));
+ EXPECT_STREQ(data_uri, target_uri);
+}
+
+// dart:core Uri allows for the base url to be relative (no scheme, no
+// authory, relative path) but this behavior is not in RFC 3986. We
+// do not implement this.
+TEST_CASE(ResolveUri_RelativeBase_NotImplemented) {
+ const char* target_uri;
+ EXPECT(!ResolveUri("../r1", "b1/b2", &target_uri));
+ EXPECT(target_uri == NULL);
+
+ EXPECT(!ResolveUri("..", "b1/b2", &target_uri));
+ EXPECT(target_uri == NULL);
+
+ EXPECT(!ResolveUri("../..", "b1/b2", &target_uri));
+ EXPECT(target_uri == NULL);
+
+ EXPECT(!ResolveUri("../../..", "b1/b2", &target_uri));
+ EXPECT(target_uri == NULL);
+
+ EXPECT(!ResolveUri("../../../r1", "b1/b2", &target_uri));
+ EXPECT(target_uri == NULL);
+
+ EXPECT(!ResolveUri("../r1", "../../b1/b2/b3", &target_uri));
+ EXPECT(target_uri == NULL);
+
+ EXPECT(!ResolveUri("../../../r1", "../../b1/b2/b3", &target_uri));
+ EXPECT(target_uri == NULL);
+}
+
+
+static const char* TestResolve(const char* base_uri, const char* uri) {
+ const char* target_uri;
+ EXPECT(ResolveUri(uri, base_uri, &target_uri));
+ return target_uri;
+}
+
+
+// This test is ported from sdk/tests/corelib/uri_test.dart (testUriPerRFCs).
+TEST_CASE(ResolveUri_TestUriPerRFCs) {
+ const char* base = "http://a/b/c/d;p?q";
+
+ // From RFC 3986
+ EXPECT_STREQ("g:h", TestResolve(base, "g:h"));
+ EXPECT_STREQ("http://a/b/c/g", TestResolve(base, "g"));
+ EXPECT_STREQ("http://a/b/c/g", TestResolve(base, "./g"));
+ EXPECT_STREQ("http://a/b/c/g/", TestResolve(base, "g/"));
+ EXPECT_STREQ("http://a/g", TestResolve(base, "/g"));
+ EXPECT_STREQ("http://g", TestResolve(base, "//g"));
+ EXPECT_STREQ("http://a/b/c/d;p?y", TestResolve(base, "?y"));
+ EXPECT_STREQ("http://a/b/c/g?y", TestResolve(base, "g?y"));
+ EXPECT_STREQ("http://a/b/c/d;p?q#s", TestResolve(base, "#s"));
+ EXPECT_STREQ("http://a/b/c/g#s", TestResolve(base, "g#s"));
+ EXPECT_STREQ("http://a/b/c/g?y#s", TestResolve(base, "g?y#s"));
+ EXPECT_STREQ("http://a/b/c/;x", TestResolve(base, ";x"));
+ EXPECT_STREQ("http://a/b/c/g;x", TestResolve(base, "g;x"));
+ EXPECT_STREQ("http://a/b/c/g;x?y#s", TestResolve(base, "g;x?y#s"));
+ EXPECT_STREQ("http://a/b/c/d;p?q", TestResolve(base, ""));
+ EXPECT_STREQ("http://a/b/c/", TestResolve(base, "."));
+ EXPECT_STREQ("http://a/b/c/", TestResolve(base, "./"));
+ EXPECT_STREQ("http://a/b/", TestResolve(base, ".."));
+ EXPECT_STREQ("http://a/b/", TestResolve(base, "../"));
+ EXPECT_STREQ("http://a/b/g", TestResolve(base, "../g"));
+ EXPECT_STREQ("http://a/", TestResolve(base, "../.."));
+ EXPECT_STREQ("http://a/", TestResolve(base, "../../"));
+ EXPECT_STREQ("http://a/g", TestResolve(base, "../../g"));
+ EXPECT_STREQ("http://a/g", TestResolve(base, "../../../g"));
+ EXPECT_STREQ("http://a/g", TestResolve(base, "../../../../g"));
+ EXPECT_STREQ("http://a/g", TestResolve(base, "/./g"));
+ EXPECT_STREQ("http://a/g", TestResolve(base, "/../g"));
+ EXPECT_STREQ("http://a/b/c/g.", TestResolve(base, "g."));
+ EXPECT_STREQ("http://a/b/c/.g", TestResolve(base, ".g"));
+ EXPECT_STREQ("http://a/b/c/g..", TestResolve(base, "g.."));
+ EXPECT_STREQ("http://a/b/c/..g", TestResolve(base, "..g"));
+ EXPECT_STREQ("http://a/b/g", TestResolve(base, "./../g"));
+ EXPECT_STREQ("http://a/b/c/g/", TestResolve(base, "./g/."));
+ EXPECT_STREQ("http://a/b/c/g/h", TestResolve(base, "g/./h"));
+ EXPECT_STREQ("http://a/b/c/h", TestResolve(base, "g/../h"));
+ EXPECT_STREQ("http://a/b/c/g;x=1/y", TestResolve(base, "g;x=1/./y"));
+ EXPECT_STREQ("http://a/b/c/y", TestResolve(base, "g;x=1/../y"));
+ EXPECT_STREQ("http://a/b/c/g?y/./x", TestResolve(base, "g?y/./x"));
+ EXPECT_STREQ("http://a/b/c/g?y/../x", TestResolve(base, "g?y/../x"));
+ EXPECT_STREQ("http://a/b/c/g#s/./x", TestResolve(base, "g#s/./x"));
+ EXPECT_STREQ("http://a/b/c/g#s/../x", TestResolve(base, "g#s/../x"));
+ EXPECT_STREQ("http:g", TestResolve(base, "http:g"));
+
+ // Additional tests (not from RFC 3986).
+ EXPECT_STREQ("http://a/b/g;p/h;s", TestResolve(base, "../g;p/h;s"));
+
+ base = "s:a/b";
+ EXPECT_STREQ("s:/c", TestResolve(base, "../c"));
+}
+
+
+// This test is ported from sdk/tests/corelib/uri_test.dart (testResolvePath).
+TEST_CASE(ResolveUri_MoreDotSegmentTests) {
+ const char* base = "/";
+ EXPECT_STREQ("/a/g", TestResolve(base, "/a/b/c/./../../g"));
+ EXPECT_STREQ("/a/g", TestResolve(base, "/a/b/c/./../../g"));
+ EXPECT_STREQ("/mid/6", TestResolve(base, "mid/content=5/../6"));
+ EXPECT_STREQ("/a/b/e", TestResolve(base, "a/b/c/d/../../e"));
+ EXPECT_STREQ("/a/b/e", TestResolve(base, "../a/b/c/d/../../e"));
+ EXPECT_STREQ("/a/b/e", TestResolve(base, "./a/b/c/d/../../e"));
+ EXPECT_STREQ("/a/b/e", TestResolve(base, "../a/b/./c/d/../../e"));
+ EXPECT_STREQ("/a/b/e", TestResolve(base, "./a/b/./c/d/../../e"));
+ EXPECT_STREQ("/a/b/e/", TestResolve(base, "./a/b/./c/d/../../e/."));
+ EXPECT_STREQ("/a/b/e/", TestResolve(base, "./a/b/./c/d/../../e/./."));
+ EXPECT_STREQ("/a/b/e/", TestResolve(base, "./a/b/./c/d/../../e/././."));
+
+ #define LH "http://localhost"
+ base = LH;
+ EXPECT_STREQ(LH "/a/g", TestResolve(base, "/a/b/c/./../../g"));
+ EXPECT_STREQ(LH "/a/g", TestResolve(base, "/a/b/c/./../../g"));
+ EXPECT_STREQ(LH "/mid/6", TestResolve(base, "mid/content=5/../6"));
+ EXPECT_STREQ(LH "/a/b/e", TestResolve(base, "a/b/c/d/../../e"));
+ EXPECT_STREQ(LH "/a/b/e", TestResolve(base, "../a/b/c/d/../../e"));
+ EXPECT_STREQ(LH "/a/b/e", TestResolve(base, "./a/b/c/d/../../e"));
+ EXPECT_STREQ(LH "/a/b/e", TestResolve(base, "../a/b/./c/d/../../e"));
+ EXPECT_STREQ(LH "/a/b/e", TestResolve(base, "./a/b/./c/d/../../e"));
+ EXPECT_STREQ(LH "/a/b/e/", TestResolve(base, "./a/b/./c/d/../../e/."));
+ EXPECT_STREQ(LH "/a/b/e/", TestResolve(base, "./a/b/./c/d/../../e/./."));
+ EXPECT_STREQ(LH "/a/b/e/", TestResolve(base, "./a/b/./c/d/../../e/././."));
+ #undef LH
+}
+
+} // namespace dart
diff --git a/runtime/vm/verifier.cc b/runtime/vm/verifier.cc
index 78b4697..5491f1d 100644
--- a/runtime/vm/verifier.cc
+++ b/runtime/vm/verifier.cc
@@ -20,7 +20,7 @@
void VerifyObjectVisitor::VisitObject(RawObject* raw_obj) {
if (raw_obj->IsHeapObject()) {
uword raw_addr = RawObject::ToAddr(raw_obj);
- if (raw_obj->IsFreeListElement()) {
+ if (raw_obj->IsFreeListElement() || raw_obj->IsForwardingCorpse()) {
if (raw_obj->IsMarked()) {
FATAL1("Marked free list element encountered %#" Px "\n", raw_addr);
}
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index edb97e4..3c11343 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -506,6 +506,9 @@
'unicode_test.cc',
'unit_test.cc',
'unit_test.h',
+ 'uri.cc',
+ 'uri.h',
+ 'uri_test.cc',
'utils_test.cc',
'verified_memory.cc',
'verified_memory.h',
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index dc17044..0f6754f 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -169,6 +169,21 @@
}
+char* Zone::MakeCopyOfStringN(const char* str, intptr_t len) {
+ ASSERT(len >= 0);
+ for (intptr_t i = 0; i < len; i++) {
+ if (str[i] == '\0') {
+ len = i;
+ break;
+ }
+ }
+ char* copy = Alloc<char>(len + 1); // +1 for '\0'
+ strncpy(copy, str, len);
+ copy[len] = '\0';
+ return copy;
+}
+
+
char* Zone::ConcatStrings(const char* a, const char* b, char join) {
intptr_t a_len = (a == NULL) ? 0 : strlen(a);
const intptr_t b_len = strlen(b) + 1; // '\0'-terminated.
diff --git a/runtime/vm/zone.h b/runtime/vm/zone.h
index dc7b25c..d8ecef5 100644
--- a/runtime/vm/zone.h
+++ b/runtime/vm/zone.h
@@ -45,6 +45,10 @@
// Make a copy of the string in the zone allocated area.
char* MakeCopyOfString(const char* str);
+ // Make a copy of the first n characters of a string in the zone
+ // allocated area.
+ char* MakeCopyOfStringN(const char* str, intptr_t len);
+
// Concatenate strings |a| and |b|. |a| may be NULL. If |a| is not NULL,
// |join| will be inserted between |a| and |b|.
char* ConcatStrings(const char* a, const char* b, char join = ',');
diff --git a/sdk/bin/dart.bat b/sdk/bin/dart.bat
index 9458999..a6a24de 100644
--- a/sdk/bin/dart.bat
+++ b/sdk/bin/dart.bat
@@ -13,4 +13,4 @@
set arguments=%*
-"%SCRIPTPATH%\..\..\build\%DART_CONFIGURATION%\dart.exe" %arguments%
+"%SCRIPTPATH%\..\..\out\%DART_CONFIGURATION%\dart.exe" %arguments%
diff --git a/sdk/bin/dart2js.bat b/sdk/bin/dart2js.bat
index d1a4095..2869680 100644
--- a/sdk/bin/dart2js.bat
+++ b/sdk/bin/dart2js.bat
@@ -42,7 +42,7 @@
rem DART_CONFIGURATION defaults to ReleaseX64
if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
-set BUILD_DIR=%DART_ROOT%\build\%DART_CONFIGURATION%
+set BUILD_DIR=%DART_ROOT%\out\%DART_CONFIGURATION%
set PACKAGE_ROOT=%BUILD_DIR%\packages
diff --git a/sdk/bin/dartanalyzer.bat b/sdk/bin/dartanalyzer.bat
index 0f33752..8130d98 100644
--- a/sdk/bin/dartanalyzer.bat
+++ b/sdk/bin/dartanalyzer.bat
@@ -43,7 +43,7 @@
rem DART_CONFIGURATION defaults to ReleaseX64
if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
-set BUILD_DIR=%DART_ROOT%\build\%DART_CONFIGURATION%
+set BUILD_DIR=%DART_ROOT%\out\%DART_CONFIGURATION%
set PACKAGE_ROOT=%BUILD_DIR%\packages
@@ -57,7 +57,7 @@
rem canonical path. Output with a link looks something like this
rem
rem 01/03/2013 10:11 PM <JUNCTION> abc def
-rem [c:\dart_bleeding\dart-repo.9\dart\build\ReleaseIA32\dart-sdk]
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
rem
rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
rem surrounded by right angle bracket and left square bracket. Once we get
diff --git a/sdk/bin/dartanalyzer_sdk.bat b/sdk/bin/dartanalyzer_sdk.bat
index bca4afb..5fe4ae5 100644
--- a/sdk/bin/dartanalyzer_sdk.bat
+++ b/sdk/bin/dartanalyzer_sdk.bat
@@ -32,7 +32,7 @@
rem canonical path. Output with a link looks something like this
rem
rem 01/03/2013 10:11 PM <JUNCTION> abc def
-rem [c:\dart_bleeding\dart-repo.9\dart\build\ReleaseIA32\dart-sdk]
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
rem
rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
rem surrounded by right angle bracket and left square bracket. Once we get
diff --git a/sdk/bin/dartdevc.bat b/sdk/bin/dartdevc.bat
index 4e02005..f42c660 100644
--- a/sdk/bin/dartdevc.bat
+++ b/sdk/bin/dartdevc.bat
@@ -39,7 +39,7 @@
rem DART_CONFIGURATION defaults to ReleaseX64
if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
-set BUILD_DIR=%DART_ROOT%\build\%DART_CONFIGURATION%
+set BUILD_DIR=%DART_ROOT%\out\%DART_CONFIGURATION%
set PACKAGE_ROOT=%BUILD_DIR%\packages
@@ -53,7 +53,7 @@
rem canonical path. Output with a link looks something like this
rem
rem 01/03/2013 10:11 PM <JUNCTION> abc def
-rem [c:\dart_bleeding\dart-repo.9\dart\build\ReleaseIA32\dart-sdk]
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
rem
rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
rem surrounded by right angle bracket and left square bracket. Once we get
diff --git a/sdk/bin/dartdevc_sdk.bat b/sdk/bin/dartdevc_sdk.bat
index 72c2069..5dbf707 100644
--- a/sdk/bin/dartdevc_sdk.bat
+++ b/sdk/bin/dartdevc_sdk.bat
@@ -32,7 +32,7 @@
rem canonical path. Output with a link looks something like this
rem
rem 01/03/2013 10:11 PM <JUNCTION> abc def
-rem [c:\dart_bleeding\dart-repo.9\dart\build\ReleaseIA32\dart-sdk]
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
rem
rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
rem surrounded by right angle bracket and left square bracket. Once we get
diff --git a/sdk/bin/dartdoc.bat b/sdk/bin/dartdoc.bat
index 880ae55..b519129 100644
--- a/sdk/bin/dartdoc.bat
+++ b/sdk/bin/dartdoc.bat
@@ -24,7 +24,7 @@
rem canonical path. Output with a link looks something like this
rem
rem 01/03/2013 10:11 PM <JUNCTION> abc def
-rem [c:\dart_bleeding\dart-repo.9\dart\build\ReleaseIA32\dart-sdk]
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
rem
rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
rem surrounded by right angle bracket and left square bracket. Once we get
diff --git a/sdk/bin/dartfmt.bat b/sdk/bin/dartfmt.bat
index f063221..c4ac9aa 100644
--- a/sdk/bin/dartfmt.bat
+++ b/sdk/bin/dartfmt.bat
@@ -30,7 +30,7 @@
rem DART_CONFIGURATION defaults to ReleaseX64
if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
-set BUILD_DIR=%DART_ROOT%\build\%DART_CONFIGURATION%
+set BUILD_DIR=%DART_ROOT%\out\%DART_CONFIGURATION%
set PACKAGE_ROOT=%BUILD_DIR%\packages
@@ -44,7 +44,7 @@
rem canonical path. Output with a link looks something like this
rem
rem 01/03/2013 10:11 PM <JUNCTION> abc def
-rem [c:\dart_bleeding\dart-repo.9\dart\build\ReleaseIA32\dart-sdk]
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
rem
rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
rem surrounded by right angle bracket and left square bracket. Once we get
diff --git a/sdk/bin/dartfmt_sdk.bat b/sdk/bin/dartfmt_sdk.bat
index 7de72c0..295b977 100644
--- a/sdk/bin/dartfmt_sdk.bat
+++ b/sdk/bin/dartfmt_sdk.bat
@@ -24,7 +24,7 @@
rem canonical path. Output with a link looks something like this
rem
rem 01/03/2013 10:11 PM <JUNCTION> abc def
-rem [c:\dart_bleeding\dart-repo.9\dart\build\ReleaseIA32\dart-sdk]
+rem [c:\dart_bleeding\dart-repo.9\dart\out\ReleaseIA32\dart-sdk]
rem
rem So in the output of 'dir /a:l "targetdir"' we are looking for a filename
rem surrounded by right angle bracket and left square bracket. Once we get
diff --git a/sdk/bin/pub.bat b/sdk/bin/pub.bat
index 2b8f94b..55ff636 100644
--- a/sdk/bin/pub.bat
+++ b/sdk/bin/pub.bat
@@ -30,7 +30,7 @@
rem Use the Dart binary in the built SDK so pub can find the version file next
rem to it.
-set BUILD_DIR=%SDK_DIR%\..\build\ReleaseX64
+set BUILD_DIR=%SDK_DIR%\..\out\ReleaseX64
set PACKAGES_DIR=%BUILD_DIR%\packages
set DART=%BUILD_DIR%\dart-sdk\bin\dart
diff --git a/sdk/lib/_internal/js_runtime/lib/internal_patch.dart b/sdk/lib/_internal/js_runtime/lib/internal_patch.dart
index cb8820c..a0c519f 100644
--- a/sdk/lib/_internal/js_runtime/lib/internal_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/internal_patch.dart
@@ -5,12 +5,23 @@
import 'dart:_js_primitives' show printString;
import 'dart:_js_helper' show patch;
import 'dart:_interceptors' show JSArray;
+import 'dart:_foreign_helper' show JS;
@patch
class Symbol implements core.Symbol {
@patch
const Symbol(String name)
: this._name = name;
+
+ @patch
+ int get hashCode {
+ int hash = JS('int|Null', '#._hashCode', this);
+ if (hash != null) return hash;
+ const arbitraryPrime = 664597;
+ hash = 0x1fffffff & (arbitraryPrime * _name.hashCode);
+ JS('', '#._hashCode = #', this, hash);
+ return hash;
+ }
}
@patch
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart b/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
index a74fb12..c181c6d 100644
--- a/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
@@ -1206,7 +1206,7 @@
if (!_receivePort._isClosed) {
_receivePort._add(msg);
}
- }, 'receive $message');
+ }, 'receive');
}
bool operator ==(var other) => (other is _NativeJsSendPort) &&
diff --git a/sdk/lib/collection/linked_list.dart b/sdk/lib/collection/linked_list.dart
index 481f04d..f1b55bb 100644
--- a/sdk/lib/collection/linked_list.dart
+++ b/sdk/lib/collection/linked_list.dart
@@ -258,13 +258,13 @@
}
/**
- * Return the succeessor of this element in its linked list.
+ * Return the successor of this element in its linked list.
*
* Returns `null` if there is no successor in the linked list, or if this
* entry is not currently in any list.
*/
E get next {
- if (identical(this, _next)) return null;
+ if (_list == null || identical(_list.first, _next)) return null;
return _next;
}
@@ -275,7 +275,7 @@
* entry is not currently in any list.
*/
E get previous {
- if (identical(this, _previous)) return null;
+ if (_list == null || identical(this, _list.first)) return null;
return _previous;
}
diff --git a/sdk/lib/internal/symbol.dart b/sdk/lib/internal/symbol.dart
index 21d976b..64fcdb3 100644
--- a/sdk/lib/internal/symbol.dart
+++ b/sdk/lib/internal/symbol.dart
@@ -112,10 +112,7 @@
bool operator ==(other) => other is Symbol && _name == other._name;
- int get hashCode {
- const arbitraryPrime = 664597;
- return 0x1fffffff & (arbitraryPrime * _name.hashCode);
- }
+ external int get hashCode;
toString() => 'Symbol("$_name")';
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 4e1d8e3..79bfaa5 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -969,7 +969,7 @@
/**
* The requested URI for the request.
*
- * The returend URI is reconstructed by using http-header fields, to access
+ * The returned URI is reconstructed by using http-header fields, to access
* otherwise lost information, e.g. host and scheme.
*
* To reconstruct the scheme, first 'X-Forwarded-Proto' is checked, and then
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index 445f5d5..f125352 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -21,6 +21,16 @@
final RawReceivePort isolateLifecyclePort = new RawReceivePort();
final RawReceivePort scriptLoadPort = new RawReceivePort();
+abstract class IsolateEmbedderData {
+ void cleanup();
+}
+
+// This is for use by the embedder. It is a map from the isolateId to
+// anything implementing IsolateEmbedderData. When an isolate goes away,
+// the cleanup method will be invoked after being removed from the map.
+final Map<int, IsolateEmbedderData> isolateEmbedderData =
+ new Map<int, IsolateEmbedderData>();
+
// These must be kept in sync with the declarations in vm/json_stream.h.
const kInvalidParams = -32602;
const kInternalError = -32603;
@@ -124,6 +134,10 @@
break;
case Constants.ISOLATE_SHUTDOWN_MESSAGE_ID:
runningIsolates.isolateShutdown(portId, sp);
+ IsolateEmbedderData ied = isolateEmbedderData.remove(portId);
+ if (ied != null) {
+ ied.cleanup();
+ }
break;
}
}
diff --git a/site/try/poi/poi.dart b/site/try/poi/poi.dart
index f40705a..cb04b8d 100644
--- a/site/try/poi/poi.dart
+++ b/site/try/poi/poi.dart
@@ -455,7 +455,7 @@
int position) {
bool isFullCompile = cachedCompiler != newCompiler;
cachedCompiler = newCompiler;
- if (poiTask == null) {
+ if (poiTask == null || poiTask.compiler != cachedCompiler) {
poiTask = new PoiTask(cachedCompiler);
cachedCompiler.tasks.add(poiTask);
}
@@ -565,7 +565,8 @@
}
class PoiTask extends CompilerTask {
- PoiTask(Compiler compiler) : super(compiler.measurer);
+ final Compiler compiler;
+ PoiTask(Compiler compiler) : compiler = compiler, super(compiler.measurer);
String get name => 'POI';
}
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index aa0daa9..bcdc45e 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -21,18 +21,6 @@
Language/Expressions/Constants/exception_t01: fail, OK
Language/Expressions/Constants/exception_t02: fail, OK
-# co19 issue #543: invocation of a non-function
-Language/Expressions/Function_Invocation/Function_Expression_Invocation/static_type_t02: fail, OK
-
-# co19 issue #564: URI can be any number adjacent string literals
-Language/Libraries_and_Scripts/URIs/syntax_t14: fail, OK
-Language/Libraries_and_Scripts/URIs/syntax_t15: fail, OK
-
-# co19 issue #615: Expect import missing
-LibTest/collection/LinkedList/LinkedList_A01_t01: Fail, OK
-
-Language/Generics/syntax_t04: StaticWarning # co19 issue #56
-
LibTest/isolate/IsolateStream/any_A01_t01: Fail # co19-roll r706: Please triage this failure.
LibTest/isolate/IsolateStream/asBroadcastStream_A01_t01: Fail # co19-roll r706: Please triage this failure.
LibTest/isolate/IsolateStream/contains_A01_t01: Fail # co19-roll r706: Please triage this failure.
@@ -68,8 +56,6 @@
LibTest/collection/ListQueue/ListQueue_class_A01_t01: Fail, OK
LibTest/collection/Queue/Queue_class_A01_t01: Fail, OK
-
-Language/Expressions/Method_Invocation/Cascaded_Invocations/syntax_t19: MissingStaticWarning
Language/Statements/Switch/last_statement_t03: MissingStaticWarning
Language/Statements/Assert/type_t04: MissingStaticWarning
@@ -83,7 +69,6 @@
Language/Expressions/Function_Invocation/Unqualified_Invocation/invocation_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
Language/Expressions/Function_Invocation/Unqualified_Invocation/invocation_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/Classes/Superinterfaces/no_member_t05: StaticWarning # co19-roll r667: Please triage this failure
LibTest/convert/JsonEncoder/JsonEncoder_A01_t01: StaticWarning # co19-roll r667: Please triage this failure
# co19 issue 656
@@ -100,9 +85,6 @@
Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t03: StaticWarning # co19-roll r706: Please triage this failure.
Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t04: StaticWarning # co19-roll r706: Please triage this failure.
Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t05: StaticWarning # co19-roll r706: Please triage this failure.
-Language/Libraries_and_Scripts/Parts/compilation_t04: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/Libraries_and_Scripts/Parts/static_warning_t01: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/Libraries_and_Scripts/Scripts/syntax_t11: CompileTimeError # co19-roll r706: Please triage this failure.
LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
LayoutTests/fast/dom/DOMImplementation/createDocumentType-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: StaticWarning # co19-roll r706: Please triage this failure.
@@ -190,7 +172,6 @@
# co19-roll r738
Language/Classes/Classes/method_definition_t06: MissingStaticWarning # co19-roll r738: Please triage this failure.
LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
LayoutTests/fast/dom/StyleSheet/removed-stylesheet-rule-deleted-parent-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
LayoutTests/fast/dom/TreeWalker/TreeWalker-basic_t01: StaticWarning # co19-roll r738: Please triage this failure.
@@ -215,8 +196,6 @@
LayoutTests/fast/dom/remove-named-attribute-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
LayoutTests/fast/dom/shadow/content-pseudo-element-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
LayoutTests/fast/dom/shadow/content-pseudo-element-relative-selector-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/host-context-pseudo-class-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/host-pseudo-class-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: StaticWarning # co19-roll r738: Please triage this failure.
WebPlatformTest/DOMEvents/approved/Event.bubbles.false_t01: StaticWarning # co19-roll r738: Please triage this failure.
WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: StaticWarning # co19-roll r738: Please triage this failure.
@@ -284,12 +263,6 @@
LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: StaticWarning # co19 issue 703
WebPlatformTest/dom/Node-replaceChild_t01: CompileTimeError # co19-roll r761: Please triage this failure.
WebPlatformTest/html/semantics/forms/the-input-element/email_t02: StaticWarning # co19 issue 701
-Language/Expressions/Instance_Creation/Const/abstract_class_t01: MissingCompileTimeError # Issue 22010
-Language/Expressions/Instance_Creation/Const/abstract_class_t03: MissingCompileTimeError # Issue 22010
-Language/Types/Interface_Types/subtype_t19: StaticWarning # co19 issue 745
-Language/Types/Interface_Types/subtype_t22: StaticWarning # co19 issue 745
-Language/Types/Interface_Types/subtype_t24: StaticWarning # co19 issue 745
-Language/Statements/Assert/type_t07: StaticWarning # Issue 23663
# isProtocolHandlerRegistered and unregisterProtocolHandler don't exist
LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # Please triage this failure.
@@ -302,22 +275,16 @@
LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: StaticWarning # Please triage this failure.
# co19 roll to Sep 29 2015 (3ed795ea02e022ef19c77cf1b6095b7c8f5584d0)
-Language/Classes/Abstract_Instance_Members/invocation_t03: MissingStaticWarning # Please triage this failure.
-Language/Classes/Abstract_Instance_Members/invocation_t04: MissingStaticWarning # Please triage this failure.
Language/Classes/Getters/static_t01: StaticWarning # Please triage this failure.
Language/Classes/Getters/type_object_t01: StaticWarning # Please triage this failure.
Language/Classes/Getters/type_object_t02: StaticWarning # Please triage this failure.
Language/Classes/Instance_Variables/definition_t03: StaticWarning # Please triage this failure.
-Language/Classes/Setters/syntax_t04: StaticWarning # Please triage this failure.
Language/Classes/Setters/type_object_t01: StaticWarning # Please triage this failure.
Language/Classes/Setters/type_object_t02: StaticWarning # Please triage this failure.
Language/Classes/Static_Methods/same_name_method_and_setter_t01: MissingStaticWarning # Please triage this failure.
Language/Classes/Static_Methods/type_object_t01: StaticWarning # Please triage this failure.
Language/Classes/Static_Methods/type_object_t02: StaticWarning # Please triage this failure.
Language/Classes/method_definition_t06: MissingStaticWarning # Please triage this failure.
-Language/Enums/declaration_equivalent_t03: StaticWarning # Please triage this failure.
-Language/Enums/declaration_equivalent_t05: StaticWarning # Please triage this failure.
-Language/Enums/declaration_equivalent_t08: StaticWarning # Please triage this failure.
Language/Expressions/Lookup/Method_Lookup/superclass_t07: StaticWarning # Please triage this failure.
Language/Expressions/Lookup/Method_Lookup/superclass_t08: StaticWarning # Please triage this failure.
Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t01: CompileTimeError # Please triage this failure.
@@ -368,21 +335,116 @@
Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: CompileTimeError # Please triage this failure.
Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t02: CompileTimeError # Please triage this failure.
Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t03: CompileTimeError # Please triage this failure.
-Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t01: StaticWarning # Please triage this failure.
-Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/static_type_t01: StaticWarning # Please triage this failure.
-Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/static_type_t02: StaticWarning # Please triage this failure.
Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/inheritance_t03: StaticWarning # Please triage this failure.
-Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t07: StaticWarning # Please triage this failure.
Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError # Please triage this failure.
Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError # Please triage this failure.
-Language/Libraries_and_Scripts/Imports/namespace_changes_t10: CompileTimeError # Please triage this failure.
-Language/Libraries_and_Scripts/URIs/syntax_t04: CompileTimeError # Please triage this failure.
-Language/Libraries_and_Scripts/URIs/syntax_t05: CompileTimeError # Please triage this failure.
-Language/Libraries_and_Scripts/URIs/syntax_t09: CompileTimeError # Please triage this failure.
-Language/Libraries_and_Scripts/URIs/syntax_t10: CompileTimeError # Please triage this failure.
-Language/Mixins/Mixin_Application/abstract_t01: StaticWarning # Please triage this failure.
-Language/Mixins/Mixin_Application/abstract_t02: StaticWarning # Please triage this failure.
Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # Please triage this failure.
Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # Please triage this failure.
Language/Mixins/Mixin_Application/warning_t01: MissingStaticWarning # Please triage this failure.
Language/Mixins/Mixin_Application/warning_t02: MissingStaticWarning # Please triage this failure.
+
+Language/Classes/Getters/static_getter_t02: CompileTimeError # Issue 24534
+Language/Classes/Setters/name_t08: CompileTimeError # Issue 23777
+Language/Classes/Setters/name_t09: CompileTimeError # Issue 23777
+Language/Classes/Setters/name_t10: CompileTimeError # Issue 23777
+Language/Classes/Setters/name_t11: CompileTimeError # Issue 23777
+Language/Classes/Setters/name_t12: CompileTimeError # Issue 23777
+Language/Classes/Setters/name_t13: CompileTimeError # Issue 23777
+Language/Classes/Setters/name_t14: CompileTimeError # Issue 23777
+Language/Classes/Setters/name_t15: CompileTimeError # Issue 23777
+Language/Enums/syntax_t08: MissingCompileTimeError # Please triage this failure.
+Language/Enums/syntax_t09: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Assignment/super_assignment_static_warning_t03: StaticWarning # Issue 15467
+Language/Expressions/Function_Invocation/Unqualified_Invocation/instance_context_invocation_t03: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Function_Invocation/Unqualified_Invocation/instance_context_invocation_t04: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_identifier_t53: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t54: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t55: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t56: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t57: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t58: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t59: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t60: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t61: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t62: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t63: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t64: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t65: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t66: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t67: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t68: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t17: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t18: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t19: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t21: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t22: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t23: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t24: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t25: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t26: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t27: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t28: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t29: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t30: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t31: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t32: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Identifier_Reference/evaluation_type_parameter_t02: MissingCompileTimeError # Please triage this failure.
+Language/Expressions/Method_Invocation/Ordinary_Invocation/object_method_invocation_t01: MissingCompileTimeError # Issue 25496
+Language/Expressions/Method_Invocation/Ordinary_Invocation/object_method_invocation_t02: MissingCompileTimeError # Issue 25496
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Super_Property_Extraction: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Super_Closurization: CompileTimeError # Issue 23777
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: CompileTimeError # Please triage this failure.
+Language/Mixins/Mixin_Application/static_warning_t01: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/static_warning_t02: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/superinterfaces_t06: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/superinterfaces_t07: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/syntax_t11: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/syntax_t12: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/syntax_t13: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/syntax_t14: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/syntax_t20: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/syntax_t21: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/syntax_t22: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/syntax_t23: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/syntax_t24: CompileTimeError # Issue 26409
+Language/Mixins/Mixin_Application/syntax_t25: CompileTimeError # Issue 26409
+Language/Mixins/declaring_constructor_t05: MissingCompileTimeError # Issue 24767
+Language/Mixins/declaring_constructor_t06: MissingCompileTimeError # Issue 24767
+Language/Statements/Yield_and_Yield_Each/Yield_Each/location_t01: MissingCompileTimeError # Issue 25495
+Language/Statements/Yield_and_Yield_Each/Yield_Each/location_t03: MissingCompileTimeError # Issue 25495
+Language/Statements/Yield_and_Yield_Each/Yield_Each/location_t05: MissingCompileTimeError # Issue 25495
+
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t01: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t02: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t03: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/positional_parameters_t01: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/named_parameters_t01: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/identical_t01: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/identical_t02: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/positional_parameters_t01: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/named_parameters_t01: CompileTimeError # Issue 23777
+Language/Expressions/Identifier_Reference/evaluation_library_or_getter_t05: StaticWarning # Misspelled "@static-waning"
+LibTest/core/Set/IterableBase_A01_t01: StaticWarning # Imports libraries with static warnings
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: StaticWarning # Imports libraries with static warnings
+LibTest/collection/IterableBase/IterableBase_class_A01_t02: StaticWarning # Imports libraries with static warnings
+LibTest/collection/HashSet/HashSet_class_A01_t01: StaticWarning # Imports libraries with static warnings
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t05: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t06: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t07: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t05: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t06: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t07: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t08: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t09: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t05: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t06: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t07: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t08: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t09: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t06: CompileTimeError # Issue 23777
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t07: CompileTimeError # Issue 23777
+Language/Libraries_and_Scripts/Scripts/syntax_t11: Pass, CompileTimeError # Issue 26592
+Language/Libraries_and_Scripts/Parts/compilation_t04: Pass, CompileTimeError # Issue 26592
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index f6e0f6d..4d8a0e7 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -14,35 +14,12 @@
[ $runtime == vm || $runtime != vm ]
# Tests that fail everywhere, including the analyzer.
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: Pass, Fail, OK # co19 issue 18
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: Pass, Fail, OK # co19 issue 18
-Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t03: Pass, Fail, OK # co19 issue 18
-Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t01: Pass, Fail, OK # co19 issue 18
-Language/Classes/Constructors/Constant_Constructors/not_a_constant_in_superclass_t02: Pass, Fail, OK # co19 issue 18
-
-# Super is now allowed in mixins and mixins may now extend a subclass of Object.
-Language/09_Mixins/09_Mixins_A01_t01: Skip # co19 issue 9.
-Language/09_Mixins/09_Mixins_A03_t01: Skip # co19 issue 9.
-
-# No longer correct, y#$ now has a meaning. github.com/dart-lang/co19/issues/2
-Language/12_Expressions/30_Identifier_Reference_A01_t03: Skip
-
LibTest/typed_data/ByteData/buffer_A01_t01: Fail # co19 r736 bug - sent comment.
LibTest/core/RegExp/firstMatch_A01_t01: Fail # co19 issue 742
-# These tests are obsolete and need updating.
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-002_t01: Skip # Issue 19019
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-003_t01: Skip # Issue 19019
-
-# These tests are broken in both Javascript and Dart (co19 folks contacted to fix).
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-004_t01: Skip # Issue 21115
-
[ $compiler != dart2analyzer ]
# Tests that fail on every runtime, but not on the analyzer.
-
-LibTest/async/Future/Future.error_A01_t01: RuntimeError # co19 issue 712
-LibTest/async/Completer/completeError_A02_t01: RuntimeError # co19 issue 712
LibTest/isolate/ReceivePort/asBroadcastStream_A02_t01: Fail # co19 issue 687
LibTest/async/Stream/asBroadcastStream_A02_t01: Fail # co19 issue 687
@@ -52,12 +29,12 @@
Language/Classes/same_name_type_variable_t04: Pass, MissingCompileTimeError, Fail # Issue 14513
Language/Classes/same_name_type_variable_t07: Pass, MissingCompileTimeError, Fail # Issue 14513
-LibTest/math/acos_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/asin_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/atan_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/acos_A01_t01: PASS, FAIL, OK # Issue 26261
+LibTest/math/asin_A01_t01: PASS, FAIL, OK # Issue 26261
+LibTest/math/atan_A01_t01: PASS, FAIL, OK # Issue 26261
-LibTest/math/cos_A01_t01: PASS, FAIL, OK # co19 issue 44
-LibTest/math/tan_A01_t01: PASS, FAIL, OK # co19 issue 44
+LibTest/math/cos_A01_t01: PASS, FAIL, OK # Issue 26261
+LibTest/math/tan_A01_t01: PASS, FAIL, OK # Issue 26261
LibTest/core/Expando/Expando_A03_t01: RuntimeError # Issue 17735
LibTest/core/Expando/Expando_A03_t03: RuntimeError # Issue 17735
@@ -96,10 +73,3 @@
[ $runtime == dartium || $compiler == dart2js ]
LibTest/async/Future/Future.delayed_A01_t02: Pass, Fail # Issue 15524
-
-### CHECKED MODE FAILURES ###
-
-[ $compiler != dart2analyzer && $checked ]
-LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # co19 issue 22
-LibTest/collection/LinkedList/LinkedList_A01_t01: RuntimeError # co19 issue 23
-LibTest/collection/LinkedList/lastWhere_A02_t01: RuntimeError # co19 issue 737
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index d12cbfc..b13b657 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -7,6 +7,7 @@
Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError, OK # co19 issue 258
Language/Classes/Constructors/Generative_Constructors/execution_of_an_initializer_t02: fail # Issue 13363
Language/Classes/Constructors/Generative_Constructors/initializing_formals_execution_t02: fail # Issue 13363
+Language/Classes/Getters/static_getter_t02: CompileTimeError # Issue 24534
Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure
Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure
Language/Classes/Instance_Methods/same_name_setter_t01: fail # Issue 21201
@@ -14,40 +15,99 @@
Language/Classes/Setters/name_t02: CompileTimeError # Issue 5023
Language/Classes/Setters/name_t03: RuntimeError # Issue 5023
Language/Classes/Setters/name_t07: CompileTimeError # Issue 5023
-Language/Classes/Setters/syntax_t04: RuntimeError # Please triage this failure
+Language/Classes/Setters/name_t08: CompileTimeError # Please triage this failure
+Language/Classes/Setters/name_t09: CompileTimeError # Please triage this failure
+Language/Classes/Setters/name_t10: CompileTimeError # Please triage this failure
+Language/Classes/Setters/name_t11: CompileTimeError # Please triage this failure
+Language/Classes/Setters/name_t12: CompileTimeError # Please triage this failure
+Language/Classes/Setters/name_t13: CompileTimeError # Please triage this failure
+Language/Classes/Setters/name_t14: CompileTimeError # Please triage this failure
+Language/Classes/Setters/name_t15: CompileTimeError # Please triage this failure
+Language/Classes/Setters/static_setter_t06: RuntimeError # Please triage this failure
Language/Classes/Setters/type_object_t01: RuntimeError # Please triage this failure
Language/Classes/Setters/type_object_t02: RuntimeError # Please triage this failure
Language/Classes/Static_Methods/same_name_method_and_setter_t01: CompileTimeError # Please triage this failure
Language/Classes/Static_Methods/type_object_t01: RuntimeError # Please triage this failure
Language/Classes/Static_Methods/type_object_t02: RuntimeError # Please triage this failure
-Language/Classes/Superclasses/wrong_superclass_t04: MissingCompileTimeError # Please triage this failure
-Language/Classes/Superclasses/wrong_superclass_t07: MissingCompileTimeError # Please triage this failure
-Language/Classes/Superclasses/wrong_superclass_t08: MissingCompileTimeError # Please triage this failure
-Language/Classes/Superinterfaces/wrong_type_t04: MissingCompileTimeError # Please triage this failure
-Language/Classes/Superinterfaces/wrong_type_t05: MissingCompileTimeError # Please triage this failure
+Language/Classes/definition_t23: CompileTimeError # Please triage this failure
Language/Classes/same_name_type_variable_t02: Fail # Missing CT error on member with same name a type parameter
Language/Classes/same_name_type_variable_t03: Fail # Missing CT error on member with same name a type parameter
Language/Classes/same_name_type_variable_t05: Fail # Missing CT error on member with same name a type parameter
Language/Classes/same_name_type_variable_t06: Fail # Missing CT error on member with same name a type parameter
Language/Classes/same_name_type_variable_t08: Fail # Missing CT error on member with same name a type parameter
Language/Classes/same_name_type_variable_t09: Fail # Missing CT error on member with same name a type parameter
-Language/Enums/restrictions_t01: MissingCompileTimeError # Please triage this failure
-Language/Enums/restrictions_t02: MissingCompileTimeError # Please triage this failure
-Language/Enums/restrictions_t05: MissingCompileTimeError # Please triage this failure
-Language/Enums/restrictions_t06: MissingCompileTimeError # Please triage this failure
-Language/Enums/restrictions_t07: MissingCompileTimeError # Please triage this failure
-Language/Enums/syntax_t02: MissingCompileTimeError # Please triage this failure
Language/Errors_and_Warnings/compile_error_t06: MissingCompileTimeError # Please triage this failure
Language/Errors_and_Warnings/compile_error_t07: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Assignment/super_assignment_failed_t05: RuntimeError # Issue 25671
+Language/Expressions/Assignment/super_assignment_value_t02: RuntimeError # Please triage this failure
+Language/Expressions/Await_Expressions/evaluation_throws_t03: RuntimeError # Please triage this failure
+Language/Expressions/Await_Expressions/evaluation_throws_t04: RuntimeError # Please triage this failure
+Language/Expressions/Await_Expressions/evaluation_throws_t06: RuntimeError # Please triage this failure
+Language/Expressions/Await_Expressions/evaluation_throws_t07: RuntimeError # Please triage this failure
+Language/Expressions/Constants/identifier_denotes_a_constant_t06: MissingCompileTimeError # Issue 26580
+Language/Expressions/Constants/identifier_denotes_a_constant_t07: MissingCompileTimeError # Issue 26580
+Language/Expressions/Function_Invocation/async_generator_invokation_t08: Timeout, Skip # Issue 25967
+Language/Expressions/Function_Invocation/async_generator_invokation_t10: Timeout, Skip # Issue 25967
+Language/Expressions/Identifier_Reference/built_in_identifier_t35: MissingCompileTimeError # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t36: MissingCompileTimeError # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t37: MissingCompileTimeError # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t53: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t54: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t55: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t56: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t57: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t58: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t59: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t60: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t61: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t62: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t63: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t64: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t65: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t66: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t67: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t68: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t14: MissingCompileTimeError # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t15: MissingCompileTimeError # Issue 26581
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t19: MissingCompileTimeError # Issue 25732
Language/Expressions/Identifier_Reference/syntax_built_in_t01: fail # Issue 21154
+Language/Expressions/Instance_Creation/Const/abstract_class_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Instance_Creation/Const/abstract_class_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Instance_Creation/New/evaluation_t19: RuntimeError # Please triage this failure
+Language/Expressions/Instance_Creation/New/evaluation_t20: RuntimeError # Please triage this failure
+Language/Expressions/Maps/key_value_equals_operator_t02: CompileTimeError # Please triage this failure
Language/Expressions/Maps/static_type_dynamic_t01: CompileTimeError # Maybe ok. Issue 17207
+Language/Expressions/Method_Invocation/Ordinary_Invocation/object_method_invocation_t01: MissingCompileTimeError # Issue 25496
+Language/Expressions/Method_Invocation/Ordinary_Invocation/object_method_invocation_t02: MissingCompileTimeError # Issue 25496
Language/Expressions/Numbers/syntax_t06: fail # Issue 21098
Language/Expressions/Numbers/syntax_t09: fail # Issue 21098
Language/Expressions/Object_Identity/Object_Identity/constant_objects_t01: fail # Issue 11551, also related to issue 563, 18738
Language/Expressions/Object_Identity/Object_Identity/double_t02: fail # Issue 11551, also related to issue 563, 18738
+Language/Expressions/Object_Identity/double_t03: RuntimeError # Please triage this failure
Language/Expressions/Object_Identity/constant_objects_t01: RuntimeError # Please triage this failure
Language/Expressions/Object_Identity/double_t02: RuntimeError # Please triage this failure
Language/Expressions/Object_Identity/object_t02: RuntimeError # Issue 1533 (int/double related)
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t01: CompileTimeError # Issue 24607
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t02: CompileTimeError # Issue 24607
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/named_parameters_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/positional_parameters_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/closurization_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/closurization_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/closurization_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/deferred_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/malbounded_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/malbounded_type_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/malformed_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/malformed_type_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/no_such_method_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/no_such_method_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/not_class_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/not_class_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/not_class_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/static_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/static_type_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Extraction/static_type_t03: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t01: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t02: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/expression_evaluation_t03: CompileTimeError # Please triage this failure
@@ -55,10 +115,25 @@
Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t02: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t03: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t05: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t06: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t07: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t08: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/getter_lookup_t09: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t01: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t02: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t03: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t05: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t06: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/method_lookup_t07: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t05: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t06: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t07: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t08: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/setter_lookup_t09: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t06: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Closurization/static_type_t07: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t01: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t02: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/General_Closurization/no_accessible_member_t03: CompileTimeError # Please triage this failure
@@ -86,24 +161,83 @@
Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/expression_evaluation_t07: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/no_such_method_t01: RuntimeError # Please triage this failure
+
+Language/Expressions/Property_Extraction/General_Super_Property_Extraction: CompileTimeError # Issue 26287
+
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/identical_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/identical_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/closurization_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/closurization_t02: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/Named_Constructor_Extraction/deferred_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malbounded_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malbounded_type_t02: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t01: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/Named_Constructor_Extraction/malformed_type_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/named_parameters_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/no_such_method_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/no_such_method_t02: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t02: CompileTimeError # Please triage this failure
Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/static_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/static_type_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/static_type_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Extraction/static_type_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/positional_parameters_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t05: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t06: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t07: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t08: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_closurization_named_params_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_closurization_named_params_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_closurization_positional_params_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_closurization_positional_params_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_identical_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_identical_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_identical_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_list_access_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_list_assignment_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t05: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t06: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t07: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t08: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t09: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t10: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t11: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t12: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t13: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t14: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t15: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t16: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_t17: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/operator_closurization_unary_bitwise_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t03: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t04: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t05: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t06: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t07: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/setter_closurization_t08: CompileTimeError # Please triage this failure
+
+Language/Expressions/Property_Extraction/Super_Closurization: CompileTimeError # Issue 26287
+
Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t01: RuntimeError # Please triage this failure
Language/Functions/External_Functions/not_connected_to_a_body_t01: CompileTimeError, OK # Issue 5021
Language/Generics/syntax_t17: fail # Issue 21203
Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError # Please triage this failure
Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError # Please triage this failure
-Language/Libraries_and_Scripts/Imports/namespace_changes_t10: CompileTimeError # Please triage this failure
-Language/Libraries_and_Scripts/URIs/syntax_t04: CompileTimeError # Please triage this failure
-Language/Libraries_and_Scripts/URIs/syntax_t05: CompileTimeError # Please triage this failure
-Language/Libraries_and_Scripts/URIs/syntax_t09: CompileTimeError # Please triage this failure
-Language/Libraries_and_Scripts/URIs/syntax_t10: CompileTimeError # Please triage this failure
-Language/Libraries_and_Scripts/URIs/syntax_t14: CompileTimeError # Please triage this failure
-Language/Libraries_and_Scripts/URIs/syntax_t15: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t01: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: CompileTimeError # Please triage this failure
+Language/Libraries_and_Scripts/Scripts/top_level_main_t05: RuntimeError # Please triage this failure
Language/Metadata/before_export_t01: RuntimeError # Please triage this failure
Language/Metadata/before_import_t01: RuntimeError # Please triage this failure
Language/Metadata/before_library_t01: RuntimeError # Please triage this failure
@@ -111,22 +245,40 @@
Language/Metadata/before_type_param_t01: CompileTimeError # Please triage this failure
Language/Metadata/before_typedef_t01: RuntimeError # Please triage this failure
Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure
-Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # Please triage this failure
-Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # Please triage this failure
-Language/Mixins/Mixin_Application/wrong_mixin_type_t01: MissingCompileTimeError # Please triage this failure
-Language/Mixins/Mixin_Application/wrong_mixin_type_t02: MissingCompileTimeError # Please triage this failure
-Language/Mixins/Mixin_Application/wrong_mixin_type_t03: MissingCompileTimeError # Please triage this failure
-Language/Mixins/Mixin_Application/wrong_mixin_type_t04: MissingCompileTimeError # Please triage this failure
-Language/Mixins/Mixin_Application/wrong_type_t01: MissingCompileTimeError # Please triage this failure
-Language/Mixins/Mixin_Application/wrong_type_t02: MissingCompileTimeError # Please triage this failure
-Language/Mixins/declaring_constructor_t01: MissingCompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/static_warning_t01: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/static_warning_t02: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/superinterfaces_t06: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/superinterfaces_t07: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/syntax_t11: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/syntax_t12: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/syntax_t13: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/syntax_t14: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/syntax_t20: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/syntax_t21: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/syntax_t22: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/syntax_t23: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/syntax_t24: CompileTimeError # Please triage this failure
+Language/Mixins/Mixin_Application/syntax_t25: CompileTimeError # Please triage this failure
+Language/Mixins/declaring_constructor_t05: MissingCompileTimeError # Issue 24767
+Language/Mixins/declaring_constructor_t06: MissingCompileTimeError # Issue 24767
Language/Mixins/deferred_t01: MissingCompileTimeError # Please triage this failure
Language/Mixins/not_object_superclass_t01: MissingCompileTimeError # Please triage this failure
Language/Mixins/reference_to_super_t01: MissingCompileTimeError # Please triage this failure
Language/Reference/Lexical_Rules/Reserved_Words/whitespace_t04: MissingCompileTimeError # Checks that other Unicode whitespaces are not allowed: check NO-BREAK SPACE (U+00A0)
Language/Reference/Lexical_Rules/whitespace_t06: MissingCompileTimeError # Checks that Unicode whitespaces other than WHITESPACE are not permitted in the source code. Checks symbol U+00a0.
+Language/Reference/Operator_Precedence/precedence_12_Shift_t02: RuntimeError # Issue 26573
+Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t04: RuntimeError # Issue 26573
+Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t08: RuntimeError # Please triage this failure
+Language/Statements/Continue/async_loops_t09: Crash # Please triage this failure
Language/Statements/Local_Function_Declaration/reference_before_declaration_t01: MissingCompileTimeError # Issue 21050
Language/Statements/Local_Function_Declaration/reference_before_declaration_t03: MissingCompileTimeError # Issue 21050
+Language/Statements/Try/catch_scope_t01: RuntimeError # Please triage this failure
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t02: RuntimeError # Please triage this failure
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_sync_t05: RuntimeError # Issue 25662,25634
+Language/Statements/Yield_and_Yield_Each/Yield_Each/location_t01: MissingCompileTimeError # Issue 25495
+Language/Statements/Yield_and_Yield_Each/Yield_Each/location_t03: MissingCompileTimeError # Issue 25495
+Language/Statements/Yield_and_Yield_Each/Yield_Each/location_t05: MissingCompileTimeError # Issue 25495
+Language/Types/Dynamic_Type_System/deferred_type_error_t01: RuntimeError # Please triage this failure
Language/Types/Interface_Types/subtype_t27: Skip # Times out or crashes. Issue 21174
Language/Types/Interface_Types/subtype_t30: fail # Issue 14654
Language/Types/Interface_Types/subtype_t28: Pass, Fail, Crash # Stack overflow. Issue 25282
@@ -143,7 +295,13 @@
LibTest/convert/JsonDecoder/fuse_A01_t01: RuntimeError # co19-roll r667: Please triage this failure
LibTest/convert/JsonEncoder/convert_A01_t01: RuntimeError # co19-roll r667: Please triage this failure
LibTest/core/DateTime/DateTime_A01_t03: fail # co19-roll r546: Please triage this failure
-LibTest/core/DateTime/parse_A03_t01: fail # co19-roll r546: Please triage this failure
+LibTest/core/DateTime/DateTime.fromMicrosecondsSinceEpoch_A01_t01: RuntimeError # Please triage this failure
+LibTest/core/DateTime/microsecond_A01_t01: RuntimeError # Please triage this failure
+LibTest/core/DateTime/microsecondsSinceEpoch_A01_t01: RuntimeError # Please triage this failure
+LibTest/core/DateTime/parse_A01_t03: RuntimeError # Please triage this failure
+LibTest/core/DateTime/to8601String_A01_t01: RuntimeError # Please triage this failure
+LibTest/core/DateTime/to8601String_A01_t02: RuntimeError # Please triage this failure
+LibTest/core/DateTime/to8601String_A01_t03: RuntimeError # Please triage this failure
LibTest/core/Duration/operator_div_A01_t01: fail # co19-roll r546: Please triage this failure
LibTest/core/List/List_class_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
LibTest/core/List/getRange_A03_t01: RuntimeError, OK # Tests that fail because they use the legacy try-catch syntax. co19 issue 184.
@@ -286,30 +444,54 @@
LibTest/typed_data/Uint8List/Uint8List.view_A05_t02: RuntimeError # co19-roll r559: Please triage this failure
LibTest/typed_data/Uint8List/Uint8List.view_A05_t03: RuntimeError # co19-roll r559: Please triage this failure
LibTest/typed_data/Uint8List/Uint8List_A02_t01: fail # co19-roll r576: Please triage this failure
-Utils/tests/Expect/identical_A01_t01: fail # co19-roll r546: Please triage this
-WebPlatformTest/DOMEvents/approved/domnodeinserted_t01: Skip # Issue 51
+Utils/tests/Expect/identical_A01_t01: fail # co19-roll r546: Please triage this failure
WebPlatformTest/Utils/test/testFail_t01: RuntimeError # co19-roll r722: Please triage this failure.
WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: CompileTimeError # co19-roll r722: Please triage this failure.
WebPlatformTest/dom/nodes/Document-createElement_t01: CompileTimeError # co19-roll r722: Please triage this failure.
WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: CompileTimeError # co19-roll r722: Please triage this failure.
WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Pass, Slow
+Language/Expressions/Function_Invocation/async_invokation_t04: RuntimeError, Pass # co19 issue 57
[ $compiler == dart2js && $checked ]
-Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure
Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure
Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure
Language/Errors_and_Warnings/static_warning_t04: RuntimeError # Please triage this failure
Language/Errors_and_Warnings/static_warning_t05: RuntimeError # Please triage this failure
Language/Errors_and_Warnings/static_warning_t06: RuntimeError # Please triage this failure
+Language/Expressions/Assignment/super_assignment_dynamic_error_t01: RuntimeError # Please triage this failure
+Language/Expressions/Function_Expressions/static_type_dynamic_async_t03: RuntimeError # Please triage this failure
+Language/Expressions/Function_Expressions/static_type_dynamic_asyncs_t03: RuntimeError # Please triage this failure
+Language/Expressions/Function_Expressions/static_type_dynamic_syncs_t03: RuntimeError # Please triage this failure
+Language/Expressions/Function_Expressions/static_type_form_3_async_t03: RuntimeError # Please triage this failure
+Language/Expressions/Function_Expressions/static_type_form_3_asyncs_t03: RuntimeError # Please triage this failure
+Language/Expressions/Function_Expressions/static_type_form_3_syncs_t03: RuntimeError # Please triage this failure
+Language/Expressions/If_null_Expressions/static_type_t01: RuntimeError # Please triage this failure
+Language/Expressions/If_null_Expressions/static_type_t02: RuntimeError # Please triage this failure
+Language/Expressions/Property_Extraction/General_Super_Property_Extraction/getter_lookup_t02: CompileTimeError # Please triage this failure
+Language/Expressions/Property_Extraction/Super_Closurization/setter_closurization_t09: Timeout, Skip # Please triage this failure
+Language/Functions/async_return_type_t01: RuntimeError # Please triage this failure
+Language/Functions/generator_return_type_t01: RuntimeError # Please triage this failure
+Language/Functions/generator_return_type_t02: RuntimeError # Please triage this failure
+Language/Libraries_and_Scripts/Imports/deferred_import_t02: RuntimeError # co19 issue 60
Language/Statements/Switch/execution_t01: Fail # Missing type check in switch expression
Language/Statements/Switch/type_t01: RuntimeError # Issue 16089
+Language/Statements/Return/runtime_type_t04: RuntimeError # Issue 26584
Language/Types/Static_Types/malformed_type_t01: RuntimeError # Issue 21089
Language/Types/Dynamic_Type_System/malbounded_type_error_t01: RuntimeError # Issue 21088
Language/Types/Parameterized_Types/malbounded_t06: RuntimeError # Issue 21088
+#LibTest/async/Future/whenComplete_A01_t01: Timeout, Skip # Please triage this failure
+#LibTest/async/Stream/Stream.eventTransformed_A01_t01: Timeout, Skip # Please triage this failure
+#LibTest/async/Stream/join_A02_t01: Timeout, Skip # Please triage this failure
+#LibTest/async/Stream/last_A02_t01: Timeout, Skip # Please triage this failure
+#LibTest/async/Stream/listen_A03_t01: Timeout, Skip # Please triage this failure
LibTest/core/Map/Map_class_A01_t04: Slow, Pass
LibTest/core/Uri/Uri_A06_t03: Slow, Pass
LibTest/math/Point/operator_mult_A02_t01: RuntimeError # Issue 1533
+[ $compiler == dart2js && $checked != true ]
+Language/Expressions/Property_Extraction/General_Super_Property_Extraction/getter_lookup_t02: Timeout, Skip # Please triage this failure
+Language/Expressions/Property_Extraction/Super_Closurization/setter_closurization_t09: CompileTimeError # Please triage this failure
+
[ $compiler == dart2js && $minified ]
LibTest/typed_data/Float32List/runtimeType_A01_t01: fail # co19-roll r559: Please triage this failure
LibTest/typed_data/Float32x4List/runtimeType_A01_t01: fail # co19-roll r559: Please triage this failure
@@ -328,6 +510,24 @@
LibTest/core/List/List_class_A01_t01: Pass, Timeout
[ $compiler == dart2js && $runtime == jsshell ]
+Language/Expressions/Await_Expressions/execution_t01: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Expressions/Await_Expressions/execution_t02: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Expressions/Await_Expressions/execution_t03: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Expressions/Await_Expressions/execution_t04: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Expressions/Await_Expressions/execution_t05: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Expressions/Await_Expressions/execution_t06: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/For/Asynchronous_For_in/execution_t04: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t02: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t03: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t04: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t05: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t06: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t07: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t08: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09: RuntimeError # Issue 7728, timer not supported in jsshell
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t10: RuntimeError # Issue 7728, timer not supported in jsshell
LibTest/async/Future/Future.delayed_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
LibTest/async/Future/Future.delayed_A03_t01: fail # Issue 7728, timer not supported in jsshell
LibTest/async/Future/wait_A01_t07: RuntimeError # Issue 7728, timer not supported in jsshell
@@ -362,7 +562,10 @@
LibTest/core/Stopwatch/start_A01_t03: RuntimeError # Issue 7728, timer not supported in jsshell
LibTest/core/Stopwatch/stop_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
LibTest/core/Uri/Uri_A06_t03: Pass, Slow
+LibTest/isolate/RawReceivePort/close_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: RuntimeError # Issue 7728, timer not supported in jsshell
LibTest/isolate/ReceivePort/asBroadcastStream_A04_t03: RuntimeError # Issue 7728, timer not supported in jsshell
+LibTest/isolate/ReceivePort/close_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
LibTest/typed_data/Float32List/Float32List.view_A06_t01: fail # co19-roll r587: Please triage this failure
LibTest/typed_data/Float32List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: fail # co19-roll r587: Please triage this failure
@@ -445,16 +648,9 @@
# Everything below this point is associated with co19 Issue 747
#
LayoutTests/fast/dynamic/insertAdjacentHTML_t01: Pass, RuntimeError
-LayoutTests/fast/layers/zindex-hit-test_t01: RuntimeError
-LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError
LayoutTests/fast/multicol/balance-unbreakable_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError
-LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError
-LayoutTests/fast/multicol/inherit-column-values_t01: RuntimeError
-LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError
LayoutTests/fast/multicol/newmulticol/balance_t01: Pass, RuntimeError
LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/newmulticol/balance-maxheight_t02: RuntimeError
LayoutTests/fast/multicol/newmulticol/balance_t02: Pass, RuntimeError
LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError
LayoutTests/fast/multicol/newmulticol/balance_t05: Pass, RuntimeError
@@ -466,96 +662,48 @@
LayoutTests/fast/multicol/newmulticol/balance-images_t01: Pass, RuntimeError
LayoutTests/fast/multicol/column-width-zero_t01: Pass, RuntimeError
LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/vertical-lr/break-properties_t01: RuntimeError
LayoutTests/fast/multicol/orphans-relayout_t01: Pass, RuntimeError
-LayoutTests/fast/multicol/zeroColumnCount_t01: RuntimeError
LayoutTests/fast/media/mq-parsing_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue.
LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Passes on Safari, Issue 23475
LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # False pass on Safari
-LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError
-LayoutTests/fast/lists/item-not-in-list-line-wrapping_t01: RuntimeError
LayoutTests/fast/lists/list-style-position-inside_t01: Pass, RuntimeError
-LayoutTests/fast/innerHTML/innerHTML-special-elements_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-inline-parent_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor_t01: RuntimeError
-LayoutTests/fast/inline/inline-relative-offset-boundingbox_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent_t01: RuntimeError
-LayoutTests/fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent_t01: RuntimeError
-LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError
-LayoutTests/fast/inline/reattach-inlines-in-anonymous-blocks-with-out-of-flow-siblings_t01: RuntimeError
LayoutTests/fast/overflow/overflow-rtl-vertical-origin_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue.
LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass # False pass
LayoutTests/fast/table/col-width-span-expand_t01: Skip
-LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError
LayoutTests/fast/text/font-fallback-synthetic-italics_t01: Pass, RuntimeError
-LayoutTests/fast/text/international/listbox-width-rtl_t01: RuntimeError
LayoutTests/fast/text/glyph-reordering_t01: Pass, RuntimeError # This is a false pass. The font gets sanitized, so whether it works or not probably depends on default sizes.
LayoutTests/fast/text/international/rtl-text-wrapping_t01: Pass # This is a false pass. All the content gets sanitized, so there's nothing to assert fail on. If the code did anything it would fail.
LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: Pass, RuntimeError
-LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError
-LayoutTests/fast/text/line-breaks-after-closing-punctuations_t01: RuntimeError
-LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError
-LayoutTests/fast/text/line-breaks-after-ideographic-comma-or-full-stop_t01: RuntimeError
LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, Fail
-LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError
LayoutTests/fast/text/font-fallback-synthetic-italics_t01: RuntimeError
LayoutTests/fast/text/font-ligatures-linebreak_t01: Skip
LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip
LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError
-LayoutTests/fast/text/pre-wrap-trailing-tab_t01: RuntimeError
-LayoutTests/fast/url/trivial_t01: RuntimeError
-LayoutTests/fast/url/trivial-segments_t01: RuntimeError
-LayoutTests/fast/url/scheme_t01: RuntimeError
-LayoutTests/fast/url/host-lowercase-per-scheme_t01: RuntimeError
-LayoutTests/fast/url/safari-extension_t01: RuntimeError
-LayoutTests/fast/url/port_t01: RuntimeError
-LayoutTests/fast/url/mailto_t01: RuntimeError
-LayoutTests/fast/url/path-url_t01: RuntimeError
-LayoutTests/fast/url/anchor_t01: RuntimeError
-LayoutTests/fast/writing-mode/auto-margins-across-boundaries_t01: RuntimeError
-LayoutTests/fast/writing-mode/display-mutation_t01: RuntimeError
-LayoutTests/fast/writing-mode/percentage-padding_t01: RuntimeError
-LayoutTests/fast/writing-mode/relative-positioning-percentages_t01: RuntimeError
-LayoutTests/fast/writing-mode/block-formatting-context_t01: RuntimeError
LayoutTests/fast/writing-mode/percentage-margins-absolute-replaced_t01: Pass, RuntimeError
LayoutTests/fast/writing-mode/positionForPoint_t01: Pass, RuntimeError
LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip
LayoutTests/fast/html/adjacent-html-context-element_t01:RuntimeError
LayoutTests/fast/dom/HTMLElement/insertAdjacentHTML-errors_t01: RuntimeError
-LayoutTests/fast/transforms/transform-inside-overflow-scroll_t01: RuntimeError
LayoutTests/fast/transforms/transform-hit-test-flipped_t01: Pass, RuntimeError # Passes on Firefox, but is clearly not testing what it's trying to test.
LayoutTests/fast/transforms/scrollIntoView-transformed_t01: Pass, RuntimeError # False passes on Firefox.
LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError, Pass # Erratic, but only passes because divs have been entirely removed.
-LayoutTests/fast/transforms/topmost-becomes-bottomost-for-scrolling_t01: RuntimeError
LayoutTests/fast/table/anonymous-table-section-removed_t01: Skip
LayoutTests/fast/table/hittest-tablecell-bottom-edge_t01: Skip
LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: Skip
LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError
-LayoutTests/fast/table/table-sections-border-spacing_t01: RuntimeError
-LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError
-LayoutTests/fast/table/resize-table-row_t01: RuntimeError
LayoutTests/fast/table/min-max-width-preferred-size_t01: Pass, RuntimeError
LayoutTests/fast/table/margins-flipped-text-direction_t01: Pass, RuntimeError
LayoutTests/fast/table/html-table-width-max-width-constrained_t01: Pass, RuntimeError
LayoutTests/fast/table/fixed-table-layout-width-change_t01: Pass, RuntimeError # False passes on Firefox
-LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError
LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Fails on Safari, false pass on others
-LayoutTests/fast/selectors/style-sharing-last-child_t01: RuntimeError
-LayoutTests/fast/selectors/specificity-overflow_t01: RuntimeError
LayoutTests/fast/ruby/parse-rp_t01: Pass, RuntimeError
-LayoutTests/fast/replaced/table-replaced-element_t01: RuntimeError
-LayoutTests/fast/replaced/table-percent-height-text-controls_t01: RuntimeError
LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError, Pass # Spurious intermittent pass
LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError, Pass # Spurious intermittent pass.
LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: RuntimeError, Pass # Spurious intermittent pass
LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: RuntimeError, Pass # Spurious intermittent pass
LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError
LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError
-LayoutTests/fast/parser/stray-param_t01: RuntimeError
-LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError
LayoutTests/fast/parser/parse-wbr_t01: Pass, RuntimeError
-LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError
WebPlatformTest/html-imports/link-import-null_t01: RuntimeError
WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t01: RuntimeError
WebPlatformTest/html/syntax/parsing/math-parse_t03: RuntimeError
@@ -581,6 +729,7 @@
#
[ $compiler == dart2js && $runtime == chromeOnAndroid ]
+LayoutTests/fast/multicol/newmulticol/balance-maxheight_t02: RuntimeError
Language/Expressions/Strings/escape_backspace_t01: Pass, Slow # Please triage this failure.
LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 22200.
LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 22200.
@@ -610,6 +759,8 @@
LibTest/typed_data/Uint8ClampedList/map_A02_t01: Pass, Slow # Please triage this failure.
[ $compiler == dart2js && $runtime == chrome ]
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 26615
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Issue 26615
LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -619,8 +770,6 @@
LayoutTests/fast/animation/request-animation-frame-timestamps-advance_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/animation/request-animation-frame-timestamps_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/animation/request-animation-frame-within-callback_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style_t01: RuntimeError # co19 issue 14
-LayoutTests/fast/backgrounds/multiple-backgrounds-computed-style_t01: RuntimeError # co19 issue 14
LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # Please triage this failure
LayoutTests/fast/borders/border-width-percent_t01: RuntimeError # Issue 25155
LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # Please triage this failure
@@ -631,9 +780,7 @@
LayoutTests/fast/canvas/alpha_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-as-image-incremental-repaint_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/canvas/canvas-as-image_t01: RuntimeError # co19 issue 19
LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-css-crazy_t01: RuntimeError # co19 issue 19
LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is behind a flag.
LayoutTests/fast/canvas/canvas-empty-image-pattern_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-getImageData-invalid_t01: RuntimeError # Please triage this failure
@@ -648,16 +795,12 @@
LayoutTests/fast/canvas/canvas-putImageData_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-resize-after-paint_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/canvas/canvas-scale-drawImage-shadow_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/crash-set-font_t01: RuntimeError # co19 issue 19
LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # Please triage this failure
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/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/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/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
@@ -669,7 +812,6 @@
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/canvas/webgl/webgl-layer-update_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/css/background-clip-text_t01: RuntimeError # Issue 54
LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/malformed-url_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
@@ -721,35 +863,20 @@
LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-intrinsic-dimensions/multicol_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/MarqueeLayoutTest_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-inheritance_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/background-position-serialize_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/background-serialize_t01: RuntimeError # https://github.com/dart-lang/co19/issues/14
LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/computed-offset-with-zoom_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # Issue 23506
-LayoutTests/fast/css/content-language-dynamically-added_t01: RuntimeError # Issue 23506
-LayoutTests/fast/css/content-language-dynamically-removed_t01: RuntimeError # Issue 23506
-LayoutTests/fast/css/content-language-mapped-to-webkit-locale_t01: RuntimeError # Issue 23506
-LayoutTests/fast/css/content-language-multiple_t01: RuntimeError # Issue 23506
-LayoutTests/fast/css/content-language-no-content_t01: RuntimeError # Issue 23506
LayoutTests/fast/css/content/content-none_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-normal_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-quotes-01_t01: RuntimeError # Issue https://github.com/dart-lang/co19/issues/46
LayoutTests/fast/css/content/content-quotes-05_t01: RuntimeError # Issue https://github.com/dart-lang/co19/issues/46
LayoutTests/fast/css/counters/complex-before_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/counters/counter-cssText_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # co19 issue 14
LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/css-selector-text_t01: RuntimeError # co19 Issue 15
LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/csstext-of-content-string_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/css/cursor-parsing-image-set_t01: RuntimeError # co19 issue 14
-LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/cursor-parsing_t01: RuntimeError # co19 issue 14
LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/ex-unit-with-no-x-height_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # Please triage this failure
@@ -765,15 +892,9 @@
LayoutTests/fast/css/fontfaceset-loadingdone_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/computed-style-border-image_t01: RuntimeError # co19 issue 14
LayoutTests/fast/css/getComputedStyle/computed-style-cross-fade_t01: RuntimeError # co19 issue 14
-LayoutTests/fast/css/getComputedStyle/computed-style-font_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/getComputedStyle/computed-style-properties_t01: RuntimeError # Issue 23506
-LayoutTests/fast/css/getComputedStyle/counterIncrement-without-counter_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/getPropertyValue-columns_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/image-set-setting_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/implicit-attach-marking_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/css/important-js-override_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/invalid-predefined-color_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/link-alternate-stylesheet-1_t01: RuntimeError # Please triage this failure
@@ -783,16 +904,11 @@
LayoutTests/fast/css/link-alternate-stylesheet-5_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/media-query-recovery_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/modify-ua-rules-from-javascript_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/nested-at-rules_t01: RuntimeError # Issue 23506
-LayoutTests/fast/css/parse-color-int-or-percent-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-css-allowed-string-characters_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-css-nonascii_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/parsing-css-nth-child_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/parsing-object-position_t01: RuntimeError # https://github.com/dart-lang/co19/issues/47
LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/parsing-text-rendering_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/pseudo-any_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out. Please triage this failure
@@ -805,7 +921,6 @@
LayoutTests/fast/css/selector-text-escape_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/shadow-current-color_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css/sticky/parsing-position-sticky_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/string-quote-binary_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css/style-scoped/style-scoped-nested_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/style-scoped/style-scoped-with-dom-operation_t01: RuntimeError # Please triage this failure
@@ -825,8 +940,8 @@
LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/52776_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/DOMException/dispatch-event-exception_t01: RuntimeError # https://github.com/dart-lang/sdk/issues/25928
LayoutTests/fast/dom/DOMException/XPathException_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/DOMException/dispatch-event-exception_t01: RuntimeError # https://github.com/dart-lang/sdk/issues/25928
LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-strict-mode-wtih-checkbox_t01: Pass, RuntimeError # Please triage this failure
@@ -835,7 +950,6 @@
LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Document/createElementNS-namespace-err_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/Element/getBoundingClientRect-getClientRects-relative-to-viewport_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Element/setAttributeNS-namespace-err_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Skip # Times out. Please triage this failure
@@ -868,6 +982,7 @@
LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: RuntimeError # Issue 25155
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/HTMLOutputElement/htmloutputelement_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # Please triage this failure
@@ -897,7 +1012,6 @@
LayoutTests/fast/dom/SelectorAPI/dumpNodeList_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: RuntimeError # Issue 55
LayoutTests/fast/dom/TreeWalker/TreeWalker-basic_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Window/getMatchedCSSRules-nested-rules_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/Window/getMatchedCSSRules-with-pseudo-elements-complex_t01: RuntimeError # Please triage this failure
@@ -906,12 +1020,10 @@
LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/background-shorthand-csstext_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/blur-contenteditable_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/click-method-on-html-element_t01: RuntimeError # Issue 25155
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/document-register-basic_t01: RuntimeError # Dartium JSInterop failure
LayoutTests/fast/dom/custom/document-register-svg-extends_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/custom/element-names_t01: Pass, RuntimeError # Please triage this failure
@@ -938,9 +1050,8 @@
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/set-innerHTML_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/shadow/content-reprojection-fallback-crash_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/content-pseudo-element-css-text_t01: RuntimeError # https://github.com/dart-lang/co19/issues/49
+LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/host-context-pseudo-class-css-text_t01: RuntimeError # https://github.com/dart-lang/co19/issues/49
LayoutTests/fast/dom/shadow/host-pseudo-class-css-text_t01: RuntimeError # https://github.com/dart-lang/co19/issues/49
LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: RuntimeError # Please triage this failure
@@ -953,7 +1064,6 @@
LayoutTests/fast/dom/shadow/shadow-disable_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/shadow-element-inactive_t01: RuntimeError # Issue 25155
LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/shadowroot-keyframes_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dynamic/crash-generated-counter_t01: RuntimeError # Please triage this failure
@@ -1002,7 +1112,8 @@
LayoutTests/fast/filesystem/directory-entry-to-uri_t01: RuntimeError # Please triage this failure
LayoutTests/fast/filesystem/file-entry-to-uri_t01: RuntimeError # Please triage this failure
LayoutTests/fast/filesystem/filesystem-reference_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/forms/ValidityState-customError_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/ValidityState-tooLong-input_t01: RuntimeError # https://github.com/dart-lang/co19/issues/48
+LayoutTests/fast/forms/ValidityState-tooLong-textarea_t01: RuntimeError # https://github.com/dart-lang/co19/issues/48
LayoutTests/fast/forms/autofocus-focus-only-once_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/forms/autofocus-opera-007_t01: Skip # Times out. Please triage this failure
@@ -1022,6 +1133,7 @@
LayoutTests/fast/forms/input-appearance-elementFromPoint_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/input-hit-test-border_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/input-inputmode_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/input-maxlength_t01: RuntimeError # co19 issue 62
LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/listbox-selection-2_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/menulist-disabled-selected-option_t01: RuntimeError # Please triage this failure
@@ -1045,8 +1157,6 @@
LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/forms/validationMessage_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/validity-property_t01: RuntimeError # Issue 25155
-LayoutTests/fast/forms/ValidityState-tooLong-textarea_t01: RuntimeError # https://github.com/dart-lang/co19/issues/48
-LayoutTests/fast/forms/ValidityState-tooLong-input_t01: RuntimeError # https://github.com/dart-lang/co19/issues/48
LayoutTests/fast/forms/willvalidate_t01: RuntimeError # Issue 25155
LayoutTests/fast/html/hidden-attr_t01: RuntimeError # Please triage this failure
LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # Please triage this failure
@@ -1060,8 +1170,6 @@
LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # Please triage this failure
LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # co19 issue 14
LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # co19 issue 14
-LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/layers/zindex-hit-test_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out. Please triage this failure
@@ -1070,16 +1178,13 @@
LayoutTests/fast/loader/scroll-position-restored-on-back_t01: RuntimeError # Please triage this failure
LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: RuntimeError # Please triage this failure
LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/masking/parsing-clip-path-iri_t01: RuntimeError # co19 issue 14
LayoutTests/fast/masking/parsing-clip-path-shape_t01: RuntimeError # Please triage this failure
LayoutTests/fast/masking/parsing-mask-source-type_t01: RuntimeError # Please triage this failure
LayoutTests/fast/masking/parsing-mask_t01: RuntimeError # Please triage this failure
LayoutTests/fast/media/media-query-list-syntax_t01: RuntimeError # Please triage this failure
LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Issue 23475
-LayoutTests/fast/multicol/balance-trailing-border_t02: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/break-properties_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/columns-shorthand-parsing_t02: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/multicol/float-truncation_t01: RuntimeError # Please triage this failure
@@ -1089,22 +1194,19 @@
LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/hit-test-gap-between-pages_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/newmulticol/balance_t07: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/newmulticol/balance_t08: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/newmulticol/balance_t09: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/newmulticol/balance_t10: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/vertical-rl/break-properties_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/multicol/vertical-rl/break-properties_t01: RuntimeError # co19 issue 63
LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # Please triage this failure
LayoutTests/fast/overflow/scrollbar-restored_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # Please triage this failure
LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError # Please triage this failure
@@ -1112,7 +1214,6 @@
LayoutTests/fast/replaced/table-percent-width_t01: RuntimeError # Please triage this failure
LayoutTests/fast/ruby/ruby-line-height_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/parsing/parsing-shape-lengths_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19 issue 14
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left_t01: RuntimeError # Please triage this failure
@@ -1130,7 +1231,6 @@
LayoutTests/fast/storage/disallowed-storage_t01: RuntimeError # Please triage this failure
LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError # Please triage this failure
LayoutTests/fast/sub-pixel/cssom-subpixel-precision_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # Please triage this failure
LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/table/anonymous-table-section-removed_t01: RuntimeError # Please triage this failure
LayoutTests/fast/table/caption-orthogonal-writing-mode-sizing_t01: RuntimeError # Please triage this failure
@@ -1199,7 +1299,6 @@
LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-text-responsetype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-get_t01: RuntimeError # Issue 25928
LayoutTests/fast/xpath/4XPath/Borrowed/cz_20030217_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xpath/4XPath/Borrowed/namespace-nodes_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: RuntimeError # Please triage this failure
@@ -1436,7 +1535,6 @@
WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: RuntimeError # Please triage this failure
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-event-interface/event-path-001_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-002_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-005_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t01: RuntimeError # Please triage this failure
@@ -1464,7 +1562,7 @@
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
WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t06: Skip # Times out. Please triage this failure
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Pass, RuntimeError # Please triage this failure
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Pass, RuntimeError, Timeout # Please triage this failure
WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-003_t01: Pass, RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-003_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-001_t01: RuntimeError # Please triage this failure
@@ -1474,7 +1572,6 @@
WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-001_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-002_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: RuntimeError # Please triage this failure
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-005_t01: RuntimeError # Issue 25155
WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-007_t01: RuntimeError # Issue 25155
@@ -1517,7 +1614,6 @@
LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width_t01: RuntimeError # Please triage this failure
LayoutTests/fast/html/article-element_t01: RuntimeError # Please triage this failure
LayoutTests/fast/html/aside-element_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # Please triage this failure
LayoutTests/fast/lists/list-style-position-inside_t01: RuntimeError # Please triage this failure
LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # Please triage this failure
@@ -1546,6 +1642,7 @@
LayoutTests/fast/xpath/py-dom-xpath/axes_t01: RuntimeError # Dartium JSInterop failure
LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # Please triage this failure
LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # Issue 18251
+LibTest/html/Element/Element.tag_A01_t01: RuntimeError # Please triage this failure
WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # Please triage this failure
WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: RuntimeError # Please triage this failure
WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: RuntimeError # Please triage this failure
@@ -1556,10 +1653,13 @@
WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: RuntimeError # Please triage this failure
[ $compiler == dart2js && $runtime == chrome && $system == macos ]
+Language/Expressions/Function_Invocation/async_invokation_t04: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/canvas-test_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLOutputElement/htmloutputelement_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/MutationObserver/observe-attributes_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/multicol/newmulticol/balance_t04: RuntimeError # Please triage this failure
+LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # Please triage this failure
LayoutTests/fast/text/glyph-reordering_t01: RuntimeError # Please triage this failure
@@ -1572,6 +1672,7 @@
LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/buffer-bind-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/canvas-2d-webgl-texture_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: RuntimeError # Please triage this failure
@@ -1579,9 +1680,11 @@
LayoutTests/fast/canvas/webgl/canvas-zero-size_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/compressed-tex-image_t01: RuntimeError # Please triage this failure
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/context-lost_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/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/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
@@ -1598,8 +1701,6 @@
LayoutTests/fast/canvas/webgl/gl-get-calls_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-getstring_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-pixelstorei_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
@@ -1615,9 +1716,11 @@
LayoutTests/fast/canvas/webgl/index-validation-with-resized-buffer_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/index-validation_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/invalid-UTF-16_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/is-object_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/null-uniform-location_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/point-size_t01: RuntimeError # Please triage this failure
@@ -1664,7 +1767,9 @@
LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-unprefixed-context-id_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-viewport-parameters-preserved_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/Element/getBoundingClientRect-getClientRects-relative-to-viewport_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/newmulticol/balance_t04: RuntimeError # Please triage this failure
+LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: RuntimeError # co19 issue #65
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # Please triage this failure
LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # Please triage this failure
@@ -1685,6 +1790,8 @@
[ $compiler == dart2js && $runtime == ff ]
Language/Expressions/Postfix_Expressions/property_decrement_t02: Skip # Times out. Please triage this failure
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 26615
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Issue 26615
LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -1710,13 +1817,10 @@
LayoutTests/fast/canvas/DrawImageSinglePixelStretch_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/alpha_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-as-image-incremental-repaint_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-as-image_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-blend-solid_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-composite-canvas_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-composite-image_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-css-crazy_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentColor_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is not implemented.
LayoutTests/fast/canvas/canvas-drawImage-incomplete_t01: RuntimeError # Please triage this failure
@@ -1753,105 +1857,30 @@
LayoutTests/fast/canvas/canvas-strokeRect-zeroSizeGradient_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-strokeText-invalid-maxWidth_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-strokeText-zeroSizeGradient_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/test-setting-canvas-color_t01: Pass, RuntimeError # co19 issue 64 (depends on the FF version)
LayoutTests/fast/canvas/canvas-toDataURL-crash_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/crash-set-font_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/drawImage-with-valid-image_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/rgba-parsing_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/buffer-bind-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/canvas-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/canvas-zero-size_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/compressed-tex-image_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-destroyed-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-lost-restored_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-lost_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/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
-LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/error-reporting_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/get-active-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-enable-enum-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-enum-tests_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-get-calls_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-uniformmatrix4fv_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-vertex-attrib-zero-issues_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-vertex-attrib_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/glsl-conformance_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/index-validation-copies-indices_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/index-validation-crash-with-buffer-sub-data_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/index-validation-verifies-too-many-indices_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/index-validation-with-resized-buffer_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/index-validation_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/is-object_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/point-size_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/program-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/read-pixels-pack-alignment_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/renderbuffer-initialization_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/shader-precision-format_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_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_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
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-uniform-binding-bugs_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-webgl_t01: 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
-LayoutTests/fast/canvas/webgl/texImage2DImageDataTest_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/texImageTest_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/texture-bindings-uneffected-on-resize_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/texture-color-profile_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/texture-complete_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/texture-npot_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/uniform-location-length-limits_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/viewport-unchanged-upon-resize_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/webgl-composite-modes-repaint_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/webgl-composite-modes_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/webgl-exceptions_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/webgl-specific_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/webgl-viewport-parameters-preserved_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/malformed-url_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
@@ -1909,14 +1938,11 @@
LayoutTests/fast/css-intrinsic-dimensions/tables_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-intrinsic-dimensions/width-property-value_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/MarqueeLayoutTest_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-inheritance_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/background-clip-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/background-parser-crash_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/background-position-serialize_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/background-serialize_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/border-image-null-image-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/border-image-style-length_t01: RuntimeError # Please triage this failure
@@ -1928,14 +1954,9 @@
LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/child-selector-implicit-tbody_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/computed-offset-with-zoom_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-dynamically-added_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-dynamically-removed_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-mapped-to-webkit-locale_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-multiple_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-no-content_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-none_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-normal_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/content/content-quotes-01_t01: RuntimeError # co19 issue 61
LayoutTests/fast/css/content/content-quotes-06_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/counters/complex-before_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/counters/counter-cssText_t01: RuntimeError # Please triage this failure
@@ -1944,19 +1965,15 @@
LayoutTests/fast/css/css-keyframe-style-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css-keyframe-unexpected-end_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/css-selector-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/csstext-of-content-string_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/cursor-parsing-image-set_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/cursor-parsing_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/deprecated-flex-box-zero-width-intrinsic-max-width_t01: RuntimeError # Please triage this failure
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/dynamic-class-pseudo-elements_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: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # Please triage this failure
@@ -1970,7 +1987,6 @@
LayoutTests/fast/css/getComputedStyle/computed-style-cross-fade_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/computed-style-font_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/computed-style-properties_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/getComputedStyle/counterIncrement-without-counter_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/font-family-fallback-reset_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/getComputedStyle-border-image-slice_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/getComputedStyle-border-radius-shorthand_t01: RuntimeError # Please triage this failure
@@ -1983,13 +1999,11 @@
LayoutTests/fast/css/getPropertyValue-border_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getPropertyValue-clip_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getPropertyValue-column-rule_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/getPropertyValue-columns_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getPropertyValue-webkit-margin-collapse_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getPropertyValue-webkit-text-stroke_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/image-set-setting_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/important-js-override_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/inherited-properties-rare-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/insertRule-font-face_t01: RuntimeError # Please triage this failure
@@ -2022,13 +2036,11 @@
LayoutTests/fast/css/nested-at-rules_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/overflow-property_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/padding-start-end_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/parse-color-int-or-percent-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-css-allowed-string-characters_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-css-escapes_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-css-nonascii_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-css-nth-child_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/parsing-object-position_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-unexpected-eof_t01: RuntimeError # Please triage this failure
@@ -2056,7 +2068,6 @@
LayoutTests/fast/css/selector-text-escape_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/shorthand-setProperty-important_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/sibling-selectors_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/string-quote-binary_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css/style-scoped/style-scoped-in-shadow_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/style-scoped/style-scoped-nested_t01: RuntimeError # Please triage this failure
@@ -2065,7 +2076,6 @@
LayoutTests/fast/css/style-scoped/style-scoped-with-important-rule_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/text-align-webkit-match-parent-parse_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/text-align-webkit-match-parent_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/transform-origin-parsing_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/unicode-bidi-computed-value_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/url-with-multi-byte-unicode-escape_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/vertical-align-length-copy-bug_t01: RuntimeError # Please triage this failure
@@ -2223,7 +2233,6 @@
LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/detached-shadow-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/empty-shadow-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/removed-stylesheet-rule-deleted-parent-crash_t01: RuntimeError # Please triage this failure
@@ -2638,7 +2647,6 @@
LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/break-properties_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/column-width-zero_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/columns-shorthand-parsing_t02: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: RuntimeError # Please triage this failure
@@ -2650,7 +2658,7 @@
LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/hit-test-gap-between-pages_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError # Uses -webkit-* style properties
LayoutTests/fast/multicol/inherit-column-values_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/initial-column-values_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError # Please triage this failure
@@ -2670,7 +2678,7 @@
LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/vertical-lr/gap-non-negative_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/vertical-rl/break-properties_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/multicol/vertical-rl/break-properties_t01: RuntimeError # co19 issue 63
LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/vertical-rl/gap-non-negative_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: RuntimeError # Please triage this failure
@@ -2684,7 +2692,6 @@
LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # Please triage this failure
LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/stray-param_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/strict-img-in-map_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # Please triage this failure
@@ -2789,7 +2796,6 @@
LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # Please triage this failure
LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-get_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-invalid-values_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-invalid-xml_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-text-responsetype_t01: RuntimeError # Please triage this failure
@@ -3175,6 +3181,98 @@
Language/Classes/Constructors/Factories/return_type_t03: Pass, Slow # Issue 25940
Language/Classes/Constructors/Factories/return_wrong_type_t02: Pass, Slow # Issue 25940
Language/Classes/Constructors/Factories/return_type_t05: Pass, Slow # Issue 25940
+LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/buffer-bind-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/buffer-data-array-buffer_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/canvas-2d-webgl-texture_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/canvas-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/canvas-zero-size_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/css-webkit-canvas_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/compressed-tex-image_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
+LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/error-reporting_t01: 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: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/get-active-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-enable-enum-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-enum-tests_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-get-calls_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-getstring_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-pixelstorei_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-uniformmatrix4fv_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-vertex-attrib-zero-issues_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-vertex-attrib_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-vertexattribpointer_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/glsl-conformance_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/index-validation-copies-indices_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/index-validation-crash-with-buffer-sub-data_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/index-validation-verifies-too-many-indices_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/index-validation-with-resized-buffer_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/index-validation_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/invalid-UTF-16_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/is-object_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/null-uniform-location_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/point-size_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/program-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/read-pixels-pack-alignment_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/renderbuffer-initialization_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/shader-precision-format_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_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-data_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-uniform-binding-bugs_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-webgl_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
+LayoutTests/fast/canvas/webgl/texImage2DImageDataTest_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/texImageTest_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/texture-active-bind_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/texture-bindings-uneffected-on-resize_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/texture-complete_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/texture-color-profile_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/texture-npot_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/uniform-location-length-limits_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/viewport-unchanged-upon-resize_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/webgl-composite-modes-repaint_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/webgl-composite-modes_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/webgl-exceptions_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/webgl-layer-update_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/webgl-specific_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/webgl-unprefixed-context-id_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/webgl-viewport-parameters-preserved_t01: RuntimeError # Please triage this failure
[ $compiler == dart2js && $runtime == ff && $system != windows ]
LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
@@ -3185,6 +3283,8 @@
LayoutTests/fast/text/whitespace/nowrap-line-break-after-white-space_t01: Pass, RuntimeError # Please triage this failure
[ $compiler == dart2js && $runtime == safari ]
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 26615
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Issue 26615
LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -3254,7 +3354,6 @@
LayoutTests/fast/canvas/drawImage-with-valid-image_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # Please triage this failure
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/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
@@ -3269,8 +3368,8 @@
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
-LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-transition_t01: RuntimeError # Please triage this failure
@@ -3315,10 +3414,9 @@
LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/MarqueeLayoutTest_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-inheritance_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/background-position-serialize_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/background-serialize_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/border-image-style-length_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
@@ -3328,21 +3426,22 @@
LayoutTests/fast/css/content/content-normal_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-quotes-01_t01: Pass, RuntimeError # Fails on 7.1. Please triage this failure
LayoutTests/fast/css/content/content-quotes-05_t01: Pass, RuntimeError # Fails on 7.1. Please triage this failure
+LayoutTests/fast/css/counters/counter-cssText_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/csstext-of-content-string_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # Please triage this failure
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
LayoutTests/fast/css/font-face-unicode-range-load_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/font-face-unicode-range-monospace_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/font-property-priority_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Uses FontFace class, not defined for this browser.
LayoutTests/fast/css/fontfaceset-download-error_t01: RuntimeError # Please triage this failure
@@ -3350,10 +3449,15 @@
LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/computed-style-font_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/computed-style-with-zoom_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/getComputedStyle/counterIncrement-without-counter_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getPropertyValue-clip_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/getPropertyValue-columns_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/important-js-override_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/inherited-properties-rare-text_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/invalid-not-with-simple-selector-sequence_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/invalid-predefined-color_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/invalidation/detach-reattach-shadow_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/invalidation/shadow-host-toggle_t01: RuntimeError # Please triage this failure
@@ -3370,6 +3474,8 @@
LayoutTests/fast/css/modify-ua-rules-from-javascript_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parse-color-int-or-percent-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/parsing-css-nth-child_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/parsing-font-variant-ligatures_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-object-position_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # Please triage this failure
@@ -3384,6 +3490,7 @@
LayoutTests/fast/css/readonly-pseudoclass-opera-005_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/shorthand-setProperty-important_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/sticky/parsing-position-sticky_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/string-quote-binary_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/style-scoped/style-scoped-in-shadow_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/style-scoped/style-scoped-nested_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/style-scoped/style-scoped-scoping-nodes-different-order_t01: RuntimeError # Please triage this failure
@@ -3392,6 +3499,7 @@
LayoutTests/fast/css/style-scoped/style-scoped-with-important-rule_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/transform-origin-parsing_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/word-break-user-modify-allowed-values_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last-inherited_t01: RuntimeError # Please triage this failure
@@ -3426,6 +3534,7 @@
LayoutTests/fast/dom/HTMLDialogElement/dialog-close-event_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLDialogElement/dialog-enabled_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLDialogElement/dialog-open_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLDialogElement/dialog-return-value_t01: RuntimeError # Dartium JSInterop failure
LayoutTests/fast/dom/HTMLDialogElement/dialog-scrolled-viewport_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLDialogElement/dialog-show-modal_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLDialogElement/inert-does-not-match-disabled-selector_t01: RuntimeError # Please triage this failure
@@ -3485,6 +3594,7 @@
LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Range/range-isPointInRange_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Range/range-on-detached-node_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/Range/remove-twice-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Range/surroundContents-for-detached-node_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/SelectorAPI/dumpNodeList-2_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/SelectorAPI/dumpNodeList_t01: RuntimeError # Please triage this failure
@@ -3502,6 +3612,7 @@
LayoutTests/fast/dom/XMLSerializer-double-xmlns_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/background-shorthand-csstext_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
@@ -3525,12 +3636,12 @@
LayoutTests/fast/dom/document-set-title-mutations_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/document-set-title-no-reuse_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/domparser-parsefromstring-mimetype-support_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/fragment-activation-focuses-target_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/getElementsByClassName/dumpNodeList_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/html-collections-named-getter-mandatory-arg_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/HTMLDialogElement/dialog-return-value_t01: RuntimeError # Dartium JSInterop failure
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
@@ -3639,6 +3750,7 @@
LayoutTests/fast/events/mutation-during-replace-child-2_t01: RuntimeError # Please triage this failure
LayoutTests/fast/events/mutation-during-replace-child_t01: RuntimeError # Please triage this failure
LayoutTests/fast/events/overflowchanged-event-raf-timing_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/events/scoped/editing-commands_t01: RuntimeError # Please triage this failure
LayoutTests/fast/events/scroll-event-does-not-bubble_t01: RuntimeError # Please triage this failure
LayoutTests/fast/events/tabindex-removal-from-focused-element_t01: RuntimeError # Please triage this failure
LayoutTests/fast/exclusions/parsing/parsing-wrap-flow_t01: RuntimeError # Please triage this failure
@@ -3690,6 +3802,8 @@
LayoutTests/fast/filesystem/simple-required-arguments-getfile_t01: RuntimeError # Please triage this failure
LayoutTests/fast/filesystem/simple-temporary_t01: RuntimeError # Please triage this failure
LayoutTests/fast/filesystem/snapshot-file-with-gc_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/flexbox/repaint-scrollbar_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/ValidityState-customError_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/ValidityState-typeMismatch-email_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/autocomplete_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/autofocus-input-css-style-change_t01: RuntimeError # Please triage this failure
@@ -3701,7 +3815,6 @@
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
LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-change-layout-by-value_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/date/ValidityState-rangeOverflow-date_t01: RuntimeError # Please triage this failure
@@ -3724,6 +3837,7 @@
LayoutTests/fast/forms/datetimelocal/datetimelocal-pseudo-classes_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datetimelocal/datetimelocal-setrangetext_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datetimelocal/input-valueasdate-datetimelocal_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal_t01: RuntimeError # Dartium JSInterop failure
LayoutTests/fast/forms/file/file-input-capture_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/form-attribute_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/input-appearance-elementFromPoint_t01: RuntimeError # Please triage this failure
@@ -3734,7 +3848,6 @@
LayoutTests/fast/forms/interactive-validation-assertion-by-validate-twice_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/interactive-validation-attach-assertion_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/interactive-validation-select-crash_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/forms/listbox-selection-2_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/menulist-disabled-selected-option_t01: Pass, RuntimeError # Fails on 7.1. Please triage this failure
LayoutTests/fast/forms/menulist-selection-reset_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/menulist-submit-without-selection_t01: Pass, RuntimeError # Fails on 7.1. Please triage this failure
@@ -3744,9 +3857,9 @@
LayoutTests/fast/forms/parser-associated-form-removal_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/plaintext-mode-1_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/search-popup-crasher_t01: Pass, RuntimeError # Fails on 7.1. Please triage this failure
-LayoutTests/fast/forms/selection-wrongtype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/select-set-length-with-mutation-remove_t01: RuntimeError
LayoutTests/fast/forms/select-set-length-with-mutation-reparent_t01: RuntimeError
+LayoutTests/fast/forms/selection-wrongtype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/setrangetext_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/textarea-maxlength_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/textarea-paste-newline_t01: RuntimeError # Please triage this failure
@@ -3763,6 +3876,7 @@
LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: RuntimeError # Please triage this failure
LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # Please triage this failure
LayoutTests/fast/innerHTML/innerHTML-svg-write_t01: RuntimeError # Issue 25941
+LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # Please triage this failure
LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out. Please triage this failure
@@ -3789,6 +3903,7 @@
LayoutTests/fast/multicol/balance-unbreakable_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/break-properties_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/multicol/columns-shorthand-parsing_t02: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/float-truncation_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/hit-test-above-or-below_t01: RuntimeError # Please triage this failure
@@ -3796,19 +3911,18 @@
LayoutTests/fast/multicol/hit-test-end-of-column_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/orphans-relayout_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/vertical-rl/break-properties_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/overflow/scrollbar-restored_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # Please triage this failure
LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError # Please triage this failure
@@ -3930,7 +4044,6 @@
LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # Please triage this failure
LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-get_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-text-responsetype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-arraybuffer_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-before-open-sync-request_t01: RuntimeError # Please triage this failure
@@ -3987,6 +4100,8 @@
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/isContentEditable_A01_t01: RuntimeError # Please triage this failure
+LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Please triage this failure
LibTest/html/Element/isTagSupported_A01_t01: RuntimeError # Please triage this failure
LibTest/html/Element/isTagSupported_A01_t02: RuntimeError # Please triage this failure
LibTest/html/Element/leftView_A01_t01: RuntimeError # Please triage this failure
@@ -4027,6 +4142,7 @@
LibTest/html/IFrameElement/getClientRects_A01_t02: RuntimeError # Please triage this failure
LibTest/html/IFrameElement/getNamespacedAttributes_A01_t01: RuntimeError # Please triage this failure
LibTest/html/IFrameElement/innerHtml_A01_t01: RuntimeError # Please triage this failure
+LibTest/html/IFrameElement/isContentEditable_A01_t01: RuntimeError # Please triage this failure
LibTest/html/IFrameElement/leftView_A01_t01: RuntimeError # Please triage this failure
LibTest/html/IFrameElement/marginEdge_A01_t01: RuntimeError # Please triage this failure
LibTest/html/IFrameElement/offsetTo_A01_t01: RuntimeError # Please triage this failure
@@ -5637,6 +5753,8 @@
[ $compiler == dart2js && $runtime == ie10 ]
Language/Expressions/Top_level_Getter_Invocation/17_Getter_Invocation_A03_t02: Skip # Times out. Please triage this failure
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 26615
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Issue 26615
LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -5666,7 +5784,6 @@
LayoutTests/fast/canvas/alpha_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-as-image-incremental-repaint_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/canvas/canvas-as-image_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-blend-image_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-blend-solid_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-blending-clipping_t01: RuntimeError # Please triage this failure
@@ -5693,7 +5810,6 @@
LayoutTests/fast/canvas/canvas-blending-transforms_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-clip-rule_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-composite-canvas_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-css-crazy_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentColor_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is not implemented
LayoutTests/fast/canvas/canvas-ellipse-360-winding_t01: RuntimeError # Please triage this failure
@@ -5731,7 +5847,6 @@
LayoutTests/fast/canvas/canvas-setTransform_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-to-canvas_t01: Pass, RuntimeError # Issue 22216
LayoutTests/fast/canvas/canvas-transforms-fillRect-shadow_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/crash-set-font_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/drawImage-with-bad-canvas_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/canvas/drawImage-with-negative-source-destination_t01: Pass, RuntimeError # Issue 22216
@@ -5913,7 +6028,6 @@
LayoutTests/fast/css-intrinsic-dimensions/tables_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-intrinsic-dimensions/width-property-value_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-inheritance_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Please triage this failure
@@ -5931,14 +6045,9 @@
LayoutTests/fast/css/child-selector-implicit-tbody_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/comment-before-charset-external_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/computed-offset-with-zoom_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-dynamically-added_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-dynamically-removed_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-mapped-to-webkit-locale_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-multiple_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-no-content_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-none_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-normal_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/content/content-quotes-01_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-quotes-03_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-quotes-06_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/counters/complex-before_t01: RuntimeError # Please triage this failure
@@ -5949,18 +6058,15 @@
LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css-selector-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/cssom-remove-shorthand-property_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/csstext-of-content-string_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/cursor-parsing-image-set_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/cursor-parsing_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/deprecated-flex-box-zero-width-intrinsic-max-width_t01: RuntimeError # Please triage this failure
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/dynamic-class-pseudo-elements_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/font-face-cache-bug_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # Please triage this failure
@@ -5980,7 +6086,6 @@
LayoutTests/fast/css/getComputedStyle/computed-style-font_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/computed-style-properties_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/computed-style-select-overflow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/getComputedStyle/counterIncrement-without-counter_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/font-family-fallback-reset_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/getComputedStyle-border-image-slice_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/getComputedStyle-border-radius-shorthand_t01: RuntimeError # Please triage this failure
@@ -6002,6 +6107,7 @@
LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/image-set-setting_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/implicit-attach-marking_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/css/important-js-override_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/inherited-properties-rare-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/insertRule-font-face_t01: RuntimeError # Please triage this failure
@@ -6100,7 +6206,6 @@
LayoutTests/fast/css/text-align-initial_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/text-align-webkit-match-parent-parse_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/text-align-webkit-match-parent_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/transform-origin-parsing_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/unicode-bidi-computed-value_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/url-with-multi-byte-unicode-escape_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/webkit-color-adjust_t01: RuntimeError # Please triage this failure
@@ -6336,7 +6441,6 @@
LayoutTests/fast/dom/StyleSheet/detached-shadow-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/detached-style-2_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/detached-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/empty-shadow-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/removed-stylesheet-rule-deleted-parent-crash_t01: RuntimeError # Please triage this failure
@@ -6407,7 +6511,6 @@
LayoutTests/fast/dom/dom-parse-serialize_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/domparser-parsefromstring-mimetype-support_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/fragment-activation-focuses-target_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/gc-image-element-2_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/dom/gc-image-element_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/dom/getElementById-consistency2_t01: RuntimeError # Please triage this failure
@@ -6794,7 +6897,6 @@
LayoutTests/fast/innerHTML/innerHTML-svg-read_t01: RuntimeError # Please triage this failure
LayoutTests/fast/innerHTML/innerHTML-svg-write_t01: RuntimeError # Please triage this failure
LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # Please triage this failure
LayoutTests/fast/layers/zindex-hit-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/lists/list-style-position-inside_t01: RuntimeError # Please triage this failure
LayoutTests/fast/loader/about-blank-hash-change_t01: RuntimeError # Please triage this failure
@@ -6822,7 +6924,6 @@
LayoutTests/fast/multicol/balance-trailing-border_t02: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/break-properties_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/columns-shorthand-parsing_t02: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/float-truncation_t01: RuntimeError # Please triage this failure
@@ -6860,7 +6961,6 @@
LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # Please triage this failure
LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/residual-style-close-across-n-blocks_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError # Please triage this failure
@@ -7007,7 +7107,6 @@
LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # Please triage this failure
LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-get_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-invalid-values_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-document-responsetype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-text-responsetype_t01: RuntimeError # Please triage this failure
@@ -7662,6 +7761,8 @@
Language/Expressions/Conditional/type_t04: Skip # Times out. Please triage this failure
Language/Expressions/Identifier_Reference/evaluation_function_t02: Skip # Times out. Please triage this failure
Language/Statements/Local_Variable_Declaration/syntax_t18: Skip # Times out. Please triage this failure
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 26615
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Issue 26615
Language/Types/Interface_Types/subtype_t37: Skip # Times out. Please triage this failure
Language/Types/Function_Types/subtype_no_args_t03: Skip # Times out. Please triage this failure
LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
@@ -7690,7 +7791,6 @@
LayoutTests/fast/canvas/alpha_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-as-image-incremental-repaint_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/canvas/canvas-as-image_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-blend-image_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-blend-solid_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-blending-clipping_t01: RuntimeError # Please triage this failure
@@ -7717,7 +7817,6 @@
LayoutTests/fast/canvas/canvas-blending-transforms_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-composite-alpha_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-css-crazy_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentColor_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is not implemented
LayoutTests/fast/canvas/canvas-ellipse-360-winding_t01: RuntimeError # Please triage this failure
@@ -7756,7 +7855,6 @@
LayoutTests/fast/canvas/canvas-to-canvas_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-toDataURL-crash_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-transforms-fillRect-shadow_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/crash-set-font_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/drawImage-with-bad-canvas_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/canvas/drawImage-with-negative-source-destination_t01: Pass, RuntimeError # Please triage this failure
@@ -7779,16 +7877,11 @@
LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-lost-restored_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-lost_t01: Pass, 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/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/draw-arrays-out-of-bounds_t01: Pass, 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
LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: Pass, RuntimeError # Please triage this failure
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/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
@@ -7807,7 +7900,6 @@
LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/null-uniform-location_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/point-size_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError # Please triage this failure
@@ -7815,15 +7907,10 @@
LayoutTests/fast/canvas/webgl/read-pixels-pack-alignment_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/read-pixels-test_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_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-data_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: Skip # Times out. Please triage this failure
@@ -7835,8 +7922,6 @@
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-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
LayoutTests/fast/canvas/webgl/texImage2DImageDataTest_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/texImageTest_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/texture-active-bind_t01: Pass, RuntimeError # Please triage this failure
@@ -7851,7 +7936,6 @@
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
-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/canvas/webgl/webgl-layer-update_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-specific_t01: RuntimeError # Please triage this failure
@@ -7918,7 +8002,6 @@
LayoutTests/fast/css-intrinsic-dimensions/tables_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-intrinsic-dimensions/width-property-value_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-inheritance_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Please triage this failure
@@ -7936,14 +8019,9 @@
LayoutTests/fast/css/child-selector-implicit-tbody_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/comment-before-charset-external_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css/computed-offset-with-zoom_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-dynamically-added_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-dynamically-removed_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-mapped-to-webkit-locale_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-multiple_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content-language-no-content_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-none_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-normal_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/content/content-quotes-01_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-quotes-03_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-quotes-06_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/counters/complex-before_t01: RuntimeError # Please triage this failure
@@ -7955,18 +8033,15 @@
LayoutTests/fast/css/css-selector-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css3-nth-tokens-script_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/cssom-remove-shorthand-property_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/csstext-of-content-string_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/cursor-parsing-image-set_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/cursor-parsing_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/deprecated-flex-box-zero-width-intrinsic-max-width_t01: RuntimeError # Please triage this failure
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/dynamic-class-pseudo-elements_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/font-face-cache-bug_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # Please triage this failure
@@ -7986,7 +8061,6 @@
LayoutTests/fast/css/getComputedStyle/computed-style-font_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/computed-style-properties_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/computed-style-select-overflow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/getComputedStyle/counterIncrement-without-counter_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/font-family-fallback-reset_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/getComputedStyle-border-radius-shorthand_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/getComputedStyle-border-style-shorthand_t01: RuntimeError # Please triage this failure
@@ -8007,6 +8081,7 @@
LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/image-set-setting_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/implicit-attach-marking_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/css/important-js-override_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/inherited-properties-rare-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/insertRule-font-face_t01: RuntimeError # Please triage this failure
@@ -8105,7 +8180,6 @@
LayoutTests/fast/css/text-align-initial_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/text-align-webkit-match-parent-parse_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/text-align-webkit-match-parent_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/transform-origin-parsing_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/unicode-bidi-computed-value_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/url-with-multi-byte-unicode-escape_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/webkit-color-adjust_t01: RuntimeError # Please triage this failure
@@ -8132,6 +8206,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/Element/attribute-uppercase_t01: RuntimeError # Please triage this failure
@@ -8321,7 +8396,6 @@
LayoutTests/fast/dom/StyleSheet/detached-shadow-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/detached-style-2_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/detached-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/empty-shadow-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/StyleSheet/removed-stylesheet-rule-deleted-parent-crash_t01: RuntimeError # Please triage this failure
@@ -8390,7 +8464,6 @@
LayoutTests/fast/dom/dom-parse-serialize_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/domparser-parsefromstring-mimetype-support_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/fragment-activation-focuses-target_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/gc-image-element-2_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/dom/gc-image-element_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/dom/getElementById-consistency2_t01: RuntimeError # Please triage this failure
@@ -8771,7 +8844,6 @@
LayoutTests/fast/innerHTML/innerHTML-svg-read_t01: RuntimeError # Please triage this failure
LayoutTests/fast/innerHTML/innerHTML-svg-write_t01: RuntimeError # Please triage this failure
LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # Please triage this failure
LayoutTests/fast/layers/zindex-hit-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/lists/list-style-position-inside_t01: RuntimeError # Please triage this failure
LayoutTests/fast/loader/about-blank-hash-change_t01: RuntimeError # Please triage this failure
@@ -8799,7 +8871,6 @@
LayoutTests/fast/multicol/balance-trailing-border_t02: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/break-properties_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/columns-shorthand-parsing_t02: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/multicol/float-truncation_t01: RuntimeError # Please triage this failure
@@ -8837,7 +8908,6 @@
LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # Please triage this failure
LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # Please triage this failure
LayoutTests/fast/parser/residual-style-close-across-n-blocks_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # Please triage this failure
LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Pass, RuntimeError # Please triage this failure
@@ -8986,7 +9056,6 @@
LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # Please triage this failure
LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-get_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-invalid-values_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-document-responsetype_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responseXML-xml-text-responsetype_t01: RuntimeError # Please triage this failure
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 545123a..a73769a 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -12,13 +12,11 @@
LayoutTests/fast/writing-mode/flipped-blocks-hit-test-overflow_t01: Pass, RuntimeError # Issue 21605
LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: Pass, RuntimeError # Issue 21605
-[ $compiler == none && $runtime == dartium && $checked && $system == macos ]
-LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # 45 roll
-
[ $compiler == none && $runtime == dartium && $system == windows ]
LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: Pass, RuntimeError # Issue 21605
WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: RuntimeError # Please triage this failure.
WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Skip # Timesout Issue 26134
+LayoutTests/fast/css/MarqueeLayoutTest_t01: Pass, RuntimeError # Please triage this failure
[ $compiler == none && $runtime == dartium && $system != windows ]
LayoutTests/fast/css/font-face-unicode-range-monospace_t01: RuntimeError # co19-roll r761: Please triage this failure.
@@ -58,7 +56,8 @@
WebPlatformTest/html/semantics/forms/the-datalist-element/datalistoptions_t01: Skip # Issue 20540.
[ $compiler == none && $runtime == dartium && $checked ]
-Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/xpath/ambiguous-operators_t01: RuntimeError # co19-roll r761: Please triage this failure.
Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure.
Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure.
Language/Errors_and_Warnings/static_warning_t04: RuntimeError # Please triage this failure.
@@ -115,7 +114,6 @@
LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/shapes/parsing/parsing-shape-image-threshold_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/shapes/parsing/parsing-shape-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/table/css-table-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/table/fixed-table-layout-width-change_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -132,7 +130,6 @@
LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/trivial-segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/trivial_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # Dartium 45 roll
LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # co19-roll r761: Please triage this failure.
LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # co19-roll r722: Issue 18251
WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # co19-roll r738: Please triage this failure.
@@ -150,7 +147,6 @@
Language/Classes/Constructors/Generative_Constructors/final_variables_t01: Pass, Fail #: Please triage this failure.
Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure.
Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure.
-Language/Classes/Setters/syntax_t04: RuntimeError # Please triage this failure.
Language/Classes/Setters/type_object_t01: RuntimeError # Please triage this failure.
Language/Classes/Setters/type_object_t02: RuntimeError # Please triage this failure.
Language/Classes/Static_Methods/type_object_t01: RuntimeError # Please triage this failure.
@@ -184,37 +180,72 @@
Language/Classes/deсlarations_t32: Skip # Times out. Please triage this failure.
Language/Classes/deсlarations_t33: Skip # Times out. Please triage this failure.
Language/Classes/deсlarations_t34: Skip # Times out. Please triage this failure.
-Language/Expressions/Instance_Creation/Const/abstract_class_t01: Fail # Issue 22007
-Language/Expressions/Instance_Creation/Const/abstract_class_t03: Fail # Issue 22007
+Language/Expressions/Assignment/super_assignment_failed_t05: RuntimeError # Issue 25671
+Language/Expressions/Function_Invocation/async_generator_invokation_t08: Timeout # Issue 25967
+Language/Expressions/Function_Invocation/async_generator_invokation_t10: Timeout # Issue 25967
+Language/Expressions/Identifier_Reference/built_in_identifier_t35: Fail # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t36: Fail # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t37: Fail # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t53: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t54: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t55: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t56: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t57: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t58: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t59: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t60: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t61: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t62: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t63: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t64: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t65: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t66: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t67: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t68: Fail # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t14: Fail # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t19: Fail # Issue 25772
Language/Expressions/Instance_Creation/New/execution_t04: Fail, OK
Language/Expressions/Instance_Creation/New/execution_t06: Fail, OK
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: RuntimeError # Please triage this failure.
+Language/Expressions/Method_Invocation/Ordinary_Invocation/object_method_invocation_t01: Fail # Issue 25496
+Language/Expressions/Method_Invocation/Ordinary_Invocation/object_method_invocation_t02: Fail # Issue 25496
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t01: RuntimeError # Issue 24607
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t02: RuntimeError # Issue 24607
+
+Language/Expressions/Property_Extraction/General_Super_Property_Extraction: RuntimeError # Issue 26287
+
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/identical_t01: RuntimeError # Issue 24607
+
+Language/Expressions/Property_Extraction/Super_Closurization: RuntimeError # Issue 26287
+
Language/Expressions/Spawning_an_Isolate/new_isolate_t01: RuntimeError, OK # Uses Isolate.spawn.
Language/Libraries_and_Scripts/Exports/reexport_t01: fail # Dart issue 12916
Language/Libraries_and_Scripts/Exports/reexport_t02: fail # Dart issue 12916
-Language/Libraries_and_Scripts/Imports/namespace_changes_t10: RuntimeError # Please triage this failure.
Language/Libraries_and_Scripts/Parts/compilation_t02: Skip # Please triage this failure.
Language/Libraries_and_Scripts/Parts/syntax_t05: Skip # Times out flakily. Issue 20881
Language/Libraries_and_Scripts/Scripts/top_level_main_t03: Pass # Issue 14478: This should break.
Language/Libraries_and_Scripts/Scripts/top_level_main_t03: RuntimeError # co19-roll r786: Please triage this failure.
-Language/Libraries_and_Scripts/URIs/syntax_t04: RuntimeError # Please triage this failure.
-Language/Libraries_and_Scripts/URIs/syntax_t05: RuntimeError # Please triage this failure.
-Language/Libraries_and_Scripts/URIs/syntax_t09: RuntimeError # Please triage this failure.
-Language/Libraries_and_Scripts/URIs/syntax_t10: RuntimeError # Please triage this failure.
-Language/Libraries_and_Scripts/URIs/syntax_t14: RuntimeError # Please triage this failure.
-Language/Libraries_and_Scripts/URIs/syntax_t15: RuntimeError # Please triage this failure.
Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure.
-Language/Mixins/Mixin_Application/error_t01: Fail # co19 issue 43
-Language/Mixins/Mixin_Application/error_t02: Fail # co19 issue 43
-Language/Mixins/declaring_constructor_t01: Fail # co19 issue 43
+Language/Mixins/Mixin_Application/syntax_t16: RuntimeError # Please triage this failure.
+Language/Mixins/declaring_constructor_t05: Fail # Issue 24767
+Language/Mixins/declaring_constructor_t06: Fail # Issue 24767
Language/Mixins/not_object_superclass_t01: Fail # Please triage this failure.
Language/Mixins/reference_to_super_t01: Fail # Please triage this failure.
+Language/Reference/Operator_Precedence/precedence_12_Shift_t02: RuntimeError # Please triage this failure
+Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t04: RuntimeError # Please triage this failure
Language/Statements/Assert/execution_t02: skip # co19 issue 734
Language/Statements/Assert/execution_t03: skip # co19 issue 734
Language/Statements/Assert/type_t02: skip # co19 issue 734
Language/Statements/Assert/type_t05: skip # co19 issue 734
+Language/Statements/Continue/async_loops_t10: Timeout, Skip # Issue 25748
Language/Statements/Labels/syntax_t03: fail # Dart issue 2238
Language/Statements/Switch/syntax_t02: fail # Dart issue 12908
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Please triage this failure
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t02: RuntimeError # Please triage this failure
+Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t04: RuntimeError # Please triage this failure
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t08: RuntimeError # Issue 25748
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09: RuntimeError # Issue 25748
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t10: RuntimeError # Issue 25748
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_sync_t05: RuntimeError # Issue 25662,25634
LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
@@ -403,17 +434,16 @@
LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: Skip # co19 issue 732.
LayoutTests/fast/css/computed-offset-with-zoom_t01: Skip # co19 issue 732.
LayoutTests/fast/css/content/content-none_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/content/content-normal_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/content/content-quotes-01_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/counters/complex-before_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: Pass, RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
@@ -435,6 +465,7 @@
LayoutTests/fast/css/link-alternate-stylesheet-5_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/media-query-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-object-position_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/css/pseudo-any_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
@@ -661,26 +692,16 @@
LayoutTests/fast/html/imports/import-events_t01: RuntimeError # co19-roll r706. Please triage this failure.
LayoutTests/fast/html/select-dropdown-consistent-background-color_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/inline/boundingBox-with-continuation_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-inline-parent_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/inline/fixed-pos-with-transform-container-moves-with-abspos-parent_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/inline/inline-position-top-align_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/inline-relative-offset-boundingbox_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/inline/inline-with-empty-inline-children_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/reattach-inlines-in-anonymous-blocks-with-out-of-flow-siblings_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/innerHTML/innerHTML-special-elements_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/layers/zindex-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/layers/zindex-hit-test_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/lists/item-not-in-list-line-wrapping_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/lists/list-style-position-inside_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out. co19-roll r801: Please triage this failure.
LayoutTests/fast/loader/hashchange-event-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
@@ -698,13 +719,11 @@
LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Issue 22111
LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: Skip # Passes on Safari, Issue 23475 # co19 issue 11.
LayoutTests/fast/mediastream/getusermedia_t01: Skip # co19 issue 738
-LayoutTests/fast/multicol/balance-trailing-border_t02: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/balance-unbreakable_t01: Pass, RuntimeError # co19 issue 11.
LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/column-width-zero_t01: Pass, RuntimeError # co19 issue 11.
LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/hit-test-above-or-below_t01: RuntimeError # co19-roll r801: Please triage this failure.
@@ -713,12 +732,8 @@
LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/hit-test-gap-between-pages_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/image-inside-nested-blocks-with-border_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/inherit-column-values_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/inline-getclientrects_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/newmulticol/balance-maxheight_t02: RuntimeError # co19 issue 11.
LayoutTests/fast/multicol/newmulticol/balance_t01: Pass, RuntimeError # co19 issue 11.
LayoutTests/fast/multicol/newmulticol/balance_t02: Pass, RuntimeError # co19 issue 11.
LayoutTests/fast/multicol/newmulticol/balance_t04: Pass, RuntimeError # co19 issue 11.
@@ -734,14 +749,12 @@
LayoutTests/fast/multicol/newmulticol/balance_t10: Pass, RuntimeError # I don't understand how, but sometimes passes. # co19 issue 11.
LayoutTests/fast/multicol/newmulticol/balance_t10: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/orphans-relayout_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/multicol/vertical-lr/break-properties_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/vertical-rl/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19 issue 11.
LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/zeroColumnCount_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/overflow/child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/overflow/overflow-rtl-vertical-origin_t01: Pass, RuntimeError # False passes on Firefox, but trying to keep these grouped with the issue. # co19 issue 11.
@@ -753,9 +766,6 @@
LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/parser/parse-wbr_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/parser/pre-first-line-break_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/parser/stray-param_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19 issue 11.
LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass # False pass # co19 issue 11.
LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19 issue 11.
@@ -765,14 +775,10 @@
LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError, Pass, Timeout # Spurious intermittent pass. # co19 issue 11.
LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError, Pass, Timeout # co19-roll r801: Please triage this failure.
LayoutTests/fast/replaced/preferred-widths_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/table-percent-height-text-controls_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/replaced/table-percent-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/replaced/table-percent-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/table-replaced-element_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/ruby/parse-rp_t01: Pass, RuntimeError # co19 issue 11.
LayoutTests/fast/ruby/ruby-line-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/selectors/specificity-overflow_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/selectors/style-sharing-last-child_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/shapes/parsing/parsing-shape-lengths_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: RuntimeError # co19-roll r801: Please triage this failure.
@@ -797,7 +803,6 @@
LayoutTests/fast/sub-pixel/size-of-span-with-different-positions_t01: Skip # co19 issue 732.
LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: Skip # co19 issue 732.
-LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/table/anonymous-table-section-removed_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/table/anonymous-table-section-removed_t01: Skip # co19 issue 11.
LayoutTests/fast/table/caption-orthogonal-writing-mode-sizing_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -825,8 +830,6 @@
LayoutTests/fast/table/min-width-html-inline-table_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/table/nested-tables-with-div-offset_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
LayoutTests/fast/table/padding-height-and-override-height_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/resize-table-row_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows-except-overlapped_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/table/table-all-rowspans-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/table/table-cell-offset-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -834,13 +837,10 @@
LayoutTests/fast/table/table-rowspan-cell-with-empty-cell_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t02: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-sections-border-spacing_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError # co19 issue 11.
LayoutTests/fast/table/table-with-content-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/text-autosizing/vertical-writing-mode_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/text/container-align-with-inlines_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/text/find-soft-hyphen_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/text/find-spaces_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/text/font-fallback-synthetic-italics_t01: Pass, RuntimeError # co19 issue 11.
@@ -852,7 +852,6 @@
LayoutTests/fast/text/glyph-reordering_t01: Pass, RuntimeError # This is a false pass. The font gets sanitized, so whether it works or not probably depends on default sizes. # co19 issue 11.
LayoutTests/fast/text/international/complex-text-rectangle_t01: Skip # co19 issue 732.
LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/international/listbox-width-rtl_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/text/international/rtl-text-wrapping_t01: Pass # This is a false pass. All the content gets sanitized, so there's nothing to assert fail on. If the code did anything it would fail. # co19 issue 11.
LayoutTests/fast/text/international/rtl-text-wrapping_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/text/international/rtl-text-wrapping_t01: Skip # co19 issue 732.
@@ -860,14 +859,10 @@
LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19 issue 11.
LayoutTests/fast/text/ipa-tone-letters_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/text/line-break-after-empty-inline-hebrew_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/line-breaks-after-closing-punctuations_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: Skip # co19 issue 732.
-LayoutTests/fast/text/line-breaks-after-ideographic-comma-or-full-stop_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/text/offsetForPosition-cluster-at-zero_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/pre-wrap-trailing-tab_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, Fail # co19 issue 11.
LayoutTests/fast/text/regional-indicator-symobls_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/text/remove-zero-length-run_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -881,44 +876,27 @@
LayoutTests/fast/transforms/bounding-rect-zoom_t01: RuntimeError, Pass # Erratic, but only passes because divs have been entirely removed. # co19 issue 11.
LayoutTests/fast/transforms/hit-test-large-scale_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/transforms/scrollIntoView-transformed_t01: Pass, RuntimeError # False passes on Firefox. # co19 issue 11.
-LayoutTests/fast/transforms/topmost-becomes-bottomost-for-scrolling_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/transforms/transform-hit-test-flipped_t01: Pass, RuntimeError # Passes on Firefox, but is clearly not testing what it's trying to test. # co19 issue 11.
-LayoutTests/fast/transforms/transform-inside-overflow-scroll_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/url/anchor_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/url/file-http-base_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/file_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/host-lowercase-per-scheme_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/url/host_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/idna2003_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/idna2008_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/invalid-urls-utf8_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/ipv4_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/ipv6_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/mailto_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/url/path-url_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/url/path_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/port_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/url/query_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/relative-unix_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/relative-win_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/relative_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/safari-extension_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/url/safari-extension_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/url/scheme_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/url/segments-from-data-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/url/standard-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/trivial-segments_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/url/trivial_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/writing-mode/auto-margins-across-boundaries_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/writing-mode/auto-sizing-orthogonal-flows_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/writing-mode/block-formatting-context_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/writing-mode/display-mutation_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/writing-mode/percentage-margins-absolute-replaced_t01: Pass, RuntimeError # co19 issue 11.
-LayoutTests/fast/writing-mode/percentage-padding_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/writing-mode/positionForPoint_t01: Skip # co19 issue 732.
-LayoutTests/fast/writing-mode/relative-positioning-percentages_t01: RuntimeError # co19 issue 11.
LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/writing-mode/vertical-font-vmtx-units-per-em_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/xmlhttprequest/xmlhttprequest-responsetype-abort_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
@@ -930,7 +908,6 @@
LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/xpath/ambiguous-operators_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/xpath/attr-namespace_t02: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/xpath/ensure-null-namespace_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/xpath/implicit-node-args_t01: RuntimeError # co19-roll r761: Please triage this failure.
@@ -944,14 +921,11 @@
LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # co19-roll r786: Please triage this failure.
LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # co19-roll r761: Please triage this failure.
LayoutTests/fast/xsl/default-html_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LibTest/async/Completer/completeError_A02_t01: Pass, Fail # Please triage this failure.
LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # co19-roll r706. Please triage this failure.
LibTest/async/Timer/Timer_A01_t01: RuntimeError, Pass # Issue 16475
LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19-roll r722: Please triage this failure.
-LibTest/core/DateTime/parse_A01_t02: Skip # Times out. Please triage this failure.
-LibTest/core/DateTime/parse_A03_t01: fail # Issue 12514
LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 22200
LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 22200
LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue 22200
@@ -1068,7 +1042,7 @@
LibTest/isolate/ReceivePort/asBroadcastStream_A04_t02: RuntimeError, OK # Uses Isolate.spawn.
LibTest/isolate/ReceivePort/asBroadcastStream_A04_t03: RuntimeError, OK # Uses Isolate.spawn.
LibTest/isolate/ReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/close_A02_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/close_A02_t01: Pass, RuntimeError, Timeout # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
LibTest/isolate/ReceivePort/contains_A01_t01: RuntimeError, OK # Uses Isolate.spawn.
LibTest/isolate/ReceivePort/distinct_A01_t01: RuntimeError, OK # Uses Isolate.spawn.
LibTest/isolate/ReceivePort/distinct_A01_t02: RuntimeError, OK # Uses Isolate.spawn.
@@ -1306,54 +1280,14 @@
LayoutTests/fast/css/aspect-ratio-inheritance_t01: Skip # 45 Roll No longer supported.
LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: Skip # 45 Roll No longer supported.
LayoutTests/fast/css/auto-min-size_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/background-position-serialize_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/content-language-dynamically-added_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/content-language-dynamically-removed_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/content-language-mapped-to-webkit-locale_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/content-language-multiple_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/content-language-no-content_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/counters/counter-cssText_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: Skip # 45 Roll failure.
-LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/csstext-of-content-string_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/ex-unit-with-no-x-height_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/getComputedStyle/computed-style-font_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/getComputedStyle/computed-style-properties_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/getComputedStyle/counterIncrement-without-counter_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/getPropertyValue-columns_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/image-set-setting_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/important-js-override_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/MarqueeLayoutTest_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/nested-at-rules_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/parse-color-int-or-percent-crash_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
LayoutTests/fast/css/parsing-css-allowed-string-characters_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/parsing-css-nth-child_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/parsing-text-rendering_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/pseudo-valid-unapplied_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/string-quote-binary_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/css/transform-origin-parsing_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
LayoutTests/fast/dom/custom/element-names_t01: RuntimeError # 45 Roll issue dart-lang/co19/issues/25
-LayoutTests/fast/dom/background-shorthand-csstext_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/dom/css-selectorText_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/dom/fragment-activation-focuses-target_t01: RuntimeError # 45 Roll co19 issue https://github.com/dart-lang/co19/issues/36
-LayoutTests/fast/dom/shadow/content-reprojection-fallback-crash_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/26
-LayoutTests/fast/dom/shadow/shadow-disable_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/27
-LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
LayoutTests/fast/encoding/css-charset-dom_t01: Skip # 45 Roll No longer supported see issue https://github.com/dart-lang/co19/issues/35
LayoutTests/fast/events/overflowchanged-event-raf-timing_t01: Skip # 45 Roll No longer supported.
LayoutTests/fast/forms/input-value-sanitization_t01: RuntimeError # 45 roll issue
-LayoutTests/fast/forms/validationMessage_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/28
-LayoutTests/fast/forms/ValidityState-customError_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/29
-LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/34
-LayoutTests/fast/multicol/columns-shorthand-parsing_t02: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/30
LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # 45 rollwebgl doesn't run on on windows/linux but failed on mac bots.
-LayoutTests/fast/xmlhttprequest/xmlhttprequest-get_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/31
WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-005_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002_t01: RuntimeError # 45 Roll co19 test rewrite issue 25807
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-event-interface/event-path-001_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/32
WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-002_t01: RuntimeError # 45 roll issue https://github.com/dart-lang/co19/issues/33
# Must fix failures below after JsInterop checkin.
WebPlatformTest/dom/nodes/Node-appendChild_t01: RuntimeError # Issue 26134
@@ -1383,3 +1317,4 @@
LibTest/html/Element/insertBefore_A01_t01: RuntimeError # Issue 26134
LibTest/html/Element/insertAllBefore_A01_t01: RuntimeError # Issue 26134
LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: Skip # Issue 26134, timeout
+html/cross_domain_iframe_test: RuntimeError # Issue 26134
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 1ce9410..ed82429 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -27,9 +27,6 @@
Language/Statements/Assert/type_t05: skip # co19 issue 734
-LibTest/core/DateTime/parse_A03_t01: fail # Issue 12514
-LibTest/core/DateTime/parse_A01_t02: Fail # co19 issue 17.
-
LibTest/core/DateTime/DateTime.now_A01_t02: Pass, Fail # co19 issue 709
LibTest/isolate/Isolate/spawnUri_A01_t02: Skip # Dart issue 15974
@@ -46,8 +43,6 @@
[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) ]
LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # co19 issue 599
LibTest/typed_data/Float32x4/reciprocal_A01_t01: Pass, Fail # co19 issue 599
-Language/Expressions/Instance_Creation/Const/abstract_class_t01: MissingCompileTimeError # Issue 22007
-Language/Expressions/Instance_Creation/Const/abstract_class_t03: MissingCompileTimeError # Issue 22007
# With asynchronous loading, the load errors in these tests are no longer recognized as compile errors:
Language/Libraries_and_Scripts/Imports/invalid_uri_t02: Fail
Language/Libraries_and_Scripts/Exports/invalid_uri_t02: Fail
@@ -56,6 +51,9 @@
[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && $mode == debug ]
LibTest/core/List/List_class_A01_t02: Pass, Slow
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && $system == windows ]
+Language/Expressions/Function_Invocation/async_invokation_t04: Pass, RuntimeError # co19 issue 54
+
[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && ($arch != x64 && $arch != simarm64 && $arch != arm64) ]
LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
@@ -86,14 +84,13 @@
[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && $mode == debug && $builder_tag == asan ]
Language/Types/Interface_Types/subtype_t27: Skip # Issue 21174.
-[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && $arch == arm ]
+[ ($runtime == vm || $runtime == dart_app) && $arch == arm ]
LibTest/typed_data/Float32x4/operator_multiplication_A01_t01: Fail # Dart issue 24416
[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) ]
# co19 update Sep 29, 2015 (3ed795ea02e022ef19c77cf1b6095b7c8f5584d0)
Language/Classes/Getters/type_object_t01: RuntimeError # Issue 23721
Language/Classes/Getters/type_object_t02: RuntimeError # Issue 23721
-Language/Classes/Setters/syntax_t04: RuntimeError # co19 issue 38
Language/Classes/Setters/type_object_t01: RuntimeError # Issue 23721
Language/Classes/Setters/type_object_t02: RuntimeError # Issue 23721
Language/Classes/Static_Methods/type_object_t01: RuntimeError # Issue 23721
@@ -112,34 +109,63 @@
Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t06: MissingCompileTimeError # Issue 24472
Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t07: MissingCompileTimeError # Issue 24472
Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError # Issue 24472
-Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: CompileTimeError # co19 issue 41
-Language/Libraries_and_Scripts/Imports/namespace_changes_t10: RuntimeError # co19 issue 39
-Language/Libraries_and_Scripts/Parts/compilation_t09: MissingCompileTimeError # co19 issue 40
-Language/Libraries_and_Scripts/URIs/syntax_t04: RuntimeError # co19 issue 42
-Language/Libraries_and_Scripts/URIs/syntax_t05: RuntimeError # co19 issue 42
-Language/Libraries_and_Scripts/URIs/syntax_t09: RuntimeError # co19 issue 42
-Language/Libraries_and_Scripts/URIs/syntax_t10: RuntimeError # co19 issue 42
-Language/Libraries_and_Scripts/URIs/syntax_t14: RuntimeError # co19 issue 42
-Language/Libraries_and_Scripts/URIs/syntax_t15: RuntimeError # co19 issue 42
-Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # co19 issue 43
-Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # co19 issue 43
-Language/Mixins/declaring_constructor_t01: MissingCompileTimeError # co19 issue 43
-Language/Mixins/not_object_superclass_t01: MissingCompileTimeError # co19 issue 43 and 44
-Language/Mixins/reference_to_super_t01: MissingCompileTimeError # co19 issue 43 and 44
+Language/Expressions/Identifier_Reference/built_in_identifier_t35: MissingCompileTimeError # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t36: MissingCompileTimeError # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t37: MissingCompileTimeError # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_identifier_t53: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t54: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t55: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t56: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t57: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t58: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t59: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t60: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t61: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t62: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t63: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t64: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t65: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t66: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t67: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_identifier_t68: MissingCompileTimeError # Issue 25733
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t14: MissingCompileTimeError # Issue 25732
+Language/Expressions/Identifier_Reference/built_in_not_dynamic_t19: MissingCompileTimeError # Issue 25772
+Language/Expressions/Method_Invocation/Ordinary_Invocation/object_method_invocation_t01: MissingCompileTimeError # Issue 25496
+Language/Expressions/Method_Invocation/Ordinary_Invocation/object_method_invocation_t02: MissingCompileTimeError # Issue 25496
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t01: RuntimeError # Issue 24607
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t01: RuntimeError # Issue 24607
+Language/Expressions/Property_Extraction/Named_Constructor_Closurization/identical_t01: RuntimeError # Issue 24607
+Language/Expressions/Assignment/super_assignment_failed_t05: RuntimeError # Issue 25671
+Language/Expressions/Function_Invocation/async_generator_invokation_t08: Fail # Issue 25967
+Language/Expressions/Function_Invocation/async_generator_invokation_t10: Fail # Issue 25967
+Language/Expressions/Property_Extraction/Anonymous_Constructor_Closurization/identical_t02: RuntimeError # Issue 24607
+Language/Mixins/Mixin_Application/syntax_t16: CompileTimeError # Issue 25765
+Language/Mixins/declaring_constructor_t05: MissingCompileTimeError # Issue 24767
+Language/Mixins/declaring_constructor_t06: MissingCompileTimeError # Issue 24767
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t08: RuntimeError # Issue 25748
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09: RuntimeError # Issue 25748
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t10: RuntimeError # Issue 25748
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_sync_t05: RuntimeError # Issue 25662,25634
+Language/Statements/Yield_and_Yield_Each/Yield_Each/location_t01: MissingCompileTimeError # Issue 25495
+Language/Statements/Yield_and_Yield_Each/Yield_Each/location_t03: MissingCompileTimeError # Issue 25495
+Language/Statements/Yield_and_Yield_Each/Yield_Each/location_t05: MissingCompileTimeError # Issue 25495
-[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && $checked ]
-Language/Errors_and_Warnings/static_warning_t01: RuntimeError # co19 issue 45
-Language/Errors_and_Warnings/static_warning_t02: RuntimeError # co19 issue 45
-Language/Errors_and_Warnings/static_warning_t03: RuntimeError # co19 issue 45
-Language/Errors_and_Warnings/static_warning_t04: RuntimeError # co19 issue 45
-Language/Errors_and_Warnings/static_warning_t05: RuntimeError # co19 issue 45
-Language/Errors_and_Warnings/static_warning_t06: RuntimeError # co19 issue 45
+Language/Expressions/Property_Extraction/General_Super_Property_Extraction: CompileTimeError # Issue 26287
+Language/Expressions/Property_Extraction/Super_Closurization: CompileTimeError # Issue 26287
+
+# co19 Roll May 30 2016
+Language/Reference/Operator_Precedence/precedence_12_Shift_t02: RuntimeError # Issue 26573
+Language/Reference/Operator_Precedence/precedence_15_unary_prefix_t04: RuntimeError # Issue 26573
[ $noopt || $compiler == precompiler || $mode == product ]
Language/Metadata/*: SkipByDesign # Uses dart:mirrors
+Language/Expressions/Null/instance_of_class_null_t01: Skip # Uses dart:mirrors
[ $runtime == dart_precompiled || $runtime == dart_app ]
LibTest/isolate/Isolate/spawnUri*: Skip # Isolate.spawnUri
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t01: CompileTimeError # spawnUri
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: RuntimeError # spawnUri
+Language/Libraries_and_Scripts/Imports/deferred_import_t02: RuntimeError # Unsupported
[ $noopt || $compiler == precompiler ]
LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
@@ -152,6 +178,7 @@
Language/Mixins/Mixin_Application/error_t02: Pass
Language/Mixins/declaring_constructor_t01: Pass
+
[ ($arch == simdbc || $arch == simdbc64) && $mode == debug ]
# TODO(vegorov) These tests are very slow on unoptimized SIMDBC
LibTest/collection/ListMixin/ListMixin_class_A01_t02: Timeout
diff --git a/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart b/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
index 7f531eb..d4d85ef 100644
--- a/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
+++ b/tests/compiler/dart2js/analyze_dart2js_helpers_test.dart
@@ -48,9 +48,11 @@
options: options, showDiagnostics: verbose);
FormattingDiagnosticHandler diagnostics =
new FormattingDiagnosticHandler(compiler.provider);
- HelperAnalyzer analyzer = new HelperAnalyzer(diagnostics);
Directory dir =
new Directory.fromUri(Uri.base.resolve('pkg/compiler/lib/'));
+ String helpersUriPrefix = dir.uri.resolve('src/helpers/').toString();
+ HelperAnalyzer analyzer = new HelperAnalyzer(diagnostics, helpersUriPrefix);
+ LibraryElement helperLibrary;
for (FileSystemEntity entity in dir.listSync(recursive: true)) {
if (entity is File && entity.path.endsWith('.dart')) {
Uri file = Uri.base.resolve(nativeToUriPath(entity.path));
@@ -59,6 +61,9 @@
}
LibraryElement library = await compiler.analyzeUri(file);
if (library != null) {
+ if (library.libraryName == 'dart2js.helpers') {
+ helperLibrary = library;
+ }
library.forEachLocalMember((Element element) {
if (element is ClassElement) {
element.forEachLocalMember((AstElement member) {
@@ -71,12 +76,16 @@
}
}
}
+ Expect.isNotNull(helperLibrary, 'Helper library not found');
+ Expect.isTrue(analyzer.isHelper(helperLibrary),
+ "Helper library $helperLibrary is not considered a helper.");
Expect.isTrue(analyzer.errors.isEmpty, "Errors found.");
});
}
class HelperAnalyzer extends TraversalVisitor {
final FormattingDiagnosticHandler diagnostics;
+ final String helpersUriPrefix;
List<SourceSpan> errors = <SourceSpan>[];
ResolvedAst resolvedAst;
@@ -86,7 +95,7 @@
AnalyzableElement get analyzedElement => resolvedAst.element;
- HelperAnalyzer(this.diagnostics) : super(null);
+ HelperAnalyzer(this.diagnostics, this.helpersUriPrefix) : super(null);
@override
void apply(Node node, [_]) {
@@ -105,7 +114,7 @@
bool isHelper(Element element) {
Uri uri = element.library.canonicalUri;
- return '$uri'.startsWith('package:compiler/src/helpers/');
+ return '$uri'.startsWith(helpersUriPrefix);
}
void checkAccess(Node node, MemberElement element) {
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index 71d92ae..dffab8a 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -69,7 +69,7 @@
// 2. Some code was refactored, and there are more methods.
// Either situation could be problematic, but in situation 2, it is often
// acceptable to increase [expectedMethodCount] a little.
- int expectedMethodCount = 449;
+ int expectedMethodCount = 432;
Expect.isTrue(
generatedCode.length <= expectedMethodCount,
'Too many compiled methods: '
diff --git a/tests/compiler/dart2js/mock_libraries.dart b/tests/compiler/dart2js/mock_libraries.dart
index 1141416..24c42e4 100644
--- a/tests/compiler/dart2js/mock_libraries.dart
+++ b/tests/compiler/dart2js/mock_libraries.dart
@@ -258,7 +258,7 @@
final Type owner;
final String name;
final int bound;
- TypeVariable(this.owner, this.name, this.bound);
+ const TypeVariable(this.owner, this.name, this.bound);
}''',
'unwrapException': 'unwrapException(e) {}',
'voidTypeCheck': 'voidTypeCheck(value) {}',
diff --git a/tests/compiler/dart2js/serialization/equivalence_test.dart b/tests/compiler/dart2js/serialization/equivalence_test.dart
index 7caae28..bd903da 100644
--- a/tests/compiler/dart2js/serialization/equivalence_test.dart
+++ b/tests/compiler/dart2js/serialization/equivalence_test.dart
@@ -9,11 +9,13 @@
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common.dart';
+import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/constants/constructors.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/diagnostics/invariant.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/visitor.dart';
+import 'package:compiler/src/library_loader.dart';
import 'package:compiler/src/ordered_typeset.dart';
import 'package:compiler/src/serialization/element_serialization.dart';
import 'package:compiler/src/serialization/equivalence.dart';
@@ -52,10 +54,13 @@
CompilationResult result = await runCompiler(
entryPoint: entryPoint, options: [Flags.analyzeAll]);
Compiler compiler = result.compiler;
- testSerialization(compiler.libraryLoader.libraries,
- compiler.reporter,
- outPath: outPath,
- prettyPrint: prettyPrint);
+ testSerialization(
+ compiler.libraryLoader.libraries,
+ compiler.reporter,
+ compiler.resolution,
+ compiler.libraryLoader,
+ outPath: outPath,
+ prettyPrint: prettyPrint);
Expect.isFalse(compiler.reporter.hasReportedError,
"Unexpected errors occured.");
});
@@ -64,6 +69,8 @@
void testSerialization(
Iterable<LibraryElement> libraries1,
DiagnosticReporter reporter,
+ Resolution resolution,
+ LibraryProvider libraryProvider,
{String outPath,
bool prettyPrint}) {
Serializer serializer = new Serializer();
@@ -82,7 +89,8 @@
}
Deserializer deserializer = new Deserializer.fromText(
- new DeserializationContext(reporter), Uri.parse('out1.data'),
+ new DeserializationContext(reporter, resolution, libraryProvider),
+ Uri.parse('out1.data'),
text, const JsonSerializationDecoder());
List<LibraryElement> libraries2 = <LibraryElement>[];
for (LibraryElement library1 in libraries1) {
@@ -102,7 +110,8 @@
String text2 = serializer2.toText(const JsonSerializationEncoder());
Deserializer deserializer3 = new Deserializer.fromText(
- new DeserializationContext(reporter), Uri.parse('out2.data'),
+ new DeserializationContext(reporter, resolution, libraryProvider),
+ Uri.parse('out2.data'),
text2, const JsonSerializationDecoder());
for (LibraryElement library1 in libraries1) {
LibraryElement library2 =
@@ -135,7 +144,10 @@
checkElementProperties(
Object object1, object2, String property,
Element element1, Element element2) {
+ currentCheck =
+ new Check(currentCheck, object1, object2, property, element1, element2);
const ElementPropertyEquivalence().visit(element1, element2);
+ currentCheck = currentCheck.parent;
}
/// Checks the equivalence of [constructor1] and [constructor2].
@@ -255,6 +267,16 @@
element1.isFinal, element2.isFinal);
check(element1, element2, 'isConst',
element1.isConst, element2.isConst);
+ check(element1, element2, 'isAbstract',
+ element1.isAbstract, element2.isAbstract);
+ check(element1, element2, 'isStatic',
+ element1.isStatic, element2.isStatic);
+ check(element1, element2, 'isTopLevel',
+ element1.isTopLevel, element2.isTopLevel);
+ check(element1, element2, 'isClassMember',
+ element1.isClassMember, element2.isClassMember);
+ check(element1, element2, 'isInstanceMember',
+ element1.isInstanceMember, element2.isInstanceMember);
}
@override
@@ -360,7 +382,10 @@
throw message;
}
}
+ currentCheck = new Check(currentCheck, element1, element1,
+ 'member:$name', member1, member2);
visit(member1, member2);
+ currentCheck = currentCheck.parent;
}
}
@@ -368,15 +393,35 @@
void visitClassElement(ClassElement element1, ClassElement element2) {
checkElementIdentities(null, null, null, element1, element2);
check(element1, element2, 'name',
- element1.name, element2.name);
- check(element1, element2, 'sourcePosition',
+ element1.name, element2.name);
+ if (!element1.isUnnamedMixinApplication) {
+ check(element1, element2, 'sourcePosition',
element1.sourcePosition, element2.sourcePosition);
+ } else {
+ check(element1, element2, 'sourcePosition.uri',
+ element1.sourcePosition.uri, element2.sourcePosition.uri);
+ MixinApplicationElement mixin1 = element1;
+ MixinApplicationElement mixin2 = element2;
+ checkElementIdentities(mixin1, mixin2, 'subclass',
+ mixin1.subclass, mixin2.subclass);
+ checkTypes(mixin1, mixin2, 'mixinType',
+ mixin1.mixinType, mixin2.mixinType);
+ }
checkElementIdentities(
element1, element2, 'library',
element1.library, element2.library);
checkElementIdentities(
element1, element2, 'compilationUnit',
element1.compilationUnit, element2.compilationUnit);
+ checkTypeLists(
+ element1, element2, 'typeVariables',
+ element1.typeVariables, element2.typeVariables);
+ checkTypes(
+ element1, element2, 'thisType',
+ element1.thisType, element2.thisType);
+ checkTypes(
+ element1, element2, 'rawType',
+ element1.rawType, element2.rawType);
check(element1, element2, 'isObject',
element1.isObject, element2.isObject);
checkTypeLists(element1, element2, 'typeVariables',
@@ -391,27 +436,27 @@
EnumClassElement enum1 = element1;
EnumClassElement enum2 = element2;
checkElementLists(enum1, enum2, 'enumValues',
- enum1.enumValues, enum2.enumValues);
+ enum1.enumValues, enum2.enumValues);
}
if (!element1.isObject) {
checkTypes(element1, element2, 'supertype',
element1.supertype, element2.supertype);
}
check(element1, element2, 'hierarchyDepth',
- element1.hierarchyDepth, element2.hierarchyDepth);
+ element1.hierarchyDepth, element2.hierarchyDepth);
checkTypeLists(
element1, element2, 'allSupertypes',
element1.allSupertypes.toList(),
element2.allSupertypes.toList());
OrderedTypeSet typeSet1 = element1.allSupertypesAndSelf;
- OrderedTypeSet typeSet2 = element1.allSupertypesAndSelf;
+ OrderedTypeSet typeSet2 = element2.allSupertypesAndSelf;
checkListEquivalence(
element1, element2, 'allSupertypes',
typeSet1.levelOffsets,
typeSet2.levelOffsets,
check);
check(element1, element2, 'allSupertypesAndSelf.levels',
- typeSet1.levels, typeSet2.levels);
+ typeSet1.levels, typeSet2.levels);
checkTypeLists(
element1, element2, 'supertypes',
typeSet1.supertypes.toList(),
@@ -435,7 +480,20 @@
getConstructors(element1),
getConstructors(element2));
+ checkElementIdentities(element1, element2, 'defaultConstructor',
+ element1.lookupDefaultConstructor(),
+ element2.lookupDefaultConstructor());
+
visitMembers(element1, element2);
+
+ ClassElement superclass1 = element1.superclass;
+ ClassElement superclass2 = element2.superclass;
+ while (superclass1 != null && superclass1.isMixinApplication) {
+ checkElementProperties(element1, element2, 'supermixin',
+ superclass1, superclass2);
+ superclass1 = superclass1.superclass;
+ superclass2 = superclass2.superclass;
+ }
}
@override
@@ -550,8 +608,13 @@
check(
element1, element2, 'name',
element1.name, element2.name);
- check(element1, element2, 'sourcePosition',
+ if (!element1.isSynthesized) {
+ check(element1, element2, 'sourcePosition',
element1.sourcePosition, element2.sourcePosition);
+ } else {
+ check(element1, element2, 'sourcePosition.uri',
+ element1.sourcePosition.uri, element2.sourcePosition.uri);
+ }
checkListEquivalence(
element1, element2, 'parameters',
element1.parameters, element2.parameters,
diff --git a/tests/compiler/dart2js/serialization/helper.dart b/tests/compiler/dart2js/serialization/helper.dart
index a7d185c..3f2b429 100644
--- a/tests/compiler/dart2js/serialization/helper.dart
+++ b/tests/compiler/dart2js/serialization/helper.dart
@@ -88,6 +88,9 @@
if (test.preserializedSourceFiles != null) {
sourceFiles.addAll(test.preserializedSourceFiles);
}
+ if (test.unserializedSourceFiles != null) {
+ sourceFiles.addAll(test.unserializedSourceFiles);
+ }
List<Uri> resolutionInputs = <Uri>[];
for (SerializedData data in dataList) {
data.expandMemorySourceFiles(sourceFiles);
@@ -196,9 +199,13 @@
for (String key in test.preserializedSourceFiles.keys) {
uriList.add(Uri.parse('memory:$key'));
}
+ Map<String, String> sourceFiles = serializedData.toMemorySourceFiles();
+ sourceFiles.addAll(test.preserializedSourceFiles);
+ if (test.unserializedSourceFiles != null) {
+ sourceFiles.addAll(test.unserializedSourceFiles);
+ }
Compiler compiler = compilerFor(
- memorySourceFiles:
- serializedData.toMemorySourceFiles(test.preserializedSourceFiles),
+ memorySourceFiles: sourceFiles,
resolutionInputs: serializedData.toUris(),
options: [Flags.analyzeOnly, Flags.analyzeMain]);
compiler.librariesToAnalyzeWhenRun = uriList;
diff --git a/tests/compiler/dart2js/serialization/members_test.dart b/tests/compiler/dart2js/serialization/members_test.dart
new file mode 100644
index 0000000..ef23e87
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/members_test.dart
@@ -0,0 +1,157 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.class_members_test;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/common/names.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/filenames.dart';
+import 'package:compiler/src/resolution/class_members.dart';
+import 'package:compiler/src/serialization/equivalence.dart';
+import '../memory_compiler.dart';
+import 'helper.dart';
+import 'test_helper.dart';
+
+
+main(List<String> args) {
+ Arguments arguments = new Arguments.from(args);
+ asyncTest(() async {
+ SerializedData serializedData =
+ await serializeDartCore(arguments: arguments);
+ if (arguments.filename != null) {
+ Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
+ await checkClassMembers(
+ serializedData, entryPoint, verbose: arguments.verbose);
+ } else {
+ await checkClassMembers(
+ serializedData, Uris.dart_core, verbose: arguments.verbose);
+ }
+ });
+}
+
+Future checkClassMembers(
+ SerializedData serializedData,
+ Uri entryPoint,
+ {bool verbose: false}) async {
+
+ Compiler compilerNormal = compilerFor(
+ options: [Flags.analyzeAll]);
+ await compilerNormal.run(entryPoint);
+
+ Compiler compilerDeserialized = compilerFor(
+ memorySourceFiles: serializedData.toMemorySourceFiles(),
+ resolutionInputs: serializedData.toUris(),
+ options: [Flags.analyzeAll]);
+ await compilerDeserialized.run(entryPoint);
+
+ checkAllMembers(compilerNormal, compilerDeserialized, verbose: true);
+}
+
+void checkAllMembers(
+ Compiler compiler1,
+ Compiler compiler2,
+ {bool verbose: false}) {
+ checkLoadedLibraryMembers(
+ compiler1,
+ compiler2,
+ (Element member1) => member1 is ClassElement,
+ checkMembers,
+ verbose: verbose);
+}
+
+
+/// Check equivalence of members of [class1] and [class2].
+void checkMembers(
+ Compiler compiler1, ClassMemberMixin class1,
+ Compiler compiler2, ClassMemberMixin class2,
+ {bool verbose: false}) {
+ if (verbose) {
+ print('Checking $class1 vs $class2');
+ }
+ MembersCreator.computeAllClassMembers(compiler1.resolution, class1);
+ MembersCreator.computeAllClassMembers(compiler2.resolution, class2);
+
+ check(class1, class2, 'interfaceMemberAreClassMembers',
+ class1.interfaceMembersAreClassMembers,
+ class2.interfaceMembersAreClassMembers);
+ class1.forEachClassMember((Member member1) {
+ Name name1 = member1.name;
+ Name name2 = convertName(name1, compiler2);
+ checkMember(class1, class2, 'classMember:$name1',
+ member1, class2.lookupClassMember(name2));
+ });
+
+ class1.forEachInterfaceMember((MemberSignature member1) {
+ Name name1 = member1.name;
+ Name name2 = convertName(name1, compiler2);
+ checkMemberSignature(class1, class2, 'interfaceMember:$name1',
+ member1, class2.lookupInterfaceMember(name2));
+ });
+}
+
+Name convertName(Name name, Compiler compiler) {
+ if (name.isPrivate) {
+ LibraryElement library =
+ compiler.libraryLoader.lookupLibrary(name.library.canonicalUri);
+ if (!areElementsEquivalent(name.library, library)) {
+ throw 'Libraries ${name.library} and ${library} are not equivalent';
+ }
+ name = new Name(name.text, library, isSetter: name.isSetter);
+ }
+ return name;
+}
+
+void checkMember(ClassElement class1, ClassElement class2, String property,
+ Member member1, Member member2) {
+ if (member2 == null) {
+ print('$class1 class members:');
+ class1.forEachClassMember((m) => print(' ${m.name} $m'));
+ print('$class2 class members:');
+ class2.forEachClassMember((m) => print(' ${m.name} $m'));
+ throw "No member ${member1.name} in $class2 for $property";
+ }
+ checkMemberSignature(class1, class2, property, member1, member2);
+ checkElementIdentities(class1, class2, '$property.element',
+ member1.element, member2.element);
+ check(class1, class2, '$property.declarer',
+ member1.declarer, member2.declarer, areTypesEquivalent);
+ check(class1, class2, '$property.isStatic',
+ member1.isStatic, member2.isStatic);
+ check(class1, class2, '$property.isDeclaredByField',
+ member1.isDeclaredByField, member2.isDeclaredByField);
+ check(class1, class2, '$property.isAbstract',
+ member1.isAbstract, member2.isAbstract);
+ if (member1.isAbstract && member1.implementation != null) {
+ checkMember(class1, class2, '$property.implementation',
+ member1.implementation, member2.implementation);
+ }
+}
+
+void checkMemberSignature(ClassElement class1, ClassElement class2,
+ String property,
+ MemberSignature member1, MemberSignature member2) {
+ if (member2 == null) {
+ print('$class1 interface members:');
+ class1.forEachInterfaceMember((m) => print(' ${m.name} $m'));
+ print('$class2 interface members:');
+ class2.forEachInterfaceMember((m) => print(' ${m.name} $m'));
+ throw "No member ${member1.name} in $class2 for $property";
+ }
+ check(class1, class2, '$property.name',
+ member1.name, member2.name, areNamesEquivalent);
+ check(class1, class2, '$property.type',
+ member1.type, member2.type, areTypesEquivalent);
+ check(class1, class2, '$property.functionType',
+ member1.functionType, member2.functionType, areTypesEquivalent);
+ check(class1, class2, '$property.isGetter',
+ member1.isGetter, member2.isGetter);
+ check(class1, class2, '$property.isSetter',
+ member1.isSetter, member2.isSetter);
+ check(class1, class2, '$property.isMethod',
+ member1.isMethod, member2.isMethod);
+}
diff --git a/tests/compiler/dart2js/serialization/model_test.dart b/tests/compiler/dart2js/serialization/model_test.dart
index dd86acd..d7eeed6 100644
--- a/tests/compiler/dart2js/serialization/model_test.dart
+++ b/tests/compiler/dart2js/serialization/model_test.dart
@@ -45,6 +45,10 @@
int index,
Test test,
bool verbose: false}) async {
+ if (test != null && test.name == 'Disable tree shaking through reflection') {
+ // TODO(johnniwinther): Support serialization of metadata.
+ return;
+ }
String testDescription = test != null ? test.name : '${entryPoint}';
String id = index != null ? '$index: ' : '';
@@ -220,8 +224,17 @@
}
}
if (!found) {
+ if (child.isInstantiated) {
+ print('Missing subclass ${child.cls} of ${node1.cls} '
+ 'in ${node2.directSubclasses}');
+ print(compiler1.world.dump(
+ verbose ? compiler1.coreClasses.objectClass : node1.cls));
+ print(compiler2.world.dump(
+ verbose ? compiler2.coreClasses.objectClass : node2.cls));
+ }
Expect.isFalse(child.isInstantiated,
- 'Missing subclass ${child.cls} of ${node1.cls}');
+ 'Missing subclass ${child.cls} of ${node1.cls} in '
+ '${node2.directSubclasses}');
}
}
checkMixinUses(compiler1, compiler2, node1.cls, node2.cls, verbose: verbose);
diff --git a/tests/compiler/dart2js/serialization/test_data.dart b/tests/compiler/dart2js/serialization/test_data.dart
index 49f3f44..87a580f 100644
--- a/tests/compiler/dart2js/serialization/test_data.dart
+++ b/tests/compiler/dart2js/serialization/test_data.dart
@@ -308,12 +308,90 @@
class C = S with M;
''',
}),
+
+ const Test('Import mirrors, thus checking import paths', const {
+ 'main.dart': '''
+import 'dart:mirrors';
+main() {}
+''',
+ },
+ expectedWarningCount: 1),
+
+ const Test('Serialized symbol literal', const {
+ 'main.dart': '''
+import 'lib.dart';
+main() => m();
+''',
+ }, preserializedSourceFiles: const {
+ 'lib.dart': '''
+m() => print(#main);
+''',
+ }),
+
+ const Test('Indirect unserialized library', const {
+ 'main.dart': '''
+import 'a.dart';
+main() => foo();
+''',
+ }, preserializedSourceFiles: const {
+ 'a.dart': '''
+import 'memory:b.dart';
+foo() => bar();
+''',
+ }, unserializedSourceFiles: const {
+ 'b.dart': '''
+import 'memory:a.dart';
+bar() => foo();
+''',
+ }),
+
+ const Test('Multiple structurally identical mixins', const {
+ 'main.dart': '''
+class S {}
+class M {}
+class C1 extends S with M {}
+class C2 extends S with M {}
+main() {
+ new C1();
+ new C2();
+}
+''',
+ }),
+
+ const Test('Deferred loading', const {
+ 'main.dart': '''
+import 'a.dart' deferred as lib;
+main() {
+ lib.foo();
+}
+''',
+ 'a.dart': '''
+void foo() {}
+''',
+ }),
+
+ const Test('fromEnvironment constants', const {
+ 'main.dart': '''
+main() => const String.fromEnvironment("foo");
+''',
+ }),
+
+ const Test('Disable tree shaking through reflection', const {
+ 'main.dart': '''
+import 'dart:mirrors';
+
+main() {
+ reflect(null).invoke(#toString, []).reflectee;
+}
+''',
+ }, expectedWarningCount: 1),
];
class Test {
final String name;
final Map sourceFiles;
final Map preserializedSourceFiles;
+ final Map unserializedSourceFiles;
final int expectedErrorCount;
final int expectedWarningCount;
final int expectedHintCount;
@@ -323,6 +401,7 @@
this.name,
this.sourceFiles,
{this.preserializedSourceFiles,
+ this.unserializedSourceFiles,
this.expectedErrorCount: 0,
this.expectedWarningCount: 0,
this.expectedHintCount: 0,
diff --git a/tests/compiler/dart2js/serialization/test_helper.dart b/tests/compiler/dart2js/serialization/test_helper.dart
index 496d0e3..4bbed39 100644
--- a/tests/compiler/dart2js/serialization/test_helper.dart
+++ b/tests/compiler/dart2js/serialization/test_helper.dart
@@ -4,6 +4,7 @@
library dart2js.serialization_test_helper;
+import 'dart:collection';
import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/constants/expressions.dart';
import 'package:compiler/src/dart_types.dart';
@@ -12,6 +13,40 @@
import 'package:compiler/src/serialization/equivalence.dart';
import 'package:compiler/src/tree/nodes.dart';
+Check currentCheck;
+
+class Check {
+ final Check parent;
+ final Object object1;
+ final Object object2;
+ final String property;
+ final Object value1;
+ final Object value2;
+
+ Check(this.parent, this.object1, this.object2, this.property, this.value1, this.value2);
+
+ String printOn(StringBuffer sb, String indent) {
+ if (parent != null) {
+ indent = parent.printOn(sb, indent);
+ sb.write('\n$indent|\n');
+ }
+ sb.write("${indent}property='$property'\n ");
+ sb.write("${indent}object1=$object1 (${object1.runtimeType})\n ");
+ sb.write("${indent}value=${value1 == null ? "null" : "'$value1'"} ");
+ sb.write("(${value1.runtimeType}) vs\n ");
+ sb.write("${indent}object2=$object2 (${object2.runtimeType})\n ");
+ sb.write("${indent}value=${value2 == null ? "null" : "'$value2'"} ");
+ sb.write("(${value2.runtimeType})");
+ return ' $indent';
+ }
+
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ printOn(sb, '');
+ return sb.toString();
+ }
+}
+
/// Strategy for checking equivalence.
///
/// Use this strategy to fail early with contextual information in the event of
@@ -99,15 +134,12 @@
/// [value2] respectively, are equal and throw otherwise.
bool check(var object1, var object2, String property, var value1, var value2,
[bool equivalence(a, b) = equality]) {
+ currentCheck = new Check(
+ currentCheck, object1, object2, property, value1, value2);
if (!equivalence(value1, value2)) {
- throw "property='$property'\n "
- "object1=$object1 (${object1.runtimeType})\n "
- "value=${value1 == null ? "null" : "'$value1'"} "
- "(${value1.runtimeType}) <>\n "
- "object2=$object2 (${object2.runtimeType})\n "
- "value=${value2 == null ? "null" : "'$value2'"} "
- "(${value2.runtimeType})";
+ throw currentCheck;
}
+ currentCheck = currentCheck.parent;
return true;
}
@@ -119,6 +151,8 @@
Object object1, Object object2, String property,
Iterable list1, Iterable list2,
void checkEquivalence(o1, o2, property, a, b)) {
+ currentCheck =
+ new Check(currentCheck, object1, object2, property, list1, list2);
for (int i = 0; i < list1.length && i < list2.length; i++) {
checkEquivalence(
object1, object2, property,
@@ -138,6 +172,7 @@
'`${property}` on $object1:\n ${list1.join('\n ')}\n'
'`${property}` on $object2:\n ${list2.join('\n ')}';
}
+ currentCheck = currentCheck.parent;
return true;
}
@@ -244,7 +279,8 @@
if (type1 == null || type2 == null) {
return check(object1, object2, property, type1, type2);
} else {
- return const TypeEquivalence(const CheckStrategy()).visit(type1, type2);
+ return check(object1, object2, property, type1, type2,
+ (a, b) => const TypeEquivalence(const CheckStrategy()).visit(a, b));
}
}
@@ -268,7 +304,8 @@
if (exp1 == null || exp2 == null) {
return check(object1, object2, property, exp1, exp2);
} else {
- return const ConstantEquivalence(const CheckStrategy()).visit(exp1, exp2);
+ return check(object1, object2, property, exp1, exp2,
+ (a, b) => const ConstantEquivalence(const CheckStrategy()).visit(a, b));
}
}
@@ -302,6 +339,15 @@
ClassElement class2 = member2;
if (!class1.isResolved) return;
+ if (hasProperty(member1)) {
+ if (areElementsEquivalent(member1, member2)) {
+ checkMemberProperties(
+ compiler1, member1,
+ compiler2, member2,
+ verbose: verbose);
+ }
+ }
+
class1.forEachLocalMember((m1) {
checkMembers(m1, class2.localLookup(m1.name));
});
diff --git a/tests/corelib/uri_test.dart b/tests/corelib/uri_test.dart
index f1dce7a..30b6242 100644
--- a/tests/corelib/uri_test.dart
+++ b/tests/corelib/uri_test.dart
@@ -130,9 +130,13 @@
// Test non-URI base (no scheme, no authority, relative path).
base = Uri.parse("a/b/c?_#_");
testResolve("a/b/g?q#f", "g?q#f");
+ testResolve("./", "../..");
testResolve("../", "../../..");
testResolve("a/b/", ".");
testResolve("c", "../../c");
+ base = Uri.parse("../../a/b/c?_#_"); // Initial ".." in base url.
+ testResolve("../../a/d", "../d");
+ testResolve("../../../d", "../../../d");
base = Uri.parse("s:a/b");
testResolve("s:/c", "../c");
diff --git a/tests/html/html.status b/tests/html/html.status
index d39e5b9..57c3849 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -284,6 +284,7 @@
event_test: RuntimeError # Safarimobilesim does not support WheelEvent
[ $runtime == safari ]
+audiobuffersourcenode_test/functional: RuntimeError
input_element_test/supported_month: RuntimeError
input_element_test/supported_time: RuntimeError
input_element_test/supported_week: RuntimeError
diff --git a/tests/language/initializing_formal_access_test.dart b/tests/language/initializing_formal_access_test.dart
new file mode 100644
index 0000000..3d3ceed
--- /dev/null
+++ b/tests/language/initializing_formal_access_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// DartOptions=--initializing-formal-access
+
+import "package:expect/expect.dart";
+
+class C {
+ final int x;
+ final int y;
+
+ const C.constant(this.x) : y = x + 1;
+
+ C(this.x) : y = x + 1 {
+ int z = x + 2;
+ assert(z == y + 1);
+ }
+}
+
+main() {
+ C c = new C(2);
+ Expect.equals(c.x, 2);
+ Expect.equals(c.y, 3);
+ const C cc = const C.constant(4);
+ Expect.equals(cc.x, 4);
+ Expect.equals(cc.y, 5);
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index d744e27..9657b54 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -53,6 +53,9 @@
generic_methods_function_type_test: CompiletimeError # Issue 25869
generic_methods_type_expression_test: CompiletimeError # Issue 25869
+# Experimental feature: Use initializing formals in initializers and constructor body.
+initializing_formal_access_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
+
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) ]
class_keyword_test/02: MissingCompileTimeError # Issue 13627
@@ -92,6 +95,7 @@
main_test/42: Fail # Issue 20028
mirror_in_static_init_test: Fail # Issue 22071
vm/debug_break_enabled_vm_test/*: Skip # Issue 14651.
+
# Experimental feature: Syntactic support for generic methods.
generic_methods_test: RuntimeError # Issue 25869
generic_functions_test: RuntimeError # Issue 25869
@@ -100,6 +104,10 @@
generic_methods_new_test: RuntimeError # Issue 25869
generic_methods_function_type_test: RuntimeError # Issue 25869
generic_methods_type_expression_test: RuntimeError # Issue 25869
+
+# Experimental feature: Use initializing formals in initializers and constructor body.
+initializing_formal_access_test: RuntimeError # TODO(eernst): create a suitable sdk issue.
+
config_import_test: Skip # Issue 26250
[ $compiler == none && $runtime == dartium && $system == linux && $arch != x64 ]
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index a0e3ee5..8525e33 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -509,3 +509,6 @@
generic_methods_new_test: CompiletimeError # Issue 25868
generic_methods_function_type_test: CompiletimeError # Issue 25868
generic_methods_type_expression_test: CompiletimeError # Issue 25868
+
+# Experimental feature: Use initializing formals in initializers and constructor body.
+initializing_formal_access_test: CompiletimeError # TODO(eernst): Create a suitable sdk issue.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index b61dd39..bb54e5c 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -54,6 +54,9 @@
generic_methods_function_type_test: CompiletimeError # DartOptions not passed to compiler.
generic_methods_type_expression_test: CompiletimeError # DartOptions not passed to compiler.
+# Experimental feature: Use initializing formals in initializers and constructor body.
+initializing_formal_access_test: CompiletimeError # DartOptions not passed to compiler.
+
[ $compiler == dart2js ]
invocation_mirror_empty_arguments_test: Fail # Issue 24331
nan_identical_test: Fail # Issue 11551
diff --git a/tests/language/regress_26453_test.dart b/tests/language/regress_26453_test.dart
new file mode 100644
index 0000000..32d6f59
--- /dev/null
+++ b/tests/language/regress_26453_test.dart
@@ -0,0 +1,33 @@
+// 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.
+
+// The program crashed with segfault because we when we first compile foo
+// and bar we allocate all four variables (a, b, c and d) to the context.
+// When we compile foo the second time (with optimizations) we allocate
+// only c and d to the context. This happened because parser folds away
+// "${a}" and "${b}" as constant expressions when parsing bar on its own,
+// i.e. the expressions were not parsed again and thus a and b were not
+// marked as captured.
+// This caused a mismatch between a context that bar expects and that
+// the optimized version of foo produces.
+
+foo() {
+ const a = 1;
+ const b = 2;
+ var c = 3;
+ var d = 4;
+
+ bar() {
+ if ("${a}" != "1") throw "failed";
+ if ("${b}" != "2") throw "failed";
+ if ("${c}" != "3") throw "failed";
+ if ("${d}" != "4") throw "failed";
+ }
+
+ bar();
+}
+
+main() {
+ for (var i = 0; i < 50000; i++) foo();
+}
diff --git a/tests/language/regress_26543_1_test.dart b/tests/language/regress_26543_1_test.dart
new file mode 100644
index 0000000..8c425de
--- /dev/null
+++ b/tests/language/regress_26543_1_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// Regression test for issue 26543
+
+class C {
+ var x;
+ C() : x = null ?? <int, int>{} {}
+}
+
+main() {
+ print(new C());
+}
\ No newline at end of file
diff --git a/tests/language/regress_26543_2_test.dart b/tests/language/regress_26543_2_test.dart
new file mode 100644
index 0000000..36c06f0
--- /dev/null
+++ b/tests/language/regress_26543_2_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// Regression test for issue 26543
+
+class C {
+ var x, y;
+ C() : x = null ?? <int, int>{}, y = 0 {}
+}
+
+main() {
+ print(new C());
+}
\ No newline at end of file
diff --git a/tests/language/regress_26543_3_test.dart b/tests/language/regress_26543_3_test.dart
new file mode 100644
index 0000000..379e7567
--- /dev/null
+++ b/tests/language/regress_26543_3_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// Regression test for issue 26543
+
+class C {
+ var x, y;
+ C() : x = 0, y = null ?? <int, int>{} {}
+}
+
+main() {
+ print(new C());
+}
\ No newline at end of file
diff --git a/tests/lib/collection/linked_list_test.dart b/tests/lib/collection/linked_list_test.dart
index 3ed06b7..785ebe7 100644
--- a/tests/lib/collection/linked_list_test.dart
+++ b/tests/lib/collection/linked_list_test.dart
@@ -14,6 +14,55 @@
}
+testPreviousNext() {
+ var list = new LinkedList<MyEntry>();
+ Expect.throws(() => list.first);
+ Expect.throws(() => list.last);
+ Expect.equals(0, list.length);
+
+ for (int i = 0; i < 3; i++) {
+ list.add(new MyEntry(i));
+ }
+ Expect.equals(3, list.length);
+
+ var entry = list.first;
+ Expect.isNull(entry.previous);
+ Expect.equals(0, entry.value);
+ entry = entry.next;
+ Expect.equals(1, entry.value);
+ entry = entry.next;
+ Expect.equals(2, entry.value);
+ Expect.isNull(entry.next);
+ entry = entry.previous;
+ Expect.equals(1, entry.value);
+ entry = entry.previous;
+ Expect.equals(0, entry.value);
+ Expect.isNull(entry.previous);
+}
+
+testUnlinked() {
+ var unlinked = new MyEntry(0);
+ Expect.isNull(unlinked.previous);
+ Expect.isNull(unlinked.next);
+ var list = new LinkedList<MyEntry>();
+ list.add(unlinked);
+ Expect.isNull(unlinked.previous);
+ Expect.isNull(unlinked.next);
+ list.remove(unlinked);
+ Expect.isNull(unlinked.previous);
+ Expect.isNull(unlinked.next);
+ list.add(unlinked);
+ list.add(new MyEntry(1));
+ Expect.isNull(unlinked.previous);
+ Expect.equals(1, unlinked.next.value);
+ list.remove(unlinked);
+ Expect.isNull(unlinked.previous);
+ Expect.isNull(unlinked.next);
+ list.add(unlinked);
+ Expect.isNull(unlinked.next);
+ Expect.equals(1, unlinked.previous.value);
+}
+
testInsert() {
// Insert last.
var list = new LinkedList<MyEntry>();
@@ -168,6 +217,8 @@
}
main() {
+ testPreviousNext();
+ testUnlinked();
testInsert();
testRemove();
testBadAdd();
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index e5ec3ae..1eaae3f 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -85,7 +85,8 @@
TestCase _makeNormalTestCase(name, expectations) {
var command = CommandBuilder.instance.getProcessCommand(
- 'custom', Platform.executable, [Platform.script.toFilePath(), name],
+ 'custom', Platform.executable,
+ ['--package-root=${Platform.packageRoot}', Platform.script.toFilePath(), name],
{});
return _makeTestCase(name, DEFAULT_TIMEOUT, command, expectations);
}
diff --git a/tests/standalone/packages_file_test.dart b/tests/standalone/packages_file_test.dart
new file mode 100644
index 0000000..719d3d7
--- /dev/null
+++ b/tests/standalone/packages_file_test.dart
@@ -0,0 +1,975 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:async";
+import "dart:io";
+import "dart:convert" show JSON;
+import "package:path/path.dart" as p;
+import "package:async_helper/async_helper.dart";
+
+/// Root directory of generated files.
+/// Path contains trailing slash.
+/// Each configuration gets its own sub-directory.
+Directory fileRoot;
+/// Shared HTTP server serving the files in [httpFiles].
+/// Each configuration gets its own "sub-dir" entry in `httpFiles`.
+HttpServer httpServer;
+/// Directory structure served by HTTP server.
+Map<String, dynamic> httpFiles = {};
+/// List of configurations.
+List<Configuration> configurations = [];
+/// Collection of failing tests and their failure messages.
+///
+/// Each test may fail in more than one way.
+var failingTests = <String, List<String>>{};
+
+main() async {
+ asyncStart();
+ await setUp();
+
+ await runTests(); /// 01: ok
+ await runTests([spawn]); /// 02: ok
+ await runTests([spawn, spawn]); /// 03: ok
+ await runTests([spawnUriInherit]); /// 04: ok
+ await runTests([spawnUriInherit, spawn]); /// 05: ok
+ await runTests([spawn, spawnUriInherit]); /// 06: ok
+
+ // Test that spawning a new VM with file paths instead of URIs as arguments
+ // gives the same URIs in the internal values.
+ await runTests([asPath]); /// 07: ok
+
+ // Test that spawnUri can reproduce the behavior of VM command line parameters
+ // exactly.
+ // (Don't run all configuration combinations in the same test, so
+ // unroll the configurations into multiple groups and run each group
+ // as its own multitest.
+ {
+ var groupCount = 8;
+ var groups = new List.generate(8, (_)=>[]);
+ for (int i = 0; i < configurations.length; i++) {
+ groups[i % groupCount].add(configurations[i]);
+ }
+ var group = -1;
+ group = 0; /// 10: ok
+ group = 1; /// 11: ok
+ group = 2; /// 12: ok
+ group = 3; /// 13: ok
+ group = 4; /// 14: ok
+ group = 5; /// 15: ok
+ group = 6; /// 16: ok
+ group = 7; /// 17: ok
+ if (group >= 0) {
+ for (var other in groups[group]) {
+ await runTests([spawnUriOther(other)]);
+ }
+ }
+ }
+
+
+ await tearDown();
+
+ if (failingTests.isNotEmpty) {
+ print("Errors found in tests:");
+ failingTests.forEach((test, actual) {
+ print("$test:\n ${actual.join("\n ")}");
+ });
+ exit(255);
+ }
+
+ asyncEnd();
+}
+
+/// Test running the test of the configuration through [Isolate.spawn].
+///
+/// This should not change the expected results compared to running it
+/// directly.
+Configuration spawn(Configuration conf) {
+ // TODO(26555): Clean up when fixed.
+ // TEMPORARY FIX FOR ISSUE #26555 (http://dartbug.com/26555)
+ if (conf.expect["iroot"] == null &&
+ conf.expect["iconf"] == null &&
+ conf.expect["pconf"] != null) {
+ // The spawned isolate will do a search for a package file or root,
+ // which is not what the original did. Skip test for now.
+ return null;
+ }
+ // REMOVE WHEN ISSUE FIXED!
+ return conf.update(
+ description: conf.description + "/spawn",
+ main: "spawnMain",
+ newArgs: [conf.mainType],
+ // TEMPORARY FIX FOR ISSUE #26555 (http://dartbug.com/26555)
+ expect: {
+ "proot": conf.expect["iroot"],
+ "pconf": conf.expect["iconf"],
+ }
+ // REMOVE WHEN ISSUE FIXED!
+ );
+}
+
+/// Tests running a spawnUri on top of the configuration before testing.
+///
+/// The `spawnUri` call has no explicit root or config parameter, and
+/// shouldn't search for one, so it implicitly inherits the current isolate's
+/// actual root or configuration.
+Configuration spawnUriInherit(Configuration conf) {
+ if (conf.expect["iroot"] == null &&
+ conf.expect["iconf"] == null &&
+ conf.expect["pconf"] != null) {
+ // This means that the specified configuration file didn't exist.
+ // spawning a new URI to "inherit" that will actually do an automatic
+ // package resolution search with results that are unpredictable.
+ // That behavior will be tested in a setting where we have more control over
+ // the files around the spawned URI.
+ return null;
+ }
+ return conf.update(
+ description: conf.description + "/spawnUri-inherit",
+ main: "spawnUriMain",
+ // encode null parameters as "-". Windows fails if using empty string.
+ newArgs: [conf.mainFile, "-", "-", "false"],
+ expect: {
+ "proot": conf.expect["iroot"],
+ "pconf": conf.expect["iconf"],
+ }
+ );
+}
+
+/// Tests running a spawnUri with an explicit configuration different
+/// from the original configuration.
+///
+/// Duplicates the explicit parameters as arguments to the spawned isolate.
+ConfigurationTransformer spawnUriOther(Configuration other) {
+ return (Configuration conf) {
+ bool search = (other.config == null) && (other.root == null);
+ return conf.update(
+ description: "${conf.description} -spawnUri-> ${other.description}",
+ main: "spawnUriMain",
+ newArgs: [other.mainFile,
+ other.config ?? "-", other.root ?? "-", "$search"],
+ expect: other.expect
+ );
+ };
+}
+
+
+/// Convert command line parameters to file paths.
+///
+/// This only works on the command line, not with `spawnUri`.
+Configuration asPath(Configuration conf) {
+ bool change = false;
+
+ String toPath(String string) {
+ if (string == null) return null;
+ if (string.startsWith("file:")) {
+ change = true;
+ return new File.fromUri(Uri.parse(string)).path;
+ }
+ return string;
+ }
+
+ var mainFile = toPath(conf.mainFile);
+ var root = toPath(conf.root);
+ var config = toPath(conf.config);
+ if (!change) return null;
+ return conf.update(description: conf.description + "/as path",
+ mainFile: mainFile, root: root, config: config);
+}
+
+/// --------------------------------------------------------------
+
+
+Future setUp() async {
+ fileRoot = createTempDir();
+ // print("FILES: $fileRoot");
+ httpServer = await startServer(httpFiles);
+ // print("HTTPS: ${httpServer.address.address}:${httpServer.port}");
+ createConfigurations();
+}
+
+Future tearDown() async {
+ fileRoot.deleteSync(recursive: true);
+ await httpServer.close();
+}
+
+typedef Configuration ConfigurationTransformer(Configuration conf);
+
+Future runTests([List<ConfigurationTransformer> transformations]) async {
+ outer: for (var config in configurations) {
+ if (transformations != null) {
+ for (int i = transformations.length - 1; i >= 0; i--) {
+ config = transformations[i](config);
+ if (config == null) {
+ continue outer; // Can be used to skip some tests.
+ }
+ }
+ }
+ await testConfiguration(config);
+ }
+}
+
+// Creates a combination of configurations for running the Dart VM.
+//
+// The combinations covers most configurations of implicit and explicit
+// package configurations over both file: and http: file sources.
+// It also specifies the expected values of the following for a VM
+// run in that configuration.
+//
+// * `Process.packageRoot`
+// * `Process.packageConfig`
+// * `Isolate.packageRoot`
+// * `Isolate.packageRoot`
+// * `Isolate.resolvePacakgeUri` of various inputs.
+// * A variable defined in a library loaded using a `package:` URI.
+//
+// The configurations all have URIs as `root`, `config` and `mainFile` strings,
+// have empty argument lists and `mainFile` points to the the `main.dart` file.
+void createConfigurations() {
+ add(String description, String mainDir, {String root, String config,
+ Map file, Map http, Map expect}) {
+ var id = freshName("conf");
+
+ file ??= {};
+ http ??= {};
+
+ // Fix-up paths.
+ String fileUri = fileRoot.uri.resolve("$id/").toString();
+ String httpUri =
+ "http://${httpServer.address.address}:${httpServer.port}/$id/";
+
+ String fixPath(String path) {
+ return path?.replaceAllMapped(fileHttpRegexp, (match) {
+ if (path.startsWith("%file/", match.start)) return fileUri;
+ return httpUri;
+ });
+ }
+
+ void fixPaths(Map dirs) {
+ for (var name in dirs.keys) {
+ var value = dirs[name];
+ if (value is Map) {
+ Map subDir = value;
+ fixPaths(subDir);
+ } else {
+ var newValue = fixPath(value);
+ if (newValue != value) dirs[name] = newValue;
+ }
+ }
+ }
+
+ if (!mainDir.endsWith("/")) mainDir += "/";
+ // Insert main files into the main-dir map.
+ Map mainDirMap;
+ {
+ if (mainDir.startsWith("%file/")) {
+ mainDirMap = file;
+ } else {
+ mainDirMap = http;
+
+ }
+ var parts = mainDir.split('/');
+ for (int i = 1; i < parts.length - 1; i++) {
+ var dirName = parts[i];
+ mainDirMap = mainDirMap[dirName] ?? (mainDirMap[dirName] = {});
+ }
+ }
+
+ mainDirMap["main"] = testMain;
+ mainDirMap["spawnMain"] = spawnMain.replaceAll("%mainDir/", mainDir);
+ mainDirMap["spawnUriMain"] = spawnUriMain;
+
+ mainDir = fixPath(mainDir);
+ root = fixPath(root);
+ config = fixPath(config);
+ fixPaths(file);
+ fixPaths(http);
+ // These expectations are default. If not overridden the value will be
+ // expected to be null. That is, you can't avoid testing the actual
+ // value of these, you can only change what value to expect.
+ // For values not included here (commented out), the result is not tested
+ // unless a value (maybe null) is provided.
+ fixPaths(expect);
+
+ expect = {
+ "pconf": null,
+ "proot": null,
+ "iconf": null,
+ "iroot": null,
+ // "foo": null,
+ "foo/": null,
+ "foo/bar": null,
+ "foo.x": "qux",
+ }..addAll(expect ?? const {});
+
+ // Add http files to the http server.
+ if (http.isNotEmpty) {
+ httpFiles[id] = http;
+ }
+ // Add file files to the file system.
+ if (file.isNotEmpty) {
+ createFiles(fileRoot, id, file);
+ }
+
+ configurations.add(new Configuration(
+ description: description,
+ root: root,
+ config: config,
+ mainFile: mainDir + "main.dart",
+ args: const [],
+ expect: expect));
+ }
+
+ // The `test` function can generate file or http resources.
+ // It replaces "%file/" with URI of the root directory of generated files and
+ // "%http/" with the URI of the HTTP server's root in appropriate contexts
+ // (all file contents and parameters).
+
+ // Tests that only use one scheme to access files.
+ for (var scheme in ["file", "http"]) {
+
+ /// Run a test in the current scheme.
+ ///
+ /// The files are served either through HTTP or in a local directory.
+ /// Use "%$scheme/" to refer to the root of the served files.
+ addScheme(description, main, {expect, files, args, root, config}) {
+ add("$scheme/$description", main, expect: expect,
+ root: root, config: config,
+ file: (scheme == "file") ? files : null,
+ http: (scheme == "http") ? files : null);
+ }
+
+ {
+ // No parameters, no .packages files or packages/ dir.
+ // A "file:" source realizes there is no configuration and can't resolve
+ // any packages, but a "http:" source assumes a "packages/" directory.
+ addScheme("no resolution",
+ "%$scheme/",
+ files: {},
+ expect: (scheme == "file") ? {
+ "foo.x": null
+ } : {
+ "iroot": "%http/packages/",
+ "foo/": "%http/packages/foo/",
+ "foo/bar": "%http/packages/foo/bar",
+ "foo.x": null,
+ });
+ }
+
+ {
+ // No parameters, no .packages files,
+ // packages/ dir exists and is detected.
+ var files = {"packages": fooPackage};
+ addScheme("implicit packages dir","%$scheme/",
+ files: files,
+ expect: {
+ "iroot": "%$scheme/packages/",
+ "foo/": "%$scheme/packages/foo/",
+ "foo/bar": "%$scheme/packages/foo/bar",
+ });
+ }
+
+ {
+ // No parameters, no .packages files in current dir, but one in parent,
+ // packages/ dir exists and is used.
+ //
+ // Should not detect the .packages file in parent directory.
+ // That file is empty, so if it is used, the system cannot resolve "foo".
+ var files = {"sub": {"packages": fooPackage},
+ ".packages": ""};
+ addScheme("implicit packages dir overrides parent .packages",
+ "%$scheme/sub/",
+ files: files,
+ expect: {
+ "iroot": "%$scheme/sub/packages/",
+ "foo/": "%$scheme/sub/packages/foo/",
+ "foo/bar": "%$scheme/sub/packages/foo/bar",
+ // "foo.x": "qux", // Blocked by issue http://dartbug.com/26482
+ });
+ }
+
+ {
+ // No parameters, a .packages file next to entry is found and used.
+ // A packages/ directory is ignored.
+ var files = {".packages": "foo:pkgs/foo/",
+ "packages": {},
+ "pkgs": fooPackage};
+ addScheme("implicit .packages file", "%$scheme/",
+ files: files,
+ expect: {
+ "iconf": "%$scheme/.packages",
+ "foo/": "%$scheme/pkgs/foo/",
+ "foo/bar": "%$scheme/pkgs/foo/bar",
+ });
+ }
+
+ {
+ // No parameters, a .packages file in parent dir, no packages/ dir.
+ // With a file: URI, find the .packages file.
+ // WIth a http: URI, assume a packages/ dir.
+ var files = {"sub": {},
+ ".packages": "foo:pkgs/foo/",
+ "pkgs": fooPackage};
+ addScheme(".packages file in parent", "%$scheme/sub/",
+ files: files,
+ expect: (scheme == "file") ? {
+ "iconf": "%file/.packages",
+ "foo/": "%file/pkgs/foo/",
+ "foo/bar": "%file/pkgs/foo/bar",
+ } : {
+ "iroot": "%http/sub/packages/",
+ "foo/": "%http/sub/packages/foo/",
+ "foo/bar": "%http/sub/packages/foo/bar",
+ "foo.x": null,
+ });
+ }
+
+ {
+ // Specified package root that doesn't exist.
+ // Ignores existing .packages file and packages/ dir.
+ addScheme("explicit root not there",
+ "%$scheme/",
+ files: {"packages": fooPackage,
+ ".packages": "foo:%$scheme/packages/"},
+ root: "%$scheme/notthere/",
+ expect: {
+ "proot": "%$scheme/notthere/",
+ "iroot": "%$scheme/notthere/",
+ "foo/": "%$scheme/notthere/foo/",
+ "foo/bar": "%$scheme/notthere/foo/bar",
+ "foo.x": null,
+ });
+ }
+
+ {
+ // Specified package config that doesn't exist.
+ // Ignores existing .packages file and packages/ dir.
+ addScheme("explicit config not there",
+ "%$scheme/",
+ files: {".packages": "foo:packages/foo/",
+ "packages": fooPackage},
+ config: "%$scheme/.notthere",
+ expect: {
+ "pconf": "%$scheme/.notthere",
+ "iconf": null, // <- Only there if actually loaded (unspecified).
+ "foo/": null,
+ "foo/bar": null,
+ "foo.x": null,
+ });
+ }
+
+ {
+ // Specified package root with no trailing slash.
+ // The Platform.packageRoot and Isolate.packageRoot has a trailing slash.
+ var files = {".packages": "foo:packages/foo/",
+ "packages": {},
+ "pkgs": fooPackage};
+ addScheme("explicit package root, no slash", "%$scheme/",
+ files: files,
+ root: "%$scheme/pkgs",
+ expect: {
+ "proot": "%$scheme/pkgs/",
+ "iroot": "%$scheme/pkgs/",
+ "foo/": "%$scheme/pkgs/foo/",
+ "foo/bar": "%$scheme/pkgs/foo/bar",
+ });
+ }
+
+ {
+ // Specified package root with trailing slash.
+ var files = {".packages": "foo:packages/foo/",
+ "packages": {},
+ "pkgs": fooPackage};
+ addScheme("explicit package root, slash", "%$scheme/",
+ files: files,
+ root: "%$scheme/pkgs",
+ expect: {
+ "proot": "%$scheme/pkgs/",
+ "iroot": "%$scheme/pkgs/",
+ "foo/": "%$scheme/pkgs/foo/",
+ "foo/bar": "%$scheme/pkgs/foo/bar",
+ });
+ }
+
+ {
+ // Specified package config.
+ var files = {".packages": "foo:packages/foo/",
+ "packages": {},
+ ".pkgs": "foo:pkgs/foo/",
+ "pkgs": fooPackage};
+ addScheme("explicit package config file", "%$scheme/",
+ files: files,
+ config: "%$scheme/.pkgs",
+ expect: {
+ "pconf": "%$scheme/.pkgs",
+ "iconf": "%$scheme/.pkgs",
+ "foo/": "%$scheme/pkgs/foo/",
+ "foo/bar": "%$scheme/pkgs/foo/bar",
+ });
+ }
+
+ {
+ // Specified package config as data: URI.
+ // The package config can be specified as a data: URI.
+ // (In that case, relative URI references in the config file won't work).
+ var files = {".packages": "foo:packages/foo/",
+ "packages": {},
+ "pkgs": fooPackage};
+ var dataUri = "data:,foo:%$scheme/pkgs/foo/\n";
+ addScheme("explicit data: config file", "%$scheme/",
+ files: files,
+ config: dataUri,
+ expect: {
+ "pconf": dataUri,
+ "iconf": dataUri,
+ "foo/": "%$scheme/pkgs/foo/",
+ "foo/bar": "%$scheme/pkgs/foo/bar",
+ });
+ }
+ }
+
+ // Tests where there are files on both http: and file: sources.
+
+ for (var entryScheme in const ["file", "http"]) {
+ for (var pkgScheme in const ["file", "http"]) {
+ // Package root.
+ if (entryScheme != pkgScheme) {
+ // Package dir and entry point on different schemes.
+ var files = {};
+ var https = {};
+ (entryScheme == "file" ? files : https)["main"] = testMain;
+ (pkgScheme == "file" ? files : https)["pkgs"] = fooPackage;
+ add("$pkgScheme pkg/$entryScheme main", "%$entryScheme/",
+ file: files, http: https,
+ root: "%$pkgScheme/pkgs/",
+ expect: {
+ "proot": "%$pkgScheme/pkgs/",
+ "iroot": "%$pkgScheme/pkgs/",
+ "foo/": "%$pkgScheme/pkgs/foo/",
+ "foo/bar": "%$pkgScheme/pkgs/foo/bar",
+ "foo.x": "qux",
+ });
+ }
+ // Package config. The configuration file may also be on either source.
+ for (var configScheme in const ["file", "http"]) {
+ // Don't do the boring stuff!
+ if (entryScheme == configScheme && entryScheme == pkgScheme) continue;
+ // Package config, packages and entry point not all on same scheme.
+ var files = {};
+ var https = {};
+ (entryScheme == "file" ? files : https)["main"] = testMain;
+ (configScheme == "file" ? files : https)[".pkgs"] =
+ "foo:%$pkgScheme/pkgs/foo/\n";
+ (pkgScheme == "file" ? files : https)["pkgs"] = fooPackage;
+ add("$pkgScheme pkg/$configScheme config/$entryScheme main",
+ "%$entryScheme/",
+ file: files, http: https,
+ config: "%$configScheme/.pkgs",
+ expect: {
+ "pconf": "%$configScheme/.pkgs",
+ "iconf": "%$configScheme/.pkgs",
+ "foo/": "%$pkgScheme/pkgs/foo/",
+ "foo/bar": "%$pkgScheme/pkgs/foo/bar",
+ "foo.x": "qux",
+ });
+ }
+ }
+ }
+}
+
+
+// ---------------------------------------------------------
+// Helper functionality.
+
+var fileHttpRegexp = new RegExp(r"%(?:file|http)/");
+
+// Executes a test in a configuration.
+//
+// The test must specify which main file to use
+// (`main`, `spawnMain` or `spawnUriMain`)
+// and any arguments which will be used by `spawnMain` and `spawnUriMain`.
+//
+// The [expect] map may be used to override the expectations of the
+// configuration on a value-by-value basis. Passing, e.g., `{"pconf": null}`
+// will override only the `pconf` (`Platform.packageConfig`) expectation.
+Future testConfiguration(Configuration conf) async {
+ print("-- ${conf.description}");
+ var description = conf.description;
+ try {
+ var output = await execDart(conf.mainFile,
+ root: conf.root,
+ config: conf.config,
+ scriptArgs: conf.args);
+ match(JSON.decode(output), conf.expect, description, output);
+ } catch (e, s) {
+ // Unexpected error calling execDart or parsing the result.
+ // Report it and continue.
+ print("ERROR running $description: $e\n$s");
+ failingTests.putIfAbsent(description, () => []).add("$e");
+ }
+}
+
+
+/// Test that the output of running testMain matches the expectations.
+///
+/// The output is a string which is parse as a JSON literal.
+/// The resulting map is always mapping strings to strings, or possibly `null`.
+/// The expectations can have non-string values other than null,
+/// they are `toString`'ed before being compared (so the caller can use a URI
+/// or a File/Directory directly as an expectation).
+void match(Map actuals, Map expectations, String desc, String actualJson) {
+ for (var key in expectations.keys) {
+ var expectation = expectations[key]?.toString();
+ var actual = actuals[key];
+ if (expectation != actual) {
+ print("ERROR: $desc: $key: Expected: <$expectation> Found: <$actual>");
+ failingTests.putIfAbsent(desc, ()=>[]).add(
+ "$key: $expectation != $actual");
+ }
+ }
+}
+
+const String improt = "import"; // Avoid multitest import rewriting.
+
+/// Script that prints the current state and the result of resolving
+/// a few package URIs. This script will be invoked in different settings,
+/// and the result will be parsed and compared to the expectations.
+const String testMain = """
+$improt "dart:convert" show JSON;
+$improt "dart:io" show Platform, Directory;
+$improt "dart:isolate" show Isolate;
+$improt "package:foo/foo.dart" deferred as foo;
+main(_) async {
+ String platformRoot = await Platform.packageRoot;
+ String platformConfig = await Platform.packageConfig;
+ Directory cwd = Directory.current;
+ Uri script = Platform.script;
+ Uri isolateRoot = await Isolate.packageRoot;
+ Uri isolateConfig = await Isolate.packageConfig;
+ Uri base = Uri.base;
+ Uri res1 = await Isolate.resolvePackageUri(Uri.parse("package:foo"));
+ Uri res2 = await Isolate.resolvePackageUri(Uri.parse("package:foo/"));
+ Uri res3 = await Isolate.resolvePackageUri(Uri.parse("package:foo/bar"));
+ String fooX = await foo
+ .loadLibrary()
+ .timeout(const Duration(seconds: 1))
+ .then((_) => foo.x, onError: (_) => null);
+ print(JSON.encode({
+ "cwd": cwd.path,
+ "base": base?.toString(),
+ "script": script?.toString(),
+ "proot": platformRoot,
+ "pconf": platformConfig,
+ "iroot" : isolateRoot?.toString(),
+ "iconf" : isolateConfig?.toString(),
+ "foo": res1?.toString(),
+ "foo/": res2?.toString(),
+ "foo/bar": res3?.toString(),
+ "foo.x": fooX?.toString(),
+ }));
+}
+""";
+
+/// Script that spawns a new Isolate using Isolate.spawnUri.
+///
+/// Takes URI of target isolate, package config, package root and
+/// automatic package resolution-flag parameters as command line arguments.
+/// Any further arguments are forwarded to the spawned isolate.
+const String spawnUriMain = """
+$improt "dart:isolate";
+$improt "dart:async";
+main(args) async {
+ Uri target = Uri.parse(args[0]);
+ Uri config = (args[1] == "-") ? null : Uri.parse(args[1]);
+ Uri root = (args[2] == "-") ? null : Uri.parse(args[2]);
+ bool search = args[3] == "true";
+ var restArgs = args.skip(4).toList();
+ // Port keeps isolate alive until spawned isolate terminates.
+ var port = new RawReceivePort();
+ port.handler = (res) async {
+ port.close(); // Close on exit or first error.
+ if (res != null) {
+ await new Future.error(res[0], new StackTrace.fromString(res[1]));
+ }
+ };
+ Isolate.spawnUri(target, restArgs, null,
+ packageRoot: root, packageConfig: config,
+ automaticPackageResolution: search,
+ onError: port.sendPort, onExit: port.sendPort);
+}
+""";
+
+/// Script that spawns a new Isolate using Isolate.spawn.
+///
+/// Uses the first argument to select which target to spawn.
+/// Should be either "test", "uri" or "spawn".
+const String spawnMain = """
+$improt "dart:async";
+$improt "dart:isolate";
+$improt "%mainDir/main.dart" as test;
+$improt "%mainDir/spawnUriMain.dart" as spawnUri;
+main(List<String> args) async {
+ // Port keeps isolate alive until spawned isolate terminates.
+ var port = new RawReceivePort();
+ port.handler = (res) async {
+ port.close(); // Close on exit or first error.
+ if (res != null) {
+ await new Future.error(res[0], new StackTrace.fromString(res[1]));
+ }
+ };
+ var arg = args.first;
+ var rest = args.skip(1).toList();
+ var target;
+ if (arg == "main") {
+ target = test.main;
+ } else if (arg == "spawnUriMain") {
+ target = spawnUri.main;
+ } else {
+ target = main;
+ }
+ Isolate.spawn(target, rest, onError: port.sendPort, onExit: port.sendPort);
+}
+""";
+
+/// A package directory containing only one package, "foo", with one file.
+const Map fooPackage = const { "foo": const { "foo": "var x = 'qux';" }};
+
+
+/// Runs the Dart executable with the provided parameters.
+///
+/// Captures and returns the output.
+Future<String> execDart(String script,
+ {String root, String config,
+ Iterable<String> scriptArgs}) async {
+ var checked = false;
+ assert((checked = true));
+ // TODO: Find a way to change CWD before running script.
+ var executable = Platform.executable;
+ var args = [];
+ if (checked) args.add("--checked");
+ if (root != null) args.add("--package-root=$root");
+ if (config != null) args.add("--packages=$config");
+ args.add(script);
+ if (scriptArgs != null) {
+ args.addAll(scriptArgs);
+ }
+ return Process.run(executable, args).then((results) {
+ if (results.exitCode != 0 || results.stderr.isNotEmpty) {
+ throw results.stderr;
+ }
+ return results.stdout;
+ });
+}
+
+/// Creates a number of files and subdirectories.
+///
+/// The [content] is the content of the directory itself. The map keys are
+/// names and the values are either strings that represent Dart file contents
+/// or maps that represent subdirectories.
+void createFiles(Directory tempDir, String subDir, Map content) {
+ Directory createDir(Directory base, String name) {
+ Directory newDir = new Directory(p.join(base.path, name));
+ newDir.createSync();
+ return newDir;
+ }
+
+ void createTextFile(Directory base, String name, String content) {
+ File newFile = new File(p.join(base.path, name));
+ newFile.writeAsStringSync(content);
+ }
+
+ void createRecursive(Directory dir, Map map) {
+ for (var name in map.keys) {
+ var content = map[name];
+ if (content is String) {
+ // If the name starts with "." it's a .packages file, otherwise it's
+ // a dart file. Those are the only files we care about in this test.
+ createTextFile(dir,
+ name.startsWith(".") ? name : name + ".dart",
+ content);
+ } else {
+ assert(content is Map);
+ var subdir = createDir(dir, name);
+ createRecursive(subdir, content);
+ }
+ }
+ }
+
+ createRecursive(createDir(tempDir, subDir), content);
+}
+
+/// Start an HTTP server which serves a directory/file structure.
+///
+/// The directories and files are described by [files].
+///
+/// Each map key is an entry in a directory. A `Map` value is a sub-directory
+/// and a `String` value is a text file.
+/// The file contents are run through [fixPaths] to allow them to be self-
+/// referential.
+Future<HttpServer> startServer(Map files) async {
+ return (await HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 0))
+ ..forEach((request) {
+ var result = files;
+ onFailure: {
+ for (var part in request.uri.pathSegments) {
+ if (part.endsWith(".dart")) {
+ part = part.substring(0, part.length - 5);
+ }
+ if (result is Map) {
+ result = result[part];
+ } else {
+ break onFailure;
+ }
+ }
+ if (result is String) {
+ request.response..write(result)
+ ..close();
+ return;
+ }
+ }
+ request.response..statusCode = HttpStatus.NOT_FOUND
+ ..close();
+ });
+}
+
+// Counter used to avoid reusing temporary file or directory names.
+//
+// Used when adding extra files to an existing directory structure,
+// and when creating temporary directories.
+//
+// Some platform temporary-directory implementations are timer based,
+// and creating two temp-dirs withing a short duration may cause a collision.
+int tmpNameCounter = 0;
+
+// Fresh file name.
+String freshName([String base = "tmp"]) => "$base${tmpNameCounter++}";
+
+Directory createTempDir() {
+ return Directory.systemTemp.createTempSync(freshName("pftest-"));
+}
+
+typedef void ConfigUpdate(Configuration configuration);
+
+/// The configuration for a single test.
+class Configuration {
+ /// The "description" of the test - a description of the set-up.
+ final String description;
+ /// The package root parameter passed to the Dart isolate.
+ ///
+ /// At most one of [root] and [config] should be supplied. If both are
+ /// omitted, a VM will search for a packages file or dir.
+ final String root;
+ /// The package configuration file location passed to the Dart isolate.
+ final String config;
+ /// Path to the main file to run.
+ final String mainFile;
+ /// List of arguments to pass to the main function.
+ final List<String> args;
+ /// The expected values for `Platform.package{Root,Config}`,
+ /// `Isolate.package{Root,Config}` and resolution of package URIs
+ /// in a `foo` package.
+ ///
+ /// The results are found by running the `main.dart` file inside [mainDir].
+ /// The tests can run this file after doing other `spawn` or `spawnUri` calls.
+ final Map expect;
+
+ Configuration({this.description,
+ this.root,
+ this.config,
+ this.mainFile,
+ this.args,
+ this.expect});
+
+ // Gets the type of main file, one of `main`, `spawnMain` or `spawnUriMain`.
+ String get mainType {
+ var lastSlash = mainFile.lastIndexOf("/");
+ if (lastSlash < 0) {
+ // Assume it's a Windows path.
+ lastSlash = mainFile.lastIndexOf(r"\");
+ }
+ var name = mainFile.substring(lastSlash + 1, mainFile.length - 5);
+ assert(name == "main" || name == "spawnMain" || name == "spawnUriMain");
+ return name;
+ }
+
+ String get mainPath {
+ var lastSlash = mainFile.lastIndexOf("/");
+ if (lastSlash < 0) {
+ // Assume it's a Windows path.
+ lastSlash = mainFile.lastIndexOf(r"\");
+ }
+ return mainFile.substring(0, lastSlash + 1);
+ }
+
+ /// Create a new configuration from the old one.
+ ///
+ /// [description] is new description.
+ ///
+ /// [main] is one of `main`, `spawnMain` or `spawnUriMain`, and changes
+ /// the [Configuration.mainFile] to a different file in the same directory.
+ ///
+ /// [mainFile] overrides [Configuration.mainFile] completely, and ignores
+ /// [main].
+ ///
+ /// [newArgs] are prepended to the existing [Configuration.args].
+ ///
+ /// [args] overrides [Configuration.args] completely and ignores [newArgs].
+ ///
+ /// [expect] overrides individual expectations.
+ ///
+ /// [root] and [config] overrides the existing values.
+ Configuration update({
+ String description,
+ String main,
+ String mainFile,
+ String root,
+ String config,
+ List<String> args,
+ List<String> newArgs,
+ Map expect
+ }) {
+ return new Configuration(
+ description: description ?? this.description,
+ root: root ?? this.root,
+ config: config ?? this.config,
+ mainFile: mainFile ??
+ ((main == null) ? this.mainFile : "${this.mainPath}$main.dart"),
+ args:
+ args ?? (<String>[]..addAll(newArgs ?? const <String>[])
+ ..addAll(this.args)),
+ expect: expect == null
+ ? this.expect
+ : new Map.from(this.expect)..addAll(expect ?? const {}));
+ }
+
+ // For debugging.
+ String toString() {
+ return "Configuration($description\n"
+ " root : $root\n"
+ " config: $config\n"
+ " main : $mainFile\n"
+ " args : ${args.map((x) => '"$x"').join(" ")}\n"
+ ") : expect {\n${expect.keys.map((k) =>
+ ' "$k"'.padRight(6) + ":${JSON.encode(expect[k])}\n").join()}"
+ "}";
+ }
+}
+
+
+// Inserts the file with generalized [name] at [path] with [content].
+//
+// The [path] is a directory where the file is created. It must start with
+// either '%file/' or '%http/' to select the structure to put it into.
+//
+// The [name] should not have a trailing ".dart" for Dart files. Any file
+// not starting with "." is assumed to be a ".dart" file.
+void insertFileAt(Map file, Map http,
+ String path, String name, String content) {
+ var parts = path.split('/').toList();
+ var dir = (parts[0] == "%file") ? file : http;
+ for (var i = 1; i < parts.length - 1; i++) {
+ var entry = parts[i];
+ dir = dir[entry] ?? (dir[entry] = {});
+ }
+ dir[name] = content;
+}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 4ab080c..d0cad39 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -7,6 +7,9 @@
# listed in tests/lib/analyzer/analyze_tests.status without the "standalone"
# prefix.
+packages_file_test: Pass, Slow
+packages_file_test/none: Skip # contains no tests.
+
package/invalid_uri_test: Fail, OK # CompileTimeErrors intentionally
package/scenarios/packages_file_strange_formatting/empty_package_dir_test: Fail, OK # CompileTimeErrors intentionally
package/scenarios/empty_packages_file/empty_packages_file_discovery_test: Fail, OK # CompileTimeErrors intentionally
@@ -18,6 +21,9 @@
issue14236_test: Pass # Do not remove this line. It serves as a marker for Issue 14516 comment #4.
+[ ($runtime != vm || $compiler != none) && $compiler != dartanalyzer && $compiler != dart2analyzer ]
+packages_file_test: Skip # Uses Platform.executable
+
[ ($runtime != vm && $runtime != dart_precompiled && $runtime != dart_app) && ($runtime != drt || $compiler != none)) ]
no_assert_test: Fail, OK # This is testing a vm flag.
@@ -181,6 +187,7 @@
io/skipping_dart2js_compilations_test: Fail # Issue 19551.
verbose_gc_to_bmu_test: Skip
io/platform_resolved_executable_test/06: RuntimeError # Issue 23641
+io/process_sync_test: Pass, Timeout # Issue 24596
io/sleep_test: Pass, Fail # Issue 25757
[ $arch != ia32 && $arch != x64 && $arch != simarm && $arch != simarmv5te && $mode == debug ]
diff --git a/tools/.packages b/tools/.packages
new file mode 100644
index 0000000..888665a
--- /dev/null
+++ b/tools/.packages
@@ -0,0 +1,9 @@
+# The test runner logic depends on `package:yaml`, because it is not structured
+# as a pub package, we generated this file manually to contain all of yaml's
+# transitive dependencies.
+charcode:../third_party/pkg/charcode/lib/
+collection:../third_party/pkg/collection/lib/
+path:../third_party/pkg/path/lib/
+source_span:../third_party/pkg/source_span/lib/
+string_scanner:../third_party/pkg/string_scanner/lib/
+yaml:../third_party/pkg/yaml/lib/
diff --git a/tools/VERSION b/tools/VERSION
index 64279a9..a19c07d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
#
CHANNEL dev
MAJOR 1
-MINOR 17
+MINOR 18
PATCH 0
-PRERELEASE 6
-PRERELEASE_PATCH 4
+PRERELEASE 0
+PRERELEASE_PATCH 0
diff --git a/tools/dartium/buildbot_annotated_steps.py b/tools/dartium/buildbot_annotated_steps.py
index a4d7fc3..61faf75 100755
--- a/tools/dartium/buildbot_annotated_steps.py
+++ b/tools/dartium/buildbot_annotated_steps.py
@@ -30,9 +30,12 @@
def RunDartTests(mode, component, suite, arch, checked, test_filter=None,
is_win_ninja=False):
- """Runs the Dart WebKit Layout tests.
+ """Runs tests using the Dart test.py or the layout test runner.
"""
- cmd = [sys.executable]
+ cmd = []
+ if sys.platform.startswith('linux'):
+ cmd = ['xvfb-run', '-a']
+ cmd.append(sys.executable)
script = os.path.join(DART_PATH, 'tools', 'dartium', 'test.py')
cmd.append(script)
cmd.append('--buildbot')
diff --git a/tools/dartium/upload_steps.py b/tools/dartium/upload_steps.py
index 2ab3fc8..d0a7cb0 100755
--- a/tools/dartium/upload_steps.py
+++ b/tools/dartium/upload_steps.py
@@ -238,18 +238,21 @@
dir_name = os.path.dirname(layout_test_results_dir)
base_name = os.path.basename(layout_test_results_dir)
cwd = os.getcwd()
- os.chdir(dir_name)
+ try:
+ os.chdir(dir_name)
- archive_name = 'layout_test_results.zip'
- archive.ZipDir(archive_name, base_name)
+ archive_name = 'layout_test_results.zip'
+ archive.ZipDir(archive_name, base_name)
- target = '/'.join([GS_DIR, 'layout-test-results', name, component + '-' +
- checked + '-' + version + '.zip'])
- status = OldUploadFile(os.path.abspath(archive_name), GS_SITE + target)
- os.remove(archive_name)
- if status == 0:
- print ('@@@STEP_LINK@download@' + GS_URL + target + '@@@')
- else:
+ target = '/'.join([GS_DIR, 'layout-test-results', name, component + '-' +
+ checked + '-' + version + '.zip'])
+ status = OldUploadFile(os.path.abspath(archive_name), GS_SITE + target)
+ os.remove(archive_name)
+ if status == 0:
+ print ('@@@STEP_LINK@download@' + GS_URL + target + '@@@')
+ else:
+ print '@@@STEP_FAILURE@@@'
+ except:
print '@@@STEP_FAILURE@@@'
os.chdir(cwd)
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 8c8343c..015ae81 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -8,8 +8,8 @@
# Now we need to override some settings and add some new ones.
vars.update({
- "dartium_chromium_commit": "b6b6b76417ce80120ee48b662a7c7ef257723494",
- "dartium_webkit_commit": "586bcb7d9e5c46c84a3c9d1f43f26343da78548a",
+ "dartium_chromium_commit": "ef7d4ae18c646aea34c07a7ef62de7342c3b8c12",
+ "dartium_webkit_commit": "b7c1bc7268a2b3bdd0cbf59998d99624b3e1a4e9",
"chromium_base_revision": "338390",
# We use mirrors of all github repos to guarantee reproducibility and
@@ -68,7 +68,7 @@
"web_components_rev": "@6349e09f9118dce7ae1b309af5763745e25a9d61",
"WebCore_rev": "@a86fe28efadcfc781f836037a80f27e22a5dad17",
- "co19_rev": "@3ed795ea02e022ef19c77cf1b6095b7c8f5584d0",
+ "co19_rev": "@3f0a4bc9a080a792cdf5f093147a900f99ea301f",
})
deps.update({
diff --git a/tools/gyp/configurations_android.gypi b/tools/gyp/configurations_android.gypi
index 8708d6d..2aa561b 100644
--- a/tools/gyp/configurations_android.gypi
+++ b/tools/gyp/configurations_android.gypi
@@ -19,8 +19,17 @@
# order.
'Dart_Android_Base': {
'abstract': 1,
- 'cflags': [ '-Wno-abi', '-Wall', '-W', '-Wno-unused-parameter',
- '-Wnon-virtual-dtor', '-fno-rtti', '-fno-exceptions',],
+ 'cflags': [
+ # No -Werror due to warnings in stl.
+ '<@(common_gcc_warning_flags)',
+ '-Wnon-virtual-dtor',
+ '-Wvla',
+ '-Woverloaded-virtual',
+ '-g3',
+ '-ggdb3',
+ '-fno-rtti',
+ '-fno-exceptions',
+ ],
'target_conditions': [
['_toolset=="target"', {
'defines': [
diff --git a/tools/gyp/configurations_make.gypi b/tools/gyp/configurations_make.gypi
index 05292bf..8b61127 100644
--- a/tools/gyp/configurations_make.gypi
+++ b/tools/gyp/configurations_make.gypi
@@ -18,16 +18,11 @@
'<@(common_gcc_warning_flags)',
'-Wnon-virtual-dtor',
'-Wvla',
- '-Wno-conversion-null',
'-Woverloaded-virtual',
'-g3',
'-ggdb3',
- # TODO(iposva): Figure out if we need to pass anything else.
- #'-ansi',
'-fno-rtti',
'-fno-exceptions',
- # '-fvisibility=hidden',
- # '-fvisibility-inlines-hidden',
'-fstack-protector',
'-Wa,--noexecstack',
],
diff --git a/tools/gyp/configurations_msvs.gypi b/tools/gyp/configurations_msvs.gypi
index adcc1d4..68a08c5 100644
--- a/tools/gyp/configurations_msvs.gypi
+++ b/tools/gyp/configurations_msvs.gypi
@@ -10,6 +10,11 @@
'configurations': {
'Dart_Win_Base': {
'abstract': 1,
+ 'msvs_configuration_attributes': {
+ 'OutputDirectory': '<(DEPTH)\\out\\$(ConfigurationName)',
+ 'IntermediateDirectory': '$(OutDir)\\obj\\$(ProjectName)',
+ 'CharacterSet': '1',
+ },
'defines': [
'_HAS_EXCEPTIONS=0', # disable C++ exceptions use in C++ std. libs.
],
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index e9fed49..3f755dd 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -18,6 +18,9 @@
// CommandOutput.exitCode in subclasses of CommandOutput.
import "dart:io" as io;
import "dart:math" as math;
+
+import 'package:yaml/yaml.dart';
+
import 'android.dart';
import 'dependency_graph.dart' as dgraph;
import "browser_controller.dart";
@@ -463,13 +466,33 @@
String _destinationFile;
Map<String, Map> _dependencyOverrides;
- ModifyPubspecYamlCommand._(
- this._pubspecYamlFile, this._destinationFile, this._dependencyOverrides)
+ ModifyPubspecYamlCommand._(this._pubspecYamlFile,
+ this._destinationFile, this._dependencyOverrides)
: super._("modify_pubspec") {
assert(_pubspecYamlFile.endsWith("pubspec.yaml"));
assert(_destinationFile.endsWith("pubspec.yaml"));
}
+ static Map<String, Map> _filterOverrides(
+ String pubspec, Map<String, Map> overrides) {
+ if (overrides.isEmpty) return overrides;
+ var yaml = loadYaml(pubspec);
+ var deps = yaml['dependencies'];
+ var filteredOverrides = <String, Map>{};
+ if (deps != null) {
+ for (var d in deps.keys) {
+ if (!overrides.containsKey(d)) {
+ // pub depends on compiler_unsupported instead of compiler
+ // The dependency is so hackish that we currently ignore it here.
+ if (d == 'compiler_unsupported') continue;
+ throw "Repo doesn't have package $d used in $pubspec";
+ }
+ filteredOverrides[d] = overrides[d];
+ }
+ }
+ return filteredOverrides;
+ }
+
String get reproductionCommand =>
"Adding necessary dependency overrides to '$_pubspecYamlFile' "
"(destination = $_destinationFile).";
@@ -485,12 +508,13 @@
var destinationFile = new io.File(_destinationFile);
var lockfile = new io.File(pubspecLockFile);
return file.readAsString().then((String yamlString) {
+ var overrides = _filterOverrides(yamlString, _dependencyOverrides);
var dependencyOverrideSection = new StringBuffer();
if (_dependencyOverrides.isNotEmpty) {
dependencyOverrideSection.write("\n"
"# This section was autogenerated by test.py!\n"
"dependency_overrides:\n");
- _dependencyOverrides.forEach((String packageName, Map override) {
+ overrides.forEach((String packageName, Map override) {
dependencyOverrideSection.write(" $packageName:\n");
override.forEach((overrideKey, overrideValue) {
dependencyOverrideSection
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 8bc8e9a..5fe73cc 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -437,6 +437,7 @@
* dart/
* pkg/PACKAGE_NAME
* third_party/pkg/PACKAGE_NAME
+ * third_party/pkg_tested/PACKAGE_NAME
* runtime/observatory/PACKAGE_NAME
* sdk/lib/_internal/PACKAGE_NAME
*/
@@ -450,6 +451,7 @@
var futures = [
listDir(dartDir.append('pkg'), isValid),
listDir(dartDir.append('third_party').append('pkg'), isValid),
+ listDir(dartDir.append('third_party').append('pkg_tested'), isValid),
listDir(dartDir.append('runtime').append('observatory'), isValid),
listDir(dartDir.append('sdk').append('lib').append('_internal'), isValid),
];
@@ -2235,12 +2237,10 @@
static String outputDir(Map configuration) {
var result = '';
var system = configuration['system'];
- if (system == 'linux' || system == 'android') {
+ if (system == 'linux' || system == 'android' || system == 'windows') {
result = 'out/';
} else if (system == 'macos') {
result = 'xcodebuild/';
- } else if (system == 'windows') {
- result = 'build/';
} else {
throw new Exception('Unknown operating system: "$system"');
}
diff --git a/tools/utils.py b/tools/utils.py
index c4be5af..0611bdd 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -221,7 +221,7 @@
# Mapping table between OS and build output location.
BUILD_ROOT = {
- 'win32': os.path.join('build'),
+ 'win32': os.path.join('out'),
'linux': os.path.join('out'),
'freebsd': os.path.join('out'),
'macos': os.path.join('xcodebuild'),